Skip to content

Re-sequence taxonomy sort orders on apply; report them in validate#213

Merged
PatrikBak merged 1 commit into
mainfrom
patrik/taxonomy-resequence-on-apply
Jun 19, 2026
Merged

Re-sequence taxonomy sort orders on apply; report them in validate#213
PatrikBak merged 1 commit into
mainfrom
patrik/taxonomy-resequence-on-apply

Conversation

@PatrikBak

Copy link
Copy Markdown
Owner

Why

Competition / category / round sort_order in the DB is defined as the entity's 1-based index in metadata.shared.json, enforced by unique indexes (ux_competition_sort_order, ux_category_sort_order, and two partial composite round indexes). apply get-or-created only the draft's own taxonomy and never re-sequenced the rest, so inserting or reordering a competition mid-array left the later rows at their old orders — and the next apply that created an entity at a now-occupied index died with an opaque Postgres 23505. validate didn't catch it: its preview only probed create-vs-reuse, never sort order.

What

  • apply is now the authoritative re-sequencer. Before creating anything, it reconciles the families a draft can shift — competitions and categories (global spaces) and the target competition's rounds — to their registry positions, freeing the slot a new entity will claim.
  • Two-phase renumber (TaxonomyResequencer): park every mover just past the live range, flush, then number 1..N (all targets below the parked range), wrapped in one transaction so a mid-run failure can't leave parked values committed. PostgreSQL checks a non-deferrable unique index per-row, so this vacate-then-fill is required — it mirrors the existing ReplaceJoinRowsAsync idiom and handles arbitrary reorderings, not just monotone shifts.
  • validate reports the pending renumbering as informational re-sequence … lines (never blocking), so the operator sees exactly what apply will do.
  • Orphan guard: a stored competition / category / round whose slug the registry can't place is surfaced as a blocking taxonomy-orphan error, instead of silently passing validate and then crashing apply.
  • The kind of taxonomy entity is a typed TaxonomyKind enum.

Covered by new Postgres integration tests (mid-array insertion, a non-monotone swap, per-round and per-category re-sequencing, the no-op case, and competition/round orphan detection).

🤖 Generated with Claude Code

Competition/category/round sort_order in the DB is defined as the entity's
1-based index in metadata.shared.json, enforced by unique indexes. apply
get-or-created only the draft's own taxonomy and never re-sequenced the rest,
so inserting or reordering a competition mid-array left the later rows at
their old orders — and the next apply that created an entity at a now-occupied
index died with an opaque Postgres 23505 on ux_competition_sort_order.

apply now reconciles the families a draft can shift (competitions, categories,
and the target competition's rounds) to their registry positions before
creating anything, via a two-phase park-past-the-end/number-1..N update that
never transiently violates the unique index. validate previews and reports the
pending renumbering (informational, never blocking), and a stored taxonomy row
whose slug the registry can't place is surfaced as a blocking orphan rather
than crashing apply.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
math-comps Ready Ready Preview, Comment Jun 19, 2026 12:16pm

@PatrikBak PatrikBak enabled auto-merge June 19, 2026 12:15
@PatrikBak PatrikBak merged commit 18f0873 into main Jun 19, 2026
5 checks passed
@PatrikBak PatrikBak deleted the patrik/taxonomy-resequence-on-apply branch June 19, 2026 12:19
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