The Node Tree Architecture
Every piece of content in Writan is a node. Nodes are nested in a strict hierarchy that mirrors the structure of a work of fiction.
The Hierarchy
Series (optional)
└── Book
└── Act (optional)
└── Chapter (optional)
└── Scene
└── BeatBook and Scene are the only mandatory levels. All intermediate levels — Series, Act, Chapter — are optional scaffolding that appears when the work is complex enough to need it.
Hierarchy by Form
The model adapts to different forms of fiction:
| Form | Typical Structure |
|---|---|
| Novel | Book → Act → Chapter → Scene → Beat |
| Novella | Book → Chapter → Scene → Beat |
| Short Story | Book → Scene → Beat |
| Series | Series → Book → Act → Chapter → Scene → Beat |
The Beat: The Atomic Unit
A beat is defined as:
“A single, focused moment of change, action, or emotion.”
A beat has one job. It may generate multiple paragraphs of prose, but it represents a single unit of narrative movement — a decision made, a revelation landed, an emotion shifted. If a beat is doing two things, it should probably be two beats.
Database Representation
Every node is stored in the nodes table with:
id— UUID primary keyproject_id— which project this node belongs toparent_id— the parent node (null for root nodes)type— one of:series,book,act,chapter,scene,beatposition— integer ordering among siblingsprose— the output layer textdata— JSONB data layer (characters, locations, objects, freeform blocks)generation— JSONB generation layer (beat notes, AI logs, decisions)
See Database Schema for the full SQL.
Node Operations
All node operations are managed through projectStore:
- addNode — creates a node with position based on sibling count
- renameNode — updates the title
- deleteNode — cascades to children and their pips
- reorderNode — moves to a new parent/position, reindexes siblings
- updateNodeData — writes to the
data.blocksJSONB field - updateNodeProse — updates the output layer text
- updateNodeGeneration — updates beat notes and generation metadata
All operations write to IndexedDB first, queue a sync operation, then update Zustand state and rebuild the tree.
Key Principle: Structure Is Load-Bearing
The hierarchy is not cosmetic. It is the data model. Every feature — generation, analysis, feedback — is built on top of this tree structure. Data flows down (parent context informs child generation) and feedback flows up (child-level pips are visible on parent nodes).