Commit graph

6 commits

Author SHA1 Message Date
Chris Parsons
09b9b9bdad
Optimize user data fetching with batch queries and centralize display name logic (#176)
* Fall back to displayName when username is null for Discord webhook

Users who sign up via OAuth (Google, GitHub, etc.) without setting a
Clerk username have a null `username` field but always have a `displayName`
(computed from firstName+lastName or email). Previously, `usernameByClerkId`
was filtered to only include users with a non-null username, causing those
owners to appear without any identifier in Discord standings messages
(e.g. "Liverpool def. Galatasaray" instead of "Liverpool def. Galatasaray (Madmike)").

https://claude.ai/code/session_01VAkeDDVZMYS1DweQnUrRnH

* Extract getUserDisplayName helper and use consistently throughout

Add a single getUserDisplayName(user) function to app/models/user.ts that
encapsulates the username → displayName fallback logic. Replace 9 scattered
inline expressions across the codebase (owner-map, scoring-calculator,
league routes, settings, invite flow, draft API, Clerk webhook) with calls
to the shared helper.

No behaviour change — all existing logic preserved, just centralised.

https://claude.ai/code/session_01VAkeDDVZMYS1DweQnUrRnH

* Fix N+1 user queries in league loader and settings loader

Add findUsersByClerkIds() batch function to the user model and replace two
separate Promise.all+findUserByClerkId loops (one for owners, one for
commissioners) with a single inArray query in both $leagueId.server.ts and
$leagueId.settings.tsx. The merged query covers both owner and commissioner
IDs in one round-trip.

https://claude.ai/code/session_01VAkeDDVZMYS1DweQnUrRnH

* Fix N+1 user queries in buildOwnerMap

Replace the Promise.all+findUserByClerkId loop with a single
findUsersByClerkIds batch query, consistent with the league loader
and settings loader fixes.

https://claude.ai/code/session_01VAkeDDVZMYS1DweQnUrRnH

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-18 16:46:07 -07:00
Chris Parsons
cf8ac8a765
feat: progressive floor scoring for playoff brackets (#100)
When a participant wins a bracket round, they immediately earn provisional
"floor" points (the averaged minimum they'd receive if eliminated next round).
These update as they advance and are replaced by finalized scores on elimination.

Key changes:
- Add `is_partial_score` column to `participant_results` (migration 0038)
- `processPlayoffEvent`: assign provisional position 5 to non-scoring round
  winners; assign round-appropriate floors to scoring round winners via
  `getGuaranteedMinimumPosition`; add catch-all for unrecognized round names
- `upsertParticipantResult`: guard against un-finalizing rows (never overwrite
  isPartialScore=false with true)
- `calculateBracketPoints`: new function averaging tied bracket tiers
  (5-8 → 20 pts, 3-4 → avg, 1-2 solo); used in `calculateTeamScore` for
  playoff_bracket pattern (pattern-aware, doesn't affect F1/golf scoring)
- `PlayoffBracket`: "In Contention" table for still-active participants;
  AFL double-chance fix (participants who won a later match excluded from
  earlier round's loser list); correct `nextRank` starting position
- Server loader: batch owner DB queries (one query vs N+1); deduplicate
  participantPoints; use calculateBracketPoints for bracket point display
- Clean up Phase/Q-number tracking comments throughout scoring-calculator.ts
- 3 new tests for non-scoring round provisional floor behavior

Also includes a dev admin bypass via DEV_ADMIN_CLERK_ID env var (separate
change on this branch, not part of floor scoring feature).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 10:27:58 -07:00
Chris Parsons
ee125565dd feat: add team ownership management UI with admin controls 2025-10-21 22:15:15 -07:00
Chris Parsons
61929536a1 feat: add username field to users and display in league views 2025-10-14 21:20:58 -07:00
Chris Parsons
dc727b6f3f feat: add sports and participant models with admin user functionality 2025-10-12 21:16:00 -07:00
Chris Parsons
9749fc8b77 feat: add user model, routes, and Clerk webhook integration 2025-10-11 00:53:39 -07:00