diff --git a/Sources/Dev/pbs-hub-pre-production-extension.md b/Sources/Dev/pbs-hub-pre-production-extension.md new file mode 100644 index 0000000..24dc8af --- /dev/null +++ b/Sources/Dev/pbs-hub-pre-production-extension.md @@ -0,0 +1,393 @@ +--- +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` \ No newline at end of file