This repository is a pnpm + Turborepo monorepo with the following workspaces:
backend: Express + TypeScript API serverfrontend: Next.js 14 apppackages/tsconfig: Shared TypeScript configspackages/types: Shared TypeScript types (@forse/types)
- Node.js 18+ (LTS recommended)
- pnpm (this repo uses the root
pnpm-lock.yaml)
pnpm installRuns dev servers in parallel via Turborepo:
pnpm devTypical dev URLs:
- Backend API: http://localhost:3001 (check server config)
- Frontend: http://localhost:3000
pnpm buildNotes:
builddepends oncodegenin the Turbo pipeline.- Backend generates
backend/openapi.jsonduringcodegen.
Run all code generation tasks across the monorepo:
pnpm codegen- Backend: generates OpenAPI spec (
backend/openapi.json). - Frontend and shared packages provide no-op
codegenscripts to keep the pipeline consistent.
pnpm lint
pnpm testbackenddepends on@forse/typesfor shared TypeScript types.frontendimports types from@forse/typesdirectly. The legacy shimfrontend/lib/types/dynamic-form.tshas been removed.
The Turbo pipeline is defined in turbo.json:
dev: non-cached, persistent processescodegen: writes**/openapi.jsonbuild: depends on^buildandcodegen, outputsdist/**,.next/**, and OpenAPI artifacts
Common scripts at the repo root:
pnpm dev # turbo run dev --parallel
pnpm build # turbo run build
pnpm codegen # turbo run codegen
pnpm lint # turbo run lint
pnpm test # turbo run testKey scripts:
pnpm --filter ./backend dev
pnpm --filter ./backend codegen
pnpm --filter ./backend build
pnpm --filter ./backend startOpenAPI:
- Generate:
pnpm --filter ./backend codegen - Served at
/docswhenopenapi.jsonexists (generated at build/codegen)
Database:
- Migrations via Knex CLI
- Per-organisation schemas: we use schema-per-org (e.g.
org_polygon,org_rootstock). Org schemas are created automatically when organizations are seeded.
Local dev setup:
# Run migrations
pnpm --filter ./backend run migrate:dev
# Seed dev data
pnpm --filter ./backend run seed:dev:tsReset database (keeps Docker running):
pnpm --filter ./backend run seed:reset:dev
pnpm --filter ./backend run migrate:dev
pnpm --filter ./backend run seed:dev:tsVerify in psql:
\dn -- list schemas
\dt org_polygon.* -- list tables in org_polygon schema
SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema='org_polygon';Key scripts:
pnpm --filter ./frontend dev
pnpm --filter ./frontend build
pnpm --filter ./frontend startImports:
- Use
@forse/typesfor shared types.
- One lockfile at repo root only. No nested
pnpm-lock.yamlin packages. - Prefer workspace protocol
workspace:*for internal deps. - Keep
packages/typesas type-only exports; no runtime side effects.
- If the docs at
/docs404, runpnpm --filter ./backend codegen. - If builds don’t see generated artifacts, ensure
pnpm codegenruns and checkturbo.jsonoutputs includeopenapi.json.
:) :)