Commit Graph

2 Commits

Author SHA1 Message Date
Sylvain Bettinelli
a29569c05c Les push natives ne sont branchées nulle part, et le README affirme l'inverse
Vérifié dans les deux dépôts : web/push_notify.py envoie via ntfy, en se
servant du token du device comme nom de topic. Aucun enregistrement de token
APNs côté serveur (recherche registerToken / /api/devices / device_token :
zéro résultat), et le web n'appelle jamais PushNotifications de Capacitor
(zéro résultat). La moitié native est prête — plugin installé, aps-environment
déclaré, remote-notification dans UIBackgroundModes — et personne ne la
branche. Pour recevoir un rappel, il faut installer l'app ntfy et s'abonner à
un topic.

Deux conséquences. Le README liste « ✅ Push notifications natives » comme
PREMIER argument de sa section anti-rejet Guideline 4.2 : l'argument ne tient
pas si un examinateur teste les rappels, et 4.2 est justement le risque de
cette architecture. Et une capability déclarée mais inutilisée tombe sous
2.3.1(a) (« hidden, dormant, or undocumented features »).

En contrepartie, le risque APNs que l'audit supposait en § 5.1 (token
production envoyé au sandbox, notification jetée silencieusement) est sans
objet : il n'y a pas d'APNs. Un item de moins, un plus sérieux à la place.

La décision est produit avant d'être technique : brancher la chaîne APNs, ou
assumer ntfy et retirer plugin + entitlement + la ligne du README. L'état
actuel est le seul qui cumule les inconvénients des deux.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 06:58:17 +00:00
Sylvain Bettinelli
b1e7cf6d47 Audit complet de l'app mobile : natif, conformité Apple, ergonomie
Trois axes, chaque constat marqué [vérifié] / [rapporté] / [doc] — la
distinction n'est pas cosmétique : un constat non revérifié relayé comme un
fait est la dérive que la règle 3 interdit.

Le plus grave (§1.1, vérifié ligne à ligne) : WorkoutManager.swift:199 garde la
dernière FC connue quand le capteur décroche, et :218 la réémet avec un
horodatage NEUF. Le watchdog de LiveStore ne peut donc jamais basculer en
.lost — il reçoit des samples frais. Au poignet, une FC morte s'affiche stable,
avec sa zone colorée, indéfiniment. Pour un post-infarctus sous bêtabloquants
qui lit ce chiffre pour décider d'une pente, ce n'est pas un bug d'affichage.

Quatre affirmations d'audits antérieurs corrigées, toutes vérifiées :
- la politique de confidentialité EXISTE (HTTP 200) — le TODO du README est
  périmé, et « missing privacy policy » circulait encore ;
- la suppression de compte EXISTE (5.1.1(v), motif de rejet fréquent) ;
- 88 tests Swift verts, pas 57 ;
- npm audit réellement propre, et aucun secret jamais commité (git log vide).

aps-environment = development n'est pas le problème qu'on croyait : Apple
documente que la valeur vient du provisioning profile et que TestFlight utilise
production. Le vrai risque est côté backend, sur l'endpoint APNs.

Côté produit : le mot « Démarrer » n'existe nulle part pour une séance
sportive, et widgets/today-session.html:6 documente un CTA que le markup ne
contient pas. L'app ne permet pas de démarrer une séance.

Ce qui n'a pas été audité est dit en § 7 — aucun build Xcode possible ici,
CoachPolarBLE non revu, backend non audité au-delà de l'ergonomie.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 06:55:20 +00:00