{"openapi":"3.0.1","info":{"title":"JeanFe Résidence — API Backend","description":"## API de gestion hôtelière — JeanFe Résidence, Kananga (RDC)\n\nBackend complet pour la gestion de 3 sites hôteliers : réservations,\nfacturation (TVA 16%), paiements multi-modes (MPesa, Flutterwave, espèces),\npersonnel, housekeeping, maintenance, stock, restaurant et KPIs.\n\n### Authentification — Flow 2FA obligatoire\n\n```\n1. POST /auth/login          → { sessionToken, message }\n2. POST /auth/verify-otp     → { accessToken (1h), refreshToken (30j) }\n3. Header sur chaque appel   → Authorization: Bearer <accessToken>\n4. POST /auth/refresh        → renouveler le token silencieusement\n```\n\n### Codes d'erreur (RFC 9457 ProblemDetail)\n\n| Code | Signification |\n|------|--------------|\n| 200  | Succès |\n| 201  | Créé |\n| 204  | Supprimé / sans contenu |\n| 400  | Requête invalide (validation) |\n| 401  | Non authentifié / token expiré |\n| 403  | Accès refusé (rôle insuffisant) |\n| 404  | Ressource introuvable |\n| 422  | Règle métier violée |\n| 429  | Trop de tentatives (rate limiting) |\n| 500  | Erreur serveur interne |\n\n### Rôles disponibles\n`SUPER_ADMIN` · `GESTIONNAIRE` · `RECEPTIONNISTE` ·\n`FEMME_DE_CHAMBRE` · `CUISINIER` · `SECURITE` · `TECHNICIEN`\n\n### Devise par défaut : USD · TVA RDC : 16%\n","contact":{"name":"JeanFe Résidence — Support technique","url":"https://jeanferesidence.cd","email":"tech@jeanferesidence.cd"},"license":{"name":"Propriétaire — JeanFe Résidence","url":"https://jeanferesidence.cd/license"},"version":"1.0.0"},"servers":[{"url":"http://localhost:8080/api","description":"Développement local"},{"url":"https://api.jeanferesidence.cd/api","description":"Production"}],"security":[{"BearerAuth":[]}],"tags":[{"name":"Audit trail","description":"Journal immuable de toutes les actions critiques"},{"name":"Dev — Tests email","description":"Endpoints de test des templates email (profil dev uniquement)"},{"name":"Caution","description":"Cycle de vie : encaissement, restitution, rétention"},{"name":"Restaurant & Bar","description":"Commandes restaurant, room service, statuts"},{"name":"Push Notifications","description":"Enregistrement des appareils pour les notifications push FCM"},{"name":"Avis clients","description":"Notes et commentaires post-séjour. Envoyés automatiquement J+1 après checkout. Validés par un employé avant publication."},{"name":"Documents clients","description":"Upload et gestion des pièces d'identité (stockage MinIO S3)"},{"name":"Facturation","description":"Factures (TVA 16%), lignes, annulation, export PDF"},{"name":"Push Notifications","description":"Enregistrement des appareils mobiles/web pour les notifications push Firebase FCM.\n\nL'application mobile appelle `POST /push/register` au démarrage avec son FCM token.\n\n**Notifications envoyées automatiquement :**\nnouvelle réservation, check-in, checkout (housekeeping), ticket maintenance urgent, alerte stock.\n\n**Activation Firebase :** définir `FCM_ENABLED=true` + `FIREBASE_SERVICE_ACCOUNT_JSON=/chemin/creds.json`\n"},{"name":"Clients","description":"Gestion de la clientèle, statut VIP, blacklist"},{"name":"Types de chambre","description":"Catégories de chambres avec tarifs de base"},{"name":"Dashboard KPIs","description":"Indicateurs temps réel : taux d'occupation, ADR, RevPAR"},{"name":"Politique annulation","description":"Politiques et calcul de pénalités"},{"name":"Authentification Clients","description":"Inscription et connexion des clients par e-mail / mot de passe.\n\n**Flow :**\n1. `POST /auth/client/register` — création de compte (nom complet, e-mail, mot de passe)\n2. `POST /auth/client/login` — connexion (e-mail, mot de passe)\n3. Backend → JWT interne JeanFe (rôle CLIENT, 1h)\n"},{"name":"Personnel","description":"Employés, rôles, mots de passe, désactivation"},{"name":"Tarification","description":"Tarifs saisonniers, remises, code promo, simulation de prix"},{"name":"Réservations de groupe","description":"Dossiers groupes avec remise négociée et facturation consolidée"},{"name":"Taux de change","description":"Historique USD/CDF, publication d'un nouveau taux"},{"name":"Authentification","description":"Login 2FA, OTP, refresh token, logout, reset mot de passe"},{"name":"Disponibilité","description":"Recherche de chambres disponibles avec suggestions cross-sites, filtres avancés et tarifs calculés avec remises appliquées"},{"name":"Réservations","description":"Réservations individuelles : création, check-in/out, annulation"},{"name":"Authentification Clients","description":"Inscription et connexion self-service des clients via Firebase Auth.\n\nProviders : 🔵 Google · 🍎 Apple · 📧 Email/Mot de passe · 📱 Téléphone OTP\n\n**Setup Firebase (une fois) :**\n1. Créer un projet sur https://console.firebase.google.com\n2. Activer les providers souhaités (Authentication → Sign-in method)\n3. Télécharger `google-services.json` (Android) et `GoogleService-Info.plist` (iOS)\n4. Placer les fichiers dans l'app Flutter\n5. Côté backend : définir `FCM_ENABLED=true` + `FIREBASE_SERVICE_ACCOUNT_JSON`\n\n**Mode sandbox** : sans Firebase, utiliser `sandbox:{uid}:{provider}:{email}` comme idToken.\n"},{"name":"Housekeeping","description":"Tâches de nettoyage et statuts des chambres"},{"name":"Sites","description":"Gestion des sites hôteliers (nom, adresse, coordonnées GPS)"},{"name":"Rapports financiers","description":"CA mensuel, TVA, occupation — export CSV"},{"name":"Documents clients","description":"Upload et gestion des pièces d'identité clients (passeport, carte nationale, permis…).\nStockage sécurisé dans **MinIO S3-compatible**.\n\n**Organisation :** `identite/{clientId}/{YYYYMM}/{uuid}.{ext}`\n\n**Formats acceptés :** JPEG, PNG, WebP, PDF — max 10 Mo\n\n**Accès :** URL pré-signée temporaire (TTL 15 min) — aucune URL publique permanente.\n"},{"name":"Chambres","description":"Chambres physiques et statuts (LIBRE, OCCUPEE, EN_NETTOYAGE…)"},{"name":"Configuration métier","description":"34 paramètres modifiables à chaud par SUPER_ADMIN"},{"name":"Blacklist clients","description":"Liste noire avec niveaux de gravité et levée de blacklist"},{"name":"Stock","description":"Articles, mouvements (entrée/sortie/ajustement/perte)"},{"name":"Paiements","description":"Enregistrement paiements multi-modes (MPesa, Flutterwave, espèces…)"},{"name":"Extras & Note de frais","description":"Room service, minibar, blanchisserie — consolidés au check-out"},{"name":"Planning shifts","description":"Planning hebdomadaire des horaires par site"},{"name":"Maintenance","description":"Tickets de panne avec journal d'interventions"}],"paths":{"/types-chambre/{id}":{"put":{"tags":["Types de chambre"],"summary":"Modifier un type de chambre","operationId":"update","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTypeChambreRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TypeChambreResponse"}}}}}},"delete":{"tags":["Types de chambre"],"summary":"Supprimer un type de chambre (refusé si chambres / réservations actives)","operationId":"delete","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/types-chambre/{id}/photos/{photoId}":{"put":{"tags":["Types de chambre"],"summary":"Modifier les métadonnées d'une photo (titre, catégorie, ordre, principale)","operationId":"modifierPhoto","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"photoId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSitePhotoRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TypeChambrePhotoResponse"}}}}}},"delete":{"tags":["Types de chambre"],"summary":"Supprimer une photo d'un type de chambre","operationId":"supprimerPhoto","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"photoId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/types-chambre/{id}/equipements":{"get":{"tags":["Types de chambre"],"summary":"Équipements associés à un type de chambre","operationId":"equipements","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}},"put":{"tags":["Types de chambre"],"summary":"Remplacer les équipements associés à un type de chambre","operationId":"remplacerEquipements","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteEquipementsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}}},"/sites/{id}":{"get":{"tags":["Sites"],"operationId":"findById","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}}}},"put":{"tags":["Sites"],"summary":"Modifier un site","operationId":"update_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSiteRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}}}},"delete":{"tags":["Sites"],"summary":"Supprimer définitivement un site (+ types orphelins)","operationId":"delete_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/sites/{id}/photos/{photoId}":{"put":{"tags":["Sites"],"summary":"Modifier les métadonnées d'une photo (titre, catégorie, ordre, principale)","operationId":"modifierPhoto_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"photoId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSitePhotoRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SitePhotoResponse"}}}}}},"delete":{"tags":["Sites"],"summary":"Supprimer une photo d'un site","operationId":"supprimerPhoto_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"photoId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/sites/{id}/equipements":{"get":{"tags":["Sites"],"operationId":"equipements_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}},"put":{"tags":["Sites"],"summary":"Remplacer les équipements associés à un site","operationId":"remplacerEquipements_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteEquipementsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}}},"/notifications/preferences":{"get":{"tags":["Notifications"],"operationId":"getPreferences","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PreferenceNotificationResponse"}}}}}},"put":{"tags":["Notifications"],"operationId":"updatePreferences","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePreferenceNotificationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PreferenceNotificationResponse"}}}}}}},"/equipements/{id}":{"put":{"tags":["Équipements"],"operationId":"update_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertEquipementRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EquipementResponse"}}}}}},"delete":{"tags":["Équipements"],"summary":"Supprimer un équipement (retire aussi ses associations)","operationId":"delete_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/employes/{id}":{"get":{"tags":["Personnel"],"operationId":"findById_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EmployeResponse"}}}}}},"put":{"tags":["Personnel"],"summary":"Modifier un employé (infos, rôle, site)","operationId":"update_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmployeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EmployeResponse"}}}}}},"delete":{"tags":["Personnel"],"summary":"Désactiver un compte employé","operationId":"deactivate","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/config/{cle}":{"get":{"tags":["Configuration métier"],"summary":"Valeur d'un paramètre par sa clé","operationId":"findByCle","parameters":[{"name":"cle","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConfigMetierResponse"}}}}}},"put":{"tags":["Configuration métier"],"summary":"Modifier un paramètre métier — SUPER_ADMIN uniquement","description":"Met à jour la valeur d'un paramètre. La valeur est validée selon son type (NUMBER, BOOLEAN, EMAIL, STRING, DURATION_DAYS). Exemples de clés : `TAUX_CHANGE_USD_CDF`, `TVA_TAUX_PCT`, `ANNULATION_GRATUITE_JOURS`, `OTP_EXPIRY_MINUTES`, `REMISE_VIP_PCT`. Traçabilité : l'employé modificateur est enregistré.\n","operationId":"update_4","parameters":[{"name":"cle","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConfigRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConfigMetierResponse"}}}}}}},"/config/batch":{"put":{"tags":["Configuration métier"],"summary":"Modifier plusieurs paramètres en une seule requête","operationId":"updateBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConfigBatchRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConfigMetierResponse"}}}}}}}},"/clients/{id}":{"get":{"tags":["Clients"],"operationId":"findById_6","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}}}},"put":{"tags":["Clients"],"summary":"Modifier un client","operationId":"update_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClientRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}}}}},"/chambres/{id}":{"get":{"tags":["Chambres"],"operationId":"findById_7","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ChambreResponse"}}}}}},"put":{"tags":["Chambres"],"summary":"Modifier une chambre (numéro, étage, type, statut, notes)","operationId":"update_6","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChambreRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ChambreResponse"}}}}}},"delete":{"tags":["Chambres"],"summary":"Supprimer une chambre (refusé si réservations actives)","operationId":"delete_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/types-chambre":{"get":{"tags":["Types de chambre"],"operationId":"findAllAvailable","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TypeChambreResponse"}}}}}}},"post":{"tags":["Types de chambre"],"summary":"Créer un type de chambre — SUPER_ADMIN","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTypeChambreRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TypeChambreResponse"}}}}}}},"/types-chambre/{id}/photos":{"get":{"tags":["Types de chambre"],"operationId":"photos","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TypeChambrePhotoResponse"}}}}}}},"post":{"tags":["Types de chambre"],"summary":"Ajouter une photo (multipart) à un type de chambre","operationId":"ajouterPhoto","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"titre","in":"query","required":false,"schema":{"type":"string"}},{"name":"categorie","in":"query","required":false,"schema":{"type":"string"}},{"name":"ordre","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"principale","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"altText","in":"query","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["fichier"],"type":"object","properties":{"fichier":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TypeChambrePhotoResponse"}}}}}}},"/taux-change":{"get":{"tags":["Taux de change"],"summary":"Historique complet des taux","operationId":"historique","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TauxChangeResponse"}}}}}}},"post":{"tags":["Taux de change"],"summary":"Publier un nouveau taux de change","operationId":"publier","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublierTauxChangeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TauxChangeResponse"}}}}}}},"/stock/mouvements":{"post":{"tags":["Stock"],"operationId":"mouvement","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MouvementStockRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StockArticleResponse"}}}}}}},"/stock/articles":{"post":{"tags":["Stock"],"operationId":"create_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStockArticleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StockArticleResponse"}}}}}}},"/sites":{"get":{"tags":["Sites"],"operationId":"findAll","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SiteResponse"}}}}}}},"post":{"tags":["Sites"],"summary":"Créer un site — SUPER_ADMIN ou GESTIONNAIRE","operationId":"create_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSiteRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}}}}},"/sites/{id}/photos":{"get":{"tags":["Sites"],"operationId":"photos_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SitePhotoResponse"}}}}}}},"post":{"tags":["Sites"],"summary":"Ajouter une photo (multipart) à un site","operationId":"ajouterPhoto_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"titre","in":"query","required":false,"schema":{"type":"string"}},{"name":"categorie","in":"query","required":false,"schema":{"type":"string"}},{"name":"ordre","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"principale","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"altText","in":"query","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["fichier"],"type":"object","properties":{"fichier":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SitePhotoResponse"}}}}}}},"/rfid/verifier":{"post":{"tags":["RFID"],"summary":"Vérifier un badge sur une serrure — journalise la tentative","description":"Carte CLIENT : uniquement sa chambre pendant le séjour. Cartes de service : toutes les chambres pendant la validité.","operationId":"verifier","parameters":[{"name":"codeCarte","in":"query","required":true,"schema":{"type":"string"}},{"name":"chambreId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AccesRfidResponse"}}}}}}},"/rfid/cartes":{"post":{"tags":["RFID"],"summary":"Encoder une carte — client (via réservation) ou employé (carte de service)","operationId":"encoder","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EncoderCarteRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CarteRfidResponse"}}}}}}},"/reservations":{"post":{"tags":["Réservations"],"operationId":"create_3","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReservationRequest"}}},"required":true},"responses":{"422":{"description":"Conflit de dates ou client blacklisté","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"404":{"description":"Client, site ou chambre introuvable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"201":{"description":"Réservation créée — chambre RESERVEE","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/{id}/payer":{"post":{"tags":["Réservations"],"summary":"Payer une réservation (client)","description":"Génère la facture si besoin et initie le paiement (acompte par défaut) via le gateway choisi. Le paiement reçu confirme automatiquement la réservation.","operationId":"payer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayerReservationRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaiementLienResponse"}}}}}}},"/reservations/{id}/no-show":{"post":{"tags":["Réservations"],"summary":"Marquer no-show — pénalité 100% + libération chambre","description":"Enregistre le no-show du client. Pénalité 100% appliquée. La chambre repasse automatiquement en LIBRE.\n","operationId":"noShow","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/{id}/confirmer":{"post":{"tags":["Réservations"],"summary":"Confirmer une réservation (EN_ATTENTE → CONFIRMEE)","description":"Passe la réservation de EN_ATTENTE à CONFIRMEE. À utiliser après réception d'un acompte ou validation manuelle.\n","operationId":"confirmer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/{id}/check-out":{"post":{"tags":["Réservations"],"operationId":"checkOut","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/{id}/check-in":{"post":{"tags":["Réservations"],"operationId":"checkIn","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/{id}/annuler":{"post":{"tags":["Réservations"],"summary":"Annuler une réservation","description":"Un client n'annule que ses propres réservations (politique d'annulation + pénalité appliquées). La réception annule sans restriction de propriété.","operationId":"annuler","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/reception":{"post":{"tags":["Réservations"],"summary":"Créer une réservation (réception)","description":"Type-basée : le serveur affecte une chambre libre et recalcule le prix. Statut CONFIRMEE si confirmer=true, sinon EN_ATTENTE (sans hold).","operationId":"creerParReception","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReservationReceptionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/me":{"get":{"tags":["Réservations"],"summary":"Mes réservations (client connecté)","operationId":"mesReservations","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"post":{"tags":["Réservations"],"summary":"Réserver (client connecté)","description":"Crée une réservation EN_ATTENTE pour le client connecté. Le prix est recalculé serveur et une chambre libre du type est affectée automatiquement.","operationId":"reserverPourMoi","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReservationClientRequest"}}},"required":true},"responses":{"422":{"description":"Indisponibilité, e-mail non vérifié ou blacklist","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"201":{"description":"Réservation créée — EN_ATTENTE avec hold","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/devis":{"post":{"tags":["Réservations"],"summary":"Devis de réservation (client) — aucun prix n'est accepté du client","description":"Calcule prix, caution, acompte attendu, politique d'annulation, pénalité estimée et validité. Ne crée aucune réservation.","operationId":"devis","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DevisReservationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DevisReservationResponse"}}}}}}},"/reclamations":{"get":{"tags":["Réclamations"],"summary":"Toutes les réclamations (réception/gestion) — récentes d'abord","operationId":"toutes","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReclamationResponse"}}}}}}},"post":{"tags":["Réclamations"],"summary":"Déposer une réclamation — client connecté","operationId":"creer","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReclamationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReclamationResponse"}}}}}}},"/push/register":{"post":{"tags":["Push Notifications"],"summary":"Enregistrer un appareil pour les push notifications","description":"L'application mobile envoie son FCM token à chaque démarrage.\nSi le token existe déjà, la date de dernière activité est mise à jour.\n\n**À appeler depuis l'app mobile :**\n- Au premier lancement\n- Quand FCM génère un nouveau token (`onTokenRefresh`)\n- Après reconnexion\n\nPlatforms : `ANDROID`, `IOS`, `WEB`\n","operationId":"register","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeviceRequest"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/presences/pointer":{"post":{"tags":["Présences"],"summary":"Pointer (employé connecté) — 1er appel du jour = arrivée, 2e = départ. La position GPS doit être à moins de 300 m du site.","operationId":"pointer","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PointerRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PresenceResponse"}}}}}}},"/planning":{"post":{"tags":["Planning shifts"],"summary":"Ajouter un shift au planning (anti-chevauchement)","operationId":"planifier","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShiftRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ShiftResponse"}}}}}}},"/paiements":{"post":{"tags":["Paiements"],"operationId":"create_4","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaiementRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaiementResponse"}}}}}}},"/paiements/webhook/orange-money":{"post":{"tags":["Webhooks paiement"],"summary":"Webhook Orange Money","operationId":"orangeMoney","requestBody":{"content":{"application/json":{"schema":{"type":"string"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/paiements/webhook/mpesa":{"post":{"tags":["Webhooks paiement"],"summary":"Webhook MPesa — callback STK Push","operationId":"mpesa","requestBody":{"content":{"application/json":{"schema":{"type":"string"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/paiements/webhook/maxicash":{"post":{"tags":["Webhooks paiement"],"summary":"Webhook MaxiCash — notification de paiement","operationId":"maxicash","responses":{"200":{"description":"OK"}}}},"/paiements/webhook/flutterwave":{"post":{"tags":["Webhooks paiement"],"summary":"Webhook Flutterwave — confirmation de paiement","operationId":"flutterwave","parameters":[{"name":"verif-hash","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/paiements/webhook/airtel-money":{"post":{"tags":["Webhooks paiement"],"summary":"Webhook Airtel Money","operationId":"airtelMoney","parameters":[{"name":"X-Signature","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/paiements/initier":{"post":{"tags":["Paiements électroniques"],"summary":"Initier un paiement — retourne un lien ou déclenche un STK Push","operationId":"initier","parameters":[{"name":"factureId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"gateway","in":"query","required":true,"schema":{"type":"string","enum":["FLUTTERWAVE","MPESA","AIRTEL_MONEY","ORANGE_MONEY","AFRIMONEY","ILLICOCASH","PAYPAL","MAXICASH","MANUAL"]}},{"name":"montant","in":"query","required":false,"schema":{"type":"number"}},{"name":"devise","in":"query","required":false,"schema":{"type":"string","default":"USD"}},{"name":"telephone","in":"query","required":false,"schema":{"type":"string"}},{"name":"clientEmail","in":"query","required":false,"schema":{"type":"string"}},{"name":"clientNom","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaiementLienResponse"}}}}}}},"/notifications/envoyer":{"post":{"tags":["Notifications"],"summary":"Envoyer une notification manuelle (USER / ROLE / SITE / ALL)","operationId":"envoyer","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvoyerNotificationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}}}}}},"/note-frais/reservation/{reservationId}":{"post":{"tags":["Note de frais"],"summary":"Génère la note de frais consolidée (hébergement + extras)","operationId":"generer","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FactureResponse"}}}}}}},"/maintenance":{"post":{"tags":["Maintenance"],"summary":"Signaler une panne — création ticket de maintenance","description":"Crée un ticket de maintenance. Si `chambreHorsService = true`, la chambre passe automatiquement en HORS_SERVICE. Types : PLOMBERIE, ELECTRICITE, CLIMATISATION, MOBILIER, SERRURE_RFID, PEINTURE, AUTRE. Priorités : BASSE, NORMALE, HAUTE, URGENTE.\n","operationId":"creer_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TicketResponse"}}}}}}},"/maintenance/{id}/resoudre":{"post":{"tags":["Maintenance"],"summary":"Résoudre un ticket — libération automatique de la chambre","description":"Résout le ticket et notifie la résolution. Si la chambre était HORS_SERVICE, elle repasse automatiquement en EN_NETTOYAGE (étape obligatoire avant réouverture aux clients).\n","operationId":"resoudre","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResoudreTicketRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TicketResponse"}}}}}}},"/housekeeping":{"post":{"tags":["Housekeeping"],"operationId":"create_5","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateHousekeepingRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/HousekeepingResponse"}}}}}}},"/housekeeping/{id}/terminer":{"post":{"tags":["Housekeeping"],"operationId":"terminer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/HousekeepingResponse"}}}}}}},"/groupes":{"post":{"tags":["Réservations de groupe"],"summary":"Créer un dossier groupe (chambres nominatives)","operationId":"creer_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGroupeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GroupeResponse"}}}}}}},"/groupes/{id}/annuler":{"post":{"tags":["Réservations de groupe"],"summary":"Annuler un dossier groupe (annule ses réservations, libère les chambres)","operationId":"annuler_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GroupeResponse"}}}}}}},"/groupes/par-type":{"post":{"tags":["Réservations de groupe"],"summary":"Créer un dossier groupe par type de chambre (quantité)","description":"Type-basé : le serveur affecte N chambres libres du type demandé.","operationId":"creerParType","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGroupeParTypeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GroupeResponse"}}}}}}},"/factures":{"post":{"tags":["Facturation"],"operationId":"create_6","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFactureRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FactureResponse"}}}}}}},"/extras/reservation/{reservationId}":{"get":{"tags":["Extras"],"summary":"Liste les extras d'une réservation","operationId":"findByReservation_1","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ExtraResponse"}}}}}}},"post":{"tags":["Extras"],"summary":"Ajoute un extra à une réservation","operationId":"ajouter","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AjouterExtraRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ExtraResponse"}}}}}}},"/extras/reservation/{reservationId}/room-service/{commandeId}":{"post":{"tags":["Extras"],"summary":"Attache une commande restaurant comme room service","operationId":"ajouterRoomService","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"commandeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ExtraResponse"}}}}}}},"/equipements":{"get":{"tags":["Équipements"],"operationId":"findAll_2","parameters":[{"name":"categorie","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}},"post":{"tags":["Équipements"],"operationId":"create_7","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertEquipementRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}},"/employes":{"get":{"tags":["Personnel"],"operationId":"findAll_3","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EmployeResponse"}}}}}}},"post":{"tags":["Personnel"],"operationId":"create_8","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEmployeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EmployeResponse"}}}}}}},"/employes/{id}/photo":{"post":{"tags":["Personnel"],"summary":"Téléverser la photo d'un employé (multipart « fichier »)","operationId":"uploaderPhoto","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["fichier"],"type":"object","properties":{"fichier":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EmployeResponse"}}}}}}},"/config/{cle}/reset":{"post":{"tags":["Configuration métier"],"summary":"Réinitialiser un paramètre à sa valeur d'usine","operationId":"reset","parameters":[{"name":"cle","in":"path","required":true,"schema":{"type":"string"}},{"name":"employeId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConfigMetierResponse"}}}}}}},"/commandes":{"post":{"tags":["Restaurant & Bar"],"operationId":"create_9","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommandeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommandeResponse"}}}}}}},"/clients":{"get":{"tags":["Clients"],"summary":"Recherche clients (q = prénom ou nom)","operationId":"search","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageClientResponse"}}}}}},"post":{"tags":["Clients"],"operationId":"create_10","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClientRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}}}}},"/clients/{id}/photo":{"post":{"tags":["Clients"],"summary":"Téléverser la photo d'un client (multipart « fichier »)","operationId":"uploaderPhoto_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["fichier"],"type":"object","properties":{"fichier":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}}}}},"/clients/{clientId}/documents":{"get":{"tags":["Documents clients"],"summary":"Liste les documents d'un client","description":"Retourne les métadonnées de tous les documents actifs. **Ne retourne pas le contenu du fichier** — utiliser `GET /{id}/lien` pour accéder au fichier.","operationId":"findByClient_1","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DocumentResponse"}}}}}}},"post":{"tags":["Documents clients"],"summary":"Uploader une pièce d'identité","description":"Téléverse un document d'identité client vers MinIO.\n\n**Formats acceptés :** JPEG, PNG, WebP, PDF\n**Taille max :** 10 Mo (configurable via `DOCUMENT_TAILLE_MAX_MB`)\n\n**Organisation dans MinIO :**\n```\nbucket: jeanfe-documents\n  identite/{clientId}/{YYYYMM}/{uuid}.{ext}\n```\n\n**Types de document :**\n`PASSEPORT`, `CARTE_NATIONALE`, `PERMIS_CONDUIRE`, `VISA`, `TITRE_SEJOUR`, `AUTRE`\n","operationId":"uploader","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"typeDocument","in":"query","description":"Type du document","required":true,"schema":{"type":"string","enum":["PASSEPORT","CARTE_NATIONALE","PERMIS_CONDUIRE","VISA","TITRE_SEJOUR","AUTRE"]},"example":"PASSEPORT"},{"name":"employeId","in":"query","description":"Employé effectuant l'upload","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"dateExpiration","in":"query","description":"Date d'expiration du document (ISO 8601)","required":false,"schema":{"type":"string","format":"date"},"example":"2030-12-31"}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["fichier"],"type":"object","properties":{"fichier":{"type":"string","description":"Fichier à uploader (JPEG, PNG, WebP ou PDF, max 10 Mo)","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DocumentClient"}}}}}}},"/clients/{clientId}/documents/{documentId}/verifier":{"post":{"tags":["Documents clients"],"summary":"Marquer un document comme vérifié","description":"Un employé confirme avoir vérifié physiquement la pièce d'identité.","operationId":"verifier_1","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"employeId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"notes","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DocumentResponse"}}}}}}},"/clients/{clientId}/blacklist":{"get":{"tags":["Blacklist clients"],"summary":"Historique blacklist d'un client","operationId":"historique_3","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlacklistResponse"}}}}}}},"post":{"tags":["Blacklist clients"],"summary":"Ajouter un client en liste noire","operationId":"blacklister","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlacklisterClientRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BlacklistResponse"}}}}}}},"/chambres":{"post":{"tags":["Chambres"],"operationId":"create_11","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChambreRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ChambreResponse"}}}}}}},"/cautions/{reservationId}/retenir":{"post":{"tags":["Cautions"],"summary":"Retient une partie ou totalité de la caution pour dommages","operationId":"retenir","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetenirCautionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CautionResponse"}}}}}}},"/cautions/{reservationId}/restituer":{"post":{"tags":["Cautions"],"summary":"Restitue intégralement la caution au client","operationId":"restituer","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"employeId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CautionResponse"}}}}}}},"/cautions/{reservationId}/encaisser":{"post":{"tags":["Cautions"],"summary":"Enregistre l'encaissement de la caution","operationId":"encaisser","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"employeId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CautionResponse"}}}}}}},"/cautions/{reservationId}/definir":{"post":{"tags":["Cautions"],"summary":"Définit le montant de caution (défaut = 1 nuit)","operationId":"definir","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DefinirCautionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CautionResponse"}}}}}}},"/avis":{"post":{"tags":["Avis clients"],"summary":"Laisser un avis — client connecté","description":"Soumet un avis (note 1–5 + commentaire) pour une réservation terminée. L'avis est publié après validation par un employé.","operationId":"creer_3","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAvisRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvisResponse"}}}}}}},"/avis/{id}/valider":{"post":{"tags":["Avis clients"],"summary":"Valider un avis pour publication","description":"Rend l'avis visible sur le site et l'application mobile.","operationId":"valider","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"employeId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"reponse","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvisClient"}}}}}}},"/auth/verify-otp":{"post":{"tags":["Authentification"],"summary":"Étape 2 — Validation OTP → JWT + Refresh token","description":"Valide le code OTP. Retourne un `accessToken` JWT (1h) et un `refreshToken` (30j). Le refreshToken est persisté en DB et révocable. **Rate limiting** : 5 tentatives/session.\n","operationId":"verifyOtp","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyOtpRequest"}}},"required":true},"responses":{"200":{"description":"Authentification réussie — JWT retourné","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"422":{"description":"Code incorrect, expiré ou session invalide","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"429":{"description":"Trop de tentatives OTP","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}}}}},"/auth/reset-password":{"post":{"tags":["Authentification"],"summary":"Réinitialisation mot de passe avec le token reçu par email","description":"Valide le token reçu par email et applique le nouveau mot de passe (haché BCrypt). Le token est à usage unique — invalide après utilisation ou expiration (30 min).\n","operationId":"resetPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/auth/refresh":{"post":{"tags":["Authentification"],"summary":"Renouvellement silencieux — refresh token → nouveau JWT","description":"Échange un refreshToken valide contre un nouveau couple accessToken/refreshToken. **Rotation automatique** : l'ancien refreshToken est révoqué. À appeler automatiquement quand l'accessToken expire (HTTP 401).\n","operationId":"refresh","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}}}}},"/auth/profil/photo":{"post":{"tags":["Mon compte"],"summary":"Téléverser ma photo de profil (client)","operationId":"uploaderPhoto_2","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["fichier"],"type":"object","properties":{"fichier":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProfilResponse"}}}}}}},"/auth/logout":{"post":{"tags":["Authentification"],"summary":"Déconnexion — révoque le refresh token (appareil courant)","description":"Révoque uniquement le refreshToken de cet appareil. L'accessToken reste valide jusqu'à expiration naturelle (max 1h). Pour forcer la déconnexion immédiate de tous les appareils : `POST /auth/logout-all`.\n","operationId":"logout","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequest"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/auth/logout-all":{"post":{"tags":["Authentification"],"summary":"Déconnexion globale — révoque tous les refresh tokens","description":"Révoque tous les refreshTokens de l'utilisateur connecté. Idéal en cas de vol d'appareil ou de compromission de compte.\n","operationId":"logoutAll","responses":{"200":{"description":"OK"}}}},"/auth/login":{"post":{"tags":["Authentification"],"summary":"Login unifié (email + mot de passe) — employé d'abord, sinon client","description":"Résolution **employé d'abord**, puis client :\n- **Employé** → vérifie le mot de passe (BCrypt), envoie un OTP 6 chiffres\n  (TTL 5 min) et retourne `{type:\"EMPLOYE\", sessionToken}` à passer à\n  `/auth/verify-otp`.\n- **Client** (e-mail non employé) → vérifie le mot de passe et retourne\n  directement `{type:\"CLIENT\", accessToken}` (JWT ROLE_CLIENT, pas d'OTP).\n\n**Rate limiting** : 5 tentatives/IP/5 min. Compte employé verrouillé 15 min après 5 échecs.\n","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"422":{"description":"E-mail ou mot de passe incorrect","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnifiedLoginResponse"}}}},"429":{"description":"Trop de tentatives","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnifiedLoginResponse"}}}},"200":{"description":"Employé : OTP envoyé — Client : JWT retourné","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnifiedLoginResponse"}}}}}}},"/auth/forgot-password":{"post":{"tags":["Authentification"],"summary":"Mot de passe oublié — envoi email de reset","description":"Envoie un lien de réinitialisation par email (TTL 30 min). **Retourne toujours HTTP 200** même si l'email n'est pas enregistré (prévention d'énumération des comptes — CVE OWASP A07). **Rate limiting** : 3 tentatives/IP/15 min.\n","operationId":"forgotPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/auth/client/verify-email":{"post":{"tags":["Authentification Clients"],"summary":"Vérifier l'e-mail via le code à 6 chiffres","description":"Valide le code reçu par e-mail à l'inscription. Une fois l'e-mail\nvérifié, le client peut effectuer une réservation.\n","operationId":"verifyEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"422":{"description":"Code incorrect ou expiré","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"200":{"description":"E-mail vérifié","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/auth/client/resend-verification":{"post":{"tags":["Authentification Clients"],"summary":"Renvoyer le code de vérification d'e-mail","operationId":"resendVerification","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendVerificationRequest"}}},"required":true},"responses":{"200":{"description":"Code renvoyé","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"422":{"description":"E-mail inconnu ou déjà vérifié","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/auth/client/register":{"post":{"tags":["Authentification Clients"],"summary":"Inscription e-mail / mot de passe","description":"Crée un compte client directement en base (table `client`) à partir\nd'un nom complet, d'un e-mail et d'un mot de passe.\n\nSeules ces informations minimales sont requises ; le reste du profil\n(pays, date de naissance, pièce d'identité…) est complété plus tard,\nau moment de la réservation.\n\nRenvoie immédiatement un **JWT `ROLE_CLIENT`** (auto-connexion).\n","operationId":"register_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterClientRequest"}}},"required":true},"responses":{"422":{"description":"E-mail déjà utilisé ou données invalides","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthClientResponse"}}}},"200":{"description":"Compte créé — JWT retourné","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthClientResponse"}}}}}}},"/auth/client/login":{"post":{"tags":["Authentification Clients"],"summary":"Connexion e-mail / mot de passe","description":"Authentifie un client via son e-mail et son mot de passe.\nRenvoie un **JWT `ROLE_CLIENT`** (valable 1h).\n","operationId":"login_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginClientRequest"}}},"required":true},"responses":{"422":{"description":"E-mail ou mot de passe incorrect","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthClientResponse"}}}},"200":{"description":"Connexion réussie — JWT retourné","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthClientResponse"}}}}}}},"/auth/change-password":{"post":{"tags":["Mon compte"],"summary":"Changer mon mot de passe (employé ou client)","operationId":"changePassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/annulations/{reservationId}":{"post":{"tags":["Annulations"],"summary":"Annule une réservation avec calcul de pénalité","operationId":"annuler_2","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"motif","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SimulationAnnulationResponse"}}}}}}},"/types-chambre/{id}/statut":{"patch":{"tags":["Types de chambre"],"summary":"Activer / désactiver un type de chambre","operationId":"changerStatut","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"actif","in":"query","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TypeChambreResponse"}}}}}}},"/types-chambre/{id}/photos/reorder":{"patch":{"tags":["Types de chambre"],"summary":"Réorganiser les photos d'un type de chambre","operationId":"reordonner","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderPhotosRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TypeChambrePhotoResponse"}}}}}}}},"/sites/{id}/statut":{"patch":{"tags":["Sites"],"summary":"Activer / désactiver un site","operationId":"changerStatut_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"actif","in":"query","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}}}}},"/sites/{id}/photos/reorder":{"patch":{"tags":["Sites"],"summary":"Réorganiser les photos d'un site","operationId":"reordonner_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderPhotosRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SitePhotoResponse"}}}}}}}},"/rfid/cartes/{id}/desactiver":{"patch":{"tags":["RFID"],"summary":"Désactiver une carte (perte, départ anticipé, fin de service)","operationId":"desactiver","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CarteRfidResponse"}}}}}}},"/reclamations/{id}":{"patch":{"tags":["Réclamations"],"summary":"Traiter une réclamation — changer le statut et/ou répondre au client","operationId":"traiter","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"statut","in":"query","required":false,"schema":{"type":"string","enum":["OUVERTE","EN_COURS","RESOLUE","FERMEE"]}},{"name":"reponse","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReclamationResponse"}}}}}}},"/planning/{id}/statut":{"patch":{"tags":["Planning shifts"],"summary":"Mettre à jour le statut d'un shift","operationId":"changerStatut_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"statut","in":"query","required":true,"schema":{"type":"string","enum":["PLANIFIE","CONFIRME","EFFECTUE","ABSENT","ANNULE"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ShiftResponse"}}}}}}},"/notifications/{id}/lu":{"patch":{"tags":["Notifications"],"operationId":"marquerLu","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotificationResponse"}}}}}}},"/notifications/lu-tout":{"patch":{"tags":["Notifications"],"operationId":"marquerToutLu","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}}}}}},"/maintenance/{id}/statut":{"patch":{"tags":["Maintenance"],"summary":"Changer le statut d'un ticket avec commentaire","operationId":"changerStatut_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"statut","in":"query","required":true,"schema":{"type":"string","enum":["OUVERT","ASSIGNE","EN_COURS","EN_ATTENTE_PIECES","RESOLU","FERME","ANNULE"]}},{"name":"commentaire","in":"query","required":true,"schema":{"type":"string"}},{"name":"employeId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TicketResponse"}}}}}}},"/maintenance/{id}/assigner":{"patch":{"tags":["Maintenance"],"summary":"Assigner un ticket à un technicien","operationId":"assigner","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"technicienId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"employeId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TicketResponse"}}}}}}},"/factures/{id}/annuler":{"patch":{"tags":["Facturation"],"summary":"Annuler une facture BROUILLON ou EMISE","operationId":"annuler_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FactureResponse"}}}}}}},"/equipements/{id}/statut":{"patch":{"tags":["Équipements"],"summary":"Activer / désactiver un équipement","operationId":"changerStatut_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"actif","in":"query","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}},"/employes/{id}/statut":{"patch":{"tags":["Personnel"],"summary":"Activer / désactiver un compte employé","operationId":"changerStatut_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"actif","in":"query","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EmployeResponse"}}}}}}},"/employes/{id}/reset-mot-de-passe":{"patch":{"tags":["Personnel"],"summary":"Réinitialiser le mot de passe d'un employé (admin)","operationId":"resetPassword_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetMotDePasseRequest"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/employes/{id}/mot-de-passe":{"patch":{"tags":["Personnel"],"summary":"Changer son mot de passe (ou celui d'un subordonné)","operationId":"changePassword_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/commandes/{id}/statut":{"patch":{"tags":["Restaurant & Bar"],"operationId":"updateStatut","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"statut","in":"query","required":true,"schema":{"type":"string","enum":["OUVERTE","EN_PREPARATION","SERVIE","ANNULEE"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommandeResponse"}}}}}}},"/clients/{id}/vip":{"patch":{"tags":["Clients"],"summary":"Basculer le statut VIP d'un client","operationId":"toggleVip","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}}}}},"/clients/{id}/statut":{"patch":{"tags":["Clients"],"summary":"Activer / désactiver un compte client","operationId":"changerStatut_6","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"actif","in":"query","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClientResponse"}}}}}}},"/clients/{id}/reset-mot-de-passe":{"patch":{"tags":["Clients"],"summary":"Réinitialiser le mot de passe d'un client (admin)","operationId":"resetPassword_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetMotDePasseRequest"}}},"required":true},"responses":{"200":{"description":"OK"}}}},"/chambres/{id}/statut":{"patch":{"tags":["Chambres"],"operationId":"updateStatut_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStatutChambreRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ChambreResponse"}}}}}}},"/auth/profil":{"get":{"tags":["Mon compte"],"summary":"Mon profil (employé ou client)","operationId":"getProfil","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProfilResponse"}}}}}},"patch":{"tags":["Mon compte"],"summary":"Mettre à jour mon profil (téléphone ; nom complet pour le client)","operationId":"updateProfil","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfilRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProfilResponse"}}}}}}},"/types-chambre/site/{siteId}":{"get":{"tags":["Types de chambre"],"operationId":"findBySite","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TypeChambreResponse"}}}}}}}},"/types-chambre/admin":{"get":{"tags":["Types de chambre"],"summary":"Tous les types de chambre (actifs + inactifs) — module admin","operationId":"findAllForAdmin","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TypeChambreResponse"}}}}}}}},"/taux-change/courant":{"get":{"tags":["Taux de change"],"summary":"Taux USD/CDF effectif aujourd'hui","operationId":"courant","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TauxChangeResponse"}}}}}}},"/taux-change/convertir":{"get":{"tags":["Taux de change"],"summary":"Convertit un montant USD en CDF","operationId":"convertir","parameters":[{"name":"montantUsd","in":"query","required":true,"schema":{"type":"number"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"number"}}}}}}},"/stock/site/{siteId}":{"get":{"tags":["Stock"],"operationId":"findBySite_1","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StockArticleResponse"}}}}}}}},"/stock/me":{"get":{"tags":["Stock"],"summary":"Stock du site de l'employé connecté (articles actifs)","operationId":"monStock","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StockArticleResponse"}}}}}}}},"/stats/accueil":{"get":{"tags":["Statistiques"],"operationId":"accueil","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AccueilStatsResponse"}}}}}}},"/rfid/cartes/reservation/{reservationId}":{"get":{"tags":["RFID"],"summary":"Cartes d'une réservation","operationId":"cartesDeReservation","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CarteRfidResponse"}}}}}}}},"/rfid/cartes/actives":{"get":{"tags":["RFID"],"summary":"Cartes actives — récentes d'abord","operationId":"cartesActives","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CarteRfidResponse"}}}}}}}},"/rfid/acces":{"get":{"tags":["RFID"],"summary":"Journal des accès — 100 derniers","operationId":"journalRecent","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AccesRfidResponse"}}}}}}}},"/rfid/acces/chambre/{chambreId}":{"get":{"tags":["RFID"],"summary":"Journal des accès d'une chambre","operationId":"journalChambre","parameters":[{"name":"chambreId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AccesRfidResponse"}}}}}}}},"/reservations/{id}":{"get":{"tags":["Réservations"],"operationId":"findById_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}},"/reservations/{id}/pdf":{"get":{"tags":["Réservations"],"summary":"Confirmation de réservation au format PDF","description":"Génère la confirmation de réservation (Content-Type application/pdf) aux couleurs JeanFe : référence, statut, client, séjour, tarifs.","operationId":"pdf","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}}}},"/reservations/{id}/paiement-info":{"get":{"tags":["Réservations"],"summary":"Infos de paiement d'une réservation (acompte, payé, restant)","operationId":"paiementInfo","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaiementInfoResponse"}}}}}}},"/reservations/site/{siteId}":{"get":{"tags":["Réservations"],"summary":"Réservations d'un site — liste paginée","description":"Retourne toutes les réservations d'un site avec pagination Spring standard (`?page=0&size=20&sort=dateArrivee,desc`).\n","operationId":"findBySite_2","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageReservationResponse"}}}}}}},"/reservations/site/{siteId}/en-cours":{"get":{"tags":["Réservations"],"summary":"Séjours en cours — clients CHECKED_IN","description":"Retourne les réservations au statut CHECKED_IN (clients actuellement dans l'hôtel).\n","operationId":"enCours","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}}},"/reservations/site/{siteId}/departs-aujourd-hui":{"get":{"tags":["Réservations"],"summary":"Départs du jour — clients à checkout aujourd'hui","description":"Retourne les réservations avec `dateDepart = aujourd'hui` et statut CHECKED_IN. Vue opérationnelle pour la réception.\n","operationId":"departsDuJour","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}}},"/reservations/site/{siteId}/arrivees-aujourd-hui":{"get":{"tags":["Réservations"],"summary":"Arrivées du jour — clients attendus aujourd'hui","description":"Retourne les réservations avec `dateArrivee = aujourd'hui` et statut EN_ATTENTE ou CONFIRMEE. Vue opérationnelle pour la réception.\n","operationId":"arriveesDuJour","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}}},"/reservations/client/{clientId}":{"get":{"tags":["Réservations"],"summary":"Historique des séjours d'un client — toutes réservations, récentes d'abord","operationId":"findByClient","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}}},"/reservations/chambre/{chambreId}":{"get":{"tags":["Réservations"],"operationId":"findByChambre","parameters":[{"name":"chambreId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}}},"/reclamations/me":{"get":{"tags":["Réclamations"],"summary":"Mes réclamations (client connecté)","operationId":"mesReclamations","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReclamationResponse"}}}}}}}},"/rapports/tva/site/{siteId}/{annee}/{mois}":{"get":{"tags":["Rapports financiers"],"summary":"Rapport TVA d'un mois — pour la comptabilité","operationId":"tva","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"annee","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"mois","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RapportTva"}}}}}}},"/rapports/site/{siteId}/pdf":{"get":{"tags":["Rapports financiers"],"summary":"Export PDF du rapport financier mensuel (CA, TVA, occupation 6 mois)","operationId":"rapportPdf","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"annee","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"mois","in":"query","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}}}},"/rapports/occupation/site/{siteId}":{"get":{"tags":["Rapports financiers"],"summary":"Rapport d'occupation sur N mois (défaut: 12)","operationId":"occupation","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"mois","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":12}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RapportOccupation"}}}}}}}},"/rapports/occupation/site/{siteId}/csv":{"get":{"tags":["Rapports financiers"],"summary":"Export CSV du rapport d'occupation","operationId":"occupationCsv","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"mois","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":12}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}}}},"/rapports/ca-mensuel/site/{siteId}":{"get":{"tags":["Rapports financiers"],"summary":"Rapport CA du mois courant","operationId":"caMoisCourant","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RapportCaMensuel"}}}}}}},"/rapports/ca-mensuel/site/{siteId}/{annee}/{mois}":{"get":{"tags":["Rapports financiers"],"summary":"Rapport CA d'un mois spécifique","operationId":"caMensuel","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"annee","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"mois","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RapportCaMensuel"}}}}}}},"/rapports/ca-historique/site/{siteId}":{"get":{"tags":["Rapports financiers"],"summary":"Historique CA sur N mois (défaut: 12)","operationId":"caHistorique","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"mois","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":12}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RapportCaMensuel"}}}}}}}},"/rapports/ca-historique/site/{siteId}/csv":{"get":{"tags":["Rapports financiers"],"summary":"Export CSV du rapport CA","operationId":"caCsv","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"mois","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":12}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}}}},"/presences/site/{siteId}/aujourd-hui":{"get":{"tags":["Présences"],"summary":"Présences du jour d'un site (vue gestion)","operationId":"presencesDuJour","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PresenceResponse"}}}}}}}},"/presences/me":{"get":{"tags":["Présences"],"summary":"Mes présences (employé connecté), récentes d'abord","operationId":"mesPresences","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PresenceResponse"}}}}}}}},"/planning/site/{siteId}/semaine":{"get":{"tags":["Planning shifts"],"summary":"Planning hebdomadaire d'un site — groupé par date (DTO scalaires)","operationId":"planningHebdomadaire","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"semaineDe","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/ShiftResponse"}}}}}}}}},"/planning/site/{siteId}/aujourd-hui":{"get":{"tags":["Planning shifts"],"summary":"Shifts du jour pour un site","operationId":"shiftsAujourdHui","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ShiftResponse"}}}}}}}},"/planning/me":{"get":{"tags":["Planning shifts"],"summary":"Mon planning (employé connecté) — 7 prochains jours","operationId":"monPlanning","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ShiftResponse"}}}}}}}},"/planning/employe/{employeId}":{"get":{"tags":["Planning shifts"],"summary":"Planning d'un employé sur une période","operationId":"planningEmploye","parameters":[{"name":"employeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"debut","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"fin","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ShiftResponse"}}}}}}}},"/paiements/statut/{txRef}":{"get":{"tags":["Paiements électroniques"],"summary":"Vérifier le statut d'un paiement (polling ou après retour redirect)","operationId":"statut","parameters":[{"name":"txRef","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaiementLienResponse"}}}}}}},"/paiements/maxicash/redirect/{txRef}":{"get":{"tags":["maxi-cash-redirect-controller"],"operationId":"redirect","parameters":[{"name":"txRef","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/paiements/gateways":{"get":{"tags":["Paiements électroniques"],"summary":"Liste des moyens de paiement disponibles","operationId":"gateways","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["FLUTTERWAVE","MPESA","AIRTEL_MONEY","ORANGE_MONEY","AFRIMONEY","ILLICOCASH","PAYPAL","MAXICASH","MANUAL"]}}}}}}}},"/paiements/facture/{factureId}":{"get":{"tags":["Paiements"],"operationId":"findByFacture","parameters":[{"name":"factureId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaiementResponse"}}}}}}}},"/notifications":{"get":{"tags":["Notifications"],"summary":"Mes notifications (filtres : categorie, lu)","operationId":"mesNotifications","parameters":[{"name":"categorie","in":"query","required":false,"schema":{"type":"string","enum":["RESERVATION","PAIEMENT","CHECK_IN_OUT","MENAGE","MAINTENANCE","SECURITE","STOCK","RESTAURATION","WIFI","SYSTEME","SUPPORT","ALERTE_CRITIQUE"]}},{"name":"lu","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageNotificationResponse"}}}}}}},"/notifications/priorites":{"get":{"tags":["Notifications"],"operationId":"priorites","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/notifications/non-lues/count":{"get":{"tags":["Notifications"],"operationId":"compteurNonLues","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}}}}}}}},"/notifications/categories":{"get":{"tags":["Notifications"],"operationId":"categories","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/notifications/admin":{"get":{"tags":["Notifications"],"summary":"Historique global des notifications","operationId":"historique_1","parameters":[{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageNotificationResponse"}}}}}}},"/note-frais/site/{siteId}":{"get":{"tags":["Note de frais"],"summary":"Notes de frais d'un site (préfixe NF-), récentes d'abord — vue gestion","operationId":"parSite","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FactureResponse"}}}}}}}},"/maintenance/{id}/interventions":{"get":{"tags":["Maintenance"],"summary":"Journal des actions d'un ticket (qui a fait quoi, quand)","operationId":"interventions","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterventionResponse"}}}}}}}},"/maintenance/site/{siteId}":{"get":{"tags":["Maintenance"],"summary":"Tous les tickets d'un site (paginé)","operationId":"findAll_1","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageTicketResponse"}}}}}}},"/maintenance/site/{siteId}/ouverts":{"get":{"tags":["Maintenance"],"summary":"Tickets ouverts/en cours d'un site, triés par priorité","operationId":"findOuverts","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketResponse"}}}}}}}},"/maintenance/mes-tickets/{technicienId}":{"get":{"tags":["Maintenance"],"summary":"Tickets assignés à un technicien","operationId":"findMesTickets","parameters":[{"name":"technicienId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketResponse"}}}}}}}},"/maintenance/me":{"get":{"tags":["Maintenance"],"summary":"Mes tickets (technicien connecté) — assignés, en cours, en attente pièces","operationId":"mesTickets","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketResponse"}}}}}}}},"/maintenance/me/historique":{"get":{"tags":["Maintenance"],"summary":"Historique des interventions du technicien connecté — tickets résolus/fermés","operationId":"mesInterventions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketResponse"}}}}}}}},"/housekeeping/historique":{"get":{"tags":["Housekeeping"],"operationId":"historique_2","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HousekeepingResponse"}}}}}}}},"/housekeeping/a-nettoyer":{"get":{"tags":["Housekeeping"],"operationId":"findANettoyer","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HousekeepingResponse"}}}}}}}},"/groupes/{id}":{"get":{"tags":["Réservations de groupe"],"summary":"Détail d'un dossier groupe","operationId":"findById_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GroupeResponse"}}}}}}},"/groupes/site/{siteId}":{"get":{"tags":["Réservations de groupe"],"summary":"Liste paginée des groupes d'un site","operationId":"findBySite_3","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageGroupeResponse"}}}}}}},"/fidelite/me":{"get":{"tags":["Fidélité"],"summary":"Mon programme de fidélité — solde, niveau, historique","operationId":"maFidelite","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FideliteResponse"}}}}}}},"/factures/{id}":{"get":{"tags":["Facturation"],"operationId":"findById_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FactureResponse"}}}}}}},"/factures/{id}/pdf":{"get":{"tags":["Facturation"],"summary":"Export PDF — facture avec design JeanFe","description":"Génère et retourne la facture au format PDF (Content-Type: application/pdf). Design aux couleurs JeanFe : violet #5B4FA8, or #F0A500. Contenu : en-tête hôtel, infos client, tableau des lignes, totaux HT/TVA/TTC, modes de paiement acceptés (MPesa, Airtel, Orange, espèces...).\n","operationId":"pdf_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PDF généré (Content-Type: application/pdf)","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"Facture introuvable","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}}}},"/factures/site/{siteId}":{"get":{"tags":["Facturation"],"summary":"Factures d'un site — liste paginée (gestion)","operationId":"findBySite_4","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageFactureResponse"}}}}}}},"/factures/reservation/{reservationId}":{"get":{"tags":["Facturation"],"summary":"Factures d'une réservation","operationId":"findByReservation","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FactureResponse"}}}}}}}},"/factures/me":{"get":{"tags":["Facturation"],"summary":"Mes factures (client connecté)","operationId":"mesFactures","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FactureResponse"}}}}}}}},"/extras/reservation/{reservationId}/total":{"get":{"tags":["Extras"],"summary":"Total des extras non encore facturés","operationId":"totalNonFacture","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"number"}}}}}}},"/equipements/icones":{"get":{"tags":["Équipements"],"operationId":"icones","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/equipements/codes":{"get":{"tags":["Équipements"],"operationId":"codes","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/equipements/categories":{"get":{"tags":["Équipements"],"operationId":"categories_1","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/equipements/admin":{"get":{"tags":["Équipements"],"summary":"Tous les équipements (actifs + inactifs)","operationId":"findAllForAdmin_1","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EquipementResponse"}}}}}}}},"/employes/site/{siteId}":{"get":{"tags":["Personnel"],"summary":"Employés actifs par site","operationId":"findBySite_5","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EmployeResponse"}}}}}}}},"/employes/roles":{"get":{"tags":["Personnel"],"summary":"Rôles système (liste déroulante)","operationId":"roles","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/disponibilite":{"get":{"tags":["Disponibilité"],"summary":"Disponibilité (vue mobile, à plat)","operationId":"rechercherMobile","parameters":[{"name":"siteId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"dateArrivee","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"dateDepart","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"capaciteMin","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"prixMax","in":"query","required":false,"schema":{"type":"number"}},{"name":"vip","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"codePromo","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DisponibiliteResponse"}}}}}}},"/disponibilite/rechercher":{"get":{"tags":["Disponibilité"],"summary":"Rechercher des chambres disponibles","description":"Recherche complète de disponibilité **avec suggestions automatiques** si le site\nest complet — comme Booking.com.\n\n**Algorithme :**\n1. Cherche dans le site demandé (`siteId`)\n2. Si complet → propose automatiquement les autres sites disponibles\n3. Calcule le tarif avec toutes les remises applicables\n   (saison, VIP, durée longue, code promo)\n4. Affiche l'économie réalisée par rapport au prix de base\n5. Alerte stock si ≤ 3 chambres restantes\n\n**Réponse inclut pour chaque chambre :**\n- Prix par nuit avec/sans remise\n- Prix total du séjour\n- Politique d'annulation applicable\n- Nombre de chambres restantes (alerte urgence)\n- Note moyenne et nombre d'avis\n","operationId":"rechercher","parameters":[{"name":"siteId","in":"query","description":"Site préféré (null = tous les sites)","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"dateArrivee","in":"query","description":"Date d'arrivée","required":true,"schema":{"type":"string","format":"date"},"example":"2026-07-15"},{"name":"dateDepart","in":"query","description":"Date de départ","required":true,"schema":{"type":"string","format":"date"},"example":"2026-07-20"},{"name":"capaciteMin","in":"query","description":"Nombre de personnes minimum","required":false,"schema":{"type":"integer","format":"int32"},"example":2},{"name":"prixMax","in":"query","description":"Budget max par nuit en USD","required":false,"schema":{"type":"number"},"example":80},{"name":"vip","in":"query","description":"Client VIP (remise automatique)","required":false,"schema":{"type":"boolean","default":false}},{"name":"codePromo","in":"query","description":"Code promotionnel","required":false,"schema":{"type":"string"},"example":"JEANFE10"}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResultatRecherche"}}}}}}},"/dashboard/site/{siteId}":{"get":{"tags":["Dashboard KPIs"],"summary":"KPIs mois courant — occupation, ADR, RevPAR vs N-1","description":"Calcule les indicateurs de performance du mois courant avec comparaison sur la même période de l'année précédente. KPIs : taux d'occupation, ADR (Average Daily Rate), RevPAR (Revenue Per Available Room), revenu total, réservations. Accès : SUPER_ADMIN, GESTIONNAIRE.\n","operationId":"kpisMoisCourant","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DashboardKpi"}}}}}}},"/dashboard/site/{siteId}/{annee}/{mois}":{"get":{"tags":["Dashboard KPIs"],"summary":"KPIs d'un mois spécifique — occupation, ADR, RevPAR","description":"Même que `/dashboard/site/{id}` mais pour un mois spécifique. Ex : `/dashboard/site/{id}/2026/1` pour janvier 2026.\n","operationId":"kpisMois","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"annee","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"mois","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DashboardKpi"}}}}}}},"/dashboard/site/{siteId}/aujourd-hui":{"get":{"tags":["Dashboard KPIs"],"summary":"Vue temps réel du jour — arrivées, départs, statuts chambres","description":"État opérationnel en temps réel : nombre d'arrivées et départs du jour, chambres libres/occupées/en nettoyage/hors service, séjours en cours, réservations en attente. Rafraîchi à chaque appel (pas de cache).\n","operationId":"vueJour","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VueOperationnelle"}}}}}}},"/config":{"get":{"tags":["Configuration métier"],"summary":"Configuration métier — tous les paramètres (groupés par catégorie)","description":"Retourne les 34 paramètres métier groupés par catégorie : FINANCIER (taux USD/CDF, TVA...), ANNULATION, SEJOUR, NOTIFICATION, SECURITE, SYSTEME. Tous les employés connectés peuvent lire. Modification réservée SUPER_ADMIN.\n","operationId":"findAll_4","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/ConfigMetierResponse"}}}}}}}}},"/config/parametres":{"get":{"tags":["Configuration métier"],"summary":"Liste à plat des paramètres (triés par ordre) — SUPER_ADMIN","description":"Écran « Configuration globale » : tous les paramètres de config_metier\ntriés par `ordre` croissant. Réservé au SUPER_ADMIN.\n","operationId":"liste","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConfigMetierResponse"}}}}}}}},"/config/categorie/{categorie}":{"get":{"tags":["Configuration métier"],"summary":"Paramètres d'une catégorie (FINANCIER, ANNULATION, SEJOUR, ...)","operationId":"findByCategorie","parameters":[{"name":"categorie","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConfigMetierResponse"}}}}}}}},"/commandes/{id}":{"get":{"tags":["Restaurant & Bar"],"operationId":"findById_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommandeResponse"}}}}}}},"/commandes/site/{siteId}/ouvertes":{"get":{"tags":["Restaurant & Bar"],"operationId":"findOuvertes","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommandeResponse"}}}}}}}},"/commandes/me":{"get":{"tags":["Restaurant & Bar"],"summary":"File cuisine du cuisinier connecté — commandes OUVERTE + EN_PREPARATION (FIFO)","operationId":"maFileCuisine","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommandeResponse"}}}}}}}},"/commandes/me/historique":{"get":{"tags":["Restaurant & Bar"],"summary":"Historique du jour du cuisinier connecté — commandes SERVIE depuis minuit","operationId":"monHistoriqueCuisine","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommandeResponse"}}}}}}}},"/clients/{id}/reservations":{"get":{"tags":["Clients"],"summary":"Historique des réservations d'un client","operationId":"findReservations","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}}}}}}}},"/clients/{clientId}/documents/{documentId}/lien":{"get":{"tags":["Documents clients"],"summary":"Obtenir un lien de téléchargement sécurisé","description":"Génère une URL pré-signée MinIO pour télécharger le document.\n\n⏱ **Durée de validité : 15 minutes** (configurable via `DOCUMENT_LIEN_TTL_MINUTES`)\n\nL'URL est à usage unique temporaire — ne jamais la partager ni la stocker.\nChaque appel génère un nouveau lien.\n","operationId":"genererLien","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}}}},"/clients/{clientId}/documents/non-verifies":{"get":{"tags":["Documents clients"],"summary":"Documents en attente de vérification","description":"Retourne tous les documents uploadés mais pas encore vérifiés par un employé.","operationId":"findNonVerifies","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DocumentResponse"}}}}}}}},"/clients/pays":{"get":{"tags":["Clients"],"summary":"Liste des pays (ISO alpha-3 + nom FR) pour liste déroulante","operationId":"pays","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/chambres/statuts":{"get":{"tags":["Chambres"],"summary":"Liste des statuts de chambre (liste déroulante)","operationId":"statuts","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnumOptionResponse"}}}}}}}},"/chambres/site/{siteId}":{"get":{"tags":["Chambres"],"operationId":"findBySite_6","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChambreResponse"}}}}}}}},"/chambres/site/{siteId}/libres":{"get":{"tags":["Chambres"],"operationId":"findLibres","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChambreResponse"}}}}}}}},"/chambres/admin":{"get":{"tags":["Chambres"],"summary":"Toutes les chambres (tous sites) — module admin","operationId":"findAllForAdmin_2","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChambreResponse"}}}}}}}},"/avis/type-chambre/{typeChambreId}":{"get":{"tags":["Avis clients"],"summary":"Avis validés d'un type de chambre","operationId":"findByTypeChambre","parameters":[{"name":"typeChambreId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageAvisClient"}}}}}}},"/avis/site/{siteId}":{"get":{"tags":["Avis clients"],"summary":"Avis validés d'un site — paginés","description":"Retourne les avis validés par l'équipe, du plus récent au plus ancien.","operationId":"findBySite_7","parameters":[{"name":"siteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageAvisClient"}}}}}}},"/avis/me":{"get":{"tags":["Avis clients"],"summary":"Mes avis (client connecté)","description":"Avis soumis par le client, du plus récent au plus ancien (validés ou en attente).","operationId":"mesAvis","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AvisResponse"}}}}}}}},"/avis/en-attente":{"get":{"tags":["Avis clients"],"summary":"Avis en attente de validation","operationId":"findEnAttente","parameters":[{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageAvisClient"}}}}}}},"/auth/me":{"get":{"tags":["Authentification"],"summary":"Profil de l'utilisateur connecté","operationId":"me","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}}}}},"/audit":{"get":{"tags":["Audit trail"],"summary":"Journal d'audit global paginé","operationId":"findAll_5","parameters":[{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageAuditLog"}}}}}}},"/audit/entite/{entite}/{entiteId}":{"get":{"tags":["Audit trail"],"summary":"Historique d'une entité spécifique","operationId":"findByEntite","parameters":[{"name":"entite","in":"path","required":true,"schema":{"type":"string"}},{"name":"entiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditLog"}}}}}}}},"/audit/employe/{employeId}":{"get":{"tags":["Audit trail"],"summary":"Actions d'un employé","operationId":"findByEmploye","parameters":[{"name":"employeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"pageable","in":"query","required":true,"schema":{"$ref":"#/components/schemas/Pageable"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageAuditLog"}}}}}}},"/audit/action/{action}":{"get":{"tags":["Audit trail"],"summary":"Dernières actions d'un type donné (30 derniers jours)","operationId":"findByAction","parameters":[{"name":"action","in":"path","required":true,"schema":{"type":"string"}},{"name":"jours","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":30}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditLog"}}}}}}}},"/annulations/simuler/{reservationId}":{"get":{"tags":["Annulations"],"summary":"Simule la pénalité d'annulation sans annuler","operationId":"simuler","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SimulationAnnulationResponse"}}}}}}},"/push/unregister":{"delete":{"tags":["Push Notifications"],"summary":"Désinscrire un appareil des push notifications","description":"À appeler lors de la déconnexion pour ne plus recevoir de notifications.","operationId":"unregister","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/planning/{id}":{"delete":{"tags":["Planning shifts"],"summary":"Supprimer un shift planifié","operationId":"supprimer","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/notifications/{id}":{"delete":{"tags":["Notifications"],"operationId":"supprimer_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/extras/{extraId}":{"delete":{"tags":["Extras"],"summary":"Supprime un extra non encore facturé","operationId":"supprimer_2","parameters":[{"name":"extraId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/clients/{clientId}/documents/{documentId}":{"delete":{"tags":["Documents clients"],"summary":"Supprimer un document","description":"Supprime le document de MinIO et désactive l'entrée en base. Irréversible.","operationId":"supprimer_3","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"}}}},"/clients/{clientId}/blacklist/{blacklistId}":{"delete":{"tags":["Blacklist clients"],"summary":"Lever le blacklist (désactiver l'entrée)","operationId":"lever","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"blacklistId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BlacklistResponse"}}}}}}}},"components":{"schemas":{"UpdateTypeChambreRequest":{"type":"object","properties":{"nom":{"type":"string"},"description":{"type":"string"},"capacite":{"type":"integer","format":"int32"},"prixNuit":{"type":"number"},"prixSemaine":{"type":"number"},"prixMois":{"type":"number"},"superficieM2":{"type":"integer","format":"int32"},"vue":{"type":"string"},"nbLits":{"type":"integer","format":"int32"},"typeLit":{"type":"string"},"actif":{"type":"boolean"}}},"TypeChambreResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"nom":{"type":"string"},"description":{"type":"string"},"capacite":{"type":"integer","format":"int32"},"prixNuit":{"type":"number"},"prixSemaine":{"type":"number"},"prixMois":{"type":"number"},"actif":{"type":"boolean"},"superficieM2":{"type":"integer","format":"int32"},"vue":{"type":"string"},"nbLits":{"type":"integer","format":"int32"},"typeLit":{"type":"string"},"noteMoyenne":{"type":"number"},"nbAvis":{"type":"integer","format":"int32"},"nbChambres":{"type":"integer","format":"int64"},"photoPrincipaleUrl":{"type":"string"}}},"UpdateSitePhotoRequest":{"type":"object","properties":{"titre":{"maxLength":200,"minLength":0,"type":"string"},"categorie":{"maxLength":30,"minLength":0,"type":"string"},"ordre":{"type":"integer","format":"int32"},"principale":{"type":"boolean"},"altText":{"maxLength":200,"minLength":0,"type":"string"}}},"TypeChambrePhotoResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"titre":{"type":"string"},"categorie":{"type":"string"},"ordre":{"type":"integer","format":"int32"},"principale":{"type":"boolean"},"altText":{"type":"string"},"url":{"type":"string"}}},"SiteEquipementsRequest":{"type":"object","properties":{"equipementIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"EquipementResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nom":{"type":"string"},"icone":{"type":"string"},"categorie":{"type":"string"},"actif":{"type":"boolean"}}},"UpdateSiteRequest":{"required":["adresse","nom"],"type":"object","properties":{"nom":{"maxLength":100,"minLength":0,"type":"string"},"adresse":{"type":"string"},"ville":{"maxLength":100,"minLength":0,"type":"string"},"province":{"maxLength":100,"minLength":0,"type":"string"},"pays":{"maxLength":50,"minLength":0,"type":"string"},"telephone":{"maxLength":20,"minLength":0,"type":"string"},"email":{"maxLength":150,"minLength":0,"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"actif":{"type":"boolean"}}},"SiteResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nom":{"type":"string"},"adresse":{"type":"string"},"ville":{"type":"string"},"province":{"type":"string"},"pays":{"type":"string"},"telephone":{"type":"string"},"email":{"type":"string"},"actif":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"photoPrincipaleUrl":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"nbChambres":{"type":"integer","format":"int64"},"nbTypesChambre":{"type":"integer","format":"int64"}}},"SitePhotoResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"titre":{"type":"string"},"categorie":{"type":"string"},"ordre":{"type":"integer","format":"int32"},"principale":{"type":"boolean"},"altText":{"type":"string"},"url":{"type":"string"}}},"UpdatePreferenceNotificationRequest":{"type":"object","properties":{"pushActif":{"type":"boolean"},"categoriesDesactivees":{"type":"array","items":{"type":"string"}}}},"PreferenceNotificationResponse":{"type":"object","properties":{"pushActif":{"type":"boolean"},"categoriesDesactivees":{"type":"array","items":{"type":"string"}}}},"UpsertEquipementRequest":{"required":["categorie","code","nom"],"type":"object","properties":{"code":{"maxLength":50,"minLength":0,"type":"string"},"nom":{"maxLength":100,"minLength":0,"type":"string"},"icone":{"maxLength":50,"minLength":0,"type":"string"},"categorie":{"maxLength":30,"minLength":0,"type":"string"},"actif":{"type":"boolean"}}},"UpdateEmployeRequest":{"required":["nomComplet","poste","roleSysteme"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"nomComplet":{"type":"string"},"email":{"type":"string"},"telephone":{"type":"string"},"poste":{"type":"string"},"roleSysteme":{"type":"string","enum":["SUPER_ADMIN","GESTIONNAIRE","RECEPTIONNISTE","FEMME_DE_CHAMBRE","CUISINIER","SECURITE","TECHNICIEN"]},"actif":{"type":"boolean"},"dateEmbauche":{"type":"string","format":"date"}}},"EmployeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"nomComplet":{"type":"string"},"email":{"type":"string"},"telephone":{"type":"string"},"poste":{"type":"string"},"roleSysteme":{"type":"string","enum":["SUPER_ADMIN","GESTIONNAIRE","RECEPTIONNISTE","FEMME_DE_CHAMBRE","CUISINIER","SECURITE","TECHNICIEN"]},"actif":{"type":"boolean"},"photoUrl":{"type":"string"},"dateEmbauche":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time"}}},"UpdateConfigRequest":{"required":["valeur"],"type":"object","properties":{"valeur":{"type":"string"},"libelle":{"type":"string"},"description":{"type":"string"},"valeurDefaut":{"type":"string"}}},"ConfigMetierResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"cle":{"type":"string"},"valeur":{"type":"string"},"typeValeur":{"type":"string"},"categorie":{"type":"string"},"libelle":{"type":"string"},"description":{"type":"string"},"valeurDefaut":{"type":"string"},"modifiable":{"type":"boolean"},"ordre":{"type":"integer","format":"int32"},"updatedAt":{"type":"string","format":"date-time"},"updatedByNom":{"type":"string"}}},"UpdateConfigBatchRequest":{"required":["parametres"],"type":"object","properties":{"parametres":{"type":"object","additionalProperties":{"type":"string"}},"employeId":{"type":"string","format":"uuid"}}},"CreateClientRequest":{"required":["nomComplet"],"type":"object","properties":{"nomComplet":{"maxLength":200,"minLength":0,"type":"string"},"email":{"maxLength":150,"minLength":0,"type":"string"},"telephone":{"maxLength":30,"minLength":0,"type":"string"},"pays":{"type":"string"},"ville":{"type":"string"},"typePiece":{"type":"string","enum":["PASSEPORT","CARTE_NATIONALE","PERMIS_CONDUIRE","AUTRE"]},"numeroPiece":{"type":"string"},"dateNaissance":{"type":"string","format":"date"},"vip":{"type":"boolean"},"notes":{"type":"string"}}},"ClientResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nomComplet":{"type":"string"},"email":{"type":"string"},"telephone":{"type":"string"},"pays":{"type":"string"},"ville":{"type":"string"},"typePiece":{"type":"string","enum":["PASSEPORT","CARTE_NATIONALE","PERMIS_CONDUIRE","AUTRE"]},"numeroPiece":{"type":"string"},"dateNaissance":{"type":"string","format":"date"},"vip":{"type":"boolean"},"actif":{"type":"boolean"},"emailVerifie":{"type":"boolean"},"photoUrl":{"type":"string"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"UpdateChambreRequest":{"type":"object","properties":{"typeChambreId":{"type":"string","format":"uuid"},"numero":{"type":"string"},"etage":{"type":"integer","format":"int32"},"statut":{"type":"string","enum":["LIBRE","OCCUPEE","EN_NETTOYAGE","HORS_SERVICE","RESERVEE"]},"notes":{"type":"string"}}},"ChambreResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"typeChambreId":{"type":"string","format":"uuid"},"typeChambreNom":{"type":"string"},"numero":{"type":"string"},"etage":{"type":"integer","format":"int32"},"statut":{"type":"string","enum":["LIBRE","OCCUPEE","EN_NETTOYAGE","HORS_SERVICE","RESERVEE"]},"notes":{"type":"string"},"derniereInspection":{"type":"string","format":"date-time"},"photoTypeUrl":{"type":"string"},"prixNuit":{"type":"number"},"capacite":{"type":"integer","format":"int32"}}},"CreateTypeChambreRequest":{"required":["nom","prixNuit","siteId"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"nom":{"type":"string"},"description":{"type":"string"},"capacite":{"type":"integer","format":"int32"},"prixNuit":{"type":"number"},"prixSemaine":{"type":"number"},"prixMois":{"type":"number"},"superficieM2":{"type":"integer","format":"int32"},"vue":{"type":"string"},"nbLits":{"type":"integer","format":"int32"},"typeLit":{"type":"string"}}},"PublierTauxChangeRequest":{"required":["dateEffective","taux"],"type":"object","properties":{"taux":{"type":"number"},"dateEffective":{"type":"string","format":"date"},"employeId":{"type":"string","format":"uuid"},"notes":{"type":"string"}}},"TauxChangeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deviseSource":{"type":"string"},"deviseCible":{"type":"string"},"taux":{"type":"number"},"dateEffective":{"type":"string","format":"date"},"source":{"type":"string"},"actif":{"type":"boolean"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"MouvementStockRequest":{"required":["quantite","stockArticleId","typeMouvement"],"type":"object","properties":{"stockArticleId":{"type":"string","format":"uuid"},"employeId":{"type":"string","format":"uuid"},"typeMouvement":{"type":"string","enum":["ENTREE","SORTIE","AJUSTEMENT","PERTE"]},"quantite":{"type":"number"},"motif":{"type":"string"}}},"StockArticleResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"nom":{"type":"string"},"categorie":{"type":"string"},"unite":{"type":"string"},"quantiteActuelle":{"type":"number"},"seuilAlerte":{"type":"number"},"prixUnitaire":{"type":"number"},"actif":{"type":"boolean"},"enAlerte":{"type":"boolean"}}},"CreateStockArticleRequest":{"required":["nom","siteId"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"nom":{"type":"string"},"categorie":{"type":"string"},"unite":{"type":"string"},"quantiteActuelle":{"type":"number"},"seuilAlerte":{"type":"number"},"prixUnitaire":{"type":"number"}}},"CreateSiteRequest":{"required":["adresse","nom"],"type":"object","properties":{"nom":{"maxLength":100,"minLength":0,"type":"string"},"adresse":{"type":"string"},"ville":{"maxLength":100,"minLength":0,"type":"string"},"province":{"maxLength":100,"minLength":0,"type":"string"},"pays":{"maxLength":50,"minLength":0,"type":"string"},"telephone":{"maxLength":20,"minLength":0,"type":"string"},"email":{"maxLength":150,"minLength":0,"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"}}},"AccesRfidResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"chambreNumero":{"type":"string"},"typeCarte":{"type":"string"},"porteurNom":{"type":"string"},"accesAutorise":{"type":"boolean"},"motifRefus":{"type":"string"},"horodatage":{"type":"string","format":"date-time"}}},"EncoderCarteRequest":{"required":["typeCarte"],"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"employeId":{"type":"string","format":"uuid"},"typeCarte":{"type":"string","enum":["CLIENT","MENAGE","MAINTENANCE","SECURITE","ADMINISTRATION"]},"valideDu":{"type":"string","format":"date-time"},"valideJusquAu":{"type":"string","format":"date-time"}}},"CarteRfidResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"codeCarte":{"type":"string"},"typeCarte":{"type":"string"},"active":{"type":"boolean"},"chambreNumero":{"type":"string"},"reservationId":{"type":"string","format":"uuid"},"porteurNom":{"type":"string"},"valideDu":{"type":"string","format":"date-time"},"valideJusquAu":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"CreateReservationRequest":{"required":["chambreId","clientId","dateArrivee","dateDepart","prixParNuit","siteId"],"type":"object","properties":{"clientId":{"type":"string","description":"UUID du client","format":"uuid","example":"0c8200a5-cda4-4688-b00a-d3ad19c3434e"},"siteId":{"type":"string","description":"UUID du site hôtelier","format":"uuid","example":"08278930-7b6c-4903-8660-c8a46a3ce089"},"chambreId":{"type":"string","description":"UUID de la chambre","format":"uuid","example":"4111a94c-dabc-45dd-84be-7717573d8800"},"source":{"type":"string","description":"Canal d'origine de la réservation","example":"WHATSAPP","enum":["RECEPTION","SITE_WEB","WHATSAPP","BOOKING_COM","AIRBNB","EXPEDIA","TELEPHONE","AUTRE"],"default":"RECEPTION"},"dateArrivee":{"type":"string","description":"Date d'arrivée du client","format":"date","example":"2026-07-15"},"dateDepart":{"type":"string","description":"Date de départ du client (doit être après dateArrivee)","format":"date","example":"2026-07-20"},"heureArrivee":{"$ref":"#/components/schemas/LocalTime"},"heureDepart":{"$ref":"#/components/schemas/LocalTime"},"prixParNuit":{"type":"number","description":"Prix par nuit en USD","example":45.0},"acompte":{"type":"number","description":"Montant de l'acompte versé en USD","example":50.0,"default":0},"refExterne":{"type":"string","description":"Référence externe (numéro Booking.com, Airbnb, etc.)","example":"BK-2026-98765"},"notes":{"type":"string","description":"Notes internes sur la réservation"}},"description":"Données pour créer une réservation. Les conflits de dates et la blacklist sont vérifiés automatiquement."},"LocalTime":{"type":"object","properties":{"hour":{"type":"integer","format":"int32"},"minute":{"type":"integer","format":"int32"},"second":{"type":"integer","format":"int32"},"nano":{"type":"integer","format":"int32"}},"description":"Heure de départ prévue","example":"12:00"},"ReservationResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"clientId":{"type":"string","format":"uuid"},"clientPrenom":{"type":"string"},"clientNom":{"type":"string"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"chambreId":{"type":"string","format":"uuid"},"chambreNumero":{"type":"string"},"typeChambreId":{"type":"string","format":"uuid"},"typeChambreNom":{"type":"string"},"source":{"type":"string","enum":["RECEPTION","SITE_WEB","WHATSAPP","BOOKING_COM","AIRBNB","EXPEDIA","TELEPHONE","AUTRE"]},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"heureArrivee":{"$ref":"#/components/schemas/LocalTime"},"heureDepart":{"$ref":"#/components/schemas/LocalTime"},"statut":{"type":"string","enum":["EN_ATTENTE","CONFIRMEE","CHECKED_IN","CHECKED_OUT","ANNULEE","NO_SHOW","EXPIREE"]},"prixParNuit":{"type":"number"},"nombreNuits":{"type":"integer","format":"int32"},"prixTotal":{"type":"number"},"acompte":{"type":"number"},"cautionMontant":{"type":"number"},"cautionStatut":{"type":"string"},"penaliteAnnulation":{"type":"number"},"refExterne":{"type":"string"},"checkinAt":{"type":"string","format":"date-time"},"checkoutAt":{"type":"string","format":"date-time"},"expireLe":{"type":"string","format":"date-time"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"PayerReservationRequest":{"type":"object","properties":{"gateway":{"type":"string","enum":["FLUTTERWAVE","MPESA","AIRTEL_MONEY","ORANGE_MONEY","AFRIMONEY","ILLICOCASH","PAYPAL","MAXICASH","MANUAL"]},"total":{"type":"boolean"}},"description":"Paiement d'une réservation (acompte ou total)."},"PaiementLienResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"gateway":{"type":"string"},"txRef":{"type":"string"},"montant":{"type":"number"},"devise":{"type":"string"},"lien":{"type":"string"},"statut":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}},"CreateReservationReceptionRequest":{"required":["clientId","dateArrivee","dateDepart","nombrePersonnes","siteId","typeChambreId"],"type":"object","properties":{"clientId":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"typeChambreId":{"type":"string","format":"uuid"},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"nombrePersonnes":{"type":"integer","format":"int32","example":2},"codePromo":{"type":"string","description":"Code promotionnel éventuel"},"notes":{"type":"string","description":"Notes internes"},"confirmer":{"type":"boolean","description":"Créer directement en CONFIRMEE"}},"description":"Création d'une réservation côté réception (type-basée)."},"CreateReservationClientRequest":{"required":["dateArrivee","dateDepart","nombrePersonnes","siteId","typeChambreId"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"typeChambreId":{"type":"string","format":"uuid"},"dateArrivee":{"type":"string","format":"date","example":"2026-07-15"},"dateDepart":{"type":"string","format":"date","example":"2026-07-20"},"nombrePersonnes":{"type":"integer","format":"int32","example":2},"codePromo":{"type":"string","description":"Code promotionnel éventuel","example":"JEANFE10"},"notes":{"type":"string","description":"Demandes spéciales du client"}},"description":"Réservation client : seul le type de chambre, le site, les dates et le nombre de personnes sont fournis. Prix, chambre et client sont déterminés côté serveur."},"DevisReservationRequest":{"required":["dateArrivee","dateDepart","nombrePersonnes","siteId","typeChambreId"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"typeChambreId":{"type":"string","format":"uuid"},"dateArrivee":{"type":"string","format":"date","example":"2026-07-15"},"dateDepart":{"type":"string","format":"date","example":"2026-07-20"},"nombrePersonnes":{"type":"integer","format":"int32","example":2},"codePromo":{"type":"string","description":"Code promotionnel éventuel","example":"JEANFE10"}},"description":"Demande de devis (aucune réservation n'est créée)."},"DevisReservationResponse":{"type":"object","properties":{"disponible":{"type":"boolean"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"typeChambreId":{"type":"string","format":"uuid"},"typeChambreNom":{"type":"string"},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"nombreNuits":{"type":"integer","format":"int64"},"nombrePersonnes":{"type":"integer","format":"int32"},"prixParNuit":{"type":"number"},"prixTotal":{"type":"number"},"caution":{"type":"number"},"acompteAttendu":{"type":"number"},"politiqueNom":{"type":"string"},"penaliteEstimee":{"type":"number"},"descriptionRemises":{"type":"string"},"nbChambresRestantes":{"type":"integer","format":"int64"},"devisExpireLe":{"type":"string","format":"date-time"},"message":{"type":"string"}}},"CreateReclamationRequest":{"required":["message","sujet"],"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"sujet":{"maxLength":150,"minLength":0,"type":"string"},"message":{"type":"string"}}},"ReclamationResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reservationId":{"type":"string","format":"uuid"},"clientNom":{"type":"string"},"sujet":{"type":"string"},"message":{"type":"string"},"statut":{"type":"string"},"reponse":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"RegisterDeviceRequest":{"required":["platform","token"],"type":"object","properties":{"token":{"type":"string","description":"FCM registration token de l'appareil","example":"fGH8xyz..."},"platform":{"type":"string","description":"Plateforme","example":"ANDROID","enum":["ANDROID","IOS","WEB"]},"appVersion":{"type":"string","description":"Version de l'application","example":"1.2.3"},"deviceModel":{"type":"string","description":"Modèle de l'appareil","example":"Samsung Galaxy S24"}},"description":"Requête d'enregistrement d'un appareil FCM"},"PointerRequest":{"type":"object","properties":{"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"}}},"PresenceResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"employeNom":{"type":"string"},"datePresence":{"type":"string"},"heureEntree":{"type":"string","format":"date-time"},"heureSortie":{"type":"string","format":"date-time"},"notes":{"type":"string"}}},"CreateShiftRequest":{"required":["dateShift","employeId","heureDebut","heureFin","siteId"],"type":"object","properties":{"employeId":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"dateShift":{"type":"string","format":"date"},"heureDebut":{"$ref":"#/components/schemas/LocalTime"},"heureFin":{"$ref":"#/components/schemas/LocalTime"},"posteCouvre":{"type":"string"},"notes":{"type":"string"},"creePar":{"type":"string","format":"uuid"}}},"ShiftResponse":{"type":"object","properties":{"id":{"type":"string"},"dateShift":{"type":"string"},"heureDebut":{"type":"string"},"heureFin":{"type":"string"},"statut":{"type":"string"},"siteNom":{"type":"string"},"employeNom":{"type":"string"},"employeId":{"type":"string"},"posteCouvre":{"type":"string"},"notes":{"type":"string"}}},"CreatePaiementRequest":{"required":["factureId","modePaiement","montant"],"type":"object","properties":{"factureId":{"type":"string","format":"uuid"},"modePaiement":{"type":"string","enum":["ESPECES","CARTE_BANCAIRE","PAYPAL","MPESA","AIRTEL_MONEY","ORANGE_MONEY","AFRIMONEY","ILLICOCASH","LIEN_PAIEMENT","VIREMENT","AUTRE"]},"montant":{"type":"number"},"devise":{"type":"string"},"refTransaction":{"type":"string"},"notes":{"type":"string"}}},"PaiementResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"factureId":{"type":"string","format":"uuid"},"modePaiement":{"type":"string","enum":["ESPECES","CARTE_BANCAIRE","PAYPAL","MPESA","AIRTEL_MONEY","ORANGE_MONEY","AFRIMONEY","ILLICOCASH","LIEN_PAIEMENT","VIREMENT","AUTRE"]},"montant":{"type":"number"},"devise":{"type":"string"},"statut":{"type":"string","enum":["EN_ATTENTE","CONFIRME","ECHEC","REMBOURSE"]},"refTransaction":{"type":"string"},"notes":{"type":"string"},"datePaiement":{"type":"string","format":"date-time"}}},"EnvoyerNotificationRequest":{"required":["categorie","cible","message","titre"],"type":"object","properties":{"titre":{"type":"string"},"message":{"type":"string"},"categorie":{"type":"string","enum":["RESERVATION","PAIEMENT","CHECK_IN_OUT","MENAGE","MAINTENANCE","SECURITE","STOCK","RESTAURATION","WIFI","SYSTEME","SUPPORT","ALERTE_CRITIQUE"]},"priorite":{"type":"string","enum":["INFORMATION","NORMAL","IMPORTANT","CRITIQUE"]},"cible":{"type":"string"},"destinataireId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["SUPER_ADMIN","GESTIONNAIRE","RECEPTIONNISTE","FEMME_DE_CHAMBRE","CUISINIER","SECURITE","TECHNICIEN"]},"siteId":{"type":"string","format":"uuid"},"lien":{"type":"string"}}},"FactureResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reservationId":{"type":"string","format":"uuid"},"clientId":{"type":"string","format":"uuid"},"clientPrenom":{"type":"string"},"clientNom":{"type":"string"},"numeroFacture":{"type":"string"},"dateEmission":{"type":"string","format":"date-time"},"montantHt":{"type":"number"},"tauxTva":{"type":"number"},"montantTva":{"type":"number"},"montantTtc":{"type":"number"},"statut":{"type":"string","enum":["BROUILLON","EMISE","PARTIELLEMENT_PAYEE","PAYEE","ANNULEE"]},"notes":{"type":"string"},"lignes":{"type":"array","items":{"$ref":"#/components/schemas/LigneFactureResponse"}},"createdAt":{"type":"string","format":"date-time"}}},"LigneFactureResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"description":{"type":"string"},"quantite":{"type":"integer","format":"int32"},"prixUnitaire":{"type":"number"},"montantTotal":{"type":"number"}}},"CreateTicketRequest":{"required":["description","priorite","siteId","titre","typePanne"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"chambreId":{"type":"string","format":"uuid"},"signaleParId":{"type":"string","format":"uuid"},"typePanne":{"type":"string"},"priorite":{"type":"string","enum":["BASSE","NORMALE","HAUTE","URGENTE"]},"titre":{"type":"string"},"description":{"type":"string"},"chambreHorsService":{"type":"boolean"}}},"TicketResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"titre":{"type":"string"},"description":{"type":"string"},"typePanne":{"type":"string"},"priorite":{"type":"string"},"statut":{"type":"string"},"siteId":{"type":"string","format":"uuid"},"chambreNumero":{"type":"string"},"chambreHorsService":{"type":"boolean"},"signaleParNom":{"type":"string"},"assigneANom":{"type":"string"},"dateResolution":{"type":"string","format":"date-time"},"coutReparation":{"type":"number"},"notesResolution":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"ResoudreTicketRequest":{"required":["notesResolution"],"type":"object","properties":{"notesResolution":{"type":"string"},"coutReparation":{"type":"number"},"employeId":{"type":"string","format":"uuid"}}},"CreateHousekeepingRequest":{"required":["chambreId"],"type":"object","properties":{"chambreId":{"type":"string","format":"uuid"},"employeId":{"type":"string","format":"uuid"},"statut":{"type":"string","enum":["A_NETTOYER","EN_COURS","NETTOYE","INSPECTE","INCIDENT"]},"typeNettoyage":{"type":"string"},"observations":{"type":"string"}}},"HousekeepingResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"chambreId":{"type":"string","format":"uuid"},"chambreNumero":{"type":"string"},"employeId":{"type":"string","format":"uuid"},"employeNom":{"type":"string"},"statut":{"type":"string","enum":["A_NETTOYER","EN_COURS","NETTOYE","INSPECTE","INCIDENT"]},"typeNettoyage":{"type":"string"},"debut":{"type":"string","format":"date-time"},"fin":{"type":"string","format":"date-time"},"observations":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"CreateGroupeRequest":{"required":["chambreIds","contactClientId","contactNom","dateArrivee","dateDepart","nom","siteId"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"nom":{"type":"string"},"contactClientId":{"type":"string","format":"uuid"},"contactNom":{"type":"string"},"contactEmail":{"type":"string"},"contactTelephone":{"type":"string"},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"chambreIds":{"type":"array","items":{"type":"string","format":"uuid"}},"remisePct":{"type":"number"},"factureUnique":{"type":"boolean"},"employeId":{"type":"string","format":"uuid"}}},"GroupeLigneResponse":{"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"chambreNumero":{"type":"string"},"typeChambreNom":{"type":"string"},"statut":{"type":"string"},"prixTotal":{"type":"number"}}},"GroupeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"nom":{"type":"string"},"contactNom":{"type":"string"},"contactEmail":{"type":"string"},"contactTelephone":{"type":"string"},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"remisePct":{"type":"number"},"factureUnique":{"type":"boolean"},"acompteVerse":{"type":"number"},"statut":{"type":"string"},"notes":{"type":"string"},"nombreChambres":{"type":"integer","format":"int32"},"prixTotal":{"type":"number"},"createdAt":{"type":"string","format":"date-time"},"lignes":{"type":"array","items":{"$ref":"#/components/schemas/GroupeLigneResponse"}}}},"CreateGroupeParTypeRequest":{"required":["contactClientId","contactNom","dateArrivee","dateDepart","nom","quantite","siteId","typeChambreId"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"nom":{"type":"string"},"contactClientId":{"type":"string","format":"uuid"},"contactNom":{"type":"string"},"contactEmail":{"type":"string"},"contactTelephone":{"type":"string"},"typeChambreId":{"type":"string","format":"uuid"},"quantite":{"type":"integer","format":"int32","example":5},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"remisePct":{"type":"number"},"factureUnique":{"type":"boolean"},"employeId":{"type":"string","format":"uuid"}},"description":"Réservation de groupe par type de chambre (quantité)."},"CreateFactureRequest":{"required":["clientId","lignes","reservationId"],"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"clientId":{"type":"string","format":"uuid"},"tauxTva":{"type":"number"},"notes":{"type":"string"},"lignes":{"type":"array","items":{"$ref":"#/components/schemas/LigneFactureRequest"}}}},"LigneFactureRequest":{"required":["description","prixUnitaire"],"type":"object","properties":{"description":{"type":"string"},"quantite":{"type":"integer","format":"int32"},"prixUnitaire":{"type":"number"}}},"AjouterExtraRequest":{"required":["categorie","libelle","prixUnitaire"],"type":"object","properties":{"employeId":{"type":"string","format":"uuid"},"categorie":{"type":"string","enum":["ROOM_SERVICE","MINIBAR","BLANCHISSERIE","TELEPHONE","PARKING","SPA","AUTRE"]},"libelle":{"type":"string"},"quantite":{"type":"integer","format":"int32"},"prixUnitaire":{"type":"number"},"notes":{"type":"string"}}},"ExtraResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reservationId":{"type":"string","format":"uuid"},"categorie":{"type":"string","enum":["ROOM_SERVICE","MINIBAR","BLANCHISSERIE","TELEPHONE","PARKING","SPA","AUTRE"]},"libelle":{"type":"string"},"quantite":{"type":"integer","format":"int32"},"prixUnitaire":{"type":"number"},"montantTotal":{"type":"number"},"devise":{"type":"string"},"facture":{"type":"boolean"},"notes":{"type":"string"},"horodatage":{"type":"string","format":"date-time"}}},"CreateEmployeRequest":{"required":["motDePasse","nomComplet","poste","roleSysteme"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"nomComplet":{"type":"string"},"email":{"type":"string"},"telephone":{"type":"string"},"poste":{"type":"string"},"roleSysteme":{"type":"string","enum":["SUPER_ADMIN","GESTIONNAIRE","RECEPTIONNISTE","FEMME_DE_CHAMBRE","CUISINIER","SECURITE","TECHNICIEN"]},"motDePasse":{"maxLength":2147483647,"minLength":8,"type":"string"},"dateEmbauche":{"type":"string","format":"date"}}},"CreateCommandeRequest":{"required":["lignes","siteId"],"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"employeId":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"tableNumero":{"type":"string"},"lignes":{"type":"array","items":{"$ref":"#/components/schemas/LigneCommandeRequest"}}}},"LigneCommandeRequest":{"required":["article","prixUnitaire"],"type":"object","properties":{"article":{"type":"string"},"quantite":{"type":"integer","format":"int32"},"prixUnitaire":{"type":"number"},"notes":{"type":"string"}}},"CommandeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reservationId":{"type":"string","format":"uuid"},"employeId":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"tableNumero":{"type":"string"},"statut":{"type":"string","enum":["OUVERTE","EN_PREPARATION","SERVIE","ANNULEE"]},"montantTotal":{"type":"number"},"factureeChambre":{"type":"boolean"},"horodatage":{"type":"string","format":"date-time"},"lignes":{"type":"array","items":{"$ref":"#/components/schemas/LigneCommandeResponse"}}}},"LigneCommandeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"article":{"type":"string"},"quantite":{"type":"integer","format":"int32"},"prixUnitaire":{"type":"number"},"montantTotal":{"type":"number"},"notes":{"type":"string"}}},"Client":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"nomComplet":{"type":"string"},"email":{"type":"string"},"motDePasse":{"type":"string"},"emailVerifie":{"type":"boolean"},"codeVerif":{"type":"string"},"codeVerifExpire":{"type":"string","format":"date-time"},"photoUrl":{"type":"string"},"telephone":{"type":"string"},"pays":{"type":"string"},"ville":{"type":"string"},"typePiece":{"type":"string","enum":["PASSEPORT","CARTE_NATIONALE","PERMIS_CONDUIRE","AUTRE"]},"numeroPiece":{"type":"string"},"dateNaissance":{"type":"string","format":"date"},"vip":{"type":"boolean"},"actif":{"type":"boolean"},"notes":{"type":"string"},"pointsFidelite":{"type":"integer","format":"int32"},"niveauFidelite":{"type":"string"},"totalNuits":{"type":"integer","format":"int32"},"totalSejours":{"type":"integer","format":"int32"},"tentativesEchec":{"type":"integer","format":"int32"},"verrouilleJusquAu":{"type":"string","format":"date-time"},"nbVerrous":{"type":"integer","format":"int32"}}},"DocumentClient":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"client":{"$ref":"#/components/schemas/Client"},"uploadePar":{"$ref":"#/components/schemas/Employe"},"typeDocument":{"type":"string"},"nomOriginal":{"type":"string"},"mimeType":{"type":"string"},"tailleOctets":{"type":"integer","format":"int64"},"extension":{"type":"string"},"bucketName":{"type":"string"},"cheminObjet":{"type":"string"},"verifie":{"type":"boolean"},"verifiePar":{"$ref":"#/components/schemas/Employe"},"verifieAt":{"type":"string","format":"date-time"},"notesVerification":{"type":"string"},"dateExpiration":{"type":"string","format":"date"},"actif":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"tailleFormatee":{"type":"string"}}},"Employe":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"site":{"$ref":"#/components/schemas/Site"},"nomComplet":{"type":"string"},"email":{"type":"string"},"telephone":{"type":"string"},"poste":{"type":"string"},"roleSysteme":{"type":"string","enum":["SUPER_ADMIN","GESTIONNAIRE","RECEPTIONNISTE","FEMME_DE_CHAMBRE","CUISINIER","SECURITE","TECHNICIEN"]},"motDePasseHash":{"type":"string"},"photoUrl":{"type":"string"},"actif":{"type":"boolean"},"dateEmbauche":{"type":"string","format":"date"},"tentativesEchec":{"type":"integer","format":"int32"},"verrouilleJusquAu":{"type":"string","format":"date-time"},"nbVerrous":{"type":"integer","format":"int32"}}},"Site":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"nom":{"type":"string"},"adresse":{"type":"string"},"ville":{"type":"string"},"province":{"type":"string"},"pays":{"type":"string"},"telephone":{"type":"string"},"email":{"type":"string"},"actif":{"type":"boolean"},"latitude":{"type":"number"},"longitude":{"type":"number"}}},"DocumentResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"typeDocument":{"type":"string"},"nomOriginal":{"type":"string"},"mimeType":{"type":"string"},"tailleOctets":{"type":"integer","format":"int64"},"extension":{"type":"string"},"verifie":{"type":"boolean"},"uploadeParNom":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"BlacklisterClientRequest":{"required":["employeId","gravite","motif"],"type":"object","properties":{"employeId":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"motif":{"type":"string"},"gravite":{"type":"string","enum":["AVERTISSEMENT","MODEREE","GRAVE","INTERDICTION_DEFINITIVE"]},"dateFin":{"type":"string","format":"date-time"},"notesInternes":{"type":"string"}}},"BlacklistResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"motif":{"type":"string"},"gravite":{"type":"string"},"active":{"type":"boolean"},"employeNom":{"type":"string"},"siteNom":{"type":"string"},"dateDebut":{"type":"string","format":"date-time"},"dateFin":{"type":"string","format":"date-time"}}},"CreateChambreRequest":{"required":["numero","siteId","typeChambreId"],"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"typeChambreId":{"type":"string","format":"uuid"},"numero":{"type":"string"},"etage":{"type":"integer","format":"int32"},"statut":{"type":"string","enum":["LIBRE","OCCUPEE","EN_NETTOYAGE","HORS_SERVICE","RESERVEE"]},"notes":{"type":"string"}}},"RetenirCautionRequest":{"required":["montantRetenu","motif"],"type":"object","properties":{"montantRetenu":{"type":"number"},"motif":{"type":"string"},"employeId":{"type":"string","format":"uuid"}}},"CautionResponse":{"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"cautionMontant":{"type":"number"},"cautionStatut":{"type":"string","enum":["NON_REQUISE","EN_ATTENTE","ENCAISSEE","RESTITUEE","RETENUE_PARTIELLE","RETENUE_TOTALE"]},"dateEncaissement":{"type":"string","format":"date-time"},"dateRestitution":{"type":"string","format":"date-time"},"motifRetention":{"type":"string"}}},"DefinirCautionRequest":{"type":"object","properties":{"montant":{"type":"number"}}},"CreateAvisRequest":{"required":["noteGlobale","reservationId"],"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"noteGlobale":{"maximum":5,"minimum":1,"type":"integer","format":"int32"},"noteProprete":{"maximum":5,"minimum":1,"type":"integer","format":"int32"},"noteConfort":{"maximum":5,"minimum":1,"type":"integer","format":"int32"},"notePersonnel":{"maximum":5,"minimum":1,"type":"integer","format":"int32"},"noteRapportQualite":{"maximum":5,"minimum":1,"type":"integer","format":"int32"},"titre":{"maxLength":150,"minLength":0,"type":"string"},"commentaire":{"type":"string"},"recommande":{"type":"boolean"}}},"AvisResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reservationId":{"type":"string","format":"uuid"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"typeChambreId":{"type":"string","format":"uuid"},"typeChambreNom":{"type":"string"},"noteGlobale":{"type":"integer","format":"int32"},"noteProprete":{"type":"integer","format":"int32"},"noteConfort":{"type":"integer","format":"int32"},"notePersonnel":{"type":"integer","format":"int32"},"noteRapportQualite":{"type":"integer","format":"int32"},"titre":{"type":"string"},"commentaire":{"type":"string"},"recommande":{"type":"boolean"},"valide":{"type":"boolean"},"reponseHotel":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"AvisClient":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reservation":{"$ref":"#/components/schemas/Reservation"},"client":{"$ref":"#/components/schemas/Client"},"site":{"$ref":"#/components/schemas/Site"},"typeChambre":{"$ref":"#/components/schemas/TypeChambre"},"noteGlobale":{"type":"integer","format":"int32"},"noteProprete":{"type":"integer","format":"int32"},"noteConfort":{"type":"integer","format":"int32"},"notePersonnel":{"type":"integer","format":"int32"},"noteRapportQualite":{"type":"integer","format":"int32"},"titre":{"type":"string"},"commentaire":{"type":"string"},"recommande":{"type":"boolean"},"valide":{"type":"boolean"},"validePar":{"$ref":"#/components/schemas/Employe"},"valideAt":{"type":"string","format":"date-time"},"reponseHotel":{"type":"string"},"reponsePar":{"$ref":"#/components/schemas/Employe"},"reponseAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"noteCalculee":{"type":"number","format":"double"}}},"Chambre":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"site":{"$ref":"#/components/schemas/Site"},"typeChambre":{"$ref":"#/components/schemas/TypeChambre"},"numero":{"type":"string"},"etage":{"type":"integer","format":"int32"},"statut":{"type":"string","enum":["LIBRE","OCCUPEE","EN_NETTOYAGE","HORS_SERVICE","RESERVEE"]},"notes":{"type":"string"},"derniereInspection":{"type":"string","format":"date-time"}}},"Equipement":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nom":{"type":"string"},"icone":{"type":"string"},"categorie":{"type":"string"},"actif":{"type":"boolean"}}},"PolitiqueAnnulation":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"site":{"$ref":"#/components/schemas/Site"},"nom":{"type":"string"},"description":{"type":"string"},"estDefaut":{"type":"boolean"},"actif":{"type":"boolean"},"regles":{"type":"array","items":{"$ref":"#/components/schemas/RegleAnnulation"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RegleAnnulation":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"politiqueAnnulation":{"$ref":"#/components/schemas/PolitiqueAnnulation"},"delaiJoursMin":{"type":"integer","format":"int32"},"delaiJoursMax":{"type":"integer","format":"int32"},"tauxPenalitePct":{"type":"number"},"description":{"type":"string"},"ordre":{"type":"integer","format":"int32"}}},"Reservation":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"client":{"$ref":"#/components/schemas/Client"},"site":{"$ref":"#/components/schemas/Site"},"chambre":{"$ref":"#/components/schemas/Chambre"},"source":{"type":"string","enum":["RECEPTION","SITE_WEB","WHATSAPP","BOOKING_COM","AIRBNB","EXPEDIA","TELEPHONE","AUTRE"]},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"heureArrivee":{"$ref":"#/components/schemas/LocalTime"},"heureDepart":{"$ref":"#/components/schemas/LocalTime"},"statut":{"type":"string","enum":["EN_ATTENTE","CONFIRMEE","CHECKED_IN","CHECKED_OUT","ANNULEE","NO_SHOW","EXPIREE"]},"prixParNuit":{"type":"number"},"nombreNuits":{"type":"integer","format":"int32"},"prixTotal":{"type":"number"},"acompte":{"type":"number"},"refExterne":{"type":"string"},"checkinAt":{"type":"string","format":"date-time"},"checkoutAt":{"type":"string","format":"date-time"},"expireLe":{"type":"string","format":"date-time"},"notes":{"type":"string"},"politiqueAnnulation":{"$ref":"#/components/schemas/PolitiqueAnnulation"},"penaliteAnnulation":{"type":"number"},"cautionMontant":{"type":"number"},"cautionStatut":{"type":"string","enum":["NON_REQUISE","EN_ATTENTE","ENCAISSEE","RESTITUEE","RETENUE_PARTIELLE","RETENUE_TOTALE"]},"cautionDateEncaissement":{"type":"string","format":"date-time"},"cautionDateRestitution":{"type":"string","format":"date-time"},"cautionMotifRetention":{"type":"string"}}},"TypeChambre":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"site":{"$ref":"#/components/schemas/Site"},"nom":{"type":"string"},"description":{"type":"string"},"capacite":{"type":"integer","format":"int32"},"prixNuit":{"type":"number"},"prixSemaine":{"type":"number"},"prixMois":{"type":"number"},"actif":{"type":"boolean"},"nbLits":{"type":"integer","format":"int32"},"typeLit":{"type":"string"},"superficieM2":{"type":"integer","format":"int32"},"vue":{"type":"string"},"noteMoyenne":{"type":"number"},"nbAvis":{"type":"integer","format":"int32"},"equipements":{"uniqueItems":true,"type":"array","items":{"$ref":"#/components/schemas/Equipement"}}}},"VerifyOtpRequest":{"required":["code","sessionToken"],"type":"object","properties":{"sessionToken":{"type":"string","description":"Session token retourné par POST /auth/login","example":"32294892ac614d144e77bc822e03439334d4117817f96b71ed7d17de9149c19f"},"code":{"pattern":"\\d{6}","type":"string","description":"Code OTP à 6 chiffres reçu par email","example":"847291"}},"description":"Validation du code OTP reçu par email"},"AuthResponse":{"type":"object","properties":{"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"expiresIn":{"type":"integer","format":"int64"},"email":{"type":"string"},"role":{"type":"string"}}},"ResetPasswordRequest":{"required":["nouveauMotDePasse","token"],"type":"object","properties":{"token":{"type":"string"},"nouveauMotDePasse":{"maxLength":2147483647,"minLength":8,"type":"string"}}},"RefreshTokenRequest":{"required":["refreshToken"],"type":"object","properties":{"refreshToken":{"type":"string"}}},"ProfilResponse":{"type":"object","properties":{"type":{"type":"string"},"nomComplet":{"type":"string"},"email":{"type":"string"},"telephone":{"type":"string"},"photoUrl":{"type":"string"},"siteId":{"type":"string"},"siteNom":{"type":"string"}}},"LoginRequest":{"required":["email","motDePasse"],"type":"object","properties":{"email":{"type":"string","description":"Adresse email de l'employé","example":"admin@jeanfe.cd"},"motDePasse":{"type":"string","description":"Mot de passe en clair (haché BCrypt côté serveur)","example":"VotreMotDePasse"}},"description":"Identifiants de connexion pour l'étape 1 du flow 2FA"},"UnifiedLoginResponse":{"type":"object","properties":{"type":{"type":"string"},"mfaRequired":{"type":"boolean"},"sessionToken":{"type":"string"},"message":{"type":"string"},"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"clientId":{"type":"string"},"email":{"type":"string"},"nomComplet":{"type":"string"},"emailVerifie":{"type":"boolean"},"expiresIn":{"type":"integer","format":"int32"},"role":{"type":"string"}}},"ForgotPasswordRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string"}}},"VerifyEmailRequest":{"required":["code","email"],"type":"object","properties":{"email":{"type":"string","example":"jean.kalombo@gmail.com"},"code":{"pattern":"\\d{6}","type":"string","example":"482915"}},"description":"Vérification d'e-mail par code"},"ResendVerificationRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string","example":"jean.kalombo@gmail.com"}},"description":"Renvoi du code de vérification"},"RegisterClientRequest":{"required":["email","motDePasse","nomComplet"],"type":"object","properties":{"nomComplet":{"maxLength":200,"minLength":0,"type":"string","description":"Nom complet du client","example":"Jean-Pierre Kalombo"},"email":{"maxLength":150,"minLength":0,"type":"string","description":"Adresse e-mail (identifiant de connexion)","example":"jean.kalombo@gmail.com"},"motDePasse":{"maxLength":100,"minLength":6,"type":"string","description":"Mot de passe (min. 6 caractères)"}},"description":"Création de compte client par e-mail / mot de passe"},"AuthClientResponse":{"type":"object","properties":{"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"clientId":{"type":"string"},"email":{"type":"string"},"nomComplet":{"type":"string"},"emailVerifie":{"type":"boolean"},"expiresIn":{"type":"integer","format":"int32"}}},"LoginClientRequest":{"required":["email","motDePasse"],"type":"object","properties":{"email":{"type":"string","description":"Adresse e-mail","example":"jean.kalombo@gmail.com"},"motDePasse":{"type":"string","description":"Mot de passe"}},"description":"Connexion client par e-mail / mot de passe"},"ChangePasswordRequest":{"required":["ancienMotDePasse","nouveauMotDePasse"],"type":"object","properties":{"ancienMotDePasse":{"type":"string"},"nouveauMotDePasse":{"maxLength":2147483647,"minLength":8,"type":"string"}}},"SimulationAnnulationResponse":{"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"joursAvantArrivee":{"type":"integer","format":"int64"},"politiqueNom":{"type":"string"},"tauxPenalite":{"type":"number"},"penalite":{"type":"number"},"montantRembourse":{"type":"number"},"montantTotal":{"type":"number"}}},"ReorderPhotosRequest":{"required":["photoIds"],"type":"object","properties":{"photoIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"NotificationResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"titre":{"type":"string"},"message":{"type":"string"},"categorie":{"type":"string"},"priorite":{"type":"string"},"lien":{"type":"string"},"lu":{"type":"boolean"},"statutPush":{"type":"string"},"erreurPush":{"type":"string"},"siteNom":{"type":"string"},"roleCible":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"luAt":{"type":"string","format":"date-time"}}},"ResetMotDePasseRequest":{"required":["nouveauMotDePasse"],"type":"object","properties":{"nouveauMotDePasse":{"maxLength":2147483647,"minLength":8,"type":"string"}}},"UpdateStatutChambreRequest":{"required":["statut"],"type":"object","properties":{"statut":{"type":"string","enum":["LIBRE","OCCUPEE","EN_NETTOYAGE","HORS_SERVICE","RESERVEE"]}}},"UpdateProfilRequest":{"type":"object","properties":{"nomComplet":{"maxLength":200,"minLength":0,"type":"string","example":"Jean-Pierre Kalombo"},"telephone":{"maxLength":30,"minLength":0,"type":"string","example":"+243 978 000 001"}},"description":"Mise à jour du profil self-service"},"AccueilStatsResponse":{"type":"object","properties":{"nombreChambres":{"type":"integer","format":"int64"},"noteMoyenne":{"type":"number"},"nombreAvis":{"type":"integer","format":"int64"},"nombreServices":{"type":"integer","format":"int64"}}},"PaiementInfoResponse":{"type":"object","properties":{"prixTotal":{"type":"number"},"acomptePct":{"type":"number"},"acompteMontant":{"type":"number"},"montantPaye":{"type":"number"},"montantRestant":{"type":"number"},"statutFacture":{"type":"string"}}},"Pageable":{"type":"object","properties":{"page":{"minimum":0,"type":"integer","format":"int32"},"size":{"minimum":1,"type":"integer","format":"int32"},"sort":{"type":"array","items":{"type":"string"}}}},"PageReservationResponse":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}},"PageableObject":{"type":"object","properties":{"pageNumber":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"paged":{"type":"boolean"},"unpaged":{"type":"boolean"},"offset":{"type":"integer","format":"int64"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}}}},"SortObject":{"type":"object","properties":{"direction":{"type":"string"},"nullHandling":{"type":"string"},"ascending":{"type":"boolean"},"property":{"type":"string"},"ignoreCase":{"type":"boolean"}}},"RapportTva":{"type":"object","properties":{"mois":{"type":"string"},"montantHt":{"type":"number"},"montantTva":{"type":"number"},"montantTtc":{"type":"number"},"tauxTva":{"type":"number"},"annee":{"type":"integer","format":"int32"},"numeroMois":{"type":"integer","format":"int32"}}},"RapportOccupation":{"type":"object","properties":{"mois":{"type":"string"},"totalChambres":{"type":"integer","format":"int64"},"nuitsOccupees":{"type":"integer","format":"int64"},"chambresNuits":{"type":"integer","format":"int64"},"tauxOccupationPct":{"type":"number","format":"double"},"revenu":{"type":"number"},"revpar":{"type":"number"},"annee":{"type":"integer","format":"int32"},"numeroMois":{"type":"integer","format":"int32"}}},"RapportCaMensuel":{"type":"object","properties":{"mois":{"type":"string"},"revenuTtc":{"type":"number"},"revenuN1":{"type":"number"},"evolutionPct":{"type":"number"},"montantHt":{"type":"number"},"montantTva":{"type":"number"},"annee":{"type":"integer","format":"int32"},"numeroMois":{"type":"integer","format":"int32"}}},"PageNotificationResponse":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/NotificationResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}},"EnumOptionResponse":{"type":"object","properties":{"code":{"type":"string"},"libelle":{"type":"string"}}},"InterventionResponse":{"type":"object","properties":{"action":{"type":"string"},"commentaire":{"type":"string"},"ancienStatut":{"type":"string"},"nouveauStatut":{"type":"string"},"employeNom":{"type":"string"},"horodatage":{"type":"string","format":"date-time"}}},"PageTicketResponse":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/TicketResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}},"PageGroupeResponse":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/GroupeResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}},"FideliteResponse":{"type":"object","properties":{"points":{"type":"integer","format":"int32"},"niveau":{"type":"string"},"totalNuits":{"type":"integer","format":"int32"},"totalSejours":{"type":"integer","format":"int32"},"transactions":{"type":"array","items":{"$ref":"#/components/schemas/TransactionItem"}}}},"TransactionItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"points":{"type":"integer","format":"int32"},"soldeApres":{"type":"integer","format":"int32"},"description":{"type":"string"},"date":{"type":"string","format":"date-time"}}},"PageFactureResponse":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/FactureResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}},"DisponibiliteItemResponse":{"type":"object","properties":{"typeChambreId":{"type":"string","format":"uuid"},"typeNom":{"type":"string"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"},"capacite":{"type":"integer","format":"int32"},"photoPrincipaleUrl":{"type":"string"},"prixNuit":{"type":"number"},"prixTotal":{"type":"number"},"nbChambresDispos":{"type":"integer","format":"int64"},"alerteStock":{"type":"string"},"noteMoyenne":{"type":"number"}}},"DisponibiliteResponse":{"type":"object","properties":{"nombreNuits":{"type":"integer","format":"int64"},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"nombreResultats":{"type":"integer","format":"int32"},"chambres":{"type":"array","items":{"$ref":"#/components/schemas/DisponibiliteItemResponse"}}}},"ChambreDisponible":{"type":"object","properties":{"typeChambre":{"$ref":"#/components/schemas/TypeChambre"},"site":{"$ref":"#/components/schemas/Site"},"nbChambresDispos":{"type":"integer","format":"int64"},"tarif":{"$ref":"#/components/schemas/ResultatTarif"},"politiqueAnnulation":{"$ref":"#/components/schemas/PolitiqueAnnulation"},"nombreNuits":{"type":"integer","format":"int64"},"economie":{"type":"number"},"prixTotalSeJour":{"type":"number"},"alerteStock":{"type":"string"}}},"ResultatRecherche":{"type":"object","properties":{"sites":{"type":"array","items":{"$ref":"#/components/schemas/ResultatSite"}},"nombreNuits":{"type":"integer","format":"int64"},"dateArrivee":{"type":"string","format":"date"},"dateDepart":{"type":"string","format":"date"},"siteDemandeComplet":{"type":"boolean"},"messageSuggestion":{"type":"string"}}},"ResultatSite":{"type":"object","properties":{"site":{"$ref":"#/components/schemas/Site"},"chambres":{"type":"array","items":{"$ref":"#/components/schemas/ChambreDisponible"}},"sitePrincipal":{"type":"boolean"},"complet":{"type":"boolean"}}},"ResultatTarif":{"type":"object","properties":{"prixBase":{"type":"number"},"prixNuitAvantRemise":{"type":"number"},"totalRemises":{"type":"number"},"prixNuitFinal":{"type":"number"},"prixTotal":{"type":"number"},"nombreNuits":{"type":"integer","format":"int64"},"tarifSaisonApplique":{"type":"string"},"descriptionRegles":{"type":"string"}}},"DashboardKpi":{"type":"object","properties":{"courant":{"$ref":"#/components/schemas/KpiPeriode"},"precedent":{"$ref":"#/components/schemas/KpiPeriode"},"vueJour":{"$ref":"#/components/schemas/VueOperationnelle"},"dateDebut":{"type":"string"},"dateFin":{"type":"string"}}},"KpiPeriode":{"type":"object","properties":{"totalChambres":{"type":"integer","format":"int64"},"nuitsOccupees":{"type":"integer","format":"int64"},"chambresNuits":{"type":"integer","format":"int64"},"tauxOccupationPct":{"type":"number","format":"double"},"adr":{"type":"number"},"revpar":{"type":"number"},"revenuTotal":{"type":"number"},"totalReservations":{"type":"integer","format":"int64"},"reservationsAnnulees":{"type":"integer","format":"int64"},"dateDebut":{"type":"string"},"dateFin":{"type":"string"}}},"VueOperationnelle":{"type":"object","properties":{"totalChambres":{"type":"integer","format":"int64"},"chambresOccupees":{"type":"integer","format":"int64"},"chambresLibres":{"type":"integer","format":"int64"},"horsService":{"type":"integer","format":"int64"},"enNettoyage":{"type":"integer","format":"int64"},"tauxOccupationPct":{"type":"number","format":"double"},"arriveesDuJour":{"type":"integer","format":"int64"},"departsDuJour":{"type":"integer","format":"int64"},"sejoursEnCours":{"type":"integer","format":"int64"},"enAttente":{"type":"integer","format":"int64"},"date":{"type":"string"}}},"PageClientResponse":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/ClientResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}},"PageAvisClient":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/AvisClient"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}},"MeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nomComplet":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"siteId":{"type":"string","format":"uuid"},"siteNom":{"type":"string"}}},"AuditLog":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"employeId":{"type":"string","format":"uuid"},"employeEmail":{"type":"string"},"action":{"type":"string"},"entite":{"type":"string"},"entiteId":{"type":"string","format":"uuid"},"avant":{"type":"string"},"apres":{"type":"string"},"description":{"type":"string"},"ipAddress":{"type":"string"},"userAgent":{"type":"string"},"horodatage":{"type":"string","format":"date-time"}}},"PageAuditLog":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"last":{"type":"boolean"},"first":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/AuditLog"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"empty":{"type":"boolean"}}}},"securitySchemes":{"BearerAuth":{"type":"http","description":"Access token JWT obtenu après double authentification.\nDurée de vie : **1 heure**.\nRenouveler via `POST /auth/refresh` avec le refreshToken (30 jours).\n","scheme":"bearer","bearerFormat":"JWT"}}}}