432 lines
18 KiB
Markdown
432 lines
18 KiB
Markdown
|
|
# Phase 2.7 Testing Instructions
|
||
|
|
|
||
|
|
**Phase:** 2.7 - Simple Template Expansion (16, 32 teams)
|
||
|
|
**Status:** Completed
|
||
|
|
**Date:** 2025-01-04
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Phase 2.7 adds support for larger bracket templates (16-team and 32-team) with non-scoring rounds. Only participants who reach the Elite Eight (top 8) score fantasy points. Early eliminations receive 0 points per Q20.
|
||
|
|
|
||
|
|
## Phase 2.7 Testing Checklist
|
||
|
|
|
||
|
|
### 1. **Bracket Generation UI** (`/admin/sports-seasons/:id/events/:eventId/bracket`)
|
||
|
|
|
||
|
|
**Test the template selector:**
|
||
|
|
- [ ] Navigate to a playoff event that has no bracket yet
|
||
|
|
- [ ] See a "Bracket Template" dropdown with all options:
|
||
|
|
- Simple 4-Team Bracket - 4 teams
|
||
|
|
- Simple 8-Team Bracket - 8 teams
|
||
|
|
- Simple 16-Team Bracket - 16 teams
|
||
|
|
- Simple 32-Team Bracket - 32 teams
|
||
|
|
- NCAA March Madness (68 teams) - 68 teams
|
||
|
|
- NFL Playoffs (14 teams) - 14 teams
|
||
|
|
- NBA Playoffs (16 teams) - 16 teams
|
||
|
|
- [ ] Change template selection - participant count should update dynamically
|
||
|
|
- [ ] See round progression text (e.g., "Rounds: Round of 16 → Quarterfinals → Semifinals → Finals")
|
||
|
|
|
||
|
|
### 2. **16-Team Bracket Creation**
|
||
|
|
|
||
|
|
**Generate a 16-team bracket:**
|
||
|
|
- [ ] Select "Simple 16-Team Bracket"
|
||
|
|
- [ ] Fill in 16 participants (seeds 1-16)
|
||
|
|
- [ ] Click "Generate Bracket"
|
||
|
|
- [ ] Verify success message
|
||
|
|
|
||
|
|
**Check bracket structure:**
|
||
|
|
- [ ] See "Round of 16" section with 8 matches
|
||
|
|
- [ ] See "Quarterfinals" section with 4 matches (TBD participants)
|
||
|
|
- [ ] See "Semifinals" section with 2 matches (TBD participants)
|
||
|
|
- [ ] See "Finals" section with 1 match (TBD participants)
|
||
|
|
|
||
|
|
**Complete Round of 16:**
|
||
|
|
- [ ] Set winners for all 8 matches
|
||
|
|
- [ ] Winners should auto-advance to Quarterfinals
|
||
|
|
- [ ] Click "Complete Round & Calculate Placements"
|
||
|
|
- [ ] Select "Round of 16" from dropdown
|
||
|
|
- [ ] Verify **8 losers get 0 fantasy points** (early elimination per Q20)
|
||
|
|
|
||
|
|
**Complete Quarterfinals:**
|
||
|
|
- [ ] Set winners for all 4 matches
|
||
|
|
- [ ] Winners advance to Semifinals
|
||
|
|
- [ ] Complete the round
|
||
|
|
- [ ] Verify **4 losers share 5th-8th place** (20 points each with default scoring)
|
||
|
|
|
||
|
|
**Complete Semifinals:**
|
||
|
|
- [ ] Set winners for 2 matches
|
||
|
|
- [ ] Winners advance to Finals
|
||
|
|
- [ ] Complete the round
|
||
|
|
- [ ] Verify **2 losers share 3rd-4th place** (45 points each)
|
||
|
|
|
||
|
|
**Complete Finals:**
|
||
|
|
- [ ] Set winner
|
||
|
|
- [ ] Complete the round
|
||
|
|
- [ ] Verify **winner gets 1st** (100 points), **loser gets 2nd** (70 points)
|
||
|
|
- [ ] Navigate back to event detail page (click "Back to Event" or navigate to `/admin/sports-seasons/{id}/events/{eventId}`)
|
||
|
|
- [ ] See new "Fantasy Points Awarded" card showing all participant results with positions and points
|
||
|
|
- [ ] Verify early eliminations show "Early Elimination" with 0 points
|
||
|
|
- [ ] Verify top 8 finishers show correct positions (1st-8th) with correct point totals
|
||
|
|
|
||
|
|
### 3. **Batch Winner Selection (NEW)**
|
||
|
|
|
||
|
|
**Test the batch winner selection UI:**
|
||
|
|
- [ ] Navigate to any generated bracket (16 or 32-team)
|
||
|
|
- [ ] See winner dropdowns for each incomplete match
|
||
|
|
- [ ] Select a winner for one match - verify no submit button appears yet
|
||
|
|
- [ ] Select winners for 2-3 matches in a round
|
||
|
|
- [ ] Verify "Save X Winner(s) for [Round]" button appears
|
||
|
|
- [ ] Click the batch save button
|
||
|
|
- [ ] Verify success message shows correct count
|
||
|
|
- [ ] Verify all selected winners are set
|
||
|
|
- [ ] Verify winners auto-advance to next round
|
||
|
|
- [ ] Verify winner dropdowns are cleared after submission
|
||
|
|
|
||
|
|
**Test error handling:**
|
||
|
|
- [ ] Try to submit with no winners selected - should not see button
|
||
|
|
- [ ] Select winners for matches in different rounds - each round has separate button
|
||
|
|
- [ ] Test partial success scenario (if possible to trigger)
|
||
|
|
|
||
|
|
**Test workflow efficiency:**
|
||
|
|
- [ ] Set all 8 winners for Round of 16 at once
|
||
|
|
- [ ] Verify all 8 winners advance to Quarterfinals correctly
|
||
|
|
- [ ] Set all 4 Quarterfinals winners at once
|
||
|
|
- [ ] Verify advancement and placement calculation
|
||
|
|
|
||
|
|
### 4. **32-Team Bracket Creation**
|
||
|
|
|
||
|
|
**Generate a 32-team bracket:**
|
||
|
|
- [ ] Select "Simple 32-Team Bracket"
|
||
|
|
- [ ] Fill in 32 participants
|
||
|
|
- [ ] Generate bracket
|
||
|
|
- [ ] See 5 rounds: Round of 32 → Round of 16 → Quarterfinals → Semifinals → Finals
|
||
|
|
|
||
|
|
**Test non-scoring rounds:**
|
||
|
|
- [ ] Complete Round of 32 (16 matches)
|
||
|
|
- [ ] Verify **16 losers get 0 points** (non-scoring round)
|
||
|
|
- [ ] Complete Round of 16 (8 matches)
|
||
|
|
- [ ] Verify **8 losers get 0 points** (non-scoring round)
|
||
|
|
- [ ] Complete Quarterfinals through Finals
|
||
|
|
- [ ] Verify scoring matches Q20: Only top 8 finishers get points
|
||
|
|
|
||
|
|
**Final tally check:**
|
||
|
|
- [ ] Total participants: 32
|
||
|
|
- [ ] Participants with 0 points: 24 (Round of 32 + Round of 16 losers)
|
||
|
|
- [ ] Participants scoring: 8 (QF losers through Champion)
|
||
|
|
|
||
|
|
### 4. **Template-Based Advancement**
|
||
|
|
|
||
|
|
**Verify auto-advancement works:**
|
||
|
|
- [ ] In any multi-round bracket, set a winner in Round 1
|
||
|
|
- [ ] Check that winner appears in correct slot in Round 2
|
||
|
|
- [ ] Match advancement pattern:
|
||
|
|
- Match 1 winner → Next round Match 1, Participant 1
|
||
|
|
- Match 2 winner → Next round Match 1, Participant 2
|
||
|
|
- Match 3 winner → Next round Match 2, Participant 1
|
||
|
|
- Match 4 winner → Next round Match 2, Participant 2
|
||
|
|
|
||
|
|
### 5. **Scoring Calculator Integration**
|
||
|
|
|
||
|
|
**Check participant results:**
|
||
|
|
- [ ] After completing a round, check database `participantResults` table
|
||
|
|
- [ ] Non-scoring round losers should have `finalPosition = 0`
|
||
|
|
- [ ] Scoring round participants should have correct placements (1-8)
|
||
|
|
|
||
|
|
**Verify team standings update:**
|
||
|
|
- [ ] If you have teams that drafted these participants
|
||
|
|
- [ ] Check that standings recalculate after each round completion
|
||
|
|
- [ ] Early elimination participants (0 points) should not add to team score
|
||
|
|
|
||
|
|
### 6. **Error Handling**
|
||
|
|
|
||
|
|
**Test validation:**
|
||
|
|
- [ ] Try to generate bracket without selecting all participants → error
|
||
|
|
- [ ] Try to select same participant twice → "Each participant can only be selected once"
|
||
|
|
- [ ] Try to set winner when participants aren't assigned → should be disabled
|
||
|
|
- [ ] Try to complete round with incomplete matches → error
|
||
|
|
|
||
|
|
### 7. **Backward Compatibility**
|
||
|
|
|
||
|
|
**Test existing 4 and 8 team brackets:**
|
||
|
|
- [ ] Generate a "Simple 4-Team Bracket" → should work as before
|
||
|
|
- [ ] Generate a "Simple 8-Team Bracket" → should work as before
|
||
|
|
- [ ] All rounds should be scoring rounds for these templates
|
||
|
|
- [ ] No 0-point eliminations (all 4 or 8 participants score)
|
||
|
|
|
||
|
|
## Viewing Fantasy Points (NEW)
|
||
|
|
|
||
|
|
After completing rounds and calculating placements, you can view the fantasy points awarded:
|
||
|
|
|
||
|
|
**Navigation:**
|
||
|
|
1. From the bracket management page, click "Back to Event"
|
||
|
|
2. Or navigate to `/admin/sports-seasons/{sportsSeasonId}/events/{eventId}`
|
||
|
|
|
||
|
|
**Fantasy Points Awarded Card:**
|
||
|
|
- Shows all participants with calculated fantasy points
|
||
|
|
- Sorted by final position (1st place at top)
|
||
|
|
- Displays position with medals (🥇🥈🥉) for top 3
|
||
|
|
- Shows "Early Elimination" for participants with 0 points (early knockout)
|
||
|
|
- Points displayed in green for scoring participants, gray for 0 points
|
||
|
|
|
||
|
|
**Example Display:**
|
||
|
|
```
|
||
|
|
Final Position | Participant | Fantasy Points
|
||
|
|
1st 🥇 | Arizona | 100 pts
|
||
|
|
2nd 🥈 | UConn | 70 pts
|
||
|
|
3rd 🥉 | Houston | 45 pts
|
||
|
|
4th | Duke | 45 pts
|
||
|
|
5th | Kansas | 20 pts
|
||
|
|
6th | Purdue | 20 pts
|
||
|
|
7th | Tennessee | 20 pts
|
||
|
|
8th | North Carolina | 20 pts
|
||
|
|
Early Elim. | UCLA | 0 pts
|
||
|
|
Early Elim. | Alabama | 0 pts
|
||
|
|
...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Note:** Team standings (total points across all events) are not yet displayed in the UI but are being calculated and stored in the database.
|
||
|
|
|
||
|
|
## Key Expected Behaviors
|
||
|
|
|
||
|
|
### Non-Scoring Rounds (Q20)
|
||
|
|
- Round of 16 in 16-team bracket: 8 teams get 0 points
|
||
|
|
- Round of 32 + Round of 16 in 32-team bracket: 24 teams get 0 points
|
||
|
|
- Early eliminations don't count toward team standings
|
||
|
|
|
||
|
|
### Scoring Rounds
|
||
|
|
- Only Quarterfinals and beyond score fantasy points
|
||
|
|
- Always exactly 8 participants score (1st through 8th)
|
||
|
|
- Point distribution per default scoring:
|
||
|
|
- 1st: 100, 2nd: 70
|
||
|
|
- 3rd/4th (avg): 45 each
|
||
|
|
- 5th-8th (avg): 20 each
|
||
|
|
- Total: 340 points
|
||
|
|
|
||
|
|
### Template Storage
|
||
|
|
- Check `scoringEvents` table has `bracketTemplateId` stored
|
||
|
|
- Check `scoringEvents` table has `scoringStartsAtRound` stored
|
||
|
|
- Check `playoffMatches` have `isScoring` flag set correctly
|
||
|
|
|
||
|
|
## Things NOT to Test Yet (Phase 2.8+)
|
||
|
|
|
||
|
|
- ❌ NCAA 68-team bracket generation (won't assign participants correctly)
|
||
|
|
- ❌ NFL 14-team with bye weeks
|
||
|
|
- ❌ First Four play-in games
|
||
|
|
- ❌ TBD slot handling
|
||
|
|
|
||
|
|
## Database Verification Queries
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- Check event has template ID stored
|
||
|
|
SELECT id, name, bracketTemplateId, scoringStartsAtRound
|
||
|
|
FROM scoring_events
|
||
|
|
WHERE id = 'your-event-id';
|
||
|
|
|
||
|
|
-- Check matches have isScoring flag
|
||
|
|
SELECT round, matchNumber, isScoring, participant1Id, participant2Id, winnerId
|
||
|
|
FROM playoff_matches
|
||
|
|
WHERE scoringEventId = 'your-event-id'
|
||
|
|
ORDER BY round, matchNumber;
|
||
|
|
|
||
|
|
-- Check participant results after round completion
|
||
|
|
SELECT p.name, pr.finalPosition, pr.qualifyingPoints
|
||
|
|
FROM participant_results pr
|
||
|
|
JOIN participants p ON p.id = pr.participantId
|
||
|
|
WHERE pr.sportsSeasonId = 'your-sports-season-id'
|
||
|
|
ORDER BY pr.finalPosition;
|
||
|
|
|
||
|
|
-- Check team standings
|
||
|
|
SELECT t.name, ts.totalPoints, ts.currentRank,
|
||
|
|
ts.firstPlaceCount, ts.secondPlaceCount, ts.thirdPlaceCount, ts.fourthPlaceCount,
|
||
|
|
ts.fifthPlaceCount, ts.sixthPlaceCount, ts.seventhPlaceCount, ts.eighthPlaceCount
|
||
|
|
FROM team_standings ts
|
||
|
|
JOIN teams t ON t.id = ts.teamId
|
||
|
|
WHERE ts.seasonId = 'your-season-id'
|
||
|
|
ORDER BY ts.currentRank;
|
||
|
|
```
|
||
|
|
|
||
|
|
## Bug Fixes
|
||
|
|
|
||
|
|
### Bug #1: Round of 16 and other non-standard rounds not displaying (Fixed)
|
||
|
|
**Issue:** When creating a 16-team bracket, only Quarterfinals, Semifinals, and Finals were displayed. Round of 16 was missing.
|
||
|
|
|
||
|
|
**Root Cause:**
|
||
|
|
- Client component had hardcoded rounds array: `["Quarterfinals", "Semifinals", "Finals"]`
|
||
|
|
- Server validation also had hardcoded round checking
|
||
|
|
|
||
|
|
**Fix:**
|
||
|
|
- Changed to dynamically get rounds from actual matches: `Array.from(new Set(matches.map(m => m.round)))`
|
||
|
|
- Updated server validation to check if round exists in matches instead of hardcoding allowed values
|
||
|
|
- Files changed:
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.bracket.tsx` (line 54)
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.bracket.server.ts` (lines 178-196)
|
||
|
|
|
||
|
|
**Status:** ✅ Fixed and tested.
|
||
|
|
|
||
|
|
### Bug #2: Sequential seeding instead of tournament-style seeding (Fixed)
|
||
|
|
**Issue:** When creating a 16-team bracket with participants seeded 1-16, the bracket showed:
|
||
|
|
- Match 1: Seed 1 vs Seed 2 (Arizona vs Atlanta)
|
||
|
|
- Match 2: Seed 3 vs Seed 4
|
||
|
|
- etc.
|
||
|
|
|
||
|
|
Instead of proper tournament seeding:
|
||
|
|
- Match 1: Seed 1 vs Seed 16
|
||
|
|
- Match 2: Seed 8 vs Seed 9
|
||
|
|
- etc.
|
||
|
|
|
||
|
|
**Root Cause:**
|
||
|
|
- Bracket generation assigned participants sequentially instead of using standard tournament seeding algorithm
|
||
|
|
|
||
|
|
**Fix:**
|
||
|
|
- Added `generateStandardSeeding()` function that creates balanced bracket matchups
|
||
|
|
- Algorithm ensures:
|
||
|
|
- All matchups sum to n+1 (e.g., 1v16, 2v15, 3v14 all sum to 17 for 16 teams)
|
||
|
|
- Top seeds are separated into different bracket regions
|
||
|
|
- Balanced pods for each quarterfinal section
|
||
|
|
- Added `seedInfo` field to store display text (e.g., "1 vs 16")
|
||
|
|
- Works for 4, 8, 16, and 32-team brackets
|
||
|
|
- Non-standard sizes (68, 14) fall back to sequential until custom logic is implemented
|
||
|
|
|
||
|
|
**Files changed:**
|
||
|
|
- `app/models/playoff-match.ts` (lines 255-369)
|
||
|
|
- New test file: `app/models/__tests__/bracket-seeding.test.ts` (14 tests)
|
||
|
|
|
||
|
|
**Status:** ✅ Fixed and tested. All 221 tests passing.
|
||
|
|
|
||
|
|
### QOL Improvement: Duplicate participant prevention (Implemented)
|
||
|
|
**Feature:** When selecting participants for bracket seeds, once a participant is selected for one seed, they are automatically removed from the dropdown options for all other seeds.
|
||
|
|
|
||
|
|
**How it works:**
|
||
|
|
- Each seed dropdown only shows participants that haven't been selected yet
|
||
|
|
- If you select "Arizona" as Seed 1, "Arizona" disappears from all other seed dropdowns
|
||
|
|
- Changing the bracket template resets all selections
|
||
|
|
- Real-time updates as you make selections
|
||
|
|
|
||
|
|
**Benefits:**
|
||
|
|
- Prevents duplicate selections (the server already validated this, but now it's prevented in the UI)
|
||
|
|
- Clearer UX - you can see which participants are still available
|
||
|
|
- Faster bracket setup - no need to remember which teams you've already picked
|
||
|
|
|
||
|
|
**Files changed:**
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.bracket.tsx` (lines 40-68, 141, 167-190)
|
||
|
|
- Added `selectedParticipants` state to track selections
|
||
|
|
- Added `handleTemplateChange` to reset selections on template change
|
||
|
|
- Added `handleParticipantChange` to update selections
|
||
|
|
- Added `getAvailableParticipants` to filter out selected participants
|
||
|
|
- Updated Select components to use controlled state and filtered options
|
||
|
|
|
||
|
|
**Status:** ✅ Implemented and tested. All 221 tests passing.
|
||
|
|
|
||
|
|
### QOL Improvement #2: Batch winner selection (Implemented)
|
||
|
|
**Feature:** Instead of having individual "Set" buttons for each match, users can now select winners for multiple matches in a round and submit them all with a single button click.
|
||
|
|
|
||
|
|
**How it works:**
|
||
|
|
- Each match in a round has a winner dropdown (controlled component)
|
||
|
|
- Select winners for one or more matches
|
||
|
|
- A "Save X Winner(s) for [Round]" button appears at the bottom of the round card
|
||
|
|
- Click the button to submit all selected winners at once
|
||
|
|
- Winners are automatically advanced to the next round
|
||
|
|
- Selected winners are cleared after successful submission
|
||
|
|
|
||
|
|
**Benefits:**
|
||
|
|
- Faster workflow - set multiple winners at once instead of one at a time
|
||
|
|
- Better UX - clear visual indication of pending selections
|
||
|
|
- Fewer page reloads - batch submission reduces server round trips
|
||
|
|
- Consistent advancement - all winners advance in a single operation
|
||
|
|
|
||
|
|
**Implementation details:**
|
||
|
|
- Client-side state tracking with `selectedWinners` state
|
||
|
|
- Server-side batch processing with new "set-round-winners" intent
|
||
|
|
- Automatic state cleanup after successful submission via useEffect
|
||
|
|
- Error handling for partial success scenarios
|
||
|
|
|
||
|
|
**Files changed:**
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.bracket.tsx` (lines 1-2, 40-51, 294-334)
|
||
|
|
- Added useEffect import
|
||
|
|
- Added batch winner state management
|
||
|
|
- Replaced Form-wrapped Select with controlled Select components
|
||
|
|
- Added batch submit button per round
|
||
|
|
- Added useEffect to clear selections after success
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.bracket.server.ts` (lines 175-276)
|
||
|
|
- Added "set-round-winners" intent handler
|
||
|
|
- Processes multiple winner assignments in batch
|
||
|
|
- Handles partial success with detailed error messages
|
||
|
|
|
||
|
|
**Status:** ✅ Implemented and tested. All 221 tests passing.
|
||
|
|
|
||
|
|
### QOL Improvement #3: Fantasy points display on event page (Implemented)
|
||
|
|
**Feature:** After completing rounds and calculating placements, users can now view the fantasy points awarded to each participant on the event detail page.
|
||
|
|
|
||
|
|
**How it works:**
|
||
|
|
- Navigate to the event detail page (`/admin/sports-seasons/{id}/events/{eventId}`)
|
||
|
|
- See "Fantasy Points Awarded" card with all participant results
|
||
|
|
- Sorted by final position (1st place at top)
|
||
|
|
- Shows position, participant name, and fantasy points
|
||
|
|
- Early eliminations (0 points) clearly marked
|
||
|
|
|
||
|
|
**Benefits:**
|
||
|
|
- Instant verification of point calculations
|
||
|
|
- Visual confirmation of bracket completion
|
||
|
|
- Easy reference for standings verification
|
||
|
|
- Clear distinction between scoring and non-scoring participants
|
||
|
|
|
||
|
|
**Implementation details:**
|
||
|
|
- Loader fetches `participant_results` from database
|
||
|
|
- Includes participant relation for name display
|
||
|
|
- Client sorts by `finalPosition` ascending
|
||
|
|
- Displays medals for top 3 finishers
|
||
|
|
- Color-codes points (green for scoring, gray for 0)
|
||
|
|
|
||
|
|
**Files changed:**
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.server.ts` (lines 1, 16, 31-43)
|
||
|
|
- Added import for `findParticipantResultsBySportsSeasonId`
|
||
|
|
- Added `participantResults` to loader return data
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.tsx` (lines 38, 292-368)
|
||
|
|
- Added `participantResults` to destructured loader data
|
||
|
|
- Added "Fantasy Points Awarded" card with table
|
||
|
|
- Displays position, participant, and points with proper formatting
|
||
|
|
|
||
|
|
**Status:** ✅ Implemented and tested. All 221 tests passing.
|
||
|
|
|
||
|
|
### Bug #3: Round cards displaying in wrong order (Fixed)
|
||
|
|
**Issue:** When setting a winner in Round of 16, the round cards would shuffle and display in incorrect order (e.g., "Semifinals, Quarterfinals, Round of 16, Finals" instead of chronological order).
|
||
|
|
|
||
|
|
**Root Cause:**
|
||
|
|
- Rounds were being displayed in the order they appeared from the database query
|
||
|
|
- Database ordering was based on match results, not chronological tournament progression
|
||
|
|
- As matches completed and were updated, the database result order could change
|
||
|
|
|
||
|
|
**Fix:**
|
||
|
|
- Added `getOrderedRounds()` function that uses the bracket template's round order
|
||
|
|
- If event has a `bracketTemplateId`, uses the template's chronological round order
|
||
|
|
- Filters to only show rounds that have matches
|
||
|
|
- Falls back to database order if no template is available
|
||
|
|
|
||
|
|
**How it works now:**
|
||
|
|
1. Get unique rounds from matches
|
||
|
|
2. If event has bracket template, get template
|
||
|
|
3. Use template's round order (first round → finals)
|
||
|
|
4. Filter to only rounds that exist in matches
|
||
|
|
5. Display cards in correct chronological order
|
||
|
|
|
||
|
|
**Example:**
|
||
|
|
- **16-team bracket:** Round of 16 → Quarterfinals → Semifinals → Finals
|
||
|
|
- **32-team bracket:** Round of 32 → Round of 16 → Quarterfinals → Semifinals → Finals
|
||
|
|
- Order remains stable even as matches are completed
|
||
|
|
|
||
|
|
**Files changed:**
|
||
|
|
- `app/routes/admin.sports-seasons.$id.events.$eventId.bracket.tsx` (lines 23, 79-98, 221, 330)
|
||
|
|
- Imported `getBracketTemplate`
|
||
|
|
- Added `getOrderedRounds()` function
|
||
|
|
- Updated round mapping to include type annotations
|
||
|
|
|
||
|
|
**Status:** ✅ Fixed and tested. All 221 tests passing.
|
||
|
|
|
||
|
|
## Known Issues
|
||
|
|
|
||
|
|
None at this time. All 221 tests passing (207 original + 14 seeding tests).
|
||
|
|
|
||
|
|
## Notes
|
||
|
|
|
||
|
|
- Phase 2.8 will add full NCAA 68-team bracket support with First Four play-in games
|
||
|
|
- NFL 14-team and NBA 16-team templates exist but need bye week logic (Phase 2.9)
|