Skip to content

Commit bb2726e

Browse files
committed
fix: foundry module review — fix runtime bugs, add missing sync flows, update docs
Runtime bug fixes: - Replace {{json}} Handlebars helper (doesn't exist in Foundry) with data-item-id lookup - Fix drawing coordinate conversion: add percentage↔pixel conversion matching tokens - Fix fog reconciliation _syncing flag corruption by extracting _createFogDrawingData and using batched createEmbeddedDocuments - Add entity_type_id fallback in syncapi CreateEntity handler (use first available type) Data flow improvements: - Add scene-to-map linking: context menu on scene nav + auto-link for single-map campaigns - Add onSyncMapping to MapSync (map/drawing/token) and CalendarSync (calendar_event) - Add onInitialSync to MapSync: pull drawings/tokens/fog on first connect - Fetch full entity data in _onEntityCreated (WS payload may be partial) Documentation & metadata: - Add SimpleCalendar as optional dependency in module.json - Fix calendar setting hint to mention both Calendaria and SimpleCalendar - Fix .ai.md: fog is implemented (not TODO), ShopWindow is Application v1 (not v2) - Add Fog of War and Scene-to-Map Linking sections to TESTING.md https://claude.ai/code/session_01XMwxFR8BCi5XvgaSVMSBZB
1 parent 4b19804 commit bb2726e

10 files changed

Lines changed: 393 additions & 38 deletions

File tree

foundry-module/.ai.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ All sync modules use a `_syncing` boolean flag to prevent infinite loops:
4343
| `scripts/api-client.mjs` | REST client (Bearer auth) + WebSocket (auto-reconnect, message queue, event emitter) |
4444
| `scripts/sync-manager.mjs` | Orchestrator. Owns API client, routes WS messages, manages sync mapping lookups |
4545
| `scripts/journal-sync.mjs` | Entity ↔ JournalEntry bidirectional sync. Monk's Enhanced Journal support |
46-
| `scripts/map-sync.mjs` | Map drawings/tokens sync. Percentage↔pixel coordinate conversion. Fog is TODO |
46+
| `scripts/map-sync.mjs` | Map drawings/tokens/fog sync. Percentage↔pixel coordinate conversion. Scene-to-map linking via context menu |
4747
| `scripts/calendar-sync.mjs` | Adapter pattern for Calendaria and SimpleCalendar. 0-indexed↔1-indexed conversion |
48-
| `scripts/shop-widget.mjs` | Shop window (ApplicationV2). Context menu, drag-to-character-sheet, real-time updates |
48+
| `scripts/shop-widget.mjs` | Shop window (Application v1). Context menu, drag-to-character-sheet, real-time updates |
4949
| `templates/shop-window.hbs` | Handlebars template for shop inventory display |
5050
| `styles/chronicle-sync.css` | Status indicator + shop window styles |
5151
| `lang/en.json` | English localization for all UI strings |

foundry-module/TESTING.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ Requires a running Chronicle instance and Foundry VTT with the chronicle-sync mo
6060
- [ ] Drawing at (0,0) maps correctly
6161
- [ ] Drawing at scene edge maps correctly
6262

63+
## Fog of War
64+
65+
### Chronicle -> Foundry
66+
- [ ] Create fog region in Chronicle -> Semi-transparent polygon drawing appears on scene
67+
- [ ] Create multiple fog regions -> All render correctly as overlay drawings
68+
- [ ] Reset fog in Chronicle -> All fog drawings cleared from scene
69+
- [ ] Fog region reconciliation: add/remove regions correctly on re-fetch
70+
71+
### Foundry -> Chronicle
72+
- [ ] Draw a dark polygon (black fill, alpha > 0.5) -> Pushes as fog region to Chronicle
73+
- [ ] Delete a fog drawing in Foundry -> Fog region deleted in Chronicle
74+
- [ ] Non-fog polygon (light color or low alpha) -> Syncs as regular drawing, not fog
75+
6376
## Calendar Sync
6477

6578
### Chronicle -> Foundry
@@ -91,6 +104,16 @@ Requires a running Chronicle instance and Foundry VTT with the chronicle-sync mo
91104
- [ ] Multiple shop windows can be open simultaneously
92105
- [ ] Closing shop window cleans up properly
93106

107+
## Scene-to-Map Linking
108+
109+
- [ ] Right-click scene in nav bar -> "Link to Chronicle Map" option visible (GM only)
110+
- [ ] Dialog shows all Chronicle maps for the campaign
111+
- [ ] Selecting a map links the scene (sets flag)
112+
- [ ] Unlinking clears the flag
113+
- [ ] Auto-link: if campaign has exactly one map, scene auto-links on initial sync
114+
- [ ] Multi-map warning: if campaign has multiple maps, log warning with instructions
115+
- [ ] Linked scene shows correct map ID in flag inspector
116+
94117
## Initial Sync
95118

96119
- [ ] Fresh connection triggers initial sync (GET /sync/pull)

foundry-module/lang/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
},
2929
"SyncCalendar": {
3030
"Name": "Sync Calendar",
31-
"Hint": "Sync Chronicle calendar with Calendaria module"
31+
"Hint": "Sync Chronicle calendar with Calendaria or Simple Calendar module"
3232
}
3333
},
3434
"Status": {

foundry-module/module.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
"type": "module",
4646
"compatibility": {},
4747
"reason": "Optional: Calendar sync between Chronicle and Calendaria"
48+
},
49+
{
50+
"id": "foundryvtt-simple-calendar",
51+
"type": "module",
52+
"compatibility": {},
53+
"reason": "Optional: Calendar sync between Chronicle and Simple Calendar"
4854
}
4955
]
5056
}

foundry-module/scripts/calendar-sync.mjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,21 @@ export class CalendarSync {
8787
}
8888
}
8989

90+
/**
91+
* Handle a sync mapping received during initial sync.
92+
* Stores calendar event mappings for later lookup.
93+
* @param {object} mapping
94+
*/
95+
async onSyncMapping(mapping) {
96+
if (mapping.chronicle_type !== 'calendar_event') return;
97+
if (!getSetting('syncCalendar') || !this._calendarModule) return;
98+
99+
// Store the mapping so we can correlate local ↔ Chronicle events.
100+
if (mapping.external_id && mapping.chronicle_id) {
101+
this._storeEventMapping(mapping.external_id, mapping.chronicle_id);
102+
}
103+
}
104+
90105
/**
91106
* Perform initial calendar sync on WebSocket connect.
92107
* Fetches Chronicle calendar structure and syncs current date.

foundry-module/scripts/journal-sync.mjs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ export class JournalSync {
103103

104104
/**
105105
* Create a new JournalEntry from a Chronicle entity.
106-
* @param {object} entity - Chronicle entity data.
106+
* Fetches full entity data from the API since WebSocket payloads may
107+
* not include content fields (entry_html, fields_data, tags).
108+
* @param {object} entity - Chronicle entity data (possibly partial).
107109
* @private
108110
*/
109111
async _onEntityCreated(entity) {
@@ -115,7 +117,15 @@ export class JournalSync {
115117
);
116118
if (existing) return;
117119

118-
await this._createJournalFromEntity(entity);
120+
// Fetch full entity data (WS payload may be partial).
121+
try {
122+
const fullEntity = await this._api.get(`/entities/${entity.id}`);
123+
await this._createJournalFromEntity(fullEntity || entity);
124+
} catch (err) {
125+
// Fallback to WS payload data if fetch fails.
126+
console.warn('Chronicle: Failed to fetch full entity, using WS payload', err);
127+
await this._createJournalFromEntity(entity);
128+
}
119129
}
120130

121131
/**

0 commit comments

Comments
 (0)