Roadmap et décisions : exploitation de la référence API du service

Source : la page d'aide générée https://<host>/ApplicationService/Help, qui
documente des champs et des endpoints que le MCP n'utilise pas. Toutes les
affirmations ci-dessous ont été testées contre LIMAGRAI2512.

D3 corrigé — QueryContextType a quatre valeurs, pas deux :
Reading 0 (ApplicationReadingContext), Writing 1 (ApplicationWritingRepository),
DataWarehouse 2 (non configuré sur ce tenant : IDataWarehouse non résolu),
Metrics 3 (ApplicationMetricDataContext, présent, modèle non exploré). Le
message d'erreur nomme le contexte, ce qui donne un moyen rapide de savoir quel
QueryType a servi.

L4.1 étendu aux quatre contextes.

L4.2 tranché sur son point dur : le champ Application ne partitionne pas le
contexte de lecture. Context.AgvTasks répond aussi bien avec Application AGV
qu'avec EasyWMS — le contexte est commun au tenant. La table de résolution du
lot 2 devra donc agréger le Metadata de toutes les applications, mais un
paramètre application sur QueryExecute serait inutile. Les entités CustomApp
restent inatteignables sous les quatre QueryType, au singulier comme au
pluriel, et Metadata renvoie 0 entité pour cette application : ce sont des
définitions EasyBuilder sans projection requêtable. L'API AD est le seul accès
au spécifique client.

Trois chantiers ajoutés :
- L4.3 ClientModule, non renseigné, d'où des requêtes du MCP journalisées sous
  « Client: GNA » et indistinguables du vrai client GNA.
- L4.4 API WorkflowLog (GetInstances, GetLogs, Validate), joignable et
  fonctionnelle, susceptible de remettre en cause D16.
- L4.5 champs inexploités de QueryExecute : Parameters (requêtes paramétrées,
  piste pour D13), CommandTimeout, QueryId + QueryCancel, QueryExecuteStream
  (piste pour L3.1), plus les endpoints event sourcing et les sondes
  healthcheck/ready.

CLAUDE.md pointe désormais vers la page d'aide comme source de vérité.
MONITORING.md documente healthcheck/ready comme sonde légère.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Arthur Ria
2026-08-24 15:58:28 +02:00
parent 7621b87c49
commit 86923542fa
4 changed files with 102 additions and 20 deletions
+1
View File
@@ -28,6 +28,7 @@ pour le debug et l'analyse. **Fonctionnel et en service.**
| API | Endpoint | Usage |
|---|---|---|
| Query | `POST {api}/QueryExecute` | requêtes LINQ, lignes |
| Référence complète | `https://<host>/ApplicationService/Help` | page d'aide générée du service — **la source de vérité** sur les champs et les endpoints |
| Query scalaire | `POST {api}/QueryScalarExecute` | `Count()`, `Sum()` — à préférer pour « combien » |
| Command | `POST {api}/CommandExecute` | exécution de commandes WMS |
| Metadata | `GET {api}/Metadata/Entities`, `GET {api}/Metadata/EntityProperties` | entités interrogeables et leurs champs |
+12 -4
View File
@@ -46,17 +46,25 @@ Voir `src/services/api-service.js`, méthode `authenticate()`.
## D3 — `QueryType: 0` (Reading), pas 1
**Piège.** `QueryType` sélectionne le modèle de données interrogé :
**Piège.** `QueryType` (type `QueryContextType`) sélectionne le contexte de
données interrogé. Il a **quatre** valeurs, pas deux — vérifiées une à une sur
le tenant `LIMAGRAI2512` :
| Valeur | Modèle | Champs de statut |
| Valeur | Contexte | Statut sur ce tenant |
|---|---|---|
| `0` | **Reading** | chaînes de caractères (`"Release"`) |
| `1` | Writing | énumérations |
| `0` | **Reading** `ApplicationReadingContext` | opérationnel, champs de statut en **chaînes** (`"Release"`) |
| `1` | Writing `ApplicationWritingRepository` | opérationnel, champs de statut en **énumérations** |
| `2` | DataWarehouse | **non configuré** : `Could not resolve serviceType 'IDataWarehouse…'` |
| `3` | Metrics — `ApplicationMetricDataContext` | contexte présent, modèle de données non exploré |
Les comparaisons de statut par chaîne — de loin le cas le plus courant en
debug — **échouent** en `QueryType: 1`. Le code force donc `0` dans
`executeQuery()` et `executeScalarQuery()`.
Le message d'erreur nomme le contexte (`ApplicationReadingContext`,
`ApplicationWritingRepository`, …) : c'est le moyen le plus rapide de savoir
quel `QueryType` a réellement été utilisé.
**Attention.** D'anciens exemples (dont le PHP de référence) utilisent `1`. Ne
les recopiez pas.
+5
View File
@@ -148,6 +148,11 @@ Sortie attendue :
Code de sortie `0` si tout passe, `1` sinon — utilisable tel quel dans une
tâche planifiée.
Sonde plus légère, si l'on veut seulement savoir si le WMS répond (sans
authentification applicative) : `GET https://<host>/ApplicationService/api/healthcheck?tenantCode=<TENANT>`
et `.../api/ready?tenantCode=<TENANT>` renvoient 200. Elles ne disent rien de la
validité des credentials — pour ça, `npm test`.
C'est le premier réflexe quand Claude signale une erreur WMS : il isole en
quelques secondes une panne de connectivité d'un problème de requête.
+84 -16
View File
@@ -159,17 +159,22 @@ chiffres ci-dessous sont mesurés sur le tenant `LIMAGRAI2512`.
### L4.1 — Le modèle Writing est inatteignable
`QueryType` est figé à `0` (Reading) en dur dans `api-service.js`
(`executeQuery` et `executeScalarQuery`). Aucun outil ne permet d'interroger le
modèle **Writing**.
(`executeQuery` et `executeScalarQuery`). Or `QueryContextType` a **quatre**
valeurs. Testées une à une :
Ce n'est pas une limite de l'API : `{"Application":"EasyWMS","QueryType":1,
"Expression":"Context.Products.OrderBy(z => z.Id)","Take":1}` répond
correctement. Il manque simplement le paramètre.
| Valeur | Contexte | Résultat sur `LIMAGRAI2512` |
|---|---|---|
| `0` | Reading | opérationnel (seul utilisé aujourd'hui) |
| `1` | Writing | **opérationnel**`Context.Products` répond |
| `2` | DataWarehouse | **non configuré** : `Could not resolve serviceType 'IDataWarehouse…'` |
| `3` | Metrics | contexte présent (`ApplicationMetricDataContext`), modèle non exploré |
Attention en l'exposant : D3 reste vrai — en `QueryType: 1` les champs de statut
sont des **énumérations**, donc les comparaisons par chaîne (`== "Release"`)
échouent. Le défaut doit rester `0`, et la bascule être un choix explicite et
documenté, pas une option qu'on active au hasard.
Exposer `query_type` sur les outils de requête, défaut `0`. Attention : D3 reste
vrai — en Writing les champs de statut sont des **énumérations**, donc
`== "Release"` échoue. La bascule doit être un choix explicite et documenté.
Le contexte `Metrics` mérite une exploration à part : c'est probablement là que
vivent les données agrégées produites par les jobs `MetricGatherer`.
### L4.2 — Une seule application sur neuf est visible
@@ -203,13 +208,76 @@ suffit d'un paramètre `application` sur les outils AD et workflow, avec une cl
de cache incluant l'application (sinon un cache pollué mélange les
applications).
**QueryExecute — non résolu, à investiguer.** Passer `Application: "CustomApp"`
ne change **pas** le contexte de lecture : l'erreur reste
`ApplicationReadingContext ne contient pas de définition pour …`. Les 11 entités
`CST_` ne sont atteignables ni au singulier ni au pluriel, et **aucune** n'est
présente dans les 232 entités du Metadata `EasyWMS` (vérifié). Elles sont
définies dans EasyBuilder (`FromMetadata: false`) — reste à déterminer si elles
sont interrogeables, et sous quel nom. Ne rien promettre avant d'avoir tranché.
**QueryExecute — tranché : le champ `Application` ne partitionne rien.**
`Context.AgvTasks` (entité de l'application AGV) répond aussi bien avec
`Application: "AGV"` qu'avec `Application: "EasyWMS"`. Le contexte de lecture est
**commun au tenant** : toutes les applications y déversent leurs entités.
Conséquence pour L2.1 : la table de résolution doit **agréger le Metadata de
toutes les applications** (`GET /Metadata/Entities?applicationName=…` par
application, 232 + 20 + 6 + …), et non se limiter à `EasyWMS`. Inutile en
revanche d'ajouter un paramètre `application` à `QueryExecute` : il ne changerait
rien.
**Les entités `CustomApp` ne sont interrogeables dans aucun contexte.** Les 11
entités `CST_` ont été testées sous les quatre `QueryType`, au singulier et au
pluriel : échec partout, et `Metadata/Entities` comme `Metadata/EntitiesAll`
renvoient **0 entité** pour `CustomApp`. Aucune n'est marquée
`isDataWarehouse`. Ce sont des définitions EasyBuilder (`FromMetadata: false`)
sans projection dans un contexte requêtable.
**L'API AD reste donc le seul accès au spécifique client** — ce qui rend le
paramètre `application` sur les outils AD et workflow d'autant plus utile.
### L4.3 — Identifier le MCP dans les logs du WMS
`QueryExecute` accepte un champ **`ClientModule`** que le MCP n'envoie pas.
Résultat : ses requêtes apparaissent dans les logs du WMS sous
`Execute error. Client: GNA` — le client OAuth partagé — donc indistinguables de
celles du vrai client GNA.
Renseigner `ClientModule` (`"MCP-WMS"` ou le nom du profil actif) rend chaque
requête du MCP traçable côté serveur. Vérifié : le champ est accepté.
### L4.4 — Historique d'exécution des workflows par API
`ApplicationService` expose une API `WorkflowLog` que le MCP n'utilise pas :
| Endpoint | Usage |
|---|---|
| `GET /WorkflowLog/GetInstances?processDefinitionId=&skip=&take=&startDateFrom=&startDateTo=` | instances d'un workflow sur une plage de dates, filtrables par attribut |
| `GET /WorkflowLog/GetInstance?processId=` | une instance |
| `GET /WorkflowLog/GetLogs?processId=&skip=&take=&logDateFrom=&logDateTo=` | journal d'exécution d'une instance |
| `GET /WorkflowLog/Validate?applicationName=&processDefinitionId=` | validation d'une définition |
Endpoints joignables et fonctionnels — `Validate` renvoie
`{"Success":true,"ErrorMessage":null,"Warnings":[]}`. `GetInstances` répond `[]`
sur le workflow testé : à confirmer sur un workflow ayant réellement tourné, la
journalisation n'étant pas forcément active partout.
**Peut remettre en cause D16** (historique des shipment templates jugé hors de
portée faute de logs fichier) : si l'historique d'exécution est disponible par
API, la conclusion change. À vérifier avant d'écrire quoi que ce soit.
### L4.5 — Champs de `QueryExecute` inexploités
La référence de l'API documente des champs que le MCP n'envoie jamais :
| Champ | Intérêt |
|---|---|
| `Parameters` | requêtes **paramétrées** (dictionnaire `nom -> {TypeName, Value}`) — supprimerait toute concaténation de chaîne dans les filtres, et pourrait débloquer D13 (`Select`) |
| `CommandTimeout` | timeout par requête, au lieu du timeout HTTP global de 30 s |
| `QueryId` + `POST /QueryCancel` | annulation d'une requête longue |
| `POST /QueryExecuteStream` | résultats en flux — piste sérieuse pour L3.1 (sorties volumineuses) |
Autres endpoints jamais utilisés, à évaluer : `QueryEvents`, `QueryCommands`,
`QueryCorrelationEvents`, `QuerySnapshots` (event sourcing — utile en debug),
`GET /Metadata/Commands|Events|Aggregates` et leurs variantes `…All`,
`GET /configuration/applications` (liste les applications **avec leur version**,
plus riche que `/AD/api/Application/GetAll`), `GET /healthcheck?tenantCode=` et
`GET /ready?tenantCode=` (sondes de disponibilité, répondent 200).
---
---