Feature : changeMode
Objectif
Permet à un utilisateur de basculer un capteur électronique DeltaV entre deux modes de mesure :
vibration— courbes d'accéléromètre, Linkfeel annuel.accelero_tilt— PPV / seuils instantanés, Linkfeel mensuel.
La feature présente un bottom-sheet expliquant ce qui change, consomme un crédit Linkfeel (Sigfox), et applique le changement soit directement via BLE (quand le téléphone est connecté au capteur), soit à distance via LTE/Sigfox (mis en file comme action distante).
API publique
import { ChangeMode, useChangeMode } from 'src/features/changeMode';
useChangeMode(opts)— hook d'intégration. Retourne{ changeMode, onChangeModeClose, changeModeBottomSheet }.ChangeMode— le composant bottom-sheet (normalement, on rendchangeModeBottomSheetissu du hook plutôt que ce composant directement).
Architecture
changeMode/
├── index.ts API publique : { ChangeMode, useChangeMode }
├── config.tsx getWhatChangeItems(t) : contenu « ce qui change » par mode (icônes/couleurs)
├── context/ ChangeModeContext — compose les hooks ; useChangeModeColors (Strategy par mode)
├── hooks/
│ ├── useChangeMode hook d'entrée (vérif Linkfeel → ouvre le sheet ou alerte)
│ ├── useChangeModeConsumables crédits Linkfeel/SIGFOX restants + token_validity
│ ├── useChangeModeForm compteur +/- borné aux crédits restants
│ └── useChangeModeSubmit branchement BLE-vs-LTE + mutation CHANGE_DELTA_V_MODE
├── components/ ChangeMode, ChangeModeContent (routeur d'étapes), ChangeModeFooter,
│ + WhatChange/ ModeChips/ Linkfeel/ LinkfeelIssue/ SubmitContent/ Summary/ AccordionList/
└── utils/ prorata.ts — calcul des jours de validité Linkfeel (dayjs)
Machine à états : type ChangeModeStep = 'form' | 'success_ble' | 'success_lte' | 'error'. Les modes proviennent de DeltaVMode (utils/hooks/sensorActions/types).
Décisions clés
- Pattern Strategy pour les couleurs (
useChangeModeColors) indexé sur le mode courant — selon les recommandations de CLAUDE.md sur le remplacement des switches par type. - BLE d'abord avec rollback :
useChangeModeSubmitlit le mode courant depuis l'appareil, le bascule, l'écrit, puis mute le backend ; en cas d'erreur GraphQL il fait un rollback du mode BLE. Si non connecté, il se rabat sur une action distante/LTE mise en file via le callbackcreateAction. - Compteur Linkfeel : le compteur de crédits (
valueissu deuseChangeModeForm, borné aux crédits restants) est passé commetokenCountà la mutationupdateMode, de sorte que l'utilisateur choisit combien de crédits Linkfeel le changement de mode consomme. - Suit l'architecture par module de feature ; c'est la variante centrée context/hook (à comparer avec
unitPreference, entièrement en couches).
Utilisation
Consommateur réel — src/utils/hooks/sensorActions/useSensorActions.tsx :
const { changeMode, changeModeBottomSheet } = useChangeMode({
id,
id_device: sensorState?.deviceId ?? '',
isConnected,
createAction: remote.createAction, // utilisé pour le chemin distant/LTE
});
// déclencher le flux :
<Button onPress={changeMode} />
// rendre le sheet quelque part dans l'arbre :
{changeModeBottomSheet}
changeMode() vérifie d'abord le statut Linkfeel via getLinkfeelStatus (utils/sigfox/utils) : si ACTIVE il ouvre le sheet, sinon il affiche une alerte « Linkfeel requis ».
Tests
La feature est à 100 % de couverture — tests co-localisés pour les hooks, les composants, le context, le rich-text de config et l'utilitaire prorata. Lancez :
yarn jest src/features/changeMode --coverage
Voir testing.md pour le pattern de test de hook (mock Apollo, reset des stores dans beforeEach).
Note
useChangeModeSubmit.tsx contient un cast de nombre magique // TODO PUT IN CONST qui mériterait un nettoyage.