Replace the Supabase application data plane with the Node/PostgreSQL API, migrate mobile, admin, web, and MCP callers, add controlled cutover tooling, and define hardened Dokploy infrastructure.
3.6 KiB
Local full-stack development
Use scripts/dev-local.sh; do not start a mixture of local and production data
services manually. The default stack uses conventional PostgreSQL and the Sauci
Node API. It does not start local Supabase. Supabase remains the hosted
identity provider, so local application processes need the public Auth settings
described by their environment examples.
| Service | Owner | Port |
|---|---|---|
| PostgreSQL | Docker Compose | 54320 |
| Sauci API | Node / Hono | 3003 |
| Operations worker | Node / Hono domain modules | none |
| Web | Next.js | 3000 |
| Admin | Vite | 3001 |
| MCP | Hono | 3002 |
| Expo Metro | Expo | 8081 |
PostgreSQL is bound to 127.0.0.1, is healthchecked before application startup,
and stores data in a named Docker volume. The local connection string is:
postgresql://sauci:sauci_local_only@127.0.0.1:54320/sauci
Those credentials are for local development only. Deployed environments must
inject unique secrets; they must never consume infra/backend/.env.example.
First run
- Use Node from
.nvmrcand runnpm ci. - Install Docker Desktop or Rancher Desktop and tmux.
- Configure the hosted Supabase Auth public URL/key for the mobile application
and the hosted Auth issuer/JWKS settings for the API. Do not configure any
local command with production credentials. Authenticated mobile E2E requires
the designated hosted non-production Auth project and a disposable,
onboarding-complete user whose subject has a matching local profile. Pass
its credentials as
E2E_EMAILandE2E_PASSWORDonly to the Maestro process; do not store them in an Expo environment file. To exercise MCP tools, also set a localADMIN_API_SERVICE_TOKEN, its fixtureADMIN_API_SERVICE_USER_ID, and a separateSAUCI_MCP_API_KEY.scripts/dev-local.shpasses the service token to MCP asSAUCI_ADMIN_API_TOKEN; MCP never receives a database or Supabase service credential. - Run
scripts/dev-local.sh resetto recreate only the dedicated local Docker volume, apply API migrations, and create configured fixtures. - Run
scripts/dev-local.sh up.
up is idempotent. down stops tmux application processes and leaves the
database available. down --all also stops PostgreSQL but retains its volume.
Use status, logs <service>, restart <service>, and attach for diagnosis.
logs postgres reads Compose logs; other names read their tmux panes.
The worker pane owns scheduled jobs, notifications, moderation classification,
and filesystem cleanup; local development disables external AI classification.
reset is destructive but fails closed unless the database is the dedicated
loopback instance on port 54320. It removes only the sauci-local Compose
volume, starts a fresh healthy database, then runs the API's db:migrate and
db:seed scripts. seed retains the volume and reapplies those two scripts.
The API seed is a no-op unless its documented local fixture identity is set.
The Expo window defaults to Metro with
EXPO_PUBLIC_API_URL=http://127.0.0.1:3003. Use scripts/dev-local.sh ios or
android to launch the native application against the same API. Physical
devices require a reachable host URL rather than loopback.
e2e/maestro/login-screen-smoke.yaml verifies the native build and Auth shell
without credentials. e2e/maestro/login-smoke.yaml is the authenticated
standalone-API flow and must fail closed unless the non-production fixture above
is explicitly supplied. Neither local nor E2E runs may use the production Auth
project, production subscriber, or production application database.