Technical DocumentationThe Node Tree Architecture

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
                          └── Beat

Book 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:

FormTypical Structure
NovelBook → Act → Chapter → Scene → Beat
NovellaBook → Chapter → Scene → Beat
Short StoryBook → Scene → Beat
SeriesSeries → 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 key
  • project_id — which project this node belongs to
  • parent_id — the parent node (null for root nodes)
  • type — one of: series, book, act, chapter, scene, beat
  • position — integer ordering among siblings
  • prose — the output layer text
  • data — 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.blocks JSONB 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).