Files
Omika/docs/DEPLOIEMENT_API_LANGUES.md
2026-10-23 18:46:50 +02:00

28 KiB

Marche à suivre — Mise en production API de téléchargement des langues (modèles ONNX)

Objet : procédure complète de mise en production de l'API dédiée de téléchargement des modèles de langue ONNX (traduction hors-ligne pour le mobile). Cette API est un service Windows séparé (OmikaLanguesApi, projet src/Omika.Langues.Api), distinct d'OmikaApi. Elle sert au mobile les fichiers de modèle + un manifeste versionné, en accès anonyme (fichiers génériques, aucune donnée client). L'URL de base reste lue en base (ParametreSysteme PAS_Code = 'SRV_LANGUES') par OmikaApi, qui l'expose au bootstrap mobile.

Cible : Windows Server SRV-OMIKA, PowerShell administrateur, runtime .NET 10. Aucune base de données, aucune authentification, aucun service externe.

Ce document complète T15-RUNBOOK-DEPLOIEMENT-PRODUCTION.md et MISE_EN_PRODUCTION_DIAGNOSTICS_V2.md : il ne couvre que le service Langues. OmikaApi garde uniquement la lecture SRV_LANGUES → LanguesUrl au bootstrap.


0. Vue d'ensemble de l'API Langues

Composant Rôle Référence
Omika.Langues.Api Service dédié : endpoints GET /api/langues* (manifeste + streaming). Windows Service OmikaLanguesApi
Omika.Core LanguageModelService (lecture manifeste + résolution fichier) + LanguageModelOptions + contrats partagés. —
Langues:RootPath Dossier racine des modèles + du manifeste. variable d'env. Langues__RootPath
ParametreSysteme.SRV_LANGUES URL de base du service Langues, lue par OmikaApi. HFSQL (Omika et Batik)

Flux :

1. GET /api/mobile/bootstrap  ──>  OmikaApi lit SRV_LANGUES  ──>  LanguesUrl (→ URL du service Langues)
2. GET {LanguesUrl}/api/langues          ──>  manifeste (packs + fichiers + sha256)   [anonyme]
3. GET {LanguesUrl}/api/langues/{code}/{sens}/{fichier}  ──>  streaming (reprise)     [anonyme]
  • SRV_LANGUES absent/vide → LanguesUrl = null → le mobile désactive la traduction hors-ligne (aucun appel, aucun plantage).
  • Les textes à traduire ne sortent jamais de l'appareil : traduction 100 % locale une fois le modèle téléchargé.

1. Ce qui a changé

  1. Nouveau service dédié OmikaLanguesApi (src/Omika.Langues.Api) : les endpoints langues ne sont plus dans OmikaApi.
  2. Accès anonyme : aucun token requis (les modèles sont des fichiers génériques).
  3. Nouvelle section de configuration : Langues (RootPath, ManifestFileName), portée par le service OmikaLanguesApi.
  4. OmikaApi ne conserve que la lecture SRV_LANGUES → MobileConfigurationDto.LanguesUrl.
  5. Nouveaux fichiers à déployer sur disque : manifest.json + modèles ONNX (jamais embarqués dans l'APK/IPA ni dans un binaire).

Le client de téléchargement ONNX côté mobile (téléchargement, reprise, vérification SHA-256, stockage local) relève d'un ticket ultérieur : ce document ne couvre que le serveur (service Langues + exposition SRV_LANGUES).


2. Prérequis

Poste DEV (publication)

cd D:\Avalonia\Omika
dotnet --version            # SDK 10 (global.json épingle 10.0.302)
git pull                    # branche à jour

SRV-OMIKA (PowerShell administrateur)

net session                                          # OK sinon STOP
dotnet --list-runtimes                               # Microsoft.AspNetCore.App 10.x
Get-Service OmikaApi                                 # Running (bootstrap métier)
Test-Path 'C:\Omika\Data'                            # dossier de données (langues)

OmikaLanguesApi n'a besoin d'aucun accès HFSQL : uniquement du dossier de fichiers Langues:RootPath.


3. Publication (poste DEV)

cd D:\Avalonia\Omika

# Omika.Api (métier : lit SRV_LANGUES → LanguesUrl ; endpoints langues retirés)
dotnet publish src\Omika.Api\Omika.Api.csproj `
  -c Release -r win-x64 --self-contained false -o C:\Omika\Deploy\OmikaApi-next

# Omika.Langues.Api (NOUVEAU service dédié)
dotnet publish src\Omika.Langues.Api\Omika.Langues.Api.csproj `
  -c Release -r win-x64 --self-contained false -o C:\Omika\Deploy\LanguesApi-next

Contrôles : chaque dossier contient son .exe ; appsettings.Development.json absent ; aucun secret Dev dans les publications.

Transférer OmikaApi-next et LanguesApi-next vers C:\Omika\Deploy\ sur SRV-OMIKA.


4. Base HFSQL — paramètre SRV_LANGUES

OmikaApi lit l'URL depuis la table ParametreSysteme (schéma Omika et Batik — rubriques PAS_Code / PAS_Valeur, groupe ProtectionPlus).

Rubrique Valeur
PAS_Code SRV_LANGUES
PAS_Description ex. « URL du service de téléchargement des modèles de langue »
PAS_Valeur URL de base du service Langues, sans slash final

Exemples de PAS_Valeur (pointe vers le service OmikaLanguesApi) :

  • Production derrière Apache (vhost/hôte dédié) : https://langues.applilogik.fr
  • Chemin dédié derrière l'Apache existant : https://omika.applilogik.fr/langues
  • API interne directe : https://omika-langues.local:8443

Le slash final est toléré (l'API le normalise), mais ne pas le mettre évite toute ambiguïté. La valeur doit être une URL HTTPS joignable par le mobile.

Écriture : même mécanisme que SRV_LICENCE_MOBILE existant — côté WinDev ParametreSystemeEcrit("SRV_LANGUES", "<url>"), ou insertion/UPDATE direct via l'outil de gestion HFSQL. La valeur n'est jamais codée en dur dans l'application.


5. Fichiers modèles + manifeste (sur disque)

5.1 Arborescence sous RootPath

Langues/
├── manifest.json
├── es/
│   ├── versFrancais/
│   │   ├── encoder.onnx
│   │   └── vocab.spm
│   └── depuisFrancais/
│       ├── encoder.onnx
│       └── vocab.spm
├── pt/
│   ├── versFrancais/...
│   └── depuisFrancais/...
└── ar/ ...
  • {code} : code ISO de la langue (es, pt, ar, ru, pl, …).
  • {sens} : deux valeurs canoniques uniquement :
    • versFrancais → langue secondaire → français (dictée, avant insertion) ;
    • depuisFrancais → français → langue secondaire (lecture, affichage seul).

5.2 Fichier manifest.json (clés en camelCase)

{
  "packs": [
    {
      "code": "es",
      "libelle": "Espagnol",
      "version": "1.0.0",
      "fichiers": [
        {
          "sens": "versFrancais",
          "nomFichier": "encoder.onnx",
          "tailleOctets": 122000000,
          "sha256": "a1b2c3d4...<empreinte hexadécimale SHA-256>"
        },
        {
          "sens": "versFrancais",
          "nomFichier": "vocab.spm",
          "tailleOctets": 804000,
          "sha256": "e5f6a7b8..."
        },
        {
          "sens": "depuisFrancais",
          "nomFichier": "encoder.onnx",
          "tailleOctets": 122000000,
          "sha256": "11121314..."
        }
      ]
    }
  ]
}
  • url n'est pas à renseigner : l'API la construit (/api/langues/{code}/{sens}/{nomFichier}).
  • tailleOctets = taille réelle en octets (progression mobile).
  • sha256 = empreinte SHA-256 hexadécimale (intégrité).

5.3 Générer les empreintes SHA-256 (PowerShell)

Get-FileHash -Algorithm SHA256 .\es\versFrancais\encoder.onnx |
  ForEach-Object { $_.Hash.ToLowerInvariant() }

5.4 Générer le manifeste (script — recommandé)

tailleOctets et sha256 sont des valeurs mesurées sur les fichiers, jamais saisies à la main : une empreinte fausse ou absente ne se voit que sur le téléphone, où le pack est refusé sans qu'aucune erreur ne remonte au serveur.

# Écrit <RootPath>\manifest.json depuis les fichiers réellement présents
.\infra\deploy\New-OmikaLanguesManifeste.ps1 -RootPathLangues C:\Omika\Data\Langues

# Contrôle après chaque ajout/remplacement de modèle : code 1 au moindre écart
.\infra\deploy\New-OmikaLanguesManifeste.ps1 -Verifier
  • La racine par défaut est lue dans Langues__RootPath (MACHINE) : le manifeste est donc écrit là où l'API le lit (§6).
  • Le script refuse d'écrire (code 1) un manifeste vide, et signale en clair un code de langue invalide, un dossier de sens inconnu, un fichier absent, une taille ou une empreinte divergente. Ces cas produisent sinon un pack silencieusement ignoré (code invalide) ou refusé (empreinte) par le mobile.
  • -Verifier ne demande aucun droit administrateur : c'est le contrôle à passer dans la foulée de toute livraison de modèle.
  • -WhatIf affiche le manifeste qui serait écrit, sans rien modifier.

Le format de §5.2 reste la référence ; le script ne fait que le remplir avec des valeurs exactes. À noter : le mobile compare sens de façon sensible à la casse (versFrancais / depuisFrancais) — le script normalise cette casse et le signale s'il la corrige.


6. Configuration serveur (Langues)

Règle : en variable d'environnement, : devient __ (Langues:RootPath ⇔ Langues__RootPath). Toute modification d'une variable du service exige un redémarrage d'OmikaLanguesApi.

Variable Défaut Rôle
Langues__RootPath <dossier de l'application>\Langues Dossier racine des modèles + manifeste
Langues__ManifestFileName manifest.json Nom du fichier manifeste
ASPNETCORE_URLS http://localhost:5000 Adresse/port d'écoute Kestrel (HTTP loopback derrière Apache)
ASPNETCORE_ENVIRONMENT Production Environnement (recommandé)

Le défaut de RootPath est le dossier de l'application (résolu via AppContext.BaseDirectory), jamais le répertoire de travail courant — un service Windows démarre dans C:\Windows\System32, ce qui rendrait ce dernier inutilisable.

Recommandation production : fixer Langues__RootPath sur C:\Omika\Data\Langues (cohérent avec les autres données sous C:\Omika\Data). Ne jamais placer les modèles dans C:\Omika\Apps\LanguesApi : ils seraient écrasés à chaque redéploiement (voir §7.4).

Port : voir §6bis — le port n'est pas imposé par ce document et ne doit jamais être repris d'un exemple : il se décide contre le plan de ports Apache, une fois, et s'écrit ensuite partout à l'identique.


6bis. Choix du port loopback (à décider AVANT §7.5bis)

Aucun port n'est fixé par ce document. La convention Apache/Kestrel du parc omika.applilogik.fr n'est pas consignée dans le dépôt : elle ne peut donc pas être devinée ici. Elle doit être relevée sur le serveur, puis appliquée.

Ports déjà connus du dépôt — à ne pas réutiliser :

Port Service Source
5097 Omika.Api (développement) docs\start_omika_test.ps1
5098 Omika.Diagnostics.Api DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md §4
5080 Omika.Diagnostics.Web DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md §4
5000 Kestrel par défaut (si ASPNETCORE_URLS absente) —

Procédure (à exécuter sur le serveur)

# <PORT_LANGUES> : à remplacer par le port candidat avant exécution.
$portLangues = <PORT_LANGUES>

# 1. Le port candidat est-il déjà en écoute ?
Get-NetTCPConnection -LocalPort $portLangues -State Listen -ErrorAction SilentlyContinue |
  Select-Object LocalAddress,LocalPort,OwningProcess

# 2. Tranches réservées par Hyper-V / WSL / Docker (elles peuvent être n'importe où)
netsh int ipv4 show excludedportrange protocol=tcp

# 3. Plage éphémère Windows : le port fixe doit rester EN DESSOUS
netsh int ipv4 show dynamicport tcp

# 4. Ports Omika réellement en écoute (vue d'ensemble)
Get-NetTCPConnection -State Listen | Where-Object LocalPort -in 5097,5098,5080,$portLangues

Critères d'acceptation du port

  1. Libre : aucune écoute sur 127.0.0.1 (étapes 1 et 2).
  2. Hors plage éphémère : en dessous de la borne basse de l'étape 3 (49152 par défaut) — sinon une socket sortante peut le préempter.
  3. Conforme au plan Apache : le vhost proxy doit pointer vers ce port.
  4. Un seul chiffre dans tout le déploiement : ASPNETCORE_URLS, ProxyPass et SRV_LANGUES doivent décrire le même service. Une divergence produit un routage silencieux vers le mauvais service (404, ou réponse d'un autre service).

Sécurité : Kestrel reste lié à 127.0.0.1 (HTTP), jamais à 0.0.0.0. L'exposition publique se fait uniquement en HTTPS par le reverse proxy Apache. Le numéro choisi n'a aucune incidence sur ce point : c'est l'adresse de liaison qui protège le service, pas le port.


7. Marche à suivre détaillée (fenêtre de maintenance)

7.1 Audit (lecture seule)

Get-Service OmikaLanguesApi -ErrorAction SilentlyContinue | Select-Object Name,Status
[Environment]::GetEnvironmentVariable('Langues__RootPath','Machine')
Test-Path 'C:\Omika\Data\Langues\manifest.json'

7.2 Backup des binaires et des données (AVANT remplacement)

$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$root = 'C:\Omika\Backups'
# Binaires : seulement s'ils existent déjà
if (Test-Path 'C:\Omika\Apps\LanguesApi') {
  Copy-Item 'C:\Omika\Apps\LanguesApi' -Destination "$root\LanguesApi_${stamp}" -Recurse -Force
}
if (Test-Path 'C:\Omika\Apps\OmikaApi') {
  Copy-Item 'C:\Omika\Apps\OmikaApi' -Destination "$root\OmikaApi_${stamp}" -Recurse -Force
}
# Données langues : seulement si le dossier existe déjà
if (Test-Path 'C:\Omika\Data\Langues') {
  Copy-Item 'C:\Omika\Data\Langues' -Destination "$root\Langues_${stamp}" -Recurse -Force
}

7.3 Arrêt des services

Stop-Service OmikaLanguesApi -Force -ErrorAction SilentlyContinue
Stop-Service OmikaApi -Force
Get-Service OmikaApi,OmikaLanguesApi | Select-Object Name,Status

7.4 Copie des binaires (préserve la config serveur existante)

robocopy 'C:\Omika\Deploy\OmikaApi-next'   'C:\Omika\Apps\OmikaApi'   /E /XF appsettings.json appsettings.Production.json web.config
robocopy 'C:\Omika\Deploy\LanguesApi-next' 'C:\Omika\Apps\LanguesApi' /E /XF appsettings.json appsettings.Production.json web.config

Ne jamais supprimer : C:\Omika\Config\**, C:\Omika\Data\** (dont C:\Omika\Data\Langues\**), certificats TLS, variables d'environnement MACHINE.

7.5 Création du service OmikaLanguesApi (NOUVEAU — premier déploiement)

Le service se crée par le script dédié (recommandé : idempotent, vérifie le compte, le droit de connexion et la disponibilité du port, prend en charge -WhatIf et -Desinstaller) :

cd C:\Omika\Deploy\Deploy
.\Install-OmikaLanguesApi.ps1 -Port <PORT_LANGUES>

Le script résout le compte, pose les ACL (lecture seule sur les modèles), vérifie que <PORT_LANGUES> est réellement libre, puis crée le service OmikaLanguesApi (Manual, non démarré). Il n'écrit aucune variable d'environnement : la configuration reste l'étape §7.5bis ci-dessous.

Équivalent manuel (si vous préférez ne pas utiliser le script) :

$cred = Get-Credential -UserName '.\svc_omika_langues' -Message 'Compte service OmikaLanguesApi'
New-Service -Name 'OmikaLanguesApi' -DisplayName 'Omika Langues Api' `
  -BinaryPathName '"C:\Omika\Apps\LanguesApi\Omika.Langues.Api.exe"' `
  -Credential $cred -StartupType Manual

# ACL sur le dossier des modèles (lecture seule suffit)
icacls 'C:\Omika\Data\Langues' /grant:r "$env:COMPUTERNAME\svc_omika_langues:(OI)(CI)R"

Le compte dédié doit avoir le droit « Ouvrir une session en tant que service » (le script le vérifie et avertit si le droit manque — erreur 1069 au démarrage).

Prérequis binaire : le service doit embarquer UseWindowsService(). Sans lui, il démarre puis s'arrête aussitôt avec l'erreur 1053 (« le service n'a pas répondu à temps »). C'est le cas depuis l'ajout de Microsoft.Extensions.Hosting.WindowsServices à Omika.Langues.Api.

infra\deploy\Install-OmikaServices.ps1 couvre désormais ce service, via l'option -InclureLangues (voir §11).

7.5bis Configuration du service (variables d'environnement MACHINE)

Premier déploiement uniquement : poser la configuration en variables d'environnement MACHINE (le robocopy §7.4 a exclu appsettings.json, donc le service démarre sans fichier de config). Toute modification exige ensuite un redémarrage du service.

# <PORT_LANGUES> : port décidé en §6bis — NE PAS copier une valeur d'exemple.
$portLangues = <PORT_LANGUES>

[Environment]::SetEnvironmentVariable('Langues__RootPath', 'C:\Omika\Data\Langues', 'Machine')
[Environment]::SetEnvironmentVariable('ASPNETCORE_URLS', "http://127.0.0.1:$portLangues", 'Machine')
[Environment]::SetEnvironmentVariable('ASPNETCORE_ENVIRONMENT', 'Production', 'Machine')

# Contrôle
[Environment]::GetEnvironmentVariable('Langues__RootPath', 'Machine')
[Environment]::GetEnvironmentVariable('ASPNETCORE_URLS', 'Machine')
  • Langues__RootPath : obligatoire en production (défaut = dossier de l'application, qui serait écrasé au prochain déploiement).
  • ASPNETCORE_URLS : port loopback explicite, décidé en §6bis (ne jamais recopier un exemple : le port se déduit du plan Apache, pas de ce document). Sans cette variable, Kestrel écoute http://localhost:5000.
  • Le reverse proxy Apache expose ensuite ce port en HTTPS ; SRV_LANGUES pointe sur l'URL publique (voir §4 et §7.5ter).

7.5ter Exposition HTTPS par le reverse proxy Apache

Le service écoute en HTTP sur 127.0.0.1 : il est inatteignable depuis un téléphone. L'exposition se fait dans le vhost 443 existant.

SRV_LANGUES décrit l'URL de base seule : le mobile construit ensuite {base}/api/langues puis {base}/api/langues/{code}/{sens}/{fichier} (LanguagePackService.ConstruireUrl, qui concatène — un chemin dans la base est donc conservé). Pour SRV_LANGUES = https://omika.applilogik.fr/langues, Apache doit donc retirer le préfixe /langues avant de transmettre au service :

    # C:\Apache24\conf\extra\httpd-ssl.conf — dans le <VirtualHost ...:443>
    # Service Langues : /langues/api/langues -> http://127.0.0.1:5099/api/langues
    ProxyPass        /langues/  http://127.0.0.1:5099/
    ProxyPassReverse /langues/  http://127.0.0.1:5099/
    ProxyPass        /langues   http://127.0.0.1:5099/
    ProxyPassReverse /langues   http://127.0.0.1:5099/

Puis :

& C:\Apache24\bin\httpd.exe -t          # doit dire « Syntaxe OK »
Restart-Service <service Apache>

Contrôles (le --resolve évite le DNS : depuis le serveur, le nom public résout souvent vers une IP externe qui ne revient pas sur la machine) :

$U = 'https://omika.applilogik.fr'
$C = @('--resolve','omika.applilogik.fr:443:127.0.0.1','-k','-s','-o','NUL','-w','%{http_code}\n')

curl.exe @C "$U/langues/api/langues"                            # 200
curl.exe @C "$U/langues/api/langues/gl/commun/vocab.json"       # 200
curl.exe @C "$U/health"                                         # 200 : API métier intacte

$j = (curl.exe -k -s --resolve omika.applilogik.fr:443:127.0.0.1 "$U/langues/api/langues") -join ''
($j | ConvertFrom-Json).packs.Count                             # 31
  • Le préfixe /langues n'est pas décoratif : la règle existante ProxyPass /api/ http://127.0.0.1:5080/api/ capte /api/langues et l'envoie à l'API métier, qui ne sert plus les langues (404). Un préfixe dédié évite de toucher à cette règle métier et de dépendre de l'ordre des ProxyPass.
  • Variante vhost dédié (https://langues.applilogik.fr) : la règle devient ProxyPass /api/langues http://127.0.0.1:5099/api/langues (sans préfixe à retirer), et SRV_LANGUES = https://langues.applilogik.fr.
  • $U/langues seul répond 404 du service : il n'y a pas de route /, c'est normal et sans conséquence (le mobile n'appelle que les chemins /api/...).
  • Un 404 sur $U/langues/api/langues signifie que la règle n'a pas été chargée (fichier non réécrit, ou Apache non rechargé) — ce n'est pas un problème de service : http://127.0.0.1:5099/api/langues reste alors 200.

7.6 Déploiement des fichiers modèles + manifeste

Procédure complète : LIVRAISON_MODELES_LANGUES.md (obtention des modèles, arborescence, dépôt, génération du manifeste, contrôles). Résumé :

$root = 'C:\Omika\Data\Langues'
New-Item -ItemType Directory -Force -Path $root | Out-Null

# 1. Copier UNIQUEMENT les dossiers de langue {code}\ (pas de manifest.json
#    préparé ailleurs : il dépend des fichiers réellement présents ici)
robocopy 'C:\Omika\Deploy\Langues\es' "$root\es" /E /R:2 /W:2

# 2. GÉNÉRER le manifeste sur le serveur (taille + SHA-256 de chaque fichier)
cd C:\Omika\Deploy\Deploy
.\New-OmikaLanguesManifeste.ps1

# 3. Contrôler
.\New-OmikaLanguesManifeste.ps1 -Verifier

Le manifeste n'est jamais recopié d'une autre machine : il contient la taille et l'empreinte SHA-256 des fichiers de ce disque. Un manifeste provenant d'ailleurs fait refuser chaque pack par le mobile, sans aucune erreur côté serveur.

Le manifeste et les fichiers modèles sont relus à chaque requête : aucun redémarrage n'est nécessaire. Le mobile, lui, garde son index mémorisé : il faut « Actualiser la liste » dans Paramètres → Langue secondaire.

7.7 Création / mise à jour du paramètre SRV_LANGUES (HFSQL)

Écrire la ligne ParametreSysteme (voir §4) si elle n'existe pas, en pointant vers l'URL du service Langues. Aucun redémarrage requis : relue à chaque bootstrap mobile.

7.8 Redémarrage (consommateurs avant producteurs)

Start-Service OmikaLanguesApi   # 1. service Langues (d'abord, car appelé par le mobile)
Start-Service OmikaApi          # 2. API métier (expose LanguesUrl)
Get-Service OmikaApi,OmikaLanguesApi | Select-Object Name,Status

8. Smoke tests

Accès anonyme : aucun token requis — les réponses sont directes. <PORT_LANGUES> = le port décidé en §6bis et posé en §7.5bis (aucun exemple n'est fourni ici : recopier un chiffre d'exemple est précisément l'erreur à éviter).

# Racine du service
Invoke-WebRequest 'http://127.0.0.1:<PORT_LANGUES>/' -UseBasicParsing          # 200 {status:ok}

# Manifeste
$manifest = Invoke-RestMethod 'http://127.0.0.1:<PORT_LANGUES>/api/langues'
$manifest.packs | Select-Object code,libelle,version

# Téléchargement d'un fichier (valide le streaming + la résolution)
Invoke-WebRequest 'http://127.0.0.1:<PORT_LANGUES>/api/langues/es/versFrancais/encoder.onnx' `
  -OutFile "$env:TEMP\encoder.onnx"
Get-Item "$env:TEMP\encoder.onnx" | Select-Object Name,Length   # taille = tailleOctets

# Cas d'erreur attendu
Invoke-WebRequest 'http://127.0.0.1:<PORT_LANGUES>/api/langues/es/versFrancais/absent.onnx' -SkipHttpErrorCheck
# → 404

Vérifier aussi côté métier : après un bootstrap mobile, LanguesUrl vaut bien l'URL du service Langues (pas null).


9. Mise à jour (ajout de langue / nouvelle version de modèle)

9.1 Ajouter une nouvelle langue

  1. Déposer les fichiers sous C:\Omika\Data\Langues\{code}\versFrancais\ et {code}\depuisFrancais\.
  2. Ajouter l'objet pack dans manifest.json (avec version, tailleOctets, sha256).
  3. Aucun redémarrage : le manifeste est relu à chaque GET /api/langues.

9.2 Mettre à jour un modèle existant

  1. Remplacer le(s) fichier(s) .onnx / .spm sous {code}\{sens}\.
  2. Recalculer tailleOctets et sha256 (§5.3).
  3. Incrémenter version du pack (ex. 1.0.0 → 1.0.1).

Le mobile compare version (et sha256) entre son modèle local et le manifeste serveur pour décider du re-téléchargement : tant que version et sha256 sont inchangés, le mobile considère son modèle à jour.

9.3 Retirer une langue

  1. Supprimer l'objet pack de manifest.json.
  2. Optionnel : supprimer le dossier {code} de C:\Omika\Data\Langues.

10. Rollback

  • Binaires : restaurer C:\Omika\Backups\LanguesApi_<stamp> (arrêt → copie → démarrage §7.8). Idem OmikaApi_<stamp> si besoin.
  • Fichiers langues : restaurer C:\Omika\Backups\Langues_<stamp> (simple copie, aucune migration à annuler).
  • Paramètre HFSQL : remettre l'ancienne valeur de PAS_Valeur (ou vider SRV_LANGUES → LanguesUrl = null → la fonctionnalité est désactivée côté mobile).

11. Écarts constatés (scripts/documents à mettre à jour)

  1. infra\deploy\Install-OmikaServices.ps1 : ne crée pas le service OmikaLanguesApi ni ses ACL. RÉSOLU : infra\deploy contient désormais un script par déploiement (Install-OmikaApi.ps1, Install-OmikaWorker.ps1, Install-OmikaDiagnosticsApi.ps1, Install-OmikaDiagnosticsWorker.ps1, Install-OmikaDiagnosticsWeb.ps1, Install-OmikaLanguesApi.ps1) partageant le module Omika.Deploy.Common.psm1. Install-OmikaServices.ps1 devient un orchestrateur qui les enchaîne, avec -InclureLangues pour le service Langues. Le service embarque aussi UseWindowsService() (sans lui : erreur 1053 au démarrage).
  2. infra\deploy\Install-OmikaServerFiles.ps1 : ne copie pas la publication LanguesApi ni le dossier de livraison des modèles — à livrer séparément (§3, §7.6). La livraison des modèles (obtention, arborescence, manifeste, contrôles) est décrite pas à pas dans LIVRAISON_MODELES_LANGUES.md, et le manifeste se génère avec infra\deploy\New-OmikaLanguesManifeste.ps1 (§5.4).
  3. Omika.slnx ne référence pas Omika.Langues.Api (comme les projets Diagnostics) : on publie le .csproj directement.
  4. Client mobile : le téléchargement des modèles est implémenté côté application (voir TRADUCTION_HORS_LIGNE_MOBILE.md). Le moteur d'inférence ONNX Runtime reste à activer (paquet NuGet optionnel, un symbole de compilation) : sans lui, l'application télécharge et vérifie les modèles, mais annonce la traduction comme indisponible au lieu d'échouer.
  5. Plan de ports Apache/Kestrel : non consigné dans le dépôt. Les seuls ports connus sont ceux de DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md §4 (5097, 5098, 5080), qui y sont eux-mêmes donnés comme « à définir / à confirmer » en production. Aucun document ne fixe le port de OmikaLanguesApi : il se décide sur le serveur (§6bis). Tant que ce plan n'existe pas par écrit, tout port cité en exemple dans un runbook doit être traité comme un espace réservé à remplacer, jamais comme une valeur à recopier.

12. Récapitulatif des points de configuration

  1. Base HFSQL : ligne ParametreSysteme PAS_Code = 'SRV_LANGUES' → URL du service Langues.
  2. Service OmikaLanguesApi : variables MACHINE Langues__RootPath → C:\Omika\Data\Langues et ASPNETCORE_URLS → http://127.0.0.1:<PORT_LANGUES> (port décidé en §6bis, posé §7.5bis).
  3. Fichiers : arborescence {code}/{sens}/{fichier} sous RootPath, puis manifest.json généré par New-OmikaLanguesManifeste.ps1 (§5.4) — jamais saisi à la main.
  4. Binaires : Omika.Langues.Api (nouveau) + Omika.Api (republication).
  5. Accès : anonyme — aucun token, aucun accès HFSQL.
  6. Mise à jour : ajouter/remplacer les fichiers puis regénérer le manifeste ; aucun redémarrage du service n'est requis (il relit le manifeste à chaque appel de GET /api/langues). Le mobile, lui, garde son index mémorisé : il faut un rafraîchissement de la liste des langues pour voir le changement.