# CC Soccer D11 - Session Handoff

**Last Updated:** January 22, 2026 - 5:00am  
**Status:** ✅ Credits system complete and working

---

## 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  # Trounament 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: 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

### Files Modified for Credits
```
modified:   ccsoccer.install (update hooks 9041-9043, hook_install phases 23-25)
modified:   ccsoccer.libraries.yml
modified:   ccsoccer.module
modified:   ccsoccer.routing.yml
modified:   ccsoccer.services.yml
modified:   config/install/commerce_checkout.commerce_checkout_flow.ccsoccer.yml
new file:   css/checkout-credits.css
modified:   src/Controller/RegistrationController.php
modified:   src/Controller/SeasonController.php
modified:   src/Entity/Credits.php
modified:   src/EventSubscriber/OrderCompleteSubscriber.php
new file:   src/Form/CancelRegistrationForm.php
modified:   src/Form/GameStatusForm.php
modified:   src/Plugin/Commerce/CheckoutFlow/CCSoccerCheckoutFlow.php
modified:   src/Plugin/Commerce/CheckoutPane/CreditsPane.php
modified:   src/Service/CreditManagerService.php
```

---

## ✅ 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 (~85% 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 - FULL IMPLEMENTATION**
- 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 6: Player Credits Management Page (public-facing credit history)
- Reports (City Payment, Insurance, Tournament Team, Jersey)
- Migration scripts from D7
- Mobile testing
- End-to-end testing

---

## For Next Session

### Testing Priority
1. ✅ Complete checkout flow with credits - WORKING
2. Test credits properly deducted after order completion
3. Test rainout credit issuance from Game Status form
4. Test cancel registration credit issuance
5. Test fresh install (see INSTALLATION_GUIDE.md Step 10)

### Phase 6 (Not Started)
- Player Credits Management Page (public-facing credit history)
- Manual adjustment capability for admins
- Filter by status
- Total balance display

### Nice to Have
- Checkout button alignment CSS fixes

---

## 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 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
- Updated SESSION_HANDOFF.md

**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 |
| `PROJECT_STATUS.md` | Detailed project status |
| `ARCHITECTURE_DECISIONS.md` | Key architecture decisions |
| `REQUIREMENTS_TO_ARCHITECTURE.md` | Original requirements mapping |

---

**End of Session Handoff**
