Files
GameTime/.ideai/tickets/172/carnet.md

5.5 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#172 2
kind agent_id
agent 57695b92-24d0-4876-837c-76116e70a6ae
1785272880017

#172 — Cadrage Main (2026-07-28)

Décision produit

Direction validée :

  • la montre reste un capteur + télécommande ;
  • le téléphone reste source de vérité métier ;
  • on optimise le trafic et la chauffe par batching côté montre, pas par déplacement de logique métier.

1. Télémétrie stats montre

Deux modes à cadrer :

  • écran montre allumé : cadence plus fréquente pour un live crédible ;
  • écran montre éteint / ambient : flush agrégé toutes les ~30s, inspiré du comportement observé sur Heavy.

La montre ne calcule pas les agrégats métier finaux. Elle bufferise seulement des échantillons ou micro-agrégats transport :

  • FC : min/max/moy locale de fenêtre + latest utile à l'affichage ;
  • distance/calories : latest cumulée de fenêtre, jamais recalcul métier final ;
  • timestamps de capture et contexte d'exécution.

Le téléphone :

  • persiste ;
  • fusionne ;
  • construit les agrégats de séance / étape / série / exercice / historique ;
  • résout les conflits et les trous.

2. Score manuel montre

Décision : oui au debounce 500ms, non au "score final sans contexte".

Le flux cible minimal :

  • la montre met à jour le score optimistement à chaque tap ;
  • chaque tap reset un timer de 500ms ;
  • au silence de 500ms, la montre envoie au téléphone une intention de type setManualScore contextualisée ;
  • le téléphone valide, persiste, reprojette ;
  • la montre se recale silencieusement sur la projection confirmée.

3. Garde-fous architecture

  • Pas de logique métier durable sur la montre.
  • Pas de calcul d'historique ni de règle d'invariants sur la montre.
  • Chaque message montre -> téléphone doit embarquer le contexte minimal : sessionId, indices d'exécution, baseRevision, horodatage.
  • Rejet/conflit côté téléphone : la projection confirmée gagne toujours.
  • Crash montre avant flush : perte limitée à la fenêtre non flushée, acceptable pour le score seulement si la montre ne prétend jamais avoir persisté côté téléphone.

4. Contrat à cadrer ensuite

Ticket attendu après celui-ci :

  • extension ou adaptation du contrat watch bridge pour batches télémétrie ;
  • ajout d'une commande contextualisée setManualScore ou équivalent ;
  • stratégie de flush explicite selon état écran / foreground / ambient ;
  • QA device sur chauffe, batterie, cohérence de resync.

Cadrage Architect (2026-07-28)

Statut : cadrage exploitable, prêt pour découpage dev.

Architecture cible minimale

  • Garder phone = source de vérité, watch = capteur + télécommande.
  • Conserver WatchCompanionCommandHandler comme point d'entrée unique des intentions montre.
  • Ajouter un flux applicatif téléphone dédié pour la télémétrie batchée : WatchTelemetryBatchIngress -> validation -> appel de WorkoutTelemetryUseCases.recordTelemetrySample(...) pour chaque sample -> WorkoutHistoryUseCases.updateHeartRateSummary(...) au flush final.
  • La montre ne calcule ni score final ni agrégats métier ; elle ne bufferise que du transport.

Télémétrie batchée watch -> phone

  • Recommandation : nouveau DTO WatchTelemetryBatch, schemaVersion = 5, nouveau path message /gametime/watch/telemetry-batch.
  • Le téléphone déduplique au niveau sample (sampleId stable), pas au niveau batch.
  • WatchSensorSummary est conservé pour le résumé final de séance, pas remplacé.

Stratégie interactive vs ambient/screenOff

  • interactive : flush toutes les 5s max.
  • ambient/screenOff : flush toutes les 30s max.
  • Flush immédiat aussi sur : fin de séance, pause explicite si la collecte s'arrête, reconnexion téléphone, changement d'état écran, buffer plein.
  • Cap de sécurité : couper les batches trop gros (~60 samples).
  • Une petite outbox locale de télémétrie côté montre est acceptable pour survivre à un crash : c'est du transport, pas du métier.

Score manuel debounce

  • Décision Architect : ne pas faire de setManualScore(value) comme contrat principal.
  • Recommandation : un batch d'intentions delta, type applyManualScoreDeltaBatch.
  • La montre accumule les taps +/- pendant 500 ms, puis envoie un seul delta net avec sessionId, position courante, baseRevision, horodatage.
  • Le téléphone applique le delta seulement si la cible métier est toujours la même ; sinon rejet et resync.

Invariants et risques

  • La montre ne calcule jamais la valeur finale du score.
  • Les écritures d'historique et agrégats durables restent côté téléphone.
  • Une intention score batchée n'est applicable que si sessionId + scope + position courante correspondent encore.
  • Les retries de télémétrie ne doivent jamais dupliquer les samples : sampleId stable obligatoire.
  • En cas de crash montre :
    • score pending perdu puis recalage sur projection téléphone ;
    • télémétrie non flushée reprise depuis l'outbox local.
  • En reconnexion :
    • resync projection immédiat ;
    • flush immédiat de l'outbox télémétrie ;
    • aucun replay d'anciennes intentions score.

Lots recommandés

  1. B1 [DevBackend] Contrat bridge v5 et ingress télémétrie batchée
  2. B2 [DevBackend] Application téléphone score debounce + validation de cible
  3. B3 [DevBackend] Déduplication, retries, flush final
  4. F1 [DevFrontend] Buffer montre télémétrie et stratégie interactive vs ambient
  5. F2 [DevFrontend] Score optimiste debounce 500 ms
  6. QA1 [QA] Matrice de cohérence et robustesse