Developer guide
How the monorepo is laid out and how to extend it. See architecture.md for the design and ADR index for the decisions behind it.
Prerequisites
- Node 22,
corepack enable(pnpm frompackageManager). pnpm installat the repo root.
Layout
apps/
web/ SPA (React + Vite) — the UI
worker/ Hono app: api / auth / webhooks / scheduled — the backend
server/ Node host shell (SQLite/PostgreSQL) — zero-Cloudflare host
packages/
domain/ provider-neutral entities + health rules
contracts/ shared DTOs / validation
provider-github/ GitHub data adapter
provider-gitlab/ GitLab data adapter
provider-mock/ mock data (demo mode)
persistence-core/ storage seam (IDataStore)
persistence-d1/ the SQL queries the API calls
persistence-sqlite/ D1-compatible adapter over node:sqlite
persistence-postgres/ D1-compatible adapter over PostgreSQL
credits/ ui/ test-support/
migrations/ ordered *.sql applied at boot on every target
deploy/ per-target recipes (cloudflare, docker, azure-*, kubernetes, github-pages)
docs/ this documentationEveryday commands
| Command | Purpose |
|---|---|
pnpm -r typecheck | Typecheck all packages. |
pnpm test | Unit tests (vitest). |
pnpm --filter @repo-wrangler/web build | Build the SPA. |
pnpm dev | Cloudflare Worker dev server (Miniflare + local D1). |
pnpm start:server | Node host (SQLite). |
The seams (extend here, don't fork the core)
Add a data provider
- Create
packages/provider-<name>implementing the provider port used byprovider-github/provider-gitlab(discovery + entity mapping to the provider-neutraldomainentities). - Wire configuration in
apps/worker/src/bindings.ts(anis<Name>Configuredhelper) and pass values throughapps/server/src/env.tsbuildEnvfor the Node host. - Map its webhooks under
apps/worker/src/webhooks/if it has any. - Add tests and docs (
docs/providers/<name>.md) and update the capability matrix.
Add a storage adapter
The persistence layer calls a D1-shaped handle (prepare().bind().first/all/run). To add a database:
- Create
packages/persistence-<db>exposingopen<Db>D1(...)returning a D1-compatible object and anapply<Db>Migrations(...). - If the SQL dialect differs, follow
persistence-postgres: keep the sharedmigrations/and query strings, and add (a) compatibility functions for SQLite-isms and (b) a small, unit-testedtranslateSql. Don't fork the ~60 query sites. - Register it in
apps/server/src/store.tsbehind a config switch. - Verify with the same approach used for PostgreSQL (typecheck + translator tests
- run representative queries against the real engine).
See ADR-015 for the reference.
Add an auth provider
AUTH_MODE selects the sign-in provider; each issues the same signed session cookie so nothing downstream changes:
- Add routes under
apps/worker/src/auth/<provider>.ts(login + callback) that, on success, callcreateSessionCookie(...)with an allowlisted role. - Add config to
bindings.ts+apps/serverbuildEnv, extendauthMode(), and surface it in/auth/configso the SPA renders the right button. - Document it under
docs/providers/and add an ADR.
See ADR-016 / Entra for the reference.
Migrations
- Add a new file
migrations/NNNN_<slug>.sql(next number, ordered). Use plain SQL that runs on SQLite, D1, and PostgreSQL — stick to the constructs already in use (datetime('now'),ON CONFLICT … excluded, integer-boolean columns). - Migrations are applied automatically at boot and ledgered in
_migrations; never edit an applied migration — add a new one. - New camelCase result aliases or SQLite-only functions must be covered by the PostgreSQL translator/compat (add a
translateSqltest).
Adding an endpoint
Add the route in apps/worker/src/api/routes.ts, the DTO in contracts, the query in persistence-d1, and the SPA hook in apps/web/src/api/client.ts. Keep it read-only (ADR-008). Update api.md.
Testing & CI
- Unit tests live in each package's
test/(*.test.ts, vitest). - CI runs typecheck, tests, build, and CodeQL (
.github/workflows/). - The doc quality gate: a change that affects behavior/deploy/config/security/ architecture must update the relevant docs (see ROADMAP DOC-quality-gate).
Releases & ADRs
- Update CHANGELOG.md and ROADMAP.md.
- Bump
APP_VERSIONinapps/worker/src/bindings.ts. - Record notable decisions as a new numbered ADR in
docs/adr/using the Context / Decision / Consequences format. - See CONTRIBUTING.md.