Skip to content

Mode hors ligne ​

API prête, mobile à faire Cette page décrit le fonctionnement prévu côté mobile. L'API a déjà tout ce qu'il faut (voir plus bas).

Le sujet demande deux choses :

  • un mode hors ligne avec synchronisation automatique (stockage local ou SQLite) ;
  • une explication de comment fonctionne le pointage hors ligne.

Aujourd'hui ​

SituationComportement actuel
Ouvrir un écran sans réseau« Serveur injoignable ». Si l'écran avait déjà chargé ses données, useQuery les garde affichées.
Pointer sans réseauLe pointage échoue, rien n'est enregistré.
SessionGardée : une erreur réseau ne déconnecte jamais.

Le principe ​

Le téléphone ne refuse jamais un pointage. Sans réseau, il l'enregistre localement avec l'heure du geste, puis l'envoie dès que le réseau revient.

Étape par étape ​

1. Détecter le réseau ​

Avec @react-native-community/netinfo, l'app sait à tout moment si elle est connectée. Un bandeau « Hors ligne » s'affiche en haut de l'écran.

2. Garder les données lues ​

Chaque réponse de lecture est enregistrée localement. Sans réseau, useQuery affiche la dernière version connue au lieu d'une erreur. L'historique, l'équipe et le tableau de bord restent lisibles.

3. Mettre les pointages en file d'attente ​

Sans réseau, un pointage (arrivée, départ, début ou fin de pause) est enregistré dans une file locale avec :

  • l'utilisateur ;
  • l'action ;
  • l'heure exacte du téléphone ;
  • un identifiant unique (pour ne jamais l'envoyer deux fois).

L'écran réagit tout de suite comme si le pointage était parti : statut, chrono, frise. Le bandeau indique « 1 pointage en attente ».

4. Synchroniser ​

Dès que le réseau revient (et à chaque ouverture de l'app) :

  1. les pointages sont envoyés dans l'ordre où ils ont été faits ;
  2. chaque pointage accepté est retiré de la file ;
  3. un pointage qui échoue reste dans la file, et l'app réessaie plus tard ;
  4. une fois la file vide, tout est rechargé depuis le serveur et le bandeau disparaît.

Ce que l'API sait faire maintenant ​

L'équipe backend a ajouté tout ce qu'il faut au mode hors ligne (pull requests #162 à #166, fusionnées dans main). Il ne reste qu'à l'utiliser côté mobile.

BesoinCe que l'API proposeCommit
Garder l'heure réelle du gestePOST /clocks/:id et /break acceptent un champ time (ISO 8601) : jamais dans le futur (1 minute de tolérance), au plus 72 h en arrière, jamais avant le dernier pointage, jamais dans une semaine validée. Le serveur note aussi quand il l'a reçu (received_at).a789c7e
Ne jamais inverser un pointage renvoyéUne action explicite (in / out, start / end) et un client_id (un UUID créé par le téléphone). Le même client_id renvoyé ne change rien et rend ce qui a été enregistré. Une action qui ne correspond pas à l'état répond 409 avec un code (already_clocked_in, not_clocked_in...).41acb76
Ne pas créer deux fois une demande de correctionPOST /corrections accepte aussi un client_id5e4f03b
Rester connecté sur un mauvais réseauPOST /auth/login avec "client": "mobile" renvoie les jetons dans la réponse (Bearer, sans cookie ni CSRF). Une réponse de renouvellement perdue ne déconnecte plus.365c63d

Sans corps de requête, rien ne change : l'app actuelle et le site web continuent de fonctionner pendant la transition.

Le problème de l'heure, décrit dans les versions précédentes de cette page, est donc réglé par l'option A : le champ time côté API, sans passer par une demande de correction.

Les cas particuliers ​

CasCe qui se passe
L'app est fermée avant le retour du réseauLa file est sur le téléphone, rien n'est perdu. L'envoi se fait à la prochaine ouverture.
Double appui ou file renvoyéeChaque pointage a son client_id : le serveur reconnaît un renvoi et ne l'enregistre qu'une fois.
Heure du téléphone trafiquéeL'API limite l'écart : 72 h au maximum, jamais dans le futur, jamais avant le dernier pointage.
Session expirée pendant la coupureLa file attend la reconnexion, puis elle est envoyée.
Le serveur refuse un pointage (409 : semaine validée, ordre impossible, chevauchement)Il est retiré de la file et l'utilisateur est prévenu, avec la possibilité de demander une correction.
Deux téléphonesChaque téléphone a sa file. L'API garde l'ordre grâce aux heures.

Les dépendances prévues ​

PaquetRôleDans Expo Go
@react-native-community/netinfoSavoir si on est connectéOui
expo-sqliteStocker le cache et la fileOui

Les deux s'installent avec npx expo install et fonctionnent sans « development build ».