L2.1 : résout entity_type via l'API Metadata (D21)
Context.{entity_type} attend le TableName du Metadata, pas le nom
d'entité de l'AD (Container -> Containers, mais Alias -> Alias) : un nom
faux partait en HTTP 500 de compilation LINQ. Nouveau service
entity-resolver.js : table Name|TableName (insensible à la casse) ->
TableName, agrégée sur les applications déployées (via
GET /configuration/applications — les applications sans contexte
requêtable n'y figurent pas et n'apportent 0 entité Metadata), cache TTL
partagé, invalidation par onSwitch (D8). Branché dans wms-query-service
(query/count/schema/search) et call_query_api.
Nom inconnu -> échec avant tout appel réseau de requête, suggestions
proches + renvoi vers get_entity_metadata. Metadata injoignable -> le
nom passe tel quel avec un warning dans la réponse.
Mesures (LIMAGRAIN, via le protocole) :
- query_wms_entities("Container", limit 1) -> succès, 1 ligne, résolu
Containers
- query_wms_entities("Alias") -> succès, invariant (pas de pluriel)
- query_wms_entities("Item") -> "Item" n'existe pas dans le modèle
Reading. Proches : RFMenuItems, Sites. 288 entités disponibles —
aucune ligne [API] POST dans stderr
- count_wms_entities("Product") -> 51160
- get_entity_schema("Container") et call_query_api("Container") : mêmes
résolutions
- 288 TableName distincts sur 5 applications, aucun conflit
Name -> TableName (mesuré le 24/08/2026)
Docs : D21 dans DECISIONS.md ; CLAUDE.md (piège retiré des points
ouverts, liste d'entités corrigée Aliases -> Alias, entity-resolver dans
la structure) ; exemple singulier/pluriel dans wms://query-examples ;
ROADMAP allégée (cause racine + L2.1 + L3.3 livrés).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+4
-54
@@ -12,51 +12,10 @@ contient que ce qui reste à faire.
|
||||
|
||||
---
|
||||
|
||||
## Cause racine commune
|
||||
|
||||
Le MCP interpole `entity_type` dans `Context.{entity_type}` **sans aucune
|
||||
validation** (vérifié : aucune liste blanche dans le code). Or le nom attendu
|
||||
par le contexte de lecture n'est pas le nom d'entité de l'Application
|
||||
Dictionary.
|
||||
|
||||
L'API Metadata (`GET /Metadata/Entities`, **232 entités**) donne la
|
||||
correspondance exacte :
|
||||
|
||||
| `Name` (renvoyé par `search_ad_elements`) | `TableName` (attendu par `Context.`) |
|
||||
|---|---|
|
||||
| `Container` | `Containers` |
|
||||
| `Product` | `Products` |
|
||||
| `ContainerType` | `ContainerTypes` |
|
||||
| `Alias` | `Alias` — **invariant, pas de pluriel** |
|
||||
| `Item` | *n'existe pas dans le modèle Reading* |
|
||||
|
||||
Ce n'est donc pas une règle de pluralisation : c'est un mapping, et seul
|
||||
`TableName` fait foi. `TableName` est unique sur les 232 entités.
|
||||
|
||||
Conséquences déjà constatées :
|
||||
- une session utilisant les noms de l'AD (singuliers) déclenche un **HTTP 500**
|
||||
sur chaque requête ;
|
||||
- la liste d'entités documentée était fausse (`Aliases` n'existe pas, c'est
|
||||
`Alias`) ;
|
||||
- le MCP n'expose que 12 entités figées là où l'API en connaît 232.
|
||||
|
||||
---
|
||||
|
||||
## Lot 2 — Correctif de fond
|
||||
|
||||
### L2.1 — Résolution des entités via l'API Metadata
|
||||
|
||||
Accepter `entity_type` au nom d'entité (`Container`) ou au nom de jeu
|
||||
(`Containers`), insensible à la casse, et émettre `Context.{TableName}`. Cache
|
||||
identique aux autres (TTL partagé, invalidation au changement de profil).
|
||||
|
||||
Sur nom inconnu, échouer **avant tout appel réseau**, avec un message
|
||||
actionnable :
|
||||
|
||||
> « Item » n'existe pas dans le modèle Reading. Proches : ItemGroup, StockItem.
|
||||
> 232 entités disponibles — utilisez `get_entity_metadata` pour la liste.
|
||||
|
||||
Supprime la cause des 500 et débloque 232 entités au lieu de 12.
|
||||
La cause racine commune du lot (résolution `Name` -> `TableName` via l'API
|
||||
Metadata) est livrée — la règle et ses mesures vivent en **D21**.
|
||||
|
||||
### L2.2 — Rejeter les paramètres inconnus
|
||||
|
||||
@@ -114,14 +73,6 @@ diagnostic exact, invisible depuis les outils comme depuis le smoke test.
|
||||
Faire remonter `error.response.data` dans le message, comme L1.1 l'a fait pour
|
||||
les outils. Même contrainte : ne jamais logguer les credentials.
|
||||
|
||||
### L3.3 — Documentation
|
||||
|
||||
- DECISIONS.md : **D21** la règle `TableName` (D22, le routage par table
|
||||
explicite, a été livrée avec le lot 1).
|
||||
- CLAUDE.md : corriger la liste d'entités (`Aliases` → `Alias`) et renvoyer vers
|
||||
`get_entity_metadata` comme source de vérité.
|
||||
- `wms://query-examples` : un exemple singulier/pluriel commenté.
|
||||
|
||||
---
|
||||
|
||||
## Lot 4 — Modèle de données et applications
|
||||
@@ -186,9 +137,8 @@ applications).
|
||||
`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
|
||||
Conséquence — traitée : la table de résolution (D21) **agrège le Metadata de
|
||||
toutes les applications** déployées, et non le seul `EasyWMS`. Inutile en
|
||||
revanche d'ajouter un paramètre `application` à `QueryExecute` : il ne changerait
|
||||
rien.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user