# CC Soccer D11 - Session Handoff

**Last Updated:** January 24, 2026 - 5:30pm  
**Status:** ✅ Credits system Phases B & C 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: Credits System Enhancement (Phases B & C)

### Phase B - Admin User Credits Management ✅

**Routes Added:**
- `/admin/ccsoccer/player/{user}/credits` - View user's credit history
- `/admin/ccsoccer/player/{user}/credits/add` - Add new credit for user
- `/admin/ccsoccer/credit/{credits}/edit` - Edit existing credit
- `/admin/ccsoccer/credit/{credits}/revoke` - Revoke active credit

**Features:**
- "Credits" tab on user profile pages (for admins with 'view reports' permission)
- View complete credit history for any user
- Add credits with amount, reason, and optional season association
- Edit existing credits (amount, reason, season, status)
- Single-click revoke for active credits

**Files Created:**
- `ccsoccer.links.task.yml` - Local task for Credits tab on user profiles
- `templates/ccsoccer-admin-user-credits.html.twig` - Admin credits view template
- `css/admin-credits.css` - Admin credits styling
- `src/Controller/AdminCreditsController.php` - Admin credits controller
- `src/Form/AdminCreditForm.php` - Add/edit credit form

**Files Modified:**
- `ccsoccer.routing.yml` - Added 4 admin user credits routes
- `ccsoccer.libraries.yml` - Added admin-credits library
- `ccsoccer.module` - Added ccsoccer_admin_user_credits theme hook

### Phase C - Player Credits Page ✅

**Route:** `/my-credits`  
**Access:** Authenticated users only

**Features:**
- Prominent credit balance display
- Summary showing earned, used, and donated totals
- Credit history table with source, amount, status, and expiration
- Clean, responsive styling

**Files Created:**
- `templates/ccsoccer-player-credits.html.twig` - Player credits view template
- `css/player-credits.css` - Player credits styling
- `src/Controller/PlayerCreditsController.php` - Player credits controller

**Files Modified:**
- `ccsoccer.routing.yml` - Added my-credits route
- `ccsoccer.links.menu.yml` - Added "My Credits" to main menu
- `ccsoccer.libraries.yml` - Added player-credits library
- `ccsoccer.module` - Added ccsoccer_player_credits theme hook

---

## 📋 TODO: Phase A - Season Credits Summary Page

**Status:** Not Started  
**Priority:** Medium

### Overview
Replace the current per-player credits list at `/admin/ccsoccer/season/{season}/credits` with a high-level Season Credit Events view.

### Current State
- Shows ALL individual credits for every player in the season
- Includes: Date, Player, Amount, Source, Reason, Status, Expires
- Multiple rows per player possible

### Desired State (From Old Site)
- Simple list of credit events (not per-player)
- "Add New Season Credit" link at top
- Columns: Date Created, Amount, Title, Apply Dates, Revoke Dates, Actions
- Actions: Apply (if not applied), Revoke, Edit, Delete

### Implementation Questions to Resolve
1. **Storage:** New entity `SeasonCreditEvent` or simpler database table/config?
2. **Apply/Revoke Flow:** Use same preview/confirm pattern as Game Status?
3. **Relationship to Game Status:** Should rainout credits create a Season Credit Event record?
4. **Revoke behavior:** Delete credits or mark as revoked?

### Proposed SeasonCreditEvent Fields
```
- season (entity_reference to season)
- amount_cents (integer)
- title (string) - e.g., "Rainout Jan 22", "Admin bonus"
- source (list) - rain_out, admin_credit, other
- status (list) - pending, applied, revoked
- applied_date (datetime)
- revoked_date (datetime)
- credits_issued_count (integer)
- total_amount_issued (integer)
```

### Files to Create/Modify
- New: `src/Entity/SeasonCreditEvent.php` (if using entity)
- New: `src/Form/SeasonCreditEventForm.php`
- Modify: `SeasonController.php` - Update `credits()` method
- Modify: `GameStatusForm.php` - Optionally create Season Credit Event records

---

## ✅ COMPLETED: Full Credits System (Phases 1-5)

### Current Working Checkout Flow

| Step | Page | Button Label | Goes To |
|------|------|--------------|---------|
| player_information | Player Information | Continue to Group | group_invitations |
| group_invitations | Group | Continue to Agreements | agreements |
| agreements | Agreements | Continue to Credits | credits |
| credits | Player Credits | Continue to Review | review |
| review | Review | Pay and complete purchase | payment (hidden) |
| payment | (hidden) | (processes payment) | complete |
| complete | Complete | (no button) | - |

### Phase 1-2: Credits Display and Admin
- Season Players page shows player credit balances
- Season Credits admin page for viewing all credits by season
- Credits entity updated with proper field definitions (amount in cents, status, source, reason)

### Phase 3: Cancel Registration with Credits
- New CancelRegistrationForm for admin cancellation workflow
- Issues credit to player when registration is cancelled
- Updates registration status and logs the action

### Phase 4: Automatic Rainout Credits
- GameStatusForm extended to issue credits when game marked as rainout
- Calculates credit amount based on (season_price / total_games) * 75%
- Dynamic UI shows affected players and credit amounts before confirmation
- Bulk credit issuance to all registered players for rained out games

### Phase 5: Checkout Credits Integration
- Dedicated credits step in checkout flow (between Agreements and Review)
- Players can apply credits, keep for later, or donate to league
- Shows "no credits" message when balance is zero
- Credits applied as order adjustment (reduces total)
- OrderCompleteSubscriber processes credit usage and donations on order completion

### Checkout Flow Technical Details
**Key Insight:** In Commerce Checkout, the button label comes from the NEXT step's `next_label`, not the current step's.

**Critical Requirement:** The `payment_process` pane MUST stay on the `payment` step because it hardcodes return/cancel URLs to that step. Moving it causes redirect loops.

### Credit Manager Service
- All amounts stored in CENTS (integer) to avoid floating point issues
- Methods: `issueCredit`, `issueRainoutCredit`, `issueCancellationCredit`
- Methods: `useCredits` (FIFO), `donateCredits`, `getUserBalanceCents`
- Methods: `calculateRainoutCreditCents`, `getSeasonCredits`
- Logging via `@logger.factory` dependency injection

### Update Hooks for Credits
- 9041: Credits entity fields (amount in cents, season reference)
- 9042: Move ccsoccer_credits pane to dedicated credits step
- 9043: Ensure payment_process pane stays on payment step

---

## ✅ ALSO COMPLETED: Security & Bug Fixes

### Access Control - Team Roster Privacy
- Changed `/teams` and `/team/{team}` routes to require authentication
- Anonymous users redirected to login when accessing team rosters
- File: `ccsoccer.routing.yml`

### Cache Invalidation Fix - Registration Page
- Added dynamic cache tags in `RegistrationController::available()`
- Implemented `postSave()` and `postDelete()` in Registration entity
- Spots remaining now updates immediately after registration
- Files: `RegistrationController.php`, `Registration.php`

### Duplicate Registration Prevention
- Added duplicate check in `addSeasonToCart()` and `addTournamentToCart()`
- If already registered: shows warning + redirects to group management
- File: `RegistrationController.php`

### Cart Duplicate Prevention
- CartEventSubscriber prevents adding same season/tournament twice
- Forces quantity back to 1 and displays warning
- File: `src/EventSubscriber/CartEventSubscriber.php`

---

## Project Status (~87% Complete)

### ✅ Complete
- All 10 custom entities (League, Season, Tournament, Team, Game, Registration, Credits, Invitation, Waitlist, Override)
- Registration flow (season + tournament)
- Group management system
- Roster builder with drag-drop and balancing algorithm
- Schedule builder with round-robin generation
- Notification service (email/SMS)
- Game status with auto-reset and credits
- **Credits system - Phases 1-5 (checkout integration)**
- **Credits system - Phase B (admin user credits management)**
- **Credits system - Phase C (player credits page)**
- Season publishing with visibility flags
- Override system with admin UI
- Content pages (home, teams, schedule, my-schedule, my-teams, jerseys)
- Masquerade for testing
- Cart duplicate prevention
- Team roster access control
- Registration page cache invalidation
- Duplicate registration prevention

### ⏳ In Progress
- Schedule cancellation overlay (Andrew)

### 📋 Backlog
- **Phase A: Season Credits Summary Page** - High-level credit events view
- Reports (City Payment, Insurance, Tournament Team, Jersey)
- Migration scripts from D7
- Mobile testing
- End-to-end testing

---

## For Next Session

### Testing Priority
1. Test "Credits" tab on user profile pages
2. Test adding/editing/revoking credits via admin interface
3. Test player /my-credits page
4. Test checkout flow with credits still works
5. Test rainout credit issuance from Game Status form

### Phase A Implementation (When Ready)
- Decide on storage approach (entity vs table)
- Create SeasonCreditEvent entity or table
- Modify SeasonController::credits() for summary view
- Create apply/revoke functionality
- Integrate with GameStatusForm for rainout tracking

---

## Development Environment

**Stack:**
- DDEV local development
- Drupal 11
- PHP 8.3
- MariaDB 10.6+

**Notification Testing:**
- Local emails → MailHog: https://ccsoccer-d11.ddev.site:8026
- SMS disabled in dev (checks environment)

**Mobile Testing:**
- Set `bind_all_interfaces: true` in `.ddev/config.yaml`
- Access via `http://<your-ip>.ddev.site`
- See INSTALLATION_GUIDE.md for details

---

## Fresh Install Notes

The checkout flow config is managed in two places:
1. `config/install/commerce_checkout.commerce_checkout_flow.ccsoccer.yml` - For fresh module installs
2. `config/sync/` - For site config import

**IMPORTANT:** If you need to reset your environment:
1. Export config first: `ddev drush cex -y`
2. Commit changes
3. Follow Clean Install steps in INSTALLATION_GUIDE.md
4. Verify checkout config after install (Step 10 in guide)

Expected verification output:
```yaml
# ccsoccer_credits pane
step: credits

# payment_process pane
step: payment
```

---

## Key Architecture Decisions

### Credits Storage
- All amounts stored in CENTS (integer) to avoid floating point issues
- Use CreditManagerService methods for conversion:
  - `dollarsToCents()` / `centsToDollars()`
  - `formatCentsAsDollars()` - Returns $X.XX format

### Commerce Checkout Flow
- Button labels use `next_label` from the DESTINATION step, not current step
- `payment_process` pane must stay on `payment` step (hardcoded URLs)
- Keep `payment` step even if hidden

### Config Management
- Module config in `config/install/` - imported on fresh module install
- Site config in `config/sync/` - imported with `drush cim`
- Update hooks for database changes on existing installs
- Helper functions called from both update hooks AND `hook_install()`

---

## Collaboration Notes

**Working with Andrew:**
- Always `git pull` before `git push`
- Use SESSION_HANDOFF.md for detailed context
- View existing files before modifying
- Comprehensive testing before commits
- Andrew working on: Schedule cancellation overlay

**Code Style:**
- Complete functions (not partial updates)
- Detailed logging for debugging
- Clear comments explaining business logic
- Follow Drupal coding standards
- Use update hooks for database/config changes (infrastructure as code)

---

## Git Workflow

```bash
git pull                          # Always pull first
git status                        # Check what changed
git add .                         # Stage changes
git commit -m "Descriptive msg"   # Commit
git push                          # Push to remote
```

---

## Recent Changes Log

**January 24, 2026 (5:30pm):**
- Completed Phase B: Admin User Credits Management
  - Credits tab on user profile pages
  - Add/edit/revoke credits for any user
  - AdminCreditsController and AdminCreditForm
- Completed Phase C: Player Credits Page
  - /my-credits route for authenticated users
  - Balance display with earned/used/donated totals
  - Credit history table
  - PlayerCreditsController and template

**January 22, 2026 (5:00am):**
- Fixed checkout flow button labels and step order
- Added helper functions to hook_install() for fresh installs
- Updated INSTALLATION_GUIDE.md with config export step and checkout verification

**January 22, 2026 (4:00am):**
- Access control: Require login for team roster pages
- Cache fix: Registration page spots remaining now updates immediately
- Security: Prevent duplicate registration payments via direct URL access

**January 21, 2026 (9:30pm):**
- Complete credits system (Phases 1-5)
- Dedicated credits step in checkout flow
- Rainout credits, cancellation credits, checkout integration
- Credit Manager Service rewrite (cents-based)

**January 21, 2026 (6:40pm):**
- Cart duplicate prevention via EventSubscriber
- Fixed Commerce AJAX cart operations

---

## Documentation Index

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

---

**End of Session Handoff**
