17 KiB
| created | path | project | tags | type | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-05-17 | Sources/Dev | pbs-hub-pre-production-extension |
|
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 → scriptedprepended 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 —
shotandreminder
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
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
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.
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.
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.
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 stagescripted— script/scenes/shot lists built, ready to shootraw— 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
scenesrows — edits sync to the Scenes surface. Samesort_orderdrives 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.pywith in-memory SQLite fixture - Document test invocation in README
Write tests for new code only:
SceneandSceneItemmodel 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)
- 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. - Rail framework — persistent left rail UI scaffolding, with cards rendering placeholder state. All canvas slots empty initially.
- Outline surface — end-to-end (column, service, route, rail card, GUI).
- Treatment surface — end-to-end with split-pane and live scene title list.
- Scenes surface — Edit Mode — full CRUD on scenes and items, briefing fields, per-scene script.
- Scenes surface — Present Mode — scene strip, focused scene view, tablet polish.
- Project metadata —
project_metadata+project_metadata_fieldsCRUD, Settings integration, seed fields. - Status workflow — add
plannedandscriptedto UI dropdowns. Small slice, slots anywhere. - 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:
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:
- Add a one-line note to
sql/create_tables.sqlheader (or CLAUDE.md) marking the database housing question RESOLVED →pbs_automation. Next reader doesn't hit the TBD wall. - Update CLAUDE.md to reflect Path B (separate scene_items table) and the new rail-based UI for Project Detail.
Notes / flags
platform_postsn8n chain unaffected — the comment-reply lookup path (platform_posts → projects → pbs_recipes) is untouched. Schema additions are purely additive toprojects. No risk to the existing comment-reply automation./pbscontenthubURL prefix — hardcoded inbase.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.statusholds both reel-flavored values and video lifecycle values. Disambiguated byproject_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
.drpassociation.
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
plannedandscripted - 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