Add track_position column to flowsheet (E6-4, #835)#932
Merged
Conversation
Adds a nullable TEXT column for the Discogs `release_track.position` value (vinyl side or multi-disc prefix like "A1", "B3", "1-12") so the dj-site flowsheet picker can persist the selected track. Free-text DJ entries, tubafrenzy mirror rows, and every pre-existing row stay NULL — the column has no constraint, no default, and no backfill. Schema, migration 0076, FSEntryFieldsRaw select, FSEntryRaw type, transformToIFSEntry materialization, and transformToV2 projection all move in lockstep so the V2 read shape carries the value end-to-end. Project-32 compatibility: BS#891 (C1 metadata_status enum) and BS#897 (D1 album_metadata table) also touch the flowsheet area but target different columns and tables; no schema collision. D4's eventual drop of album-level cols does not include this per-entry column. Closes #835.
Schema constraint shape reportno new constraints detected in this diff (uniqueIndex, .unique(), SET NOT NULL, CHECK, FK) |
This was referenced May 18, 2026
jakebromberg
added a commit
that referenced
this pull request
May 18, 2026
BS#835 / PR #932 shipped the schema, the read projection, and the V2 wire shape for `flowsheet.track_position`, but the V1 `POST /flowsheet` and `PATCH /flowsheet/entries/:id` controllers in apps/backend/controllers/flowsheet.controller.ts didn't accept the field on the request body. Without this, the dj-site flowsheet picker (E6-6, dj-site#501) can send `track_position` and BS silently drops it. Three edits: - `FSEntryRequestBody.track_position?: string | null` and `UpdateRequestBody.track_position?: string | null` declared. - `addEntry` album_id branch forwards `body.track_position ?? null` into `NewFSEntry` explicitly (the explicit assembly didn't spread `body`). - The free-form branch already propagates via the existing `...body` spread, so the type widening alone is the entire wiring there. The message-only branch (talkset / breakpoint / PSA) deliberately does NOT carry `track_position` — that column is `entry_type='track'`-only by design. A regression test pins this. `updateEntry` service does a straight `db.update(flowsheet).set(data)`, so widening `UpdateRequestBody` is the only wiring needed. Tests: - tests/unit/controllers/flowsheet.controller.test.ts: 3 new addEntry cases + 1 updateEntry case pinning the forwarding contract; the message-branch negative case prevents future drift. - tests/integration/flowsheet.spec.js: round-trip POST then read for both the album_id branch ("A1") and the free-form branch ("B2"), exercising real PG + transformToV2's projection. Local CI: typecheck, lint (0 errors), format:check, test:unit (1937 passing). Closes #943.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
flowsheet.track_position(TEXT, nullable) so the dj-site flowsheet picker (E6-6, BS#836's downstream consumer) can persist the Discogsrelease_track.positionof the selected track. NULL is the natural value for legacy rows, tubafrenzy mirror rows, and free-text DJ entries — no constraint, no default, no backfill.The change rides through every layer that materializes a flowsheet entry: schema, migration 0076,
FSEntryFieldsRawSQL select,FSEntryRawtype,transformToIFSEntrymaterialization, andtransformToV2projection. V2 reads now carrytrack_positionend-to-end.Wire-shape decision (TEXT-not-INT) lives in WXYC/wxyc-shared#111 / #134 — Discogs positions are free-form strings (
"A1","B3","1-12"), not integers.Why this is safe
ALTER TABLE ADD COLUMN ... NULLis metadata-only on PostgreSQL 11+ regardless of the 2.6M-row table size — same pattern as 0069'smetadata_attempt_ataddition (Migration 0053 wedge: split DDL from backfill, harden migration runner #511's lesson).-- @no-precondition-neededrationale captured in the migration comment block.Project #32 compatibility check
Verified non-collision against the two open migrations in Post-launch service hardening:
metadata_statusenum onflowsheetalbum_metadatatableD4's eventual drop of 10 album-level metadata columns is at least a month out and does not include this per-entry column.
Test plan
transformToV2projectingtrack_position(populated + NULL); now greennpm run typecheckclean across all workspacesnpm run lint0 errors (393 pre-existing warnings unchanged)npm run format:checkcleannpm run test:unit— 1919 tests passnode scripts/validate-migrations.mjs— 75 entries, 0 errors, 2 pre-existing warningsnpm run drizzle:freeze-hashes— applied-hashes.json updated for 0076Closes #835.