13. Decisions¶
The decisions that hold today. Each one is recorded with its reason, the alternatives not chosen and what it affects. This log shows the live design and nothing else: when a decision changes, its entry is rewritten to say what is true now, and the change is recorded in Appendix C, the version history.
13.1 The decision log¶
ADR-001: The database enforces its own rules¶
Decision. Every rule is enforced by the database file itself, not by a script, a formula or a screen.
Reason. A rule that can be bypassed is not a rule. A mistyped but well-formed value, such as the country code USS, passes a format check and must be refused by the database. A value must be refused whether it arrives from a person, a script or an import.
Not chosen. Check columns that only flag a wrong value; one validated entry point with hand edits left unprotected.
Affects. 9.4 The physical schema and 9.6 Rules and tests.
ADR-002: The data dictionary is the only source¶
Decision. A field is defined once, in the data dictionary. The schema, the checks, the reference lists and the field pages of this site are generated from it. Reason. What is typed twice drifts apart. One source makes drift impossible. Affects. Chapter 9 as a whole.
ADR-003: The blueprint is data inside the database¶
Decision. The data dictionary and the reference definitions live in blueprint tables in the database: tables, fields, rules, lists, tags and terms, each with a definition and a purpose. The generator reads them and produces the migrations, the field pages, the rule catalog and the tests. No table or column exists unless a blueprint row says it should. Reason. Scripts must be able to ask the database what a field is called and how it is tagged. The blueprint gets the same constraints as the data, and a view that compares it with SQLite's own list of real columns makes any difference visible at once. Not chosen. Files in version control as the only source (not queryable, and apart from the data); a document and a database kept as separate copies (they drift). Affects. 9.2 The data dictionary.
ADR-004: Fixed lists are tables¶
Decision. Every closed list, including the country codes, is a reference table that fields link to. Free text is never used for a value that has a list. Reason. A list stored as a link makes a value that is not on the list impossible, and a code can be checked against a real country, not only against a pattern. Not chosen. A list typed into each field; a list inside a rule formula. Affects. 9.3 Reference data.
ADR-005: SQLite inside the application¶
Decision. The database is a SQLite file inside the VeeJay program, which is its only writer. The program's own screens edit it. Migrations use Alembic.
Reason. VeeJay is an application meant to be installed. An embedded database needs nothing installed and backs up by copying one file. SQLite can refuse bad values: it has CHECK, UNIQUE, STRICT columns, foreign keys, generated columns and triggers. With the program as the only writer, the one remaining weakness, that foreign keys must be switched on for each connection, is handled by opening the file the same way every time and by a test that opens it the wrong way.
Not chosen. A database server, which an application cannot ship with.
Cost. No separate database logins, so permissions live in the application. Several programs writing at once is not supported.
Affects. 9.4 The physical schema and 9.5 Migrations.
ADR-006: Every structural change is a numbered migration¶
Decision. The schema changes only by ordered, never-edited migration scripts, applied after a copy of the file is made. The database can always be rebuilt from empty. Reason. The history is exact, every copy of the database is the same, and any state can be reproduced. Affects. 9.5 Migrations.
ADR-007: A rule is not finished until a test breaks it¶
Decision. Each rule has a number and a test that tries the most tempting wrong value, as an insert, an update and a bulk import. A coverage check fails when a constraint, rule or test is unmatched. Reason. A rule that has never been seen to refuse anything is a hope. Affects. 9.6 Rules and tests.
ADR-008: Raw data lands in staging, facts live in the core¶
Decision. Data as it arrives is held in a loose staging area. A promotion step moves a row into the strict core only if it meets every rule. Reason. The raw playlist can be loaded in one batch without weakening the core tables, and nothing unidentified is ever counted as a fact. Affects. 9.4 The physical schema.
ADR-009: Origin country is a three-letter ISO code¶
Decision. An artist's origin country is the ISO 3166-1 alpha-3 code (USA, GBR, PRI), checked against the country table.
Reason. Three letters read more clearly than two. The check against a real list catches wrong codes that a pattern would pass.
Affects. Rule V-01.
ADR-010: Status fields depend on the kind of artist¶
Decision. Life status (Living, Deceased) applies only to a Person. Activity status (Active, Dissolved) applies only to a Group. Each is refused on the other kind. Reason. A group is not living or deceased, and a person is not dissolved. The wrong combination is a data error. Affects. Rules V-02 and V-03.
ADR-011: Every change is audited¶
Decision. Every update and delete in the core and research areas leaves a copy of the old row with its time. Reason. Nothing is changed or removed without a record that can undo it, and bad data can be traced to its origin. Affects. Rule V-17.