# Champion Spirit API

## Project Overview

Champion Spirit is a SaaS platform for managing fitness/wellness/coworking centers. This is the Laravel REST API backend powering:
- A mobile app (Expo/React Native)
- A Filament admin panel
- An AI chatbot (multi-provider)
- Web booking and access validation interfaces

## Tech Stack

- **Framework:** Laravel 10.12.0 / PHP 8.2+ (`strict_types` mandatory)
- **Database:** MySQL (utf8mb4_bin)
- **Auth:** Laravel Sanctum (Bearer tokens)
- **Admin:** Filament 2.x
- **Tests:** Pest 2.6
- **Static Analysis:** PHPStan level 7 (Larastan)
- **Linting:** Laravel Pint (Laravel preset)
- **CI/CD:** GitHub Actions (tests + quality)
- **Monitoring:** Sentry
- **Queue:** sync (dev) / redis (prod)
- **Storage:** MinIO (dev) / S3 Scaleway (prod)
- **Real-time:** Pusher
- **Money:** brick/money pattern (`{field}_amount` bigint + `{field}_currency` string)

## Critical Rules

1. **Pre-commit check:** Always run `./gitCheck.sh` before committing (runs `composer lint` + `composer types`)
2. **Strict types:** Every PHP file must start with `declare(strict_types=1);`
3. **Public ID:** Never expose auto-increment `id` in the API. Always use `public_id` (UUID). In Resources: `'id' => $this->public_id`
4. **Final classes:** All classes are `final` by default unless inheritance is explicitly needed
5. **Conventional commits:** `type(scope): description` — types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert
6. **Swagger docs:** Every new API controller MUST have `@OA\` OpenAPI annotations. Run `php artisan l5-swagger:generate` after adding endpoints
7. **Tests required:** Every new feature MUST have Pest tests
8. **Translations:** User-facing text fields on models MUST use `HasDatabaseTranslations` trait
9. **PHPDoc:** `@throws` on Actions/Services, `@property-read` on model relations, `@mixin` on Resources, `@param Collection<int, Model>` for generic collections
10. **No debug code:** No `dd()`, `dump()`, `var_dump()` in committed code
11. **Explicit fillable:** Use `$fillable`, never `$guarded = []`
12. **Reversible migrations:** Always provide `down()` method
13. **Timezone:** UTC in database, Place timezone for temporal queries. Use `CarbonImmutable`, never mutable Carbon

## Two Separate Systems: API REST vs Filament Admin

| Aspect | API REST | Filament Admin |
|--------|----------|----------------|
| Target | Mobile app, chatbot, frontend | Back-office employees |
| Auth | Sanctum Bearer tokens | Web session |
| Users | Customers, Coaches, Employees | Employees only (with roles) |
| URL | `/v1/*` | `/admin/*` |
| Code | `app/Http/Controllers/Api/` | `app/Filament/Resources/` |

Shared business logic lives in Actions (`app/Actions/`) and Services (`app/Services/`).

## Architecture & Code Placement

| Code Type | Location | Naming Convention |
|-----------|----------|-------------------|
| API Controller | `app/Http/Controllers/Api/{Domain}/` | `{Verb}{Subject}Controller.php` |
| Action | `app/Actions/{Domain}/` | `{Verb}{Subject}Action.php` |
| Service | `app/Services/{Domain}/` | `{Domain}Service.php` |
| Model | `app/Models/` | `{Entity}.php` |
| Enum | `app/Enums/` | `{Name}.php` |
| Observer | `app/Observers/` | `{Model}Observer.php` |
| Form Request | `app/Http/Requests/` | `{Action}{Subject}Request.php` |
| API Resource | `app/Http/Resources/` | `{Model}Resource.php` |
| Filament Resource | `app/Filament/Resources/` | `{Model}Resource.php` |
| Builder | `app/Builders/` | `{Model}Builder.php` |
| DTO | `app/Data/` | `{Name}Data.php` |
| Test | `tests/Feature/` or `tests/Unit/` | `{Description}Test.php` |

### Flow Pattern

```
Route -> Middleware -> Controller -> FormRequest (validation)
                          |
                          v
                    Action/Service (business logic)
                          |
                          v
                    Model (persistence) -> Observer (side effects) -> Event -> Listener
                          |
                          v
                    Resource (JSON transformation)
```

### Controller Pattern

One controller = one action = one `__invoke` method. Always `final`. Example: `{Verb}{Subject}Controller`.

### API Response Format

Resources extend `ApiResource`. Pagination uses `page` + `size` params with format:
```json
{ "data": [...], "totalItems": 42, "totalPages": 5 }
```

## Key Models

| Model | Description |
|-------|-------------|
| `User` | User (customer/coach/employee) |
| `Place` | Center (gym, spa, coworking) |
| `Booking` | Reservation (polymorphic bookable) |
| `Order` / `OrderItem` | Order with polymorphic orderable items |
| `Wallet` / `WalletTransaction` | Credit wallet system |
| `Membership` | Subscription |
| `Service`, `Activity`, `PersonalCourse`, `GroupCourse`, `Event` | Bookable entities |
| `Pack` | Credit/daypass packages |
| `Product` | Shop products |

All models inherit from `BaseModel` (not `Model` directly). Morph maps are in `AppServiceProvider::boot()`.

## Wallet System

- `Wallet.balance` — Credits (float)
- `Wallet.balance_daypass` — Day passes (int)
- `Wallet.balance_guest_pass` — Guest passes (int)
- Every operation creates a `WalletTransaction`

## Payment Flow

```
POST /v1/orders -> UpsertOrderAction
POST /v1/orders/{id}/stripe-pay -> Stripe session
Stripe Webhook -> OrderPaid event -> Listeners:
  - CreateBookingWhenOrderConfirmed
  - CreditWalletWhenPackOrderConfirmed
  - FulfillFlexMembershipWhenOrderPaid
```

## Notifications

Channels: `sendinblue_email`, `expo` (push), `database`. Convention: `{Role}{Action}Notification.php`.

## Translations

4 languages: en, es, fr, zh. Two systems:
1. **JSON files** (`storage/languages/`) — UI strings for mobile/back-office
2. **Database** (`model_translations`) — Model field translations via `HasDatabaseTranslations` trait

After translation changes: `php artisan translations:clear-cache`

## Useful Commands

```bash
composer lint          # Code style check/fix (Pint)
composer types         # Static analysis (PHPStan level 7)
composer test          # Run tests (Pest)
./gitCheck.sh          # Pre-commit: lint + types (MANDATORY)
./reloadChanges.sh     # Reload caches + swagger
./setPermissions.sh    # Fix file permissions
php artisan migrate    # Run migrations
php artisan db:seed    # Seed database
php artisan l5-swagger:generate  # Regenerate Swagger docs
php artisan cache:clear && php artisan config:clear && php artisan route:clear && php artisan view:clear  # Clear all caches
```

## Files Never to Modify Without Good Reason

- `composer.lock`, `package-lock.json` — auto-generated
- `phpstan-baseline.neon` — only via `--generate-baseline`
- `storage/packages/` — local packages managed separately
- `.env` — environment-specific
- `public/build/` — generated by Vite
- `storage/api-docs/` — generated by l5-swagger

## Documentation Reference

Detailed docs are in `docs/`:
- `ARCHITECTURE.md` — Folder structure and patterns
- `MODELS_DATABASE.md` — All models and DB schema
- `API_ROUTES.md` — All API endpoints
- `FILAMENT_ADMIN.md` — Admin panel (Resources, Pages, Widgets, Policies)
- `BUSINESS_LOGIC.md` — Services, Actions, Jobs, Events
- `CONFIGURATION.md` — Config, CI/CD, DevOps scripts
- `CODING_STANDARDS.md` — Detailed coding conventions

## After Initialization

Once you have read this file, ask the user what they want to do. Based on their answer, read the relevant docs before starting work:

| Task | Docs to read |
|------|-------------|
| **Develop** (new feature, endpoint, model) | `docs/ARCHITECTURE.md`, `docs/CODING_STANDARDS.md`, `docs/MODELS_DATABASE.md`, `docs/API_ROUTES.md` |
| **Filament** (admin panel work) | `docs/FILAMENT_ADMIN.md`, `docs/MODELS_DATABASE.md` |
| **Audit / Review** (code quality, PHPStan, security) | `docs/CODING_STANDARDS.md`, `docs/ARCHITECTURE.md` |
| **Test** (write or fix tests) | `docs/CODING_STANDARDS.md` (section 5: Tests), `docs/MODELS_DATABASE.md` |
| **Debug / Fix** (bug investigation) | `docs/BUSINESS_LOGIC.md`, `docs/MODELS_DATABASE.md`, `docs/API_ROUTES.md` |
| **DevOps / Config** (CI, scripts, env) | `docs/CONFIGURATION.md` |
| **Implementation plan** (multi-phase feature) | Check `docs/implementation/` for existing plans, then all relevant docs |

Ask: **"What would you like to do? (develop, filament, audit, test, debug, devops, or describe your task)"**
