Phase 9 Wave 1: add ReleaseMedium discriminator + Session/Mix metadata
Add ReleaseMedium enum (Cut/Session/Mix) and two 1:1 satellite entities (SessionMetadata, MixMetadata) with EF configs and an additive migration. ReleaseDto.ReleaseType is now nullable, nulled for non-Cut at the converter. Existing releases default to Cut via column default; no data migration.
This commit is contained in:
@@ -42,6 +42,18 @@ public class ReleaseConfiguration : BaseEntityConfiguration<ReleaseEntity>
|
||||
.HasMaxLength(500)
|
||||
.HasColumnName("image_path");
|
||||
|
||||
// ReleaseType is meaningful ONLY when Medium == Cut. It is the Cut medium's discriminator
|
||||
// data and lives on the base table by deliberate, named exception:
|
||||
// A CutMetadata satellite (mirroring SessionMetadata/MixMetadata) was considered and
|
||||
// rejected. ReleaseType is read on every card of the /cuts browse — the highest-traffic
|
||||
// read in the system. Moving it to a satellite would put a join on that hot path. So it
|
||||
// stays here. Future media MUST NOT copy this pattern: the default is a satellite metadata
|
||||
// table; this is the one allowed exception, justified solely by the /cuts read volume.
|
||||
//
|
||||
// The "ReleaseType only for Cut" invariant is advisory — enforced at the service layer and
|
||||
// surfaced via the nullable ReleaseDto.ReleaseType (nulled for non-Cut at the converter).
|
||||
// It is NOT a DB check constraint by choice, not necessity: EF supports HasCheckConstraint,
|
||||
// but the invariant is advisory and we keep the schema free of it.
|
||||
builder.Property(e => e.ReleaseType)
|
||||
.IsRequired()
|
||||
.HasConversion<string>() // Store as readable string, not int ordinal
|
||||
@@ -49,6 +61,13 @@ public class ReleaseConfiguration : BaseEntityConfiguration<ReleaseEntity>
|
||||
.HasColumnName("release_type")
|
||||
.HasDefaultValue(ReleaseType.Single);
|
||||
|
||||
builder.Property(e => e.Medium)
|
||||
.IsRequired()
|
||||
.HasConversion<string>() // Store as readable string, not int ordinal
|
||||
.HasMaxLength(20)
|
||||
.HasColumnName("medium")
|
||||
.HasDefaultValue(ReleaseMedium.Cut); // Existing rows migrate to Cut with no data migration.
|
||||
|
||||
builder.Property(e => e.CreatedByUserId)
|
||||
.HasColumnName("created_by_user_id");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user