Repository navigation
Audit fixes: hardening, R32 seating guards, and super-admin analytics - #139
Merged
Merged
Conversation
added 5 commits
July 9, 2026 00:54
…tracking Adds an admin-only analytics dashboard (/admin/analytics) tracking user engagement across all pools, plus the event-logging layer that feeds it. - AnalyticsEvent model + enum (audit-style plain-id FKs, no relations/cascade, indexed by day/type/user) — additive and non-breaking, mirroring the PrizeAward/Feedback precedent. Migration + regenerated client included. - logEvent: best-effort write that never throws or breaks the triggering action (mirrors notifyPool). Instrumented at sign-in/up, pool create, pool join (code + invite, new members only), bracket submit, chat message, reaction. - Pure, unit-tested rollups (UTC day bucketing, DAU/WAU/MAU, type breakdown, top pools, stickiness) split from the DB query layer. - Dashboard gated by getTournamentAdmin (fail-closed), custom Tailwind bar charts (no new deps), linked from the admin page. MAU/stickiness fetch window covers the full rolling 30d boundary so late-day actives aren't clipped.
… the bracket slot The answer key stores third-place advancers as an ordered list whose order drives R32 seating (resolveR32Slots backtracks in list order). A standings re-save with the same eight teams in a different order silently re-seated the live bracket — orphaning recorded winners, breaking pair-map fixture mapping, and corrupting every seed-derived surface (this happened in prod mid-R32). - setGroupStandings now preserves the stored order when the submitted set is unchanged (mergeThirdAdvance), and rejects any seating that contradicts a recorded knockout winner (findKnockoutSeatingConflict). - setKnockoutResultLocked now orients API-reported scores/pens to the bracket slot (orientScoresToSlot) before mirroring, matching the live-row path — the FINAL row could previously flip against winnerCode whenever the provider's home differed from the bracket's home (exactly the pens ties in play now).
- getKnockoutChallengeProfile now requires board membership (which carries the verified-email anti-Sybil gate): it previously rendered gated entries' full picks with a fabricated rank, and its pick-share denominators now match the public board population. - MD3 form/breakdown pin kickoff day/time labels to DISPLAY_TZ (the form was a hydration mismatch, the breakdown rendered UTC times and split late fixtures across wrong day headers). - Chat pins its own scroll box instead of scrollIntoView, which scrolled every ancestor and yanked live match pages down to the embedded chat on mount. - R32Countdown seeds its passed state from the clock so a past kickoff no longer flashes a stale countdown banner on first paint.
The complete-eight-thirds set is now seated via FIFA's Annex C table (#124), which is deterministic by team, not by thirdAdvance list order — so rotating the order no longer re-seats the bracket and the test's premise no longer holds. mergeThirdAdvance and its unit tests remain (order still drives partial-draft seating via backtracking).
dommango
force-pushed
the
worktree-audit-fixes
branch
from
July 9, 2026 05:20
dfe29f3 to
fc864c0
Compare
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.
Summary
Batches accumulated audit and hardening work that never had a PR (9 commits, 31 files net vs main):
Test plan
🤖 Generated with Claude Code