Local dev setup
The full stack runs from a single monorepo at ~/.openclaw/workspace/twistcue/app. It’s an npm workspaces layout with three apps: services/api, apps/admin, apps/mobile (plus this docs app at apps/docs).
Prerequisites
Section titled “Prerequisites”| Tool | Version | Notes |
|---|---|---|
| Node.js | 22.x | Same major as the API runtime target. |
| npm | 10.x | Workspaces used. Do not mix pnpm/yarn. |
| PostgreSQL | 15+ | Local instance, DB name twistcue. |
| Redis | 7+ | Local instance on default port. |
Docker Compose is provided (docker-compose.yml at repo root) if you’d rather run Postgres + Redis in containers.
Boot order
Section titled “Boot order”From ~/.openclaw/workspace/twistcue/app:
# 1) Install everything (one-time / after pulls)npm install
# 2) Migrate and seed the databasecd services/apinpx prisma migrate deploynpm run seed # creates the 6 seed admins + demo users, series, purchases
# 3) Start the API (port 3000)cd ../..npm run api # listens on :3000
# 4) Start the admin (port 3100)npm run admin # listens on :3100, proxies to http://localhost:3000/v1Open http://localhost:3100 and log in with a seed account below.
Ports at a glance
Section titled “Ports at a glance”| Port | Service | Command |
|---|---|---|
| 3000 | NestJS API | npm run api |
| 3100 | Admin panel (Next.js 16) | npm run admin |
| 3300 | These docs (Astro) | npm --prefix apps/docs run dev |
| 5432 | Postgres | via Docker or system install |
| 6379 | Redis | via Docker or system install |
| 8081 | Expo/mobile Metro (optional) | npm run mobile |
Seeded admin credentials
Section titled “Seeded admin credentials”| Password | Role | Purpose | |
|---|---|---|---|
admin@twistcue.local | twistcue-admin-dev | superadmin | Break-glass; requester in approval smoke tests |
admin2@twistcue.local | twistcue-admin2-dev | superadmin | Second approver (distinct from the requester) |
content@twistcue.local | twistcue-content-dev | content_manager | Series/episode/curation flows |
moderator@twistcue.local | twistcue-moderator-dev | moderator | Comments & reports queues |
support@twistcue.local | twistcue-support-dev | support | Wallet-adjust and refund-request flows |
finance@twistcue.local | twistcue-finance-dev | finance | Refund execution and pricing flows |
analyst@twistcue.local | twistcue-analyst-dev | analyst | Dashboards read-only |
All seed passwords come from the SEED_* env vars in the smoke scripts: override them in .env if you want.
Smoke tests
Section titled “Smoke tests”Each phase has an end-to-end shell script that exercises real API flows and asserts invariants. They’re the fastest way to know the stack is healthy after a change.
# From repo root, with API + Postgres running:./scripts/p2-smoke.sh # Media & Publishing./scripts/p3-smoke.sh # Users & Support (login, ledger adjust, 500/day cap, approvals)./scripts/p4-smoke.sh # Money (refunds, reconciliation, pricing overrides)./scripts/p5-smoke.sh # Analytics & Curation (rollups, rails, free-today)./scripts/p6-smoke.sh # Engagement & Moderation (push, comments, reports)They fail loudly on the first assertion: use them as regression gates before merging.
Verify build
Section titled “Verify build”Before pushing, the workspace has a canonical verify chain:
npm run verify # api prisma-validate + build, admin build, mobile typecheck# or piecewise:npm run verify:apinpm run verify:adminnpm run verify:mobileReset the DB
Section titled “Reset the DB”cd services/apinpx prisma migrate reset # drops, migrates, seeds, nuclear but reproducibleCommon gotchas
Section titled “Common gotchas”ECONNREFUSED :3000from admin: API not running. Startnpm run apifirst.- JWT decode errors: clear the
tc_admin_tokencookie in devtools and log in again. insufficient_permissionson a route you “should” have: checkpackages/contracts/src/rbac.tsfor the exact permission your role holds; the guard rechecks on every call.prisma migrate deploycomplains about drift: you probably editedschema.prismawithout runningprisma migrate dev; fix by generating a migration or resetting.- Turbopack error about
middleware.ts: Next 16 usesproxy.tsfile convention now. Don’t createmiddleware.ts.