A portfolio-level overview of how the explAIn codebase is organized and run. The repository is private; the canonical engineering docs live in docs/ in the main repo.

Repo layout

apps/mobile/             Expo app (iOS + Android + Web)
packages/
  shared/                Zod schemas, message types, persona enums
  llm/                   Provider abstraction (DeepSeek now; Anthropic/OpenAI/Google scaffolded)
  personas/              Persona behavior modules — pure logic, framework-free
  db/                    Generated Supabase types, migrations, RLS policies
  ui/                    Shared React Native + Web components
supabase/
  migrations/            SQL migrations
  functions/             Edge functions (advise, mediate, chronicle-tick, dm-tick)
docs/
  design.md              Product thesis + transparency contract + persona catalog
  architecture.md        Schema reference + message lifecycle
  roadmap.md             v0.1 -> v1 milestones

It is a pnpm + Turborepo monorepo. The Expo app is a single codebase targeting iOS, Android, and Web via Expo Router and NativeWind.

Browse the UI on mock data

pnpm install
pnpm --filter mobile web

This boots an Expo web dev server. Without any environment configuration, the app loads mock conversations so the transparency UI can be explored end-to-end.

Wiring the real backend

The full flow needs a Supabase project and a DeepSeek API key (the v0.1 default provider). At a high level:

  1. Create the Supabase project and link it.
  2. Apply the schema with supabase db push.
  3. Set the LLM provider key as a Supabase function secret and deploy the advise and mediate edge functions.
  4. Configure the client’s public Supabase URL and anon key, then restart the dev server and sign in via the magic-link form.

The service role key and the LLM provider key never leave the Supabase edge functions; only the public Supabase URL and anon key are needed by the client bundle. Exact commands and secret names are kept in the private repo’s README.md and are intentionally not reproduced here.

Deploying the web build

A repo-root vercel.json configures Vercel for the Expo web build: output is apps/mobile/dist, with SPA rewrites for conversation and invite routes. The Vercel project needs the two public client env vars (Supabase URL and anon key) for Production and Preview; the build runs the Expo web export and serves the dist directory.

A local sanity check before pushing: pnpm --filter mobile build should produce apps/mobile/dist/.

Conventions

  • TypeScript strict, ESM, functional components with hooks only. No any in new code.
  • Edge-function failures throw a typed error; call sites branch on the error code, never substring-match the message.
  • Comments are rare by default — added only when the why is non-obvious (a hidden constraint, a workaround, surprising behavior).
  • RLS + edge-function pattern: writes and cross-participant reads on RLS-protected tables default to a Supabase Edge Function using the service role plus a JWT-decoded user id, working around a PostgREST/ES256 JWT context-propagation quirk.
  • NativeWind v4 is pinned to Tailwind 3.4.x — Tailwind is not bumped to 4.
  • Conventional commits (feat:, fix:, refactor:, docs:, chore:). No attribution footers; the owner is the sole author.

Error monitoring

Client errors and missing-invariant events go to Sentry via a thin wrapper that no-ops when the Sentry DSN env var is unset, so local development needs no Sentry account. The build pipeline uploads source maps when the Sentry secrets are present and removes the public .map files afterward so maps reach Sentry without being served publicly.