Stop duplicating synced data into localStorage when connected to Supabase#175
Conversation
…abase LocalStorage was always written on every edit regardless of Supabase connection status, doubling storage pressure and causing quota issues for users with an active database connection. Now the reducer only persists to localStorage while offline/disconnected (isOffline()); while connected, the existing Supabase push + pending-sync-queue mechanism is the durable write, with a failed push still buffered per-record in the pending queue until it retries successfully. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 48 minutes and 11 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||
Summary
localStorage, once pushed to Supabase), which causes quota issues for users with a database connected.localStorageis now only the persistence target while genuinely offline/disconnected. The newisOffline()helper (!navigator.onLine || !storageSync.isConnected()) gates every reducersave*()call insrc/context/AppContext.tsxfor Supabase-synced entities.storageSync.pushOne). If that push fails despite being "connected" (RLS error, transient failure), it already falls into the existingrm_pending_syncqueue (src/store/storage.ts) as a per-record retry buffer, and gets cleared from that queue once the retry succeeds — no new fallback mechanism was needed, this already matched the desired write-through-fallback/per-record-clear behavior.essayAssignments/essaySubmissionsare not synced to Supabase at all, so their reducer cases were left unconditional — gating them would only lose data with no fallback.CLAUDE.md's "Offline-first rule" section to describe the new behavior instead of the previous "localStorage is always the source of truth" rule.Test plan
npm run typecheckpassesnpx eslint src/context/AppContext.tsx— no new warnings/errorsAppContext.test.tsx,AppContext.extended.test.tsx,src/store,src/services/databasetest suites all pass unchanged (tests run fully offline, so behavior is unchanged in that mode)localStoragedomain keys while connected, and that a forced push failure still buffers viarm_pending_syncand clears on retry🤖 Generated with Claude Code