You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Alembic migration:alembic revision --autogenerate -m "add_eligible_cast_and_session_casting" — include data migration: each Character.played_by → CharacterEligibleCast(priority=0). Also update SessionStartController from #1112 to seed SessionCasting rows for all characters using priority-0 cast when a session is started/created.
Replace entire list. Body: {cast_ids: [ordered]}. Syncs Character.played_by to cast_ids[0].
GET
/api/v1/show/sessions/{id}/casting
READ
All SessionCasting rows for a session
PATCH
/api/v1/show/sessions/{id}/casting
WRITE
Bulk-update. Body: [{character_id, cast_id}]. 409 if session already started. Validates cast_id is in eligible pool.
Frontend changes (client-v3/)
New route:show-config-casting → ConfigCasting.vue
New nav item in ShowConfigView.vue (between Characters and Mics): Casting
New components (components/show/config/casting/):
ConfigCasting.vue — page; "Preparing for:" session picker; contains CastingMatrix.vue; shows MicPlanStaleBanner.vue when active session has any non-principal cast
CastingMatrix.vue — horizontal-scroll table; sticky "Character" + "Eligible Cast" columns; one column per session; active column green-tinted; cover cells amber-tinted; click cell → CastPickerDropdown.vue
CastPickerDropdown.vue — eligible cast list with PRINCIPAL badge; "↺ Reset to principal"; "+ Add cast to eligible pool…"
EligibleCastChips.vue — chip per eligible cast member; × to remove non-principals; "+ Cover" add button
MicPlanStaleBanner.vue (stub) — amber bar: "Casting changes may require a mic re-run. Review on Mics →"
ConfigSessions.vue (from #1112) — add "Cast" action button → navigates to casting page for that session; extend start-session confirmation to show full cast roster table.
Summary
Characters currently have a single
played_bylink to a cast member. This adds:Part 2 of 3 for issue #792. Depends on #1112 (session scheduling).
Backend changes
New model
CharacterEligibleCast(server/models/show.py):Add
eligible_castrelationship toCharacter(ordered by priority).New model
SessionCasting(server/models/session.py):Add
castingrelationship toShowSession.Alembic migration:
alembic revision --autogenerate -m "add_eligible_cast_and_session_casting"— include data migration: eachCharacter.played_by→CharacterEligibleCast(priority=0). Also updateSessionStartControllerfrom #1112 to seedSessionCastingrows for all characters using priority-0 cast when a session is started/created.Schema updates:
CharacterSchema→ addeligible_cast;ShowSessionSchema→ addcasting; newSessionCastingSchema,CharacterEligibleCastSchema.New endpoints:
GET/api/v1/show/characters/{id}/eligible-castPUT/api/v1/show/characters/{id}/eligible-cast{cast_ids: [ordered]}. SyncsCharacter.played_bytocast_ids[0].GET/api/v1/show/sessions/{id}/castingSessionCastingrows for a sessionPATCH/api/v1/show/sessions/{id}/casting[{character_id, cast_id}]. 409 if session already started. Validates cast_id is in eligible pool.Frontend changes (
client-v3/)New route:
show-config-casting→ConfigCasting.vueNew nav item in
ShowConfigView.vue(between Characters and Mics): CastingNew components (
components/show/config/casting/):ConfigCasting.vue— page; "Preparing for:" session picker; containsCastingMatrix.vue; showsMicPlanStaleBanner.vuewhen active session has any non-principal castCastingMatrix.vue— horizontal-scroll table; sticky "Character" + "Eligible Cast" columns; one column per session; active column green-tinted; cover cells amber-tinted; click cell →CastPickerDropdown.vueCastPickerDropdown.vue— eligible cast list with PRINCIPAL badge; "↺ Reset to principal"; "+ Add cast to eligible pool…"EligibleCastChips.vue— chip per eligible cast member; × to remove non-principals; "+ Cover" add buttonMicPlanStaleBanner.vue(stub) — amber bar: "Casting changes may require a mic re-run. Review on Mics →"ConfigCharacters.vue— add "Eligible Cast" column showingEligibleCastChips; eligible cast section in edit modal.ConfigSessions.vue(from #1112) — add "Cast" action button → navigates to casting page for that session; extend start-session confirmation to show full cast roster table.stores/show.tsadditions:sessionCasting: Record<string, SessionCasting[]>,characterEligibleCast: Record<string, EligibleCast[]>getSessionCasting,updateSessionCasting,getCharacterEligibleCast,updateCharacterEligibleCastcastDiffForSession(sessionId): CastDiff[]— compares session casting vs each character's priority-0 castNew
src/types/api/casting.ts:E2E tests
New
client-v3/e2e/tests/12b-show-config-casting.spec.ts:Update
12-show-config-sessions.spec.ts:Notes
Character.played_byis kept for backward compatibility;PUT /eligible-castkeeps it in sync with priority-0 cast.start_date_timeis set on a session,PATCH /sessions/{id}/castingreturns 409. Frontend disables cell editing for started/completed sessions.Verification
pytest— new tests for eligible cast and session casting endpointsnpm run typecheck+npm run lintnpm run test:e2e— full suite