Developer · Contributing
User Guide
Developer
Conventions that keep a monorepo mergeable
This repository is built by multiple agents and humans working in the same tree, often in parallel. These are the rules that make that survivable — they are all drawn from conventions the existing milestones actually followed.
Strict TypeScript is the bar
Every workspace compiles under strict: true, and the gate is:
npm run typecheck # tsc --noEmit across all workspacesA green typecheck is the minimum verification for any change; past milestones caught real bugs this way (untyped error-handler params, ??/|| precedence mistakes). If your change touches behavior, also record a functional verification — curl transcripts for api work, rendered-output checks for geometry work.
Declare file ownership before you edit
Parallel work in one tree only works with declared ownership: state the paths you own up front and do not edit outside them — no drive-by tweaks to other pages, shared components, lib files, or package.json files. If you need a shared component that doesn't exist, create it inside your owned paths rather than editing a communal file. Cross-imports are fine; cross-edits are not.
packages/shared is append-only
Both apps compile against @pacfully/shared, so changes there are additive: add new constants and types, never modify or remove existing exports in the same pass as a feature. After appending, rebuild the package before typechecking the apps:
npm run build -w @pacfully/shared && npm run typecheckValidate at the edge, in Fastify schemas
Request validation lives inline in each route as Fastify/ajv JSON schema — deliberately not zod, which is not in the dependency tree. Unknown fields are rejected (additionalProperties: false), and every failure surfaces through the single error handler as the shared ApiError shape. Keep new routes consistent: schema first, scoped queries (userId = request.user.sub), serialized responses.
The glass design system has rules
- Tokens live in
globals.css(Tailwind v4@theme); components incomponents/glass/. Use theglassandtext-accentutilities instead of hand-rolling surfaces. - The indigo→cyan gradient is reserved for primary CTAs and active states — never decoration.
- Glass is for interactive surfaces (panels, toolbars, code blocks, tables). Backdrop blur never sits behind long-form body text.
- Real content only: every string comes from the product, the template catalog, or the spec. No lorem ipsum, no stock placeholders, no fake screenshots.
- Vary surfaces between adjacent sections — hairline lists, typographic blocks, glass cards, bare prose on the aurora field. Two identical patterns in a row is a bug.
Leave a build log
Every milestone ends with a build-log/NN-scope.md entry: what was created (with file paths), how it was verified (real commands and their results), and honest deviations from the spec. The log is how the next agent — human or AI — trusts the tree without re-verifying it. See build-log/02-backend.md and 03-editor.md for the house style.
Definition of done
- 1
npm run typecheck passes in every affected workspace.
- 2
Behavior verified by running it — curl flows, rendered output, or the dev server — not by reading code.
- 3
No edits outside declared ownership; shared-package changes are additive and rebuilt.
- 4
UI changes follow the design-system rules above and contain real content only.
- 5
A build-log entry records what changed, the verification, and every deviation.