--- id: "67ec03c4-2fba-491c-9b87-a9bd219ea7a7" number: 95 title: "#91-A [DevBackend] Contrats watch bridge partagés + façade WatchCompanionUseCases" status: "closed" priority: "medium" sprint: null links: [] agentRefs: [{"agentId":"10ee045b-1c41-479e-ba03-dceed9edd495","role":"assigned"}] createdBy: {"kind":"agent","agent_id":"57695b92-24d0-4876-837c-76116e70a6ae"} updatedBy: {"kind":"agent","agent_id":"57695b92-24d0-4876-837c-76116e70a6ae"} createdAt: 1784991949110 updatedAt: 1784991949110 version: 1 --- Partie #91. Cf. mémoires `gametime-architecture-watch-companion` et `gametime-ux-watch-companion`. Créer le package Dart partagé `packages/watch_bridge_contract/` avec les DTO/enums de transport versionnés : - `WatchCommandEnvelope { schemaVersion, commandId, type, sessionId, expectedRevision, sentAtEpochMs }` - enum `WatchCommandType` : startCurrentExercise, pauseSession, resumeSession, startPreparedTimedStep, skipCurrentStep, skipCurrentPassage, finishCurrentSet, skipCurrentSet, skipCurrentRest - enum `WatchCommandAck` : accepted, acceptedNoOp, rejectedStaleRevision, rejectedNotApplicable, rejectedNoActiveSession, rejectedSessionMismatch, rejectedPhoneBusy - `WatchSessionProjection` + `WatchTimerProjection` (champs exacts cf. mémoire archi) - Sérialisation JSON stable + versionnée (parsers tolérants pour champs futurs). Ajouter la façade `WatchCompanionUseCases` (port application) exposant les points d'entrée que l'adapter Android (D) implémentera : envoi de projection, réception/routing de commande. Pas de logique Android ici. Définition de done : package partagé créé, DTO/enums sérialisables, tests unitaires de sérialisation/deserialization (round-trip + champs manquants tolérés), `dart analyze` propre.