M2.1: Saved Themes, Theme-Editor, Link-Expiry/Revoke, Reseeding - #4
Merged
Conversation
Polish milestone built via an orchestrated 3-slice pass + a 4-lens adversarial review (2 blockers + 1 major folded in). Type-checked (api + web exit 0) and the engine tests still pass (12/12). Backend (apps/api): - themes module: user-scoped SavedTheme CRUD (GET/POST/DELETE /themes, 401 for guests, owner-only delete). - links: optional expiresInHours on create; DELETE /tournaments/:id/links/:linkId to revoke. - reseed: PUT /tournaments/:id/seeding regenerates the bracket from a new seed order; the generation/persistence path is now a shared helper used by create() and reseed(); all guards + the destructive regenerate run in one transaction; emits an SSE change signal. Frontend (apps/web): - ThemeEditor (preset + color pickers via a new hex<->HSL util in lib/color.ts + round-trip test) with a saved-theme library gated by useSession. - SeedingEditor: dependency-free up/down reorder (dnd-kit isn't installable offline) → reseed; locked once a real result exists. - SharePanel: per-link TTL select + expiry display + revoke. Review fix (the important one): auto-advanced byes are COMPLETED but carry no score, so counting COMPLETED matches wrongly (a) flipped a fresh non-power-of-2 bracket to RUNNING and (b) locked reseeding immediately — exactly where seeding matters. Introduced isScored() (both opponents carry a numeric score) and use it for the reseed lock and status recompute; the frontend lock mirrors it. Also: retry:false on auth-gated queries. Deferred (see docs/PLAN.md): dnd-kit polish, re-score/correction, SSE multi-replica, in-app dialogs instead of window.prompt/confirm. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Politur-Meilenstein M2.1. Orchestrierter 3-Slice-Build + adversariales 4-Perspektiven-Review (2 Blocker + 1 Major eingearbeitet). Verifiziert:
tscgrün (api + web), Engine-Tests 12/12.Was drin ist
apps/api/src/themes/*): user-scopedSavedTheme-CRUD (401 für Gäste, nur eigene löschbar).ThemeEditor.tsx): Preset + Color-Picker (neuerlib/color.tsHex↔HSL-Util + Round-Trip-Test) + Theme-Bibliothek (peruseSessiongated).expiresInHoursbeim Erstellen,DELETE /tournaments/:id/links/:linkId; SharePanel zeigt Ablauf + Revoke-Button.SeedingEditor.tsx+PUT /tournaments/:id/seeding): Reihenfolge ändern → Bracket regenerieren. Reorder dependency-frei (Hoch/Runter), weil dnd-kit offline nicht installierbar war.Der wichtige Review-Fund 🔴
Auto-advancte Byes sind
COMPLETED, tragen aber keine Score. Das Zählen vonCOMPLETED-Matches hat dadurch (a) ein frisches Nicht-Zweierpotenz-Bracket sofort aufRUNNINGgekippt und (b) Reseeding sofort gesperrt — genau dort, wo Seeding zählt. Fix:isScored()(beide Opponents haben numerische Score) steuert jetzt Reseed-Lock und Status-Recompute; das Frontend-Lock spiegelt es. Reseed-Guards laufen jetzt in einer Transaktion (TOCTOU) und emittieren ein SSE-Signal.Verschoben (dokumentiert in docs/PLAN.md)
dnd-kit-Politur, Re-Scoring/Korrektur, SSE-Multi-Replica, In-App-Dialoge statt
window.prompt/confirm.Wie zuvor: DB-gestützter Flow (Reseed-Regenerate, Themes-Persistenz, SSE durch BFF) ist offline nicht real gelaufen — nur typecheck + Engine-Unit-Tests.
prisma migrate+ ein echter Start stehen noch aus.🤖 Generated with Claude Code