Readme

EBO <eric.bouhana@softalys.com> committé le 2026-07-23 18:49

a9a1f85a97668ea11b3d94515bbd50a8961ede62

1 parent(s)

3 fichiers modifiés +59 -3
M .gitignore
+2 -0
@@ -25,6 +25,8 @@ __pycache__/
25 25 *.pyc
26 26
27 27 .venv/
28 +#workspace
29 +EBII_mobileVCF.code-workspace
28 30
29 31 # QR codes — regenerated on-site with real SSID/pass/IP values
30 32 staging/*.png
M README.md
+6 -3
@@ -28,11 +28,14 @@ Sync **offline-first** avec un serveur [Projectiaon](https://github.com/) (ailia
28 28
29 29 **Prérequis serveur :** variable `AILIANCE_API_CLES` (clés API par utilisateur), endpoints `/api/auth/cle`, `/api/sync/status`, `/api/sync/pull` — voir le [plan serveur](../Projectiaon/docs/plans/sync_api_mobile_v1.md).
30 30
31 -**Configuration dans l’app :** Paramètres (engrenage) → URL HTTPS du serveur → identifiant + mot de passe → « Obtenir la clé » → retaper le mot de passe pour déchiffrer la clé API (stockée chiffrée sur l’appareil ; le mot de passe n’est jamais conservé).
31 +**Configuration dans l’app :** Paramètres (engrenage) → URL **HTTPS** du serveur → identifiant + mot de passe → « Obtenir la clé » → retaper le mot de passe pour déchiffrer la clé API (stockée chiffrée sur l’appareil ; le mot de passe n’est jamais conservé).
32 32
33 -**Utilisation :** à l’ouverture, un bandeau signale les changements distants sans pull automatique. Le bouton **Sync** pousse les modifications locales (contacts créés/édités dans le carnet, tâches, CR…) puis tire le delta serveur. Sans sync configurée, le carnet reste local uniquement.
33 +Pour le **développement**, un **réseau interne** ou une **démo** sans TLS : cocher **« Autoriser HTTP (clair) »** avant de saisir une URL `http://…`. Sans cette case, l’app refuse le HTTP (HTTPS obligatoire). Ne pas activer cette option en production sur Internet.
34 34
35 -Plan d’implémentation client : [`docs/plans/sync_card2vcf_projectiaon_v1.md`](docs/plans/sync_card2vcf_projectiaon_v1.md).
35 +**Utilisation :** à l’ouverture, un bandeau signale les changements distants sans pull automatique. Le bouton **Sync** pousse les modifications locales (contacts créés/édités dans le carnet **y compris l’image de carte scannée** et la photo de profil si présentes, tâches, CR…) puis tire le delta serveur. Sans sync configurée, le carnet reste local uniquement.
36 +
37 +Plan d’implémentation client : [`docs/plans/sync_card2vcf_projectiaon_v1.md`](docs/plans/sync_card2vcf_projectiaon_v1.md).
38 +Sync images carte/photo : [`docs/plans/sync_cartes_visite_v1.md`](docs/plans/sync_cartes_visite_v1.md).
36 39
37 40 > **Upgrade schéma v2 :** la migration Room peut réinitialiser les données locales (documenté dans le plan sync).
38 41
A docs/plans/sync_cartes_visite_v1.md
+51 -0
@@ -0,0 +1,51 @@
1 +# Sync cartes de visite (images) — v1
2 +
3 +**Date :** 2026-07-23
4 +**Dépôts :** Projectiaon (serveur) + EBII_mobileVCF / Card2vcf (client)
5 +**Statut :** implémenté
6 +
7 +## Objectif
8 +
9 +À la sync, pousser/tirer non seulement le **contact texte**, mais aussi l’**image de carte de visite** (et la photo de profil) déjà gérées côté Projectiaon via `Contact.carte_visite` / `Contact.photo`.
10 +
11 +## Contexte
12 +
13 +La sync CRM v1 excluait explicitement les « médias serveur ». L’upload image n’existait qu’en session web (`POST /contacts/:id/carte`), inutilisable par Card2vcf (Bearer).
14 +
15 +## API serveur (Bearer)
16 +
17 +| Méthode | Route | Rôle |
18 +|---|---|---|
19 +| `POST` | `/api/contacts/:id/carte` | multipart → `carte_visite` |
20 +| `GET` | `/api/contacts/:id/carte` | sert le fichier |
21 +| `POST` | `/api/contacts/:id/photo` | multipart → `photo` |
22 +| `GET` | `/api/contacts/:id/photo` | sert la photo |
23 +
24 +- Auth : même garde Bearer que le reste de `/api`
25 +- Validation : png/jpg/jpeg/webp/gif, max 5 Mo (`medias::enregistrer_upload`)
26 +- POST : `200` + JSON `Contact` (avec `mis_a_jour_le` mis à jour)
27 +- Routes web `/contacts/:id/carte|photo` inchangées (session)
28 +
29 +## Client Card2vcf
30 +
31 +1. **Push** : après `create`/`update` contact JSON réussi, upload `card.jpg` / `profile.jpg` si présents.
32 +2. **Retry** : échec upload → SyncOp `contact_media` (ne re-crée pas le contact).
33 +3. **Rotation** : `rotateCardImage` enqueue un update contact pour re-pousser l’image.
34 +4. **Pull** : si DTO a `carte_visite`/`photo` et (fichier local absent **ou** serveur plus récent), `GET` + `ContactImageStore.saveBytes`. Skip si SyncOp contact/média pending.
35 +
36 +## Hors scope
37 +
38 +- Fichier `.vcf` en pièce jointe
39 +- Champ `PHOTO` dans l’export VCF
40 +- Sync des champs locaux non mappés (`website`, `address`, …)
41 +
42 +## Tests
43 +
44 +- Projectiaon : `tests/api_contacts_media_http.rs`
45 +- Card2vcf : `AilianceApiClientTest` (multipart/download), `SyncEngineTest` (push image, retry, pull)
46 +
47 +## Critères de succès
48 +
49 +1. Scan + sync → vignette carte visible dans l’UI web Projectiaon
50 +2. 2ᵉ appareil / réinstall → pull récupère contact + `card.jpg`
51 +3. Routes web inchangées