Skip to content

Stop duplicating synced data into localStorage when connected to Supabase#175

Merged
NesiciCoding merged 1 commit into
mainfrom
claude/sweet-poitras-8fa5e1
Jun 23, 2026
Merged

Stop duplicating synced data into localStorage when connected to Supabase#175
NesiciCoding merged 1 commit into
mainfrom
claude/sweet-poitras-8fa5e1

Conversation

@NesiciCoding

Copy link
Copy Markdown
Owner

Summary

  • LocalStorage was written on every reducer mutation unconditionally, even while a Supabase connection was active — meaning every edit was stored twice (once in localStorage, once pushed to Supabase), which causes quota issues for users with a database connected.
  • localStorage is now only the persistence target while genuinely offline/disconnected. The new isOffline() helper (!navigator.onLine || !storageSync.isConnected()) gates every reducer save*() call in src/context/AppContext.tsx for Supabase-synced entities.
  • While connected, an edit lives in memory and is pushed via the existing delta-sync effect (storageSync.pushOne). If that push fails despite being "connected" (RLS error, transient failure), it already falls into the existing rm_pending_sync queue (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/essaySubmissions are not synced to Supabase at all, so their reducer cases were left unconditional — gating them would only lose data with no fallback.
  • Updated 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 typecheck passes
  • npx eslint src/context/AppContext.tsx — no new warnings/errors
  • AppContext.test.tsx, AppContext.extended.test.tsx, src/store, src/services/database test suites all pass unchanged (tests run fully offline, so behavior is unchanged in that mode)
  • Manual verification with a live Supabase connection: confirm edits no longer write to localStorage domain keys while connected, and that a forced push failure still buffers via rm_pending_sync and clears on retry

🤖 Generated with Claude Code

…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>
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@NesiciCoding, we couldn't start this review because you've reached your PR review rate limit.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fd0f9907-81a3-4d34-a3a1-8d53ec313b81

📥 Commits

Reviewing files that changed from the base of the PR and between 577245a and 2612a56.

📒 Files selected for processing (2)
  • CLAUDE.md
  • src/context/AppContext.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/sweet-poitras-8fa5e1

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 60.78% (🎯 52%) 5580 / 9180
🔵 Statements 59.47% (🎯 51%) 6401 / 10763
🔵 Functions 49.09% (🎯 42%) 1840 / 3748
🔵 Branches 50.52% (🎯 43%) 4513 / 8933
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/context/AppContext.tsx 56.46% 38.3% 50% 57.93% 153, 204-223, 252-268, 318, 356, 359, 371, 374, 407, 449, 457, 470, 477-483, 501-606, 611, 787-806, 820, 879-880, 890-958, 966, 970-974, 975-976, 982-988, 1004-1029, 1042-1070, 1100-1101, 1132-1133, 1152, 1180, 1294, 1306-1309, 1313, 1316, 1319, 1322, 1325, 1329, 1333, 1338, 1342-1343, 1346-1347, 1350-1351, 1354-1355, 1361-1380, 1387-1388, 1392, 1396-1400, 1406, 1410-1417, 1421, 1424, 1426, 1430, 1434, 1437, 1438, 1440, 1444, 1447, 1451-1452, 1456-1457, 1462-1464, 1470, 1474, 1478, 1482-1485, 1491-1505, 1516, 1518, 1521, 1524, 1527, 1528, 1530, 1534, 1539-1550, 1670
Generated in workflow #577 for commit 2612a56 by the Vitest Coverage Report Action

@NesiciCoding NesiciCoding merged commit 64918d2 into main Jun 23, 2026
8 checks passed
@NesiciCoding NesiciCoding deleted the claude/sweet-poitras-8fa5e1 branch June 23, 2026 13:08
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