feat: implement patch#40
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis release (v26.05.05) introduces badge award detail pages with OG image sharing, dynamic badge rarity computation, pack/topic export in multiple formats, admin user role management, reaction drill-down UI, a refined Elo system with history tracking and a new pairwise calculation model, stat card refactoring, and a "non-click" difficulty-rate signal for unrevealed questions. Database schema gains per-player Elo snapshots; multiple new API endpoints and React components are added across the codebase. ChangesBadge Award Details & Rarity System
Pack & Topic Export
Admin User Role Management
Reaction Breakdown UI
ELO System & Stats UI
Difficulty Rate Non-Click Signal
Release Management
Sequence Diagram(s)sequenceDiagram
participant User as User (Browser)
participant Web as Web App
participant API as API Backend
participant DB as Database
User->>Web: View badge award detail<br/>(/badges/$badgeId/awards/$awardId)
activate Web
Web->>API: orpc.badge.findAward($awardId)
activate API
API->>DB: SELECT award + badge + user + game + topic
DB-->>API: award data
API-->>Web: award metadata
deactivate API
Web->>Web: Generate SEO metadata +<br/>OG image URL
Web-->>User: Render award page<br/>+ share button
deactivate Web
User->>User: Click "Copy share link"
User->>Web: Copy canonical URL
Web-->>User: Success toast
User->>User: Share on social media<br/>(OG image preview)
User->>Web: GET /api/og/badges/$badgeId/awards/$awardId/og.png
activate Web
Web->>API: getBadgeAwardOgData($awardId)
activate API
API->>DB: SELECT award + badge + user
DB-->>API: award + badge data
API-->>Web: OG data payload
deactivate API
Web->>Web: Render BadgeAwardOg template
Web-->>User: OG PNG image
deactivate Web
sequenceDiagram
participant User as User (Browser)
participant Web as Web App
participant API as API Backend
participant DB as Database
User->>Web: View badges directory
activate Web
Web->>API: orpc.badge.getCatalogStats()
activate API
API->>DB: SELECT COUNT(DISTINCT player_badge_award.id)<br/>+ COUNT(DISTINCT user_id) per badge<br/>+ COUNT(DISTINCT user_id) total
DB-->>API: catalog stats
API-->>Web: { rows: [...], totalEligibleUsers }
deactivate API
Web->>Web: For each badge:<br/>rarity = computeBadgeRarity(<br/>uniqueEarners,<br/>totalEligibleUsers)
User->>Web: Filter by rarity / earned status /<br/>sort by rarity/name/earns
Web->>Web: Filter + sort badges using<br/>catalog stats + rarity ranks
Web-->>User: Render directory with<br/>rarity tiers + stats
deactivate Web
User->>Web: Click badge → View earners
activate Web
Web->>API: orpc.badge.listEarners()<br/>with filters (username, dateRange, etc.)
activate API
API->>DB: SELECT * FROM player_badge_award<br/>WHERE badges match filters
DB-->>API: earned rows
API-->>Web: paginated earners
deactivate API
Web-->>User: Render earners list<br/>+ link to award detail
deactivate Web
sequenceDiagram
participant User as User (Browser)
participant Web as Web App
participant API as API Backend
participant DB as Database
User->>Web: View profile stats tab
activate Web
Web->>API: orpc.user.getEloHistory()<br/>{ username, limit: 30 }
activate API
API->>DB: SELECT game, rank, elo snapshot fields<br/>FROM player WHERE user matches<br/>ORDER BY game.finishedAt DESC
DB-->>API: ordered Elo history rows
API-->>Web: { items: [...] }
deactivate API
Web->>Web: Reverse history (oldest→newest)<br/>Map to chart data
Web->>Web: computeEloTrendChart(history)
Web-->>User: Render EloTrendChart<br/>+ historical deltas
Web->>API: orpc.user.getMyStats()
activate API
API->>DB: SELECT user stats
DB-->>API: user totals<br/>+ computed derived ratios
API-->>Web: { ...stats, derived: {...ratios...} }
deactivate API
Web->>Web: Render StatsGrid<br/>with StatCard per metric<br/>using derived values + formatRatio()
Web-->>User: Stats dashboard<br/>with Elo trend + stat cards
deactivate Web
sequenceDiagram
participant User as User (Browser)
participant Web as Web App
participant API as API Backend
User->>Web: Open pack/topic edit page
activate Web
Web-->>User: Render page with<br/>export menu button
deactivate Web
User->>Web: Click "Export pack"<br/>→ Select format (JSON/YAML/XML/CSV/TXT)
activate Web
Web->>API: orpc.pack.export()<br/>{ slug, format }
activate API
API->>API: exportPack():<br/>fetch pack + topics + questions,<br/>authorize (author/staff),<br/>serialize to format
API-->>Web: { filename, mimeType, body }
deactivate API
Web->>Web: createObjectURL(blob)<br/>Trigger browser download
Web->>Web: Revoke object URL
Web-->>User: File downloaded
Web-->>User: Success toast
deactivate Web
sequenceDiagram
participant User as User (Browser)
participant Web as Web App
participant API as API Backend
participant DB as Database
User->>Web: View post/comment reactions
activate Web
Web->>Web: Show reaction counts
Web-->>User: Reaction summary (emoji + counts)
deactivate Web
User->>Web: Click reaction type to drill down
activate Web
Web->>Web: Switch dialog view → "reactors"
Web->>API: orpc.reaction.listReactors()<br/>{ postId, type, limit, cursor }
activate API
API->>DB: SELECT id, type, createdAt, user fields<br/>FROM reaction WHERE postId + type<br/>ORDER BY createdAt DESC<br/>LIMIT + cursor pagination
DB-->>API: reactor rows
API-->>Web: { items, nextCursor }
deactivate API
Web->>Web: Render ReactorList<br/>with avatars + reaction emoji
Web-->>User: Drilled-down reactor list
User->>Web: Click "Load more"
Web->>API: orpc.reaction.listReactors()<br/>{ postId, type, cursor: nextCursor }
activate API
API->>DB: Fetch next page
DB-->>API: more reactor rows
API-->>Web: next items + cursor
deactivate API
Web->>Web: Append to list
Web-->>User: More reactors loaded
deactivate Web
sequenceDiagram
participant Game as Game Finalization
participant Elo as ELO Calculator
participant DB as Database
Game->>Elo: calculateEloDeltas(players[], options)
activate Elo
loop For each player P
loop Against each other player O
Elo->>Elo: expectedCorrect(P.rating, O.rating)
Elo->>Elo: actualOutcome = <br/>blended(P.rank, P.score,<br/>O.rank, O.score)
Elo->>Elo: delta_contribution +=<br/>(actualOutcome - expectedCorrect)<br/>× K_factor(P.gamesPlayedBefore)
end
Elo->>Elo: Apply accuracy modifier<br/>from correctAnswers/total
Elo->>Elo: Clamp delta to [-K, K]
Elo->>Elo: Map P.id → rounded delta
end
Elo-->>Game: Map<playerId, delta>
deactivate Elo
Game->>DB: For each player:<br/>eloRatingAfter = eloRatingBefore + delta<br/>Store snapshot (before, after, delta)
activate DB
DB-->>Game: Updated
deactivate DB
Estimated Code Review Effort🎯 5 (Critical) | ⏱️ ~120 minutes This is a substantial multi-feature release spanning 7 distinct cohorts with significant logic density (ELO calculation model overhaul, export serialization across formats, dynamic rarity computation), database schema changes, API endpoint proliferation (~8 new endpoints), and UI refactoring across multiple pages. The variety of domain-specific reasoning required (game logic, export formats, admin authorization, OG image generation, dynamic rarity ranking) and the breadth of files affected (40+ modified, 20+ new) necessitate careful line-by-line review to ensure correctness of calculations, authorization checks, data consistency, and UI state management. Possibly Related PRs
Suggested Labels
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
Summary by CodeRabbit
Release Notes — v26.05.05
New Features
Improvements