5.3 KiB
5.3 KiB
CHUNK #5 — Plot & Whiteboard
Duration: ~3 days · Prereqs: CHUNK #2 (entity storage) · Follows: CHUNK #4 · Unblocks: CHUNK #9 (AI reasons over plot structure)
Purpose: Give authors three ways to see and shape their story's structure — a beat board with genre templates, a configurable timeline, and a free-form whiteboard — all backed by React Flow 12 and all linked to chapters and entities. After this chunk, plot structure is first-class and the whiteboard handles 200+ nodes at 60 fps.
Steps
1. Beat board (apps/web/src/features/plot/)
- Beat editor (
BeatEditor.tsx): a beat is aPlotBeatwithtemplate,title,description,status(draft→revised→locked), optionalchapterIdlink,order,notes. Edit inline in a list or in a right-rail drawer. - Templates (
apps/web/src/features/plot/templates.ts): ship four — Three-Act (Setup / Confrontation / Resolution), Save-the-Cat (all 15 beats), Seven-Point (Hook, Plot Turn 1, Midpoint, Plot Turn 2, Climax), and Custom. Selecting a template seeds N empty beats with the template's titles; the author edits from there. - Board view (
BeatBoard.tsx): horizontal swimlanes per act/template-section, or a single ordered list. Drag to reorder; each beat shows status color, word count of linked chapter, and a "link to chapter" picker. Progress bar = % of beats that arerevisedorlocked. - Locking: a
lockedbeat is read-only until unlocked (with reason). Prevents accidental edits during a draft pass.
2. Timeline (apps/web/src/features/timeline/)
- TimelineView.tsx: a horizontal time axis. Events (
TimelineEvent) carrywhen: {era, day} | date(configurable: real dates OR a fictional calendar with named eras + day numbers),title,description, optionalchapterId, andlinks[](causal links to other events). - Filters: show/hide by character (events mentioning a character), by location, by era. Multi-select.
- Causal links: draw an arrow from cause → effect; rendered as a separate layer behind the events. Click an event → open a read-only panel (full edit in the beat/entity system).
3. Whiteboard flow editor (packages/boards)
- Board model (
packages/boards/src/types.ts):Board { id, projectId, nodes: FlowNode[], edges: FlowEdge[] }where aFlowNodeis a typed card —character,world,chapter,note,image, orgroup. Edges are typed (leads-to,contrasts,causes,custom). - Node views (
packages/boards/src/nodes/): each node type renders a styled card with the entity's key fields (name, role, word count, etc.) and a drag handle. Groups are translucent containers that children snap to. - Canvas (
packages/boards/src/BoardCanvas.tsx): React Flow 12 with:- Minimap (top-right), zoom/pan (mouse + keyboard), auto-layout (grid, force, or radial) via
@xyflow/layout. - Multi-select (shift-click, marquee), group/ungroup, align (distribute edges).
- Keyboard:
Deldelete,Ctrl/Cmd+Dduplicate,Ctrl/Cmd+Ggroup, arrow keys nudge. - Persistence: every node/edge change → autosave (Chunk 2 engine) with optimistic
rev.
- Minimap (top-right), zoom/pan (mouse + keyboard), auto-layout (grid, force, or radial) via
- Performance (
packages/boards/src/perf.ts): virtualize off-screen nodes, memoize node views, cap visible edges. 200 nodes at 60 fps is the hard budget — a Playwright perf test seeds 200 nodes and measures frame time.
4. Cross-links
- Board ↔ chapters: a
chapternode links to aChapterdoc; click → opens it in the writer. - Board ↔ entities:
character/worldnodes link to entities; click → opens the entity editor. - Import from beat board: "Add beats to board" bulk-imports locked/revised beats as nodes.
5. Tests
- Unit: template seeding (correct beat count + titles); board save/load round-trip (both adapters).
- E2E: create a 6-node board, drag nodes, draw edges, save → reload → identical layout.
- Perf: 200-node board at 60 fps (Playwright).
Acceptance criteria (all must pass)
- Select "Save-the-Cat" → 15 beats seeded with correct titles; edit one → saves.
- Reorder beats by drag; progress bar updates (% revised/locked).
- Lock a beat → editing is blocked with a reason prompt; unlock → editable.
- Timeline renders events on a configurable calendar (real dates OR era/day); filters by character/location work.
- Whiteboard: create nodes of every type, drag, group, align, draw typed edges, save → reload identical.
- 200-node board renders at 60 fps (Playwright perf test in CI).
- A chapter node opens the writer; a character node opens the entity editor.
- Contract suite still green on both adapters.
Definition of done
Authors can structure a story three ways — beats, timeline, whiteboard — all linked to the prose and entities, and the whiteboard stays smooth at scale.
Risks & fallbacks
- React Flow 12 API churn → pin the exact version; wrap all calls in
packages/boardsso the app never imports@xyflow/reactdirectly. - 200-node perf → if force-layout is too slow, default to grid layout and make force-layout opt-in; document the node cap in
docs/BOARDS.md. - Drag-and-drop jank on low-end machines → virtualize off-screen nodes; throttle autosave to 800ms.