docs: move Phase 9 §9.1 from PLAN to COMPLETED

This commit is contained in:
daniel-c-harvey
2026-06-12 21:53:45 -04:00
parent 93dcc59814
commit 22f4939b24
2 changed files with 25 additions and 19 deletions
+25
View File
@@ -6,6 +6,31 @@ Newest entries at the top. Group by phase/wave header (mirroring `PLAN.md` / `CM
---
## Phase 9 — Release Medium Types
### 9.1 Wave 1 — Data model + migration
**Landed:** 2026-06-12 on dev.
- **What:** New `ReleaseMedium` enum (`Cut, Session, Mix`) in `DeepDrftModels/Enums/`. `ReleaseEntity` gains `ReleaseMedium Medium` (default `Cut`) plus 1:1 nav properties to two new metadata entities. New `SessionMetadata` (`HeroImageEntryKey`) and `MixMetadata` (`WaveformEntryKey`) entities, each 1:1 with `ReleaseEntity`. EF configurations + migration.
- **Why:** Every other wave reads this schema. The discriminator-plus-optional-table shape is the load-bearing decision of the phase; it must land first and land right.
- **Shape:**
- `ReleaseMedium` enum with `Cut = 0` (default — existing/migrated releases stay studio cuts with no discriminator data migration).
- `Medium` column on `releases`; `ReleaseConfiguration` documents the `ReleaseType`-only-for-`Cut` invariant *and* the named `CutMetadata`-rejected exception (see the phase intro above).
- `session_metadata` and `mix_metadata` tables, each with a unique FK to `releases` (1:1). `MixMetadata.WaveformEntryKey` is a vault entry key (resolved — see open question), not an inline blob.
- Migration is **additive only** — no data migration of existing rows beyond defaulting `Medium = Cut`. Lower risk than the Phase 8 normalization.
- **Prerequisite:** Phase 8 §8.0 normalization (`ReleaseEntity` exists) — already landed.
- **Acceptance criteria:**
- `ReleaseMedium` enum exists; `ReleaseEntity.Medium` defaults to `Cut`.
- `SessionMetadata` / `MixMetadata` entities + EF configs + migration applied; solution compiles and existing releases read back as `Cut`.
- The invariant is documented in `ReleaseConfiguration` (no DB constraint — a deliberate choice; EF supports check constraints, see the phase intro).
- **Open questions:**
- **Resolved — waveform storage:** vault blob + `WaveformEntryKey`. Settled by the server-side trigger design (9.2.B): the API computes and stores the datum vault-side; SQL holds only the entry key, so a JSON column never enters the flow. This wave adds only the SQL column — the vault write rides the existing vault abstraction server-side.
**Completion note:** `ReleaseMedium` enum with `Cut`, `Session`, `Mix` values implemented in `DeepDrftModels/Enums/`. `ReleaseEntity` extended with `Medium` column (default `Cut`) and 1:1 nav properties to `SessionMetadata` and `MixMetadata`. New entities added with their EF configurations. Additive migration `AddReleaseMedium` authored and applied. `ReleaseDto` updated with `Medium` field and nested metadata DTOs. `TrackConverter` updated. Solution builds; existing releases read back as `Cut`; acceptance criteria met.
---
## Phase 8 — CMS Track Browser
### 8.6 "Music through Every Medium" home page section
-19
View File
@@ -165,25 +165,6 @@ Sequenced as four waves. Wave 1 is a prerequisite for everything; within Waves 2
---
### 9.1 Wave 1 — Data model + migration `[prerequisite gate]`
- **What:** New `ReleaseMedium` enum (`Cut, Session, Mix`) in `DeepDrftModels/Enums/`. `ReleaseEntity` gains `ReleaseMedium Medium` (default `Cut`) plus 1:1 nav properties to two new metadata entities. New `SessionMetadata` (`HeroImageEntryKey`) and `MixMetadata` (`WaveformEntryKey`) entities, each 1:1 with `ReleaseEntity`. EF configurations + migration.
- **Why:** Every other wave reads this schema. The discriminator-plus-optional-table shape is the load-bearing decision of the phase; it must land first and land right.
- **Shape:**
- `ReleaseMedium` enum with `Cut = 0` (default — existing/migrated releases stay studio cuts with no discriminator data migration).
- `Medium` column on `releases`; `ReleaseConfiguration` documents the `ReleaseType`-only-for-`Cut` invariant *and* the named `CutMetadata`-rejected exception (see the phase intro above).
- `session_metadata` and `mix_metadata` tables, each with a unique FK to `releases` (1:1). `MixMetadata.WaveformEntryKey` is a vault entry key (resolved — see open question), not an inline blob.
- Migration is **additive only** — no data migration of existing rows beyond defaulting `Medium = Cut`. Lower risk than the Phase 8 normalization.
- **Prerequisite:** Phase 8 §8.0 normalization (`ReleaseEntity` exists) — already landed.
- **Acceptance criteria:**
- `ReleaseMedium` enum exists; `ReleaseEntity.Medium` defaults to `Cut`.
- `SessionMetadata` / `MixMetadata` entities + EF configs + migration applied; solution compiles and existing releases read back as `Cut`.
- The invariant is documented in `ReleaseConfiguration` (no DB constraint — a deliberate choice; EF supports check constraints, see the phase intro).
- **Open questions:**
- **Resolved — waveform storage:** vault blob + `WaveformEntryKey`. Settled by the server-side trigger design (9.2.B): the API computes and stores the datum vault-side; SQL holds only the entry key, so a JSON column never enters the flow. This wave adds only the SQL column — the vault write rides the existing vault abstraction server-side.
---
### 9.2 Wave 2 — API: medium reads + metadata uploads
A new `api/release` controller — the medium unit is the *release*, not the track, so medium browse and metadata uploads are release-cardinal rather than bolted onto `api/track/page`.