Synchronisation des saisies du widget vers le serveur

`CoachQuickSync.flush()` envoie la file partagée vers POST /api/drinks et retire
les entrées transmises. Cible App uniquement : l'extension n'appelle jamais ce
code, elle n'a ni session ni droit de tenir une requête — c'est toute la raison
d'être de la file.

Le cookie de session du WebView est réutilisé plutôt que de refabriquer une
authentification qui divergerait.

Trois comportements voulus, documentés pour qu'on ne les « corrige » pas :
une entrée qui échoue reste en file et repartira — mieux vaut un doublon visible
qu'une saisie disparue ; un 400 est considéré comme traité, sans quoi un payload
refusé bloquerait la file indéfiniment ; la date est formatée en fuseau local,
pour qu'un verre bu à 23 h compte pour le jour où il a été bu.

Reste un appel à poser dans AppDelegate.applicationDidBecomeActive — le
one-liner est dans le runbook.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Sylvain Bettinelli
2026-08-06 13:06:28 +00:00
parent 7778e62c40
commit 823bfb2ab9
2 changed files with 106 additions and 8 deletions

View File

@@ -141,13 +141,21 @@ file, l'app la vide.
6. Builder sur un device réel — les App Intents ne s'exécutent pas de façon
fiable en simulateur.
### Ce qui reste à câbler côté app
### Synchronisation (fait — `CoachQuickSync.swift`, cible **App** seule)
La file `CoachQuickLog.pending()` doit être transmise au serveur à l'ouverture
de l'app, puis retirée par `CoachQuickLog.remove(ids:)` — **par identifiant, pas
en vidant la file** : une saisie faite pendant la synchronisation serait sinon
perdue sans laisser de trace. Endpoint : `POST /api/drinks`
(`drink_type`, `volume_ml`, `date`).
`CoachQuickSync.flush()` envoie la file vers `POST /api/drinks` et retire les
entrées transmises **par identifiant**. Reste à l'appeler depuis `AppDelegate` :
Tant que ce câblage manque, les saisies restent locales : le widget affiche une
flèche de synchronisation et son compteur reste juste.
```swift
func applicationDidBecomeActive(_ application: UIApplication) {
Task { await CoachQuickSync.flush() }
}
```
Comportements voulus, à ne pas « corriger » :
- une entrée qui échoue **reste en file** et repartira — mieux vaut un doublon
visible qu'une saisie disparue ;
- un **400** est considéré comme traité : le réessayer indéfiniment bloquerait
la file ;
- la date est formatée en **fuseau local** — un verre bu à 23 h compte pour le
jour où il a été bu.