Repository navigation
fix(debate): keep saved pins through early changes and free deleted pins - #77
Conversation
A pin made before the first pin load returned threw that load away, so saved pins looked unpinned and could not be unpinned. Loads now replay local changes on top of the saved rows. Pin writes for a debate run in order, the limit counts only pins whose result still exists, and pin buttons wait for saved pins to load. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe debate context plan now reports keys for valid results, including the open Ask chat. Pin limits can exclude pins for missing results. Pin controls wait for server, sparring-history, and pin readiness. The store applies pin changes optimistically, serializes writes, and reconciles concurrent loads and failures. ChangesDebate output pin handling
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant DebateContextControl
participant SessionStore
participant SparringStore
participant DebateContextStore
participant PinDatabase
SessionStore-->>DebateContextControl: server hydration status
SparringStore-->>DebateContextControl: saved-history completion
DebateContextControl->>DebateContextStore: loadPins
DebateContextStore->>PinDatabase: fetch saved pins
PinDatabase-->>DebateContextStore: saved pins
DebateContextControl->>DebateContextStore: togglePin with resultKeys
DebateContextStore->>DebateContextStore: apply optimistic change
DebateContextStore->>PinDatabase: serialize pin write
Architecture SummaryArchitecture risk: 🔵 Low · up to The change affects 1 system. Changed systems: Architecture concerns Review detailsSystems and components
Before / after behavior
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing. Comment |
|
@coderabbitai review |
|
|
@coderabbitai review |
|
|
@coderabbitai full review |
✅ Action performedFull review finished. |
…ed count Two quick pin clicks shared one rendered count, so both could pass the three-pin limit. The plan now passes the debate's existing result keys, and the store counts its current pins against them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The retained stale-count concern is fixed in c8d5d39:
Enforcing the three-pin limit across devices is left out on purpose. The limit is a preference. Every request uses at most three pins ( |
|
@coderabbitai review |
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
A pin save queued before sign-out ran after it, reading the next account's user ID, and a failed old save could undo the next account's pin. The next account's first pin change also waited behind the old request, and a pin load that returned after sign-out filled in the old account's pins. Resetting local data now starts a new generation. Old writes that have not started are skipped, old results leave state alone, the write queue starts fresh, and late loads are ignored. Also explains why pins on results that are not loaded locally do not count toward the limit: they cannot be shown, sent or unpinned. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Pin, unpin and pin again while the first save was pending: if that save failed, its rollback removed the latest pin from the screen, while the queued delete and insert still succeeded. The database ended pinned and the app did not. A failed save now undoes its change only when no later change to the same result is queued behind it. An insert that hits the primary key means the result is already pinned, so it counts as saved. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The pin limit leaves out pins on results that are not listed, so a deleted result cannot hold a slot forever. On a fresh sign-in, results load in parallel with pins. Until they arrive, pins on results still loading were left out too, and a fourth pin could get through. Pin buttons now also wait for saved results and sparring history to load. The session store gets a serverHydrated flag for this. It is not persisted and is cleared on sign-out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A saved-result or sparring history query that fails still finishes hydration, leaving that list empty. The pin limit then left out real pins on the missing results, so a fourth pin could get through. The session store now reports serverHydration as pending, partial or complete, and the sparring store reports historyComplete. Pins on unlisted results are left out of the limit only when every list loaded. A quick pin and unpin that both failed also left the result pinned, although neither save reached the database. A failed change that a later change replaced now hands its prior state to that change, so a failure rolls back to the last saved state. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A pin load reads the table and answers later. If a pin was still saving when the load read the table, but finished before the load answered, the load's older rows replaced it and the pin vanished from the screen. A load now also replays every change that was still saving when it started. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Follow-up to #75. An internal review after the merge found two bugs in the pinned-results store.
A pin made before the first pin load returned threw that load away. This regression came from the race fix in #75.
A pin on a deleted result counted toward the 3-pin limit forever.
Also in this PR:
Codex review follow-ups
Two Codex reviewers (the CLI and the plugin, both on
gpt-6.1-solat high effort) went over this PR in several rounds and found five more problems. Each fix below started with a test that failed.serverHydration(pending, partial or complete), and the sparring store reportshistoryComplete. Pins on unlisted results are left out of the limit only when every list loaded. The same commit fixes a quick pin and unpin that both failed: the result is now left unpinned, as the database has it (ad43294).Pins on sparring sessions older than the 50 kept locally stay out of the limit on purpose. They can't be shown, sent or unpinned, so counting them would bring back the stuck slot.
Tests
src/test/debate/debate-context.test.tsxhas 26 tests, 13 of them new. Every new test failed before its fix.Verification
All local, at
bf24d44onmainf98624f. Hosted GitHub Actions can't start because of the account's billing block, so these runs stand in for CI../.superset/db-gate.shexited 0:debate-context.spec.tson desktop and mobile.docs:checkpassed.bf24d44found nothing blocking.🤖 Generated with Claude Code
Summary by CodeRabbit