Seed the two legacy cross-reference tables - #2392
Conversation
Schema constraint shape reportno schema or migration changes detected in this PR |
Not ready: the new CI gate immediately caught a real failureMarking this draft. The workflow change works -- and the first thing it did was fail. Before the gate fix, It failed on both attempts in the same run, so it is not a flake in the ordinary sense -- though the assertion's own comment records observed values of 4-6 against a ceiling of 7, so its headroom is one unit. What is and is not establishedThe counter reads So the mechanism is not obvious, and I have not established one. Two candidates worth checking, neither confirmed:
Docker was unavailable on the machine this was written on, so the failure could not be reproduced locally to distinguish them. What that means for this PRThe gate change is doing its job: this failure was reachable from
Not retrying CI -- the failure is deterministic and retries would only spend minutes. |
Unrelated to this PR's subject, and pre-existing on main: 9494e31 left plans/mu-ziq-replacement-char-remediation.md with emphasis markers prettier rewrites, so format:check has been failing on main since. The change here is entirely prettier --write output, asterisk emphasis to underscore, no prose touched. It went unnoticed for the same reason this PR exists. That commit touched only plans/, which no paths-filter entry covers, so lint-and-typecheck never ran on it. This PR's workflow edit is what pulled the job back in and surfaced it. Fixed here rather than split out because format:check gates lint-and-typecheck, which gates Integration-Tests -- the job this PR adds the seed to. Leaving it red would leave the seed unexecuted, which is the thing being fixed.
A change to seed_db.sql or init-db.mjs executed neither file in CI. Both are in the db-init filter, but db-init gates only the migration dry-run, which applies migrations and stops short of the seed. The integration suite -- the one job that builds a database from this seed and asserts against it -- keys off apps, jobs, shared and tests, none of which a dev_env change matches. Observed on a branch that added rows to seed_db.sql and two counts to init-db.mjs: the run went green with Integration-Tests reporting success in fourteen seconds, having executed neither file. With db-init added to the gate, the same branch ran the suite for two and a half minutes and failed a spec. That failure is real and predates this change being able to see it. The failure this now catches is a seed that does not apply, or that applies different rows than a spec expects, which otherwise surfaces at the next developer's first run against a database nobody had rebuilt yet.
artist_crossreference and artist_library_crossreference were empty in every dev database while carrying rows in production. Nothing local exercised their read path, and the screens that surface them showed an empty state indistinguishable from a failed fetch, so a broken query would have looked exactly like correct behaviour. The relationships seeded here are real, and so is the filing situation they record. Coltrane played tenor on Kind of Blue, which the seed already files under Davis; the Ellington and Alice Coltrane pairings are the canonical case of a release credited to one artist and filed under another, which is what artist_library_crossreference exists to express. Miles Davis was already seeded, so the artist cross-references reach an existing fixture rather than standing in their own island. Ids are resolved by name rather than written as literals. Artist ids come from a sequence, so any row added above shifts every literal below it, and the failure would be silent -- a cross-reference would attach to whichever artist happened to land on that id. That resolution has a cost the literal ids did not: on a second run, a name would match both the original row and the duplicate the same run had just inserted. Every insert here is therefore guarded, with NOT EXISTS where the table has no unique constraint to conflict on and ON CONFLICT DO NOTHING where it does. Verified by running the block three times against a fresh database and confirming the counts do not move. The seed verification now prints both cross-reference counts alongside the existing ones, so an empty table is visible at seed time rather than at the point some screen renders nothing.
97e4be4 to
0cb3e9c
Compare
Closes #2391
artist_crossreferenceandartist_library_crossreferencewere empty in every dev database while carrying rows in production. Nothing local exercised their read path, and a consumer rendering "there are no cross-references" emitted that claim unconditionally -- a broken query looked exactly like correct behaviour.What is seeded
Five artist cross-references and two release cross-references, over three new artists (John Coltrane, Alice Coltrane, Duke Ellington) and one new library row.
The relationships are real, and so is the filing situation they record. Coltrane played tenor on
Kind of Blue, which the seed already files under Davis; the Ellington and Alice Coltrane pairings are the canonical case of a release credited to one artist and filed under another, which is whatartist_library_crossreferenceexists to express. Miles Davis was already a fixture, so the artist cross-references reach existing seeded data rather than forming an island.Ids are resolved by name
Artist ids come from a sequence. A literal id breaks the moment a row is added above it, and breaks silently -- the cross-reference attaches to whichever artist landed on that id, which still satisfies every foreign key.
That resolution has a cost the literal ids did not: on a re-run a name matches both the original row and the duplicate the same run just inserted. Every insert is therefore guarded --
NOT EXISTSwhere the table has no unique constraint to conflict on (artists,library),ON CONFLICT DO NOTHINGwhere it does.Verification
Docker was unavailable locally, so the full
init-db.mjspipeline was not run here; CI's integration job is the first end-to-end execution.What was verified: the new block was extracted verbatim from
seed_db.sqland executed against a PostgreSQL 18.6 database built with the same constraints the real schema declares (artist_genre_key,artist_crossref_source_target,library_id_artist_id, and both foreign keys). It applied cleanly and produced the expected 5 and 2 rows with the name resolution linking correctly to the pre-existing Miles Davis fixture.Idempotency was verified by running the block three times against a fresh database: all three runs succeeded and the counts did not move (artists 4, library 2, genre xrefs 3, artist xrefs 5, release xrefs 2). An earlier revision failed on the second run -- that is what prompted the guards.
Placement
The block sits before the
library.artist_namebackfill at the end of the file, so the new library row is picked up by it. Placed after, the row would have carried a nullartist_nameand been invisible to both the tsvector and trigram search paths.Also
Seed verification now prints both cross-reference counts alongside the existing ones, so an empty table is visible at seed time rather than at the point some screen renders nothing.