Files
euchre_camp/TEAM_DURABILITY_CHANGES.md
T
david 603cc238fa feat: implement variable team matchups with partner rotation
- Add manual team entry for permanent teams in Matchups tab
- Rename 'Teams' tab to 'Matchups' for clarity
- Implement partner rotation strategies (minimize_repeat, maximize_even, elo_based)
- Track partnerships across rounds to minimize repeat pairings
- Fix unit tests for team configuration and ELO calculations
- Add E2E test for 9+ participant tournaments with variable matchups

Key changes:
- TeamsSection.tsx: Added router.refresh(), manual team entry, and matchup display
- schedule-generator.ts: Enhanced generateVariableRoundRobin to track partnerships
- team-generator.ts: Fixed partnership frequency tracking across rounds
- API routes: Updated to support variable team durability with rotation strategies
2026-04-04 00:24:57 -07:00

4.5 KiB

Team Durability Options - Implementation Summary

Overview

Restructured team durability options to provide clearer, more useful choices for tournament organizers.

New Options

1. Fixed Teams (previously "Permanent")

  • Description: Teams formed once and stay fixed throughout the tournament
  • Behavior:
    • Teams are generated once at tournament start
    • Same partnerships in every round
    • Round-robin schedule between fixed teams
  • Use Case: Traditional league play where partnerships are established

2. Pre-Planned Variable (previously "Variable")

  • Description: Fresh teams each round with partner rotation, schedule pre-planned before tournament starts
  • Behavior:
    • Teams are generated fresh for each round
    • Partner rotation strategies (none, minimize_repeat, maximize_even, elo_based) apply
    • Full schedule is generated at tournament creation
    • Each round has different team pairings
  • Use Case: Social tournaments where players want to partner with different people each round

3. Dynamic/Progressive (new option, previously "Per-Round")

  • Description: Teams formed based on results, schedule progresses as rounds complete
  • Behavior:
    • Cannot pre-generate full schedule
    • Next round is scheduled after current round completes
    • Enables bracket-style or Swiss-style tournaments
    • Teams can be formed based on performance/results
  • Use Case: Single/double elimination tournaments, Swiss-system tournaments

Key Changes

API Changes (src/app/api/tournaments/[id]/schedule/route.ts)

  • Added generateVariableRoundRobin function from schedule-generator.ts
  • Refactored schedule generation into three clear code paths:
    1. Fixed Teams: Generate once, apply round-robin
    2. Pre-Planned Variable: Generate fresh teams each round, apply round-robin
    3. Dynamic: Return requiresDynamicScheduling: true flag
  • Fixed round count calculation (was using participant count instead of team count)

Database Changes

  • No schema changes needed - existing teamDurability field already supports all values
  • Values: "permanent" (Fixed), "variable" (Pre-Planned), "per_round" (Dynamic)

UI Changes

  • Tournament Creation Form (src/app/admin/tournaments/new/page.tsx):

    • Renamed "Team Durability" to "Team Formation Strategy"
    • Updated option labels:
      • "Permanent Teams" → "Fixed Teams"
      • "Variable Teams" → "Pre-Planned Variable"
      • "Per-Round Teams" → "Dynamic/Progressive"
    • Updated descriptions to clearly explain each option
  • Edit Tournament Form (src/components/EditTournamentForm.tsx):

    • Same UI updates as creation form
  • Teams Section (src/components/TeamsSection.tsx):

    • Same UI updates
    • Partner rotation options only shown for "Pre-Planned Variable"

Function Changes

  • src/lib/schedule-generator.ts:
    • Added TeamPairing type
    • Added generateVariableRoundRobin() function
    • This function generates fresh teams for each round and applies round-robin pairing

How It Works

Fixed Teams Example

Teams: [Emma+Kendall, Katie+Linden, Sara+Amelia, Bri+Jesse]
Round 1: Emma+Kendall vs Katie+Linden, Sara+Amelia vs Bri+Jesse
Round 2: Emma+Kendall vs Sara+Amelia, Katie+Linden vs Bri+Jesse
Round 3: Emma+Kendall vs Bri+Jesse, Katie+Linden vs Sara+Amelia

Same teams in every round, just different opponents.

Pre-Planned Variable Example (with minimize_repeat)

Round 1 Teams: [Emma+Kendall, Katie+Linden, Sara+Amelia, Bri+Jesse]
Round 1: Emma+Kendall vs Katie+Linden, Sara+Amelia vs Bri+Jesse

Round 2 Teams: [Emma+Sara, Katie+Bri, Kendall+Amelia, Linden+Jesse]
Round 2: Emma+Sara vs Katie+Bri, Kendall+Amelia vs Linden+Jesse

Round 3 Teams: [Emma+Katie, Sara+Bri, Kendall+Linden, Amelia+Jesse]
Round 3: Emma+Katie vs Sara+Bri, Kendall+Linden vs Amelia+Jesse

Fresh partnerships each round, minimizing repeat partnerships.

Dynamic/Progressive Example

Round 1: Generate first matchups based on initial seeding
[After Round 1 completes]
Round 2: Generate matchups based on Round 1 results
[Continue until tournament completes]

Schedule is generated progressively based on actual results.

Testing

  • Build successful
  • Lint passes
  • Unit tests pass (120 pass, 7 pre-existing failures)
  • E2E tests can be added for new functionality

Migration Notes

  • Existing tournaments with teamDurability: "permanent" will continue to work
  • Existing tournaments with teamDurability: "variable" or "per_round" will now behave as intended
  • No database migrations needed
  • No breaking changes to API endpoints