Files
mcp-wms-api/src/resources/query-examples.js
T
Arthur Ria cb625a7918 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>
2026-08-24 17:28:27 +02:00

281 lines
8.1 KiB
JavaScript

/**
* Query Examples Resources
* Provides example LINQ queries and diagnostic recipes for WMS entities.
*/
function listResources() {
return [
{
uri: 'wms://query-examples',
name: 'Query Examples',
description: 'LINQ query examples and diagnostic recipes for WMS entities',
mimeType: 'text/markdown',
},
];
}
async function readResource(uri) {
let content;
switch (uri) {
case 'wms://query-examples':
content = getQueryExamples();
break;
default:
throw new Error(`Unknown query examples resource: ${uri}`);
}
return {
contents: [{
uri,
mimeType: 'text/markdown',
text: content,
}],
};
}
function getQueryExamples() {
return `# WMS LINQ Query Examples & Diagnostic Recipes
> **Reading model** — \`query_wms_entities\` / \`count_wms_entities\` use \`QueryExecute\`
> (QueryType=Reading). Status/enum fields are **strings** (enum names), never integers.
> Always verify enum values via \`docs://entities/\` or \`get_entity_metadata\` before filtering.
## Entity names — singular AD name or TableName, both accepted
\`entity_type\` is resolved case-insensitively against the Metadata API: the AD
entity name (singular) and the TableName both work. The mapping is **not** a
pluralisation rule — only the Metadata \`TableName\` is authoritative:
\`\`\`
query_wms_entities(entity_type="Container") # AD name -> resolved to Containers
query_wms_entities(entity_type="Containers") # TableName -> used as-is
query_wms_entities(entity_type="Alias") # invariant: TableName IS "Alias" (no plural)
query_wms_entities(entity_type="Item") # fails fast: not in the Reading model,
# error lists close matches + get_entity_metadata
\`\`\`
---
## Diagnostic Recipes
Recipes below were validated against a live WMS. Use them as-is, substituting the
\`X\` placeholders.
### OS incomplètes par classe d'expédition
Compter les ordres de sortie incomplets, actifs, d'une classe donnée
(\`OutboundClassCode\`). Fields verified on the \`OutboundOrder\` Reading entity:
\`OutboundClassCode\` (string), \`IncompleteOrder\` (bool), \`IsActive\` (bool).
\`\`\`
# Toutes classes confondues
count_wms_entities(
entity_type="OutboundOrders",
filter='z.IncompleteOrder == true && z.IsActive == true'
)
# Pour une classe précise
count_wms_entities(
entity_type="OutboundOrders",
filter='z.OutboundClassCode == "SHIPPING_GROUP_01" && z.IncompleteOrder == true && z.IsActive == true'
)
# Lister le détail des OS concernées
query_wms_entities(
entity_type="OutboundOrders",
filter='z.OutboundClassCode == "SHIPPING_GROUP_01" && z.IncompleteOrder == true && z.IsActive == true',
limit=200
)
\`\`\`
### Containers bloquants sur un emplacement
Identifier les conteneurs qui retiennent un emplacement parce qu'ils ont des tâches
en attente. Fields verified on the \`Container\` Reading entity:
\`LocationCode\` (string), \`NumContainerPendingTasks\` (long).
\`\`\`
# Combien de containers ont des tâches en attente sur l'emplacement
count_wms_entities(
entity_type="Containers",
filter='z.LocationCode == "QUAI_EXP_01" && z.NumContainerPendingTasks > 0'
)
# Lister ces containers (renvoie toutes les colonnes du container)
query_wms_entities(
entity_type="Containers",
filter='z.LocationCode == "QUAI_EXP_01" && z.NumContainerPendingTasks > 0',
limit=200
)
# Vue globale : tous les containers bloquants du WMS
count_wms_entities(
entity_type="Containers",
filter='z.NumContainerPendingTasks > 0'
)
\`\`\`
### Paramètres système d'un entrepôt
Pour lire les paramètres de configuration WMS et leurs valeurs par entrepôt,
utiliser l'outil dédié \`get_system_parameters\` plutôt qu'une requête LINQ :
\`\`\`
get_system_parameters(warehouse="DOMBASLE") # tous les paramètres
get_system_parameters(warehouse="DOMBASLE", param_class="Shipping")
get_system_parameters(search="CROSSDOCK")
\`\`\`
### Modèles d'expédition — suivi des exécutions
> ⚠️ L'API ne conserve que la **dernière** exécution de chaque modèle d'expédition
> (\`ShipmentTemplate.LastExecuteDate\`). L'historique complet des exécutions n'existe
> que dans les logs serveur \`ApplyShipmentTemplates\`, non exposés par ce MCP.
Fields verified on the \`ShipmentTemplate\` Reading entity: \`Code\`, \`Status\`,
\`IsEnabled\`, \`IsActive\`, \`LastExecuteDate\`, \`WarehouseCode\`, \`Priority\`,
\`DirectiveCode\`.
\`\`\`
# Tous les modèles d'un entrepôt + leur dernière exécution et leur statut
query_wms_entities(
entity_type="ShipmentTemplates",
filter='z.WarehouseCode == "DOMBASLE"',
limit=200
)
# Modèles activés mais jamais exécutés (LastExecuteDate null)
query_wms_entities(
entity_type="ShipmentTemplates",
filter='z.IsEnabled == true && z.LastExecuteDate == null',
limit=200
)
# Combien de modèles exécutés au moins une fois
count_wms_entities(
entity_type="ShipmentTemplates",
filter='z.LastExecuteDate != null'
)
# Modèles exécutés depuis une date (littéral DateTime obligatoire — voir Date filters)
count_wms_entities(
entity_type="ShipmentTemplates",
filter='z.LastExecuteDate >= new DateTime(2025, 1, 1)'
)
\`\`\`
---
## Counting (\`count_wms_entities\`)
Always prefer \`count_wms_entities\` for any "combien" / "how many" question — it uses
\`QueryScalarExecute\` and never materialises rows.
\`\`\`
count_wms_entities(entity_type="OutboundOrders")
count_wms_entities(entity_type="Tasks", filter='z.TaskStatus == "InProcess"')
\`\`\`
---
## Basic Queries
### Get rows (with limit)
\`\`\`
query_wms_entities(entity_type="Products", limit=100)
query_wms_entities(entity_type="Tasks", limit=50)
\`\`\`
> Note: the \`select_expression\` parameter (LINQ projections) is currently unreliable
> against \`QueryExecute\` — prefer querying full rows and reading the fields you need.
## Filtering Examples
### Status filters (string enum names)
\`\`\`
# Tâches en cours / en attente
query_wms_entities(entity_type="Tasks", filter='z.TaskStatus == "InProcess"', limit=100)
query_wms_entities(entity_type="Tasks", filter='z.TaskStatus == "Pending"', limit=100)
# Ordres de sortie lancés
query_wms_entities(entity_type="OutboundOrders", filter='z.OutboundOrderStatus == "Release"', limit=100)
\`\`\`
### Date filters
> ⚠️ \`AddDays()\` et les dates relatives (\`DateTime.Now\`, \`DateTime.Today\`) ne sont
> **pas traduisibles** par le moteur de requête — toujours utiliser un littéral
> \`new DateTime(année, mois, jour)\`. Le nom du champ date dépend de l'entité
> (\`LastExecuteDate\`, \`InternalInfo.CreationDate\`, …) — le vérifier via
> \`get_entity_metadata\` ou \`docs://entities/\`.
\`\`\`
# Éléments depuis une date donnée (littéral DateTime obligatoire)
count_wms_entities(
entity_type="ShipmentTemplates",
filter='z.LastExecuteDate >= new DateTime(2025, 1, 1)'
)
\`\`\`
### Numeric filters
\`\`\`
query_wms_entities(entity_type="Stocks", filter="z.Quantity > 0", limit=100)
\`\`\`
### String filters
\`\`\`
query_wms_entities(entity_type="Products", filter='z.Code.StartsWith("ABC")', limit=100)
query_wms_entities(entity_type="Products", filter='z.Code.Contains("test")', limit=100)
\`\`\`
## Complex Filters
### Multiple conditions (AND / OR)
\`\`\`
query_wms_entities(
entity_type="Tasks",
filter='z.TaskStatus == "Pending" && z.Priority > 50',
limit=100
)
query_wms_entities(
entity_type="OutboundOrders",
filter='z.OutboundOrderStatus == "Release" || z.OutboundOrderStatus == "Creating"',
limit=100
)
\`\`\`
## Common Patterns
### Find an entity by code
\`\`\`
query_wms_entities(entity_type="Products", filter='z.Code == "PROD123"', limit=1)
query_wms_entities(entity_type="OutboundOrders", filter='z.Code == "ORDER123"', limit=1)
\`\`\`
## Performance Tips
1. **Always use limits** — max 1000 rows per query.
2. **Use \`count_wms_entities\` for counts** — never fetch rows just to count them.
3. **Verify enum values first** — Reading model uses string enum names.
4. **Use specific filters** — narrow results at the API level.
---
**Note:** All queries respect the maximum limit of 1000 rows configured in the server.
`;
}
module.exports = {
listResources,
readResource,
};