Skip to content

Accept track_position in POST/PATCH flowsheet controllers (BS#943)#945

Merged
jakebromberg merged 2 commits into
mainfrom
bs-943-track-position-controllers
May 18, 2026
Merged

Accept track_position in POST/PATCH flowsheet controllers (BS#943)#945
jakebromberg merged 2 commits into
mainfrom
bs-943-track-position-controllers

Conversation

@jakebromberg
Copy link
Copy Markdown
Member

Summary

Wires the V1 POST /flowsheet and PATCH /flowsheet/entries/:id controllers to accept track_position on the request body and forward it through to the DB. BS#835 / PR #932 shipped the column, the read projection, and the V2 wire shape — but the controllers were silently dropping the field. Without this wiring the dj-site flowsheet picker (E6-6, WXYC/dj-site#501) would write track_position over the wire and the column would stay NULL forever.

Changes

Layer Edit
FSEntryRequestBody track_position?: string | null
UpdateRequestBody track_position?: string | null
addEntry album_id branch explicit track_position: body.track_position ?? null into NewFSEntry
addEntry free-form branch no code change — the existing ...body spread propagates once the type allows it
addEntry message-only branch no change (track_position is entry_type='track'-only by design; regression test pins this)
updateEntry no code change — db.update(flowsheet).set(data) already passes any field on the type-widened data through

Test plan

  • 3 new unit cases on addEntry:
    • album_id branch — track_position lands in the addTrack call
    • free-form branch — same
    • message-only branch — track_position does NOT land (negative case)
  • 1 new unit case on updateEntry — forwards track_position via the service
  • 2 new integration tests on POST /flowsheet:
    • album_id branch round-trip: track_position: 'A1' written and read back
    • free-form branch round-trip: track_position: 'B2' written and read back
  • npm run typecheck clean
  • npm run lint — 0 errors (396 pre-existing warnings unchanged)
  • npm run format:check clean
  • npm run test:unit — 1937 passing (151 suites)

Why this is split from BS#835

PR #932 was scoped to the schema + read projection. Splitting the controller wiring into its own PR keeps the storage change reviewable on its own, lets the controller wiring land closer to dj-site#501 (the actual writer), and means a hypothetical revert of #932 wouldn't snag this on the way out.

Project-32 compatibility

Same posture as BS#835: this PR doesn't touch apps/backend/services/metadata/, apps/backend/services/lml/, or any of the project-#32 surfaces. Controller-layer-only.

Closes #943.

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.
Review feedback on PR #945:

1. apps/backend/app.yaml: the V1 wire contract changes — POST /flowsheet
   accepts `track_position` and PATCH /flowsheet updates it — but the
   swagger schema didn't reflect that. Add `track_position` (string,
   nullable) to the `FlowsheetEntry` component (used by POST) and to the
   inline PATCH request schema.

2. tests/integration/flowsheet.spec.js: the unit test for `updateEntry`
   mocks the service. Add a round-trip integration test that POSTs a row
   with `track_position: 'A1'`, PATCHes it to 'B2', then clears it to
   `null`, asserting the PATCH response each time. This pins the actual
   UPDATE wire path through Postgres (Drizzle `.update(...).set(data)
   .returning()`) and prevents a future regression that drops the field
   on the write side.
@jakebromberg jakebromberg merged commit ee392e3 into main May 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

E6-4 follow-up: accept track_position in POST/PATCH flowsheet controllers

1 participant