fix(data): import bundled transactionnel + isDataLoaded fiable #10

Closed
opened 2026-06-23 20:51:16 +02:00 by CyrilLeblanc · 0 comments
Owner

Contexte

L'import des données bundled (TransitRepository.importBundledData, data/repository/TransitRepository.kt:92-115) enchaîne 6 inserts DAO (clusters, lines, sequences, clusterLines, geometries, physicalStops) sans transaction. Si le process meurt en cours (mémoire basse, utilisateur tue l'app au premier lancement), Room reste à moitié rempli.

Pire, isDataLoaded() (:86-88) ne vérifie que clusterDao.getAll().isNotEmpty() : un import partiel où les clusters ont atterri mais pas les géométries/séquences est considéré comme « chargé » à jamais → carte/ETAs silencieusement cassés jusqu'à l'effacement des données de l'app.

Comportement attendu

  • Import atomique : les 6 inserts dans une seule transaction Room — tout passe ou rien ne passe.
  • isDataLoaded fiable : un import partiel ne doit jamais être rapporté comme complet. Préférable : une ligne sentinelle / data_version écrite en dernier (présente ⇔ import complet), sinon un EXISTS conjoint sur les tables critiques.

Pistes d'implémentation

  • Envelopper les 6 insertAll dans db.withTransaction { … } (atomique + plus rapide : un seul commit WAL).
  • isDataLoaded() : lire la sentinelle data_version (ou EXISTS conjoint clusters + lines + geometries) ; absent/incomplet → false → relance l'import.
  • Hors scope (à suivre) : invalidation des assets .six/.mbtiles régénérés, et fallbackToDestructiveMigration manquant — sujets distincts.

Critères d'acceptation

  • L'import est atomique : un échec/kill mid-import laisse la base vide, pas partielle.
  • isDataLoaded() retourne false sur un import partiel (relance au prochain lancement).
  • Import nominal inchangé (premier lancement correct, données complètes).
  • assembleDebug/assembleRelease OK ; pas de régression chargement/carte/ETAs.
## Contexte L'import des données bundled (`TransitRepository.importBundledData`, `data/repository/TransitRepository.kt:92-115`) enchaîne 6 inserts DAO (clusters, lines, sequences, clusterLines, geometries, physicalStops) **sans transaction**. Si le process meurt en cours (mémoire basse, utilisateur tue l'app au premier lancement), Room reste à moitié rempli. Pire, `isDataLoaded()` (`:86-88`) ne vérifie que `clusterDao.getAll().isNotEmpty()` : un import partiel où les clusters ont atterri mais pas les géométries/séquences est considéré comme « chargé » à jamais → carte/ETAs silencieusement cassés jusqu'à l'effacement des données de l'app. ## Comportement attendu - **Import atomique** : les 6 inserts dans une seule transaction Room — tout passe ou rien ne passe. - **isDataLoaded fiable** : un import partiel ne doit jamais être rapporté comme complet. Préférable : une ligne sentinelle / `data_version` écrite **en dernier** (présente ⇔ import complet), sinon un `EXISTS` conjoint sur les tables critiques. ## Pistes d'implémentation - Envelopper les 6 `insertAll` dans `db.withTransaction { … }` (atomique + plus rapide : un seul commit WAL). - `isDataLoaded()` : lire la sentinelle `data_version` (ou `EXISTS` conjoint clusters + lines + geometries) ; absent/incomplet → `false` → relance l'import. - Hors scope (à suivre) : invalidation des assets `.six`/`.mbtiles` régénérés, et `fallbackToDestructiveMigration` manquant — sujets distincts. ## Critères d'acceptation - [ ] L'import est atomique : un échec/kill mid-import laisse la base vide, pas partielle. - [ ] `isDataLoaded()` retourne `false` sur un import partiel (relance au prochain lancement). - [ ] Import nominal inchangé (premier lancement correct, données complètes). - [ ] `assembleDebug`/`assembleRelease` OK ; pas de régression chargement/carte/ETAs.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
CyrilLeblanc/gresit#10
No description provided.