feature/account-sync #1

Merged
werring merged 8 commits from feature/account-sync into master 2026-06-02 13:58:03 +00:00
Owner
No description provided.
Users can sign up to sync lessons, exercises, and custom images across
devices. Sync is entirely opt-in — anonymous users retain full
functionality unchanged. All writes remain local-first; sync runs in
the background and queues automatically when offline.

- PocketBase SDK + auth store (login, register, logout, session restore)
- Sync service: push/pull, queue drain on reconnect, last-write-wins
- Seed-exercise conflict resolution on first login across devices
- NavBar account button, AuthModal, SyncStatusIndicator, SeedConflictModal
- Local-only warning banners hidden when logged in, softened when
  sync is available but user is not signed in
- Dexie v9 migration: pb_id, synced_at, seed_key, sync_queue table
- docker-compose.yml for local PocketBase dev
- SETUP.md with backend configuration instructions
- Docs updated to reflect sync behaviour and invariants

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Collections are created automatically on first PocketBase startup.
The migration is idempotent — it skips collections that already exist.
pb_migrations/ excluded from ESLint as it runs in PocketBase's JS VM,
not the browser environment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Pin pocketbase docker image to 0.27 instead of latest
- Fix SyncStatusIndicator reactivity by keeping auth store ref intact
- Suppress unhandled rejection warnings on fire-and-forget drainQueue calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove redundant owner filters from getFullList calls; collection rules enforce ownership
- Remove double pullAll() in syncOnLogin (pushAllLocal handles it in Scenario B)
- Reset SeedConflictModal choices when conflicts prop changes
- Fix delete queue losing pbId: read pbId before local delete and store in SyncQueueEntry
- Fix conflict/sync race: gate syncOnLogin until after user resolves seed conflicts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use `app` parameter in migrate() callbacks instead of $app global
  ($app is available in hooks but not migrations)
- Override container entrypoint to pass --migrationsDir flag
  (command: appends to entrypoint; entrypoint: replaces it)
- Mount pb_migrations in local docker-compose
- Exclude pb_migrations from ESLint (PocketBase JS VM environment)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove JSON.stringify/parse round-trip for PocketBase JSON fields.
  PocketBase auto-parses JSON fields on ingest and returns objects on
  read — calling JSON.parse on an already-parsed object threw a
  SyntaxError, causing sync to fail on login.
- Send data as plain objects when pushing; read as plain objects when
  pulling (cast to the appropriate type).
- Reload all three Pinia stores after syncOnLogin so data pulled from
  the server is immediately visible without a page refresh.
- Add console.error logging in drainQueue and progress logs in
  pushAllLocal to make sync failures visible in the browser console.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Change png_data field to json type to remove 5000-char text limit
- Fall back to create (with pbId cleared) when PATCH returns 404/403,
  covering PocketBase resets and account switches without explicit logout
- Clear all pbIds on logout so records are treated as new on next login
- Reconnect local records to server by local_id after pbIds were cleared,
  preventing ConstraintErrors and duplicate records on re-login
- Strip stored local id from server data before add to avoid key conflicts
  on records pulled from a different device
- duplicateLesson now enqueues a sync and strips pbId/syncedAt from the
  source so the copy is created as a new server record
- syncNow (force sync button) now also pulls from server and reloads stores
- Pull remote changes on app startup when already logged in
- Pull remote changes on every navigation via router.afterEach

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
werring force-pushed feature/account-sync from b4b24464a6 to cf1457bcd7 2026-06-02 13:50:18 +00:00 Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
werring merged commit 78ceb7fc95 into master 2026-06-02 13:58:03 +00:00
werring referenced this pull request from a commit 2026-06-02 13:58:05 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
werring/judo-lesplan!1
No description provided.