Levandor CRM - Agent Quick Context
Agent Onboarding
Read this first when working on the Levandor CRM project.
What is it?
Personal business management CRM. React 19 SPA → Supabase (no custom backend). Monorepo with pnpm workspaces.
Critical Knowledge
Data Layer Pattern
Component → useMutation/useQuery hook → supabaseQuery<T>() → Supabase client → Postgres
↓
TanStack Query cache invalidation
- All queries go through
supabaseQuery()atweb/src/lib/query.ts- wraps Supabase{data, error}and throws errors - 80+ hooks in
web/src/lib/hooks/with barrel export - Query hooks:
useSupabase()+useQuery()+supabaseQuery<ViewType>() - Mutation hooks:
useMutation()+queryClient.invalidateQueries()inonSuccess
Auth Flow
Clerk manages sessions/JWTs → Supabase receives Clerk tokens via custom template → RLS enforces access
TypeScript Strictness
tsc -b(project build mode) in CI - stricter thantsc --noEmitverbatimModuleSyntax: true- explicittypekeyword for type imports- Always verify:
cd web && npx tsc -bbefore pushing
Bilingual
- EN + HU required for all UI strings
useTranslation()hook from i18next- Locale files:
web/src/locales/en.jsonandhu.json
Architecture Quick Ref
| Component | Location | Notes |
|---|---|---|
| Admin CRM | web/ | React 19, main SPA |
| Client portal | userspace/ | Planned, separate Clerk instance |
| UI primitives | packages/ui/ | shadcn/Radix, CLI-managed, don’t edit |
| Shared types | packages/shared/src/db-mappings.ts | Domain type aliases |
| Generated types | packages/shared/src/database.types.ts | ~2400 lines, auto-generated |
| Edge functions | web/supabase/functions/ | Deno, 7+ functions |
| Migrations | web/supabase/migrations/ | SQL, sequential |
Code Conventions
| Convention | Rule |
|---|---|
| File naming | PascalCase .tsx components, camelCase use*.ts hooks, kebab-case utils |
| Exports | Named exports for components/hooks, default for pages |
| Imports | React first → third-party → internal → hooks → type-only last |
| Styling | Tailwind + cn() utility, dark theme, semantic tokens |
| Git | Conventional commits: feat(scope):, fix(scope):, chore: |
| Push | Direct to origin/master (no PR workflow, solo dev) |
| DnD | Never put dnd-kit refs on Radix ScrollArea - use plain div wrapper |
Key Domain Types
| Type | Source | Notes |
|---|---|---|
| TaskView | db-mappings.ts | Task with relations |
| ProjectView | db-mappings.ts | Project with details |
| InvoiceView | db-mappings.ts | Has name field, NOT description |
| WorkflowStatus | db-mappings.ts | Has category field, NOT is_closed |
| DayPlanBlockView | db-mappings.ts | Includes joined task/project/related_tasks |
| BudgetEnvelope | db-mappings.ts | Four types: BUDGET, SAVINGS_GOAL, SAVINGS_TARGET, TRACKING |
Edge Functions
| Function | Purpose |
|---|---|
| billingo-sync-statuses | Invoice status sync from Billingo |
| billingo-sync-inbound | Vendor bill sync from Billingo |
| sync-outbound | Outbound data sync |
| rss-fetch | RSS feed ingestion |
| notify | Notifications |
| market-data | Market/exchange rate data |
| service-health | Health checks |
| ingest-email | Email ingestion (via CF Worker) |
Context Providers
SupabaseProvider- Authenticated Supabase clientCurrentPersonProvider- Logged-in person contextCurrencyProvider- HUF/EUR with live exchange ratesSidebarProvider- UI collapse state
Common Commands
cd web && pnpm dev # Dev server
cd web && npx tsc -b # Type check (CI-equivalent)
cd web && pnpm build # Production build
pnpm install # Install deps
# After schema changes:
npx supabase gen types # Regenerate database.types.tsDeeper Reading
- levandor-crm - Full project overview
- budget - Budget/envelope system
- kanban - Kanban board architecture
- day-planner - Day planner system
- debugging-log-crm - Past bugs and fixes