Maintaining the Data Model
The Prisma schema-change procedure, backward-compatibility considerations, and when to reach for a migration versus a code change.
The data model lives in packages/database/prisma/schema/ as a multi-file Prisma schema. Schema files are split by bounded context (base, auth, enums, fleet, pricing, crm, quotes, orders, missions, billing, documents, audit) and compiled into a single Prisma client at packages/database/src/index.ts.
Schema-change procedure
Follow these steps for any change to the Prisma schema — whether adding a field, creating a table, or modifying an enum.
1. Edit the schema file
Locate the correct bounded-context file under packages/database/prisma/schema/. Edit only the file that owns the model you are changing.
# Example: adding a field to the Mission model
# Edit: packages/database/prisma/schema/missions.prisma2. Generate and validate
Run the Prisma generator to validate syntax and regenerate the client:
pnpm --filter database generateFix any validation errors before proceeding.
3. Create the migration
Generate a named migration for the change:
pnpm --filter database exec prisma migrate dev --name descriptive-migration-nameThis creates a timestamped SQL migration file in packages/database/prisma/migrations/ and applies it to the local development database.
4. Review the migration SQL
Open the generated .sql file and verify it matches your intent. Pay special attention to:
ALTER TABLE ... DROP COLUMN— this is destructive and loses data.ALTER TABLE ... ALTER COLUMNon a column with existing data — may fail on non-empty tables.CREATE INDEX— fine, but adds migration time on large tables.
5. Apply to staging / production
pnpm --filter database exec prisma migrate deployThis runs all pending migrations against the target database without generating new files. Run it in CI before deploying the application.
Backward-compatibility considerations
Adding a field (safe)
Adding a nullable field (field Type?) is always safe — existing rows will have null for the new field. Adding a required field with a @default is also safe.
Adding a required field without a default fails on existing data unless you provide a one-time migration value.
Removing a field (destructive)
Removing a field from the schema and creating the migration drops the column. Always:
- Deprecate the field in code first — stop writing to it, keep reading it.
- Deploy the code deprecation.
- Remove the field from the schema in a subsequent migration.
Renaming a field (destructive)
Prisma does not detect renames — it generates a DROP COLUMN + ADD COLUMN. Use the @map directive to decouple the Prisma field name from the database column name if you need to rename without a column drop.
Enum changes
Adding a new enum value is safe. Removing an enum value is destructive — any existing rows referencing the removed value will fail. Always migrate existing data to a valid value before dropping an enum member.
Important semantic facts:
QuoteLine.unitPriceandQuoteLine.totalPriceare stored HT (excl. tax) — do not confuse with TTC amounts.QuoteLine.vatRateis stored as a decimal percentage:10.00means 10%, not0.10.Mission.quoteIdis nullable — internal tasks have no associated quote.- Every VTC model has an
organizationIdfield — records are isolated per operator organization.
Multi-tenancy guard
Whenever you add a new model that holds operator data, add an organizationId String field immediately. This is a non-negotiable convention — all queries must filter by organizationId.
Documentation impact
Data model changes require updating:
- The Data Model documentation if the new model or field is user-visible or developer-visible.
- Any operator back-office screen (
apps/web) or API response that surfaces the changed data — use the traceability matrix (FR415) to identify affected pages. - The OpenAPI spec — if any API endpoint's request or response schema changes, regenerate
openapi.json. See API maintenance.
See also: Data Model overview · Pricing engine maintenance · API maintenance
Maintaining the Pricing Engine
When to add a strategy or rate versus refactoring the algorithm, and the configuration-first principle for the pricing subsystem.
Maintaining the API
Adding or changing Hono routes, keeping the OpenAPI spec in sync, implications for the API reference, and the realtime/SSE event-extension procedure.