Surfc Repository Map
Surfc Repository Map
CHANGE SUMMARY
- SUR-354 (2026-05-31): Added §0 multi-repo workspace section documenting
surfc-evals/and the three-repo layout.- Updated: Pointed the Supabase node and descriptions at the new migration set plus schema contract/check tooling.
- Updated: Called out
scripts/check-schema.jsas part of the cloud boundary hotspot description.
Skill in use: repo-map — mapping structure, entry points, and hotspots per AGENTS.md.
0. Multi-repo workspace
The Surfc workspace spans three sibling repositories:
| Repo | Visibility | Served at | Purpose |
|---|---|---|---|
surfc/ | private | app.surfc.app | React 18 + Vite PWA, Dexie/IndexedDB, Supabase Edge Functions, Android TWA |
surfc-web/ | private | surfc.app | Static Astro marketing site, /policies/*, blog, pricing |
surfc-evals/ | private | n/a | Managed-AI evaluation harness (SUR-354) |
surfc-evals/ — evaluation harness
Extracted from surfc/scripts/evals/ in SUR-354. Full git history preserved via git filter-repo --subdirectory-filter.
Purpose: Evaluates discover + transcribe quality across providers and models.
- M1–M2 (
discover): Anthropic baseline, then OpenAI + Together AI (Llama + Qwen) - M3 (
transcribe): vision matrix (Anthropic, OpenAI, Mistral) + hybrid OCR pipeline (PaddleOCR) - M4 / M4b / M5 (SUR-313, SUR-443, SUR-314) will land in this repo
Stack: Node 22 + --experimental-strip-types, multi-provider SDKs, Python .venv for PaddleOCR. Separate release cadence from the app.
prompts.ts consumption mechanism (v1 — vendored):
surfc-evals/vendored/prompts.ts— copy ofsurfc/supabase/functions/anthropic-proxy/prompts.ts, with its import repointed tovendored/constants.jssurfc-evals/vendored/constants.js— theGREAT_IDEASexport extracted fromsurfc/src/constants.js.github/workflows/prompt-drift.yml— weekly CI job that fetches the source-of-truth fromsurfc/mainand fails the build if the vendored copies have drifted. The one permitted diff (the import-path rewrite on line 9) is normalised before comparing.
v2 direction (future, not yet scoped): publish @surfc/managed-ai-prompts as a private npm package consumed by both the Edge Function and the harness.
Baseline: Last committed report at surfc-evals/reports/discover-2026-05-04T19-02-44.md — parity verified via .cache/ replay after extraction.
1. Repository shape (surfc/)
graph TD A[package.json] --> B[src/main.jsx] B --> C[src/App.jsx] C --> D[hooks] C --> E[components] C --> F[styles.css] D --> G[useAuth.js] D --> H[useNoteForm.js] G --> I[src/db.js] G --> J[src/supabase.js] H --> K[src/api.js] H --> L[src/ingest/photoAdapter.js] J --> M[supabase/migrations/*.sql]src/holds the entire PWA: root mount (src/main.jsx), monolithic app shell (src/App.jsx), presentation components, stateful hooks, Dexie data layer (src/db.js), Supabase boundary (src/supabase.js), and AI adapters (src/ingest/*).supabase/provides the authoritative SQL schema, row-level security (RLS), and storage policy via versioned migrations (supabase/migrations/*.sql) plus the canonicalscripts/schema-contract.jsconsumed byscripts/check-schema.js.docs/contains legacy architecture notes plus the new evidence-based pack underdocs/architecture.- Build/runtime config is concentrated in
package.json,vite.config.js,.env, andnetlify.toml, defining the Vite+React toolchain, PWA manifest, and Netlify deployment instructions. - Tests live in
src/test/and cover user flows (src/test/App.behaviour.test.jsx), capture/tagging (src/test/capture.test.jsx), custom-idea CRUD (src/test/custom-ideas.test.jsx), and sync/outbox behavior (src/test/outbox.test.js,src/test/sync.test.js), giving executable evidence for critical paths.
2. Entry points
- Bootstrap:
src/main.jsxmounts the React tree and imports the globaltokens.css+styles.css, so any CSS variables or PWA layout tweaks fan out from there. - App shell:
src/App.jsxwires every screen, hook, and modal; it is effectively the router, orchestrator, and composition root at ~450 lines. - Authentication + sync:
useAuth(src/hooks/useAuth.js) subscribes to Supabase auth state, loads Dexie vialoadAll, flushes/enqueues the outbox, and refreshes UI state. - Data layer gate:
src/db.jsinstantiates Dexie, defines six schema migrations, and exports helpers used across hooks and components; nearly all persistence crosses this file. - Cloud boundary:
src/supabase.jscreates the Supabase client, auth helpers, database upserts, storage upload/download, and outbox collapse logic. - AI gateway:
src/api.jsprovidescallTranscribeImageandcallDiscoverIdeas, whichuseNoteFormanduseNoteActionsinvoke directly from the browser. - Ingest abstraction:
src/ingest/index.js+ adapters are the seam for future sources (today: manual + photo) before persisting viauseNoteForm.
3. High-signal files
src/db.js— full local schema, migrations, outbox queue, merge logic, and import/export helpers; any schema drift or sync bug originates here.src/hooks/useNoteForm.js— owns capture, transcription, AI tagging, note creation, and media upload orchestration.src/hooks/useSettings.js— manages Anthropic API key storage, custom idea CRUD, import/export flows, and cascading tag renames.src/hooks/useAuth.js— online/offline lifecycle, Dexie hydration, Supabase sync, and cloud write helper.src/supabase.js+supabase/migrations/*.sql/scripts/schema-contract.js— defines the exact shape of remote data, storage bucket policies, and RLS boundaries, withscripts/check-schema.jsas the drift detector.src/api.js+src/ingest/photoAdapter.js— encode Anthropics calls, sanitization, throttling, and dedupe behavior.vite.config.js+netlify.toml— PWA manifest, autoUpdate service worker, Workbox caching strategy, and SPA routing fix for Netlify.src/test/*.test.(js|jsx)— particularlyoutbox.test.js,sync.test.js,note-mutations.test.jsx, andcustom-ideas.test.jsx, which codify desired behaviors for syncing, dedupe, and UI contracts.
4. Architectural hotspots
- UI orchestration piled into
src/App.jsx: all navigation, conditional layouts, mobile tabs, modals, and long-press gestures originate here, so a regression in this file affects the entire shell. - Hooks doubling as services:
src/hooks/useNoteForm.jsmixes Dexie writes, Supabase uploads, AI calls, and navigation callbacks;src/hooks/useSettings.jswraps API key storage, import/export, and custom-idea cascades. Both exceed typical hook scope and deserve service modules. - Schema + sync centralized:
src/db.jsdefines six Dexie versions, CRUD helpers, outbox, merge logic, and import/export routines. Any change to the sync protocol or schema passes through this single file. - Cloud integration thin layer:
src/supabase.jsis the sole bridge to Supabase auth/DB/storage with minimal validation; policy drift is mitigated only if engineers run the migrations plusnpm run check:schema(supabase/migrations/*.sql,scripts/check-schema.js). - AI access embedded in UI hooks: Browser-side
fetchcalls insrc/api.jsrely on locally stored Anthropic keys, so throttling and privacy protections depend entirely on the user’s environment.
5. Open questions
- Confirmed: Tests cover outbox collapse, sync merge, App behaviors, and custom idea flows (
src/test/outbox.test.js,src/test/sync.test.js,src/test/App.behaviour.test.jsx,src/test/custom-ideas.test.jsx). - Assumption: Future ingest adapters (Readwise/Kindle) are hinted via comments in
src/db.jsandsupabase/migrations/0003_notes_add_source_ingest.sql, but no code path currently uses them. - Unknown: No evidence yet of background sync scheduling, multi-tab coordination, or push notifications; also unclear how secrets for Anthropic are rate-limited beyond local storage.