Commit Graph

7 Commits

Author SHA1 Message Date
Arthur Ria 5386f54922 L2.2 : rejette les paramètres inconnus et les requis manquants (D23)
Mesure V1 (24/08/2026) : le SDK MCP ignore additionalProperties: false —
read_recent_logs({lines: 5}) avec la clause sur le schéma répondait
success: true, returnedLines: 100 (retombée silencieuse sur le défaut).
La validation vit donc dans le wrapper tools/call de src/index.js,
pilotée par les schémas de la table de routage (D22) : paramètre inconnu
ou requis manquant -> erreur structurée nommant le fautif et les
paramètres valides, avant tout dispatch.

Les 23 schémas portent additionalProperties: false — inerte côté SDK,
mais c'est le contrat que lisent les clients. Pas de renommage de
paramètres (écarté, cf. ROADMAP).

Mesures (via le protocole) :
- read_recent_logs({"lines": 5}) -> "Paramètre(s) inconnu(s) pour
  read_recent_logs : lines. Paramètres valides : count, log_file."
- read_recent_logs({"count": 5}) -> succès, returnedLines: 5
- boucle sur 22 outils avec {} (execute_command vérifié statiquement) :
  22/22 répondent, aucun Unknown tool, les 11 outils à paramètres requis
  échouent avec le message actionnable
- handshake : 23 outils, 6 resources

Docs : D23 dans DECISIONS.md, L2.2 retirée de la ROADMAP.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 17:32:15 +02:00
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
Arthur Ria 3a89c317e8 L1.3 : aligne les projections des workflows sur les clés réelles de l'AD
Les clés réelles d'un workflow AD (relevées en direct, minuscules,
cf. D5) sont : id, name, version, applicationName, commonInfo, data…
search_workflows projetait w.Id, w.Code, w.Name, w.Category,
w.Description, w.Created, w.Modified — toutes undefined, supprimées par
JSON.stringify : 50 objets vides pour un count pourtant correct.

La projection porte désormais id, name, applicationName, version, et
les équivalents réels de created/modified trouvés dans commonInfo
(createdBy, createDate, updateDate). Code et Description n'existent
dans aucune casse : non projetés.

La notion de catégorie n'a aucun support dans les données : elle est
mappée explicitement sur applicationName, seul regroupement fourni par
l'API AD — assumé dans les descriptions d'outils et par une note dans
la réponse de list_workflow_categories, qui renvoyait 0 catégorie et
classait les 4012 workflows en « Uncategorized ». Le paramètre category
de search_workflows filtre sur applicationName. Le filtre de recherche
ne teste plus description/code, clés inexistantes.

Vérifié contre le WMS réel : search_workflows("stacker") renvoie des
objets peuplés (StackerCrane_…), list_workflow_categories renvoie
EasyWMS avec 4012 workflows, get_workflow_details renvoie toujours
l'objet brut complet (data 71 Ko).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 16:45:24 +02:00
Arthur Ria e0bdc1707d L1.2 : route les outils par table explicite nom -> module (D22)
Le routage par préfixe de nom laissait deux outils listés dans
tools/list mais injoignables : get_entity_metadata (capté par
startsWith('get_entity_') avant sa propre branche) et list_log_files
(aucune branche : le nom contient _log_files, pas _logs).

Une table nom d'outil -> module est construite au démarrage depuis les
listTools() des 8 modules de src/tools/. tools/list est servi depuis
cette même table et le dispatch devient un lookup : un outil listé est
un outil routé, par construction. Deux modules déclarant le même nom
font échouer le serveur au démarrage avec un message nommant les deux
modules. Le wrapper d'erreur du handler tools/call est inchangé, les
23 outils gardent leurs noms.

Vérifié contre le WMS réel : get_entity_metadata renvoie 232 entités,
list_log_files renvoie 19 fichiers, tools/list expose toujours 23
outils et chaque nom listé est traité par le executeTool() de son
module.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 16:43:40 +02:00
Arthur Ria 3dad5c6088 L1.1 : remonte le détail des erreurs HTTP dans les réponses d'outils
Toute erreur d'API se résumait à « Request failed with status code 500 »
alors que le WMS renvoie le diagnostic complet (erreurs de compilation
LINQ, entité inconnue…) dans le corps de la réponse, jusqu'ici jeté par
les catch de post() et get().

L'erreur propagée porte désormais : verbe, URL complète, statut HTTP,
payload envoyé (dont Application et QueryType), et corps de réponse
tronqué à 2000 caractères. Pour les corps structurés, Message et
InnerException.Message sont extraits plutôt qu'un JSON.stringify
intégral qui noierait le diagnostic dans le bruit WatsonBuckets.
Le rejeu après refresh de token 401 est conservé, et une erreur pendant
le rejeu est enrichie de la même façon. Aucun credential ni token dans
le message (les headers ne sont jamais inclus).

Vérifié contre le WMS réel : query_wms_entities("Container") fait
apparaître « 'ApplicationReadingContext' ne contient pas de définition
pour 'Container' » dans la réponse de l'outil. npm test : 4/4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 16:41:18 +02:00
Arthur Ria 9b95e15cbc Nettoyage du dépôt : doublons, code mort, secrets, build
Fichiers hors périmètre ou dupliqués :
- suppression des 5 .md dupliqués à la racine (copies md5-identiques de
  docs/api/ et docs/entities/)
- suppression de JANITOR_main.js / JANITOR_entities.json (application
  Electron sans lien avec le serveur MCP)
- suppression de temp/*.json (dumps de workflows versionnés par accident)
  et ajout de temp/ au .gitignore
- suppression de claude_desktop_config_ssh.json : mots de passe en clair et
  variables ORACLE_* d'une architecture abandonnée
- AD_API_TEST_RESULTS.md -> docs/ad-api-validation.md (credentials du
  snippet remplacés par des variables d'environnement)
- suppression d'IMPLEMENTATION_SUMMARY.md, doublon du précédent
- queries api.php -> docs/reference-queries-api.php (renommage seul)

Code mort :
- suppression de src/resources/documentation.js : la resource docs:// n'a
  jamais été branchée dans src/index.js
- suppression de src/config/constants.js : module entièrement inutilisé,
  requis par wms-query-service.js mais dont aucune constante n'était lue.
  Emporte RESOURCE_URIS.WORKFLOWS_CATEGORIES, URI déclarée jamais servie.
- log-service.js : suppression de findRecentErrors, readFullLog et
  getLogStats, exportées mais exposées par aucun outil MCP
- suppression de LOG_FILE_PATTERN (lue depuis .env, jamais appliquée : le
  scan filtre sur .log en dur), y compris dans .env.example
- log-service.js : préfixe [Logs] sur les messages, comme les autres modules

Secrets :
- test-ad-api.ps1 -> scripts/test-ad-api.ps1, credentials passés en
  paramètres ou par WMS_USERNAME / WMS_PASSWORD au lieu d'être en dur

Build et test :
- @yao-pkg/pkg en devDependency, cible node22-win-x64 : npm run build
  échouait faute de pkg, et node20 n'a pas de binaire prébuilt (bascule sur
  une compilation de Node qui échoue sans toolchain MSVC)
- index.js : le .env est lu à côté de l'exécutable quand le serveur est
  packagé. Avec un chemin statique, pkg embarquait le .env dans le snapshot,
  figeant les credentials dans le binaire.
- scripts/test-connection.js : npm test pointait sur un fichier absent.
  Smoke test en lecture seule (OAuth, QueryExecute, QueryScalarExecute,
  API AD), par profil ou sur tous.

Vérifié après nettoyage : 23 outils et 6 resources répondent au handshake
MCP, npm test passe 4/4 contre le WMS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 15:15:08 +02:00
Arthur Ria b59cbb3546 version mise à jour par claude , à tester 2026-05-20 09:38:07 +02:00