Files
PubScript/CHUNK#4.md
T

59 lines
5.1 KiB
Markdown

# CHUNK #4 — Characters & World-Building
**Duration:** ~2 days · **Prereqs:** CHUNK #2 (entity storage), CHUNK #3 (editor for mentions) · **Follows:** CHUNK #3 · **Unblocks:** CHUNK #5 (plot links entities), #9 (AI context pulls from entities)
**Purpose:** Make the story's moving parts first-class: character sheets with typed relationships, flexible world items, fast fuzzy search, backlinks, and `@mention` links from prose to entities. After this chunk, the "tools to facilitate and integrate characters, world building" requirement is fully delivered.
---
## Steps
### 1. Entity engine (`apps/web/src/features/entities/`)
1. **Generic field renderer** (`EntityFields.tsx`) — driven entirely by `ENTITY_FIELDS` from `packages/core/src/schema.ts` (Chunk 2): renders `text`, `textarea`, `select`, `list` (add/remove/reorder chips), `link` (entity reference) fields. Adding a field to the registry = it appears in the UI. No per-entity UI code.
2. **Entity panel** (`EntitiesView.tsx`) — tabbed: **Characters · World · Notes**. Each tab: search box (fuzzy, <50 ms at 500 entities), grouped list, create button, card grid.
3. **Entity editor** (`EntityEditor.tsx`) — right-rail drawer: fields from the registry, plus:
- **Relationships editor** (characters): add `{ target: character, kind: 'ally'|'rival'|'family'|'mentor'|'romantic'|'custom', note }`; render as a list with the linked character's chip.
- **Backlinks** tab: "Appears in" — chapters containing a mention of this entity, plus entities that reference it.
- Duplicate, delete (with confirm + backlink warning), "pin to context rail".
4. **World kinds** — `location`, `faction`, `item`, `glossary`, `system` — each with its field set from the registry (e.g. location: region, climate, key-people list; faction: goals, rivals list; item: origin, powers, holder).
5. **Relationship map** (`RelationshipMap.tsx`) — a small force/graph view (reuse React Flow with a static layout) of the selected character's web; click a node → open that character.
### 2. Mentions & linking
1. **Autocomplete** (`packages/editor/src/mention.ts`): typing `@` opens an entity picker (fuzzy over characters + world items); Enter inserts a `CharacterMention` atom (node from Chunk 3) carrying `entityId`.
2. **Mention chip** — styled, hover → mini popover (name + one-line bio + "Open sheet"); click → opens the entity editor.
3. **Backlink computation** (`packages/core/src/backlinks.ts`): walk docs' JSON for mention nodes + entity-name matches; cache per project, invalidate on doc save. Power the "Appears in" tab and the context rail.
4. **Consistency check** (small win, big value): `findInconsistencies(project)` — e.g. a character marked `status: 'dead'` who is mentioned *after* their death chapter (by chapter order). Surface as a warnings list in the Characters tab.
### 3. Search & navigation
1. Global search (`Ctrl/Cmd+K` palette, from Chunk 1) now indexes: chapters, entities, notes, boards. Grouped results, jump-to with context snippet.
2. Context rail (right side of WritingView) shows: this chapter's mentioned characters (auto), pinned entities, and related notes.
### 4. Data & seed
1. Extend `server/src/seed.ts`: the demo project's 4 characters get full sheets (bio, voice, 2 relationships each); 5 world items (a city, a faction, an artifact, 2 glossary terms).
2. `docs/DATA_MODEL.md` — the entity registry table (kind → fields) as the human reference.
### 5. Tests
1. Unit: field renderer per type; fuzzy search (500 entities < 50 ms); backlink computation (property test: insert mention → backlink appears; remove → disappears).
2. Contract: entity CRUD + `?q=` search through both adapters (add to Chunk 2's suite).
3. E2E: create character → `@mention` it in a chapter → backlinks tab lists the chapter → open sheet from the chip.
---
## Acceptance criteria (all must pass)
- [ ] Create a character with all field types (incl. list + link) via the generic renderer — no custom code added.
- [ ] Fuzzy search over 500 seeded entities returns in < 50 ms (measured in test).
- [ ] `@` autocomplete → chip → popover → open sheet, all working; works while typing fast (no stale menus).
- [ ] Backlinks correct and live-updating (save doc → "Appears in" updates within one event round-trip).
- [ ] Consistency check flags the seeded dead-character-after-death case.
- [ ] Relationship map renders and navigates.
- [ ] Global palette finds a chapter, a character, and a note from one box.
- [ ] Contract suite still green on both adapters.
## Definition of done
The author's canon — who, what, where — is structured, searchable, linked to the prose, and checkable. This is the data the AI roles will reason from in Chunk 9.
## Risks & fallbacks
- **Fuzzy search quality** → use a small, well-tested scorer (e.g. `fuse.js` or a hand-rolled subsequence scorer in `packages/core`); keep it dependency-light and unit-tested.
- **Backlink cost on huge docs** → compute incrementally on save (diff the doc), not full re-scan; cache in the DB (`mentions(entity_id, chapter_id)` table).
- **Mention vs. plain text ambiguity** → only explicit `@`-inserted atoms are links; name-matching is *suggested*, never auto-applied.