Skip to content

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.js as 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:

RepoVisibilityServed atPurpose
surfc/privateapp.surfc.appReact 18 + Vite PWA, Dexie/IndexedDB, Supabase Edge Functions, Android TWA
surfc-web/privatesurfc.appStatic Astro marketing site, /policies/*, blog, pricing
surfc-evals/privaten/aManaged-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 of surfc/supabase/functions/anthropic-proxy/prompts.ts, with its import repointed to vendored/constants.js
  • surfc-evals/vendored/constants.js — the GREAT_IDEAS export extracted from surfc/src/constants.js
  • .github/workflows/prompt-drift.yml — weekly CI job that fetches the source-of-truth from surfc/main and 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 canonical scripts/schema-contract.js consumed by scripts/check-schema.js.
  • docs/ contains legacy architecture notes plus the new evidence-based pack under docs/architecture.
  • Build/runtime config is concentrated in package.json, vite.config.js, .env, and netlify.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.jsx mounts the React tree and imports the global tokens.css + styles.css, so any CSS variables or PWA layout tweaks fan out from there.
  • App shell: src/App.jsx wires 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 via loadAll, flushes/enqueues the outbox, and refreshes UI state.
  • Data layer gate: src/db.js instantiates Dexie, defines six schema migrations, and exports helpers used across hooks and components; nearly all persistence crosses this file.
  • Cloud boundary: src/supabase.js creates the Supabase client, auth helpers, database upserts, storage upload/download, and outbox collapse logic.
  • AI gateway: src/api.js provides callTranscribeImage and callDiscoverIdeas, which useNoteForm and useNoteActions invoke directly from the browser.
  • Ingest abstraction: src/ingest/index.js + adapters are the seam for future sources (today: manual + photo) before persisting via useNoteForm.

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, with scripts/check-schema.js as 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) — particularly outbox.test.js, sync.test.js, note-mutations.test.jsx, and custom-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.js mixes Dexie writes, Supabase uploads, AI calls, and navigation callbacks; src/hooks/useSettings.js wraps API key storage, import/export, and custom-idea cascades. Both exceed typical hook scope and deserve service modules.
  • Schema + sync centralized: src/db.js defines 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.js is the sole bridge to Supabase auth/DB/storage with minimal validation; policy drift is mitigated only if engineers run the migrations plus npm run check:schema (supabase/migrations/*.sql, scripts/check-schema.js).
  • AI access embedded in UI hooks: Browser-side fetch calls in src/api.js rely 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.js and supabase/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.