# Modeles Eloquent & Schema de Base de Donnees

## Vue d'ensemble

Le projet utilise **54+ modeles Eloquent** repartis dans `app/Models/`. Tous les modeles metier heritent de `BaseModel` qui applique le trait `ConvertDateTimeToUTC` pour normaliser les dates en UTC.

**Conventions :**
- Tous les modeles metier ont un `public_id` (UUID v4 ordonne) via le trait `HasPublicId`
- Le `public_id` est utilise dans les URLs et l'API (jamais l'`id` auto-increment)
- Soft deletes sur la quasi-totalite des modeles
- Les champs monetaires utilisent le pattern `{field}_amount` + `{field}_currency` avec le cast `AsMoney` (brick/money)
- Les champs traduisibles utilisent le trait `HasDatabaseTranslations` et la table `model_translations`

---

## Modele de Base

### BaseModel (`app/Models/BaseModel.php`)

Classe abstraite etendant `Illuminate\Database\Eloquent\Model`.

**Trait applique :**
- `ConvertDateTimeToUTC` : Convertit automatiquement les dates en UTC lors de la serialisation

Tous les modeles metier (sauf User et quelques modeles systeme) heritent de BaseModel.

---

## Modeles par Domaine

### 1. Utilisateurs & Authentification

#### User (`app/Models/User.php`)

Le modele central du systeme. Un User peut etre Customer, Coach et/ou Employee simultanement.

**Traits :**
- `HasApiTokens` (Sanctum), `HasFactory`, `Notifiable`, `SoftDeletes`
- `HasPublicId`, `InteractsWithMedia` (Spatie), `LogsActivity` (Spatie)
- `HasConversations`, `HasDatabaseTranslations`, `SyncsQuickbooksCustomer`

**Champs principaux :**
| Champ | Type | Description |
|-------|------|-------------|
| `firstname` | string | Prenom |
| `lastname` | string | Nom |
| `email` | string (unique) | Email principal |
| `email_2` | string (nullable) | Email secondaire |
| `phone` | string (nullable) | Telephone |
| `gender` | enum (Gender) | Genre |
| `type` | enum (UserType) | CUSTOMER, COACH, EMPLOYEE |
| `lang` | string | Code langue (en, fr, es, zh) |
| `is_vip` | boolean | Statut VIP |
| `allow_busy_bypass` | boolean | Ignorer les conflits de planning |
| `unlimited_credits` | boolean | Credits illimites |
| `force_vat_exclusive` | boolean | Forcer HT |
| `discount` | integer | Pourcentage de remise |
| `place_id` | FK | Lieu principal |
| `family_id` | FK (nullable) | Famille |
| `stripe_customer_id` | string (nullable) | ID client Stripe |
| `member_infos` | JSON (nullable) | Infos membre supplementaires |
| `chat_notification` | boolean | Notifications chat actives |
| `email_notification` | boolean | Notifications email actives |
| `push_notification` | boolean | Notifications push actives |
| `kids_zone` | boolean | Acces zone enfants |
| `registered` | boolean | Inscription complete |

**Relations :**
- `hasOne` : Coach, Employee, Wallet
- `hasMany` : Orders, Bookings, Guests (via GuestUser), Kids, SocialAccounts, Notifications, TrackingEntries, PlaceAccessLogs, DoorAccesses, BioStar2Cards
- `belongsTo` : Place, Family
- `belongsToMany` : Roles (Spatie), FavouriteCoaches, FavouriteCategories

**Builder personnalise :** `UserBuilder`

---

#### Coach (`app/Models/Coach.php`)

Profil coach lie a un User (1-to-1).

**Traits :** `HasPublicId`, `SoftDeletes`, `HasFactory`, `LogsActivity`, `HasDatabaseTranslations`

**Champs principaux :**
| Champ | Type | Description |
|-------|------|-------------|
| `user_id` | FK (cascade) | Utilisateur lie |
| `hourly_income_amount/currency` | Money | Revenu horaire |
| `hourly_price_amount/currency` | Money | Prix horaire client |
| `member_hourly_price_amount/currency` | Money | Prix horaire membre |
| `account_balance_amount/currency` | Money | Solde compte |
| `booking_delay` | integer | Delai reservation (heures) |
| `stripe_id` | string (nullable) | ID Stripe Connect |
| `stripe_access_token` | string (nullable) | Token Stripe |
| `stripe_on_boarding_completed_at` | datetime (nullable) | Onboarding Stripe |
| `iban` | string (nullable) | IBAN pour virements |
| `display_in_app` | boolean | Visible dans l'app |
| `description_en` | text (nullable) | Description anglaise |

**Relations :**
- `belongsTo` : User
- `belongsToMany` : Places (pivot `coach_place`), Categories (pivot `category_coach`), GroupCourses, Events
- `hasMany` : PersonalCourses, WellnessCourses, Availabilities, Bookings, DoorAccesses

---

#### Employee (`app/Models/Employee.php`)

Profil employe lie a un User (1-to-1).

**Roles (flags booleens) :**
- `is_super_admin` : Super administrateur
- `is_hospitality` : Personnel d'accueil
- `is_manager` : Manager
- `is_coordinator` : Coordinateur
- `is_security` : Securite
- `is_maintenance` : Maintenance
- `is_shop_manager` : Gestionnaire boutique (vente POS/CASH, gestion stock, dashboard analytics)

**Champs specifiques :**
| Champ | Type | Description |
|-------|------|-------------|
| `employee_number` | string (nullable) | Numero employe |
| `is_active` | boolean | Actif |
| `employment_start` | date | Debut contrat |
| `employment_end` | date (nullable) | Fin contrat |
| `contract_details` | text (nullable) | Details contrat |
| `comments` | text (nullable) | Commentaires |
| `receive_email_notifications` | boolean | Recevoir emails |
| `receive_push_notifications` | boolean | Recevoir push |

**Relations :**
- `belongsTo` : User
- `belongsToMany` : Places (pivot `employee_place`)
- `hasMany` : DoorAccesses

---

#### Family (`app/Models/Family.php`)

Regroupe plusieurs Users pour partager un wallet et un abonnement.

**Champs :** `public_id`, `name`, `place_id`, `vip_price`, `discount`, `head_user_id`

**Relations :**
- `belongsTo` : Place, Head User
- `hasMany` : Users, Kids
- `hasOne` : Wallet, Membership

---

### 2. Lieux & Installations

#### Place (`app/Models/Place.php`)

Modele central representant un centre (gym, spa, coworking).

**Traits :** `HasPublicId`, `SoftDeletes`, `InteractsWithMedia`, `LogsActivity`, `HasDatabaseTranslations`

**Champs principaux :**
| Champ | Type | Description |
|-------|------|-------------|
| `name` | string | Nom du lieu |
| `description` | text | Description |
| `description_en` | text | Description anglaise |
| `opening_hours` | JSON | Horaires d'ouverture (array jour/open_at/close_at) |
| `courses_type` | JSON | Types de cours proposes |
| `timezone` | string | Fuseau horaire |
| `currency` | string(3) | Devise (USD, EUR, etc.) |
| `vat` | decimal | Taux TVA |
| `vat_inclusive` | boolean | Prix TTC ou HT |
| `credit_to_currency` | float | Taux de conversion credits -> devise |
| `enable_daypass` | boolean | Day pass active |
| `daypass_price_amount/currency` | Money | Prix day pass |
| `member_daypass_price_amount/currency` | Money | Prix day pass membre |
| `guest_daypass_price_amount/currency` | Money | Prix day pass invite |
| `non_member_resort_access_fee_amount/currency` | Money | Frais acces resort non-membre |
| `door_system` | enum | Systeme de porte (none, biostar2) |
| `door_system_credentials` | encrypted JSON | Credentials du systeme de porte |
| `location` | geometry | Coordonnees GPS |
| `quickbooks_department` | string (nullable) | Departement QuickBooks |
| `department_id` | FK (nullable) | Departement |

**Relations :**
- `hasMany` : Services, Activities, PersonalCourses, WellnessCourses, GroupCourses, Events, Bookings, Orders, Memberships, Departments, Banners, ExceptionalClosingHours, PlaceAccessLogs, AvailabilityStats, DoorAccesses, PreArrivalForms, FlexMemberships
- `belongsToMany` : Coaches, Employees, Facilities, Packs, Languages, Categories
- `hasMany` : Users (via place_id)

**Builder personnalise :** `PlaceBuilder`

---

#### Facility (`app/Models/Facility.php`)

Installation/equipement d'un lieu (piscine, sauna, salle de sport...).

**Relations :** `belongsToMany` Places (pivot `facility_place`)
**Traduisible :** `name`

#### Department (`app/Models/Department.php`)

Departement organisationnel (peut etre global ou specifique a un lieu).

**Relations :** `belongsTo` Place (nullable), `hasMany` : Services, Activities, GroupCourses, PersonalCourses, WellnessCourses, Events, Products, Packs, Categories

---

### 3. Cours & Services

Tous les modeles ci-dessous implementent les interfaces `Bookable` et `Orderable`.

#### PersonalCourse (`app/Models/PersonalCourse.php`)

Cours individuel avec un coach.

**Champs :** `category_id`, `coach_id`, `place_id`, `department_id`, `hourly_price`, `member_hourly_price`, `resort_money_price`, `is_kids_zone`, `is_recreational_area`
**Relations :** `belongsTo` Category, Coach, Place, Department. `morphMany` Bookings.
**Traduisible :** `name`

#### WellnessCourse (`app/Models/WellnessCourse.php`)

Cours de bien-etre (meme structure que PersonalCourse).

#### GroupCourse (`app/Models/GroupCourse.php`)

Cours collectif avec horaires, capacite et potentiellement plusieurs coaches.

**Champs specifiques :** `start_at`, `end_at`, `capacity`, `bulk_id` (UUID pour creation en lot), `service_id`, `free_access`, `price`, `member_price`, `resort_money_price`
**Relations :** `belongsToMany` Coaches (pivot `coach_group_course`), `belongsTo` Category, Place, Department, Service

#### Service (`app/Models/Service.php`)

Service reservable (gym, co-working, spa...).

**Champs specifiques :** `type` (enum ServiceType: gym, co_working, etc.), `is_bookable`, `is_activity`, `opening_hours` (JSON), `capacity`, `half_hour` (slots de 30 min), `simultaneous_slots`, `free_access`
**Relations :** `belongsTo` Category, Place, Department. `belongsToMany` Activities (linked_services)

#### Activity (`app/Models/Activity.php`)

Activite reservable (similaire a Service mais avec media et capacite).

**Champs specifiques :** `is_bookable`, `capacity`, `opening_hours` (JSON), `free_access`, `is_kids_zone`, `is_recreational_area`
**Relations :** `belongsTo` Category, Place, Department. `belongsToMany` LinkedServices. `hasMany` ExceptionalClosingHours

#### Event (`app/Models/Event.php`)

Evenement ponctuel avec date de debut/fin.

**Champs specifiques :** `start_at`, `end_at`, `capacity`, `free_access`, `is_kids_zone`, `is_recreational_area`
**Relations :** `belongsToMany` Coaches (pivot `coach_event`), `belongsTo` Category, Place, Department

---

### 4. Reservations & Acces

#### Booking (`app/Models/Booking.php`)

Reservation d'un client pour un cours/service/activite.

**Relation polymorphique :** `bookable` -> PersonalCourse, GroupCourse, WellnessCourse, Activity, Event, Service, Place

**Champs principaux :**
| Champ | Type | Description |
|-------|------|-------------|
| `bookable_type/id` | morph | Element reserve (polymorphique) |
| `coach_id` | FK (nullable) | Coach assigne |
| `place_id` | FK | Lieu |
| `attendee_id` | FK (users) | Client qui assiste |
| `start_at` | immutable_datetime | Debut |
| `end_at` | immutable_datetime | Fin |
| `seen_at` | datetime (nullable) | Vu par le coach |
| `has_attended` | boolean | A assiste |
| `refunded` | boolean | Rembourse |
| `late_cancellation` | boolean | Annulation tardive |
| `coach_report_sent` | boolean | Rapport coach envoye |
| `coordinator_report_sent` | boolean | Rapport coordinateur envoye |
| `guest_id` | FK (nullable) | Invite |
| `kid_id` | FK (nullable) | Enfant |
| `guest_user_id` | FK (nullable) | Utilisateur invitant |
| `order_item_id` | FK (nullable) | Item de commande lie |
| `linked_service_id` | FK (nullable) | Service lie |
| `is_guest_pass` | boolean | Pass invite |
| `is_resort_access` | boolean | Acces resort |

**Relations :** `belongsTo` Coach, Place, User (attendee), Guest, Kid, OrderItem. `morphTo` bookable. `hasMany` PlaceAccessLogs.

#### PlaceAccessLog (`app/Models/PlaceAccessLog.php`)

Log d'acces physique a un lieu.

**Champs :** `user_id`, `guest_id`, `kid_id`, `place_id`, `booking_id`, `access_granted`, `access_timestamp`, `reason`, `pre_arrival_form`

#### DoorAccess (`app/Models/DoorAccess.php`)

Droits d'acces physique (portes) pour un utilisateur.

**Champs :** `user_id`, `place_id`, `access_type`, `start_at`, `end_at`, `active`

#### BioStar2Card (`app/Models/BioStar2Card.php`)

Carte d'acces biometrique BioStar2.

**Champs :** `user_id`, `place_id`, `card_uid`, `card_number`

---

### 5. Produits & Commandes

#### Product (`app/Models/Product.php`)

Produit physique vendable.

**Champs :**
| Champ | Type | Description |
|-------|------|-------------|
| `category_id` | FK | Categorie |
| `department_id` | FK (nullable) | Departement |
| `place_id` | FK (nullable) | Lieu |
| `name` | string | Nom (traduisible) |
| `description` | text (nullable) | Description (traduisible) |
| `sale_money_price_amount/currency` | Money | Prix de vente |
| `sale_member_money_price_amount/currency` | Money | Prix membre vente |
| `rent_money_price_amount/currency` | Money | Prix location |
| `rent_member_money_price_amount/currency` | Money | Prix membre location |
| `can_buy` | boolean | Achetable |
| `can_rent` | boolean | Louable |
| `is_active` | boolean | Actif (utilise par Shop Manager pour filtrer les produits vendables) |
| `specifications` | JSON (nullable) | Specifications techniques |

**Relations :** `hasMany` ProductVariations, `belongsTo` Category, Department, Place

#### ProductVariation (`app/Models/ProductVariation.php`)

Variante d'un produit (taille, couleur).

**Champs :** `product_id`, `name`, `price_amount/currency`, `member_price_amount/currency`
**Relations :** `belongsTo` Product, `hasMany` ProductVariationStocks

#### ProductVariationStock (`app/Models/ProductVariationStock.php`)

Stock d'une variante dans un lieu specifique. Utilise par le Shop Manager pour le suivi d'inventaire et les alertes de stock bas.

**Champs :** `product_variation_id`, `place_id`, `quantity` (integer), `low_stock_threshold` (integer, defaut 5)
**Relations :** `belongsTo` ProductVariation, Place

#### Order (`app/Models/Order.php`)

Commande regroupant des items.

**Champs :**
| Champ | Type | Description |
|-------|------|-------------|
| `user_id` | FK | Client |
| `place_id` | FK | Lieu |
| `status` | enum (OrderStatus) | PENDING, PAID, CANCELLED |
| `payment_provider` | enum (PaymentProvider) | STRIPE, WALLET, NOWPAYMENTS, DESK, POS, CASH |
| `stripe_payment_intent_id` | string (nullable) | Intent Stripe |

**Relations :** `belongsTo` User, Place. `hasMany` OrderItems, WalletTransactions.
**Builder personnalise :** `OrderBuilder`

#### OrderItem (`app/Models/OrderItem.php`)

Ligne de commande polymorphique.

**Relation polymorphique :** `orderable` -> Pack, FlexMembership, Activity, Event, PersonalCourse, GroupCourse, Service, WellnessCourse, Product

**Champs :**
| Champ | Type | Description |
|-------|------|-------------|
| `order_id` | FK | Commande |
| `orderable_type/id` | morph | Element commande |
| `price_amount/currency` | Money | Prix unitaire |
| `credits_price` | integer | Prix en credits |
| `credits_taxes` | integer | Taxes en credits |
| `money_amount/currency` | Money | Equivalent monetaire |
| `is_gift` | boolean | Cadeau |
| `is_guest_pass` | boolean | Pass invite |
| `order_item_id` | FK (nullable) | Item parent (pour bundles) |

---

### 6. Abonnements & Credits

#### Membership (`app/Models/Membership.php`)

Abonnement actif d'un utilisateur ou d'une famille.

**Champs :** `user_id` (nullable), `family_id` (nullable), `place_id`, `start_at`, `end_at`
**Attribut calcule :** `is_active` (base sur les dates)
**Scope :** `mustBeActive()`

#### FlexMembership (`app/Models/FlexMembership.php`)

Abonnement flexible avec obligation de depense minimale.

**Champs :** `place_id`, `name`, `description`, `min_spend_amount/currency`, `membership_pack_id` (FK packs), `is_active`, `comments`
**Traduisible :** `name`, `description`

#### Pack (`app/Models/Pack.php`)

Forfait achetable (credits, day pass, guest pass, abonnement).

**Champs :** `place_id`, `department_id`, `name`, `type` (enum: CREDIT, DAYPASS, GUEST_PASS, MEMBERSHIP), `price_amount/currency`, `credits`, `is_membership`
**Relations :** `belongsToMany` Places (pivot `pack_place`)

#### Wallet (`app/Models/Wallet.php`)

Portefeuille de credits d'un utilisateur ou d'une famille.

**Champs :**
| Champ | Type | Description |
|-------|------|-------------|
| `user_id` | FK (nullable, unique) | Proprietaire utilisateur |
| `family_id` | FK (nullable, unique) | Proprietaire famille |
| `balance` | float | Solde en credits |
| `balance_daypass` | integer | Solde day passes |
| `balance_guest_pass` | integer | Solde guest passes |

**Methodes :** `debit()`, `credit()` — creent automatiquement un WalletTransaction

#### WalletTransaction (`app/Models/WalletTransaction.php`)

Transaction sur le wallet.

**Champs :**
| Champ | Type | Description |
|-------|------|-------------|
| `wallet_id` | FK | Wallet |
| `type` | enum | DEBIT, CREDIT, DEBIT_ADJUSTMENT, CREDIT_ADJUSTMENT |
| `payment_type` | enum WalletPaymentType (nullable) | STRIPE, REFUND, CASH, CHECK, CREDIT_CARD, BANK_TRANSFER |
| `amount` | float | Montant en credits |
| `amount_daypass` | integer | Nombre de day passes |
| `amount_guest_pass` | integer | Nombre de guest passes |
| `description` | string | Description |
| `order_item_id` | FK (nullable) | Item de commande lie |
| `money_amount` | integer | Equivalent en centimes |
| `money_currency` | string(3) | Devise |

---

### 7. Social & Communication

#### Guest (`app/Models/Guest.php`)

Invite d'un membre.

**Relations :** `belongsToMany` Users (via GuestUser pivot avec metadata firstname, lastname, phone, comments), Places. `hasMany` Bookings, PlaceAccessLogs.

#### GuestUser (Pivot Model)

Pivot enrichi entre User et Guest avec metadata (prenom, nom, telephone, commentaires).

#### GuestInvitation (`app/Models/GuestInvitation.php`)

Invitation d'un guest par un utilisateur.

#### Kid (`app/Models/Kid.php`)

Enfant d'un utilisateur.

**Champs :** `user_id`, `family_id`, `name`, `email`, `phone`, `dob` (date de naissance)

#### SocialAccount (`app/Models/SocialAccount.php`)

Compte OAuth (Google, Facebook, LinkedIn, Instagram, Apple).

**Champs :** `user_id`, `provider`, `provider_id`, `email`

---

### 8. Chat & Messagerie

#### Conversation (`app/Models/Chat/Conversation.php`)

Conversation entre participants.

**Relations :** `hasMany` Messages, Participants (ConversationParticipant), Settings (ConversationSetting). `hasOne` AiSession.

#### Message (`app/Models/Chat/Message.php`)

Message dans une conversation.

**Champs :** `conversation_id`, `sender_id`, `body`, `type` (enum MessageType: text, attachment)
**Relations :** `hasMany` Attachments (MessageAttachment), Receipts (MessageReceipt), GpsShares (MessageGpsShare)

#### MessageAttachment, MessageReceipt, MessageGpsShare

Pieces jointes, accuses de reception, et partages GPS lies aux messages.

#### ConversationParticipant, ConversationSetting

Participants et parametres de conversation.

#### AiSession, AiMessage (`app/Models/Chat/AiSession.php`)

Session IA et messages IA pour les conversations assistees par intelligence artificielle.

---

### 9. Traductions & Contenu

#### Language (`app/Models/Language.php`)

Langue supportee (en, es, fr, zh).

#### ModelTranslation (`app/Models/ModelTranslation.php`)

Traduction d'un champ de modele. Relation polymorphique avec le modele traduit.

#### Translation (`app/Models/Translation.php`)

Cle de traduction avec ses valeurs par langue.

#### Banner (`app/Models/Banner.php`)

Banniere promotionnelle avec support de deep linking.

**Champs :** `place_id`, `category_id`, `title`, `url`, `start_at`, `end_at`, `position`, `has_linked_object`, `object_type`, `object_public_id`
**Traduisible :** `title`

---

### 10. Disponibilites & Suivi

#### Availability (`app/Models/Availability.php`)

Creneau de disponibilite d'un coach dans un lieu.

**Champs :** `coach_id`, `place_id`, `datetime` (immutable)
**Attributs calcules :** `start_at`, `end_at` (depuis datetime)
**Builder personnalise :** `AvailabilityBuilder`

#### AvailabilityStat (`app/Models/AvailabilityStat.php`)

Statistiques pre-calculees de disponibilite par lieu/categorie/service/activite.

**Champs :** `place_id`, `category_id`, `service_id`, `activity_id`, `orderable_type`, `available_count`, `computed_at`

#### TrackingEntry (`app/Models/TrackingEntry.php`)

Entree de suivi de presence/activite (polymorphique).

---

### 11. Autres Modeles

| Modele | Description |
|--------|-------------|
| `Address` | Adresse (polymorphique, lie a User ou Place) |
| `Category` | Categorie de cours/service avec hierarchie parent/enfant |
| `CategoryCoach` | Pivot coach-categorie avec auto-creation de cours |
| `ExceptionalClosingHour` | Fermeture exceptionnelle (activite) |
| `FeaturedCategory` | Categorie mise en avant |
| `Notification` | Notification utilisateur |
| `PasswordReset` | Token de reset de mot de passe |
| `PersonalAccessToken` | Token Sanctum |
| `PreArrivalForm` | Formulaire pre-arrivee |
| `Report` | Rapport genere |
| `RestaurantRevenue` | Revenu restaurant |
| `Task` | Tache employe |

---

## Relations Polymorphiques (Morph Map)

Definie dans `AppServiceProvider::boot()` :

```php
Relation::morphMap([
    'personal_course'  => PersonalCourse::class,
    'wellness_course'  => WellnessCourse::class,
    'group_course'     => GroupCourse::class,
    'service'          => Service::class,
    'activity'         => Activity::class,
    'event'            => Event::class,
    'place'            => Place::class,
    'pack'             => Pack::class,
    'flex_membership'  => FlexMembership::class,
    'product'          => Product::class,
]);
```

---

## Interfaces de Modeles

### Bookable (`app/Models/Interfaces/Bookable.php`)

Interface pour les modeles reservables. Implementee par : PersonalCourse, WellnessCourse, GroupCourse, Service, Activity, Event, Place.

### Orderable (`app/Models/Interfaces/Orderable.php`)

Interface pour les modeles commandables. Implementee par : tous les Bookable + Pack, FlexMembership, Product.

---

## Traits de Modeles

| Trait | Description | Utilise par |
|-------|-------------|-------------|
| `HasPublicId` | UUID public auto-genere, `findByPublicId()` | Quasi tous les modeles |
| `HasDatabaseTranslations` | Champs traduisibles via `model_translations` | Place, Category, Facility, cours, services |
| `HasPlaceScope` | Auto-scope queries par `place_id` | Modeles lies a un lieu |
| `HasConversations` | Support conversations chat | User |
| `SyncsQuickbooksCustomer` | Sync QuickBooks a la creation/modification | User |
| `ConvertDateTimeToUTC` | Conversion dates UTC | BaseModel (tous) |
| `HasFlags` | Flags generiques par modele | Booking |
| `InteractsWithMedia` | Gestion de medias (Spatie) | User, Place, Activity, Product, etc. |
| `LogsActivity` | Journal d'activite (Spatie) | User, Coach, Place, etc. |

---

## Seeders

| Seeder | Description |
|--------|-------------|
| `DatabaseSeeder` | Orchestrateur principal |
| `AdminSeeder` | Cree les utilisateurs admin avec roles |
| `CategorySeeder` | Popule les categories avec hierarchie |
| `PermissionSeeder` | Enregistre les permissions Spatie |
| `PlaceSeeder` | Cree les lieux avec configurations |
| `LanguageSeeder` | Charge les langues supportees (en, es, fr, zh) |
| `CoachPersonalCourseSeeder` | Cree les cours perso pour les coaches |
| `ClassicSeeder` | Donnees de test legacy |
| `DepartmentSeeder` | Cree les departements |

## Factories (22)

Toutes les factories sont dans `database/factories/` et suivent la convention `{Model}Factory.php`. Elles utilisent Faker pour generer des donnees realistes.
