597 lines
26 KiB
Markdown
597 lines
26 KiB
Markdown
# 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 = '<SECRET_POSTGRES_ADMIN>'
|
|
$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 = '<SECRET_POSTGRES_ADMIN>'
|
|
$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 = '<SECRET_POSTGRES_ADMIN>'
|
|
$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:<PORT_WEB_DIAG>/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:<PORT_API_DIAG>/' -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:<PORT_WEB_DIAG>/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 = '<horodatage_du_backup>' # 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_<stamp>_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<Service>.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.
|