--- created: '2026-05-17' path: Sources/Dev project: pbs-hub-pre-production-extension tags: - pbs - pbs-hub - flask - mysql - video-production - scenes - ui - membership type: project-plan --- # PBS Hub — Pre-Production Extension ## Background The current `pbs-hub` (codebase: `pbs-video-manager`, internally branded "PBS Hub") is a post-shoot management tool. For each video or reel, Jenny and Travis create a project record, attach social media info, manage publish-pipeline checklists, and build YouTube descriptions. It works as a sidecar to Trello — Trello holds the board view, the Hub provides the depth Trello can't. This project extends pbs-hub *upstream* of the shoot, into pre-production. The animating goal: stop forgetting shots during the shoot. The specific pain Jenny and Travis have hit is mid-shoot realization that something didn't get captured — solved here by a tablet-friendly Present Mode showing color-coded scene completion at a glance. Same philosophy as the existing tool: Trello is the board, pbs-hub is where the work lives. Pre-production work (outline, treatment, scenes, shot tracking) is more work that lives in the Hub. ## Cross-references - Codebase: `pbs-video-manager` (`/opt/projects/pbs/pbs-video-manager`, branded "PBS Hub" internally, served at `/pbscontenthub`) - 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` - Deploy: `wordpress-install` (Ansible repo, `wp-i`) ## Scope summary - New authoring surfaces on Project Detail: **Outline**, **Treatment**, **Scenes** - New UI paradigm for Project Detail: persistent card rail + canvas (replaces 3-tab layout) - New Present Mode for shoot-day use on tablet - Project metadata as CRUD-managed key/value pairs - Extended status workflow (`planned → scripted` prepended to existing lifecycle) - Test infrastructure bootstrapped (pytest scaffold + tests for new code only) - No CLI changes - No changes to existing Publish Check or Desc Build surfaces --- ## Terminology Industry-standard film production vocabulary throughout: - **Outline** — rough story scratch (project-level) - **Treatment** — narrative prose, scene-by-scene story (project-level) - **Scene** — unit of narrative ("Intro," "Recipe," "Closer"). Single location/time/purpose - **Shot** — a specific camera capture within a scene - **Shot list** — the planned shots for a scene - **Scene list** — the new pre-production surface (scenes + scene items). Distinct from "Checklist" - **Checklist** — the existing publish-pipeline surface. Unchanged - **Item types** — `shot` and `reminder` --- ## Schema All new tables target the **`pbs_automation`** database (resolved — the Phase 5 "TBD" was implicitly decided when `sql/create_tables.sql` was written; documenting it explicitly in this plan). ### Extended: `projects` ```sql ALTER TABLE projects ADD COLUMN outline TEXT DEFAULT NULL; ALTER TABLE projects ADD COLUMN treatment TEXT DEFAULT NULL; ``` Both are freeform markdown authoring surfaces. Existing projects backfill to NULL — fine. ### New: `scenes` ```sql CREATE TABLE scenes ( id INT PRIMARY KEY AUTO_INCREMENT, project_id INT NOT NULL, sort_order INT NOT NULL DEFAULT 0, title VARCHAR(255) NOT NULL, purpose VARCHAR(500) DEFAULT NULL, in_shot TEXT DEFAULT NULL, background VARCHAR(500) DEFAULT NULL, script TEXT DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE ); ``` Briefing fields are read aloud on-camera in Present Mode — plain text, no markdown rendering needed. `is_complete` is **not stored**. Scene completion is derived from the scene's items. ### New: `scene_items` Path B — separate table from `checklist_items`. Reasoning: `checklist_items.category` is workflow-stage-shaped (export/wordpress/youtube/instagram/email) and doesn't fit scene items. Sharing the table would force every existing query to add filter logic, creating a latent "shot items leak into Publish Check" bug class. Separate tables isolate the new work cleanly. ```sql CREATE TABLE scene_items ( id INT PRIMARY KEY AUTO_INCREMENT, scene_id INT NOT NULL, sort_order INT NOT NULL DEFAULT 0, label VARCHAR(500) NOT NULL, item_type ENUM('shot', 'reminder') NOT NULL DEFAULT 'reminder', is_complete BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (scene_id) REFERENCES scenes(id) ON DELETE CASCADE ); ``` Above/below-the-line behavior driven by `is_complete`. Single `sort_order` drives both zones. Un-checking pops an item back above the line naturally. ### New: `default_scenes` + `default_scene_items` Mirrors the runtime structure. Loaded on `pbs init` (or new-project creation) to seed a starter scene structure. Fully editable via Settings CRUD. Implementation agent picks reasonable defaults — the data model just needs to support them. ```sql CREATE TABLE default_scenes ( id INT PRIMARY KEY AUTO_INCREMENT, sort_order INT NOT NULL DEFAULT 0, title VARCHAR(255) NOT NULL, purpose VARCHAR(500) DEFAULT NULL, in_shot TEXT DEFAULT NULL, background VARCHAR(500) DEFAULT NULL ); CREATE TABLE default_scene_items ( id INT PRIMARY KEY AUTO_INCREMENT, default_scene_id INT NOT NULL, sort_order INT NOT NULL DEFAULT 0, label VARCHAR(500) NOT NULL, item_type ENUM('shot', 'reminder') NOT NULL DEFAULT 'reminder', FOREIGN KEY (default_scene_id) REFERENCES default_scenes(id) ON DELETE CASCADE ); ``` ### New: `project_metadata` + `project_metadata_fields` Generic key/value CRUD. Hybrid approach — outline, treatment, and per-scene script are first-class columns (they're authoring surfaces and deserve dedicated UI). Smaller metadata fields go through the generic table so future additions are a CRUD operation, not a migration. ```sql CREATE TABLE project_metadata_fields ( id INT PRIMARY KEY AUTO_INCREMENT, `key` VARCHAR(100) NOT NULL UNIQUE, label VARCHAR(255) NOT NULL, sort_order INT NOT NULL DEFAULT 0 ); CREATE TABLE project_metadata ( id INT PRIMARY KEY AUTO_INCREMENT, project_id INT NOT NULL, `key` VARCHAR(100) NOT NULL, value TEXT DEFAULT NULL, sort_order INT NOT NULL DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE ); ``` Seeded fields on first deploy: `logline`, `working_title`, `tagline`. ### Untouched `checklist_items` and `default_checklist_items` — no schema changes. The existing publish-pipeline machinery stays exactly as it is today. --- ## Status workflow `projects.status` stays as VARCHAR (per Phase 5 doc — eventual lookup table refactor pending Trello integration). Extended video lifecycle: ``` planned → scripted → raw → editing → exported → final → published → archived ``` Status meanings: - `planned` — project exists, idea stage - `scripted` — script/scenes/shot lists built, ready to shoot - `raw` — footage exists - (rest unchanged) All transitions manual. **Coexistence:** the existing reel-flavored status values (`draft / ready / live-matched / live-needs-review`) and the video lifecycle values share the same column. Disambiguated by `project_types.name`. The eventual status-as-lookup-table refactor will need to accommodate both vocabularies. --- ## UI: persistent card rail + canvas (C2) Project Detail replaces its current 3-tab layout (Overview / Publish Check / Desc Build) with a persistent left rail of live status cards plus a canvas area. ### Rail **Order (lifecycle):** Overview / Outline / Treatment / Scenes / Publish Check / Desc Build **Per-card visual:** - Card title (surface name) - Live status content per card type: - 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 - Publish Check — X of Y complete with progress bar - Desc Build — "drafted" / "not started" / "complete" - Currently active card has clear selected treatment (border, background, or accent ring) **Rail behavior:** - Click a card → that surface loads in the canvas - Rail width: roughly 280-320px on desktop, collapsible to icon-only or hidden - On tablet for Present Mode: rail collapses to maximize canvas ### Canvas surfaces **Overview** — unchanged. **Outline** — single freeform textarea. Markdown-friendly but no required convention. **Treatment** — split-pane: - **Left:** treatment prose editor (long-form textarea) - **Right:** scene title list with "Add scene" button and drag-to-reorder - Right pane is a live view onto `scenes` rows — edits sync to the Scenes surface. Same `sort_order` drives both views **Scenes** — two modes: *Edit Mode (default):* - Full CRUD on scenes (create, reorder via drag, delete, edit briefing fields + per-scene script) - Full CRUD on scene items (create, reorder via drag, delete, set/change item_type, toggle complete) - Items split visually above/below the line by `is_complete` - Item types visually distinguished (shot vs. reminder) - "Present" button to enter Present Mode *Present Mode (shoot-day surface):* - **Scene strip across the top** — horizontal banner of tappable scene chips, color-coded: - Gray — empty scene (no items) - Red — items exist, none complete - Amber — partial completion - Green — all items complete - Active chip has clear selected treatment - Tap chips to focus that scene (non-sequential — tap any scene, any order) - Horizontal scroll if more chips than fit - 44px minimum tap target for tablet - No drag-reorder in Present Mode (Edit Mode action only) - **Focused scene area** below the strip shows: - Project title + current date (for on-camera "clapper" context) - Scene title - Briefing: purpose / in_shot / background (read-only — editing requires returning to Edit Mode) - Items split above/below the line; tap to toggle complete; inline "Add item" for mid-shoot additions - "X of Y remaining" indicator - Button to exit back to Edit Mode **Publish Check** — unchanged. **Desc Build** — unchanged. ### Drag-drop SortableJS (CDN). Touch-friendly on tablet. Used on: - Treatment right pane (scene title reorder) - Scenes Edit Mode (scene reorder + scene-item reorder) - Anywhere else item reordering surfaces ### Visual polish The current pbs-hub UI is functional but not polished. **This project prioritizes function over aesthetic.** Visual polish (typography hierarchy, refined card design, motion/transitions, dark mode, etc.) is deferred to a separate "modern and sexy" pass. Same applies to Jinja macro extraction — defer to the polish pass when macros can be extracted coherently across old and new surfaces in one consistent design language. **Specific items deferred to polish:** - Color-change animations on scene chip state transitions - Progress dots inside scene chips - Jinja macros for shared components (status pill, card, badge, action button) - Alpine.js (if ever needed for declarative client state) - Rail vs. intra-page filter chips pattern unification (Library/Settings keep filter chips for now) --- ## Pre-shoot handling Pre-shoot is just a scene. The first scene in a new project is seeded as a "Prep" scene (or similar) populated with `reminder`-type items. No separate model, no special-case UI. Same scene strip color coding applies. Defaults seeded on new-project creation via `default_scenes` + `default_scene_items`. Implementation agent picks reasonable starting items (e.g., batteries charged, SD cards formatted, audio check, lighting set). Jenny and Travis edit defaults via Settings CRUD. --- ## CLI No changes. No new commands. No sync changes — `sync_checklist_items()` stays as-is because Path B isolates scene items in their own table, so the existing sync path doesn't touch them. If scene sync is ever needed (e.g., for offline-first scene editing), it gets its own endpoint with its own shape. Pinned as future enhancement, not in this scope. --- ## Tests Bootstrap pytest infrastructure as part of this work: - Add pytest + pytest-flask to `pyproject.toml` - Create `tests/` directory + `conftest.py` with in-memory SQLite fixture - Document test invocation in README Write tests for new code only: - `Scene` and `SceneItem` model behavior - Scene completion derivation logic - Scene-item above/below-the-line behavior - Migration smoke tests (does the migration run cleanly on a Phase 5 baseline?) **Do NOT backfill tests** for existing untested code. Phase 4 (the original tests phase from CLAUDE.md) remains untouched — this work just lays the foundation so Phase 4 has somewhere to build from. --- ## Build sequencing (S3 — schema first, then vertical slices) 1. **Schema migration** — all new tables and column additions in numbered `sql/migrations/` files. New folder; existing repo has no migrations framework. Hand-written ALTER and CREATE statements, reviewable, re-runnable. 2. **Rail framework** — persistent left rail UI scaffolding, with cards rendering placeholder state. All canvas slots empty initially. 3. **Outline surface** — end-to-end (column, service, route, rail card, GUI). 4. **Treatment surface** — end-to-end with split-pane and live scene title list. 5. **Scenes surface — Edit Mode** — full CRUD on scenes and items, briefing fields, per-scene script. 6. **Scenes surface — Present Mode** — scene strip, focused scene view, tablet polish. 7. **Project metadata** — `project_metadata` + `project_metadata_fields` CRUD, Settings integration, seed fields. 8. **Status workflow** — add `planned` and `scripted` to UI dropdowns. Small slice, slots anywhere. 9. **Tests** — pytest bootstrap + tests for above slices. S3 may collapse to S1 in practice — the implementation agent will batch related changes. The slicing is primarily for clean git checkpoints and review boundaries. --- ## Pre-deployment verification Before running the new migration on staging or production, Travis verifies the Phase 5 baseline is actually applied: ```bash mysql -u pbs_api -p pbs_automation -e 'SHOW TABLES' ``` Expected: includes `projects`, `project_types`, `platform_posts`. If those exist, the new migration just ADDs scenes/scene_items/etc. on top. If they don't, the Phase 5 baseline needs to land first — this work assumes it as the starting point. ## Deploy Lovebug builds and tests locally. Stops short of deploy. Travis handles deploy via `wordpress-install` Ansible repo (`wp-i`) — staging first, then production. --- ## Documentation cleanup While in the schema, fix two doc drift items: 1. Add a one-line note to `sql/create_tables.sql` header (or CLAUDE.md) marking the database housing question RESOLVED → `pbs_automation`. Next reader doesn't hit the TBD wall. 2. Update CLAUDE.md to reflect Path B (separate scene_items table) and the new rail-based UI for Project Detail. --- ## Notes / flags - **`platform_posts` n8n chain unaffected** — the comment-reply lookup path (`platform_posts → projects → pbs_recipes`) is untouched. Schema additions are purely additive to `projects`. No risk to the existing comment-reply automation. - **`/pbscontenthub` URL prefix** — hardcoded in `base.html` (`const BASE = '/pbscontenthub'`). New routes must be aware of this. - **Rail vs. intra-page filter chips** — Project Detail's new rail does NOT replace Library/Settings filter chips. Those serve a different metaphor (filtering content within a single page) and stay as-is. Future polish pass may unify the visual language across both patterns — flagged as a follow-on project, not this scope. - **Status vocabulary coexistence** — `projects.status` holds both reel-flavored values and video lifecycle values. Disambiguated by `project_types.name`. Future status-as-lookup-table refactor (Trello integration) must accommodate both. --- ## Out of scope (deferred / future) - Auto-generation of scenes from treatment (structured parsing of treatment prose). Manual handoff for now. - Take tracking / version notes (the "active scene tracking" idea). - Mid-shoot briefing field edits (Present Mode is read-only for briefing in v1). - Quick-action affordances on rail cards (e.g., jump directly to Present Mode from the Scenes rail card). - Visual polish pass (typography, motion, dark mode, refined card design). - Jinja macro extraction (deferred to polish pass). - Rail vs. filter chip pattern unification. - Scene-aware CLI sync. - Unified "everything checkable" progress aggregation across publish items and scene items. - Color-change animations on scene chip state transitions. - Progress dots inside scene chips. - Already-deferred (from existing out-of-scope list): YouTube API integration, thumbnail management, multi-user roles, notification system, automated cloud backup, DaVinci Resolve `.drp` association. --- ## Definition of done - All schema migrations applied to staging cleanly - Rail + canvas UI replaces Project Detail tabs without regressing existing surfaces - Outline, Treatment, Scenes (Edit + Present) usable end-to-end on a real project - Pre-shoot defaults seed on new project creation - Project metadata CRUD works in Settings; logline/working_title/tagline seeded - Status workflow includes `planned` and `scripted` - pytest bootstrapped, new code covered - Existing Publish Check, Desc Build, and CLI behave identically to pre-change - Doc cleanup items addressed - Pre-deployment verification passes on staging - Travis takes over for production deploy via `wp-i`