Skip to content

fix(import): abort commit on stale schedule diff - #484

Open
chiptus wants to merge 3 commits into
mainfrom
fix-42/commit-schedule-watermark
Open

fix(import): abort commit on stale schedule diff#484
chiptus wants to merge 3 commits into
mainfrom
fix-42/commit-schedule-watermark

Conversation

@chiptus

@chiptus chiptus commented Sep 1, 2026

Copy link
Copy Markdown
Owner

commit_schedule applied a stale Analyse-time diff with no re-validation at Commit, so a concurrent edit made after Analyse could be silently overridden (most visibly, setIdsToArchive archiving sets based on an orphan list that had gone stale). commit-schedule now re-checks a watermark inside the commit transaction and aborts, applying nothing, if the edition changed since Analyse.

Closes #42

Verification

  • Run a schedule import through Analyse → Review, then edit or archive a set in another tab before clicking Commit — the review step shows "The schedule changed since this review" and Commit is disabled (only "Start over" is available).
  • Run an import with no concurrent changes — Analyse → Review → Commit succeeds exactly as before.
  • A commit failure unrelated to the watermark (e.g. an unresolved stage mismatch) still shows the generic "Import failed" message with an enabled Retry.
  • pnpm run typecheck, pnpm run lint, pnpm exec vitest run, and pnpm run build all pass.

Generated by Claude Code

diff-schedule now computes a watermark over the edition's sets and
returns it with the plan; the client threads it through unchanged to
commit-schedule, which re-validates it inside the commit transaction
and aborts (applying nothing) if the edition changed since Analyse,
instead of silently applying a stale plan.

Closes #42
…x its ordering

- Prefix commit_schedule's watermark-mismatch exception with a stable
  edition_changed_since_analyse marker, and have the review step key
  off it to show a dedicated "start over, re-run Analyse" message
  instead of a generic failure with a doomed Retry button.
- Compute diff-schedule's watermark before (not alongside, via
  Promise.all) the sets read it certifies, so a concurrent edit can no
  longer land in the gap between the two reads and slip past the
  Commit-time re-check.
Copilot AI lite review requested due to automatic review settings September 1, 2026 05:22
@chiptus chiptus added the agent:pr label Sep 1, 2026 — with Claude
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
upline Ready Ready Preview Sep 1, 2026 5:34am UTC

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Deploy → stagingworkflow run
Last updated: 2026-09-01 05:34:55 UTC

  • ⏭️ DB migrations skipped (no changes)
  • Edge functions succeeded

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The watermark computation currently depends on timestamptz text formatting, which can vary by session timezone and lead to false commit aborts.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR hardens the schedule import flow against stale Analyse-time diffs by introducing an optimistic-concurrency “watermark” that is captured during Analyse, round-tripped through the client, and re-validated inside the commit_schedule transaction before applying any changes.

Changes:

  • Add a DB-side watermark computation function and require a matching watermark parameter in commit_schedule, aborting the transaction on mismatch.
  • Thread the watermark through the diff-schedule and commit-schedule Edge Functions and the frontend schedule import service payload.
  • Update the admin UI review step to show a dedicated “schedule changed” message and disable Commit, with new unit/UI tests covering the behavior.
File summaries
File Description
supabase/migrations/20260901000000_commit_schedule_watermark.sql Adds watermark computation + enforces watermark re-check inside commit_schedule.
supabase/functions/diff-schedule/types.ts Extends Analyse response type to include the watermark.
supabase/functions/diff-schedule/index.ts Fetches watermark via RPC and includes it in the response.
supabase/functions/commit-schedule/index.ts Requires watermark in request schema and forwards it to commit_schedule.
supabase/functions/commit-schedule/commit-schedule.test.ts Updates tests to supply watermark; adds stale-watermark abort test.
src/services/scheduleImport/types.ts Updates client schemas/types and adds marker detection helper for watermark mismatch.
src/services/scheduleImport/types.test.ts Tests the watermark-mismatch marker detection helper.
src/services/scheduleImport/buildCommitPayload.ts Includes watermark in the commit payload built from the diff result.
src/services/scheduleImport/buildCommitPayload.test.ts Tests that watermark is passed through unchanged.
src/components/Admin/ScheduleImport/DiffReviewStep.tsx Shows dedicated “schedule changed” error UI and disables Commit on watermark mismatch.
src/components/Admin/ScheduleImport/DiffReviewStep.test.tsx Verifies the dedicated message + disabled Commit behavior vs generic failures.
Review details
  • Files reviewed: 11/11 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread supabase/migrations/20260901000000_commit_schedule_watermark.sql
Comment thread supabase/functions/commit-schedule/commit-schedule.test.ts Outdated
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Playwright test results

passed  65 passed

Details

stats  65 tests across 21 suites
duration  1 minute, 27 seconds
commit  92dbdc8



- Split DiffPlan (computeDiff's pure-function output) from DiffResult
  (DiffPlan + watermark) so computeDiff.ts type-checks again — it has
  no DB access and can't produce the watermark itself; index.ts still
  merges it in before responding. This is what broke the
  "Run Edge Function Tests" CI job (Deno type-checks tests before running
  them).
- Compute the watermark via EXTRACT(EPOCH FROM ...) instead of a plain
  ::TEXT cast, per Copilot review: the text cast depends on the session
  TimeZone GUC, so Analyse and Commit could see different strings for
  the same value; epoch extraction on a timestamptz doesn't.
- Capture and assert the setup insert's error/data in the new stale-
  watermark test instead of silently swallowing it, per Copilot review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

commit_schedule applies a stale diff snapshot (no re-validation at commit)

3 participants