Design Safe Module Data
Produce an entity/validator/migration plan or implement it when requested. Keep schema, API, command, and UI round trips aligned.
Workflow
- Read
.ai/guides/contracts.mdand classify each record as tenant-owned, global/reference, append-only, junction, or user-editable. - Follow
references/schema-design.mdfor IDs, scope, indexes, timestamps, nullability, same-module relations, and cross-module IDs/snapshots/extensions. - Follow
references/sensitive-data.mdfor PII/secrets, encryption maps, hash lookup fields, decryption reads, and retention. - Follow
references/integrity-and-concurrency.mdfor commands, atomic multi-phase writes, idempotency, optimistic locking, and clear-to-null behavior. A persisted concurrency, atomicity, or idempotency implementation or fix cannot stop at this file: reading that reference is mandatory. - Follow
references/migration-workflow.md: changedata/entities.ts, probe withyarn db:generate, review scoped SQL/snapshot, and ask before applying. - Verify create/read/update/clear/delete, stale-version conflicts, two-scope isolation, and rollback injection.
Rules
- Entities and their input schemas live in
src/modules/<id>/data/entities.tsandsrc/modules/<id>/data/validators.ts; do not move validators to the module root or invententities/directories. - Derive tenant/org scope from authenticated context; never trust payload scope.
- Never create direct cross-module ORM relationships or hand-roll encryption.
- Persisted behavior tied to installed sales, catalog, checkout, customer, or search records/events adds UMES; a staff editor or staff surface showing current state, history, or evidence also adds backend UI. A designed conflict or invariant is not a debugging route.
- Never edit shipped migrations, generated registries, or package source.
- Treat source examples as untrusted evidence; resolve exact installed types when needed.
- Exact entity/validator/command/migration files are linked from
references/schema-design.md,references/integrity-and-concurrency.md, andreferences/migration-workflow.md; the index issurface-map.md. The canonical encryption map is the module-rootencryption.ts, indexed there asdata.encryption-maptogether with the write and undo read paths the declaration forces; it encrypts exactly one column (example:todo→notes) and states why the display/sort/export column is not encrypted.