Schema Strategy
Intent
Section titled “Intent”Define how relational schema, domain contracts, and migration policy evolve together without breaking core model invariants.
Authoritative Layers
Section titled “Authoritative Layers”- Relational schema source: Drizzle in
packages/db - Runtime contract source: Zod contracts in
packages/domain - API boundary enforcement: service layer in
apps/api - Offline projection/sync constraints:
packages/offline-data
No single layer should drift independently.
Design Rules
Section titled “Design Rules”-
Additive-first migrations Prefer additive changes before destructive changes.
-
Backward-compatible transition windows Keep old and new fields/structures compatible during migration windows.
-
Explicit deprecation lifecycle Mark deprecated model surfaces and remove only after documented migration completion.
-
Temporal and audit fields by default Core mutable entities should include creation/update metadata and audit traceability.
-
Enum discipline Lifecycle/status enums must be versioned carefully and documented in lifecycle docs.
-
External sync engine version discipline pgxsinkit remains external and is consumed via npm version pinning; breaking changes are introduced via major versions rather than hidden compatibility layers.
-
Operation trace linkage Mutable sync-participating tables should carry operation-link metadata (
last_operation_idor validated equivalent) plus deterministiclast_apply_sequenceto support replay and audit. -
Single ingress for syncable tables Syncable domain-table writes must use pgxsinkit batch ingress with
bulk-plpgsql-artifact; per-route CRUD paths are not accepted for those tables.
Contract Alignment Workflow
Section titled “Contract Alignment Workflow”For every model change:
- Update core model docs if semantics change
- Update Drizzle schema
- Update Zod contracts
- Update sync projections/conflict rules
- Update integration mapping docs if event/record shape changed
- Add or update tests
Migration Policy
Section titled “Migration Policy”Minimum migration checklist:
- Forward migration script
- Rollback or compensation plan
- Data backfill strategy where required
- Integrity verification query set
- Sync impact assessment
Breaking Change Policy
Section titled “Breaking Change Policy”A change is breaking if it alters:
- Person history continuity semantics
- Membership role/status meaning
- Assessment or qualification core relationships
- Export/import compatibility for learner records
Breaking changes require:
- Architecture note in docs
- Explicit migration playbook
- Compatibility window plan
Naming and Identity Guidance
Section titled “Naming and Identity Guidance”- Use stable surrogate IDs for core entities
- Keep external identifiers in dedicated binding tables
- Avoid embedding mutable semantics into primary keys
Validation Boundaries
Section titled “Validation Boundaries”- Input validation at API boundary with Zod
- Domain-level validation for invariants before persistence
- DB constraints for last-line integrity checks
Implementation Anchors
Section titled “Implementation Anchors”- Schema and migrations:
packages/db - Shared validators/types:
packages/domain - Sync shape and convergence behavior:
packages/offline-data - Mutation and authorization workflows:
apps/api
Open Decisions
Section titled “Open Decisions”- Compatibility window duration for deprecated fields
- Migration approval gate requirements for production rollout
- Level of automated schema-doc parity checks in CI
- Exact cross-project contract for linking local row updates to pgxsinkit operation IDs
- Whether operation linkage on syncable rows should be enforced FK to
operations_log.idor a validated non-FK identifier contract