§ 1.2 de l'audit, vérifié le matin même puis corrigé sur demande explicite de Sylvain — le gel du 22/09 est levé pour ce point seul, les quatre autres constats restent intouchés. Pourquoi celui-là d'abord : c'est le seul dont la conséquence est un chiffre faux affiché PENDANT l'effort, chez quelqu'un qui règle son intensité dessus. Les autres perdent de la donnée ou de la batterie, ça se rattrape. Une borne de zone périmée au poignet a déjà servi à décider. **L'envoi ne se tait plus.** `pushToWatch` avait quatre sorties silencieuses sur sept lignes ; il en a maintenant six, toutes nommées et journalisées — WatchConnectivity non supportée, session non activée, aucune montre appairée, app Watch non installée, encodage impossible, envoi refusé. Les deux gardes du milieu viennent de `CoachRoutineBridge`, qui les avait déjà : sans elles, l'absence de montre se confond avec un échec d'envoi. Le log de succès nomme ce qui compte — `zones=oui depuis=2026-08-12` — pour savoir quelles bornes sont au poignet sans ouvrir la montre. ⚠️ Un échec ne fait PAS échouer `setSnapshot`, contrairement à `CoachRoutineBridge` où l'envoi EST l'opération. Ici l'App Group est déjà écrit et les widgets iPhone rafraîchis : une montre verrouillée n'invalide rien. D'où un `resolve` enrichi (`watchPushed`, `watchReason`) plutôt qu'un `reject`, et `ok` conservé — aucun appelant JS ne casse. **La date de version voyage enfin.** `HeartRateZones` ne portait aucune date, alors que le backend sert une version figée et datée (règle 9 du CLAUDE.md web) : elle se perdait au transport, et après une révision rien au poignet ne distinguait les nouvelles bornes des anciennes. `zonesSince` et `zonesFrom` rejoignent le modèle en optionnels. Le serveur les servait déjà — c'est le JS du dépôt web qui ne les faisait pas monter. Trois tests au banc Linux : la date survit à `asOf()`, elle survit à l'aller-retour JSON (ce qui n'est pas encodé n'arrive jamais), et un snapshot antérieur à ces champs se décode toujours — un décodage qui lèverait laisserait la montre sans zones du tout, pire que des zones sans date. 91 verts (88 avant). ⛔ NON COMPILÉ. Syntaxe vérifiée (`swiftc -parse`), mais Capacitor, WatchConnectivity et SwiftUI n'existent pas sur Linux. Au prochain build : ouvrir la Console sur la catégorie `widget` et vérifier qu'une ligne « snapshot poussé vers la Watch · zones=oui depuis=… » apparaît au lancement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
24 lines
877 B
Swift
24 lines
877 B
Swift
// DOUBLURE DE TEST — n'existe que dans le banc d'essai Linux.
|
||
//
|
||
// Le vrai `HeartRateZones` (ios/App/App/HeartRateZones.swift) expose une
|
||
// propriété `color: Color` et importe donc SwiftUI, absent sur Linux.
|
||
//
|
||
// ⚠️ La doublure ne reproduit que les propriétés STOCKÉES, à l'identique : le
|
||
// seul usage qu'en fait `CoachWidgetSnapshot` est de les porter et de les
|
||
// (dé)coder. `asOf(_:)` ne fait que recopier le champ sans le lire. Si un jour
|
||
// la péremption devait TOUCHER aux zones, ce test cesserait d'être pertinent —
|
||
// et c'est écrit ici pour qu'on s'en aperçoive.
|
||
import Foundation
|
||
|
||
struct HeartRateZones: Codable, Equatable, Sendable {
|
||
var z1: [Int]?
|
||
var z2: [Int]?
|
||
var z3: [Int]?
|
||
var z4: [Int]?
|
||
var z5: [Int]?
|
||
var fcmaxUsed: Int?
|
||
var clinicalTargetBpm: Int?
|
||
var zonesSince: String?
|
||
var zonesFrom: String?
|
||
}
|