Repository navigation
Sync API: change feed for Foundry catch-up, and field updates that merge - #927
Merged
Merged
Conversation
…runing Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018uKa2E5HNdeubwBSD9Jn4n
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018uKa2E5HNdeubwBSD9Jn4n
Foundry only sends the fields it maps, so a whole-map replace erased every Chronicle-only field on each actor edit. Fixes #909 (Chronicle side). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018uKa2E5HNdeubwBSD9Jn4n
keyxmakerx
marked this pull request as ready for review
October 3, 2026 00:09
7 of 9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Key Maker · project thread
Fixes #908
Fixes #909
Security implication: new read endpoint returns ids only and is limited to DM-equivalent keys (Owner or co-DM), 403 otherwise; content is still fetched through the existing permission-checked reads.
Consumer-verified: n/a (no consumer yet; the Foundry module adopts it in keyxmakerx/Chronicle-Foundry-Module#114)
Mockup: n/a (nothing on screen)
What this changes
Chronicle now keeps a numbered list of what changed in each campaign (pages, notes, map pieces, calendar events; created/updated/deleted), and every live WebSocket message carries its number (
seq).GET /api/v1/campaigns/:id/sync/changes?since=Nlets the Foundry module catch up on everything it missed while offline, deletions included, instead of relying on/sync/pull, which can't see content changes. Step 2 of the approved plan in #907.Also in this PR (step 1 of #907, approved on the Sign-offs before/after card):
PUT /entities/:id/fieldson the sync API now merges instead of replacing, so a Foundry actor edit no longer blanks Chronicle-only fields. NewEntityService.MergeFields(absent keeps, null clears); the web attributes widget still uses the replacingUpdateFields. The module half of #909 (renames, debounce) is in the Foundry module PR.Load-bearing lines
internal/plugins/syncapi/sync_change_bus.go:RecordingEventBuswraps the live bus where it is built ininternal/app/routes.go, so every publisher is covered. Recording is best effort with a 500ms timeout; a failed record still publishes live.internal/plugins/syncapi/sync_change_repository.goList: a 2-second settle window, because concurrent inserts can commit out ofseqorder and a cursor must not skip one still in flight.resetRequired: true(withnext= current head) whensinceis older than what retention kept (30 days); the client does a full resync.internal/plugins/syncapi/migrations/007_sync_changes: two new tables, additive, idempotent.Honest deviations
Test plan
go test ./...: all packages pass; 5 newTestMergeFieldPatchcases; 19 change-feed tests (handler: since, limit clamp/default, hasMore, resetRequired, co-DM allowed, player 403, no key 403, bad since 400; bus: allowlist, seq stamping, publish when record fails)go vet ./...cleantools/check-migration-immutability.shpasses; migration-safety review: PASSinternal/wire/routes_snapshot.txt)Tenet self-check
.ai.md,docs/api/openapi.yaml🤖 Generated with Claude Code
https://claude.ai/code/session_018uKa2E5HNdeubwBSD9Jn4n
Generated by Claude Code