Skip to content

Fix backend↔DB sync for sessions & maps - #191

Merged
GerardPaligot merged 5 commits into
mainfrom
fix/sync-sessions-maps
Jun 11, 2026
Merged

Fix backend↔DB sync for sessions & maps#191
GerardPaligot merged 5 commits into
mainfrom
fix/sync-sessions-maps

Conversation

@GerardPaligot

Copy link
Copy Markdown
Owner

Summary

The agenda/maps sync already used an "upsert + diff-delete" pattern, but the delete half was incomplete. Combined with enforced foreign keys, that produced three symptoms: stale data not removed, sync silently doing nothing, and duplicated map shapes/pictograms.

Root cause: when the backend dropped a referenced parent (category/format/tag/speaker), clean() deleted it while a stale junction row still pointed at it → SQLITE_CONSTRAINT_FOREIGNKEY → the swallowing catch in fetchAndStoreAgenda rolled back the whole transaction. So "stale data not removed" and "sync does nothing" were the same bug.

This PR completes the cleanup and makes deletion FK-safe:

  • Maps (M1): clear shapes/pictograms per event before re-inserting — they have autoincrement PKs and can't be upserted, so they accumulated every sync (and the Map REPLACE itself tripped an FK once children existed).
  • Sessions: rebuild SessionCategory/SessionFormat/SessionTag and speaker links for the response's sessions, delete child/junction rows before parents in clean(), wire up the unused Tag delete, add real EventSession/Schedule diff-deletes, and drop the misdirected diffSessions/deleteSessions duplicates.
  • Favorites (F1): TalkSession now uses an INSERT OR IGNORE … UPDATE upsert (like Category/Format) so is_favorite survives a sync instead of being reset to false by INSERT OR REPLACE.
  • Logging (X1): fetchAndStoreAgenda now logs the event id on failure (catch kept by design).
  • Tests: new in-memory SQLDelight harness (desktopTest, FK enforcement on) covering duplication, idempotent re-sync, category reassignment without FK crash, favorite preservation, and removal of stale rows.

Test Plan

  • ./gradlew :shared:core:desktopTest — 20 tests, 0 failures
  • ./gradlew ktlintCheck detekt — clean
  • ./gradlew lintDebug — clean
  • Manual: sync an event, remove a session/category on the backend, re-sync, confirm it disappears
  • Manual: favorite a talk, re-sync, confirm it stays favorited

🤖 Generated with Claude Code

GerardPaligot and others added 5 commits June 11, 2026 21:00
Clear shapes/pictograms for the event before re-inserting, so surviving maps
no longer accumulate duplicates and the Map REPLACE no longer trips a foreign-key
violation against stale children.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…nt sessions

Rebuild SessionCategory/Format/Tag and speaker links for sessions in the response,
delete child rows before parents in clean(), wire up Tag/EventSession/Schedule
diff-deletes, and drop the misdirected diffSessions/deleteSessions duplicates.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@GerardPaligot
GerardPaligot merged commit f6c0ee4 into main Jun 11, 2026
7 checks passed
@GerardPaligot
GerardPaligot deleted the fix/sync-sessions-maps branch June 11, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant