Commit d20598a2 authored by Mahmoud Aglan's avatar Mahmoud Aglan

docs: separate structural changes from record changes

I reached for a migration to delete rows — stale API tokens — because the change
needed to apply to every client. That is the wrong test, and the rule it violated
was written down nowhere.

The deciding question is structure or records, never reach. Schema belongs in a
migration because it is structure. Rows belong in the client's own database
because they are that client's data, even when several clients need the same
correction. A migration that edits rows edits them on every tenant at once, with
no review and no way to do it for one client only — and this product is one
install per client, each running the same software over their own records.

Also states plainly that we do not deploy: code is committed and pushed, and the
platform ships it. Nothing here triggers a CapRover build.

Records the code cannot run without — a permission it checks, a default setting
it reads — are genuinely ambiguous, and the repo has precedent both ways. Noted
as a grey area to ask about rather than pretending the line is clean.
Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
parent cc417ba9
......@@ -23,6 +23,31 @@ Therefore, non-negotiable:
- Seeders must be **idempotent** and must never contain client-specific content.
- Any migration must be safe against every existing populated client DB.
### Structure goes in the repo. Records go in the client's database.
One product, installed once per client, each running the same software over their own
records. That split decides the mechanism, and the deciding question is **structure or
records** — never "does this need to reach everyone".
| What | Where it goes |
|---|---|
| Structure of the software — any code change | Commit, push to `main`. |
| Structure of the database — tables, columns, constraints, indexes, types | A migration, committed with the code. It runs everywhere on the next deploy. |
| Records — actual rows, in one client's data | SSH to the server and write them against **that client's** database. Never a migration. |
The tempting mistake is reaching for a migration because a data change "should apply to
every client". Schema belongs in a migration because it is *structure*; rows belong in a
client's database because they are *that client's data* — even when several clients happen
to need the same correction. A migration that edits rows edits them on every tenant at
once, with no review and no way to do it for one client only.
**We do not deploy.** Code is committed and pushed; the platform builds and ships it.
Do not trigger a CapRover build or force a service update.
Grey area, worth asking rather than assuming: rows the code cannot run without — a
permission the new code checks, a default setting it reads. Records by shape, structure by
dependency. Ask first.
## Hard invariants (violating these breaks production)
**Money** — all amounts are `bigInteger` **piasters**, never decimal/float.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment