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:
@@ -1,4 +1,5 @@
|
||||
const apiService = require('../services/api-service').getInstance();
|
||||
const entityResolver = require('../services/entity-resolver');
|
||||
|
||||
/**
|
||||
* Tools MCP pour interagir avec les APIs WMS
|
||||
@@ -18,7 +19,7 @@ function listTools() {
|
||||
properties: {
|
||||
entity_type: {
|
||||
type: 'string',
|
||||
description: 'Type d\'entité (Containers, Stocks, ProductLocations, Tasks, Products, Accounts, Suppliers, Kits, Aliases, InboundOrders, Receptions, OutboundOrders)',
|
||||
description: 'Type d\'entité — nom AD (Container) ou TableName (Containers), insensible à la casse, résolu via l\'API Metadata. Ex: Containers, Stocks, ProductLocations, Tasks, Products, Accounts, Suppliers, Kits, Alias, InboundOrders, Receptions, OutboundOrders. Liste complète via get_entity_metadata.',
|
||||
},
|
||||
expression: {
|
||||
type: 'string',
|
||||
@@ -85,8 +86,12 @@ async function callQueryAPI(args) {
|
||||
const { entity_type, expression = 'z => z', filter, limit = 100 } = args;
|
||||
|
||||
try {
|
||||
// Résolution Name/TableName -> TableName (D21) — échec avant appel réseau
|
||||
// sur nom inconnu.
|
||||
const { tableName, warning } = await entityResolver.resolveEntityType(entity_type);
|
||||
|
||||
// Expression = Context.Entity + optional Where + OrderBy (required by EF when Take is used)
|
||||
let linqExpression = `Context.${entity_type}`;
|
||||
let linqExpression = `Context.${tableName}`;
|
||||
if (filter) {
|
||||
const whereExpr = /^\s*\w+\s*=>/.test(filter) ? filter : `z => ${filter}`;
|
||||
linqExpression += `.Where(${whereExpr})`;
|
||||
@@ -106,6 +111,8 @@ async function callQueryAPI(args) {
|
||||
{
|
||||
success: true,
|
||||
entityType: entity_type,
|
||||
resolvedTableName: tableName,
|
||||
...(warning ? { warning } : {}),
|
||||
result,
|
||||
},
|
||||
null,
|
||||
|
||||
Reference in New Issue
Block a user