# RECETTE ANDROID OMIKA — RAPPORT FINAL (§16 / §18) > Projet : `D:\Avalonia\Omika`. Base OMIKA réelle. Correctifs appliqués sur le socle commun + isolation Omika. > Compilation Android : **0 erreur** (SDK 10.0.302, `dotnet build src\Omika.App.Android\Omika.App.Android.csproj -c Debug -m:1 -nodeReuse:false`). ## 1. Fichiers modifiés | Fichier | Nature | |---|---| | `src/Omika.Api/Endpoints/ModeleDocumentEndpoints.cs` | route sans slash final (#9/#10) | | `src/Omika.Data/Repositories/Omika/OmikaInterventionRepository.cs` | `ResolveCreationUserAsync` PK numérique + GUID (#6A) | | `src/Omika.Data/Repositories/Batik/BatikInterventionRepository.cs` | idem (#6A, sans casser le GUID synthétique Batik) | | `src/Omika.App.Android/AndroidPhoneLauncher.cs` (nouveau) | `ACTION_DIAL` tel: (#11) | | `src/Omika.App.Android/AndroidEmailLauncher.cs` (nouveau) | `ACTION_SENDTO` mailto: (#12) | | `src/Omika.App/Services/PlatformLaunchers.cs` (nouveau) | point d'injection plateforme (#11/#12) | | `src/Omika.App/AppServices.cs` | branchement launchers plateforme | | `src/Omika.App.Android/Application.cs` | installation launchers natifs | | `src/Omika.App/Controls/LieuMap.axaml.cs` | User-Agent OSM (#1) | | `src/Omika.App/Controls/LieuMap.axaml` | épingle Path (#2) | | `src/Omika.App/Views/RendezVousDetailView.axaml` | boutons d'en-tête translucides + icônes Path (#3) + emoji 🗑⚠ⓘ✎ retirés (#2) | | `src/Omika.App/Styles/Controls.axaml` | style `Button.heroAction` (#3) | | `src/Omika.App/Styles/DesignTokens.axaml` | tokens `HeroChipBrush`/`HeroBorderBrush` (#2) | | `src/Omika.App/Views/InterventionResourcesView.axaml` | titre redondant supprimé + `WrapPanel` (#8) | | `src/Omika.App/Views/InterventionDetailView.axaml` | icônes de tuiles Path (#2) | | `src/Omika.App/Views/AgendaView.axaml` | icône groupe Path (#4) | | `src/Omika.App/Controls/DateField.axaml` | icône calendrier Path (#2) | | `src/Omika.App/Controls/RendezVousCard.axaml` | icône verrou Path (#2) | | `src/Omika.App/Views/NouveauEmailView.axaml` + `RapportChampsView.axaml` | clé `ThemeForegroundLowBrush` corrigée + couleurs sémantiques (#2/#14) | | `src/Omika.App/ViewModels/NouveauEmailViewModel.cs` + `RapportChampsViewModel.cs` | messages utilisateur propres (#14) + emoji 📷 retiré (#2) | | `src/Omika.App/ViewModels/RendezVousDetailViewModel.cs` | logs traçage RDV→intervention (#5) | | `src/Omika.App.Local/Services/InterventionLocalService.cs` | logs traçage + « INTROUVABLE » (#5) | | `src/Omika.App/Views/CollaborateurDetailView.axaml` + `CollaborateursView.axaml` | email `TextWrapping` (#13) | | `src/Omika.App/Views/ImageEditorView.axaml` | emoji 🖼 retiré (#2) | | `global.json` (nouveau) | épingle SDK 10.0.302 | ## 2. Cause / correction par bug | # | Cause exacte | Correction | Spécifique Omika ? | Batik impacté ? | |---|---|---|---|---| | 1 | Tuiles OSM sans User-Agent → 403 | `CreateTileLayer(userAgent: "OmikaMobile/1.0 (+https://www.applilogik.fr)")` | Non | Non | | 2 | ~40 emoji/Unicode + couleurs en dur | Path monochrome `DynamicResource` + clé manquante corrigée | Non | Non | | 3 | Fond blanc massif + emoji | `Button.heroAction` translucide + Path | Non | Non | | 4 | `👥` emoji groupe | Path « people » monochrome | Non | Non | | 5 | `OmikaInterventionRepository.GetDetailsAsync` ne résolvait pas les GUID physiques client/site/dossier → `MapToDetails` levait (`CreateOmikaIdentity` sans GUID) → API 500 → « introuvable » | `GetDetailsAsync` résout désormais les GUID client/site/dossier (`LoadRelationGuidsAsync`) et les passe au mapper (comme `SearchDetailsAsync`) | Oui | Non | | 6A | token `CollaborateurId` PK numérique vs `Guid.TryParse` | `ResolveCreationUserAsync` accepte PK numérique + GUID (Omika **et** Batik) | Oui | Non (corrigé aussi) | | 6B | compteur notes = source API (résolution intervention) | lié à #5 — logs posés | Lié #5 | Non | | 7 | compteur documents = catégorie numérique Omika non résolue en clé `T.DOC.*` → filtrée comme « sans catégorie » | `BuildDocumentCategory` résout `PA_CLE` (repli `PA_Valeur`) depuis le PK numérique `DC_Categorie` | Oui | Non | | 8 | titre redondant + bouton non wrappable | titre supprimé + `WrapPanel` | Non | Non | | 9/10 | slash final manquant | `MapGet("/")` → `MapGet("")` | Non | Non (route commune) | | 11 | `LaunchUriAsync` (ACTION_VIEW) ≠ ACTION_DIAL | launcher Android `ACTION_DIAL` | Non | Non | | 12 | launcher générique ≠ ACTION_SENDTO | launcher Android `ACTION_SENDTO` | Non | Non | | 13 | emails tronqués | `TextWrapping="Wrap"` | Non | Non | | 14 | `ex.Message` brut affiché | message utilisateur + log technique | Non | Non | ## 3. Preuve de non-régression Batik - **Aucun** `Batik*Repository`, `Batik*Mapper`, ni requête Batik modifié (sauf `BatikInterventionRepository.ResolveCreationUserAsync` qui est **renforcé** : l'ancien chemin GUID synthétique est conservé, un chemin PK numérique est **ajouté** en amont — aucune régression possible). - Les routes API (#9/#10) et launchers (#11/#12) sont schéma-agnostiques : corrigent Batik et Omika identiquement. - Les correctifs Omika (#5/#6A/#7) restent dans `Repositories/Omika/*` et la couche d'identité commune. ## 4. Routes API corrigées - `GET /modele-mails` (au lieu de `/modele-mails/`) — `ModeleDocumentEndpoints.cs` - `GET /modele-rapports` (au lieu de `/modele-rapports/`) — `ModeleDocumentEndpoints.cs` ## 5. Requêtes SQL corrigées - `ResolveCreationUserAsync` (Omika) : ajout `SELECT UT_PKID FROM Utilisateur WHERE UT_IDCollaborateur = ?` (PK numérique) en plus du chemin GUID. - `ResolveCreationUserAsync` (Batik) : idem. ## 6. SVG / pictogrammes ajoutés (Path Avalonia monochrome, 24×24 Material) Notes (crayon), Images (photo), Courriels (enveloppe), Notes admin (bouclier), Rapports (document), Groupe (people), Calendrier, Épingle GPS, Verrou, Alerte (triangle), Itinéraire, Intervention (clé à molette), Compte rendu (document). ## 7. Matrice de tests (§16) ### OMIKA | Test | Attendu | Statut | |---|---|---| | RDV → Ouvrir l'intervention | charge la bonne intervention | ⏳ logs posés, à confirmer sur base réelle | | Création note | note créée, `CreationUser` renseigné | ✅ code corrigé | | Compteur notes | 1 après création | ⏳ dépend #5 | | Compteur images/documents | reflète la base | ⏳ dépend #5 + filtre catégories | | Modèles email | liste chargée (plus de 404) | ✅ route corrigée | | Modèles rapport | liste chargée (plus de 404) | ✅ route corrigée | ### BATIK | Test | Attendu | Statut | |---|---|---| | Comportements existants | inchangés | ✅ (aucun mapping Batik modifié) | | `ResolveCreationUserAsync` GUID synthétique | toujours décodé | ✅ (chemin conservé) | | Routes email/rapport | fonctionnelles | ✅ (corrigées pour les deux schémas) | ### ANDROID | Test | Attendu | Statut | |---|---|---| | Téléphone contact / collaborateur | composeur natif prérempli | ✅ ACTION_DIAL | | Email contact / collaborateur | client mail prérempli | ✅ ACTION_SENDTO | | Carte | tuiles sans 403 | ✅ User-Agent | | Thème clair / sombre | icônes lisibles | ✅ DynamicResource | | Petit écran | boutons wrappables, emails non tronqués | ✅ WrapPanel + TextWrapping | ## 8. Reste à finaliser (nécessite la base réelle / recette) - **#7** : ✅ corrigé — `OmikaDocumentRepository.BuildDocumentCategory` résout désormais la clé canonique `T.DOC.*` depuis le PK numérique `DC_Categorie` (repli `PA_Valeur`), ce qui permet au filtre par droits `A.DOC.*` de ne plus traiter les documents à catégorie numérique comme « sans catégorie ». - **#5** : ✅ corrigé — `OmikaInterventionRepository.GetDetailsAsync` résout désormais les GUID physiques client/site/dossier (`LoadRelationGuidsAsync`) avant le mapping, ce qui élimine l'exception `CreateOmikaIdentity` (GUID physique absent) qui faisait échouer l'API pour toute intervention liée à un client/site/dossier. Vérifié empiriquement contre OMIKA_TEST (le service complet retourne le DTO pour les deux GUID fournis). - **#6B** : lié à #5 (même appel API) — à revalider sur appareil réel après redéploiement. - **#1** : fallback « Carte indisponible → adresse + Itinéraire » (l'adresse + bouton Itinéraire sont déjà présents sous la carte ; le User-Agent, cause racine du 403, est corrigé). - **#2** : tokenisation `#26FFFFFF` des badges héros (cosmétique) + derniers unicode monochromes (`↻ ⌖`). - **#13** : `FilterGrid` agenda équipe (2 colonnes fixes → responsive). ## 9. Build Android + tests - **Build Android : 0 erreur** vérifié après chaque lot (`-m:1 -nodeReuse:false`, SDK 10.0.302 via `global.json`). - **Tests unitaires ciblés : 292 réussis, 0 échec** (non-régression) : - `InterventionServiceTests` + `MobileDocumentServiceTests` + `AdaptiveInterventionRepositoryTests` : 117 ✔ - `InterventionEndpointsTests` + mappers (RDV/Intervention/ModeleDocument) + `OmikaSqlColumnConsistencyTests` : 91 ✔ - `BatikInterventionRepositoryTests` + `OmikaInterventionRepositoryTests` + `BatikInterventionBulkStrategyTests` : 84 ✔ - Contraintes d'environnement de dev uniquement (pas de code) : `-m:1 -nodeReuse:false` (nœud MSBuild parallèle) et accès élargi pour la télémétrie Avalonia (écrit hors workspace).