Prototype PowerSync sous Capacitor
Version 1, 29 septembre 2026. Prépare les cinq points du §15 du protocole de synchronisation. Le code est dans prototypes/powersync-capacitor/, hors des workspaces du socle.
30/09/2026 (EC-041). Le test sur téléphone est reporté à un lot ultérieur (Lot 3). Il ne compte plus dans les critères de fin du Lot 0.
- Tout est préparé et vérifié dans un navigateur. Il reste à l’exécuter sur un vrai téléphone Android : c’est la partie manuelle.
- Le prototype réutilise les tables du socle (
sync.commande,sync.commande_resultat,app.appareil,app.parametre) et un petit schéma jetableproto(producteurs, parcelles, affectation). - Aucune règle métier dans le serveur du prototype : il fait l’idempotence, contrôle l’ordre des séquences et écrit le résultat.
- Aucune dépendance n’entre dans le socle. Les ADR (SDK Capacitor, service PowerSync) sont à rédiger seulement si le prototype conclut.
1. Ce qui est prêt
Section intitulée « 1. Ce qui est prêt »| Élément | Emplacement |
|---|---|
Service PowerSync (Open Edition 1.26.1), profil powersync du compose |
infra/docker-compose.yml, infra/powersync/ |
Stockage des compartiments : PostgreSQL, base powersync_storage |
infra/postgres/init-powersync.sql |
| Tables de test, graine, volume, nouvel appareil, nettoyage | prototypes/powersync-capacitor/sql/ |
| Serveur : JWKS, jeton de 5 minutes, réception des commandes | prototypes/powersync-capacitor/serveur/ |
| Application (Vite, TypeScript, Capacitor 8) | prototypes/powersync-capacitor/app/ |
| Essais du serveur et de la validation du jeton | pnpm essai:serveur |
2. Ce qui est déjà vérifié, sans téléphone
Section intitulée « 2. Ce qui est déjà vérifié, sans téléphone »Vérifications faites dans le navigateur intégré (WA-SQLite), avec le service PowerSync réel.
| Point du §15 | Résultat |
|---|---|
| 1. Table en insertion seule | Une commande est inscrite dans commande et commande_locale en une transaction locale. La file survit à un rechargement, part dans l’ordre par lots de 50, et le résultat redescend par commande_resultat (« prov. » disparaît). 300 commandes : saisie 0,7 s, envoi et résultats 6,3 s ; 306 commandes et 306 résultats côté serveur, séquences 1 à 306, aucun doublon |
| 3. Colonne GeoJSON | Le déclencheur tient le texte GeoJSON ; la géométrie PostGIS n’est pas envoyée (colonnes explicites dans les règles). 3 499 parcelles reçues, 2,30 Mo de GeoJSON |
| 4. Jeton de l’API validé par JWKS | PowerSync lit la clé publique du serveur et accepte le jeton. Il refuse un jeton expiré, une signature d’une autre clé et une audience inconnue. Le serveur refuse tout jeton à un appareil révoqué (403) |
| 5. Volume | 2 000 producteurs et 3 499 parcelles dans le périmètre : 8,1 Mo de stockage dans le navigateur, pour une cible de 20 Mo. Les 500 producteurs d’un autre groupement ne descendent pas |
Le serveur applique aussi SP-01 (même commande envoyée deux fois : un seul enregistrement), SP-03 (trou de séquence : arrêt avant la commande) et SP-04 (même identifiant, contenu modifié : rejet), et borne la date d’opération à l’heure de réception (§6.4, règle 5).
3. Ce qui reste : le téléphone
Section intitulée « 3. Ce qui reste : le téléphone »Le point 2 ne se vérifie pas dans un navigateur : SQLite natif contre WA-SQLite, tenue sur trois jours de données, redémarrage de l’application. Les mesures de performance et de volume du point 5 doivent aussi être refaites sur un téléphone d’entrée de gamme.
Prérequis (à la charge de l’utilisateur)
Section intitulée « Prérequis (à la charge de l’utilisateur) »- Un téléphone Android (API 24 ou plus), mode développeur et débogage USB activés, sur le même réseau Wi-Fi que le poste.
- Android Studio, un JDK 17 ou plus, et
adb(paquetplatform-tools, absent du SDK local au moment de la préparation). - Docker et Node 22.
Démarrage sur le poste
Section intitulée « Démarrage sur le poste »-
Démarrer la base et le service :
Fenêtre de terminal docker compose -f infra/docker-compose.yml up -d --wait postgres# migrations (dbmate), puis :psql "$DATABASE_URL" -f prototypes/powersync-capacitor/sql/prototype.sqlpsql "$DATABASE_URL" -f prototypes/powersync-capacitor/sql/graine.sqlpsql "$DATABASE_URL" -f prototypes/powersync-capacitor/sql/volume.sqldocker compose -f infra/docker-compose.yml --profile powersync up -d powersyncLa base
powersync_storagen’est créée que sur un volume neuf (down -vavant, si le volume existe déjà). -
Démarrer le serveur du prototype :
Fenêtre de terminal cd prototypes/powersync-capacitorpnpm install && pnpm cles && pnpm serveur # écoute sur 0.0.0.0:3100pnpm essai:serveur # doit afficher « ok » partout, y compris PowerSyncSi la base n’est pas sur le port 5432, définir
APP_DATABASE_URLetDATABASE_URL. -
Trouver l’adresse IP du poste sur le réseau Wi-Fi. Le service PowerSync (
8081) et le serveur (3100) doivent être joignables depuis le téléphone (pare-feu du poste).
Installation sur le téléphone
Section intitulée « Installation sur le téléphone »cd prototypes/powersync-capacitorpnpm android:ajouter # une fois : génère le projet Androidpnpm android:lancer # construit, synchronise et lance sur le téléphone branché en USBDans l’application, saisir http://<IP du poste>:3100 et http://<IP du poste>:8081, puis « Se connecter ». Le code d’appareil est PROT1. Sans réseau au premier lancement, l’application refuse d’enregistrer : l’enrôlement se fait en ligne.
Le paramètre ?sdk=web dans l’adresse (navigateur) ou le choix du SDK dans le code permet de comparer avec le SDK web seul dans la WebView.
Grille de tests sur le téléphone
Section intitulée « Grille de tests sur le téléphone »| N° | Test | Résultat attendu |
|---|---|---|
| T1 | Connexion en ligne | « Connecté » ; 2 000 producteurs, 3 499 parcelles, environ 2,3 Mo de GeoJSON |
| T2 | Enregistrer une commande en ligne | Résultat « acceptee » en moins de 5 s |
| T3 | Mode avion, enregistrer 10 commandes, fermer et rouvrir l’application | 10 commandes en attente conservées, dans l’ordre |
| T4 | Rétablir le réseau | 10 résultats reçus, aucun doublon côté serveur, séquences continues |
| T5 | Trois jours de données : « Générer 300 commandes » plusieurs fois hors ligne, puis reconnexion | Envoi complet sans perte ni doublon ; noter durée et volume (SP-14) |
| T6 | Redémarrer le téléphone hors ligne, puis se reconnecter | Aucune perte, séquences continues |
| T7 | Jeton : laisser l’application connectée plus de 5 minutes | Jeton renouvelé sans coupure |
| T8 | Révoquer l’appareil côté base, puis se reconnecter | Plus de jeton (403) ; les commandes restent sur le téléphone |
Après avoir vidé les données de l’application, l’appareil doit être enrôlé à nouveau : psql -v code=PROT2 -f sql/nouvel-appareil.sql, puis saisir PROT2. Sinon le serveur signale un trou de séquence, ce qui est le comportement voulu (protocole §12).
4. Grille de résultats à remplir
Section intitulée « 4. Grille de résultats à remplir »| Point du §15 | Test | Constat sur téléphone | Décision |
|---|---|---|---|
| 1. Table en insertion seule | T3, T4, T6 | ||
| 2. SDK Capacitor (natif) ou SDK web | T1 à T6, comparaison ?sdk=web |
||
| 3. Colonne GeoJSON | T1 | ||
| 4. Jeton de l’API | T7, T8 | ||
| 5. Volume et performance (téléphone d’entrée de gamme) | T1, T5 |
5. Limites et réserves connues
Section intitulée « 5. Limites et réserves connues »- SDK Capacitor en bêta (version 0.9.x). Il exige Capacitor 8. Pas de chiffrement de la base sur mobile. Sur Android,
executene traite comme requête qu’une instruction qui commence parselect: pas d’INSERT … RETURNING. Le prototype s’y conforme. - Règles de synchronisation. Le prototype utilise le format
bucket_definitionsdu protocole (§7.2). PowerSync recommande désormais les « sync streams » ; à trancher avant d’écrire les règles définitives. - Navigateur intégré de l’application Claude. Il bloque le réseau des workers partagés : le prototype s’y ouvre avec
?monotab=1. Ce réglage ne concerne pas Android. - Licence. Le service PowerSync est sous licence FSL, à faire relire (ADR 0017). Hors périmètre du prototype.
- Authentification. Le serveur du prototype n’appelle pas Keycloak : l’organisation vient de la requête, là où l’API la tirera du jeton Keycloak (protocole §12). À remplacer, pas à réutiliser.
- Trafic en clair. L’application autorise le HTTP vers le réseau local (développement uniquement).
6. Décisions à tirer du prototype
Section intitulée « 6. Décisions à tirer du prototype »- SDK natif ou SDK web dans la WebView (point 2) : critère, tenue sur trois jours et après redémarrage.
- Budget de 20 Mo par téléphone : à confirmer sur un périmètre réel de 2 000 producteurs (point 5).
- Fusion des règles de synchronisation en « sync streams » ou maintien de
bucket_definitions. - ADR à rédiger si le prototype conclut : jeton PowerSync émis par l’API, écriture par commandes et file de contrôle, application terrain sous Capacitor.
- Le protocole est modifié si un point échoue (par exemple l’ordre de la file d’une table en insertion seule).
7. Retrait
Section intitulée « 7. Retrait »psql "$DATABASE_URL" -f prototypes/powersync-capacitor/sql/nettoyage.sql, puis suppression du dossier prototypes/ et du profil powersync du compose si le prototype est abandonné.