Operational guide for any coding agent working in this repo. Claude Code users:
CLAUDE.md is the fuller source of truth — this file mirrors its key facts.
OrangeCat — an AI-native platform for universal economic and governance participation ("My Cat" AI agent: earn, fund, lend, invest, govern in any currency). Bitcoin/Lightning native.
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router), TypeScript 5.8 |
| Styling | Tailwind CSS 3.3 (tokens are CSS vars in src/app/globals.css) |
| Database | Self-hosted Supabase (Postgres + Auth + RLS) at supabase.orangecat.ch |
| Bitcoin | Lightning Network, BTCPay, NWC |
| Deployment | Self-hosted on Hetzner (bitbaum, behind Caddy) — no Vercel |
npm ci # install
npm run dev -- -p 3020 # dev server on :3020 (avoids conflicts)npm run verifyverify is the ONE gate. It runs, in order: ci:docs → type-check →
audit:routes → lint → test:unit. CI (.github/workflows/ci.yml,
build-and-smoke job) calls npm run verify verbatim, so green locally ⇒ green
CI. Add or remove a check in the verify script only — never re-list checks
inline in the workflow. (E2E/Playwright is a separate post-build gate; it needs a
running server + secrets and is not part of verify.)
- SSOT is the self-hosted Supabase on Hetzner (
supabase.orangecat.ch). The managed Supabase Cloud project is retired — do NOT use it or the Supabase MCP. - Migrations live in
supabase/migrations/*.sql. Immutable once applied — never edit an existing one; always add a new file. Migrations are the schema SSOT.
main → CI (ci.yml) must go green → CD (cd.yml) ships the exact CI-built
standalone artifact to bitbaum via scripts/deploy-selfhost.sh (atomic swap +
rollback). CD is dormant until SELFHOST_SSH_KEY is set. No Vercel.
- Entity registry is SSOT:
src/config/entity-registry.ts. Never hardcode table names, API paths, or entity labels — read them from the registry. - Actor ownership: query by
actor_id, neveruser_iddirectly. - Bitcoin: store amounts as BTC in
NUMERIC(18,8)(never integer sats). Display via theuseDisplayCurrency()hook (CHF default). - Design tokens: CSS custom properties in
src/app/globals.cssare the only SSOT for color/radius/shadow. No hardcoded hex in components or Tailwind config. - Layering:
config/(what exists) →domain/(business logic, no HTTP/UI) →app/api/(thin HTTP) →components/(UI) →hooks/(data fetching).
.env.local, supabase/migrations/*, src/config/entity-registry.ts.