# Omika > **Gestion d'interventions terrain** — application .NET 10 / Avalonia, réécriture moderne de > l'application WinDev historique **Batik**. Omika couvre le cycle complet d'une intervention technique : agenda et rendez-vous, dossiers, clients et sites, interventions et suivi des temps, comptes rendus, documents et photos, courriels, rapports — sur **poste de bureau, Android et iOS**, avec un fonctionnement **hors ligne** complet et une synchronisation vers le serveur HFSQL existant. | | | |---|---| | **Langage / runtime** | C# · .NET 10 (`net10.0`) | | **UI** | Avalonia 12.1.1 (thème Fluent, police Inter) — rendu identique desktop et mobile | | **MVVM** | CommunityToolkit.Mvvm 8.4.2 | | **Base locale (mobile)** | SQLite (`Microsoft.Data.Sqlite`) — `omika.db` | | **Base serveur** | HFSQL Client/Server (PC SOFT) via ODBC / OLE DB | | **Version** | `1.0.0` build `1` — source unique : `Directory.Build.props` | | **Éditeur** | Applilogik — `com.applilogik.omika.app` | --- ## Sommaire 1. [Ce que fait Omika](#1-ce-que-fait-omika) 2. [Architecture](#2-architecture) 3. [Les projets](#3-les-projets) 4. [Prérequis](#4-prérequis) 5. [Démarrage rapide](#5-démarrage-rapide) 6. [Configuration](#6-configuration) 7. [Tests](#7-tests) 8. [Publier et déployer](#8-publier-et-déployer) 9. [Observabilité](#9-observabilité) 10. [Traduction hors ligne et packs de langues](#10-traduction-hors-ligne-et-packs-de-langues) 11. [Bases de données](#11-bases-de-données) 12. [Arborescence du dépôt](#12-arborescence-du-dépôt) 13. [Règles d'architecture](#13-règles-darchitecture) 14. [Documentation](#14-documentation) 15. [Dépannage](#15-dépannage) --- ## 1. Ce que fait Omika ### 1.1 Fonctionnel | Domaine | Contenu | |---|---| | **Licence / activation** | Inscription au premier démarrage par code ou **scan de QR** (aperçu caméra), états « connexion requise », « licence expirée ou révoquée ». Attribution et révocation de licence mobile depuis la fiche collaborateur. | | **Agenda** | Agenda personnel **Jour / Semaine / Mois**, agenda d'équipe avec filtres par équipe et collaborateur. Lecture 100 % locale, aucun appel réseau au chargement. | | **Rendez-vous** | Fiche complète : contacts, saisie de temps inline, annulation (origine + motif + note), finalisation « Fait ». | | **Interventions** | Recherche multi-critères (référence, client, site, collaborateur, état, type), onglets « Récentes » et « Épinglées », fiche complète, **création / modification / archivage offline-first**. | | **Dossiers, clients, sites** | Listes avec recherche et épinglage local, fiches détaillées, **carte géographique** (Mapsui) et lancement d'itinéraire. | | **Équipe** | Équipes de l'utilisateur, membres, fiches collaborateurs. | | **Temps et comptes rendus** | Saisie de temps avec gestion de la pause déjeuner, compte rendu individuel ou groupe/journée avec anti-doublon. | | **Documents et photos** | Téléchargement à la demande, cache hors ligne, ajout offline-first, **éditeur d'image plein écran** (annotation + signature), date réelle lue dans les métadonnées EXIF. | | **Courriels** | Composition depuis un modèle, un rapport ou un contact, envoi SMTP, brouillons. | | **Rapports** | Remplissage de modèles DOCX par champs/rubriques. | | **Synchronisation** | File Outbox, badge du nombre d'opérations en attente, déclenchement manuel, reconstruction de la base locale par **snapshot**. | | **Paramètres** | Thème clair/sombre/système, couleur principale, compte et licence, limite de poids des photos, horaires de pause, maintenance des données (purge, réinitialisation), export des journaux vers le support. | | **Traduction hors ligne** | Traduction FR ⇄ 32 langues directement sur l'appareil (ONNX Runtime), sans réseau. | ### 1.2 Principe directeur : offline-first Toute écriture métier part d'abord dans la **base SQLite locale** et dans l'**Outbox**, puis remonte au serveur à la première occasion. L'utilisateur n'attend jamais le réseau. - **Snapshot** : le serveur renvoie une photographie complète des données métier pour reconstruire la base locale. - **Outbox** : file locale des changements à pousser, rejouable après coupure. - **Idempotence** : chaque opération porte un `OperationId` unique ; la rejouer ne produit pas de doublon. --- ## 2. Architecture ``` ┌──────────────────────────────────────────────────────────────────────┐ │ TÉLÉPHONE / POSTE DE BUREAU │ │ │ │ Omika.App.Desktop · Omika.App.Android · Omika.App.iOS │ │ │ hôtes plateformes │ │ ▼ │ │ Omika.App Vues + ViewModels + Navigation + Contrôles │ │ │ │ │ ▼ │ │ Omika.App.Local SQLite (omika.db) + SyncEngine + Outbox │ │ + cache documents + traduction ONNX │ └──────────────────────────────┬───────────────────────────────────────┘ │ HTTP / JSON + Bearer token ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ SERVEUR DU CLIENT (HFSQL) │ │ │ │ Omika.Api Web service · licence · bootstrap · snapshot │ │ │ │ sync │ │ ▼ ▼ │ │ Omika.Core (métier) Omika.Worker (application des ops) │ │ │ │ │ │ └────────► Omika.Data (HFSQL par ODBC / OLE DB) ◄───────────┘ └──────────────────────────────┬───────────────────────────────────────┘ │ forwarding HTTPS des diagnostics ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ SERVEUR CENTRAL OMIKA │ │ Omika.Diagnostics.Api → Omika.Diagnostics.Worker → PostgreSQL │ │ └──► Omika.Diagnostics.Web │ │ Omika.Langues.Api distribution des modèles de langue (ONNX) │ │ (optionnel) OpenTelemetry → Collector → SigNoz → ClickHouse │ └──────────────────────────────────────────────────────────────────────┘ ``` **À retenir :** - Le **mobile ne parle jamais directement à HFSQL** : il passe toujours par `Omika.Api`. - Le **desktop** accède à HFSQL **directement** (chemin historique). - `Omika.Api` **reçoit** les opérations ; `Omika.Worker` les **applique**. - `Omika.Core` est le cerveau métier ; `Omika.Data` est la seule couche qui touche HFSQL. - Tout ce qui est **hors** métier (diagnostics, observabilité, langues) est **fail-open** : l'arrêter ne casse jamais l'application. --- ## 3. Les projets ### 3.1 Projets de la solution (`Omika.slnx`) | Projet | TFM | Rôle | |---|---|---| | `src/Omika.Core` | `net10.0` | **Noyau métier**, sans dépendance UI ni base : entités de domaine, value objects, commands, DTO (`Contracts/`), interfaces, services métier — dont le **cœur serveur de la synchronisation mobile** (`Services/Mobile/` : licence, jetons, bootstrap, snapshot, documents, opérations de sync) — configuration typée, constantes, `Runtime/` (Batik vs Omika), sécurité, politiques d'observabilité. | | `src/Omika.Data` | `net10.0` | **Accès HFSQL** : options de connexion et validation, connexion ODBC / OLE DB, repositories, mapping, **modèles physiques générés** (Batik 48 tables / Omika 58 tables), migrations Batik → Omika, détection de schéma. | | `src/Omika.App.Local` | `net10.0` | **Cerveau local du client** : SQLite (`omika.db`), schéma, `SyncEngine`, `OutboxService`, cache documents, un service local par entité, traduction ONNX, licence de développement, diagnostics locaux. | | `src/Omika.App` | `net10.0` | **Bibliothèque UI partagée** : 38 vues XAML, 48 ViewModels, navigation (`PageViewModelFactory`), contrôles réutilisables (dont la carte), styles, services d'interface. | | `src/Omika.App.Desktop` | `net10.0` | Hôte **bureau** (`WinExe`, manifeste Windows 10). | | `src/Omika.App.Android` | `net10.0-android` | Hôte **Android** — min SDK 23, `com.applilogik.omika.app`, format APK, scan QR via ZXing. | | `src/Omika.App.iOS` | `net10.0-ios` | Hôte **iOS** — min 14.0. **La compilation d'un `.app` exige macOS + Xcode.** | | `src/Omika.Api` | `net10.0` | **API métier et mobile**, installée chez chaque client : licence, bootstrap, snapshot, sync, documents, courriels, rapports, aide contextuelle. OpenAPI. | | `src/Omika.Worker` | `net10.0` | **Service de synchronisation** : dépile `TOSRV`, exécute le handler métier, journalise dans `MobLog`. Service Windows. | | `src/Omika.Observability.External` | `net10.0` | **Seul projet autorisé** à référencer OpenTelemetry : adaptateur OTLP HTTP/protobuf, `RemoteDiagnosticForwarder`, câblage DI. | | `tests/Omika.Tests` | `net10.0` | Tests xUnit de la solution métier et du client. | | `tools/Omika.HfSqlProbe` | `net10.0` | Sonde de connexion et d'inspection HFSQL. | | `tools/HfSqlModelAudit` | `net10.0` | Audit des modèles physiques (attributs de mapping). | | `tools/HfSqlOleDbAudit` | `net10.0` | Audit du schéma par OLE DB (mode `connection-test` inclus). | | `tools/Omika.LanguesProbe` | `net10.0` | Validation hors ligne d'un couple de traduction (vocabulaire SentencePiece, paire FR⇄ES). | ### 3.2 Projets compilés hors solution Ces projets existent, se compilent et se testent, mais **ne sont pas référencés par `Omika.slnx`** : un `dotnet build Omika.slnx` ne les couvre pas. Les compiler explicitement par leur chemin. | Projet | TFM | Rôle | |---|---|---| | `src/Omika.Diagnostics.Core` | `net10.0` | Modèles, abstractions de repository, importeur JSONL → PostgreSQL. Aucune logique métier. | | `src/Omika.Diagnostics.Data` | `net10.0` | Persistance PostgreSQL du Diagnostic Center (base dédiée `omika_diagnostics`), Npgsql direct. | | `src/Omika.Diagnostics.Api` | `net10.0` | API **centrale** : reçoit les lots des serveurs clients, authentifie (`ClientCode` + `ApiKey`), écrit le spool central. | | `src/Omika.Diagnostics.Worker` | `net10.0` | Import asynchrone du spool central JSONL → PostgreSQL, déduplication par `event_id`, backoff borné. | | `src/Omika.Diagnostics.Web` | `net10.0` | Interface support (Razor Pages) : Dashboard, Diagnostics, Erreurs, Traces, Synchronisation, Telemetry, Parc, Versions, Référentiel, Utilisateurs, Clients Diagnostics, Système, Mon compte. | | `src/Omika.Langues.Api` | `net10.0` | Service **stateless** de distribution des modèles de langue ONNX (`/api/langues`, `/api/langues/{code}/{sens}/{fichier}`). Sans base ni authentification. | | `tests/Omika.Diagnostics.Tests` | `net10.0` | Tests du Diagnostic Center (faux repositories, PostgreSQL simulé en panne, mappers, checkpoint, sécurité, pagination). | | `tools/*` (21 autres) | `net10.0` | Sondes de diagnostic : `ClientSnapshotProbe`, `CollaborateurBulkProbe`, `CountProbe`, `DiagnosticHashTool`, `FileAccessProbe`, `FilePasswordProbe`, `IdempotenceProbe`, `IdentityProbe`, `LieuProbe`, `MessageExterneProbe`, `OleDbSchemaProbe`, `RdvProbeJour`, `RendezVousBulkProbe`, `RendezVousProbe`, `SiteSnapshotProbe`, `SmtpMobileConfigProbe`, `SmtpRealProbe`, `StatusProbe`, `TosrvProbe`, `Verif.Dictee`, `Verif.Langues`. | --- ## 4. Prérequis | Besoin | Détail | |---|---| | **.NET SDK 10** | SDK de référence : **10.0.302** (voir `global.json.bak`). Le dépôt ne contient pas encore de `global.json` actif : renommer le `.bak` si vous voulez figer la version. | | **Workloads mobiles** | `dotnet workload install android` pour l'APK. iOS demande **macOS + Xcode**. | | **Serveur HFSQL** | HFSQL Client/Server (port **4900**) + pilote ODBC « HFSQL Client/Server », pour le développement local et les tests d'intégration. | | **Windows** | Requis pour le client desktop (OLE DB, manifeste Windows) et pour les services Windows déployés. | | **PostgreSQL** | Uniquement pour le Diagnostic Center (`omika_diagnostics`). Optionnel pour le métier. | | **Docker** | Uniquement pour la pile d'observabilité externe (optionnelle). | Packages : gestion **centralisée** via `Directory.Packages.props`. Les `.csproj` référencent les packages **sans version** — ne jamais ajouter de `Version=` dans un `.csproj`. --- ## 5. Démarrage rapide ### 5.1 Tout-en-un (mode test local) Les scripts de `docs/` compilent et lancent les trois composants (API, Worker, desktop) : ```powershell # Compiler (arrête les processus Omika en cours pour libérer les DLL) powershell -NoProfile -ExecutionPolicy Bypass -File .\docs\build_omika_test.ps1 # Lancer : API (http://localhost:5097) + Worker + application de bureau powershell -NoProfile -ExecutionPolicy Bypass -File .\docs\start_omika_test.ps1 -NoBuild # Arrêter powershell -NoProfile -ExecutionPolicy Bypass -File .\docs\stop_omika_test.ps1 ``` Options utiles de `start_omika_test.ps1` : | Option | Effet | |---|---| | `-NoBuild` | Ne pas recompiler. | | `-SkipDesktop` | Lancer seulement l'API et le Worker. | | `-SkipWorker` | Lancer seulement l'API et le desktop. | | `-Clean` | Purger `omika.db` et `omika-diagnostics.db` avant lancement (changement d'environnement). | Le script crée automatiquement, si absent, le fichier de licence de développement `%LOCALAPPDATA%\Omika\development-license.json` : ```json { "Enabled": true, "ClientCode": "LOCAL-DEV", "UserDisplayName": "", "ExpirationDays": 365, "ApiUrl": "http://localhost:5097" } ``` ### 5.2 Commandes `dotnet` directes ```powershell # Restauration dotnet restore .\Omika.slnx # Compiler toute la solution (client + API + Worker + bibliothèques + tests + 4 outils) dotnet build .\Omika.slnx # Composants pris isolément dotnet build .\src\Omika.Api\Omika.Api.csproj dotnet build .\src\Omika.Worker\Omika.Worker.csproj dotnet build .\src\Omika.App.Desktop\Omika.App.Desktop.csproj dotnet build .\src\Omika.App.Android\Omika.App.Android.csproj # APK dotnet build .\src\Omika.App.iOS\Omika.App.iOS.csproj # macOS + Xcode requis # Projets hors solution dotnet build .\src\Omika.Diagnostics.Web\Omika.Diagnostics.Web.csproj dotnet build .\src\Omika.Langues.Api\Omika.Langues.Api.csproj # Lancer dotnet run --project .\src\Omika.Api\Omika.Api.csproj # http://localhost:5097/health dotnet run --project .\src\Omika.Worker\Omika.Worker.csproj dotnet run --project .\src\Omika.App.Desktop\Omika.App.Desktop.csproj ``` ### 5.3 Ports de développement | Service | Port | |---|---| | `Omika.Api` | **5097** (HTTP) · 7160 (HTTPS) | | `Omika.Diagnostics.Api` | **5098** | | `Omika.Diagnostics.Web` | **5080** | | `Omika.Langues.Api` | **5099** (derrière Apache sur `/langues/`) | | HFSQL Client/Server | **4900** | En production, Kestrel reste en **HTTP sur loopback** ; l'exposition HTTPS est assurée par un reverse proxy **Apache**. --- ## 6. Configuration ### 6.1 `config/hfsql-test.local.json` — non versionné Les `appsettings.json` ne contiennent que des **placeholders** (hôtes `localhost`, mots de passe vides). Les vraies connexions de test vivent dans `config/hfsql-test.local.json`, **exclu du dépôt** par `.gitignore` (`/config/`). Le fichier est chargé par `HfSqlTestConfigurationLoader` **uniquement** en environnement `Development` ou `Test`, jamais en `Production`, et les **variables d'environnement restent prioritaires**. Il est localisé de deux façons : 1. variable d'environnement `OMIKA_HFSQL_TEST_CONFIG` = chemin explicite (fait foi) ; 2. sinon, `config/hfsql-test.local.json` en remontant jusqu'à 6 niveaux depuis le répertoire courant. Structure attendue pour reconstituer ce fichier : ```json { "Server": "", "Port": 4900, "FilePasswords": { "ProtectionStd": "", "ProtectionPlus": "" }, "Batik": { "Database": "", "User": "", "Credential": "" }, "Omika": { "DatabaseVersion": "Auto", "Database": "", "User": "", "Credential": "" }, "Hfsql": { "ConnectionName": "Business", "Server": "", "Port": 4900, "DatabaseName": "", "Login": "", "Password": "", "Driver": "HFSQL Client/Server", "ConnectionTimeoutSeconds": 30, "FilePasswords": { "ProtectionStd": "", "ProtectionPlus": "" } }, "LicenseConnection": { "Server": "", "Port": 4900, "DatabaseName": "Licence", "Login": "", "Password": "", "FilePasswords": { "ProtectionStd": "", "ProtectionPlus": "" } }, "SyncConnection": { "Server": "", "Port": 4900, "DatabaseName": "Sync", "Login": "", "Password": "", "FilePasswords": { "ProtectionStd": "", "ProtectionPlus": "" } }, "ServiceConnection": { "Server": "", "Port": 4900, "DatabaseName": "", "Login": "", "Password": "", "FilePasswords": { "ProtectionStd": "", "ProtectionPlus": "" } }, "MobileAuth": { "SigningKey": "" }, "DevelopmentAuth": { "Enabled": true, "DevCollaborateurPkId": 0, "DevCodeClient": "" }, "E2E": { "AllowHfSqlWrites": false, "ServiceDatabaseConfirmedTest": false, "WebServiceDatabaseConfirmedTest": false } } ``` > **Garde-fou E2E** : `E2E:AllowHfSqlWrites` doit rester à `false`. Il n'est activé que > temporairement, et explicitement, pour un test end-to-end qui écrit réellement dans HFSQL. ### 6.2 Variables d'environnement La convention .NET `__` (double souligné) permet de surcharger n'importe quelle clé : ```powershell $env:ASPNETCORE_ENVIRONMENT = 'Development' # charge config/hfsql-test.local.json $env:DOTNET_ENVIRONMENT = 'Development' $env:ASPNETCORE_URLS = 'http://localhost:5097' $env:Omika__DatabaseVersion = 'Auto' # Auto | Batik | Omika $env:Sync__RetryDelaySeconds = '5' # accélère le Worker en test E2E $env:OMIKA_HFSQL_TEST_CONFIG = 'D:\chemin\vers\hfsql-test.local.json' $env:DiagnosticsForwarding__ApiKey = '' # serveur client, jamais dans un fichier versionné ``` ### 6.3 Sélection de base : Batik ou Omika Deux notions distinctes, à ne pas confondre : - **`DatabaseSchemaSelection`** (`Omika:DatabaseVersion`) — la sélection **demandée** : `Auto` (détection automatique, défaut sûr), `Batik` (forcer l'ancienne base), `Omika` (forcer la nouvelle). - **`DatabaseSchemaVersion`** — la version **réellement détectée**. Tant que la détection n'a pas eu lieu, elle reste `Unknown`, même si une sélection forcée est configurée. En mode forcé, une base détectée différente provoque un échec explicite. ### 6.4 Secrets — ce qui ne doit jamais être versionné | Fichier / clé | Statut | |---|---| | `config/*.local.json` | **Exclu.** Contient les identifiants HFSQL réels (dont mots de passe de fichiers). | | `src/Omika.Diagnostics.Web/appsettings.Development.json` | **Exclu.** Contient un `PasswordHash` d'administrateur local. | | `appsettings.*.local.json`, `secrets.json`, `.env`, `*.pfx`, `*.p12`, `*.key` | **Exclus.** | | `DiagnosticsForwarding:ApiKey`, `MobileAuth:SigningKey`, `DiagnosticsIdentity:HmacKey`, `Diagnostics:ConnectionString` | **Vides dans les fichiers versionnés.** Injectés sur le serveur par variables d'environnement. | --- ## 7. Tests ```powershell # Tests métier et client (~3 400 tests) dotnet test .\tests\Omika.Tests\Omika.Tests.csproj # Tests du Diagnostic Center (~540 tests, sans PostgreSQL réel) dotnet test .\tests\Omika.Diagnostics.Tests\Omika.Diagnostics.Tests.csproj # Tests internes d'un outil dotnet test .\tools\HfSqlOleDbAudit\tests\HfSqlOleDbAudit.Tests\HfSqlOleDbAudit.Tests.csproj ``` **Échecs attendus hors environnement complet** — ce ne sont pas des régressions : | Type | Cause | |---|---| | Tests HFSQL / OLE DB | Exigent un serveur HFSQL réel et `config/hfsql-test.local.json`. Ils se désactivent d'eux-mêmes si le fichier est absent. | | Tests Avalonia headless | Peuvent échouer selon la configuration graphique de la machine. | | `DevelopmentLicenseTests` en **Release** | Le contournement de licence de développement est compilé en `#if DEBUG` : comportement voulu. | **Vérifications hors xUnit** — deux outils rejouent des tests sans `testhost` (contournement d'un `Win32Exception 5` sur certains postes) : ```powershell dotnet run --project .\tools\Omika.Verif.Dictee dotnet run --project .\tools\Omika.Verif.Langues ``` --- ## 8. Publier et déployer Les scripts de `infra/deploy/` installent les services **Windows**. Chacun accepte une simulation (`-WhatIf` / `-Simulation`) et s'appuie sur le module commun `Omika.Deploy.Common.psm1`. | Script | Service Windows créé | |---|---| | `Install-OmikaApi.ps1` | `OmikaApi` | | `Install-OmikaWorker.ps1` | `OmikaWorker` | | `Install-OmikaLanguesApi.ps1` | `OmikaLanguesApi` | | `Install-OmikaDiagnosticsApi.ps1` | `OmikaDiagnosticsApi` | | `Install-OmikaDiagnosticsWorker.ps1` | `OmikaDiagnosticsWorker` | | `Install-OmikaDiagnosticsWeb.ps1` | `OmikaDiagnosticsWeb` | | `Install-OmikaServices.ps1` | Orchestration de l'ensemble | | `Install-OmikaServerFiles.ps1` | Arborescence serveur (données, documents, journaux) | | `Install-DatabaseSchema.ps1` | Application des migrations PostgreSQL `001` → `016` | | `Harden-DatabaseRoles.ps1` | Rôles et droits PostgreSQL | | `New-OmikaLanguesManifeste.ps1` | Manifeste des packs de langues à distribuer | | `Test-PortDisponible.ps1` | Contrôle de disponibilité des ports | Le schéma PostgreSQL vit dans `infra/postgresql/` : appliquer les migrations **dans l'ordre** (`001_diagnostics_schema.sql` → `016_diagnostics_event_delete.sql`). Elles sont idempotentes. Procédures détaillées : - `docs/DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md` — déploiement du Diagnostic Center, rôles, ports, bootstrap du premier administrateur. - `docs/T15-RUNBOOK-DEPLOIEMENT-PRODUCTION.md` — runbook de mise en production. - `docs/DEPLOIEMENT_API_LANGUES.md` — API de distribution des modèles de langue. - `infra/deploy/tests/` — tests des scripts de déploiement. --- ## 9. Observabilité Trois niveaux, **durables et fail-open** : 1. **Journaux locaux JSONL** — `logs/` côté serveur, base `omika-diagnostics.db` côté appareil. 2. **Diagnostic Center** — remontée des diagnostics vers le serveur central (`Omika.Diagnostics.Api` → spool → `Omika.Diagnostics.Worker` → PostgreSQL → `Omika.Diagnostics.Web`). 3. **OpenTelemetry (optionnel)** — `Observability:External:Enabled=false` par défaut. Activable vers un Collector OTLP HTTP/protobuf (port 4318) puis SigNoz / ClickHouse. > **Règle absolue** : *les journaux servent Omika, Omika ne dépend jamais des journaux.* Arrêter le > Collector, SigNoz, ClickHouse ou PostgreSQL Diagnostics ne casse **jamais** le métier. Pile de référence : `infra/observability/docker-compose.yml` + `otel-collector-config.yaml`. Documentation : `docs/observability/` (configuration, déploiement, guide support, données exportées, procédure de débranchement). Le flux mobile ne passe **jamais** par OTLP : `Mobile → POST /api/diagnostics → spool JSONL serveur → ACK`, le forwarding externe étant asynchrone et best-effort **après** l'acquittement. --- ## 10. Traduction hors ligne et packs de langues La traduction FR ⇄ 32 langues s'exécute **sur l'appareil** via `Microsoft.ML.OnnxRuntime` (SentencePiece + modèles encodeur/décodeur). Le moteur n'est compilé que si le symbole `OMIKA_ONNX_RUNTIME` est défini — il l'est dans `Omika.App.Local.csproj`. Sans lui, la traduction répond « indisponible ». Les modèles (`*.onnx`, `*.spm`, environ 0,5 à 1,1 Go **par langue**) sont **hors dépôt** : | Élément | Statut | |---|---| | `packs/` (≈ 26 Go, 32 langues × `commun` / `versFrancais` / `depuisFrancais`) | **Non versionné.** Distribué par `Omika.Langues.Api` / GitHub Releases. | | `packs.zip` (≈ 23 Go) | **Non versionné.** | | `tests/fixtures/sentencepiece/*.spm`, `encoder.onnx` | **Non versionnés** — seuls les `.fixtures.json` le sont. Les tests se désactivent silencieusement en leur absence. | Régénération des packs : ```powershell .\scripts\Exporter-Packs-Langues.ps1 # export des packs .\scripts\Completer-Packs-Langues.ps1 # complétion des langues manquantes .\scripts\Generer-Fixtures-SentencePiece.ps1 ``` Voir `docs/TRADUCTION_HORS_LIGNE_MOBILE.md`, `docs/LIVRAISON_MODELES_LANGUES.md` et `docs/VALIDATION_TRADUCTION_ONNX.md`. --- ## 11. Bases de données | Base | Technologie | Rôle | |---|---|---| | **HFSQL « Batik »** | HFSQL C/S (48 tables) | Ancienne base WINDEV, toujours lue et écrite. | | **HFSQL « Omika »** | HFSQL C/S (58 tables) | Nouvelle base cible. | | **`Licence`** | HFSQL C/S | Licences et inscriptions. | | **`Sync`** | HFSQL C/S (`TOSRV`, `MobReception`, `MobLog`) | File d'opérations de synchronisation. | | **`omika.db`** | SQLite | Base locale de l'appareil (offline-first). | | **`omika-diagnostics.db`** | SQLite | Diagnostics locaux de l'appareil. | | **`omika_diagnostics`** | PostgreSQL | Diagnostic Center central. | > **Règle d'or** : la base HFSQL existante **n'est jamais modifiée**. Aucune table n'est créée, > supprimée ni altérée par le nouveau code — il ne fait que lire et écrire dans le schéma existant. > Les migrations présentes dans `Omika.Data/Migrations` concernent la **compatibilité des données** > Batik → Omika, pas la structure. Le dictionnaire machine-readable du schéma est `docs/schema-compatibilite-batik-omika.json` (582 Ko) ; les 106 modèles physiques de `src/Omika.Data/HfSql/Models/` en sont générés. --- ## 12. Arborescence du dépôt ``` Omika.slnx Solution (format .slnx) — 15 projets Directory.Build.props Version unique : OmikaVersion 1.0.0 / OmikaBuild 1 Directory.Packages.props Gestion centralisée des versions NuGet .gitignore Exclusions (build, secrets, runtime, packs, Batik) fix-sdk-locators.ps1 Correctif MSB4276 (poste de développement, admin) src/ Code source (16 projets) Omika.Core/ Métier, contrats, services (dont sync mobile) Omika.Data/ HFSQL : connexion, repositories, mapping, migrations Omika.App.Local/ SQLite, SyncEngine, Outbox, traduction ONNX Omika.App/ UI Avalonia partagée (Views, ViewModels, Navigation) Omika.App.Desktop/ Hôte bureau Omika.App.Android/ Hôte Android Omika.App.iOS/ Hôte iOS Omika.Api/ API métier et mobile Omika.Worker/ Service de synchronisation Omika.Observability.External/ Adaptateur OpenTelemetry (isolé) Omika.Diagnostics.*/ Diagnostic Center (Core, Data, Api, Worker, Web) Omika.Langues.Api/ Distribution des modèles de langue tests/ Omika.Tests/ Tests métier et client (~3 400) Omika.Diagnostics.Tests/ Tests du Diagnostic Center (~540) fixtures/sentencepiece/ Fixtures de traduction (LISEZMOI + *.fixtures.json) tools/ 25 sondes console de diagnostic docs/ Documentation (~64 documents) infra/ deploy/ Scripts d'installation des services Windows postgresql/ Migrations 001 → 016 observability/ Pile OTel / SigNoz / ClickHouse (optionnelle) collector/ Exemple de configuration collector scripts/ Export des packs de langues, seeds, publication config/ Secrets locaux — NON versionné packs/ Modèles de langue ONNX (≈ 26 Go) — NON versionné Batik/ Projet WinDev historique — NON versionné artifacts/ Sorties de publication — NON versionné logs/ Journaux runtime — NON versionné ``` --- ## 13. Règles d'architecture Ces règles sont **vérifiées par des tests** dans `tests/Omika.Tests/Architecture/` : 1. **`Omika.Core` ne référence ni Avalonia, ni ASP.NET Core, ni `Omika.Data`.** C'est le noyau partagé, sans dépendance technique. 2. **Le métier ne référence jamais OpenTelemetry.** Les packages OTel sont confinés à `Omika.Observability.External` ; seules des politiques pures vivent dans `Core`. 3. **L'UI ne référence jamais `Omika.Data`.** L'application passe par l'API (HTTP) ou par `Omika.App.Local`. 4. **Les contrats publics ne contiennent ni nom de table HFSQL, ni champ « zombie ».** Les DTO exposés ne laissent pas fuiter le schéma physique. 5. **`Omika.Data` est la seule couche qui parle HFSQL.** 6. **Résultats d'opération** : les services renvoient `Result` / `Result` plutôt que de lever des exceptions pour les cas métier. 7. **Pas de conteneur DI dans l'UI partagée** : une composition racine manuelle unique (`AppServices.cs`). 8. **Hors métier = fail-open.** Diagnostics, observabilité, distribution des langues : leur indisponibilité ne doit jamais dégrader l'application. --- ## 14. Documentation | Document | Contenu | |---|---| | `docs/ARCHITECTURE_PROJET.md` | **Guide complet** : rôle de chaque projet, flux, où chercher quand un bug apparaît. Le meilleur point d'entrée. | | `docs/architecture-solution.md` | Architecture initiale de la solution, conventions, gestion de la base Batik/Omika. | | `docs/LOT_MOBILE_0.md` | Architecture technique mobile : offline-first, SQLite, sync, identités, design system. | | `docs/MOBILE_FUNCTIONAL_STATUS.md` | État fonctionnel réel de l'application mobile, écran par écran. | | `docs/E2E_SYNC_VALIDATION.md` | Validation end-to-end du pipeline de synchronisation. | | `docs/TRADUCTION_HORS_LIGNE_MOBILE.md` | Traduction ONNX embarquée. | | `docs/DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md` | Déploiement multi-serveurs du Diagnostic Center. | | `docs/T15-RUNBOOK-DEPLOIEMENT-PRODUCTION.md` | Runbook de mise en production. | | `docs/dictionnaire-compatibilite-batik-omika.md` | Dictionnaire de compatibilité des schémas. | | `docs/observability/` | Observabilité externe (configuration, déploiement, support, débranchement). | | `docs/BATIK.md`, `docs/OMIKA.md`, `docs/Documentation_*.md` | **Exports WINDEV de l'ancien système** — référence historique uniquement. | | `ANALYSE-OMIKA-APP.md` | Analyse technique complète de l'application (écrans, pile, limites). | | `ANALYSE_OMIKA_BATIK/` | Études comparatives Batik / Omika. | --- ## 15. Dépannage | Symptôme | Cause probable / solution | |---|---| | **MSB4276** à la compilation | Workload Android/iOS corrompu sur le poste. Contournement utilisé par les scripts : `dotnet build --no-restore -m:1`. Solution durable : `dotnet workload repair`, ou exécuter `fix-sdk-locators.ps1` **en administrateur**. | | **MSB3027** (fichier verrouillé) | Une instance d'Omika tourne encore. `stop_omika_test.ps1`, ou `build_omika_test.ps1` sans `-NoStop`. | | L'API démarre mais les données sont vides | `config/hfsql-test.local.json` absent ou non résolu. Vérifier `OMIKA_HFSQL_TEST_CONFIG`, et que `ASPNETCORE_ENVIRONMENT=Development`. | | Traduction « indisponible » | Le symbole `OMIKA_ONNX_RUNTIME` n'est pas défini, ou les modèles de langue ne sont pas installés sur l'appareil. | | `omika.db` contient des données de la mauvaise base | Relancer avec `start_omika_test.ps1 -Clean` après un changement Batik ⇄ Omika. | | Le Worker ne traite pas les opérations | Vérifier la connexion `SyncConnection` et la table `TOSRV`. En test E2E, `Sync__RetryDelaySeconds=5` accélère la boucle. | | Diagnostics.Web : pages « indisponible » | PostgreSQL est en panne. **Comportement attendu** (fail-open) : l'outil support ne bloque jamais le métier. | | `dotnet build Omika.slnx` ne compile pas les Diagnostics | Normal : ces projets sont **hors solution**. Les compiler par leur chemin explicite. | | L'application Android ne se compile pas | `dotnet workload install android`. iOS exige macOS + Xcode. | --- ## Licence Projet propriétaire — © Applilogik. Tous droits réservés.