Aller au contenu

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 rend changeModeBottomSheet issu 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 : useChangeModeSubmit lit 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 callback createAction.
  • Compteur Linkfeel : le compteur de crédits (value issu de useChangeModeForm, borné aux crédits restants) est passé comme tokenCount à la mutation updateMode, 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.