Documentation J+SERVICES Guides Référence API

Contrat API — Topologie J+RADIUS

Version : 1.2 Base URL : https://live.jmoai.net/api/v1/radius Public : application mobile du client titulaire d’une licence J+RADIUS active.

Authentification et périmètre

Toutes les routes ci-dessous exigent le JWT du client. Le tenant est déduit du jeton : le client ne fournit jamais de client_id et ne peut ni voir ni promouvoir le NAS d’un autre client.

Un routeur est un NAS RADIUS lié à son allocation VPN canonique. Un NAS MEMBER reste un routeur RADIUS complet : il authentifie ses propres sessions. Le rôle PRIMARY est le routeur de référence des écritures de catalogue ; il ne redirige ni ne concentre le trafic RADIUS des secondaires.

Lire la topologie

GET /topology

Cette route n’est pas mise en cache : chaque appel renvoie 200 avec un corps JSON. L’application ne doit pas envoyer ni interpréter une réponse 304 pour cette lecture.

Compatibilité mobile : data, result et les champs racine (primary, members, warnings) décrivent la même topologie. Une application nouvelle lit result ; les clients historiques peuvent lire data.

La même compatibilité est garantie par GET /nas (nas) et GET /license (license, nas_count, nas_limit) : les champs existent à la racine, sous data et sous result.

Capacité NAS

nas_limit est le nombre maximal de routeurs NAS que le client peut rattacher, pas le nombre de NAS déjà créés. nas_count ne compte que les NAS actifs.

Une offre ne s’additionne pas implicitement à une autre : le serveur applique la plus grande capacité explicitement accordée, ou la capacité déjà acquise dans l’ancienne licence si elle est supérieure. Un droit RADIUS sans radius_nas_limit explicite n’ajoute aucun NAS. Le serveur ne rend jamais une limite inférieure au nombre de NAS actifs existants.

Réponse 200 :

{
  "success": true,
  "data": {
    "primary": {
      "id": "uuid",
      "nasname": "10.42.0.2",
      "role": "PRIMARY"
    },
    "members": [],
    "warnings": []
  },
  "result": {
    "primary": {
      "id": "uuid",
      "nasname": "10.42.0.2",
      "role": "PRIMARY"
    },
    "members": [],
    "warnings": []
  },
  "primary": {
    "id": "uuid",
    "nasname": "10.42.0.2",
    "role": "PRIMARY",
    "status": "ACTIVE",
    "tunnel_status": "CONNECTED",
    "sessions_open": 4,
    "eligibility": { "eligible": true, "code": "ELIGIBLE" }
  },
  "members": [],
  "warnings": []
}

Chaque NAS porte aussi board_name (alias de model) et devices. Un équipement est toujours imbriqué sous le NAS de son allocation_id : il n’existe pas de liste globale d’équipements dans cette réponse. Les valeurs de devices[].type sont canoniques : access_point, camera, router, switch, cpe ou other.

Tableau de bord QoE groupé

GET /qoe/dashboard

Cette route applique la même authentification et les mêmes règles de cache que GET /topology. Elle évite trois appels mobiles : result, data et la racine contiennent primary, members, warnings et capabilities dans exactement la même forme que la topologie ; qoe est la charge utile de GET /qoe/status et usage celle de GET /qoe/usage.

L’application dessine uniquement result.primary, puis result.members, et lit devices sur chaque NAS. primary: null et devices: [] sont des états normaux.

Pilotage commercial multi-routeurs

GET /commercial-readiness

Cette route est une lecture seule pour le panneau de gestion. Elle ne modifie aucun routeur, aucun NAS et aucune session. Elle donne l’arbre de pilotage à corriger avant une vente multi-routeurs : tunnel, identité routeur, cohérence NAS, inscription FreeRADIUS, premier trafic RADIUS réel, mode RADIUS et preuve CoA/PoD.

Réponse 200 :

{
  "success": true,
  "summary": {
    "technical_status": "TECHNICAL_BLOCKED",
    "commercial_status": "NO_GO_COMMERCIAL_MULTI_ROUTER",
    "score_sur_10": 6.4,
    "total_routers": 2,
    "routers_blocked": 1,
    "routers_ready_pilot": 1,
    "nas_limit": 3,
    "blockers": ["COA_POD_PROOF"],
    "warnings": ["FREERADIUS_REGISTRATION"]
  },
  "routers": [
    {
      "nas_id": "uuid",
      "nasname": "10.255.0.10",
      "status": "TECHNICAL_BLOCKED",
      "blockers": ["COA_POD_PROOF"],
      "warnings": [],
      "gates": [
        {
          "code": "COA_POD_PROOF",
          "status": "BLOCK",
          "message": "CoA/PoD non prouvé sur session réelle : exigence commerciale non satisfaite.",
          "evidence": "documenté mais non testé"
        }
      ]
    }
  ],
  "pilotage_tree": {
    "provider_policy": "NO_GO_COMMERCIAL_MULTI_ROUTER",
    "next_required_proofs": [
      "NAS auth réel",
      "accounting interim réel",
      "CoA/PoD confirmé sur ticket de test",
      "restore testé",
      "charge multi-routeurs mesurée"
    ]
  }
}

commercial_status reste NO_GO_COMMERCIAL_MULTI_ROUTER tant que les validations Provider Stack ne sont pas produites et approuvées. Même si technical_status vaut PILOT_READY, l’application ne doit pas afficher une disponibilité commerciale générale.

Promouvoir un routeur secondaire

PUT /nas/:nasId/primary

nasId doit être un NAS actif du client authentifié. Aucun body n’est requis.

Réponse 200 :

{
  "success": true,
  "nas_id": "uuid",
  "role": "PRIMARY",
  "previous_primary_nas_id": "uuid",
  "changed": true
}

La bascule est atomique : le serveur garantit qu’il n’existe jamais deux NAS PRIMARY pour le même client. L’application ne doit pas essayer de gérer cette concurrence.

Erreurs :

Statut Code Cas client
401 / 403 — session invalide ou compte non-client
403 RADIUS_LICENSE_INACTIVE ou EXPIRED licence non utilisable
404 NAS_NOT_FOUND NAS absent, inactif ou hors tenant
500 — erreur serveur : afficher une erreur réessayable, sans changer l’état local

Supprimer un routeur

DELETE /nas/:nasId

Avant de supprimer le PRIMARY alors qu’un ou plusieurs secondaires actifs existent, l’application doit d’abord promouvoir le secondaire choisi avec PUT /nas/:nasId/primary.

Sinon le serveur répond 409 :

{
  "error": "Ce NAS est le routeur principal. Désignez d abord un routeur secondaire comme principal.",
  "code": "PRIMARY_NAS_REASSIGN_REQUIRED",
  "details": {
    "primary_nas_id": "uuid",
    "candidate_nas_ids": ["uuid"]
  }
}

La suppression du dernier NAS actif est admise ; la prochaine inscription d’un NAS actif le désigne automatiquement PRIMARY.

Règles d’interface recommandées

Écart volontaire

Le primaire n’est pas un concentrateur ni un point de défaillance RADIUS : chaque NAS reste enregistré et authentifie localement via FreeRADIUS. Ce choix évite de créer un routage inter-routeurs ou une isolation fournisseur implicite non validée.