# Mise à jour production — Omika Diagnostics (SRV-OMIKA) > **Objet** : procédure de mise à jour d'une installation déjà existante > (première version de `DiagnosticsWorker` + `DiagnosticsWeb` déjà déployée) vers la > nouvelle version (code + base de données). > > **Cible** : Windows Server 2025 `SRV-OMIKA`, PowerShell **administrateur**, > PostgreSQL 18, runtime .NET 10 (framework-dependent). > > **Style** : chaque composant suit le même schéma que la documentation Omika.Api > existante → **Publier → Backup → Arrêter/Mettre à jour → Redémarrer → Vérifier**. --- ## 0. Vue d'ensemble des composants à mettre à jour | # | Composant | Projet | Service Windows | Exécutable | Santé | |---|---|---|---|---|---| | 1 | API métier/mobile (+ forwarder diagnostics) | `src\Omika.Api` | `OmikaApi` | `Omika.Api.exe` | `GET /health` | | 2 | Worker de synchronisation métier | `src\Omika.Worker` | `OmikaWorker` | `Omika.Worker.exe` | service `Running` + logs | | 3 | Import JSONL → PostgreSQL | `src\Omika.Diagnostics.Worker` | `OmikaDiagnosticsWorker` | `Omika.Diagnostics.Worker.exe` | service `Running` + checkpoint | | 4 | Interface Diagnostic Center | `src\Omika.Diagnostics.Web` | `OmikaDiagnosticsWeb` | `Omika.Diagnostics.Web.exe` | `GET /Login` (200) | | 5 | API centrale diagnostics *(optionnel, multi-serveur)* | `src\Omika.Diagnostics.Api` | `OmikaDiagnosticsApi` | `Omika.Diagnostics.Api.exe` | `GET /` (200) | | — | Base PostgreSQL `omika_diagnostics` | `infra\postgresql\*.sql` | — | migrations `001 → 011` | `SELECT count(*)` | **Ordre global de la mise à jour** (les étapes 4 à 7 sont détaillées plus bas) : ``` 1. Publier (poste DEV) §2 2. Transférer + backup §3 3. Arrêter les services §4 4. Migrer la base §5 ← TOUJOURS AVANT les nouveaux binaires 5. Copier les binaires §6 6. Redémarrer §7 7. Vérifier §8 ``` --- ## 1. Prérequis ### Poste DEV - SDK .NET 10 (`global.json` épingle `10.0.302`). - Dépôt à jour (`git pull`), branche qui contient les derniers changements. ### SRV-OMIKA (PowerShell administrateur) ```powershell net session # doit réussir, sinon STOP (droits) dotnet --list-runtimes # Microsoft.AspNetCore.App 10.x présent Get-Service postgresql* # Running Test-Path 'C:\Program Files\PostgreSQL\18\bin\psql.exe' Test-Path 'C:\Program Files\PostgreSQL\18\bin\pg_dump.exe' ``` --- ## 2. Publier sur le poste DEV Depuis `D:\Avalonia\Omika`, publier les **4 composants réellement utilisés** sur SRV-OMIKA. Le composant `Omika.Diagnostics.Api` (§6.5) n'est publié que si le mode multi-serveur (clients distants) est activé. > **Script prêt à l'emploi** : `scripts\publish-diagnostics.ps1` effectue > exactement ceci (publish + vérification des EXE). Lancer depuis la racine : > `.\scripts\publish-diagnostics.ps1` (ajouter `-IncludeCentralApi` pour l'API > centrale). Les commandes manuelles équivalentes sont ci-dessous. ```powershell cd D:\Avalonia\Omika # 1. Omika.Api dotnet publish src\Omika.Api\Omika.Api.csproj ` -c Release -r win-x64 --self-contained false ` -o C:\Omika\Deploy\OmikaApi-next # 2. Omika.Worker dotnet publish src\Omika.Worker\Omika.Worker.csproj ` -c Release -r win-x64 --self-contained false ` -o C:\Omika\Deploy\OmikaWorker-next # 3. Omika.Diagnostics.Worker (EnableWindowsService=true est le défaut : ne pas le désactiver) dotnet publish src\Omika.Diagnostics.Worker\Omika.Diagnostics.Worker.csproj ` -c Release -r win-x64 --self-contained false ` -o C:\Omika\Deploy\DiagnosticsWorker-next # 4. Omika.Diagnostics.Web dotnet publish src\Omika.Diagnostics.Web\Omika.Diagnostics.Web.csproj ` -c Release -r win-x64 --self-contained false ` -o C:\Omika\Deploy\DiagnosticsWeb-next # 5. (optionnel) Omika.Diagnostics.Api dotnet publish src\Omika.Diagnostics.Api\Omika.Diagnostics.Api.csproj ` -c Release -r win-x64 --self-contained false ` -o C:\Omika\Deploy\DiagnosticsApi-next ``` ### Vérification des sorties ```powershell Get-ChildItem C:\Omika\Deploy\OmikaApi-next # Omika.Api.exe + Omika.Api.dll + Omika.Core.dll + Omika.Data.dll + Omika.Observability.External.dll Get-ChildItem C:\Omika\Deploy\OmikaWorker-next # Omika.Worker.exe + Omika.Worker.dll + Omika.Core.dll + Omika.Data.dll + Omika.Observability.External.dll Get-ChildItem C:\Omika\Deploy\DiagnosticsWorker-next # Omika.Diagnostics.Worker.exe + Omika.Diagnostics.Worker.dll + Omika.Diagnostics.Core.dll + Omika.Diagnostics.Data.dll + Npgsql.dll Get-ChildItem C:\Omika\Deploy\DiagnosticsWeb-next # Omika.Diagnostics.Web.exe + Omika.Diagnostics.Web.dll + wwwroot\ + Omika.Diagnostics.Core.dll + Omika.Diagnostics.Data.dll + Npgsql.dll ``` > ⚠️ Ne jamais livrer de secret Dev en Prod. Vérifier l'absence de valeur de test > dans les publications, et que le serveur garde **`ASPNETCORE_ENVIRONMENT=Production`**. > (`appsettings.Development.json`, s'il est présent dans une publication, n'est chargé > que si l'environnement est `Development` — il ne doit donc jamais l'être sur SRV-OMIKA.) Transférer ensuite les dossiers `*-next` vers `SRV-OMIKA` dans `C:\Omika\Deploy\`. --- ## 3. Backup sur le serveur ### 3.1 Base PostgreSQL (AVANT toute migration) ```powershell $env:PGPASSWORD = '' $stamp = Get-Date -Format 'yyyyMMdd_HHmm' $out = "C:\Omika\Backups\omika_diagnostics_${stamp}_before_upgrade.backup" & 'C:\Program Files\PostgreSQL\18\bin\pg_dump.exe' ` -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -F c -v -f $out Remove-Item Env:PGPASSWORD $f = Get-Item $out $f.Exists -and $f.Length -gt 0 # doit être True, sinon NO-GO ``` ### 3.2 Binaires (AVANT remplacement) ```powershell $stamp = Get-Date -Format 'yyyyMMdd-HHmmss' $root = 'C:\Omika\Backups' Copy-Item 'C:\Omika\Apps\OmikaApi' -Destination "$root\OmikaApi_${stamp}" -Recurse -Force Copy-Item 'C:\Omika\Apps\OmikaWorker' -Destination "$root\OmikaWorker_${stamp}" -Recurse -Force Copy-Item 'C:\Omika\Apps\DiagnosticsWorker' -Destination "$root\DiagnosticsWorker_${stamp}" -Recurse -Force Copy-Item 'C:\Omika\Apps\DiagnosticsWeb' -Destination "$root\DiagnosticsWeb_${stamp}" -Recurse -Force ``` > Le script `infra\deploy\Install-OmikaServerFiles.ps1` fait déjà cette sauvegarde > horodatée + copie + préservation de la config, si vous préférez l'automatiser. --- ## 4. Arrêter les services (ordre) L'ordre fige d'abord la lecture (Web), puis les écrivains, et draine le Worker en dernier. ```powershell Stop-Service OmikaDiagnosticsWeb -Force Stop-Service OmikaApi -Force Stop-Service OmikaWorker -Force Stop-Service OmikaDiagnosticsWorker -Force Get-Service OmikaApi,OmikaWorker,OmikaDiagnosticsWorker,OmikaDiagnosticsWeb | Select-Object Name,Status # Attendu : les 4 = Stopped ``` --- ## 5. Mettre à jour la base de données (migrations) ### 5.1 Auditer l'état actuel (lecture seule) ```powershell $env:PGPASSWORD = '' $psql = 'C:\Program Files\PostgreSQL\18\bin\psql.exe' & $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -c ` "SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_name LIKE 'diagnostics%' ORDER BY 1;" & $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -c ` "SELECT column_name FROM information_schema.columns WHERE table_name='diagnostic_event' ORDER BY ordinal_position;" & $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -c ` "SELECT rolname FROM pg_roles ORDER BY rolname;" Remove-Item Env:PGPASSWORD ``` Cela permet de déterminer **quelles migrations sont déjà appliquées** : | Repère observé | Migration déjà appliquée | |---|---| | `diagnostic_event` présent | `001` | | colonnes `actor_key` / `actor_key_version` | `002` | | rôles `omika_diagnostics_owner/worker/web` | `003` | | `SELECT`+`DELETE` worker sur `diagnostic_event` | `004` | | colonnes `client_code`/`server_instance`/`environment` | `005` | | colonnes appareil/licence | `006` | | colonnes `screen_code`/`feature_code` | `007` | | table `diagnostics_clients` | `008` | | rôle `omika_diagnostics_api` + grants clients | `009` | | table `diagnostics_users` | `010` | | table `diagnostics_reference` | `011` | ### 5.2 Appliquer UNIQUEMENT les migrations manquantes, dans l'ordre Migrations `001 → 011`, toutes **idempotentes** (`CREATE/ADD IF NOT EXISTS`, `ON CONFLICT DO NOTHING`, `GRANT`). Les appliquer avec `ON_ERROR_STOP=1`, en compte **superuser** (`postgres`), car `003/009/010/011` font du `CREATE ROLE` / `ALTER TABLE OWNER` / `GRANT`. ```powershell $env:PGPASSWORD = '' $psql = 'C:\Program Files\PostgreSQL\18\bin\psql.exe' $db = 'C:\Omika\Deploy\DiagnosticsDatabase' # dossier contenant les .sql livrés $migrations = @( '001_diagnostics_schema.sql', '002_actor_key.sql', '003_diagnostics_roles.sql', '004_diagnostics_retention.sql', '005_diagnostics_client_context.sql', '006_diagnostics_device_license.sql', '007_diagnostics_usage.sql', '008_diagnostics_clients.sql', '009_diagnostics_clients_grants.sql', '010_diagnostics_web_users.sql', '011_diagnostics_reference.sql' ) foreach ($m in $migrations) { $f = Join-Path $db $m if (-not (Test-Path $f)) { Write-Host "ABSENT : $m" ; continue } Write-Host "Application : $m ..." & $psql -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -v ON_ERROR_STOP=1 -f $f if ($LASTEXITCODE -ne 0) { throw "ÉCHEC sur $m (exit $LASTEXITCODE). STOP." } } Remove-Item Env:PGPASSWORD ``` > **Règle d'ordre migration ↔ binaires** : les migrations doivent être appliquées > **AVANT** la copie des nouveaux binaires (§6). Les colonnes/tables ajoutées sont > additives ; les anciens binaires restent compatibles, mais les nouveaux binaires > échoueraient sur un schéma trop ancien. ### 5.3 Ce qui est nouveau dans cette mise à jour - **`011_diagnostics_reference.sql`** (dernière livraison) : table `diagnostics_reference` (référentiel administrable `ScreenCode`/`FeatureCode`), ownership `omika_diagnostics_owner`, grants `omika_diagnostics_web` (`SELECT`/`INSERT`/`UPDATE` colonnes ciblées + `USAGE` séquence), et **seed idempotent** des 29 `ScreenCode` + 3 `FeatureCode`. Aucun droit accordé aux rôles `omika_diagnostics_api` / `omika_diagnostics_worker`. - `003_diagnostics_roles_preprod.sql` ne concerne **que** la préproduction : ne **jamais** l'appliquer en Production. ### 5.4 Après `003` / `009` (rôles LOGIN) — mots de passe manuels Les rôles LOGIN créés sans mot de passe doivent être positionnés manuellement, jamais dans un script/log : ``` \password omika_diagnostics_worker \password omika_diagnostics_web \password omika_diagnostics_api # seulement si l'API centrale est activée ``` --- ## 6. Mettre à jour chaque composant Pour chaque composant, la copie **préserve** la configuration serveur existante (secrets) : on exclut `appsettings.json` et `appsettings.Production.json`. > ⚠️ Ne **jamais** supprimer : > - `C:\Omika\Data\Api\Diagnostics\Jsonl\**` (JSONL en attente d'import) > - `C:\Omika\Data\DiagnosticsWorker\Checkpoint\import-checkpoint.json` > - `C:\Omika\Config\**`, les certificats TLS, les variables d'environnement MACHINE. ### 6.1 Omika.Api (service `OmikaApi`) ```powershell # Backup : déjà fait §3.2. Puis copie : robocopy 'C:\Omika\Deploy\OmikaApi-next' 'C:\Omika\Apps\OmikaApi' ` /E /XF appsettings.json appsettings.Production.json ``` Fichiers attendus après copie : `Omika.Api.exe`, `Omika.Api.dll`, `Omika.Core.dll`, `Omika.Data.dll`, `Omika.Observability.External.dll`. Configuration Production à conserver (injectée sur le serveur) : `MobileAuth__SigningKey` (obligatoire, fail-fast), `DiagnosticsIdentity__HmacKey`, `ConnectionStrings__*` HFSQL / licence / sync, `Observability__Remote__Directory` (doit être **identique** au dossier JSONL lu par le Worker), et si le forwarding central est actif : `DiagnosticsForwarding__Enabled/Endpoint/ApiKey`. (Voir la table complète §6.6.) Redémarrage et contrôle (port Kestrel = celui défini dans `appsettings.Production.json`, ex. `5080`) : ```powershell Start-Service OmikaApi Get-Service OmikaApi # Running Invoke-WebRequest 'http://127.0.0.1:5080/health' -UseBasicParsing Invoke-WebRequest 'https://omika.applilogik.fr/health' -UseBasicParsing # Attendu : 200 + "Healthy" ``` ### 6.2 Omika.Worker (service `OmikaWorker`) ```powershell robocopy 'C:\Omika\Deploy\OmikaWorker-next' 'C:\Omika\Apps\OmikaWorker' ` /E /XF appsettings.json appsettings.Production.json ``` Fichiers attendus : `Omika.Worker.exe`, `Omika.Worker.dll`, `Omika.Core.dll`, `Omika.Data.dll`, `Omika.Observability.External.dll`. Pas de port HTTP (background service) : contrôle = service `Running` + absence de boucle d'erreur dans les logs (`C:\Omika\Logs\Worker`). ```powershell Start-Service OmikaWorker Get-Service OmikaWorker # Running Get-EventLog -LogName Application -Newest 50 | Where-Object { $_.Source -match 'Omika' } ``` ### 6.3 Omika.Diagnostics.Worker (service `OmikaDiagnosticsWorker`) ```powershell robocopy 'C:\Omika\Deploy\DiagnosticsWorker-next' 'C:\Omika\Apps\DiagnosticsWorker' ` /E /XF appsettings.json appsettings.Production.json ``` Fichiers attendus : `Omika.Diagnostics.Worker.exe`, `Omika.Diagnostics.Worker.dll`, `Omika.Diagnostics.Core.dll`, `Omika.Diagnostics.Data.dll`, `Npgsql.dll`. Configuration Production à conserver : `ConnectionStrings__DiagnosticsDatabase` (`Host=127.0.0.1;Port=5432;Database=omika_diagnostics;Username=omika_diagnostics_worker;Password=…`), `Observability__Remote__Directory` (**identique** au dossier JSONL d'Omika.Api), `Diagnostics__Import__CheckpointDirectory/CheckpointFileName`, `Diagnostics__RetentionDays`. (Voir la table complète §6.6.) ```powershell Start-Service OmikaDiagnosticsWorker Get-Service OmikaDiagnosticsWorker # Running Get-Content 'C:\Omika\Data\DiagnosticsWorker\Checkpoint\import-checkpoint.json' # Attendu : checkpoint stable ou progressant ; aucun JSONL supprimé. ``` ### 6.4 Omika.Diagnostics.Web (service `OmikaDiagnosticsWeb`) ```powershell robocopy 'C:\Omika\Deploy\DiagnosticsWeb-next' 'C:\Omika\Apps\DiagnosticsWeb' ` /E /XF appsettings.json appsettings.Production.json ``` Fichiers attendus : `Omika.Diagnostics.Web.exe`, `Omika.Diagnostics.Web.dll`, `wwwroot\`, `Omika.Diagnostics.Core.dll`, `Omika.Diagnostics.Data.dll`, `Npgsql.dll`. Configuration Production à conserver : `ConnectionStrings__DiagnosticsDatabase` (`…Username=omika_diagnostics_web;Password=…`), `DiagnosticsAuth__Operators` (bootstrap temporaire uniquement), `ASPNETCORE_ENVIRONMENT=Production`. (Voir la table complète §6.6.) Contrôle (port Kestrel = celui de `appsettings.Production.json`) : ```powershell Start-Service OmikaDiagnosticsWeb Get-Service OmikaDiagnosticsWeb # Running Invoke-WebRequest 'http://127.0.0.1:/Login' -UseBasicParsing # 200 ``` > Le Web n'expose pas de `/health` : la page `/Login` (200) est le smoke test. > Le reste est derrière authentification (redirect `/Login`). ### 6.5 Omika.Diagnostics.Api (service `OmikaDiagnosticsApi`) — **optionnel** À déployer **uniquement** si vous activez la réception de lots provenant de **serveurs clients distants**. Sur un SRV-OMIKA mono-serveur (Omika.Api écrit le JSONL localement), ce composant n'est **pas** nécessaire. ```powershell robocopy 'C:\Omika\Deploy\DiagnosticsApi-next' 'C:\Omika\Apps\DiagnosticsApi' ` /E /XF appsettings.json appsettings.Production.json ``` Fichiers attendus : `Omika.Diagnostics.Api.exe`, `Omika.Diagnostics.Api.dll`, `Omika.Core.dll`, `Omika.Diagnostics.Core.dll`, `Omika.Diagnostics.Data.dll`. Configuration Production à conserver : `ConnectionStrings__DiagnosticsDatabase` (`Username=omika_diagnostics_api`), `Diagnostics__Central__Directory` (= spool central, ex. `C:\ProgramData\Omika\Diagnostics\Central`). ```powershell Start-Service OmikaDiagnosticsApi Get-Service OmikaDiagnosticsApi # Running Invoke-WebRequest 'http://127.0.0.1:/' -UseBasicParsing # Attendu : 200 + JSON { name: "Omika.Diagnostics.Api", status: "ok" } ``` ### 6.6 Référence — variables d'environnement / clés de configuration par service **Règle de nommage** : en variable d'environnement, `:` devient `__` (`Diagnostics:Import:CheckpointDirectory` ⇔ `Diagnostics__Import__CheckpointDirectory`). **Précédence** : `ConnectionStrings:DiagnosticsDatabase` (env `ConnectionStrings__DiagnosticsDatabase`) **prime** sur `Diagnostics:ConnectionString`. Toute modification de variable d'environnement d'un service Windows nécessite un **redémarrage du service** pour être prise en compte. #### Omika.Api (service `OmikaApi`) | Variable d'environnement | Clé de configuration | Rôle | |---|---|---| | `ASPNETCORE_ENVIRONMENT` | — | `Production` obligatoire | | `MobileAuth__SigningKey` | `MobileAuth:SigningKey` | clé de signature tokens mobile (**fail-fast** en Prod) | | `DiagnosticsIdentity__HmacKey` | `DiagnosticsIdentity:HmacKey` | clé HMAC ActorKey/DeviceKey (≥ 256 bits Base64) | | `DiagnosticDeployment__ClientCode` | `DiagnosticDeployment:ClientCode` | override CodeClient (sinon fallback HFSQL) | | `DiagnosticDeployment__ServerInstanceId` | `DiagnosticDeployment:ServerInstanceId` | id d'instance (sinon `MachineName`) | | `Observability__Remote__Directory` | `Observability:Remote:Directory` | dossier JSONL (**identique** au Worker) | | `DiagnosticsForwarding__Enabled` | `DiagnosticsForwarding:Enabled` | kill switch du forwarder central (`true`/`false`) | | `DiagnosticsForwarding__Endpoint` | `DiagnosticsForwarding:Endpoint` | URL centrale **HTTPS** (si forwarding actif) | | `DiagnosticsForwarding__ApiKey` | `DiagnosticsForwarding:ApiKey` | clé d'accès centrale (**secret**) | | `LicenseConnection__*` / `SyncConnection__*` / HFSQL | — | secrets HFSQL existants (non touchés) | #### Omika.Worker (service `OmikaWorker`) | Variable d'environnement | Clé de configuration | Rôle | |---|---|---| | `ASPNETCORE_ENVIRONMENT` | — | `Production` obligatoire | | `DiagnosticDeployment__ClientCode` | `DiagnosticDeployment:ClientCode` | idem Omika.Api | | `DiagnosticDeployment__ServerInstanceId` | `DiagnosticDeployment:ServerInstanceId` | idem Omika.Api | | `SyncConnection__*` / HFSQL | — | secrets HFSQL existants (non touchés) | #### Omika.Diagnostics.Worker (service `OmikaDiagnosticsWorker`) | Variable d'environnement | Clé de configuration | Défaut | Rôle | |---|---|---|---| | `ConnectionStrings__DiagnosticsDatabase` | `ConnectionStrings:DiagnosticsDatabase` | — | Npgsql `Username=omika_diagnostics_worker` (prime sur ci-dessous) | | `Diagnostics__ConnectionString` | `Diagnostics:ConnectionString` | `""` | fallback si `ConnectionStrings` absent | | `Observability__Remote__Directory` | `Observability:Remote:Directory` | `""` | dossier JSONL (**identique** à Omika.Api) | | `Diagnostics__Import__CheckpointDirectory` | `Diagnostics:Import:CheckpointDirectory` | `""` | dossier checkpoint (sinon = dossier source) | | `Diagnostics__Import__CheckpointFileName` | `Diagnostics:Import:CheckpointFileName` | `import-checkpoint.json` | nom du checkpoint | | `Diagnostics__Import__BatchSize` | `Diagnostics:Import:BatchSize` | `100` | taille de lot d'insertion (borné 1..200) | | `Diagnostics__RetentionDays` | `Diagnostics:RetentionDays` | `60` | rétention en jours (`<=0` = purge désactivée) | | `Diagnostics__RetentionIntervalHours` | `Diagnostics:RetentionIntervalHours` | `24` | fréquence de purge | | `Diagnostics__RetentionBatchSize` | `Diagnostics:RetentionBatchSize` | `1000` | lot de suppression (borné) | | `Diagnostics__CommandTimeoutSeconds` | `Diagnostics:CommandTimeoutSeconds` | `10` | timeout court des commandes | #### Omika.Diagnostics.Web (service `OmikaDiagnosticsWeb`) | Variable d'environnement | Clé de configuration | Rôle | |---|---|---| | `ASPNETCORE_ENVIRONMENT` | — | `Production` obligatoire (default-deny) | | `ConnectionStrings__DiagnosticsDatabase` | `ConnectionStrings:DiagnosticsDatabase` | Npgsql `Username=omika_diagnostics_web` | | `DiagnosticsAuth__Operators__0__Username` | `DiagnosticsAuth:Operators:0:Username` | opérateur bootstrap (temporaire) | | `DiagnosticsAuth__Operators__0__PasswordHash` | `DiagnosticsAuth:Operators:0:PasswordHash` | **hash** bootstrap (jamais en clair) | | `DiagnosticsAuth__Operators__0__Roles__0` | `DiagnosticsAuth:Operators:0:Roles:0` | `Admin` / `Support` | | `Diagnostics__RetentionDays` | `Diagnostics:RetentionDays` | `60` (affiché dans l'UI) | #### Omika.Diagnostics.Api (service `OmikaDiagnosticsApi`) — optionnel | Variable d'environnement | Clé de configuration | Défaut | Rôle | |---|---|---|---| | `ConnectionStrings__DiagnosticsDatabase` | `ConnectionStrings:DiagnosticsDatabase` | — | Npgsql `Username=omika_diagnostics_api` | | `Diagnostics__Central__Directory` | `Diagnostics:Central:Directory` | `logs/diagnostics-central` | **spool central** (chemin explicite en Prod) | | `Diagnostics__Central__MaxRequestBodyBytes` | `Diagnostics:Central:MaxRequestBodyBytes` | `524288` | corps de requête borné | | `Diagnostics__Central__MaxEventsPerBatch` | `Diagnostics:Central:MaxEventsPerBatch` | `100` | événements max par lot | | `Diagnostics__Central__SchemaVersion` | `Diagnostics:Central:SchemaVersion` | `1` | version du schéma de transport | **Ports Kestrel** : définis par `appsettings.Production.json` de chaque composant (`Kestrel:Endpoints:Http:Url` ou `ASPNETCORE_URLS`), en HTTP loopback derrière le reverse proxy Apache (`https://omika.applilogik.fr`). Aucun port n'est codé en dur dans le binaire. --- ## 7. Redémarrer (ordre) Démarrer les **consommateurs avant les producteurs** : ```powershell Start-Service OmikaDiagnosticsWorker # 1. importeur (consommateur JSONL) Start-Service OmikaDiagnosticsWeb # 2. UI (lecture) Start-Service OmikaWorker # 3. sync métier (producteur #2) Start-Service OmikaApi # 4. API (producteur #1, dernier) Get-Service OmikaApi,OmikaWorker,OmikaDiagnosticsWorker,OmikaDiagnosticsWeb | Select-Object Name,Status # Attendu : les 4 = Running ``` > Si un service passe immédiatement en `Stopped`/`Failed`, ne pas démarrer les > suivants : diagnostiquer puis rollback si non résolu (§9). --- ## 8. Smoke tests (non destructifs) ```powershell # Services Get-Service OmikaApi,OmikaWorker,OmikaDiagnosticsWorker,OmikaDiagnosticsWeb | Select-Object Name,Status # API métier Invoke-WebRequest 'http://127.0.0.1:5080/health' -UseBasicParsing # 200 "Healthy" # Web Diagnostics (Login) Invoke-WebRequest 'http://127.0.0.1:/Login' -UseBasicParsing # 200 ``` Contrôles PostgreSQL après redémarrage : ```sql SELECT count(*) FROM diagnostic_event; SELECT max(ingested_at_utc) AS dernier_ingere FROM diagnostic_event; -- Référentiel (011) : SELECT reference_type, count(*) FROM diagnostics_reference GROUP BY reference_type; -- Attendu : SCREEN_CODE = 29, FEATURE_CODE = 3 ``` Dans **Diagnostics.Web** : vérifier Dashboard, Diagnostics, Erreurs, Traces, Synchronisation, Telemetry, Versions, et **Référentiel** (nouvelle fonctionnalité `011`) ainsi que `/Clients` et `/Users` (Admin). --- ## 9. Rollback ### Binaires ```powershell Stop-Service OmikaApi,OmikaWorker,OmikaDiagnosticsWorker,OmikaDiagnosticsWeb -Force $stamp = '' # ex. 20261002-160000 Remove-Item 'C:\Omika\Apps\OmikaApi' -Recurse -Force Copy-Item "C:\Omika\Backups\OmikaApi_${stamp}" 'C:\Omika\Apps\OmikaApi' -Recurse -Force Copy-Item "C:\Omika\Backups\OmikaWorker_${stamp}" 'C:\Omika\Apps\OmikaWorker' -Recurse -Force Copy-Item "C:\Omika\Backups\DiagnosticsWorker_${stamp}" 'C:\Omika\Apps\DiagnosticsWorker' -Recurse -Force Copy-Item "C:\Omika\Backups\DiagnosticsWeb_${stamp}" 'C:\Omika\Apps\DiagnosticsWeb' -Recurse -Force Start-Service OmikaDiagnosticsWorker Start-Service OmikaDiagnosticsWeb Start-Service OmikaWorker Start-Service OmikaApi ``` ### Base de données **Pas de rollback SQL automatique** : les migrations `001 → 011` sont **additives** et idempotentes ; les anciens binaires restent compatibles. Ne jamais `DROP` / `TRUNCATE` / `DELETE`. Restaurer via `pg_restore` (backup §3.1) uniquement sur décision humaine explicite et en dernier recours : ```powershell & 'C:\Program Files\PostgreSQL\18\bin\pg_restore.exe' ` -h 127.0.0.1 -p 5432 -U postgres -d omika_diagnostics -c ` 'C:\Omika\Backups\omika_diagnostics__before_upgrade.backup' ``` --- ## 10. Checklist finale ```text [ ] Publications DEV : 4 composants générés, EXE/DLL présents, pas de secret Dev [ ] Transfert vers SRV-OMIKA C:\Omika\Deploy\*-next [ ] pg_dump terminé + taille > 0 [ ] Backup binaires (4 dossiers) présent + complet [ ] Services arrêtés (4 = Stopped) [ ] Migrations manquantes identifiées puis appliquées dans l'ordre (ON_ERROR_STOP=1) [ ] 011 (diagnostics_reference) appliquée ; seed 29 + 3 vérifié [ ] Mots de passe rôles LOGIN posés manuellement (\password) [ ] appsettings.json / appsettings.Production.json préservés sur les 4 composants [ ] JSONL + checkpoint intacts (jamais supprimés) [ ] Redémarrage dans l'ordre (Worker → Web → OmikaWorker → OmikaApi) [ ] 4 services Running [ ] /health Omika.Api = 200 "Healthy" ; /Login DiagnosticsWeb = 200 [ ] Dashboard / Référentiel / Clients / Users fonctionnels [ ] Rollback prêt (backups binaires + décision DB additive) ``` --- ## Références internes - `docs/DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md` — architecture, ports, comptes, secrets. - `docs/T15-RUNBOOK-DEPLOIEMENT-PRODUCTION.md` — runbook complet (phases détaillées). - `scripts/publish-diagnostics.ps1` — publication automatisée des composants (poste DEV). - `infra/deploy/Install-OmikaServerFiles.ps1` — copie statique + sauvegarde + SHA256. - `infra/deploy/Omika.Deploy.Common.psm1` — module commun (comptes, ACL contrôlées, services, ports). - `infra/deploy/Install-Omika.ps1` — **un script par déploiement** (`OmikaApi`, `OmikaWorker`, `OmikaDiagnosticsApi`, `OmikaDiagnosticsWorker`, `OmikaDiagnosticsWeb`, `OmikaLanguesApi`) : idempotents, `-WhatIf`, `-Desinstaller`. - `infra/deploy/Install-OmikaServices.ps1` — orchestrateur : enchaîne les scripts ci-dessus dans l'ordre. - `infra/deploy/Test-PortDisponible.ps1` — disponibilité d'un port loopback avant configuration. - `infra/deploy/Install-DatabaseSchema.ps1` — applique `001`+`002` (schéma). - `infra/deploy/Harden-DatabaseRoles.ps1` — applique `003` (rôles). - `infra/postgresql/001…011_diagnostics_*.sql` — migrations PostgreSQL.