# PLAN MAÎTRE — reservation.energiedin.ma

**Version :** 1.0  
**Date de référence :** 13 juillet 2026  
**Cible :** moteur de réservation directe + mini-PMS + noyau de channel manager, installé sur un serveur WHM/cPanel  
**Mode d’exécution prévu :** développement incrémental avec Codex dans le répertoire racine préalablement créé pour `reservation.energiedin.ma`

---

## 0. Décision d’architecture en une page

### 0.1 Ce que le produit doit être

`reservation.energiedin.ma` doit devenir la source centrale des disponibilités, tarifs, restrictions et réservations de l’établissement. Le produit doit comporter quatre blocs cohérents :

1. **Moteur de réservation directe** pour les visiteurs venant du site officiel.
2. **Back-office hôtelier** pour gérer chambres, tarifs, planning, réservations, paiements et clients.
3. **Noyau de channel manager** capable d’émettre des mises à jour ARI — Availability, Rates, Inventory — et de recevoir les réservations, modifications et annulations des OTA.
4. **Couche de connecteurs remplaçables**, afin d’utiliser d’abord une passerelle certifiée en marque blanche, puis de développer des connecteurs directs Booking.com et Expedia sans réécrire le cœur du produit.

### 0.2 Parcours de réservation recommandé

Le parcours public doit être **hybride**, avec deux portes d’entrée :

- **Entrée principale, par dates et occupation**, car une chambre n’est réellement vendable qu’après validation des dates, du nombre d’adultes, du nombre d’enfants et de leur âge.
- **Entrée secondaire, par chambre**, depuis la présentation d’une chambre sur le site de l’hôtel. La chambre est alors pré-sélectionnée et le visiteur choisit ses dates. Si elle n’est pas disponible, le moteur suggère des dates adjacentes et des chambres équivalentes.

Le résultat de recherche est ensuite présenté **par chambre**, comme un catalogue premium : grande photographie, équipements, capacité, conditions, plans tarifaires, prix total et appel à l’action.

### 0.3 Stratégie de connexion aux OTA

La connectivité directe Booking.com/Expedia n’est pas un simple branchement à une API publique. Elle exige une relation de partenaire, des identifiants dédiés, des tests et des certifications.

La stratégie produit doit donc être :

- **Voie A — lancement commercial :** connecter le noyau du produit à une passerelle de channel management certifiée et en marque blanche, par exemple Channex ou une solution équivalente validée contractuellement.
- **Voie B — autonomie progressive :** demander en parallèle l’admission aux programmes de connectivité Booking.com et Expedia, développer les connecteurs directs derrière les mêmes interfaces, les certifier, puis migrer canal par canal.

Cette approche évite de bloquer le lancement pendant l’onboarding OTA et empêche le verrouillage technique à un fournisseur.

### 0.4 Stack recommandée

- **Backend :** Laravel 13, PHP 8.4.
- **Frontend :** Inertia 3, React 19, TypeScript, Tailwind CSS 4 et composants shadcn/ui personnalisés.
- **Base :** MySQL 8 ou MariaDB compatible, avec transactions InnoDB.
- **Cache/files :** Valkey ou Redis en production ; repli base de données possible au début.
- **Workers :** Supervisor ou systemd sous WHM/root ; repli cron cPanel uniquement pour un MVP.
- **Build :** Vite ; Node.js utilisé au build, pas comme serveur applicatif obligatoire.
- **Architecture :** monolithe modulaire, API versionnée, événements internes, outbox transactionnelle.

Cette combinaison conserve une expérience React haut de gamme sans imposer un serveur Node permanent fragile sur cPanel.

---

# 1. Périmètre fonctionnel

## 1.1 Périmètre de la première version exploitable

La première version exploitable doit permettre :

- de configurer un établissement, ses chambres, ses plans tarifaires et ses politiques ;
- de définir l’inventaire, les prix et restrictions jour par jour ;
- d’effectuer une recherche fiable de disponibilité ;
- de sélectionner une ou plusieurs chambres ;
- d’ajouter des suppléments ;
- de saisir les voyageurs ;
- de payer un acompte, régler en totalité ou garantir la réservation selon la politique ;
- de confirmer, modifier ou annuler une réservation directe ;
- de recevoir les réservations d’au moins Booking.com et Expedia via une passerelle certifiée ;
- de repousser immédiatement les changements de disponibilité et de prix vers les canaux connectés ;
- de visualiser l’état de la synchronisation et traiter les erreurs ;
- d’intégrer un widget de recherche dans le site officiel de l’établissement ;
- d’opérer en français, anglais et arabe, y compris l’affichage RTL pour l’arabe ;
- de fonctionner correctement sur mobile, tablette et ordinateur.

## 1.2 Préparation multi-établissements

Même si le lancement concerne un seul établissement, le modèle doit être **multi-établissements prêt** :

- chaque donnée métier est rattachée à un `organization_id` et/ou un `property_id` ;
- les requêtes administratives sont systématiquement filtrées par établissement autorisé ;
- les utilisateurs peuvent avoir des rôles différents selon l’établissement ;
- le domaine public peut résoudre l’établissement par sous-domaine, slug ou identifiant signé ;
- la facturation SaaS multi-clients n’est pas développée au départ, mais le schéma ne doit pas la rendre impossible.

## 1.3 Hors périmètre initial

À ne pas mélanger au premier lancement :

- comptabilité générale complète ;
- paie ;
- gestion poussée de restaurant/POS ;
- serrures connectées ;
- application mobile native ;
- moteur de revenue management basé sur l’IA ;
- marketplace publique multi-hôtels ;
- microservices séparés ;
- stockage de numéros de cartes bancaires bruts ;
- connecteurs directs non certifiés vers des OTA de production.

Ces éléments peuvent être ajoutés après stabilisation du moteur, de l’inventaire et de la distribution.

---

# 2. Principes produit et UX

## 2.1 Principes directeurs

Le produit public doit respecter les principes suivants :

- **La confiance avant la pression commerciale.** Aucun faux compte à rebours ni fausse rareté.
- **Prix total visible tôt.** Les taxes et frais obligatoires doivent être explicités avant le paiement.
- **Pas de compte obligatoire.** Le client peut réserver en invité.
- **Pas de surprise au dernier écran.** Conditions d’annulation, repas, taxes, acompte et devise sont visibles sur la carte tarifaire.
- **Une décision par écran.** Le parcours évite les pages surchargées.
- **Retour sans perte de données.** Les choix précédents persistent.
- **Mobile d’abord.** Les CTA et le récapitulatif restent accessibles avec une seule main.
- **Rapidité réelle.** Les animations ne masquent jamais des lenteurs serveur.
- **Accessibilité.** Calendrier, modales, sélecteurs et formulaires utilisables au clavier et avec lecteur d’écran.
- **Internationalisation native.** Aucun texte fonctionnel codé en dur dans un composant.

## 2.2 Arborescence publique

Routes recommandées :

- `/` : recherche par dates et occupation ;
- `/rooms` : catalogue des types de chambres ;
- `/rooms/{slug}` : détail d’une chambre et entrée « choisir mes dates » ;
- `/search` : résultats de disponibilité ;
- `/checkout` : voyageurs, suppléments et paiement ;
- `/confirmation/{public_reference}` : confirmation ;
- `/manage/{secure_token}` : consultation, modification ou annulation ;
- `/policies` : politiques de réservation ;
- `/privacy` et `/terms` ;
- `/widget.js` : script d’intégration ;
- `/health` : santé applicative minimale, sans données sensibles.

## 2.3 Écran d’entrée par dates

Composants :

- arrivée ;
- départ ;
- nombre de chambres ;
- adultes par chambre ;
- enfants par chambre avec âge obligatoire ;
- code promotionnel optionnel ;
- langue et devise d’affichage ;
- bouton principal « Voir les disponibilités ».

Comportement :

- le départ est toujours postérieur à l’arrivée ;
- les dates passées sont désactivées ;
- la durée maximale est configurable ;
- la fenêtre de réservation maximale est configurable ;
- le calendrier affiche, lorsque possible, un prix « à partir de » par jour ;
- sur mobile, le calendrier utilise une feuille plein écran ;
- le choix de l’occupation se fait par chambre, pas seulement au total ;
- le moteur conserve les paramètres dans l’URL pour permettre partage, retour et deep link.

## 2.4 Écran de résultats

Présentation recommandée :

- en-tête compact avec dates et occupation modifiables ;
- bandeau de dates flexibles ±3 jours lorsque le tarif est disponible ;
- cartes regroupées par type de chambre ;
- grande photo optimisée et galerie ;
- capacité, lits, superficie et principaux équipements ;
- badges factuels : petit-déjeuner inclus, annulation gratuite jusqu’au…, paiement à l’hôtel, non remboursable ;
- plusieurs plans tarifaires dépliables ;
- prix par nuit et prix total du séjour ;
- détail taxes/frais ;
- politique complète accessible sans quitter l’écran ;
- indication de stock uniquement si exacte ;
- bouton « Sélectionner » ;
- comparaison optionnelle entre 2 ou 3 chambres ;
- tri recommandé, prix croissant et superficie ;
- filtres repas, annulation, capacité et équipements.

Pour une réservation de plusieurs chambres, l’interface doit guider le client chambre par chambre, tout en affichant un récapitulatif global.

## 2.5 Parcours chambre d’abord

Depuis `/rooms/{slug}` ou depuis le site officiel :

1. la chambre est pré-sélectionnée ;
2. le calendrier indique les dates compatibles ;
3. le client choisit occupation et durée ;
4. les plans tarifaires disponibles apparaissent ;
5. en cas d’indisponibilité, le moteur propose :
   - les dates les plus proches ;
   - une autre chambre de capacité similaire ;
   - un séjour fractionné seulement si cette option est explicitement autorisée.

Le paramètre `room_type` doit être conservé dans le deep link, par exemple :

`/search?room_type=deluxe-king&checkin=2026-09-10&checkout=2026-09-13&adults=2`

## 2.6 Panier et hold temporaire

Lorsqu’un client sélectionne une offre :

- créer un **hold** sur l’inventaire pour une durée configurable, par défaut 10 minutes ;
- afficher le temps restant de manière calme et non anxiogène ;
- prolonger une seule fois le hold lorsque le client est actif et que le stock le permet ;
- libérer automatiquement le stock à expiration ;
- ne jamais considérer le hold comme une réservation confirmée ;
- revalider prix, restrictions et disponibilité juste avant la création finale.

## 2.7 Checkout

Étapes recommandées :

1. **Votre séjour** : chambres, tarifs, extras et conditions.
2. **Vos coordonnées** : titulaire, voyageurs, préférences et heure d’arrivée.
3. **Paiement ou garantie** : selon la politique.
4. **Confirmation**.

Champs minimaux :

- civilité facultative ;
- prénom, nom ;
- e-mail ;
- téléphone avec indicatif pays ;
- pays de résidence ;
- voyageurs par chambre ;
- demandes spéciales clairement non garanties ;
- heure d’arrivée estimée ;
- consentement aux conditions obligatoire et non pré-coché ;
- consentement marketing séparé et facultatif.

## 2.8 Confirmation et post-réservation

Après succès :

- référence publique non séquentielle ;
- résumé complet ;
- statut du paiement ;
- politique d’annulation ;
- adresse et informations d’arrivée ;
- e-mail transactionnel immédiat ;
- bouton d’ajout au calendrier ;
- téléchargement d’un voucher PDF optionnel ;
- lien sécurisé de gestion sans mot de passe ;
- e-mail pré-arrivée programmable ;
- possibilité d’ajouter un transfert, repas ou autre extra après réservation si la politique l’autorise.

---

# 3. Back-office hôtelier

## 3.1 Tableau de bord

Afficher :

- arrivées, départs et clients présents aujourd’hui ;
- nouvelles réservations ;
- annulations ;
- occupation à 7, 30 et 90 jours ;
- chiffre d’affaires confirmé ;
- ADR, RevPAR et revenu par source ;
- alertes de stock faible ;
- erreurs de mapping ;
- synchronisations en échec ;
- réservations OTA non acquittées ou en attente de traitement ;
- paiements échoués ou remboursements en attente.

## 3.2 Planning « tape chart »

Le planning doit :

- afficher les unités physiques sur l’axe vertical et les dates sur l’axe horizontal ;
- permettre zoom jour/semaine/mois ;
- afficher les réservations par statut ;
- ouvrir un panneau latéral au clic ;
- permettre le glisser-déposer uniquement lorsque les règles métier le permettent ;
- avertir avant toute modification affectant le tarif ou l’OTA ;
- gérer les chambres hors service ;
- détecter les chevauchements ;
- proposer l’affectation automatique d’une unité physique à l’approche de l’arrivée.

## 3.3 Gestion des réservations

Fonctions :

- création manuelle ;
- modification ;
- annulation ;
- duplication ;
- changement de chambre ;
- ajout ou retrait d’extras ;
- changement d’état ;
- notes internes distinctes des demandes client ;
- historique complet ;
- envoi/re-envoi des e-mails ;
- paiement, remboursement et rapprochement ;
- check-in/check-out dans une phase ultérieure ;
- no-show ;
- export ou impression.

Toute modification manuelle doit produire un événement d’audit et, si elle affecte l’inventaire, un événement de synchronisation.

## 3.4 Calendrier tarifs et disponibilités

Vue grille par type de chambre, plan tarifaire et date :

- stock vendable ;
- prix ;
- stop-sell ;
- minimum/maximum de séjour ;
- fermé à l’arrivée ;
- fermé au départ ;
- délai minimum et maximum de réservation ;
- surbooking autorisé ;
- promotion active ;
- statut de synchronisation.

Mises à jour de masse :

- période ;
- jours de semaine ;
- chambres ;
- plans tarifaires ;
- valeur fixe ou variation en montant/pourcentage ;
- aperçu avant application ;
- journal d’audit ;
- annulation logique ou commande inverse si possible.

## 3.5 Configuration des canaux

Assistant en étapes :

1. choisir le canal ;
2. saisir ou autoriser le compte ;
3. récupérer le catalogue distant ;
4. mapper établissement, chambres et plans tarifaires ;
5. valider devise, taxes, occupation et restrictions ;
6. importer les réservations futures ;
7. comparer le stock ;
8. exécuter un dry-run ;
9. pousser une synchronisation initiale ;
10. activer ;
11. surveiller les premiers événements.

L’activation doit être impossible si :

- une chambre active n’est pas mappée ;
- un plan tarifaire vendu n’est pas mappé ;
- des réservations futures n’ont pas été rapprochées ;
- la devise ou le fuseau n’est pas défini ;
- la période de disponibilité minimale exigée par le canal n’est pas chargée ;
- le test de connexion échoue.

## 3.6 Écran santé de distribution

Pour chaque canal :

- état connecté/déconnecté/suspendu ;
- dernière réservation reçue ;
- dernière mise à jour ARI réussie ;
- latence de synchronisation ;
- période future couverte ;
- nombre d’erreurs sur 24 h ;
- mapping incomplet ;
- réservations en dead-letter ;
- bouton « synchronisation complète » protégé par confirmation ;
- bouton de suspension des mises à jour ;
- journal filtrable avec identifiant de corrélation.

---

# 4. Modèle métier

## 4.1 Entités principales

### Organisation et propriété

- `organizations`
- `properties`
- `property_localizations`
- `property_settings`
- `users`
- `roles`
- `permissions`
- `property_user`

### Produit hôtelier

- `room_types`
- `room_type_localizations`
- `room_units`
- `bed_configurations`
- `amenities`
- `amenity_room_type`
- `media_assets`
- `room_type_media`
- `meal_plans`
- `cancellation_policies`
- `deposit_policies`
- `taxes_fees`

### Tarification et stock

- `rate_plans`
- `rate_plan_localizations`
- `rate_plan_room_type`
- `derived_rate_rules`
- `inventory_days`
- `inventory_ledger_entries`
- `rate_days`
- `restriction_days`
- `promotions`
- `promotion_rules`
- `promo_codes`
- `promo_redemptions`
- `packages`
- `extras`
- `extra_availability_rules`

### Réservation

- `availability_holds`
- `guests`
- `reservations`
- `reservation_rooms`
- `reservation_nights`
- `reservation_guests`
- `reservation_extras`
- `reservation_status_history`
- `reservation_notes`
- `booking_documents`

### Paiement

- `payment_accounts`
- `payment_attempts`
- `payments`
- `refunds`
- `payment_events`
- `invoices`
- `credit_notes`

### Distribution

- `channels`
- `channel_accounts`
- `channel_connections`
- `channel_capabilities`
- `channel_mappings`
- `channel_sync_cursors`
- `channel_inbox_events`
- `channel_outbox_events`
- `channel_deliveries`
- `channel_failures`
- `channel_reconciliation_runs`
- `external_reservation_links`

### Système

- `idempotency_keys`
- `audit_logs`
- `notifications`
- `consent_records`
- `webhook_subscriptions`
- `webhook_deliveries`
- `feature_flags`
- `settings`

## 4.2 Règles d’identification

- utiliser des ULID ou UUIDv7 comme identifiants publics et inter-modules ;
- conserver éventuellement une clé entière interne pour certaines tables très volumineuses ;
- ne jamais exposer un identifiant séquentiel de réservation ;
- stocker les identifiants OTA dans une table de mapping avec contrainte unique par canal et propriété ;
- ajouter `created_at`, `updated_at` et, lorsque justifié, `deleted_at` ;
- les suppressions métier sensibles sont archivées, pas détruites silencieusement.

## 4.3 Dates, heures et fuseaux

- stocker les timestamps techniques en UTC ;
- stocker les dates de nuitées en type `DATE`, car une nuit hôtelière n’est pas un instant UTC ;
- utiliser le fuseau IANA de l’établissement, par défaut `Africa/Casablanca` ;
- ne jamais coder un décalage UTC fixe ;
- enregistrer le fuseau utilisé lors des événements externes ;
- définir explicitement l’heure de check-in, check-out et la date commerciale.

## 4.4 Montants

- créer un objet valeur `Money` ;
- stocker le montant en unités mineures entières ou dans un décimal strict, avec devise ISO 4217 ;
- ne jamais utiliser un flottant binaire pour les calculs ;
- enregistrer le détail de calcul de chaque nuit ;
- fixer une règle d’arrondi documentée ;
- distinguer prix de vente, taxes, frais, commission OTA, montant net et montant collecté ;
- enregistrer le taux de change utilisé lorsqu’une devise d’affichage diffère de la devise de vente.

## 4.5 États de réservation

États recommandés :

- `draft`
- `held`
- `pending_payment`
- `confirmed`
- `cancelled`
- `expired`
- `failed`
- `no_show`
- `checked_in`
- `checked_out`

Transitions contrôlées par une machine d’état. Une transition invalide doit être rejetée et journalisée.

## 4.6 États de paiement

- `created`
- `pending`
- `requires_action`
- `authorized`
- `captured`
- `partially_refunded`
- `refunded`
- `failed`
- `cancelled`
- `expired`

La réservation et le paiement ont des machines d’état séparées.

---

# 5. Inventaire, tarification et disponibilité

## 5.1 Source unique de vérité

Après activation d’un canal, la plateforme doit être la source de vérité de l’inventaire et, selon le mapping, des tarifs et restrictions. Les modifications directes dans l’extranet OTA doivent être limitées aux fonctions non pilotées par la connexion.

Il ne doit jamais y avoir deux systèmes actifs qui pilotent simultanément le même couple chambre/plan tarifaire/date.

## 5.2 Inventaire au niveau du type de chambre

Le stock commercial est géré par `room_type` :

`available = sellable_base + overbooking_limit - confirmed_sold - active_holds - out_of_order`

Ne pas dupliquer le stock pour chaque plan tarifaire. Les plans tarifaires partagent l’inventaire du type de chambre sauf allotement explicitement séparé.

## 5.3 Ledger et projection journalière

Utiliser deux niveaux :

- **ledger append-only** : chaque réservation, annulation, blocage ou correction produit une écriture ;
- **projection `inventory_days`** : valeur rapide à interroger pour chaque date et type de chambre.

La projection doit pouvoir être reconstruite depuis le ledger et les réservations.

## 5.4 Transaction de réservation

Algorithme obligatoire :

1. normaliser la requête et calculer les dates de nuit ;
2. démarrer une transaction DB ;
3. verrouiller les lignes `inventory_days` de toutes les dates, dans un ordre stable ;
4. supprimer mentalement les holds expirés ou les purger avant validation ;
5. vérifier stock, capacité, restrictions et prix ;
6. créer le hold ou la réservation ;
7. enregistrer les nuitées et le détail du prix ;
8. mettre à jour la projection d’inventaire ;
9. écrire les événements d’outbox dans la même transaction ;
10. valider la transaction ;
11. déclencher les traitements asynchrones après commit.

Aucun appel OTA ni paiement externe ne doit être exécuté pendant le verrou DB.

## 5.5 Moteur de prix

Ordre recommandé :

1. tarif de base du plan ;
2. surcharge ou remise dérivée ;
3. ajustement selon occupation ;
4. adulte/enfant supplémentaire ;
5. surcharge par jour de semaine ou saison ;
6. promotion compatible ;
7. package ;
8. extras ;
9. taxes et frais ;
10. conversion d’affichage ;
11. arrondi final.

Chaque calcul produit un tableau de lignes explicables. Le même moteur doit être utilisé par l’interface, l’API, le checkout et les tests.

## 5.6 Restrictions

Support minimal :

- stop-sell ;
- minimum de séjour à l’arrivée ;
- minimum de séjour traversant ;
- maximum de séjour ;
- fermé à l’arrivée ;
- fermé au départ ;
- délai minimum avant arrivée ;
- délai maximum avant arrivée ;
- jours d’arrivée autorisés ;
- occupation minimale/maximale ;
- dates noires pour promotions ;
- quota promotionnel.

## 5.7 Plans tarifaires

Exemples :

- flexible ;
- non remboursable ;
- petit-déjeuner inclus ;
- demi-pension ;
- tarif membre ;
- séjour long ;
- réservation anticipée ;
- tarif mobile ou marché spécifique si le canal le permet.

Un tarif dérivé doit référencer son parent et appliquer une règle, pas recopier des milliers de prix.

## 5.8 Enfants

- définir des tranches d’âge par établissement ;
- demander l’âge de chaque enfant à la recherche ;
- définir capacité adulte, enfants et capacité totale ;
- gérer lit bébé, lit d’appoint et repas enfant ;
- expliquer clairement quand un enfant est gratuit ou payant ;
- vérifier les différences de modèle entre la plateforme canonique et chaque OTA.

## 5.9 Recherche et cache

La recherche peut être cachée quelques secondes, mais :

- la clé inclut établissement, dates, occupation, devise, langue et promo ;
- le cache est invalidé sur changement d’inventaire ou de prix ;
- le checkout revalide toujours la vérité en transaction ;
- aucune réponse de cache ne garantit une chambre tant qu’un hold n’est pas créé.

---

# 6. Architecture de synchronisation OTA

## 6.1 Modèle canonique et adaptateurs

Définir une interface par capacités, par exemple :

```php
interface ChannelConnector
{
    public function capabilities(): ConnectorCapabilities;
    public function validateConnection(ChannelConnection $connection): ConnectionCheck;
    public function pullCatalog(ChannelConnection $connection): RemoteCatalog;
    public function pushAvailability(AriChangeSet $changes): DeliveryResult;
    public function pushRates(AriChangeSet $changes): DeliveryResult;
    public function pushRestrictions(AriChangeSet $changes): DeliveryResult;
    public function fetchReservations(SyncCursor $cursor): ReservationBatch;
    public function acknowledgeReservation(ExternalReservation $reservation): AckResult;
    public function requestFullSync(FullSyncRequest $request): DeliveryResult;
}
```

Les fonctions optionnelles sont déclarées dans `ConnectorCapabilities` : contenu, photos, promotions, messages, avis, paiements, cartes virtuelles, modifications de réservation, etc.

## 6.2 Outbox transactionnelle

À chaque changement de réservation, stock, prix ou restriction :

- écrire un événement `channel_outbox_events` dans la même transaction que le changement métier ;
- le worker récupère les événements non traités ;
- il agrège les changements compatibles par établissement, canal et période ;
- il envoie uniquement le delta nécessaire ;
- il crée un `channel_delivery` par tentative ;
- il marque l’événement terminé uniquement après réponse valide ;
- il masque toute donnée sensible dans les logs.

## 6.3 Inbox idempotente

Pour tout webhook ou message entrant :

1. authentifier la source ;
2. stocker le payload brut chiffré ou protégé avec métadonnées ;
3. calculer une clé de déduplication ;
4. répondre rapidement si le protocole l’exige ;
5. traiter en file ;
6. créer ou modifier la réservation dans une transaction ;
7. écrire l’outbox destinée aux autres canaux ;
8. acquitter le message OTA seulement après succès durable ;
9. placer en dead-letter après échecs contrôlés ;
10. alerter l’exploitation.

Le traitement doit supporter :

- doublons ;
- messages hors ordre ;
- modification reçue avant le message initial ;
- annulation répétée ;
- timeouts ;
- réponse OTA ambiguë ;
- réservation contenant plusieurs chambres ;
- données partielles ;
- identifiant OTA réutilisé dans différents établissements.

## 6.4 Retries

Classer les erreurs :

- transitoire réseau ;
- limitation de débit ;
- authentification ;
- mapping ;
- validation métier ;
- indisponibilité OTA ;
- erreur interne inconnue.

Politique :

- backoff exponentiel avec jitter ;
- respect de `Retry-After` ;
- nombre maximal selon criticité ;
- pas de retry automatique infini sur erreur permanente ;
- circuit breaker par canal ;
- alerte dès qu’une réservation entrante ne peut pas être intégrée ;
- possibilité de rejouer un événement depuis le back-office.

## 6.5 Coalescence ARI

Plusieurs modifications proches doivent être fusionnées :

- même établissement ;
- même canal ;
- même type de chambre/plan tarifaire ;
- dates contiguës ;
- mêmes valeurs de restriction.

Cela réduit les appels et les risques de rate limit. La réservation entrante reste prioritaire sur les mises à jour tarifaires.

## 6.6 Réconciliation

Tâches périodiques :

- comparer les réservations futures connues ;
- vérifier la couverture de disponibilité future ;
- détecter les mappings supprimés ;
- vérifier les canaux silencieux ;
- reconstruire la projection d’inventaire ;
- générer un rapport d’écarts ;
- proposer une correction manuelle ou une synchronisation complète.

## 6.7 Prévention du surbooking

- transaction et verrouillage DB ;
- hold court ;
- réception OTA prioritaire ;
- stock tampon optionnel ;
- mise à jour des autres canaux dès commit ;
- surveillance de la latence ;
- alerte lorsqu’un canal n’a pas accepté une fermeture ;
- mode « stop-sell global » d’urgence ;
- procédure écrite de résolution de conflit.

Une synchronisation, même très rapide, ne peut pas garantir mathématiquement zéro surbooking entre systèmes distribués. Le produit doit réduire le risque et rendre chaque conflit immédiatement visible.

---

# 7. Connectivité par étapes

## 7.1 Étape de lancement : passerelle certifiée

Créer un premier connecteur vers une plateforme de connectivité B2B en marque blanche, choisie après validation :

- couverture Booking.com et Expedia ;
- bidirectionnel réel ;
- webhooks ou flux de révisions ;
- sandbox ;
- gestion des modifications/annulations ;
- mapping ;
- restrictions ;
- cartes virtuelles ou proxy PCI si nécessaire ;
- SLA ;
- politique de support ;
- coûts par établissement ;
- export des données ;
- absence de verrouillage contractuel excessif.

Channex est un exemple actuel de passerelle déclarant une API REST/webhooks et une offre en marque blanche destinée aux PMS. Le code ne doit cependant jamais dépendre de son modèle au-delà de l’adaptateur `ChannexConnector`.

## 7.2 Connecteur direct Booking.com

Ordre recommandé :

1. admission au programme de Connectivity Partner ;
2. accès au Provider Portal et compte machine ;
3. propriétés de test ;
4. Connections API ;
5. mapping chambre/plan ;
6. Rates & Availability ;
7. Reservations API avec acquittement OTA XML ;
8. récupération des modifications et annulations ;
9. paiements et cartes virtuelles selon périmètre PCI ;
10. promotions ;
11. messages ;
12. contenu/photos si certification correspondante ;
13. auto-évaluation ;
14. certification ;
15. pilote avec un établissement ;
16. montée en charge.

Exigences à intégrer dans le produit :

- au moins 12 mois de prix et disponibilité ;
- mises à jour delta ;
- mapping complet ;
- alertes sur dates non vendables ;
- récupération et acquittement des réservations ;
- gestion des fallback e-mails ;
- prise en charge des modèles de prix certifiés ;
- journalisation par identifiant de requête ;
- environnement de test séparé.

Privilégier la solution OTA XML pour les réservations lorsqu’elle est disponible, car elle permet l’acquittement explicite.

## 7.3 Connecteur direct Expedia Group

Ordre recommandé :

1. demande d’éligibilité et contrat de licence ;
2. compte de connectivité et sandbox ;
3. catalogue produit et mapping ;
4. Availability and Rates API ;
5. réception des réservations avec l’API assignée ;
6. capacité moderne de gestion de réservation GraphQL si accordée ;
7. modifications et annulations ;
8. Expedia Collect/Hotel Collect ;
9. cartes virtuelles et tokenisation ;
10. promotions ;
11. messages et avis dans des phases ultérieures ;
12. certification et pilote.

Le système doit pouvoir fonctionner avec les APIs attribuées pendant l’onboarding et ne pas supposer qu’une capacité est automatiquement ouverte.

## 7.4 Autres canaux

Priorité suggérée :

1. Airbnb ;
2. Agoda ;
3. Trip.com ;
4. Hotelbeds ou autres B2B selon la clientèle ;
5. Google Hotel Ads et liens de réservation gratuits ;
6. trivago ;
7. canaux locaux/régionaux.

Les connexions iCal ne synchronisent généralement que des calendriers et ne doivent pas être présentées comme équivalentes à une API ARI complète.

## 7.5 Google Hotel Ads

Préparer :

- pages d’atterrissage avec dates, langue, devise et propriété ;
- cohérence stricte du prix entre feed et checkout ;
- données structurées de prix ;
- catalogue de chambres et packages ;
- suivi des écarts de prix ;
- connecteur direct uniquement si accès partenaire obtenu, sinon passerelle agréée.

---

# 8. Paiement

## 8.1 Architecture fournisseur-agnostique

Interface :

```php
interface PaymentGateway
{
    public function createPayment(PaymentRequest $request): PaymentSession;
    public function verifyCallback(SignedCallback $callback): VerifiedPaymentEvent;
    public function capture(CaptureRequest $request): PaymentResult;
    public function cancel(CancelRequest $request): PaymentResult;
    public function refund(RefundRequest $request): RefundResult;
    public function retrieve(string $externalId): PaymentStatus;
}
```

Prévoir des adaptateurs CMI, NAPS, Payzone ou autre prestataire contracté. Ne pas coder le moteur autour d’un seul PSP.

## 8.2 Réduction du périmètre PCI

- utiliser une page hébergée, une redirection ou des champs hébergés par un prestataire PCI ;
- ne jamais stocker PAN ni CVV ;
- ne pas écrire de carte dans les logs ;
- ne pas faire transiter une carte par le serveur si le flux du PSP permet de l’éviter ;
- stocker uniquement token, marque, quatre derniers chiffres, expiration non sensible et identifiant PSP lorsque permis ;
- vérifier la conformité du prestataire ;
- documenter le SAQ applicable ;
- protéger les scripts de page de paiement et la chaîne de dépendances.

## 8.3 Modes commerciaux

- paiement intégral immédiat ;
- acompte fixe ;
- acompte en pourcentage ;
- autorisation sans capture ;
- paiement à l’établissement ;
- garantie par carte via solution tokenisée ;
- lien de paiement envoyé après réservation ;
- remboursement total ou partiel ;
- paiement multiple sur une même réservation.

## 8.4 Webhooks de paiement

- signature obligatoire ;
- idempotence ;
- vérification serveur-à-serveur du statut ;
- comparaison montant/devise/référence ;
- traitement asynchrone ;
- réponse rapide ;
- table d’événements brute ;
- état de réservation mis à jour seulement après événement vérifié ;
- page retour client indépendante de la vérité du paiement.

## 8.5 Paiements OTA

Les cartes virtuelles et informations de paiement reçues d’une OTA doivent être isolées :

- accès par rôle restreint ;
- affichage masqué ;
- audit de consultation ;
- durée de conservation minimale ;
- tokenisation/proxy du fournisseur de connectivité privilégié ;
- aucune donnée sensible envoyée par e-mail.

---

# 9. Stack et architecture applicative

## 9.1 Pourquoi un monolithe modulaire

Un monolithe modulaire est recommandé parce qu’il :

- se déploie simplement sur PHP-FPM/cPanel ;
- permet des transactions atomiques sur inventaire et réservation ;
- évite la complexité réseau des microservices ;
- reste découpé par domaine ;
- peut extraire un worker ou un connecteur plus tard si la charge l’exige.

## 9.2 Modules

```text
app/
  Domain/
    Catalog/
    Availability/
    Pricing/
    Reservations/
    Guests/
    Payments/
    Distribution/
    Reporting/
    Identity/
    Compliance/
  Application/
    Commands/
    Queries/
    DTO/
    Services/
  Infrastructure/
    Persistence/
    Queue/
    Payments/
    Channels/
    Mail/
    Observability/
  Http/
    Controllers/
    Middleware/
    Requests/
    Resources/
```

Chaque module :

- expose des services applicatifs ;
- ne lit pas directement les tables privées d’un autre module sans contrat ;
- publie des événements métier ;
- possède ses tests ;
- évite les modèles Eloquent « Dieu » avec toute la logique.

## 9.3 Frontend

```text
resources/js/
  components/
    booking/
    admin/
    forms/
    ui/
  pages/
    public/
    admin/
    auth/
  layouts/
  hooks/
  lib/
  types/
  i18n/
```

Conventions :

- TypeScript strict ;
- composants de domaine séparés des composants UI ;
- formulaires typés et validation serveur faisant autorité ;
- design tokens CSS ;
- aucune couleur métier dispersée ;
- gestion RTL testée ;
- `prefers-reduced-motion` respecté ;
- images responsives AVIF/WebP avec fallback ;
- code splitting par page.

## 9.4 API

- REST versionné `/api/v1` ;
- OpenAPI 3.1 généré et validé ;
- erreurs au format Problem Details ;
- identifiant de corrélation ;
- idempotency key sur créations sensibles ;
- pagination par curseur pour flux volumineux ;
- dates ISO 8601 ;
- montants structurés `{amount_minor, currency}` ;
- webhooks signés HMAC ou clés asymétriques ;
- clés API hashées ;
- scopes.

## 9.5 Endpoints publics principaux

- `GET /api/v1/properties/{property}/availability`
- `POST /api/v1/holds`
- `GET /api/v1/holds/{token}`
- `DELETE /api/v1/holds/{token}`
- `POST /api/v1/reservations`
- `GET /api/v1/reservations/{manage_token}`
- `POST /api/v1/reservations/{manage_token}/cancel`
- `POST /api/v1/reservations/{manage_token}/modify-request`
- `POST /api/v1/payments/sessions`
- `POST /api/v1/payments/{gateway}/webhook`
- `GET /api/v1/properties/{property}/calendar-prices`

## 9.6 Endpoints de distribution

- `POST /api/v1/integrations/{connector}/webhooks/{connection}`
- `POST /api/v1/admin/channel-connections/{id}/validate`
- `POST /api/v1/admin/channel-connections/{id}/pull-catalog`
- `POST /api/v1/admin/channel-connections/{id}/activate`
- `POST /api/v1/admin/channel-connections/{id}/full-sync`
- `GET /api/v1/admin/channel-connections/{id}/health`
- `GET /api/v1/admin/channel-deliveries`
- `POST /api/v1/admin/channel-failures/{id}/retry`

---

# 10. Sécurité et conformité

## 10.1 Objectif

Viser au minimum :

- OWASP ASVS 5 niveau 2 pour l’application ;
- OWASP Top 10 Web 2025 ;
- OWASP API Security Top 10 ;
- WCAG 2.2 niveau AA ;
- PCI DSS applicable au flux choisi ;
- loi marocaine 09-08 et formalités CNDP ;
- RGPD lorsque des personnes dans son champ d’application sont concernées.

## 10.2 Authentification administrative

- mot de passe robuste ;
- MFA obligatoire pour administrateurs et finance ;
- TOTP au minimum, passkeys envisageables ;
- récupération sécurisée ;
- limitation de tentatives ;
- sessions courtes pour actions sensibles ;
- révocation globale ;
- journal des connexions ;
- confirmation du mot de passe/MFA pour remboursement, export massif, clés API et activation d’un canal.

## 10.3 Autorisation

Rôles initiaux :

- super-administrateur technique ;
- propriétaire/gestionnaire ;
- réservation ;
- réception ;
- revenue manager ;
- finance ;
- lecture seule ;
- support technique limité.

Toute autorisation doit être vérifiée côté serveur et au niveau de la propriété. Ne pas se contenter de masquer un bouton.

## 10.4 Protections web

- HTTPS partout ;
- HSTS après validation ;
- cookies `Secure`, `HttpOnly`, `SameSite` adaptés ;
- CSRF ;
- CSP restrictive avec nonces ;
- protection clickjacking ;
- CORS allowlist ;
- validation stricte ;
- encodage de sortie ;
- limitation de débit ;
- protection des flux de recherche et de checkout contre l’abus automatisé ;
- CAPTCHA adaptatif uniquement en cas de risque ;
- analyse des fichiers uploadés ;
- noms de fichiers aléatoires ;
- aucun fichier client exécutable.

## 10.5 Secrets

- `.env` hors webroot ;
- aucun secret dans Git ;
- permissions minimales ;
- rotation documentée ;
- séparation staging/production ;
- clés OTA chiffrées en base avec clé applicative dédiée ;
- sauvegarde de la clé selon procédure sécurisée ;
- masquage dans les écrans et logs.

## 10.6 Données personnelles

- registre des traitements ;
- finalités documentées ;
- minimisation ;
- consentements séparés ;
- droit d’accès/rectification/opposition ;
- export et anonymisation ;
- politique de conservation validée avec conseil juridique/comptable ;
- notification ou autorisation CNDP selon le traitement ;
- procédure de transfert à l’étranger si données ou sous-traitants hors Maroc ;
- contrats de sous-traitance ;
- procédure d’incident ;
- pas de PII dans les outils d’analytics sans nécessité.

## 10.7 Audit

Journaliser :

- connexion et MFA ;
- lecture de données de paiement sensibles ;
- création/modification/annulation de réservation ;
- changement de prix/stock/restriction ;
- activation/désactivation canal ;
- mapping ;
- remboursement ;
- export ;
- modification de rôle ;
- changement de politique ;
- accès par support.

Le journal doit être append-only au niveau applicatif, horodaté, avec acteur, IP, contexte, avant/après filtré et identifiant de corrélation.

---

# 11. Performance, disponibilité et observabilité

## 11.1 Objectifs techniques

- LCP public ≤ 2,5 s au 75e percentile ;
- INP ≤ 200 ms ;
- CLS ≤ 0,1 ;
- recherche p95 côté serveur < 500 ms hors dépendance externe ;
- création de hold p95 < 700 ms ;
- aucun appel OTA synchrone dans le parcours client ;
- latence de propagation OTA surveillée ;
- disponibilité cible documentée selon l’infrastructure réelle ;
- dégradation gracieuse si un canal est indisponible.

## 11.2 Cache

- cache de configuration établissement ;
- cache de catalogue public ;
- cache court des recherches ;
- cache tags ou versionnement par propriété ;
- invalidation événementielle ;
- pas de cache d’un état de paiement final sans revalidation ;
- pas de dépendance obligatoire à Redis pour la justesse du stock.

## 11.3 Images

- original hors webroot ou stockage objet ;
- variantes générées ;
- AVIF/WebP ;
- dimensions explicites ;
- lazy loading hors image principale ;
- CDN possible ;
- texte alternatif localisé ;
- limite de poids ;
- suppression orpheline.

## 11.4 Logs et métriques

Logs JSON avec :

- `request_id` ;
- `correlation_id` ;
- `property_id` ;
- `channel` ;
- `connection_id` ;
- `event_id` ;
- durée ;
- résultat ;
- code d’erreur ;
- aucune donnée bancaire ;
- PII masquée.

Métriques :

- taux de conversion ;
- abandon par étape ;
- recherches sans résultat ;
- hold expirés ;
- réservations/minute ;
- stock négatif ;
- profondeur de queue ;
- âge du plus ancien job ;
- succès/erreur par canal ;
- latence ARI ;
- réservations non acquittées ;
- paiements échoués ;
- temps de réponse ;
- erreurs JS.

## 11.5 Alertes

Critiques :

- réservation OTA impossible à importer ;
- inventaire négatif ;
- file bloquée ;
- dernier succès d’un canal trop ancien ;
- échec de paiement après débit confirmé ;
- certificat expirant ;
- sauvegarde échouée ;
- disque presque plein ;
- taux d’erreur brutal ;
- base indisponible.

## 11.6 Sauvegardes

- sauvegarde DB quotidienne au minimum ;
- snapshots plus fréquents ou binlogs/PITR si disponibles ;
- fichiers/media sauvegardés séparément ;
- chiffrement ;
- copie hors serveur ;
- rétention définie ;
- test de restauration périodique ;
- procédure RPO/RTO documentée ;
- sauvegarde avant migration et déploiement critique.

---

# 12. Installation WHM/cPanel

## 12.1 Profil serveur recommandé

Le serveur doit permettre :

- accès WHM/root ;
- PHP-FPM 8.4 ;
- Composer 2 ;
- Node.js moderne pour le build ;
- MariaDB/MySQL InnoDB ;
- accès SSH ;
- cron ;
- Supervisor ou service équivalent ;
- Valkey/Redis si possible ;
- certificats AutoSSL ;
- sauvegardes hors machine ;
- pare-feu et mises à jour.

Une simple offre mutualisée sans worker persistant n’est pas recommandée pour des connecteurs OTA directs critiques.

## 12.2 Répertoire et document root

Le répertoire courant fourni à Codex est la racine du projet. Le document root du sous-domaine doit pointer vers :

`<PROJECT_ROOT>/public`

Ne jamais exposer la racine Laravel au web.

## 12.3 Extensions PHP

Vérifier :

- bcmath ;
- ctype ;
- curl ;
- dom/xml ;
- fileinfo ;
- intl ;
- mbstring ;
- openssl ;
- pdo_mysql ;
- sodium ;
- tokenizer ;
- zip ;
- gd ou imagick ;
- opcache.

## 12.4 Initialisation

Codex doit :

1. vérifier que le répertoire est vide ou identifier les fichiers à conserver ;
2. initialiser Git ;
3. créer Laravel 13 avec le starter officiel React ;
4. installer les dépendances ;
5. générer `.env.example` complet ;
6. créer la base et l’utilisateur via cPanel/WHM ou documenter les variables ;
7. exécuter les migrations ;
8. construire les assets ;
9. configurer le stockage ;
10. vérifier les permissions ;
11. activer les caches Laravel en production ;
12. installer scheduler et workers.

## 12.5 Scheduler

Une seule entrée cron :

```cron
* * * * * cd /CHEMIN/ABSOLU/DU/PROJET && /CHEMIN/PHP84 artisan schedule:run >> /dev/null 2>&1
```

Dans Laravel :

- expiration holds chaque minute ;
- récupération réservations canal selon protocole ;
- réconciliation légère ;
- relance d’échecs transitoires ;
- vérification santé ;
- purge contrôlée ;
- rapports quotidiens ;
- sauvegarde pilotée par infrastructure, pas uniquement par application.

Utiliser `withoutOverlapping`, verrous atomiques et timeout.

## 12.6 Workers

### Mode recommandé

Supervisor avec files séparées :

- `critical-reservations` ;
- `channel-inbound` ;
- `channel-outbound` ;
- `payments` ;
- `notifications` ;
- `default` ;
- `reports`.

La file réservation entrante doit avoir la priorité.

### Mode dégradé cPanel

Si aucun processus persistant n’est possible :

```cron
* * * * * cd /CHEMIN/PROJET && flock -n /tmp/reservation-queue.lock /CHEMIN/PHP84 artisan queue:work database --stop-when-empty --max-time=50 --tries=5
```

Ce mode doit être considéré comme transitoire. Mesurer la latence et migrer vers worker supervisé avant connectivité directe à grande échelle.

## 12.7 Déploiement

Procédure :

1. maintenance logique uniquement si migration incompatible ;
2. sauvegarde ;
3. `git fetch` et checkout de la révision approuvée ;
4. `composer install --no-dev --prefer-dist --optimize-autoloader` ;
5. `npm ci` puis `npm run build` dans l’environnement de build ;
6. `php artisan migrate --force` ;
7. cache config/routes/views/events ;
8. redémarrage workers ;
9. tests de santé ;
10. smoke test réservation ;
11. sortie maintenance ;
12. surveillance renforcée.

Préférer des releases versionnées et un lien symbolique `current` si l’hébergement le permet.

## 12.8 Staging

Créer un environnement séparé, avec :

- base différente ;
- clés PSP sandbox ;
- comptes OTA de test ;
- e-mails redirigés ;
- bannière visible ;
- robots bloqués ;
- aucune donnée réelle non anonymisée ;
- déploiement avant production.

---

# 13. Tests

## 13.1 Pyramide

- tests unitaires du moteur de prix, restrictions, transitions et mapping ;
- tests d’intégration DB avec vraies transactions ;
- tests de contrats connecteurs ;
- tests API ;
- tests E2E Playwright ;
- tests accessibilité automatisés et manuels ;
- tests de concurrence ;
- tests de charge ;
- tests sécurité ;
- tests de restauration.

## 13.2 Scénarios critiques de disponibilité

- dernière chambre réservée simultanément par deux utilisateurs ;
- hold expirant pendant le paiement ;
- réservation OTA reçue pendant un checkout direct ;
- annulation rendant le stock à nouveau disponible ;
- chambre hors service ;
- minimum de séjour ;
- CTA/CTD ;
- occupation avec enfants ;
- plusieurs chambres ;
- modification raccourcissant/allongeant un séjour ;
- fuseau et changement d’heure ;
- période traversant fin d’année ;
- stock tampon ;
- tarif dérivé ;
- promotion non cumulable ;
- arrondi et taxes.

## 13.3 Tests connecteurs

Pour chaque canal :

- authentification valide/invalide ;
- catalogue vide/partiel ;
- mapping complet/incomplet ;
- création réservation ;
- modification ;
- annulation ;
- doublon ;
- message hors ordre ;
- timeout ;
- 429 ;
- 500 ;
- schéma inconnu ;
- date non mappée ;
- plan tarifaire supprimé ;
- carte virtuelle absente ;
- full sync ;
- reprise après panne ;
- logs sans secret.

Utiliser des fixtures réalistes versionnées, jamais de données client réelles.

## 13.4 Concurrence et charge

- 50 tentatives simultanées sur la dernière chambre ;
- pics de recherche ;
- batch ARI de longue période ;
- arrivée de centaines de messages après indisponibilité ;
- reprise de queue ;
- génération de rapports sans bloquer le checkout ;
- uploads d’images ;
- latence DB et verrouillage.

Invariant absolu : aucune réservation confirmée ne doit être créée au-delà de l’inventaire autorisé sans événement explicite de surbooking.

## 13.5 E2E public

- FR/EN/AR ;
- mobile/desktop ;
- navigation clavier ;
- recherche ;
- no-result ;
- chambre unique ;
- multi-chambres ;
- promo ;
- extra ;
- paiement succès/échec/action 3DS ;
- retour navigateur ;
- rafraîchissement ;
- double clic ;
- confirmation ;
- annulation ;
- lien expiré.

## 13.6 Definition of Done globale

Une tâche n’est terminée que si :

- code et migrations existent ;
- tests adaptés passent ;
- analyse statique passe ;
- formatage passe ;
- documentation est mise à jour ;
- sécurité et autorisation sont vérifiées ;
- accessibilité est testée pour l’UI ;
- logs et métriques sont prévus ;
- rollback est documenté ;
- aucun secret ni TODO critique n’est commité.

---

# 14. Feuille de route d’exécution

Les phases sont ordonnées par dépendance. Codex ne doit jamais sauter une phase sans produire un rapport d’écart.

## Phase 0 — Préflight et décisions

### Livrables

- `AGENTS.md` ;
- `README.md` ;
- inventaire serveur ;
- choix DB/queue/cache ;
- liste des propriétés et canaux ;
- matrice des fonctionnalités ;
- ADR architecture ;
- registre des hypothèses ;
- plan de secrets ;
- environnements staging/prod ;
- décision passerelle OTA ;
- demandes d’accès Booking.com/Expedia lancées hors code.

### Critères de sortie

- le document root est connu ;
- PHP/Composer/Node sont utilisables ;
- la base est accessible ;
- le fournisseur de paiement est identifié ou l’adaptateur mock est prévu ;
- aucune dépendance externe bloquante n’est cachée.

## Phase 1 — Fondation technique

### Livrables

- Laravel/React/TypeScript ;
- lint, format, tests ;
- CI ;
- configuration multi-environnements ;
- auth ;
- MFA préparée ;
- RBAC ;
- i18n FR/EN/AR ;
- design system ;
- gestion erreurs ;
- observabilité de base ;
- health checks ;
- seed admin.

### Critères

- connexion admin ;
- isolation par propriété testée ;
- page publique responsive ;
- pipeline vert ;
- aucun secret dans Git.

## Phase 2 — Catalogue hôtelier

### Livrables

- établissement ;
- types de chambres ;
- unités ;
- lits ;
- équipements ;
- médias ;
- traductions ;
- repas ;
- politiques ;
- taxes/frais ;
- CRUD back-office.

### Critères

- une chambre complète peut être publiée dans 3 langues ;
- images optimisées ;
- validation des capacités ;
- audit des modifications.

## Phase 3 — Inventaire, tarifs et restrictions

### Livrables

- plans tarifaires ;
- grille journalière ;
- ledger ;
- règles dérivées ;
- restrictions ;
- promotions ;
- bulk edit ;
- moteur de prix ;
- tests exhaustifs.

### Critères

- prix déterministe et explicable ;
- projection reconstructible ;
- règles de séjour correctes ;
- aucun flottant monétaire.

## Phase 4 — Recherche de disponibilité

### Livrables

- API de recherche ;
- occupation multi-chambres ;
- enfants ;
- dates flexibles ;
- alternatives ;
- cache/invalidation ;
- métriques ;
- tests performance.

### Critères

- résultats exacts ;
- no-result utile ;
- p95 conforme sur dataset de test ;
- cache ne compromet pas la confirmation.

## Phase 5 — Expérience publique

### Livrables

- recherche date-first ;
- pages chambres ;
- room-first deep links ;
- résultats ;
- galerie ;
- plans tarifaires ;
- panier ;
- responsive ;
- RTL ;
- accessibilité ;
- widget.

### Critères

- parcours complet sans paiement ;
- navigation clavier ;
- aucune rupture mobile ;
- paramètres partageables ;
- Core Web Vitals de laboratoire acceptables.

## Phase 6 — Holds et réservation directe

### Livrables

- hold TTL ;
- transaction verrouillée ;
- réservation ;
- nuitées ;
- voyageurs ;
- extras ;
- statuts ;
- référence ;
- e-mails ;
- manage booking ;
- annulation.

### Critères

- test de concurrence dernière chambre ;
- idempotence ;
- hold libéré ;
- confirmation durable ;
- audit.

## Phase 7 — Paiement

### Livrables

- interface PSP ;
- mock sandbox ;
- adaptateur choisi ;
- callbacks ;
- 3DS ;
- remboursements ;
- rapprochement ;
- protection PCI ;
- états UI.

### Critères

- succès, échec, doublon et timeout testés ;
- aucun PAN/CVV stocké ;
- réservation cohérente malgré retour navigateur ;
- montant/devise vérifiés.

## Phase 8 — Back-office opérationnel

### Livrables

- dashboard ;
- planning ;
- réservation manuelle ;
- détail réservation ;
- paiements ;
- clients ;
- exports ;
- rapports de base ;
- rôles ;
- audit.

### Critères

- l’hôtel peut gérer une journée complète sans DB directe ;
- chaque changement d’inventaire produit un événement ;
- permissions testées.

## Phase 9 — Noyau de distribution

### Livrables

- interfaces connecteurs ;
- capability matrix ;
- inbox/outbox ;
- deliveries ;
- retries ;
- dead-letter ;
- mapping ;
- health dashboard ;
- reconciliation ;
- mocks OTA.

### Critères

- connecteur fictif bidirectionnel démontré ;
- doublons/hors ordre gérés ;
- reprise après panne ;
- journal exploitable.

## Phase 10 — Passerelle OTA certifiée

### Livrables

- adaptateur passerelle ;
- création établissement distant ;
- mapping ;
- push ARI ;
- flux réservations ;
- ack/revision feed ;
- import futur ;
- activation ;
- runbook support.

### Critères

- Booking.com et Expedia testés en sandbox via la passerelle ;
- changement direct ferme le stock externe ;
- réservation externe ferme le stock direct et les autres canaux ;
- modifications et annulations ;
- surveillance.

## Phase 11 — Durcissement et lancement

### Livrables

- revue sécurité ;
- accessibilité ;
- charge ;
- sauvegarde/restauration ;
- runbooks ;
- politiques légales ;
- analytics ;
- monitoring ;
- formation ;
- checklist go-live.

### Critères

- aucun défaut critique ;
- restauration testée ;
- alertes testées ;
- pilote contrôlé ;
- procédure de rollback.

## Phase 12 — Booking.com direct

Cette phase ne commence qu’avec accès officiel.

- implémentation selon périmètre certifié ;
- tests de conformité ;
- propriété pilote ;
- comparaison avec passerelle ;
- bascule contrôlée ;
- maintien du connecteur passerelle comme fallback jusqu’à stabilisation.

## Phase 13 — Expedia direct

Même démarche : accès, sandbox, certification, pilote et bascule contrôlée.

## Phase 14 — Distribution avancée

- Airbnb/Agoda/Trip.com ;
- Google Hotel Ads ;
- messages ;
- avis ;
- promotions OTA ;
- contenu ;
- revenue management ;
- CRM et automatisations.

---

# 15. Protocole de travail avec Codex

## 15.1 Règles

Codex doit :

- lire `AGENTS.md`, ce plan et les ADR avant chaque phase ;
- inspecter le dépôt avant d’agir ;
- travailler sur une seule phase ou tranche verticale à la fois ;
- annoncer les fichiers touchés dans son rapport ;
- exécuter les tests avant et après ;
- produire de petites migrations réversibles ;
- ne jamais inventer une API OTA ;
- utiliser mocks/fixtures tant que les identifiants officiels ne sont pas disponibles ;
- ne jamais appeler la production OTA pendant le développement ;
- ne jamais stocker un secret dans le dépôt ;
- ne jamais supprimer une donnée ou une migration sans stratégie ;
- ajouter des tests de non-régression ;
- documenter toute décision structurante dans `docs/adr` ;
- mettre à jour OpenAPI et schémas ;
- créer un commit logique par tranche ;
- s’arrêter proprement si un prérequis externe manque, tout en terminant les mocks, interfaces, tests et documentation possibles.

## 15.2 Fichiers de gouvernance

```text
AGENTS.md
README.md
CHANGELOG.md
docs/
  00-product-vision.md
  01-architecture.md
  02-domain-model.md
  03-booking-flow.md
  04-pricing-inventory.md
  05-channel-connectivity.md
  06-security-compliance.md
  07-cpanel-deployment.md
  08-testing.md
  09-operations-runbook.md
  adr/
  api/openapi.yaml
```

## 15.3 Rapport attendu après chaque exécution

Codex doit retourner :

1. résumé ;
2. hypothèses ;
3. fichiers créés/modifiés ;
4. migrations ;
5. tests exécutés et résultat ;
6. risques ;
7. dépendances externes ;
8. rollback ;
9. prochaine tranche logique.

## 15.4 Contrôle anti-dérive

Avant chaque nouvelle phase :

- tous les tests passent ;
- `git status` est propre ou expliqué ;
- la documentation reflète le code ;
- aucune dette critique n’est reportée ;
- les critères de sortie sont cochés ;
- une sauvegarde existe avant migration production.

---

# 16. Checklist de mise en production

## Domaine et serveur

- DNS correct ;
- AutoSSL actif ;
- document root sur `/public` ;
- PHP 8.4/FPM ;
- OPcache ;
- extensions ;
- base dédiée ;
- utilisateur DB minimal ;
- `.env` protégé ;
- permissions ;
- temps serveur synchronisé ;
- fuseau applicatif correct ;
- WAF/rate limit ;
- sauvegarde hors serveur.

## Application

- `APP_ENV=production` ;
- `APP_DEBUG=false` ;
- URL correcte ;
- cookies sécurisés ;
- caches construits ;
- migrations ;
- storage ;
- workers ;
- scheduler ;
- e-mail SPF/DKIM/DMARC ;
- templates testés ;
- observabilité ;
- endpoints de santé ;
- aucun compte de démonstration ;
- MFA admin ;
- rotation secrets de test.

## Métier

- chambres et photos ;
- capacités ;
- âge enfants ;
- tarifs ;
- disponibilité future ;
- taxes/frais ;
- conditions ;
- annulation ;
- acomptes ;
- extras ;
- langues ;
- devise ;
- coordonnées ;
- e-mails ;
- numéros d’urgence ;
- test réservation réelle puis annulation/remboursement.

## Canaux

- connexion autorisée par l’établissement ;
- mappings complets ;
- réservations futures importées ;
- stock rapproché ;
- full sync ;
- test réservation ;
- test modification ;
- test annulation ;
- alertes ;
- contacts support ;
- procédure stop-sell ;
- aucun ancien channel manager ne pilote encore le même inventaire.

## Conformité

- CGV ;
- confidentialité ;
- cookies ;
- mentions CNDP ;
- consentement non pré-coché ;
- contrat PSP ;
- périmètre PCI ;
- sous-traitants ;
- conservation ;
- procédure droits ;
- procédure incident.

---

# 17. Indicateurs produit après lancement

- taux recherche → résultat ;
- résultat → sélection ;
- sélection → checkout ;
- checkout → confirmation ;
- abandon par champ ;
- conversion mobile/desktop ;
- valeur moyenne ;
- part directe vs OTA ;
- coût d’acquisition ;
- utilisation codes promo ;
- annulations ;
- no-show ;
- erreurs paiement ;
- recherches sans disponibilité ;
- temps de réponse ;
- latence de synchronisation ;
- erreurs/mapping ;
- surbookings ;
- part des réservations nécessitant intervention manuelle.

Les analytics doivent respecter la minimisation des données et le consentement applicable.

---

# 18. Décisions par défaut à appliquer sans attendre

- parcours principal date-first, parcours secondaire room-first ;
- lancement single-property mais modèle multi-property ready ;
- Laravel 13/PHP 8.4/React/TypeScript ;
- monolithe modulaire ;
- MySQL/MariaDB InnoDB ;
- Valkey/Redis et Supervisor lorsque WHM/root le permet ;
- devise de vente MAD, devises d’affichage optionnelles ;
- langues FR/EN/AR ;
- fuseau `Africa/Casablanca` ;
- paiement via page hébergée/tokenisée ;
- hold de 10 minutes configurable ;
- pas de compte client obligatoire ;
- prix total visible ;
- gateway OTA certifiée d’abord ;
- connecteurs directs ensuite ;
- aucune donnée de carte brute ;
- WCAG 2.2 AA ;
- ASVS niveau 2 ;
- staging obligatoire ;
- tests de concurrence obligatoires avant vente réelle.

---

# 19. Sources officielles vérifiées

Ces liens servent à Codex et à l’équipe pour valider les implémentations au moment de chaque intégration. Les spécifications peuvent évoluer ; ne jamais coder uniquement à partir d’un résumé.

## Booking.com

- Connectivity APIs : https://developers.booking.com/connectivity/docs
- Rates & Availability : https://developers.booking.com/connectivity/docs/ari
- Reservations API : https://developers.booking.com/connectivity/docs/reservations-api/reservations-overview
- Connections API : https://developers.booking.com/connectivity/docs/connections-api/connections-overview
- Portail développeurs : https://developers.booking.com/connectivity/home

## Expedia Group

- Connectivity Hub : https://developers.expediagroup.com/supply/lodging
- Programme partenaires : https://developers.expediagroup.com/supply/lodging/cpp/overview
- Mises à jour : https://developers.expediagroup.com/supply/lodging/updates
- Contrat de licence : https://developers.expediagroup.com/supply/lodging/license

## Google Hotels

- Hotel Prices : https://developers.google.com/hotels/hotel-prices
- Travel Partner API : https://developers.google.com/hotels/hotel-prices/api-reference/rest
- Partenaires de connectivité : https://developers.google.com/hotels/connectivity-partners

## Infrastructure et framework

- Laravel 13 : https://laravel.com/docs/13.x
- Starter React : https://laravel.com/docs/13.x/starter-kits
- Queues : https://laravel.com/docs/13.x/queues
- Scheduler : https://laravel.com/docs/13.x/scheduling
- cPanel Application Manager : https://docs.cpanel.net/cpanel/software/application-manager/
- cPanel Cron Jobs : https://docs.cpanel.net/cpanel/advanced/cron-jobs/
- cPanel Git deployment : https://docs.cpanel.net/knowledge-base/web-services/guide-to-git-deployment/

## Sécurité, accessibilité et conformité

- WCAG 2.2 : https://www.w3.org/TR/WCAG22/
- OWASP ASVS : https://owasp.org/www-project-application-security-verification-standard/
- OWASP API Security : https://owasp.org/API-Security/editions/2023/en/0x11-t10/
- OWASP Top 10 : https://owasp.org/Top10/2025/
- PCI DSS : https://www.pcisecuritystandards.org/standards/pci-dss/
- CNDP Maroc : https://www.cndp.ma/
- Loi 09-08 : https://www.cndp.ma/loi-09-08/

## Paiement Maroc

- CMI : https://www.cmi.co.ma/fr
- NAPS : https://naps.ma/
- Payzone : https://payzone.ma/

## Passerelle en marque blanche — exemple à évaluer

- Channex : https://channex.io/
- Documentation : https://docs.channex.io/

---

# 20. Résultat final attendu

À l’issue de ce plan, `reservation.energiedin.ma` doit être :

- un moteur direct premium et rapide ;
- un outil opérable quotidiennement par l’hôtel ;
- une source de vérité cohérente ;
- un channel manager fiable et observable ;
- une base technique certifiable Booking.com et Expedia ;
- une application conforme, accessible et sécurisée ;
- un produit extensible sans réécriture du cœur.

Le succès ne se mesure pas au nombre de logos OTA affichés, mais à la profondeur réelle de chaque connexion : stock, prix, restrictions, réservations, modifications, annulations, acquittements, paiements, erreurs et réconciliation.
# AVIS D'IMPLÉMENTATION 2026-07-14

`docs/DECISIONS_IMPLEMENTATION.md` est autoritaire. Il remplace notamment le frontend React/Inertia, la passerelle générique/Channex, le lancement mono-hôtel et l'ordre historique des phases décrits ci-dessous.
