Abonnements et facturation — référence de fonctionnement

Les acteurs, ce qui est facturé, les fichiers du modèle, et le déroulé concret de chaque situation. Chaque élément porte son état : en place, décidé, ou non tranché.
Document de référence interne  ·  25 août 2026  ·  à valider entre Michael, Franck et Serge
Ce que ce document est, et ce qu'il n'est pas Il décrit le modèle décidé, celui qui fait référence. Il ne décrit pas l'état du code déployé : le passage à la facture consolidée du gestionnaire était en développement en juin, et son état exact en production n'est pas établi. Chaque mécanisme ci-dessous porte donc son statut.
En place Fonctionne aujourd'hui. Décidé Validé entre Michael et Franck, attend la modification de l'analyse ou le développement. Non tranché Aucune décision prise. Ne rien construire dessus.

1.Le contexte en cinq minutes

De quoi on parle, et où vit la facturation.

IoT-Link vend des jauges connectées — principalement LevelStream, une sonde ultrason qui mesure le niveau d'une citerne — puis un abonnement récurrent qui couvre l'accès au portail, la connectivité et les notifications. Le matériel est une vente ponctuelle. Tout le sujet de ce document est l'abonnement, qui est la source de revenu récurrent.

Le trajet de la donnée, pour situer :

sonde ──MQTT-SN/eSIM──▶ Thingstream ──▶ connector AWS ──▶ DynamoDB
                                                              │
                            service .NET/WLangage             │ (polling, décodage)
                                                              ▼
                                                    base HFSQL IoT-Link_Portail

Trois consommateurs travaillent en parallèle sur cette base : le portail web (WebDev), l'API Stripe pour les paiements et les factures, et la tâche planifiée qui produit la facturation. Cette dernière est le cœur du sujet.

Vocabulaire client Côté client, la connectivité est commercialisée sous le nom « réseau X-Stream ». Les noms Thingstream et AWS ne sortent jamais dans un document client.

2.Qui est quiEn place

Tout part du type de client. Il détermine l'architecture de facturation appliquée.

CustomerTypeActeurCe que c'est
0IoT-LinkLa racine de l'arbre commercial. Pas de facturation.
1Client final directUn particulier ou une entreprise qui équipe sa propre citerne, sans intermédiaire.
2GestionnaireUn distributeur de mazout, un installateur. Il gère un parc de jauges pour ses propres clients. C'est le cas le plus riche.
3Client final lié à un gestionnaireLe client d'un gestionnaire. Il peut payer lui-même, ou son gestionnaire paie pour lui.
4DistributeurPrévu, non défini à ce jour.

La hiérarchie est portée par Customer.IDCustomerLead, une auto-référence : le client d'un gestionnaire pointe vers son gestionnaire.

Deux réglages déterminants

3.Ce qui est facturéEn place

Le catalogue vit dans StripeProducts, typé par ProductsType. Liste donnée par Franck le 20 mai 2026.

ProductsTypeProduitAssiette
0Abonnement de base gestionnaireFixe, un par gestionnaire. Ouvre l'accès au portail.
1Abonnement full leasingFormule tout compris — matériel et service dans une mensualité unique.
2Abonnement device gestionnairePar jauge présente au portail, placée ou non, active ou non.
3Abonnement clientL'abonnement d'un client final — modèle X.
4Pack SMSAchat ponctuel de crédits de notification. Facturé hors abonnement.
5Dépassement de messagesPar jauge ayant dépassé son quota sur la période.

Où vivent les plans Bronze, Silver et Gold

Ce ne sont pas des produits, et ils n'ont donc pas de ProductsType. Ce sont des prix. Le catalogue est une hiérarchie à trois niveaux :

StripeProducts         une catégorie de produit, typée par ProductsType
   │ 1..N
StripePrices           une déclinaison tarifaire de cette catégorie
   │                ← C'EST ICI que vivent Bronze, Silver, Gold
   │                  au même titre que l'abo de base, le forfait device
   │                  ou un pack SMS
   │ N..1
ThingstreamTarifType   le coût de connectivité et le quota de messages inclus

Dire qu'« une jauge est en Gold » signifie que sa ligne dans StripeSubscriptionsObjectsIoT porte un IDStripePrices pointant vers le prix nommé Gold. Ce prix pointe lui-même vers un ThingstreamTarifType, qui porte Cost — ce que la connectivité coûte à IoT-Link — et Quantity — le nombre de messages inclus.

Le quota est par jauge, jamais mutualisé Deux jauges en Silver ont chacune leur quota de messages ; ils ne s'additionnent pas et l'une ne peut pas consommer le reliquat de l'autre. Le dépassement se calcule jauge par jauge.
Deux systèmes de messages, sans aucun rapport Les messages sonde (MQTT, télémétrie) ont un quota inclus dans le plan, et leur dépassement est facturé. Les SMS de notification (envoyés au client sur son GSM en cas d'alerte) n'ont aucun quota inclus : ils s'achètent en packs, et quand le crédit est épuisé les notifications s'arrêtent — sans blocage de la sonde, sans achat automatique, sans facturation. Piège de nommage : StripePrices.SMSQuantity compte les SMS de notification, pas les messages MQTT.

4.Les fichiers du modèle

Huit fichiers portent la facturation. Un seul est vraiment central.

FichierRôleÉtat
StripeProductsLe catalogue : quels produits existent, typés par ProductsType.En place
StripePricesLes prix. Immuables — un prix ne se modifie jamais, toute évolution tarifaire crée un nouveau prix et désactive l'ancien.En place
ThingstreamTarifTypeLe tarif de connectivité rattaché à un prix : Cost et Quantity.En place
StripeSubscriptionsL'abonnement souscrit par un client. Porte les identifiants Stripe, les dates, le statut.En place
StripeSubscriptionsObjectsIoT
souvent abrégé SSO
Le fichier central. Une ligne = une jauge rattachée à un abonnement, sur une période, à un prix donné. C'est là que vit le prorata et l'état de traitement.à compléter
StripeInvoicesLes factures émises. Status reprend les valeurs natives Stripe : draft, open, paid, uncollectible, void.En place
StripeInvoicesDetailsLe détail de la facture consolidée d'un gestionnaire : quelles lignes, quelles quantités, quels montants.à créer
StripeSubscriptionsHistoryL'historique au niveau abonnement : quel client a eu quel abonnement, à quel prix, de quand à quand, et pourquoi il s'est terminé.à créer

Un neuvième fichier existe, StripePlans : six rubriques, il stocke le prix qu'utilise un abonnement. Une fois que chaque ligne de StripeSubscriptionsObjectsIoT portera son propre IDStripePrices, il fera doublon à un grain plus grossier. Ne rien construire dessus.

Le réflexe à prendre Parce que les prix Stripe sont immuables, on ne recopie jamais un montant à côté d'une clé étrangère vers StripePrices. Le pointeur suffit à garantir l'historique : le prix pointé ne changera jamais.

5.Les deux architectures

Selon le type de client, deux mécaniques différentes coexistent. C'est la décision la plus structurante du domaine.

Client final — modèle XGestionnaire — modèle Y1-B
QuiCustomerType 1 ou 3CustomerType 2
CycleAnnuel, payé d'avanceMensuel
AbonnementsUn par sonde. Chaque sonde a sa propre date anniversaire.Un seul abonnement master multi-lignes pour tout le parc.
FactureUne à la souscription, puis une par échéance annuelleUne facture consolidée par mois, reprenant tout le parc
Facture systématique ?Non — hors anniversaire, une facture n'est créée que s'il y a dépassementOui — à chaque anniversaire mensuel, quoi qu'il arrive
ProrataCalculé une fois à l'ajout, puis figéCalculé par mouvement, consolidé mensuellement
Engagement1, 2 ou 3 ans au choix, payé intégralement d'avanceNon défini à ce jour
ÉtatEn placeEn développement

Côté base, la structure est identique dans les deux cas : un abonnement porte une à N lignes de jauge. Ce qui diffère, c'est la fréquence, le réglage du stock, et la condition de génération de facture.

Ce qui change dans la version en cours de développement Jusqu'ici, chaque type d'abonnement produisait sa propre facture et son propre prélèvement : un gestionnaire avec un abonnement de base, du Bronze et du Gold recevait trois factures et subissait trois prélèvements par mois. La cible est une facture unique, ce qui impose de retirer la récurrence Stripe sur les prix des jauges — décidé le 22 mai, confirmé le 10 juin. Dans cette cible, seul l'abonnement de base reste un abonnement Stripe récurrent ; le forfait device, les plans et les proratas sont injectés en lignes variables par la tâche planifiée avant la date anniversaire. Conséquence à lire en §11.

6.L'état d'une jauge

Deux choses à ne pas confondre : ce que la base porte aujourd'hui, et le cycle de vie qui a été conçu mais jamais mis en place.

Ce que porte ObjectsIoT.ActivityState aujourd'huiEn place

Un état technique de fonctionnement, écrit par les services de Serge. Cinq valeurs :

ValeurSignification
99Non évalué — la sonde n'a pas encore émis
1En fonctionnement
0Arrêtée — message STOP reçu
-1Arrêt anormal
-2Inconnu

Source : documentation de l'API REST publique api.iot-link.app/v1, version du 12 juin 2026, rédigée par Serge. En pratique, les valeurs rencontrées dans la base sont surtout 99, 1 et -1.

Cet état ne dit rien de la facturation Il décrit ce que fait la sonde, pas ce qu'elle coûte. Aucune valeur ne distingue une sonde encore en fabrication d'une sonde en stock prête à poser, ni une sonde arrêtée à la demande du client d'une sonde coupée pour impayé. Ne pas chercher un signal de facturation dans ce champ : il n'y en a pas.

Le cycle de vie conçu, jamais mis en placeNon tranché

Six statuts nommés ont été définis pour que l'état d'une jauge commande à la fois le plan Thingstream — donc le coût de connectivité — et l'état de facturation. Ce modèle n'existe aujourd'hui ni dans la base ni dans le code.

Statut viséSituationPlan ThingstreamFacturation
NON_ASSEMBLEEeSIM importée, sonde pas encore construiteInactifAucune
EN_TESTAssemblage et tests usineActif temporairementDémarre
PRETE_ACTIVATIONEn stock ou vendue, en attente d'abonnementInactifAucune
ACTIVEAbonnement souscrit et premier démarrage aimant effectuéActifEn cours
ARRETEELe client a demandé l'arrêt, un STOP a été envoyéActif si l'abonnement l'estContinue
ARRETEE_NON_PAIEMENTDésactivée pour défaut de paiementInactifSuspendue

Ce que ce modèle apporterait : la distinction entre fabrication, stock et service, et surtout le lien explicite entre l'état d'une sonde et sa facturation. Le point contre-intuitif à retenir est que ARRETEE ne signifierait pas « plus facturée » — un client qui demande l'arrêt des remontées continue de payer son abonnement jusqu'à sa résiliation effective.

Ce champ ne se change pas côté portail ActivityState est écrit par les services de Serge, pas par le portail. Passer du modèle actuel au modèle cible n'est donc pas une modification de l'analyse ni du code de facturation : c'est un arbitrage à trois — Michael, Serge et Franck — qui touche la chaîne de traitement des messages. Ouvert depuis le 2 juin, jamais tenu.

7.La date anniversaireEn place

C'est le principe qui commande toute la tâche planifiée. Il surprend souvent.

Toutes les factures sont calées sur la date anniversaire de souscription, jamais sur le 1er du mois. Un gestionnaire qui a souscrit un 17 est facturé le 17 de chaque mois. Son « mois » va du 17 au 16.

Conséquence pratique Quand on parle d'une jauge « ajoutée en cours de mois », il faut lire « en cours de cycle ». Le cycle est propre à chaque abonnement. Deux gestionnaires voisins n'ont ni la même date de facture, ni la même période de prorata.

8.Les cas, déroulés

Chaque situation avec ce qui se passe concrètement. Les montants sont illustratifs — la grille tarifaire n'est pas arrêtée. Les exemples de prorata utilisent un plan Gold à 4,99 € par mois sur un cycle de 30 jours.

A · Un particulier équipe sa citerneEn place
Modèle X · CustomerType 1
  1. Il achète une sonde et souscrit sur le portail. Il choisit un engagement : 1, 2 ou 3 ans.
  2. Un StripeSubscriptions est créé, annuel, avec sa propre date anniversaire.
  3. Une ligne SSO est créée pour sa jauge : Processed = TRUE, MontantProrata = 0. Pas de prorata, puisque son cycle démarre le jour même.
  4. La totalité de l'engagement est prélevée en une fois.
  5. La sonde commence à émettre au premier démarrage aimant : son état technique passe à 1.
Ensuite : aucune facture intercalaire. Rien ne sort avant l'échéance suivante, sauf si un dépassement de messages est constaté.
B · Un gestionnaire démarre, sans aucune sondeDécidé
Modèle Y1-B · CustomerType 2
  1. Il souscrit l'abonnement de base. Un StripeSubscriptions master mensuel est créé.
  2. Aucune ligne SSO : il n'a pas de jauge.
  3. Facture mensuelle : une seule ligne, l'abonnement de base — 100,00 €.
Un gestionnaire à zéro sonde est un cas valide : la base seule lui ouvre le portail. Le portail doit donc autoriser la souscription d'un abonnement de base sans jauge.
C · Il reçoit dix sondes, qui restent en stockDécidé
Le réglage BillStockDevice décide

Si TRUE — les jauges en stock sont facturées :

Abonnement de base                  100,00 €
Forfait device      10 × 0,75 €       7,50 €

Si FALSE — le stock n'est pas facturé :

Abonnement de base                  100,00 €
Une bascule de ce réglage prend effet au cycle suivant, jamais en cours de cycle — c'est délibéré, pour ne pas créer un déclencheur de prorata supplémentaire. Le nombre de jauges est un instantané au jour de facturation : peu importe quand elles sont arrivées.
D · Il pose une sonde chez un client, sans souscrire de planEn place
Appairage sans connectivité
  1. La sonde est associée à une citerne du client final.
  2. Aucun abonnement de connectivité n'est requis pour cette opération : l'abonnement de base du gestionnaire suffit.
  3. La jauge est liée mais n'émet rien : son plan de connectivité n'est pas activé.
Ce point a coûté du temps par le passé : un message d'erreur laissait croire qu'un abonnement était nécessaire pour appairer. Ce n'est pas le cas.
E · Il active un plan en cours de cycleDécidé
Le cas le plus fréquent — et celui qui génère du prorata

Cycle du 1er au 30. Une jauge Gold est activée le 15.

  1. Une ligne SSO est créée : IDStripePrices = le prix Gold, StartDate = 15, EndDate = NULL, IsResilie = FALSE.
  2. MontantProrata est calculé sur les jours restants du cycle — 16 jours sur 30 → +2,66 € — et Processed reste à FALSE.
  3. Aucun appel Stripe à ce moment. On ne pousse rien au fil de l'eau et le client ne paie pas immédiatement.
  4. À l'anniversaire, la tâche planifiée somme les proratas non traités, pousse une ligne unique, et bascule Processed à TRUE.
Pourquoi consolider : un gestionnaire qui active quinze jauges dans le cycle produirait quinze lignes sur sa facture, et chaque ligne ajoutée à une facture Stripe est un appel d'API supplémentaire dans la tâche planifiée. Une seule ligne de prorata consolidé les remplace.

Le détail reste disponible, et c'est ce qui rend la consolidation acceptable. Le fichier StripeInvoicesDetails reçoit une ligne par jauge — prix, période, montant — et chaque ligne d'abonnement pointe vers la facture qui l'a portée. À la question « ce prorata de 47,32 €, ça correspond à quoi ? », la réponse se lit sonde par sonde, numéros de série compris, sans refaire le calcul. Montage classique en télécom : facture synthétique, détail consultable.

F · Une jauge change de plan en cours de cycleDécidé
Bronze → Gold le 15 · principe d'immuabilité
  1. La ligne SSO existante est close : EndDate = 15, IsResilie = TRUE. Elle n'est pas modifiée au-delà.
  2. Une nouvelle ligne est créée pour le plan Gold, à partir du 15.
  3. Chaque ligne porte son propre prorata sur sa portion de cycle : une correction négative sur le Bronze non consommé, un prorata positif sur le Gold.
On n'écrase jamais l'historique : on clôt et on recrée. C'est ce qui permet de répondre plus tard à « quel plan cette jauge avait-elle en juin ? ». Ce cas ne peut pas fonctionner aujourd'hui : la cardinalité n'autorise qu'une seule ligne par jauge.
G · Une jauge revient en stock en cours de cycleNon tranché
Deux règles possibles, aucune décidée

Sonde activée le 15, retournée en stock le 25. La question a été posée le 22 mai et n'a jamais été tranchée : facture-t-on les dix jours réellement utilisés, ou le cycle entamé en entier ?

Règle A — correction proratisée. Une ligne négative annule la part non consommée :

Ligne 1   Qte +1    MontantProrata  +2,66 €   (16 jours, à l'entrée)
Ligne 2   Qte -1    MontantProrata  -1,00 €   (6 jours non utilisés)
                                    ─────────
Net consolidé                        +1,66 €   = 10 jours d'usage réel

Règle B — cycle entamé dû. Aucune correction. Le prorata reste appliqué à l'entrée, la sortie ne produit rien. Plus simple à coder, plus simple à expliquer, moins précis pour le client.

Le choix est commercial, pas technique. Tant qu'il n'est pas fait, ne rien coder sur ce cas. La convention de comptage des jours — bornes incluses ou non — devra être fixée en même temps.
H · Le client final paie sa propre jaugeEn place
Le mécanisme WhoPays
  1. La sonde appartient au gestionnaire ou au client, peu importe : c'est ObjectsIoT.IDCustomer.
  2. ObjectsIoT.WhoPays pointe vers le client final : c'est lui qui est facturé pour cette jauge.
  3. Il relève du modèle X : abonnement annuel propre, payé d'avance.
La granularité est à la jauge. Un même gestionnaire peut prendre en charge certaines sondes et laisser ses clients payer les autres, dans le même parc.
I · Une jauge dépasse son quota de messagesDécidé
Facturé à part, jamais fondu dans la ligne de plan
  1. La tâche vérifie les dépassements sur les 30 jours précédant la date anniversaire mensuelle de chaque sonde — pas sur le mois calendaire, pas sur le cycle du gestionnaire.
  2. S'il y a dépassement, une ligne ProductsType = 5 est produite.
  3. Pour un gestionnaire, cette ligne s'ajoute à sa facture mensuelle déjà prévue.
  4. Pour un client final, une facture est créée uniquement s'il y a dépassement — sinon rien ne sort entre deux échéances annuelles.
Le surcoût passe par un produit Stripe dédié parce que Stripe reprend le libellé du prix : on ne peut pas ajouter une ligne de description libre sur une facture d'abonnement. La marge appliquée au-dessus du coût de connectivité n'est pas tranchée.
J · Un pack de SMS de notificationEn place
Système totalement séparé
  1. Achat ponctuel d'un pack. Facture séparée, sans abonnement associé.
  2. Chaque alerte envoyée consomme un crédit.
  3. Crédit épuisé → les notifications SMS s'arrêtent. Pas de blocage de la sonde, pas d'achat automatique, pas de facturation supplémentaire.
C'est le cas qui impose que StripeInvoices.IDStripeSubscriptions puisse être vide : une facture de pack SMS n'a pas d'abonnement. Elle est rattachée par IDStripePurchaseSMS, et IDCustomer permet de retrouver le client.
K · Un impayéNon tranché
Cycle nominal décrit, mise en œuvre à concevoir
  1. Le traitement quotidien détecte le défaut de paiement.
  2. Rappel automatique au client.
  3. Après le délai de grâce, une commande STOP est envoyée à la sonde.
  4. Réception du message de confirmation d'arrêt effectif.
  5. Désactivation du plan Thingstream via API.
  6. Statut → ARRETEE_NON_PAIEMENT, qui n'existe pas encore (voir §6).
Réactivation : seule la validation d'un paiement dans le portail réactive le plan. La sonde réémet au démarrage aimant suivant.
Divergence à ne pas ignorer sur le dunning d'un gestionnaire Le comportement natif Stripe sur un abonnement multi-lignes est un dunning consolidé : un prélèvement raté fait basculer tout l'abonnement en impayé — base, device, tous les plans. Pour un gestionnaire portant plusieurs milliers de jauges installées chez ses clients finaux, couper l'ensemble du parc sur un seul incident de paiement a été jugé inacceptable. Traitement cible : rappels, puis blocage manuel de l'accès au portail, sans coupure automatique de la connectivité, avec cascade par WhoPays. À concevoir — ne pas implémenter le comportement natif sans arbitrage.
L · La formule tout comprisEn place
Leasing · ProductsType = 1

Matériel et service fondus dans une mensualité unique, sans investissement de départ. Cet abonnement remplace l'abonnement de base et tous les abonnements de jauge : il n'y a ni forfait device ni plan par sonde à côté. Déjà en production.

M · Une sonde change de mainsNon tranché
Revente, don, retour vers le gestionnaire

Un client final arrête d'utiliser sa sonde avant la fin de son engagement — il déménage, il n'a plus de citerne, il la donne. Deux besoins ont été exprimés en mai et aucun n'a été traité : pouvoir délier la sonde du compte de son propriétaire, et pouvoir la réintégrer chez un gestionnaire pour la replacer ailleurs.

Ce qui est acquis : un abonnement payé n'est pas remboursé. Le client garde l'usage jusqu'au terme qu'il a payé. La date de fin est posée, et la tâche planifiée annule l'abonnement dans Stripe le moment venu.

Ce qui manque : le mécanisme de transfert lui-même. La modification de cardinalité le rend techniquement possible — un transfert devient une ligne close et une ligne créée sous un autre abonnement — mais la règle métier n'existe pas.

9.Le prorata en détail

Deux mécaniques, une par modèle. Ne pas les confondre.

Modèle X — la règle des « poupées russes »En place

Modèle Y1-B — trois phasesDécidé

Orthogonalité à bien avoir en tête Processed répond à « ai-je déjà facturé le prorata de cette ligne ? ». EndDate répond à « cette jauge est-elle encore active pour les cycles à venir ? ». Ce sont deux questions indépendantes, et les quatre combinaisons existent. Pour compter les jauges actives : WHERE EndDate IS NULL. Pour calculer les proratas dus : WHERE Processed = FALSE.
Une exception à connaître Le forfait device n'est pas proratisé (décision du 10 juin). Il est facturé en instantané au jour de facturation — nombre de jauges facturables × tarif — sans ligne de correction. Une jauge entrée en cours de cycle paie un cycle plein de forfait device. Le grain à la journée est réservé aux plans de connectivité.

10.Les pièges à connaître

Chacun a déjà coûté du temps à quelqu'un.

Un numérique vide se lit 0 en WLanguage

La lecture WLanguage d'une rubrique numérique nullable renvoie 0, pas NULL. Pour distinguer une valeur réellement à zéro d'une valeur absente, il faut EstNull(), ou une requête SQL avec IS NULL explicite. Corollaire : tester une date par = "" ne détecte pas une date absente.

L'analyse fait foi, pas l'export SQL

Le DDL exporté d'une base HFSQL ne contient ni les cardinalités, ni l'intégrité référentielle : elles vivent dans l'analyse et sont appliquées par le moteur côté application. Une clé étrangère peut apparaître nullable dans l'export et être parfaitement protégée dans les faits. Et l'inverse : une rubrique présente dans l'analyse peut manquer dans la base tant que la modification automatique des fichiers n'a pas été passée.

Une facture Stripe demande cinq appels d'API

Créer une facture pour un client final enchaîne la création de la facture, l'ajout de ses lignes, la finalisation, la création de l'intention de paiement, puis sa confirmation. C'est ce qui rend la tâche planifiée lourde en appels réseau, et c'est pourquoi elle est le point sensible du dispositif.

Deux sens du mot « Lead »

Customer.IDCustomerLead désigne le parent commercial dans la hiérarchie des clients. Les champs …Lead côté Stripe désignent tout autre chose — un device associé. Aucun rapport entre les deux.

La 2G ne doit plus apparaître

La technologie n'est plus certifiée sur le matériel récent. Elle ne doit être exposée nulle part : ni dans l'affichage du type de réseau au portail, ni dans la documentation. La cible est LTE-M et NB-IoT.

11.Ce qui reste à faire et à trancher

À savoir avant de lire le code et de s'étonner.

Neuf modifications attendent dans l'analyseDécidé

Une partie de ce qui est décrit ci-dessus n'est pas encore implémentable : la cardinalité n'autorise qu'une seule ligne d'abonnement par jauge, les rubriques IDStripePrices, IsResilie et IDStripeInvoices n'existent pas, et les deux fichiers d'historique ne sont pas créés. Concrètement, le changement de plan du cas F ne peut pas fonctionner comme écrit. Ces modifications font l'objet d'un document dédié.

L'état réel du déploiement n'est pas établiQuestion ouverte

Le passage à la facture consolidée était en développement en juin, une partie en local. Ce qui tourne aujourd'hui en production sur la partie gestionnaire — facture unique ou factures séparées, récurrence Stripe retirée ou non — n'est pas connu de ce document. C'est la première chose à faire confirmer.

Le détail d'une facture n'est pas consultable au portailÀ développer

Les modifications 4 et 8 stockent la composition de chaque facture, jauge par jauge. L'écran qui l'affiche au gestionnaire quand il ouvre une facture reste à faire — c'est lui qui rend la ligne de prorata consolidée défendable sans intervention humaine.

La tâche planifiée n'est pas supervisée — le point le plus lourd du dossier Dans la cible, seul l'abonnement de base est un abonnement Stripe récurrent. Tout le reste — forfait device, plans, proratas — est injecté par la tâche planifiée. Si elle échoue ou ne s'exécute pas, la facturation est silencieusement incomplète : pas d'erreur visible, pas de réclamation client, personne ne s'en aperçoit. Il n'existe aujourd'hui ni alerte, ni réconciliation, ni rattrapage. Aucune des neuf modifications de l'analyse ne règle ce point.

Le cycle de vie d'une jauge n'est pas en placeNon tranché

ActivityState ne porte aujourd'hui qu'un état technique de fonctionnement, sans lien avec la facturation. Les six statuts conçus en juin n'existent ni dans la base ni dans le code, et le champ est écrit par les services de Serge : c'est un arbitrage à trois, pas une modification de l'analyse. Détail en §6.

Décisions commerciales non prisesNon tranché