docs(website): settle how module schema fragments are validated and replayed
Docs half of website PR 3 (phase 2). MODULE_SYSTEM.md 2.7 gains the PR 3 entry; MODULE_API.md 2.6 gains the decisions the section did not previously answer. The one that shapes the code: a fragment is VALIDATED at load time and EXECUTED later, split on whether a database is needed to know the answer. Everything 2.6 states about the SQL is knowable by reading the file, so breaking one of those rules costs a module its mount entirely rather than mounting and 503ing with its tables half created. What is left for the replay is the class of failure only the server can report, and that is post-mount and answers 503. Also recorded: the rules are enforced as a leading-verb allowlist (CREATE, ALTER, INSERT, UPDATE -- the four core's own schema.sql uses) rather than the DROP denylist 2.6 words them as, because the file is replayed on every boot and a denylist only ever bans what somebody thought of; the replay sits outside ensureSchema's wait-for-the-database retry loop, so one module's bad SQL cannot cost the boot two minutes; partial application is accepted, since MariaDB self-commits DDL and no transaction could undo it; and `npm run seed` is the one sanctioned caller that replays nothing, because it never requires app.js and so has no scan to read. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -453,7 +453,7 @@ too (API §7.2).
|
||||
Exit criterion: `routes.manifest.json` diff is zero lines and every existing test passes. If Phase 2
|
||||
changes one URL, it is wrong.
|
||||
|
||||
**Progress: PRs 1-2 done.**
|
||||
**Progress: PRs 1-3 done.**
|
||||
|
||||
- **PR 1** — `installed_modules` and the state machine, with the stored shape and the boot rules
|
||||
settled in §2.4 above.
|
||||
@@ -466,10 +466,18 @@ changes one URL, it is wrong.
|
||||
de-entanglement registries and the two lifecycle hooks throw `not available until phase 2 PR 4/5`
|
||||
rather than no-op — an accepting stub would let a module believe it had registered something.
|
||||
28 tests, all on the failure paths.
|
||||
- **PR 3** — schema fragment replay. `ensureSchema()` replays each installed module's fragment after
|
||||
core's, with the statement splitter extracted to `utils/sqlStatements.js` so both are split by the
|
||||
same code. The decision that shaped it, recorded in [`MODULE_API.md`](MODULE_API.md) §2.6: the
|
||||
fragment is **validated at load time and executed later**, split on whether a database is needed to
|
||||
know the answer — a fragment breaking a stated rule never mounts, while a failure only the server
|
||||
could report (a bad column type) is post-mount and 503s. The rules are enforced as a **leading-verb
|
||||
allowlist** (`CREATE`, `ALTER`, `INSERT`, `UPDATE`) rather than the `DROP` denylist §2.6 words them
|
||||
as, because the file is replayed on **every boot**. Found while wiring it: `npm run seed` calls
|
||||
`ensureSchema()` without ever requiring `app.js`, so the replay has to tolerate an unscanned loader.
|
||||
|
||||
There is still no module on the volume, no schema replay and no boot wiring, so this changes nothing
|
||||
an operator or a client can see: 842 tests pass and `routes.manifest.json` is unchanged at 229
|
||||
routes.
|
||||
There is still no module on the volume and no boot wiring, so this changes nothing an operator or a
|
||||
client can see: 856 tests pass and `routes.manifest.json` is unchanged at 229 routes.
|
||||
|
||||
**Phase 3 — Extract `module-uo`.** Moves out of `website/`: the 8 model directories and their 25
|
||||
tables; the nine UO `utils/` files plus `newsGump.js`; the 13 router/controller files;
|
||||
|
||||
Reference in New Issue
Block a user