Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,581 @@
|
||||
# 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": "<nom affiché>",
|
||||
"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": "<serveur HFSQL>",
|
||||
"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 = '<secret>' # 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 `<modele>.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<T>` 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 <projet> --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.
|
||||
Reference in New Issue
Block a user