--- created: '2026-05-17' path: Sources/Dev project: pbs-hub-scene-management tags: - pbs - pbs-hub - flask - mysql - video-production - scenes - ui - sortablejs - tablet type: project-plan --- ## Goal Extend pbs-hub (the merged successor to pbs-video-manager + pbs-api) to support the full video production lifecycle — not just the post-shoot/publish work the tool covers today. Add pre-production authoring surfaces (outline, treatment, scenes with per-scene scripts), a structured scene/shot list model, and a tablet-friendly Present Mode for shoot day that solves the specific pain of *forgetting shots while shooting*. The original animating idea of pbs-hub was a sidecar to Trello — Trello holds the project board, the Hub holds the depth Trello can't (file management, ffmpeg, description building). This extension stays true to that philosophy: Trello can't model "intro scene has three shots, two done, one not." The Hub adds that depth, in the same pattern. CLI is untouched. Existing post-shoot surfaces (Overview, Publish Check, Desc Build) are untouched. Project Detail navigation shifts from tabs to a persistent card rail (C2 pattern). --- ## Locked Decisions ### Schema (all new tables → `pbs_automation` database) **`Project` (extended):** - `outline` TEXT, nullable — rough story scratch - `treatment` TEXT, nullable — narrative prose, scene-by-scene **`ProjectMetadata` (new):** - `id` PK, `project_id` FK → `projects.id` - `key` VARCHAR, `value` TEXT, `sort_order` INT - Generic key/value to allow new metadata fields via Settings CRUD without schema migrations **`ProjectMetadataField` (new, Settings-managed):** - `id` PK, `key` VARCHAR, `label` VARCHAR, `sort_order` INT - Seeded: `logline`, `working_title`, `tagline` **`Scene` (new):** - `id` PK, `project_id` FK → `projects.id`, `sort_order` INT - `title`, `purpose`, `in_shot`, `background` (text fields, freeform) - `script` TEXT — per-scene script (the narrative lives at scene level, not project level) **`SceneItem` (new — Path B, separate from `ChecklistItem`):** - `id` PK, `scene_id` FK → `scenes.id`, `sort_order` INT - `label` VARCHAR - `item_type` ENUM: `shot`, `reminder` - `is_complete` BOOLEAN, `created_at` TIMESTAMP **`DefaultScene` (new):** - Template scenes seeded on `pbs init`. Same shape as `Scene` minus `project_id`. **`DefaultSceneItem` (new):** - Template scene items. `default_scene_id` FK → `default_scenes.id`. Same shape as `SceneItem` minus `scene_id` and `is_complete`. **Path B rationale:** `ChecklistItem.category` is workflow-stage-shaped (export/wordpress/youtube/instagram/email). Scene items don't have a workflow-stage equivalent. Forcing them into `ChecklistItem` would either compromise the category column's clear meaning or create silent-leak bugs (every existing `ChecklistItem` query becomes a future bug site). The duplication cost is bounded: one new model + ~60-80 LOC service module. The new code lives next door, doesn't touch the working publish-check path, and can't poison it. **`ChecklistItem` and `DefaultChecklistItem` are UNCHANGED.** ### Status workflow `Project.status` stays free VARCHAR. Adds: ``` planned → scripted → raw → editing → exported → final → published → archived ``` All transitions manual. Coexists with reel-flavored statuses (`draft / ready / live-matched / live-needs-review`) — disambiguated by `project_types.name`. ### Terminology - **Scene list** — new pre-production surface (scenes + scene items) - **Checklist** — existing publish-pipeline surface (unchanged) - **Outline / Treatment / Script** — industry-standard authoring vocabulary - **Scene / Shot / Shot list** — industry-standard production vocabulary - **Item types** — `shot` (visual capture) and `reminder` (non-shot task) ### UI: Persistent Card Rail + Canvas (C2 pattern) Project Detail tabs are replaced by a persistent left rail of live status cards, with the selected surface filling the canvas. Rail collapses on tablet for Present Mode. **Rail card order (lifecycle):** ``` Overview / Outline / Treatment / Scenes / Publish Check / Desc Build ``` **Each rail card shows live status**, not just a label: - Overview — project title, status badge, last activity - Outline — first line preview or "empty" - Treatment — paragraph count, last edit timestamp - Scenes — scene count + mini completion indicator (color-coded per completion state) - Publish Check — X of Y complete with progress bar - Desc Build — drafted / not started / complete **Surfaces:** - **Overview** — existing, unchanged - **Outline** — single freeform markdown field, standard editor - **Treatment** — split-pane: treatment prose on left, running scene title list on right with "Add scene" button and drag-to-reorder. Right pane is a live view of `Scene` records; edits sync with the Scenes surface - **Scenes** — two modes: - *Edit Mode* (default): full CRUD on scenes (briefing fields, per-scene script) and scene items (label, type, complete, reorder) - *Present Mode* (shoot day): scene strip across top, color-coded per scene completion (gray = empty, red = none complete, amber = partial, green = all complete); focused scene shows briefing fields (read-only) + shot list split above/below the line + X of Y indicator + inline "Add item"; non-sequential scene navigation; shows project title + date for on-camera recording context - **Publish Check** — existing, unchanged - **Desc Build** — existing, unchanged **Drag-drop:** SortableJS (CDN, touch-friendly). Used for scene reordering (in Treatment right pane and Scenes Edit Mode) and item reordering (in Scenes Edit Mode). **Pre-shoot handling:** Pre-shoot is the first scene of every project, populated with `reminder`-type items. No separate model or surface. Defaults seeded via `DefaultScene` + `DefaultSceneItem` on `pbs init`. **Scene completion derivation (not stored):** - Empty scene (no items) → gray - Items exist, none complete → red - Partial completion → amber - All complete → green Above/below-the-line in the item list driven by `is_complete`. Single `sort_order` drives both zones. Un-check pops item back above the line naturally. New items added mid-shoot land at the end of the above-the-line group. ### Tests Bootstrap pytest scaffold (pyproject section, `conftest.py`, in-memory SQLite fixture) as part of this work. Write tests for the new code: scenes model, scene items, completion derivation, migration smoke tests. Do not backfill tests for existing untested code. ### Deploy Lovebug builds and tests on the dev environment, stops short of deploy. Travis runs deploy via the `wordpress-install` Ansible repo (`wp-i`) to staging first, then production. Pre-deployment verification: confirm Phase 5 baseline is live on prod MySQL before this migration runs: ```bash mysql -u pbs_api -p pbs_automation -e 'SHOW TABLES' ``` If `projects`, `project_types`, and `platform_posts` are present, prod is cut over and this migration adds on top. If not, Phase 5 baseline lands first. ### CLI No CLI changes. No `sync_checklist_items()` changes — Path B isolates scene items in their own table, so the existing sync mechanism is untouched. Scene-aware sync, if ever needed, is a separate endpoint with its own shape (future enhancement, not v1). --- ## Open Items These need verification or input before or during implementation: - [ ] **Production MySQL state** — confirm Phase 5 baseline tables (`projects`, `project_types`, `platform_posts`) are live on prod before deploying this migration. If not, reconcile first. - [ ] **`sql/create_tables.sql` cleanup** — add a one-line note marking the database housing question (was `pbs_automation` or `pbs_content_hub`?) as **RESOLVED → `pbs_automation`**. Saves the next reader from hitting the same TBD. - [ ] **Default scene/item seed content** — implementation agent picks reasonable defaults for `DefaultScene` + `DefaultSceneItem` (e.g., a "Prep" scene with charge-batteries / format-cards reminders). Fully editable via CRUD after init. - [ ] **Migration files location** — recommend `sql/migrations/NNN_.sql` with numbered files since there's no Alembic. This work adds the first such files; future schema changes follow the pattern. --- ## Phases ### Phase 1 — Schema migration One numbered migration file in `sql/migrations/` that adds all new tables and columns in a single transaction. Targets `pbs_automation` database. - [ ] `ALTER TABLE projects ADD COLUMN outline TEXT DEFAULT NULL` - [ ] `ALTER TABLE projects ADD COLUMN treatment TEXT DEFAULT NULL` - [ ] `CREATE TABLE project_metadata (...)` - [ ] `CREATE TABLE project_metadata_fields (...)` + seed `logline`, `working_title`, `tagline` - [ ] `CREATE TABLE scenes (...)` - [ ] `CREATE TABLE scene_items (...)` - [ ] `CREATE TABLE default_scenes (...)` + seed reasonable defaults - [ ] `CREATE TABLE default_scene_items (...)` + seed reasonable defaults - [ ] Bootstrap pytest scaffold + first migration smoke test - [ ] Update `sql/create_tables.sql` to match (so fresh deploys are consistent) ### Phase 2 — Rail framework Replace the existing 3-tab implementation in `project_detail.html` with the persistent card rail + canvas pattern. Existing surfaces (Overview, Publish Check, Desc Build) become canvas-rendered with placeholder rail cards. - [ ] Rail component (Jinja partial), styled with Tailwind - [ ] Rail card with live-status props (label, status indicator, click handler) - [ ] Canvas slot in Project Detail layout - [ ] Wire existing surfaces (Overview / Publish Check / Desc Build) into canvas - [ ] Active card visual treatment - [ ] Rail collapse mechanism (for Present Mode later) - [ ] Verify `/pbscontenthub` URL prefix awareness in new routes ### Phase 3 — Outline surface (end-to-end) Simplest of the new surfaces. Validates the rail-card live-status pattern with real data. - [ ] Service method to read/write `Project.outline` - [ ] API endpoint - [ ] Route + template (single textarea, autosave or save button) - [ ] Rail card shows first-line preview or "empty" - [ ] Tests ### Phase 4 — Treatment surface (end-to-end) Split-pane layout. Right pane is a live `Scene` title list with reorder + "Add scene." Requires `Scene` CRUD basics in place but not the full Scenes Edit Mode. - [ ] Scene model + basic service (create, read, update title, delete, reorder) - [ ] API endpoints for scene list management - [ ] Treatment route + split-pane template - [ ] SortableJS integration for scene reorder in right pane - [ ] Rail card shows paragraph count + last edit timestamp - [ ] Tests ### Phase 5 — Scenes surface (Edit Mode first) Build out full scene CRUD with briefing fields, per-scene script, and scene items (the scene list). Edit Mode only — no Present Mode yet. - [ ] Scene briefing fields editor (purpose, in_shot, background) - [ ] Per-scene script editor (textarea, autosave) - [ ] SceneItem service + API endpoints (CRUD, toggle, reorder, set type) - [ ] Scene Edit Mode template — scene selector, briefing form, script editor, item list with above/below-the-line split - [ ] Item type indicators (shot vs reminder, visually distinguished) - [ ] Add/remove items inline - [ ] SortableJS for item reorder - [ ] Rail card shows scene count + completion summary - [ ] Tests ### Phase 6 — Scenes surface (Present Mode) Tablet-optimized shoot-day view. Layered on top of the Edit Mode infrastructure. - [ ] Mode toggle ("Present" button in Edit Mode, "Edit" button / back in Present Mode) - [ ] Scene strip component — horizontal banner of color-coded chips (gray/red/amber/green per scene completion state), 44px+ tap targets, horizontal scroll if needed - [ ] Active chip treatment (border or background accent) - [ ] Focused scene view — project title + date header, briefing fields (read-only), item list with above/below-the-line, X of Y indicator - [ ] Inline "Add item" on focused scene - [ ] Item toggle works directly in Present Mode (taps the action, no mode switch) - [ ] Rail collapses on Present Mode entry - [ ] Tests ### Phase 7 — Metadata fields Project metadata key/value system with Settings CRUD for adding new fields. - [ ] ProjectMetadata service + API - [ ] ProjectMetadataField management in Settings - [ ] Metadata display + edit on Overview surface (or wherever fits best — implementation call) - [ ] Tests ### Phase 8 — Status workflow Small, slots anywhere after schema is live. - [ ] Add `planned` and `scripted` to status options - [ ] Status dropdown / picker UI on Overview - [ ] Document status semantics (planned = idea, scripted = ready to shoot, raw = footage exists) --- ## Notes ### Cross-references - **Existing codebase:** `pbs-video-manager` (internally branded "PBS Hub"), at `/opt/projects/pbs/pbs-video-manager`, git remote `git-real-projects-pvm:trucktrav/pbs-video-manager.git`, branch `master` - **Phase 5 architecture:** `content-hub-phase5-architecture` - **Phase 5 schema:** `content-hub-database-schema` - **Phase 5 planning:** `content-hub-phase5-planning` - **Original master plan:** `instagram-automation-content-hub-plan` ### Design philosophy notes - **Sidecar to Trello philosophy preserved.** Trello is the project board, the Hub is where the work lives. New pre-production surfaces (outline, treatment, scenes, scene list) are *more work that lives in the Hub* — same philosophy, more depth. Not a different pattern grafted on. - **Custom is appropriate.** Off-the-shelf tools can't do "scene strip color-coded by completion across multiple scenes during a tablet-on-the-counter shoot." That's why this exists. The customization solves a specific pain (forgetting shots) that Trello, Notion, etc. can't. - **Function over polish for v1.** Visual polish ("modern and sexy") is deferred to a follow-on project. Tablet-friendly drag-drop is the one place where polish and function overlap — bad drag-drop on a tablet is bad function. SortableJS handles that. ### Flagged for plan readers - **`platform_posts` n8n lookup chain unaffected.** The comment-reply automation path (`platform_posts → projects → pbs_recipes`) is untouched. Schema additions are purely additive to `projects`. No risk to existing automation. - **Status vocabulary coexistence.** `projects.status` holds both reel-flavored values (`draft / ready / live-matched / live-needs-review`) and video-flavored values (`planned → scripted → ... → archived`). Disambiguated by `project_types.name`. The eventual status-as-lookup-table refactor (when Trello integration lands) needs to accommodate both. - **Rail vs. intra-page filter chips.** Project Detail now uses the rail nav. Library/Settings keep their existing filter chip pattern (different metaphor, both stay). Future polish pass may unify them — flagged below. ### Out of scope (deferred / future) - **Auto-generation of scenes from treatment** (structured parsing of treatment headings into Scene records). Manual handoff for v1. - **Take tracking / version notes** (the active "clapper" with per-take metadata). - **Quick-action affordances on rail cards** (e.g., one-tap to Present Mode from the Scenes card without entering Edit Mode first). - **Visual polish pass.** Typography, motion, refined cards, dark mode, color-change animations on scene strip chips, progress dots inside chips, etc. Its own future project. - **Jinja macro extraction.** Status pill, card, badge components. Done as part of the polish pass, coherently across old and new surfaces. - **Rail vs. filter chip pattern unification.** Done as part of the polish pass. - **Inline briefing editing in Present Mode.** v1 is read-only in Present Mode; switch to Edit Mode for changes. - **Scene-aware CLI sync.** If push/pull ever needs to round-trip scene data, build a separate endpoint with its own shape. Not v1. - **Unified "everything checkable" aggregation.** If a project-wide progress meter across publish items + scene items is wanted, it's a service-layer `UNION` aggregator. Not v1; flagged so it doesn't drive premature data-model fusion. - **From existing out-of-scope list (unchanged):** YouTube API integration, thumbnail management, multi-user roles, notification system.