# Domaine Segmentation « Wi-Fi Like Home » (§7.9 / EF-11, issue #395) # # Permet à un applicatif tiers (PMS hôtelier, gestion de résidence / camping, app mobile) d'ouvrir # et de fermer les séjours d'un site, et d'en consulter l'état. # # Authentification : clé d'API du hotspot ou du manager (header Authorization), ou `2isr-Auth` # depuis une IP admin whitelistée. L'IP appelante doit figurer dans la whitelist API du compte # (middleware CheckWhiteList), sinon 403. # # Cloisonnement : un compte hotspot ne voit que ses entités, un manager celles des sites de sa # flotte. Une entité d'un autre site répond 404, comme une entité inexistante. ### Liste des entités du hotspot # Aucun secret dans la réponse : ni clé Wi-Fi, ni code PIN. GET {{host}}/segmentation/entities Accept: application/json Authorization: Bearer {{hotspot}} ### ### Détail d'une entité # Si l'entité est occupée, la réponse porte en plus le bloc `occupant` (identité du séjour en cours). GET {{host}}/segmentation/entities/79 Accept: application/json Authorization: Bearer {{hotspot}} ### ### Ouverture d'un séjour — durée prédéfinie (EF-11.2) # `lastName` est obligatoire, avec `email` OU `phone`. `expirationType` accepte les codes de durée # connus : JOUR1, JOUR2, SEMAINE1, SEMAINE2, MOIS1, MOIS3, MOIS6, AN1. # # `phoneCountry` (optionnel, ISO 3166-1 alpha-2, défaut `FR`) n'intervient que sur un `phone` saisi # en notation NATIONALE : « 079 123 45 67 » + `"phoneCountry": "CH"` donne `+41791234567`. Un # numéro en notation internationale (« +41 79... ») l'ignore. Une valeur inconnue retombe # silencieusement sur `FR`. Le téléphone est stocké en E.164 (EF-04.6). # # Réponse : l'entité mise à jour, le SSID, la clé Wi-Fi du séjour (`wifiKey`) et le jeton de suivi # (`statusToken`) qui permet de construire l'URL de la page de statut. # # Effets, identiques à une activation depuis le front : clé Wi-Fi régénérée (EF-03.0), occupant # historisé en mode A, jeton de suivi émis, activité et événement journalisés. POST {{host}}/segmentation/entities/79/activate Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "lastName": "Durand", "firstName": "Lea", "email": "lea@exemple.fr", "phone": "0612345678", "phoneCountry": "FR", "expirationType": "SEMAINE1" } ### ### Ouverture d'un séjour — date de fin choisie # `expirationType: "CUSTOM"` impose `customExpiryDate` (format `Y-m-d H:i:s`), qui doit être dans # le futur. La date est validée côté serveur, sur l'horloge du serveur. POST {{host}}/segmentation/entities/79/activate Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "lastName": "Durand", "email": "lea@exemple.fr", "expirationType": "CUSTOM", "customExpiryDate": "2026-12-24 10:00:00" } ### ### Fermeture d'un séjour (EF-11.3) # Transition T2 (ou T3b si le séjour était déjà expiré). Nouvelle clé Wi-Fi, expiration effacée, # e-mails clients purgés, statut ramené à DISPONIBLE. Le code PIN, affiché physiquement dans le # lieu, est conservé. POST {{host}}/segmentation/entities/79/checkout Accept: application/json Authorization: Bearer {{hotspot}} ### ### Équipements connectés au segment de l'entité (EF-11.4) # Table ARP du routeur du site, filtrée sur le sous-réseau de l'entité, croisée avec les sessions # portail en cours. # # ⚠️ `incoming` / `outgoing` (octets) ne portent que sur les sessions OUVERTES : un appareil # déconnecté disparaît avec sa consommation. Un total par séjour relève de l'issue #414. GET {{host}}/segmentation/entities/79/devices Accept: application/json Authorization: Bearer {{hotspot}} ### ### Historique des séjours d'une entité (EF-03.T3) # Une ligne par activation, la plus récente d'abord. Sert de preuve support et d'historique # d'occupation. GET {{host}}/segmentation/entities/79/history Accept: application/json Authorization: Bearer {{hotspot}} ### # --------------------------------------------------------------------------- # Codes d'erreur du domaine # --------------------------------------------------------------------------- # 1750 / 404 - entité inconnue, OU appartenant à un autre hotspot (réponse volontairement # indifférenciée : distinguer les deux permettrait d'énumérer les entités des # autres sites) # 1751 / 404 - le hotspot n'a pas de configuration de segmentation (module non déployé) # 1752 / 409 - l'état de l'entité interdit l'action (activer une entité occupée, fermer une # entité libre, agir sur une entité hors service) # 1753 / 409 - le statut a changé entre la lecture et l'écriture (verrou optimiste) : rien n'a # été modifié, relire puis réessayer # 1754 / 400 - payload d'activation invalide ; le message nomme les champs fautifs # (lastName / expiration / contact) # 1755 / 503 - équipements illisibles : le routeur du site n'a pas répondu ### Erreur : activer une entité déjà occupée → 409 (1752) POST {{host}}/segmentation/entities/78/activate Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "lastName": "Doublon", "email": "doublon@exemple.fr", "expirationType": "JOUR1" } ### ### Erreur : identité incomplète → 400 (1754), message « contact » POST {{host}}/segmentation/entities/80/activate Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "lastName": "SansContact", "expirationType": "JOUR1" } ### ### Erreur : entité d'un autre site → 404 (1750) GET {{host}}/segmentation/entities/999999 Accept: application/json Authorization: Bearer {{hotspot}} # =========================================================================== # Lot 2 — CRUD des entités et configuration du site (EF-11.5) # =========================================================================== ### Création d'une entité # `name` (unique sur le site) et `type` suffisent. **VLAN et sous-réseau sont alloués # automatiquement** sur la première place libre du plan d'adressage : un applicatif tiers n'a pas à # connaître le découpage réseau, et le lui laisser fixer ouvrirait des collisions. # Le code PIN et la clé Wi-Fi sont générés côté serveur. # # Types acceptés : SALLE, CHAMBRE, APPARTEMENT, LOGEMENT, MOBIL_HOME, LOCAL, BUREAU, AUTRES. # Réponse : 201, avec l'entité créée. POST {{host}}/segmentation/entities Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "name": "Chambre 101", "type": "CHAMBRE" } ### ### Création d'une fratrie # `count` = nombre d'entités **supplémentaires** créées à la suite (0 par défaut). Les noms suivent # celui du parent (« Chambre 101 », « Chambre 101-2 », …), VLAN et sous-réseaux s'enchaînent. # La capacité restante du site est vérifiée avant création (409 si insuffisante). POST {{host}}/segmentation/entities Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "name": "Chambre 200", "type": "CHAMBRE", "count": 4 } ### ### Mise à jour d'une entité # Champs modifiables : `name`, `type`. **Les champs omis conservent leur valeur.** # # Ne sont pas modifiables : `vlan` / `subNetwork` (allocation automatique — les changer romprait le # plan d'adressage), `password` (la clé se renouvelle par activation ou check-out) et `pinCode` # (affiché physiquement dans le lieu). PUT {{host}}/segmentation/entities/79 Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "name": "Chambre 101 bis" } ### ### Suppression d'une entité # Refusée (409) dans deux cas : le **réseau public** (il porte le portail captif du site) et une # entité **occupée** (fermer le séjour d'abord via /checkout). La suppression cascade sur les # e-mails clients, les jetons et les logs d'activité. DELETE {{host}}/segmentation/entities/79 Accept: application/json Authorization: Bearer {{hotspot}} ### ### Configuration du site # Plan d'adressage et règles par défaut. Aucun secret. GET {{host}}/segmentation/config Accept: application/json Authorization: Bearer {{hotspot}} ### ### Mise à jour de la configuration # **Les champs omis conservent leur valeur.** # # ⚠️ `vlan` et `publicNetwork` sont répercutés sur l'entité « réseau public », qui les suit. Ils # décrivent le découpage réel du site : les changer sur une segmentation déjà déployée désaligne la # configuration des routeurs tant que `conf_routeur.sh` n'a pas été régénéré. PUT {{host}}/segmentation/config Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "defaultExpirationDate": "SEMAINE1", "passwordSize": 12 } ### # Codes d'erreur du lot 2 # 1756 / 409 - nom d'entité déjà pris sur ce hotspot # 1757 / 409 - allocation réseau impossible (VLAN ou plage IPv4 épuisés, capacité insuffisante) # 1758 / 409 - suppression refusée (réseau public, ou entité occupée) # 1759 / 400 - payload invalide ; le message nomme les champs fautifs ### Erreur : nom déjà pris → 409 (1756) POST {{host}}/segmentation/entities Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "name": "TEST_PIN", "type": "CHAMBRE" } ### ### Erreur : type inconnu → 400 (1759) POST {{host}}/segmentation/entities Content-Type: application/json Accept: application/json Authorization: Bearer {{hotspot}} { "name": "Chambre 999", "type": "CHATEAU" }