You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: bidirectional actor/character sync with system adapters (F-4)
Add ActorSync module for bidirectional sync between Foundry Actors and
Chronicle character entities. System-specific field mapping via adapters
(dnd5e: 15 fields, pf2e: HP/name back only). Dashboard Characters tab
with push button for unlinked actors. Delete from Chronicle unlinks
rather than deletes Actor to prevent data loss.
https://claude.ai/code/session_01XMwxFR8BCi5XvgaSVMSBZB
2026-03-12 -- **Sprint F-3: System Detection & Character Field Templates.**
11
+
2026-03-12 -- **Sprint F-4: Actor ↔ Entity Sync.**
12
+
13
+
34.**Sprint F-4: Actor ↔ Entity Sync (DONE).**
14
+
-**actor-sync.mjs** — New `ActorSync` module class. Bidirectional sync between Foundry Actors (type: character) and Chronicle character entities. Registers `createActor`/`updateActor`/`deleteActor` hooks. Handles `entity.created/updated/deleted` WS messages filtered by character type. Uses `_syncing` guard. `_onCharacterDeleted()` unlinks (unsets flags) rather than deleting Actor.
15
+
-**System adapters** — `adapters/dnd5e-adapter.mjs` maps 15 D&D 5e fields (ability scores, HP, AC, speed, level, class, race, alignment, proficiency_bonus). `adapters/pf2e-adapter.mjs` maps PF2e fields (ability mods, HP, AC, perception, ancestry, heritage); only pushes HP/name back to Foundry (PF2e derives most values from items/rules).
16
+
-**Dashboard Characters tab** — New tab in sync dashboard showing synced/unlinked actors with Push button for manual push. Empty states for no actors, disabled sync, no system match.
17
+
-**module.mjs** — Registered `ActorSync` as sync module.
18
+
-**TESTING.md** — Added 30+ character sync test items covering both directions, dashboard, adapters, edge cases.
-[x]**Sprint F-1: Journal Sync Fidelity** — Multi-page journal sync (split entity `entry_html` by headings into Foundry pages, concatenate pages back on Foundry→Chronicle). Ownership change hook (detect ownership changes in `updateJournalEntry` hook, push to Chronicle). Helpers: `_splitByHeadings`, `_collectTextPages`, `_syncPagesToJournal`.
287
287
-[x]**Sprint F-2: Granular Permission Mapping** — Map Chronicle `visibility: 'custom'` + `entity_permissions` to Foundry per-user ownership levels (view→OBSERVER, edit→OWNER). New syncapi endpoints: `GET /entities/:eid/permissions`, `PUT /entities/:eid/permissions`. Reverse-map Foundry ownership changes back to Chronicle. Helpers: `_buildOwnership`, `_pushPermissions`. User-specific grants stored in flags but not mapped to Foundry users (requires user ID mapping table — deferred).
288
288
-[x]**Sprint F-3: System Detection & Character Field Templates** — Expanded dnd5e character preset (15 fields: class, level, race, alignment + 6 ability scores + HP/AC/speed/proficiency). Added pf2e character preset (15 fields: class, level, ancestry, heritage + 6 ability mods + HP/AC/perception/speed). `CharacterPreset()` helper on `SystemManifest`. New `GET /api/v1/campaigns/:id/systems` endpoint returns available systems with enabled flag. Foundry module: `syncCharacters` + `detectedSystem` settings, `SYSTEM_MAP` table, `_detectSystem()` on start, `getMatchedSystem()` accessor. Dashboard Status tab shows system match info and character sync availability.
289
-
-[]**Sprint F-4: Actor ↔ Entity Sync** — New `actor-sync.mjs`module. Foundry Actor (type: "character") ↔ Chronicle entity (type: "character"). System-specific adapters (`dnd5e-adapter.mjs`, `pf2e-adapter.mjs`) with `toChronicleFields(actor)` / `fromChronicleFields(entity)`. Hooks: `createActor`, `updateActor`, `deleteActor`. WebSocket: `entity.updated` with character type. Same `_syncing` guard pattern. Dashboard "Characters" tab.
289
+
-[x]**Sprint F-4: Actor ↔ Entity Sync** — `actor-sync.mjs`with bidirectional Actor ↔ entity sync. System adapters: `dnd5e-adapter.mjs` (15 fields), `pf2e-adapter.mjs` (HP/name back only). Dashboard Characters tab with Push button. Registered in module.mjs. TESTING.md updated.
290
290
-[ ]**Sprint F-5: NPC Viewer / Hall** — Campaign route `/campaigns/:id/npcs`. Gallery/grid of revealed NPCs (non-private character entities). Portrait, name, description, location, faction. Filters by location/organization/relation. "Reveal" = DM toggles `is_private`. Foundry integration: ownership change on NPC journal → auto-reveal on Chronicle. Long-term: NPC relationship map (filtered relation graph).
291
291
-[ ]**Sprint F-6: Armory / Inventory System** — Items as entities with game-mechanic fields (weight, cost, rarity, damage, properties). Character "Inventory" tab/block via entity relations. Relation metadata: equipped, quantity, attunement. System-specific item templates (dnd5e ≠ pf2e). Foundry sync: Actor inventory ↔ Chronicle inventory relations. "Armory" campaign page showing all catalogued items.
292
292
-[ ]**Sprint F-7: Shop / Marketplace Enhancement** — Transaction logging (who bought what, when). Currency tracking per character. Stock management (auto-deplete on purchase). Foundry: purchase from shop window → update character inventory on both sides.
0 commit comments