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,6 +4,7 @@
|
||||
*/
|
||||
|
||||
const apiService = require('./api-service').getInstance();
|
||||
const entityResolver = require('./entity-resolver');
|
||||
|
||||
/**
|
||||
* Build a LINQ select expression
|
||||
@@ -20,13 +21,17 @@ const apiService = require('./api-service').getInstance();
|
||||
* @param {number} limit - Result limit
|
||||
*/
|
||||
async function queryEntities(entityType, selectExpression = 'z => z', filter = null, limit = 100) {
|
||||
// Résolution Name/TableName -> TableName (D21). Un nom inconnu échoue ici,
|
||||
// avant tout appel réseau de requête — l'erreur porte les suggestions.
|
||||
const { tableName, warning } = await entityResolver.resolveEntityType(entityType);
|
||||
|
||||
try {
|
||||
// Enforce max limit
|
||||
const maxLimit = parseInt(process.env.MAX_QUERY_ROWS) || 1000;
|
||||
const actualLimit = Math.min(limit, maxLimit);
|
||||
|
||||
// Build expression: Context + optional Where + OrderBy (required by EF when Take is used)
|
||||
let expression = `Context.${entityType}`;
|
||||
let expression = `Context.${tableName}`;
|
||||
if (filter) {
|
||||
const whereExpr = /^\s*\w+\s*=>/.test(filter) ? filter : `z => ${filter}`;
|
||||
expression += `.Where(${whereExpr})`;
|
||||
@@ -43,6 +48,8 @@ async function queryEntities(entityType, selectExpression = 'z => z', filter = n
|
||||
|
||||
return {
|
||||
entityType,
|
||||
resolvedTableName: tableName,
|
||||
...(warning ? { warning } : {}),
|
||||
expression,
|
||||
limit: actualLimit,
|
||||
count: Array.isArray(result) ? result.length : 0,
|
||||
@@ -144,9 +151,13 @@ async function getEntitySchema(entityType) {
|
||||
* @param {string|null} filter - Optional filter
|
||||
*/
|
||||
async function countEntities(entityType, filter = null) {
|
||||
// Résolution Name/TableName -> TableName (D21) — échec avant appel réseau
|
||||
// sur nom inconnu.
|
||||
const { tableName, warning } = await entityResolver.resolveEntityType(entityType);
|
||||
|
||||
try {
|
||||
// Build: Context.Entity.Where(...).Count()
|
||||
const parts = [`Context.${entityType}`];
|
||||
const parts = [`Context.${tableName}`];
|
||||
if (filter) {
|
||||
const whereExpr = /^\s*\w+\s*=>/.test(filter) ? filter : `z => ${filter}`;
|
||||
parts.push(`Where(${whereExpr})`);
|
||||
@@ -160,6 +171,8 @@ async function countEntities(entityType, filter = null) {
|
||||
|
||||
return {
|
||||
entityType,
|
||||
resolvedTableName: tableName,
|
||||
...(warning ? { warning } : {}),
|
||||
filter,
|
||||
count
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user