feat(sync): migrate cloud sync from Cloudflare Workers to PocketBase#148
Merged
vscarpenter merged 5 commits intomainfrom Feb 28, 2026
Merged
feat(sync): migrate cloud sync from Cloudflare Workers to PocketBase#148vscarpenter merged 5 commits intomainfrom
vscarpenter merged 5 commits intomainfrom
Conversation
…ketBase Replace the entire Cloudflare Workers backend (D1 + KV + R2) with a self-hosted PocketBase instance at api.vinny.io. This dramatically simplifies the sync architecture: - Drop E2E encryption — tasks stored as plaintext (user owns the server) - Use PocketBase realtime SSE for instant cross-device sync - Last-write-wins (LWW) replaces vector clock conflict resolution - Google + GitHub OAuth via PocketBase built-in auth (replaces custom OIDC) - Delete worker/ entirely — zero backend code to maintain New modules: pocketbase-client, pb-sync-engine, pb-realtime, pb-auth, task-mapper Deleted: ~95 files including worker/, crypto, vector-clock, old sync engine, OAuth handshake, token manager, queue optimizer, encryption UI Net change: 79 files, +1,744 -4,211 lines (≈2,500 lines removed) All 1,280 tests pass, typecheck clean, lint clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update all project documentation to reflect the migration from Cloudflare Workers to PocketBase: - README.md: Version 6.9.0, PocketBase sync features, updated MCP server docs, new tech stack, removed worker deployment commands - SECURITY.md: Replace E2E encryption/zero-knowledge sections with self-hosted PocketBase model, update OAuth providers, CSP headers, MCP config, and audit results - TECHNICAL.md: Database v13 migration entry, remove encryption passphrase dialog, update sync component list Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ompatibility - Fix OAuth by updating .env.local to point at production PocketBase URL - Fix 404 errors by adding setup-pocketbase-collections.sh script for tasks collection - Fix 429 rate limiting by batch-fetching remote task IDs and throttling push ops - Fix 400 errors by using client_updated_at instead of system fields in sort/filter - Fix import rejecting legacy exports by using .strip() schema for vectorClock compat - Close settings dialog after successful import for better UX - Update CLAUDE.md with PocketBase v0.23+ gotchas and dev notes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…c UI - Surface per-item push errors: pushLocalChanges() now returns failedCount and lastError so partial failures show the actual PocketBase error message instead of being silently swallowed - Fix stale closure: useSync.sync() returns PBSyncResult directly instead of reading from stale React state captured in the handleSync closure - Fix error auto-reset timing: errors now persist 10s (was 3s) so users can actually read them; success still resets after 3s - Fix double toast: removed duplicate showSyncResultToast from sync-button since fullSync() already fires notifications via sonner - Add 'partial' status to PBSyncResult for when some items sync but others fail, with failedCount field for UI display Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- [High] Preserve task metadata (notifications, time tracking) during MCP write operations instead of hardcoding defaults - [High] Always trigger pull sync in background even when local queue is empty, so remote changes are fetched when SSE is unavailable - [Medium] Escape interpolated values in PocketBase filter expressions to prevent potential injection - [Medium] Enforce HTTPS for PocketBase URL in MCP config (localhost exempt) - [Medium] Replace useState misuse with useEffect in ImportDialog so task count updates when fileContents prop changes - [Low] Use client_updated_at instead of client_created_at for lastUpdated stat in getTaskStats - [Low] Replace raw console.* calls with structured logger in retry-manager Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
vscarpenter
added a commit
that referenced
this pull request
Mar 1, 2026
…igration Remove dependencies, scripts, documentation, and code references left over from the Cloudflare Workers and Supabase sync systems that were replaced by PocketBase in #148. - Remove wrangler devDependency and hono override from package.json - Delete 8 stale files: Worker/sync/security docs, jwt.ts, scripts - Update MCP server CLI, config, and tool schemas to remove encryption refs - Rewrite architecture-diagrams.ts with PocketBase diagrams - Update 5 documentation files to reflect PocketBase architecture - Remove vectorClock from all test fixtures (schema v13 dropped it) All 1280 tests passing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.




Summary
api.vinny.ioclient_updated_attimestamps, replacing vector clock conflict resolutionworker/entirely — zero backend code to maintain (~95 files, ~2,500 lines removed)New modules
lib/sync/pocketbase-client.ts— PocketBase SDK singleton wrapperlib/sync/pb-sync-engine.ts— Push/pull sync with LWW resolutionlib/sync/pb-realtime.ts— SSE subscription manager with echo filteringlib/sync/pb-auth.ts— OAuth login/logout via PocketBase SDKlib/sync/task-mapper.ts— camelCase ↔ snake_case field mappingSync UI bug fixes (latest)
pushLocalChanges()now returnsfailedCountandlastErrorso partial failures show the actual PocketBase error instead of being silently swalloweduseSync.sync()returnsPBSyncResultdirectly instead of reading from stale React state in thehandleSyncclosureshowSyncResultToastfrom sync-button sincefullSync()already fires notifications via sonnerpartialstatus — newPBSyncResultstatus for when some items sync but others failImpact
Test plan
bun run test— 72/72 files, 1,280/1,280 tests passbun typecheck— 0 errorsbun lint— 0 errorsnpx tsc --noEmit— 0 errors🤖 Generated with Claude Code