mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-25 03:42:06 +00:00
333f509274
* fix(store): monotonic seq tiebreak for same-second status transitions (TASK-1643) Resolves the documented historical-snapshot precision edge: created_at is second-precision and ids are random UUIDs, so "latest transition <= T" was nondeterministic for 2+ same-second hops on one item. Add a monotonic `seq` (MAX+1 at insert, like items.seq; assigned inside the workspace seq lock so per-item order is serialized — cross-row dupes are harmless) and order the as-of-T reconstruction by created_at DESC, seq DESC, id DESC. - migrations 065 / 044: add seq + backfill existing rows chronologically (ROW_NUMBER over created_at,id), dual-dialect. - seq set on all four insert sites (update/move/create-seed hooks + backfill). - reportSnapshotAsOf ORDER BY uses seq; doc caveat updated (now fixed). - Test inserts same-created_at rows where id-order and seq-order DISAGREE, proving seq is the tiebreak. Parent: PLAN-1628. * fix(store): insert backfill create-seeds before hops so seq stays chronological per Codex review (round 1) The backfill inserted activity hops first, then create-seeds, so a seed got a HIGHER seq than a same-second hop — and since the as-of query orders by created_at DESC, seq DESC, the seed (the initial state) wrongly won "latest" for same-second create-and-change histories. Buffer the hops during the activity scan and insert them AFTER the seeds, so every hop's seq exceeds its item's seed seq (a seed is always chronologically first; on a created_at tie the hop's higher seq correctly wins). Adds a seed-seq-below-hop test.
20 lines
794 B
SQL
20 lines
794 B
SQL
-- Migration 044 (Postgres): monotonic ordering column for status_transitions
|
|
-- (PLAN-1628 / TASK-1643). Postgres counterpart to
|
|
-- migrations/065_status_transitions_seq.sql.
|
|
--
|
|
-- `seq` (MAX(seq)+1 at insert, like items.seq) gives a stable insertion-order
|
|
-- tiebreak for the as-of-T snapshot's "latest transition <= T" resolution,
|
|
-- which is otherwise nondeterministic for 2+ same-second hops on one item.
|
|
-- Backfill existing rows chronologically; new inserts continue from MAX(seq).
|
|
|
|
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS seq INTEGER NOT NULL DEFAULT 0;
|
|
|
|
WITH ordered AS (
|
|
SELECT id, ROW_NUMBER() OVER (ORDER BY created_at, id) AS rn
|
|
FROM status_transitions
|
|
)
|
|
UPDATE status_transitions
|
|
SET seq = ordered.rn
|
|
FROM ordered
|
|
WHERE ordered.id = status_transitions.id;
|