For Agents
Living index of themes for the Levandor CRM project (React + Supabase). Each H2 is a topic; bullets are wikilinks to related notes. Updated by
obsidian-documenterwhen documenting work. Read byhistorianat bootstrap. Topics kept alphabetical.
Auth & Security
- security — CF Access ZTNA + Supabase anon model;
cf-access.tsJWT parsing; cf-access-auth Edge Function - incident-2026-05-10-sw-cf-access-lockout — P0: Workbox
NavigationRouteblocked CF Access cookie-refresh dance, locking all users out
Brand & Design System
- levandor-brand — Copper / warm-black tokens, typography, mobile vs desktop application rules
Dashboard & Forecasting
- dashboard-forecast —
dashboard_summary_v1RPC, the avg_hrs-per-project gotcha, mobile/desktop hero alignment
DRY & Refactoring
- dry-refactor-2026-05-11 — The 2026-05-11 Tier 0+1+2 simplification pass (9 commits,
d035235..ccf6f57, ≈5k net lines removed). Catalogues the new shared abstractions future sessions should reuse rather than re-roll (web/src/components/crm/:PageHeader/ExportCsvButton/CreateButton/ErrorBanner/CardSkeleton+SkeletonLines/ResourceTable/TaskChips/getTaskCardModel/CreateEntityDialogas the standard form-dialog shell;web/src/lib/hooks/:createTableQueryWithArgs/createMaybeSingleQuery*/createRpcMutation/makeStorageAttachmentHooks/useUrlListState/useCreateTaskFromBlock/useBudgetTransactionLookups/useProjectFiles/supabase-builders.ts;web/src/lib/:on-call-rates.tsrate helpers,foreign-resource.ts,colors.tstyped status-color fns;userspace/src/lib/project-status.ts), the deliberately-deferred items (edge-function_shared/consolidation, theuseDayPlanSuggestions/useOnCallMonthlyUTC-drift bugs,packages/tender-pipeline, Tier 3 god-components,billingo1.27-VAT bug, non-atomicuseCreateInvoice/useCreateBudgetTransfer,mobile/lib/formatTime.tsTZ, possibly-deadsync-outbound), and three behavior changes (TaskCard priority pill →@/lib/colorspalette unification with the Kanban dots; TaskCard empty-AvatarFallbackbug fixed;InventoryTabname-match → FK-id-match). CAVEAT: deleted the legacynotifyEF from the repo — confirm no Supabase-dashboard Database Webhook still points at it before removing server-side.
Day Planner & Standup
- day-planner — Desktop day planner architecture (current implementation)
- mobile-day-rituals — Phone-native day-rituals (Morning, Standup notes, Lunch, Evening reflection)
- evening-checklist — Manifestation tracker v1 (mobile sheet + desktop card); also documents the timed evening-checklist nudge
- evening-checklist-day-boundary-fix-2026-05-11 — Bug + data migration: a post-midnight evening checklist filed onto the new calendar day’s
standuprow. Fix (commit1bf861a): neweveningStandupDate()inweb/src/lib/date-utils.ts— an “evening-standup day D” spans 15:00 on D → 14:59 on D+1 (uses localgetHours());MobilePlan’s evening checklist + reflection sheets now target that row (eveningStandupId+ on-demanduseEnsureStandup), gated on itsmorning_completed_at/evening_completed_at; morning/lunch/day-plan/standup-notes unchanged (calendar-date).MobilePlan.date/eveningDateun-frozen — recompute onvisibilitychange. Desktop/standupnot changed (its UTCtoISODateStringaccidentally cancels the bug for late CEST nights). Data migration moved the 4 mis-filed datapoints back. Open: not deployed yet — needspnpm --filter web deploy. Gotcha: daily-ritual “today” must be (a) local not UTC, (b) not mount-frozen in a PWA, (c) for evening rituals, post-midnight = previous day (15:00 cutoff). - mobile-autosave — Debounced field-level autosave for the standup sheets
- scheduled-reminders — Phase 3
sync_day_plan_block_reminder()trigger (split intotrg_dpb_reminder_iud+trg_dpb_reminder_upd) fires “Up next” reminders 5 min before a PLANNED block’sstart_time— which is atimestamptz(absolute instant), sofire_at = start_time - interval '5 min', nostandup.date/tz math; reminder owner isNEW.person. Live & smoke-tested. Also: the evening-checklist reminder (process_evening_checklist_reminderspg_cron job, shipped 2026-05-11) — a 21:00/22:00-Budapest nudge to finish the Evening Checklist if< Xof today’sEVENING_CHECKLISTdatapoints have a non-empty value (done = filled-in answers, notevening_completed_at);CUSTOM_REMINDERnotification withentity_type='standup', tap →/standup(auto-creates today’s standup).
External Integrations
- integrations — Index of CRM external integrations (Billingo, GitHub/GitLab, Jira, Linear, Apple Reminders, Tailscale, Cloudflare, Yahoo Finance, Polymarket)
- polymarket-fetch — External Rust pipeline writes
pm_*tables in themgmtSupabase project; CRM consumes viacreateTableQueryoncedatabase.types.tsis regenerated
Incidents & Outages
- incident-2026-05-10-sw-cf-access-lockout — 2026-05-10 P0: custom SW
NavigationRoute+ CF Access ZTNA = global lockout; fixed incd8394f
Mobile / PWA
- mobile-native-feel — As-built mobile architecture (
web/src/mobile/) — Phase 5-10 shipped + audit + brand pass - mobile-day-rituals — Phone-native ritual sheets
- mobile-autosave — Autosave hook + status pills
- evening-checklist — Manifestation tracker (mobile + desktop)
- evening-checklist-day-boundary-fix-2026-05-11 —
MobilePlanwas mount-freezing the standup date (useMemo(…, [])) and using the raw local calendar date for the evening checklist → a post-midnight session mis-filed onto the next day. Fixed:eveningStandupDate()(15:00 cutoff),visibilitychange-driven recompute, on-demanduseEnsureStandupfor the evening day. Partially closes the Mount-frozen date selectors item (MobileHours.activestill freezes). - mobile-notifications-ui — Bell + bottom drawer mirror of desktop NotificationBell + NotificationPopover
- pwa-update-prompt — Mobile bottom banner for new-version prompt (replaces silent autoUpdate + invisible toast)
- push-notifications — Web Push research (Supabase primitives + iOS PWA gotchas)
- incident-2026-05-10-sw-cf-access-lockout — Why ZTNA +
NavigationRouteis a permanent trap; SW design constraints for this codebase
Mobile Notifications UI
- mobile-notifications-ui —
MobileNotificationButton+MobileNotificationsSheet(vaul Drawer, 85vh);MobileHeaderrightSlot fallback pattern;PushDiscoveryNudgeextracted DRY; bare-render test mock pattern
Notifications
- mobile-notifications-ui — Mobile in-app list (bell + sheet); reuses
NotificationItemandTAB_FILTERSfrom desktop; extractsPushDiscoveryNudgefor sharing;handleClickgot astandup→/standupbranch for the evening-checklist nudge - push-notifications — Supabase push notifications research (transports, infra, gotchas, open decisions)
- scheduled-reminders —
remindertable +process_due_reminders()pg_cron job +CUSTOM_REMINDERtype; reminders bypassemit_notificationto dodge theevent_fanoutpush-silence; snooze (P4) re-emits viacreate_reminder. Also the evening-checklist reminder — a second pg_cron SQL fn (process_evening_checklist_reminders, cron'0 * * * *', self-gating to hours 21/22 Budapest) that direct-INSERTs aCUSTOM_REMINDERnotification (entity_type='standup',data.source='evening_checklist',origin='reminder', dedupsource_idincludes the hour) when the Evening Checklist is incomplete; does NOT use theremindertable;send-pushEF v7 +deriveUrlcase 'standup' - evening-checklist — Documents the evening-checklist reminder from the ritual side (what “done”/
N/Xmeans, why it’s filled-in-answers notevening_completed_at) - incident-2026-05-10-sw-cf-access-lockout — Push-notifications SW commit caused the auth outage; hard rule: no
NavigationRoutein any future push SW
PWA Updates
- pwa-update-prompt —
registerType: 'prompt'+MobileUpdateBanner+useUpdatePrompthook with auto-reshow on newer-update transition; vitest alias gotcha forvirtual:pwa-register/react
Scheduled Reminders
- scheduled-reminders — Phases 1-4, all shipped & applied to remote: ad-hoc one-offs (
remindertable,create_reminderRPC,process_due_reminders()pg_cron), recurring rules (compute_*_fire_atSQL helpers, 6-tab dialog), day-plan-block “Up next” trigger (splittrg_dpb_reminder_iud/trg_dpb_reminder_upd;start_timeistimestamptz), and notification snooze (SnoozePopover, forwardsentity_type/entity_id). P3 + P4 each got a 4-perspective review (DB/security/frontend/ops) — fixes shipped (ON CONFLICTre-arm guard, trigger split,reminder_update_guardBEFORE UPDATE trigger restrictingauthenticated-role direct UPDATEs tostatus-only). Plus the evening-checklist reminder (shipped 2026-05-11;process_evening_checklist_reminders+process-evening-checklist-reminderscron job) — same pattern, separate feature, does NOT touch theremindertable; revised after a 3-perspective DB/security/ops review (added the in-app-pref gate,count(DISTINCT),RAISE LOGs,'standup'click-through). Includes the Postgres gotcha cluster (STABLEvsIMMUTABLE,%ROWTYPEcursors,day+time→timestamp,timestamptz≠time& TS types both asstring,WHEN-clause triggers, MCP migration-version drift, UTC'0 * * * *'cron + in-fnAT TIME ZONEhour-gate for local-wall-clock jobs,count(DISTINCT)notcount(*)for “how many items have an answer”, self-nudging cron jobs re-check every tick + put a discriminator in the dedup key) - evening-checklist — Evening-checklist reminder documented from the ritual side
Service Worker & PWA Build
- pwa-update-prompt — Removed
install→skipWaiting()(was a recovery bridge fromcd8394f); keptactivate→clients.claim()+SKIP_WAITINGmessage handler for user-initiated updates - incident-2026-05-10-sw-cf-access-lockout —
injectManifest+web/src/sw.ts; what NOT to register; recovery viaskipWaiting+clients.claim+ in-app reset button
Tech Debt & Audit
- tech-debt — Updated 2026-05-09 with mobile audit follow-ups (UTC drift in 2 more hooks, mount-frozen date selectors, useUpdatePrompt cleanup, stub aggregations, per-user prompts v2, forecast formula cap); 2026-05-11 DRY pass deleted the “No Query Key Constants” debt (factories now centralize keys) and shrank “Direct Supabase Calls in Components” (DayPlanner/KanbanBoard/TaskDetailSheet/CSVImportWizard/TaskCard moved off — AddLoanee/AddConfiscation/CommandPalette still bypass), and added a “Deferred from the 2026-05-11 DRY Pass” section; 2026-05-11 the “Mount-frozen date selectors” item went partly fixed —
MobilePlan.date/eveningDatenow recompute onvisibilitychange(MobileHours.activestill freezes; desktop standup page still uses UTCtoISODateString) - evening-checklist-day-boundary-fix-2026-05-11 — The fix that partly closed the mount-frozen-date-selectors debt; also surfaced the “daily-ritual today must be local, not mount-frozen, and evening = post-midnight-is-previous-day” gotcha
- dry-refactor-2026-05-11 — The DRY pass’s own catalogue of what it deferred (edge-function
_shared/, the 2 UTC-drift hooks,packages/tender-pipeline, Tier 3 god-components) — the canonical record of why each was skipped - incident-2026-05-10-sw-cf-access-lockout — Stale doc flagged:
web/CLAUDE.mdand security both still describe the anon-only Supabase model; JWT exchange viacf-access-authwas reintroduced after769ba5c - scheduled-reminders — Open follow-ups (post P3/P4 review): full
reminder_update_ownRLS rewrite (now partially backstopped by thereminder_update_guardtrigger), multi-tenantday_plan_block/standupRLS tightening (lower priority — trigger usesNEW.person), no retention job forreminder/net._http_response/cron.job_run_details, thin test coverage, configurable lead-time, custom snooze picker