# CC Soccer D11 - Session Handoff
**Date:** January 14, 2026  
**Last Updated:** Session End (Clean Install Fix)

---

## COMPLETED THIS SESSION

### Clean Install Fix ✅

**Problem:** Fresh installations from scratch were failing with various dependency and config import errors.

**Root Causes Identified:**
1. `ccsoccer.info.yml` had no dependencies declared - modules weren't auto-enabled
2. Config files in `config/install/` depended on fields created by install hooks (wrong order)
3. `field.storage.node.body` conflicts with standard profile (already exists)

**Solution Implemented:**

#### 1. Added Module Dependencies (`ccsoccer.info.yml`)
All required modules now declared so `ddev drush en ccsoccer -y` installs everything:
```yaml
dependencies:
  - drupal:taxonomy
  - drupal:telephone
  - drupal:text
  - commerce:commerce
  - commerce:commerce_checkout
  - commerce:commerce_payment
  - commerce:commerce_product
  - commerce_authnet:commerce_authnet
  - masquerade:masquerade
  - admin_toolbar:admin_toolbar
  - admin_toolbar:admin_toolbar_tools
  - admin_toolbar:admin_toolbar_search
```

#### 2. Added Missing Body Field Config
Created `field.field.node.notification.body.yml` for the notification content type body field instance.

#### 3. Removed Conflicting Config
Deleted `field.storage.node.body.yml` - this storage is already provided by the standard install profile.

#### 4. Updated INSTALLATION_GUIDE.md
- Simplified installation steps (single `ddev drush en ccsoccer -y` command)
- Removed separate admin_toolbar installation step
- Renumbered steps from 11 to 10

---

## KEY FILES MODIFIED THIS SESSION

```
Module Configuration:
web/modules/custom/ccsoccer/
├── ccsoccer.info.yml
│   └── Added all dependencies (commerce, masquerade, admin_toolbar, etc.)
└── config/install/
    ├── field.field.node.notification.body.yml (NEW)
    │   └── Body field instance for notification content type
    └── field.storage.node.body.yml (DELETED)
        └── Removed - conflicts with standard profile

Documentation:
├── INSTALLATION_GUIDE.md
│   └── Simplified to single enable command
│   └── Removed separate admin_toolbar step
│   └── Renumbered steps (now 10 steps instead of 11)
```

---

## CLEAN INSTALL INSTRUCTIONS

### Quick Start (Recommended)
```bash
# Clone the repository
git clone https://github.com/caleb-ccsoccer/ccsoccer-d11.git
cd ccsoccer-d11

# Start DDEV
ddev start

# Install dependencies
ddev composer require drush/drush

# Install Drupal
ddev drush site:install standard --site-name="CC Soccer D11" --account-name=admin --account-pass=admin -y

# Enable CC Soccer module (automatically enables all dependencies: commerce, masquerade, admin_toolbar, etc.)
ddev drush en ccsoccer -y

# Run database updates (creates all entity tables and fields)
ddev drush updb -y

# Clear cache
ddev drush cr

# Seed test data with users
ddev drush ccs-seed --users

# Launch the site
ddev launch
```

**Login:** admin / admin

### Full Clean Install (Delete Everything First)
```bash
cd ~/Sites/ccsoccer-d11
ddev delete -O
cd ~/Sites
rm -rf ccsoccer-d11
git clone https://github.com/caleb-ccsoccer/ccsoccer-d11.git
cd ccsoccer-d11
ddev start
ddev composer require drush/drush
ddev drush site:install standard --site-name="CC Soccer D11" --account-name=admin --account-pass=admin -y
ddev drush en ccsoccer -y
ddev drush updb -y
ddev drush cr
ddev drush ccs-seed --users
ddev launch
```

---

## PROJECT STATUS

**Overall Completion:** ~98%

### 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 + snapshots |
| Tournament Schedule Builder | Complete | Round-robin matchups, rest optimization, true grid drag-drop, snapshots |
| Schedule Snapshots | Complete | Save/list/rename/delete/restore all working |
| Tournament Teams Admin | Complete | Teams list with skill levels + Create Team UI + Status dropdown |
| Group ID UUID System | Complete | Consistent UUIDs for both season and tournament groups |
| Notifications | Complete | Email/SMS with test mode + privileged verify + multi-season |
| Captain Notifications | Complete | Player joined, declined, removed notifications |
| 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 |
| Tournament Public Pages | Complete | /tournament-schedule, /tournament-teams, my-* variants |
| 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 with teams |
| Team Status Management | Complete | Active/Withdrawn/Disqualified status with visual indicators |
| Co-Captain Support | Complete | Co-captain field, promote/release functionality |
| Captain Management | Complete | Release captain, promote player, via Group Invitations |
| Player Removed Notification | Complete | Already in GroupController::removeMember() |
| **Clean Install** | **Complete** | **All dependencies declared, single enable command works** |

### TODO (Remaining Items)

**UI/UX Enhancements:**
1. **Roster Builder team drag-and-drop reordering** - Allow dragging team columns to reorder (uses weight field)
2. **Tournament pill boxes** - Update Tournament Public and private views to use pill boxes for tournament name
3. **Player credits UI** - Is there a UI to credit individual players?
4. **Season/Tournament player filter** - Sub menu under individual seasons and tournaments to only display players with that season or tournament

**Phase 4: Tournament Public Display (Partially Complete)**
- ✅ `/tournament-schedule` - Tournament schedule grid
- ✅ `/tournament-teams` - List of tournament team rosters
- ✅ `/my-tournament-schedule` - User's tournament games
- ✅ `/my-tournament-teams` - User's tournament team
- ⏳ `/tournament/{id}` - Public tournament info page (standalone)

**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

---

## 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 (all 3 tournaments: 2024, 2025, 2026)
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)
- 9035: Team admin_skill_level decimal conversion
- 9036: Team group_id UUID field + migration
- 9037: Schedule snapshot tables creation
- 9038: Tournament roster_visible field
- 9039: Team status and weight fields

---

## ARCHITECTURE HIGHLIGHTS

### Team Status System

**Status Values:**
| Status | Header Color | Opacity | Badge | Included in Schedule |
|--------|-------------|---------|-------|---------------------|
| Active | Green (#2c5f2d) | 100% | None | Yes |
| Withdrawn | Gray (#6c757d) | 65% | "W" | No |
| Disqualified | Red (#dc3545) | 65% | "DQ" | No |

**Schedule Builder Filter:**
```php
// In TournamentScheduleGeneratorService::getTeamsWithSkillLevels()
->condition('status', 'active')
```

### Captain/Co-Captain System

**Permissions:**
- Both captain and co-captain have `is_captain = TRUE` on their registration
- Both can invite players to the team
- Team entity has separate `captain` and `co_captain` fields

**Management Workflows:**

*Merge Two Small Teams:*
1. Go to Group Invitations for the team to disband
2. Change captain's dropdown → "⚠️ Release as Captain"
3. Save - Captain becomes regular player, team has no captain
4. Drag players to surviving team in Roster Builder

*Change Captain (Injured Captain):*
1. Go to Group Invitations for that team
2. Find new captain, change dropdown → "⭐ Promote to Captain"
3. Save - New captain takes over, old captain becomes regular team member

### Tournament Public Pages Architecture

**Menu Visibility Logic:**
```php
// In hook_menu_links_discovered_alter()
// Query active tournaments for visibility flags
$roster_visible_count = $tournament_storage->getQuery()
  ->condition('active', TRUE)
  ->condition('roster_visible', TRUE)
  ->count()->execute();

$schedule_visible_count = $tournament_storage->getQuery()
  ->condition('active', TRUE)
  ->condition('schedule_visible', TRUE)
  ->count()->execute();

// Hide links if no tournaments have the flag set
if ($roster_visible_count == 0) {
  $links['ccsoccer.tournament_teams.menu']['class'] = 'hidden';
  $links['ccsoccer.my_tournament_team.menu']['class'] = 'hidden';
}
```

**Route Access Control:**
| URL | Access | Visibility Depends On |
|-----|--------|----------------------|
| `/tournament-schedule` | Public | `schedule_visible = TRUE` |
| `/my-tournament-schedule` | Login Required | `schedule_visible = TRUE` |
| `/tournament-teams` | Login Required | `roster_visible = TRUE` |
| `/my-tournament-teams` | Login Required | `roster_visible = TRUE` |

### Snapshot System Architecture

```
User clicks "Save Snapshot"
    ↓
JavaScript sends POST to /snapshot/save
    ↓
Controller calls service->saveSnapshot()
    ↓
Service queries all games for entity
    ↓
Serializes game data (home_team, away_team, time_slot, field, etc.)
    ↓
Inserts into tournament_schedule_snapshot or season_schedule_snapshot table
    ↓
Returns success + updated snapshot list
    ↓
JavaScript refreshes snapshot table via refreshSnapshotList()
```

**Snapshot Restore Logic (Position-Based):**
```
User clicks "Restore"
    ↓
Load snapshot data from database
    ↓
Build lookup by POSITION (not game_id):
  - Tournament: time_slot + field → "3_Field 2"
  - Season: week_number + time_slot + field → "5_2_Field 1"
    ↓
Load current games for entity
    ↓
For each current game:
  - Build position key from game's time_slot/field
  - Look up snapshot data by position
  - Update game if data differs
    ↓
Return count of games updated
```

### Tournament Schedule Algorithm

**Matchup Generation - Round-Robin Based:**
```
1. Generate round-robin rounds using circle method
   - Fix position 0, rotate all others
   - Creates n-1 rounds for n teams (even)
   - Each round has n/2 games, each team plays once

2. Score and sort rounds by total skill gap
   - Lower total gap = more skill-balanced round
   - Select best rounds first

3. Select rounds until each team has games_per_team games
   - Guarantees exact game count (hard constraint)
   - No possibility of dead ends

4. Fallback for odd teams (byes)
   - fillRemainingMatchups() uses constraint-aware greedy
   - Most-constrained-first prevents stuck states
```

---

## TESTING NOTES

### Testing Clean Install:
1. Delete everything: `ddev delete -O && rm -rf ~/Sites/ccsoccer-d11`
2. Clone fresh: `git clone https://github.com/caleb-ccsoccer/ccsoccer-d11.git`
3. Run quick start commands (see above)
4. **Verify:**
   - All modules enabled with single `ddev drush en ccsoccer -y`
   - Admin toolbar visible in admin interface
   - Masquerade block in footer
   - Create Notification form has all fields (Title, Body, Seasons, etc.)
   - Seed data creates leagues, seasons, tournaments, users

### Testing Team Status Management:
1. Run `ddev drush updb` to apply update hook 9039
2. Run `ddev drush cr` to clear caches
3. Navigate to Tournament Teams page (`/admin/ccsoccer/tournament/{id}/teams`)
4. **Verify Status dropdown appears** for each team
5. Change a team's status to "Withdrawn"
6. Navigate to Roster Builder - **Verify:**
   - Team column has gray header with "W" badge
   - Team appears at 65% opacity
   - Header shows separate "Teams" and "Active Teams" counts
7. Generate schedule - **Verify:**
   - Withdrawn/Disqualified teams are NOT included in schedule

### Testing Captain/Co-Captain Management:
1. Navigate to Group Invitations for a tournament team
2. **Test Release Captain:**
   - Captain row should show dropdown with "⚠️ Release as Captain"
   - Select and Save
   - **Verify:** Captain becomes regular player, team has no captain, players stay on team
3. **Test Promote to Captain:**
   - Find an accepted player
   - Change dropdown to "⭐ Promote to Captain"
   - Save
   - **Verify:** Player becomes captain, old captain (if any) becomes regular member
4. **Test Co-Captain:**
   - Promote a different player to Co-Captain
   - **Verify:** Co-Captain row appears with blue styling
   - Release Co-Captain and verify they become regular member

### Testing Tournament Public Pages:
1. Set `roster_visible = TRUE` and/or `schedule_visible = TRUE` on a tournament
2. **Verify menu links appear:**
   - "Tournament Teams" and "Tournament Schedule" in main Links section
   - "My Tournament Team" and "My Tournament Schedule" in Player Links section
3. Visit `/tournament-schedule`:
   - Should show tournament tabs if multiple tournaments visible
   - Should show grid with time slots as rows, fields as columns
4. Visit `/tournament-teams`:
   - Should require login (redirect anonymous users)
   - Should show all teams with captain and player roster

### Testing Snapshot Feature:
1. Navigate to `/admin/ccsoccer/tournament/{tournament}/schedule`
2. Generate a schedule
3. Click "💾 Save Snapshot" - verify toast appears and snapshot added to list
4. Make changes to the schedule (drag teams around)
5. Click "Restore" on the snapshot
6. **Verify:** Schedule reverts to saved state, toast shows correct game count

---

## NEXT STEPS (Priority Order)

### UI/UX Enhancements:
1. **Roster Builder team drag-and-drop reordering**
   - Make team columns draggable (separate from player drag)
   - AJAX endpoint to save new order (update weight field)
   - Visual drop indicators between columns

2. **Tournament pill boxes**
   - Update Tournament Public and private views
   - Use pill box styling for tournament name selection

3. **Player credits UI investigation**
   - Determine if UI exists for crediting individual players
   - If not, design and implement

4. **Season/Tournament player filter**
   - Add sub-menu to filter players by specific season or tournament

### Later (Phase 4):
5. Tournament public info page (`/tournament/{id}`)

---

## HISTORICAL SESSION SUMMARIES

### Session: Clean Install Fix (January 14, 2026 - This Session)
```
fix(install): Add module dependencies and fix notification body field config

Problem: Fresh installs failing with dependency and config import errors

Solution:
- Added all dependencies to ccsoccer.info.yml (commerce, masquerade, admin_toolbar)
- Added field.field.node.notification.body.yml for notification content type
- Removed field.storage.node.body.yml (conflicts with standard profile)
- Updated INSTALLATION_GUIDE.md with simplified single-command install
```

### Session: Team Status, Co-Captain, Captain Management (January 13, 2026)
```
feat(tournament): Add team status and weight fields for management
feat(tournament): Add co-captain support and captain management

Team Status Management:
- Add status field (active/withdrawn/disqualified) to Team entity
- Add weight field for drag-and-drop ordering
- Roster Builder sorts by weight, shows status badges (W/DQ)
- Schedule Builder filters to only active teams
- Visual styling: withdrawn=gray, disqualified=red

Co-Captain Support:
- Add co_captain field to Team entity
- Add helper methods hasCoCaptain getCoCaptainId isTeamLeader
- Both captain and co-captain have is_captain=TRUE for invite permissions

Captain Management via Group Invitations:
- Captain can be released (stays on team as regular player)
- Accepted players can be promoted to Captain or Co-Captain
- Co-Captain can be released back to regular player

Seed Command:
- populateTournamentsWithTeams() now populates all 3 tournaments
```

### Session: Tournament Public Pages (January 11, 2026)
```
feat(tournament): add tournament public pages with schedule and teams views

Phase 1: Tournament roster_visible field
- Add roster_visible boolean field to Tournament entity
- Create idempotent update hook 9038 with helper function

Phase 2: Dynamic menu links
- Add 4 tournament menu links with conditional visibility
- Links show only when roster_visible or schedule_visible is TRUE

Phase 3: TournamentScheduleGridBuilder service
- Create new service for rendering tournament schedule grids
- Support MODE_PUBLIC and MODE_MY_SCHEDULE display modes

Phase 4: Controller methods and routes
- Add 4 new routes and controller methods
- Tournament tabs with smart default selection
- Captain display on tournament team cards

Phase 5: CSS library
- Create tournament-schedule-grid.css with full styling
- Responsive breakpoints for tablet and mobile
```

### Session: Snapshot Restore Fix (January 11, 2026)
```
fix(snapshots): restore functionality and UI spacing

- Fix restoreSnapshot() to use position-based matching instead of game_id
  - Tournament: matches by time_slot + field
  - Season: matches by week_number + time_slot + field

- Fix CSS spacing for Saved Snapshots section arrow
```

### Session: Schedule Snapshot Feature (January 11, 2026)
```
feat(snapshots): add schedule snapshot save/restore system for tournaments and seasons

- Create tournament_schedule_snapshot and season_schedule_snapshot tables
- Add saveSnapshot, listSnapshots, restoreSnapshot, renameSnapshot, deleteSnapshot
- Add snapshot AJAX endpoints and JavaScript handlers
```

### Session: Tournament Schedule Bug Fixes (January 11, 2026)
```
fix(tournament): fix schedule generation and enable true grid drag-drop

- Replace greedy matchup algorithm with round-robin based selection
- Fix type casting in createEmptyGameShells for consistent key matching
```

### Session: Strategy Documentation + True Grid Drag-Drop (January 11, 2026)
```
Tournament Schedule Builder enhancements:
- Add Scheduling Strategy documentation section
- Implement true grid drag-drop with empty game shells
- Add rest issue warnings for back-to-back games
```

### Session: Admin Team Creation UI + Group ID UUID Migration (January 11, 2026)
```
Add admin team creation UI and update tournament seed data

- Add Create Team button and inline form to Tournament Teams page
- Add group_id field to Team entity with UUID storage
- Update tournament seed data with 2025 SLO Friendly team names
```

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

- Add scheduling fields to Tournament entity
- Add skill level fields to Team entity
- Create TournamentScheduleGeneratorService with skill-based matchups
- Create TournamentScheduleBuilderForm with grid display
```

### Earlier Sessions (Reference):
- Tournament Overview Page + Admin UX
- Tournament Roster Builder + Seed Data
- Tournament Invite Flow Fix
- Tournament Registration System Phases 1-2
- Multi-season notification system
- 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

---

## GIT COMMIT MESSAGES (This Session)

```
fix(install): Add module dependencies and fix notification body field config

- Added all dependencies to ccsoccer.info.yml:
  - drupal: taxonomy, telephone, text
  - commerce: commerce, commerce_checkout, commerce_payment, commerce_product
  - commerce_authnet: commerce_authnet
  - masquerade: masquerade
  - admin_toolbar: admin_toolbar, admin_toolbar_tools, admin_toolbar_search

- Added field.field.node.notification.body.yml for notification content type
- Removed field.storage.node.body.yml (conflicts with standard profile)
- Updated INSTALLATION_GUIDE.md:
  - Single command install: ddev drush en ccsoccer -y
  - Removed separate admin_toolbar step
  - Renumbered steps (now 10 instead of 11)

Clean install now works with:
  ddev drush site:install standard ...
  ddev drush en ccsoccer -y
  ddev drush updb -y
  ddev drush cr
  ddev drush ccs-seed --users
```

---

**End of Session Handoff**
