Extending Orbit (developers)
Repository layout
apps/
api/ Hono REST API (/v1): domain modules + declarative generic CRUD registry
worker/ background loop: imports, reminders, report schedules, submission cleanup
web/ Next.js tenant dashboard + public jobs/events portal
overseer/ Next.js superadmin console, server-side cookie BFF
packages/
db/ Drizzle schema (122 tables), schema-per-tenant migrator, definition seeds
core/ domain services shared by api + worker (auth, scheduling, reports, imports…)
shared/ permission catalogue, licenses, definition sets, settings schemas
ui/ shared React primitives (Tailwind 4)
infra/ Dockerfiles
scripts/ shot.mjs, doc-shots.mjs (screenshots), smoke.mjs (UI smoke test)
testing/ Playwright E2E suite
documentation/ this documentation
Common changes
| Change | Where |
|---|---|
| New CRUD resource | One entry in apps/api/src/generic/registry.ts; resource rules in a hook in apps/api/src/modules/<domain>/hooks.ts |
| New permission | PERMISSION_CATALOGUE in packages/shared/src/permissions.ts. It appears in the role editor automatically |
| New license-gated resource | RESOURCE_LICENSES in packages/shared/src/licenses.ts, plus a license on the nav item in apps/web/src/components/shell.tsx |
| New definition set | STANDARD_DEFINITION_SETS in packages/shared/src/definitions.ts, then list it in a Settings section in apps/web/src/app/(authenticated)/settings/page.tsx |
| New settings section | SECTIONS registry on the settings page; useCategorySettings gives the save bar and unsaved-changes guard |
| New settings category | Schema + defaults in packages/shared/src/settings.ts (exposes GET/PUT /v1/settings/<category>) |
| New importable record type | IMPORT_ENTITIES in packages/core/src/imports/entities.ts (fields, lookups, findExisting for duplicates) |
| New report dataset | packages/core/src/reports/datasets.ts; starters in starters.ts |
| New worker job | Append to ALL_JOBS in apps/worker/src/index.ts |
| New form field type | apps/api/src/modules/forms/service.ts (coerceAnswer, FORM_ENTITY_TYPES for new Used for targets), plus renderers in components/clients/client-form.tsx (formFieldsToSpecs), components/portal/events.tsx and the form builder FIELD_TYPES |
After changing the schema: pnpm db:generate, then pnpm migrate.
When you add or change a screen, update the relevant page in documentation/ and re-shoot its screenshots with node scripts/doc-shots.mjs --only=<group>.