Architecture
Stack: Next.js 15 (pages router) · React 18 · TypeScript · Recoil ·
Bootstrap 5 · SCSS themes · Supabase (Postgres schema contractors_room,
Auth, Storage, Realtime) · Stripe Connect · Didit KYC · Lucy AI service
(separate app, HTTP API).
Layout
App/
pages/ routes (+ pages/api server routes)
components/ features/ (reusable) + partials/ (page sections)
axios/ data layer — Supabase client calls + row<->camelCase mappers
recoil/ state + cached lookups
lib/ server-only helpers (email, stripe, didit, settings)
public/scss/ custom.scss (light base) + _themes.scss (theme overrides)
utils/ constants.ts — status/type ids, shared helpers
supabase/ SQL migrations (run manually against Postgres)
docs/ internal knowledge base (this site renders App/docs-kb)
Rules that matter
- Every table access goes through
App/axios/*; grids filter viaapplyProjectFilters/applyContractorFiltersdriven by RecoilfilterState. - Platform configuration lives in the
settingstable — read via the cachedgetSettingValueclient-side andlib/settings.tsserver-side. Fees, currency, terms, auto-approve windows, the Lucy model: all settings, not code. - Status/type/role ids come from
utils/constants.ts— never inline magic numbers. - Themes are CSS variables on
html[data-theme]; components use tokens (--accent,--lucy,--surface,--border), never hard-coded hex.