# CC Soccer D11 - Session Handoff
**Date:** January 11, 2026  
**Last Updated:** Session End (Tournament Schedule Builder Phases 1-4)

---

## COMPLETED THIS SESSION (Tournament Schedule Builder Phases 1-4)

### Tournament Schedule Builder - Full Implementation

**Purpose:** Admin interface for generating and managing single-day tournament schedules with skill-based matchups and drag-drop editing.

**Route:** `/admin/ccsoccer/tournament/{tournament}/schedule`

**Access:** `manage tournaments` permission (Admin + Tournament Director/Slofriendly)

### Phase 1: Tournament Entity Scheduling Fields (update_9033)

Added 7 new fields to Tournament entity:
- `num_fields` (integer, default 4) - Number of parallel fields
- `game_duration` (integer, default 50) - Game length in minutes
- `break_duration` (integer, default 10) - Break between games in minutes
- `tournament_start_time` (string, default 08:30) - First game time
- `lunch_start_time` (string, default 12:30) - Lunch break start
- `lunch_duration` (integer, default 30) - Lunch break length in minutes
- `games_per_team` (integer, default 4) - Target games per team

Added methods: `getNumFields()`, `getGameDuration()`, `getBreakDuration()`, `getTournamentStartTime()`, `getLunchStartTime()`, `getLunchDuration()`, `getGamesPerTeam()`, `getTimeSlotDuration()`, `calculateTimeSlots()`

### Phase 2: Team Skill Level Fields (update_9034)

Added 2 fields to Team entity:
- `calculated_skill_level` (decimal, precision 3, scale 2) - Auto-calculated from player skill averages
- `admin_skill_level` (integer 1-5) - Admin override

Added methods: `getSkillLevel()`, `getCalculatedSkillLevel()`, `getAdminSkillLevel()`, `hasAdminSkillOverride()`, `calculateSkillLevelFromPlayers()`

**Skill Level Mapping:**
- 5.0: Competitive (highest)
- 4.0: Competitive
- 3.0: Friendly
- 2.0: Friendly
- 1.0: Relaxed (lowest)

### Phase 3: Tournament Schedule Generator Service

Created `TournamentScheduleGeneratorService` with:

**Core Methods:**
- `getTeamsWithSkillLevels()` - Load teams sorted by skill (highest first)
- `calculateTimeSlots()` - Generate time slots from config, handles lunch break
- `generateSchedule()` - Main entry point, creates full schedule
- `generateMatchups()` - Create skill-balanced pairings (lowest skill gap first)
- `assignGamesToSlots()` - Place games with rest optimization
- `findBestSlot()` - Find optimal slot considering rest and period balance
- `calculateRestScore()` - Score rest periods (lower = better)
- `validateSchedule()` - Check constraints met
- `getScheduleState()` - Get current schedule for UI display
- `getTeamScheduleAnalysis()` - Analyze rest periods per team
- `clearSchedule()` - Delete all games
- `setPublished()` - Publish/unpublish games

**Workbench Methods:**
- `getWorkbench()` - Get workbench contents
- `addToWorkbench()` - Add team to workbench
- `removeFromWorkbench()` - Remove team from workbench
- `clearWorkbench()` - Clear all workbench items

**Move/Swap Methods:**
- `swapTeams()` - Swap two teams in schedule
- `moveTeam()` - Move team to game slot
- `clearTeamFromSlot()` - Remove team from slot (set to NULL)

**Algorithm Highlights:**
1. Teams sorted by skill, matchups selected to minimize skill gap
2. Rest optimization scoring:
   - Gap 0 (same slot): 100 (impossible)
   - Gap 1 (back-to-back): 10 (bad)
   - Gap 2 (1 hour rest): 0 (ideal)
   - Gap 3: 2 (acceptable)
   - Gap 4+: 5 (too much waiting)
3. Period balance: Target 2 morning + 2 afternoon games per team
4. Parallel fields: Games scheduled across multiple fields per slot

### Phase 4: Tournament Schedule Builder Form

Created `TournamentScheduleBuilderForm` matching Season pattern:

**UI Sections:**
- Header with back button, tournament info (date, teams, fields, games/team)
- Configuration section (collapsible) showing time slots, capacity
- Teams section with skill levels and player counts
- Visibility status indicator
- Action buttons: Generate/Regenerate, Publish, Unpublish, Clear
- Schedule grid with drag-drop
- Workbench for temporary team storage
- Team analysis section showing rest issues and morning/afternoon balance

**Schedule Grid Features:**
- Visual table: Time slots (rows) × Fields (columns)
- Morning slots: Yellow time cell background
- Afternoon slots: Blue time cell background
- Lunch break: Gold separator row
- Skill gap indicators: Green (≤0.5), Yellow (≤1.0), Red (>1.0) left border
- Skill badges showing team ratings

**Drag-Drop Support:**
- Data attributes on cells: `data-game-id`, `data-position`, `data-slot`, `data-field`
- Draggable team names with `data-team-id`, `data-team-name`
- Swap teams by dragging within grid
- Move to workbench for temporary storage
- Restore from workbench to grid

### AJAX Endpoints (TournamentScheduleController)

Created controller with endpoints:
- `swapTeams()` - Swap two teams
- `moveTeam()` - Move team to position
- `addToWorkbench()` - Remove from grid, add to workbench
- `removeFromWorkbench()` - Remove from workbench
- `getWorkbench()` - Get workbench state
- `clearWorkbench()` - Clear all workbench items
- `getState()` - Get full schedule state

### New Routes

```yaml
ccsoccer.tournament_schedule_builder_swap      POST  /schedule/swap
ccsoccer.tournament_schedule_builder_move      POST  /schedule/move
ccsoccer.tournament_schedule_builder_workbench GET   /schedule/workbench
ccsoccer.tournament_schedule_builder_workbench_add    POST  /workbench/add
ccsoccer.tournament_schedule_builder_workbench_remove POST  /workbench/remove
ccsoccer.tournament_schedule_builder_workbench_clear  POST  /workbench/clear
ccsoccer.tournament_schedule_builder_state     GET   /schedule/state
```

### JavaScript and CSS

**tournament-schedule-builder.js:**
- Adapted from schedule-builder.js for single-day tournaments
- Full drag-drop with swap and workbench support
- Toast notifications for feedback

**CSS Strategy:**
- Reuses `schedule-grid.css` (shared table layout)
- Reuses `schedule-builder.css` (admin drag-drop, workbench, toast)
- `tournament-schedule-builder.css` for tournament-specific overrides only

---

## KEY FILES CREATED/MODIFIED THIS SESSION

```
web/modules/custom/ccsoccer/
├── ccsoccer.install                             # Added update hooks 9033, 9034
├── ccsoccer.routing.yml                         # Added 8 tournament schedule AJAX routes
├── ccsoccer.services.yml                        # Added tournament_schedule_generator service
├── ccsoccer.libraries.yml                       # Updated tournament-schedule-builder library
├── css/
│   └── tournament-schedule-builder.css          # Tournament-specific overrides
├── js/
│   └── tournament-schedule-builder.js           # NEW: Drag-drop JavaScript
├── src/
│   ├── Controller/
│   │   ├── TournamentController.php             # Updated scheduleBuilder() method
│   │   └── TournamentScheduleController.php     # NEW: AJAX endpoints
│   ├── Entity/
│   │   ├── Tournament.php                       # Added 7 scheduling fields + methods
│   │   └── Team.php                             # Added 2 skill level fields + methods
│   ├── Form/
│   │   └── TournamentScheduleBuilderForm.php    # Complete rewrite with grid + drag-drop
│   └── Service/
│       └── TournamentScheduleGeneratorService.php  # Added workbench + swap/move methods
```

---

## PREVIOUS SESSION (Tournament Overview Page + Admin UX)

### Tournament Overview Page (Mirrors Season Pattern)

**Route:** `/admin/ccsoccer/tournament/{tournament}`

**Features:**
1. Action Buttons - Edit Tournament, Roster Builder
2. Tournament Details Table - Dates, prices, location, format
3. Registration Stats Cards - Teams, Players, Captains, Pool
4. Status Flags Section - Active, Registration Visible, Schedule Visible

**Files Created/Modified:**
- `src/Controller/TournamentController.php` - view() method
- `css/tournament-view.css` - Styling
- `ccsoccer.libraries.yml` - tournament-view library

### Tournament Entity Field Changes

**Added active field (update_9031):**
- Boolean controlling admin menu dropdown visibility

**Renamed schedule_generated to schedule_visible (update_9032):**
- Controls whether players can view tournament schedule

---

## PROJECT STATUS

**Overall Completion:** ~92%

### COMPLETE Features (100%)

| Feature | Status | Notes |
|---------|--------|-------|
| Core Entities | Complete | All 10 entities working |
| Registration Flow | Complete | Season + tournament checkout |
| Group Management | Complete | Unified interface for seasons AND tournaments |
| Roster Builder | Complete | Drag-drop + algorithm (seasons) |
| Tournament Roster Builder | Complete | Drag-drop admin interface for tournament teams |
| Tournament Overview Page | Complete | Mirrors Season pattern with stats and flags |
| Schedule Builder (Season) | Complete | Drag-drop + generator |
| **Tournament Schedule Builder** | **Complete** | **Skill-based matchups, rest optimization, drag-drop** |
| Notifications | Complete | Email/SMS with test mode + privileged verify + multi-season |
| Captain Notifications | Complete | Player joined, declined notifications implemented |
| Game Status | Complete | Banner + admin form + auto-reset + credits |
| Credits System | Complete | Entity + service methods |
| Season Publishing | Complete | Visibility flags + league inheritance |
| Override System | Complete | Logic + admin UI complete |
| Content Pages | Complete | Home, teams, schedule, my-schedule, my-teams |
| Jersey Purchase | Complete | Cart display fixed, waiver skip for jersey-only |
| Masquerade | Complete | Footer block with dashboard links |
| Mobile Menu | Complete | Dropdowns work on iOS |
| Floating Schedule Nav | Complete | Arrows accessible when scrolled |
| Cancelled Game Display | Complete | Visual overlay on all schedule views |
| Board/Director Dashboards | Complete | Role-based access with appropriate footer links |
| Tournament Entity | Complete | Full entity with scheduling fields |
| Tournament Team Pane | Complete | Checkout pane with team selection/creation |
| Tournament Payment Processing | Complete | Team creation, roster joining, token flow |
| Tournament Capacity System | Complete | Roster limits enforced throughout |
| TournamentTeamManager | Complete | Complete service for team/player management |
| Tournament Invite Flow | Complete | Email invite auto-accepts for registered users |
| Tournament My Registrations UX | Complete | Status display for all player states |
| Tournament Admin Menu | Complete | Dynamic dropdown with Edit/Roster Builder/Schedule Builder links |
| Tournament Seed Data | Complete | --populate-tournaments creates 3 tournaments + 4 teams |

### TODO (Remaining Items)

**Phase 2 Enhancements (Next Priority):**
1. **Player notification when removed from team** - Notify player they were removed
2. **Admin dashboard for unassigned players** - View/manage awaiting/pool status players

**Phase 3: Admin Tournament Management**
- Tournament Teams Admin View - List of registered teams with rosters
- Registration counts and deposit tracking
- CCSoccer Pool Team Creation (admin creates CCSoccer Team 1, etc.)

**Phase 4: Tournament Public Display**
- `/tournament/{id}` - Public tournament info page
- `/tournament/{id}/teams` - List of registered teams

**Reports (deferred):**
- City Payment Report (revenue share with rainout exclusion)
- Insurance Report (player roster)
- Tournament Team Report (deposits and formation)
- Jersey Report (sizes/distribution)

**Migration (January-February):**
- Board decision on user pruning cutoff (2yr vs 3yr vs 5yr)
- Write migration scripts (users, credits, payment methods)
- Test migration with D7 data subset

---

## ARCHITECTURE HIGHLIGHTS

### Tournament Schedule Algorithm

```
1. Load teams sorted by skill level (highest first)
2. Generate matchups prioritizing similar skill levels
3. For each matchup, find optimal time slot:
   a. Check slot has capacity (fewer games than fields)
   b. Check neither team already playing in slot
   c. Check period balance (morning vs afternoon)
   d. Calculate rest score from previous games
4. Assign to best scoring slot
5. Create game entities with slot, field, teams
```

### Tournament Schedule vs Season Schedule

| Aspect | Season Schedule | Tournament Schedule |
|--------|----------------|---------------------|
| Duration | Multi-week | Single day |
| Grid Layout | Time slots × Dates | Time slots × Fields |
| Navigation | Week prev/next arrows | None needed |
| Balancing | Time slot distribution | Skill level matching + rest periods |
| Constraints | No back-to-back weeks | No back-to-back slots, AM/PM balance |
| Workbench | Same week swaps | Any slot swaps |

### Tournament Registration Flow (Complete)
```
Captain Flow:
1. Captain goes to registration page
2. Captain selects Create a new team (become captain)
3. Captain enters team name, acknowledges deposit
4. Deposit product added to cart
5. Captain completes checkout (pays deposit)
6. Team is CREATED when order completes
7. Captain can invite players from /my-group/{registration}

Player Flow:
1. Player receives invitation OR sees team on registration page
2. Player selects Join Team and picks their team
3. Player completes checkout (pays registration fee)
4. Player is added to team roster when order completes
```

---

## DEVELOPER SETUP

### After Pulling Latest Code:
```bash
git pull origin main
ddev drush updb -y
ddev drush cr
```

### Seed Commands:
```bash
# Create test users with roles
ddev drush ccs-seed --users

# Create comprehensive test data
ddev drush ccs-seed --test --force

# Create seasons with registrations
ddev drush ccs-seed --populate-seasons

# Create tournaments with teams
ddev drush ccs-seed --populate-tournaments

# Full reset and reseed tournaments
ddev drush ccs-seed --force --populate-tournaments
```

### Current Update Hooks:
- 9027: Tournament and Team max_roster_size fields
- 9029: Tournament registration_visible field
- 9030: Registration ccsoccer_pool field
- 9031: Tournament active field for admin menu visibility
- 9032: Rename Tournament schedule_generated to schedule_visible
- 9033: Tournament scheduling fields (num_fields, game_duration, etc.)
- 9034: Team skill level fields (calculated_skill_level, admin_skill_level)

---

## NEXT STEPS (Priority Order)

### Immediate (Phase 2 Enhancements):
1. **Player notification when removed from team**
   - Send email when captain removes player
   - Include guidance: contact captain or tournament director

2. **Admin dashboard for unassigned players**
   - Route: `/admin/ccsoccer/tournament/{tournament}/unassigned`
   - Show players in awaiting and pool status
   - Interface to manually assign to teams

### Short-Term (Phase 3):
3. Tournament Teams Admin View (`/admin/ccsoccer/tournament/{tournament}/teams`)
4. CCSoccer Pool Team Creation (admin-created teams)

### Later (Phase 4):
5. Tournament public info page
6. Tournament teams list page

---

## NOTES FOR NEXT SESSION

### Testing Tournament Schedule Builder:
1. Navigate to `/admin/ccsoccer/tournament/{tournament}/schedule`
2. Click Generate Schedule to create skill-based matchups
3. Drag teams to swap positions in the grid
4. Drag teams to workbench for temporary storage
5. Drag from workbench back to grid
6. Check Team Schedule Analysis for rest issues

### Business Rules for Tournament Scheduling:
- Each team plays 4 games (default, configurable)
- 2 games in morning, 2 in afternoon (balanced)
- Minimum 1 hour rest between games (ideal)
- Skill-balanced matchups (similar skill levels play each other)
- Lunch break separates morning/afternoon slots

---

## HISTORICAL SESSION SUMMARIES

### Session: Tournament Schedule Builder Phases 1-4 (January 11, 2026 - This Session)
```
Add Tournament Schedule Builder with drag-drop editing

Phase 1-4 implementation of tournament scheduling system:

- Add scheduling fields to Tournament entity (num_fields, game_duration, 
  break_duration, tournament_start_time, lunch_start_time, lunch_duration,
  games_per_team)
- Add skill level fields to Team entity (calculated_skill_level as decimal,
  admin_skill_level as integer override)
- Create TournamentScheduleGeneratorService with skill-based matchup
  generation, rest period optimization, and morning/afternoon balancing
- Create TournamentScheduleBuilderForm with grid display matching Season
  Schedule Builder pattern
- Add TournamentScheduleController with AJAX endpoints for swap, move,
  and workbench operations
- Add tournament-schedule-builder.js for drag-drop functionality
- Reuse schedule-grid.css and schedule-builder.css for consistent UI
- Add database updates 9033 and 9034 for new entity fields

Tournament schedules support single-day events with configurable time slots,
lunch breaks, and skill-balanced team matchups with visual gap indicators.
```

### Session: Tournament Overview Page + Admin UX (January 11, 2026)
```
Add Tournament overview page and admin UX improvements

Tournament Overview Page (mirrors Season pattern):
- Add TournamentController::view() with action buttons, details table,
  registration stats cards, and status flags section
- Update routing to use custom controller for entity.tournament.canonical
- Make tournament names clickable links in TournamentListBuilder
- Add tournament-view.css and library

Tournament Entity Field Changes:
- Add active field (update_9031) - controls admin menu dropdown visibility
- Rename schedule_generated to schedule_visible (update_9032) - matches
  Season pattern, controls player visibility of tournament schedule
- Simplify menu query to use condition on active field instead of
  complex status-based logic
```

### Session: Tournament Roster Builder + Seed Data (January 11, 2026)
```
Add tournament roster builder admin page and expand tournament seed data

Tournament Roster Builder:
- Create TournamentRosterBuilderForm with drag-drop team management
- Add controller, JavaScript, CSS, and routing for roster builder
- Implement workbench for unassigned players and CCSoccer pool section
- Fix player grouping logic and dynamic stat updates
- Add group management links to player cards

Tournament Admin Menu:
- Enhance hook_menu_links_discovered_alter() to add dynamic tournament submenus
- Add Edit Tournament and Roster Builder links to CC Soccer dropdown
- Match existing Seasons dropdown pattern

Tournament Seed Data (--populate-tournaments):
- Add new Drush option to create tournament test data
- Create 3 tournaments: SLO Friendly 2024/2025/2026 with varied statuses
- Generate 4 teams for 2025 tournament with 10 players each
```

### Earlier Sessions (Reference):
- Tournament Invite Flow Fix (January 10, 2026)
- Tournament Registration System Phases 1-2 (January 2026)
- Multi-season notification system with privileged verification
- Game status banner with auto-reset and credits
- Mobile menu iOS fixes
- Cancelled game display overlays
- Board/Director dashboard role-based access
- Jersey purchase waiver skip logic
- Season publishing visibility flags

---

**End of Session Handoff**
