L4.1 : expose query_type sur les outils de requête (D25)

QueryType était figé à 0 en dur dans executeQuery/executeScalarQuery : le
modèle Writing, opérationnel et mesuré, était inatteignable. Paramètre
query_type (défaut 0) sur call_query_api, query_wms_entities,
count_wms_entities — get_entity_schema et search_wms_data restent des
raccourcis Reading.

D3 reste la règle par défaut : la bascule est un opt-in, avertie dans les
descriptions d'outils (statuts en énumérations en Writing). Garde de valeur
assertValidQueryType dans le code (le wrapper D23 ne valide pas les valeurs),
avant tout réseau. En query_type != 0, un nom inconnu du Metadata Reading
passe tel quel avec warning (allowUnknown du resolver) — conservé aussi dans
la réponse d'erreur si le WMS échoue ensuite. Acté en D25 ; CLAUDE.md nuancé,
L4.1 retiré de la ROADMAP (reliquat : exploration Metrics, rapport à part).

Vérifications rejouées via le protocole (LIMAGRAIN / LIMAGRAI2512) :
- call_query_api(Products, query_type:1, limit:1) -> success, 1 ligne,
  queryType:1 dans la réponse.
- call_query_api(Products, query_type:3) -> erreur structurée contenant
  'ApplicationMetricDataContext' ne contient pas de définition pour 'Products'.
- call_query_api(Products, query_type:7) -> erreur locale nommant les 4
  contextes, aucun [API] POST/GET dans stderr.
- query_wms_entities(Container, limit:1) sans query_type -> comportement
  inchangé (resolvedTableName Containers, Reading, pas de champ queryType).
- call_query_api(FooBar123, query_type:1) -> transmis tel quel (payload
  QueryType:1 Expression Context.FooBar123...), erreur WMS
  ApplicationWritingRepository + warning de résolution dans la réponse.
- count_wms_entities(Product, query_type:1) -> count 51145 (~51160).
Baseline : tools/list 23, resources 6, rejet D23 d'un paramètre inconnu OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Arthur Ria
2026-08-25 11:17:10 +02:00
parent 88dab289cc
commit 706e628715
9 changed files with 171 additions and 49 deletions
+23 -3
View File
@@ -1,5 +1,6 @@
const apiService = require('../services/api-service').getInstance();
const entityResolver = require('../services/entity-resolver');
const { assertValidQueryType } = require('../services/wms-query-service');
/**
* Tools MCP pour interagir avec les APIs WMS
@@ -36,6 +37,11 @@ function listTools() {
description: 'Limite de résultats (défaut: 100)',
default: 100,
},
query_type: {
type: 'number',
description: 'QueryContextType (défaut: 0 = Reading — statuts en chaînes, à garder sauf raison explicite). Opt-in : 1 = Writing (statuts en ÉNUMÉRATIONS — les comparaisons de chaînes comme == "Release" ÉCHOUENT), 2 = DataWarehouse (souvent non configuré), 3 = Metrics (modèle de données distinct). En query_type != 0, un nom d\'entité inconnu du Metadata Reading est transmis tel quel avec un warning.',
default: 0,
},
},
required: ['entity_type'],
},
@@ -85,12 +91,23 @@ async function executeTool(name, args) {
* Tool: call_query_api
*/
async function callQueryAPI(args) {
const { entity_type, expression = 'z => z', filter, limit = 100 } = args;
const { entity_type, expression = 'z => z', filter, limit = 100, query_type = 0 } = args;
// Conservé hors du try : si la requête échoue ensuite côté WMS, le warning
// de résolution (nom hors Reading) reste dans la réponse d'erreur.
let resolution = null;
try {
// Garde de valeur avant tout réseau (D25) — le wrapper D23 ne valide pas
// les valeurs.
const queryType = assertValidQueryType(query_type);
// Résolution Name/TableName -> TableName (D21) — échec avant appel réseau
// sur nom inconnu.
const { tableName, warning } = await entityResolver.resolveEntityType(entity_type);
// sur nom inconnu, sauf en query_type != 0 (passage tel quel + warning, D25).
resolution = await entityResolver.resolveEntityType(entity_type, {
allowUnknown: queryType !== 0,
});
const { tableName, warning } = resolution;
// Expression = Context.Entity + optional Where + OrderBy (required by EF when Take is used)
let linqExpression = `Context.${tableName}`;
@@ -103,6 +120,7 @@ async function callQueryAPI(args) {
const result = await apiService.executeQuery(linqExpression, {
take: limit || undefined,
select: expression !== 'z => z' ? expression : undefined,
queryType,
});
return {
@@ -115,6 +133,7 @@ async function callQueryAPI(args) {
entityType: entity_type,
resolvedTableName: tableName,
...(warning ? { warning } : {}),
...(queryType !== 0 ? { queryType } : {}),
result,
},
null,
@@ -132,6 +151,7 @@ async function callQueryAPI(args) {
{
success: false,
error: err.message,
...(resolution?.warning ? { warning: resolution.warning } : {}),
},
null,
2