Contrat API — QoE RADIUS (intégration uniquement)
Base : https://live.jmoai.net/api/v1/radius.
Ce module est réservé au VPS d’intégration isolé. Il ne fait pas partie de l’offre commerciale
STARLINK X MikroTik tant que sa validation sur NAS réel n’est pas achevée. Une action est acceptée seulement après un rapport du bridge ;
202 signifie « reçue/enregistrée », jamais « bridage appliqué ».
Règle mobile — lecteur local, jamais émetteur privilégié
L’application mobile peut poser et lire son agent QoE local depuis le LAN du routeur. Elle ne
doit jamais appeler POST /qoe/telemetry directement : cette route exige le jeton privé du
bridge, qui ne doit pas exister dans une application distribuée. Sans bridge/agent autorisé,
l’app affiche ses métriques locales et ne prétend pas qu’elles sont historisées côté serveur.
Le backend ne pose ni /system script ni /system scheduler. Ces chemins RouterOS sensibles
restent sous la responsabilité de l’application locale. Le backend reçoit, conserve et analyse
la télémétrie déjà remontée par un bridge autorisé.
Télémétrie routeur
POST /qoe/telemetry exige l’en-tête x-vpn-bridge-token et le corps :
{
"nas_id": "uuid",
"observed_at": "2026-08-28T10:00:00Z",
"rtt_ms": 250,
"jitter_ms": 20,
"packet_loss_pct": 2,
"tx_bps": 9000000,
"rx_bps": 12000000,
"wan_rx_bytes": 150323855360,
"wan_tx_bytes": 18323855360,
"top_consumers": [{ "username": "u1", "ip": "10.0.0.4", "rx_bps": 6000000, "tx_bps": 800000 }]
}
Réponse : 202 { "accepted": true, "event": { "id": "…", "observed_at": "…" } }.
Le client_id est dérivé du NAS enregistré, jamais accepté depuis le routeur ; aucune
adresse d’un autre client n’est exposée.
is_congested et router_uptime, parfois produits par un agent mobile, ne font pas partie du
contrat d’ingestion actuel : le serveur calcule son propre verdict à partir de RTT, perte,
compteurs WAN et politique. Ne pas les utiliser pour annoncer un état serveur.
wan_rx_bytes et wan_tx_bytes sont des compteurs WAN cumulés en octets depuis le
dernier redémarrage du routeur. Ils doivent être transmis ensemble. Le serveur ignore le
premier point, les intervalles inférieurs à 15 s ou supérieurs à 15 min, et les retours à
zéro : ils ne créent donc jamais artificiellement des gigaoctets consommés.
top_consumers est borné à 100 entrées et normalisé côté serveur. Chaque entrée doit porter
au moins username et ip; les débits rx_bps / tx_bps et le compteur optionnel bytes
doivent être positifs. Ce signal alimente GET /qoe/active-clients sous la source
sources.qoe_agent, ce qui permet au panneau de voir des clients locaux actifs même avant
leur migration complète vers RADIUS.
État et règles (JWT client + licence RADIUS active)
GET /qoe/status: dernières mesures par NAS etcongested_nas.GET /qoe/usage: consommation du jour par NAS, volume des deux dernières heures, état de congestion et indicateursdaily_warning/accelerating.GET /qoe/active-clients?nas_id=&limit=500: clients actifs observés en temps réel, fusionnés depuis les sessions RADIUS (radacct), les actifs MikroTik locaux (/ip hotspot active) et les dernierstop_consumersdu bridge QoE. La réponse indiquesources.radius,sources.mikrotik_localetsources.qoe_agent; une source indisponible ne vaut jamais preuve de zéro client. Chaque client expose aussiprofileetprofile_sourcequand le profil est résolu depuis le compte Hotspot local ou le voucher RADIUS synchronisé ; sinonprofile_sourcevautUNKNOWN. Chaque appel écrit aussi un snapshot serveur dansqoe_active_client_snapshots, fermé par RLS.GET /qoe/active-client-history?nas_id=&username=&since_hours=24&limit=500: historique des snapshots de clients actifs. La réponse agrège par coupleusername+ip, conserve les sources observées et exposemax_gbplutôt qu’une somme naïve, car répéter un compteur de session dans plusieurs snapshots ne prouve pas une nouvelle consommation.GET /qoe/observability-alerts?since_days=7&limit=30: alertes de mesure QoE, par exempleACTIVE_CLIENT_SNAPSHOT_FAILED. Le panneau doit les afficher comme des avertissements de mesure incomplète, pas comme des incidents client ni comme une absence de trafic.
Un cron QOE_ACTIVE_CLIENT_SNAPSHOT relit périodiquement les clients dont le dernier snapshot
est absent ou trop vieux. Ainsi les clients locaux actifs laissent un historique exploitable
dans les bilans même si le gérant n’ouvre pas le panneau, et sans les forcer à authentifier
via le cloud RADIUS. Si la collecte échoue, le serveur crée au plus une alerte
ACTIVE_CLIENT_SNAPSHOT_FAILED par client et par jour dans qoe_observability_alerts et envoie
une notification applicative QoE si les préférences l’autorisent. Cette alerte signifie
« mesure incomplète », jamais « zéro client actif ».
POST /qoe/rules: crée{ name, nas_id, enabled?, condition, action }.PUT /qoe/rules/:idetDELETE /qoe/rules/:id: modifient/suppriment seulement la règle du client connecté.
Une condition minimale est { "metric":"rtt_ms", "operator":">", "threshold":150 }.
Une action déclare son type, par exemple { "type":"COA_RATE_LIMIT", "rate_limit":"1M/1M", "duration_seconds":300 }.
Le moteur d’exécution CoA asynchrone est volontairement séparé de cette première livraison :
il ne doit pas être activé avant validation réelle du NAS compatible CoA.
Alertes d’usage, rapports et préférences
GET /qoe/reports?limit=30retourne les rapports quotidiens du client connecté (maximum 90).GET /qoe/preferencesretourneurgent_push,daily_report_push,daily_report_email,usage_alert_push,quiet_start,quiet_end.PUT /qoe/preferencesmodifie uniquement ces six champs. Les heures sont entre 0 et 23.
Le rapport quotidien est produit à 23 h 59 et est unique par client/date. Il inclut le statut
temps réel quand il est lisible et l’historique 24 h de qoe_active_client_snapshots, afin
qu’un routeur indisponible à 23 h 59 ne fasse pas disparaître les clients locaux vus dans la
journée. Désactiver daily_report_push conserve le rapport mais ne déclenche pas de
notification mobile. Désactiver daily_report_email conserve le rapport mais ne l’envoie pas
par mail.
Une alerte quotidienne est créée à partir de 100 GiB. Une alerte d’accélération exige en
plus au moins 5 GiB durant les deux dernières heures et une hausse d’au moins 35 % par
rapport au volume déjà consommé plus tôt dans la journée. Chaque type d’alerte est unique
par NAS et par jour. Les alertes respectent urgent_push et usage_alert_push.
Comptabilité semi-cloud
En mode semi-cloud, un utilisateur encore authentifié localement reste comptabilisé par
RouterOS/Mikhmon et apparaît simultanément dans la fusion QoE locale. Un utilisateur authentifié
par RADIUS est comptabilisé par radacct et les mises à jour intermédiaires RADIUS ; le système
ne double pas les octets lorsqu’il apparaît dans les deux sources. Les ventes restent dans les
transactions et le stock centralisés de l’application : elles ne dépendent pas du fait que la
session soit locale ou RADIUS.
Mikhmon continue donc à gérer ses comptes locaux et ses scripts locaux, mais ses compteurs ne sont pas la source de vérité des sessions RADIUS cloud. Pour ces sessions, l’accounting RADIUS devient la référence ; les schedulers Mikhmon ne doivent pas être considérés comme preuve d’une consommation cloud.
L’alerte contient seulement une recommandation (SUGGEST_ONLY) : examen d’une file
équitable et planification éventuelle pour le lendemain. Elle ne bloque ni torrent, ni
application, ni utilisateur, et ne déclenche pas de CoA/PoD automatiquement.
Déconnexion manuelle
POST /qoe/actions/kick avec { "nas_id":"uuid", "username":"ticket", "session_id?":"…" } enregistre une action POD_DISCONNECT, appelle le bridge et renvoie 202 avec l’état RUNNING. Un réconciliateur devra constater la fin de session avant de la marquer SUCCEEDED.
Déviation volontaire
Le fallback PoD automatique après un échec CoA n’est pas livré : il couperait un client sur une panne de transport ou une incompatibilité NAS. Il sera ajouté seulement avec preuve CoA/PoD sur NAS réel, politique explicite et rollback de débit.