# CC Soccer D11 - Session Handoff

**Last Updated:** January 26, 2026 - Afternoon  
**Status:** ✅ CCSoccer Pool badge persistence and styling fixes complete

---

## Quick Reference

### Installation
See `INSTALLATION_GUIDE.md` for full details. Quick start:
```bash
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 config:set system.site uuid $(grep uuid config/sync/system.site.yml | awk '{print $2}') -y
ddev drush entity:delete shortcut_set default -y
ddev drush cim -y
ddev drush updb -y
ddev drush cr
ddev drush ccs-seed --users
ddev launch
```

### Common Commands
```bash
ddev drush cr                              # Clear cache
ddev drush updb -y                         # Run database updates
ddev drush cex -y                          # Export config
ddev drush cim -y                          # Import config
ddev drush ccs-seed --users                # Seed test data
ddev drush ccs-seed --test --force         # Registration testing data
ddev drush ccs-seed --force --populate-seasons  # Season testing data
ddev drush ccs-seed --force --populate-tournaments  # Tournament testing data
```

### Test Accounts
| Username | Password | Role |
|----------|----------|------|
| `admin` | `admin` | Administrator |
| `player_test` | `password` | Authenticated |
| `board_test` | `password` | Board Member |
| `slofriendly_test` | `password` | Slofriendly |
| `testuser0` | `password` | Authenticated (for personalized states) |

---

## ✅ COMPLETED THIS SESSION (January 26, Afternoon)

### Bug Fix: CCSoccer Pool Badge Persistence

**Issue:** Pool players (testuser60-69) showed (P) badge initially, but badge disappeared after:
1. Moving pool player to a team
2. Moving pool player to the workbench
3. Page refresh

**Root Cause:** Two separate issues:
1. `buildPlayerCard()` used the `$is_pool` parameter (rendering context) instead of player's actual `ccsoccer_pool` field value
2. Controller methods explicitly cleared `ccsoccer_pool = FALSE` when moving players to teams or groups

**Fixes Applied:**

#### Fix 1: buildPlayerCard() uses player data, not render context
- **File:** `src/Form/TournamentRosterBuilderForm.php`
- **Function:** `buildPlayerCard()`
- Changed from: `$pool_indicator = $is_pool ? ...` (used parameter)
- Changed to: `$player_is_pool = $player['ccsoccer_pool'] ?? FALSE;` (uses player data)

#### Fix 2: Stop clearing ccsoccer_pool when moving players
- **File:** `src/Controller/TournamentRosterBuilderController.php`
- **Function:** `move()` - Removed `$registration->set('ccsoccer_pool', FALSE)` when moving to team
- **Function:** `move()` - Changed workbench logic to only SET pool TRUE, never clear it
- **Function:** `mergeToGroup()` - Removed pool clearing
- **Function:** `createGroup()` - Removed pool clearing for both manager and member

**Behavior Now:**
- Pool status is a **persistent marker** from registration
- Badge shows everywhere: pool section, workbench, teams, groups
- Only set TRUE when explicitly moving TO pool section
- Never cleared - allows admin to track pool players wherever they go

---

### Styling Update: CCSoccer Pool Section - Red Theme

**Request:** CCSoccer colors are red, change pool section from teal to red.

**File:** `css/tournament-roster-builder.css`

**Changes:**
| Element | Before (Teal) | After (Red) |
|---------|---------------|-------------|
| Pool badge background | `#17a2b8` | `#dc3545` |
| Pool badge text | `white` | `#000` (black) |
| Section border-top | `#17a2b8` | `#dc3545` |
| Section background | `#e8f7fa` | `#fdf2f2` |
| Header h3 color | `#17a2b8` | `#dc3545` |
| Player count badge | `#17a2b8` | `#dc3545` |
| Dashed border | `#17a2b8` | `#dc3545` |
| Drag-over highlight | `rgba(23, 162, 184, 0.15)` | `rgba(220, 53, 69, 0.15)` |

---

### Bug Fix: Tournament Seed Command - UUID for group_id

**Issue:** Tournament teams created by `ddev drush ccs-seed --populate-tournaments` used non-UUID group_id format like `team_1359_165`, causing "Manage Group" links to break.

**File:** `src/Drush/Commands/CcsoccerCommands.php`
**Function:** `populateTournamentsWithTeams()`

**Change:**
- Before: `$group_id = "team_{$team_id}_{$captain_id}";`
- After: `$group_id = \Drupal::service('uuid')->generate();`

Now consistent with season group UUID format (e.g., `950e40f5-7b46-4a69-8311-29116743fdd1`).

---

## Files Modified This Session

| File | Function | Change |
|------|----------|--------|
| `src/Form/TournamentRosterBuilderForm.php` | `buildPlayerCard()` | Use player data for pool badge |
| `src/Controller/TournamentRosterBuilderController.php` | `move()` | Don't clear pool when moving to team; only set TRUE for pool |
| `src/Controller/TournamentRosterBuilderController.php` | `mergeToGroup()` | Don't clear pool status |
| `src/Controller/TournamentRosterBuilderController.php` | `createGroup()` | Don't clear pool for manager or member |
| `css/tournament-roster-builder.css` | Pool badge + section | Changed from teal to red theme |
| `src/Drush/Commands/CcsoccerCommands.php` | `populateTournamentsWithTeams()` | Use UUID for group_id |

---

## Testing Checklist - This Session's Fixes

### Pool Badge Persistence
1. [ ] Run `ddev drush ccs-seed --force --populate-tournaments`
2. [ ] Go to Tournament Roster Builder
3. [ ] Pool players (testuser60-69) show red (P) badge in CCSoccer Pool section
4. [ ] Drag pool player to a team → badge persists
5. [ ] Refresh page → badge still shows on team
6. [ ] Drag pool player to workbench → badge persists
7. [ ] Refresh page → badge still shows in workbench
8. [ ] Shift+drag pool player to merge with group → badge persists

### Red Styling
1. [ ] CCSoccer Pool section has red border, light red background
2. [ ] "CCSoccer Pool" header text is red
3. [ ] Player count badge is red with white text
4. [ ] Pool badges are red circles with black "P"
5. [ ] Drag-over highlight is red-tinted

### Tournament Group Management
1. [ ] Click "Manage group" on tournament team → URL has UUID (not team_id_captain_id)
2. [ ] Group management page loads correctly

---

## ✅ COMPLETED EARLIER TODAY (January 26, Morning)

### Bug Fix: Tournament Invitation Flow

**Issue:** Andrew identified multiple problems with the tournament invitation flow:
1. Click invite link → works correctly
2. My Registrations "Register to Accept" button → went to `/register` without invite token
3. `/register` page → no mention of pending invitations

**Fixes Applied:**

#### Fix 1: Template - Register to Accept button includes invite token
- **File:** `templates/ccsoccer-my-registrations.html.twig`
- Changed link from `path('ccsoccer.register')` to `path('ccsoccer.register', {invite: item.invitation.token.value})`

#### Fix 2: acceptTeamInvitationDirectly() uses UUID group_id
- **File:** `src/Controller/RegistrationController.php`
- Now uses: `$team->getGroupId()` (UUID from Team entity)

#### Fix 3: Pending invitations banner on /register page
- **File:** `src/Controller/RegistrationController.php`
- New methods: `getPendingInvitationsForUser()`, `buildPendingInvitationsSection()`
- Yellow banner shows pending invitations with accept/decline buttons

---

### Earlier Today: Group Management Fixes

- My Registrations filter for past seasons/tournaments
- Co-captain invitation permissions using `Team::isTeamLeader()`
- 3-tier duplicate invitation prevention
- Tournament team UUID group_id

---

## Project Status (~90% Complete)

### ✅ Complete
- All 10 custom entities + SeasonCreditEvent entity
- Registration flow (season + tournament)
- Group management system (with co-captain support)
- Roster builder with drag-drop and balancing
- Tournament Roster Builder with CCSoccer Pool ✅
- Schedule builder with round-robin generation
- Notification service (email/SMS)
- Game status with auto-reset and credits
- Credits system (Phases 1-5, A, B, C complete)
- Season publishing with visibility flags
- Override system with admin UI
- Content pages
- Masquerade for testing
- Cart duplicate prevention
- Team roster access control
- Registration page cache invalidation
- Duplicate registration prevention
- Override status mismatch fix
- Capacity validation defense in depth
- Season-specific notification links
- Dashboard waitlist/reserved columns
- Phase A: Season Credits Summary Page
- Schedule cancellation overlay (Andrew)
- All Players admin page with search/pagination
- Inline skill level editing on player pages
- My Registrations filter for past seasons
- Co-captain invitation permissions
- Tournament team UUID group_id
- Tournament invitation flow improvements
- CCSoccer Pool badge persistence ✅
- CCSoccer Pool red styling ✅

### 📋 Backlog
- Reports (City Payment, Insurance, Tournament Team, Jersey)
- Migration scripts from D7
- Mobile testing
- End-to-end testing

---

## Credits System Overview (All Phases Complete)

| Phase | Description | Status |
|-------|-------------|--------|
| Phase 1 | Credits entity with cents-based storage | ✅ |
| Phase 2 | CreditManagerService with FIFO usage | ✅ |
| Phase 3 | Checkout integration with credits pane | ✅ |
| Phase 4 | Credit sources (rainout, cancellation, admin) | ✅ |
| Phase 5 | GameStatusForm with credit preview | ✅ |
| Phase A | Season Credits Summary Page | ✅ |
| Phase B | Admin User Credits Management | ✅ |
| Phase C | Player Credits Page (/my-credits) | ✅ |

---

## Key Entity Relationships (Tournament Teams)

```
Tournament
  └── Team (has group_id UUID, captain, co_captain, players[])
        └── Registration (links player to team, stores group_id, ccsoccer_pool flag)
        └── Invitation (links to team by team_id, not group_id)
```

**Important:** For tournaments, the Team entity is the source of truth for:
- `players` field - who is on the team
- `captain` field - the team captain (user reference)
- `co_captain` field - the co-captain (user reference)
- `group_id` field - UUID for admin URLs (NOT captain-based)

**CCSoccer Pool:** The `ccsoccer_pool` field on Registration is a **persistent marker**:
- Set TRUE during registration if player selected "CCSoccer Pool" option
- Never cleared when moving players around
- Shows (P) badge in red circle wherever player appears

The `Team::isTeamLeader($user_id)` method returns TRUE if user is captain OR co-captain.

---

## 📋 Deferred TODOs

### 1. Enhance Cancellation Notification
- Add credit/refund details to `sendRegistrationCancelled()` notification
- Currently just says "has been cancelled" without financial details

---

## Collaboration Notes

**Working with Andrew:**
- Always `git pull` before `git push`
- Use SESSION_HANDOFF.md for detailed context
- Andrew completed: Schedule cancellation overlay ✅

**Code Style:**
- Complete functions (not partial updates)
- Detailed logging for debugging
- Clear comments explaining business logic

---

## Recent Changes Log

**January 26, 2026 (Afternoon):**
- Fixed CCSoccer Pool badge persistence - now shows everywhere player goes
- Changed pool section styling from teal to red (CCSoccer brand colors)
- Fixed tournament seed command to use UUID for group_id

**January 26, 2026 (Morning):**
- Fixed tournament invitation flow for seamless user experience
- Template: Register to Accept button now includes invite token
- RegistrationController: acceptTeamInvitationDirectly uses UUID group_id
- Register page: Added pending invitations banner for logged-in users

**January 26, 2026 (Early Morning):**
- Fixed My Registrations to filter out past seasons/tournaments
- Fixed co-captain invitation permissions using Team::isTeamLeader()
- Added 3-tier duplicate invitation prevention for tournaments
- Fixed tournament group_id to use UUID stored on Team entity (not captain-based)

**January 25, 2026 (Late Evening):**
- Fixed cart duplicate prevention - checks cart before adding season/tournament
- Fixed re-registration after cancellation - excludes cancelled registrations from duplicate check

**January 25, 2026 (Evening):**
- Added inline skill level editing to Season Players and All Players pages
- Created PlayerSkillController with AJAX endpoint
- Added player-skill.js for auto-save with visual feedback
- Updated sort order on Season Players (empty skill first, then by name)
- Added sticky table headers accounting for Drupal admin toolbar

**January 25, 2026 (Afternoon):**
- Marked Schedule cancellation overlay as complete (Andrew)

**January 25, 2026 (Morning):**
- Completed Phase A: Season Credits Summary Page
- Created SeasonCreditEvent entity
- Added two-step Add Season Credit form

---

## Documentation Index

| Document | Purpose |
|----------|---------|
| `INSTALLATION_GUIDE.md` | Full setup instructions, troubleshooting |
| `SESSION_HANDOFF.md` | This file - current state and handoff notes |
| `PROJECT_STATUS.md` | Detailed project status |
| `ARCHITECTURE_DECISIONS.md` | Key architecture decisions |
| `REQUIREMENTS_TO_ARCHITECTURE.md` | Original requirements mapping |

---

**End of Session Handoff**
