feat(qlik-search): surcharge des champs libellé/fournisseur + inventaire en trace

Les intitulés des champs varient d'une app Qlik à l'autre. La détection reste
heuristique, mais l'inventaire complet des champs est désormais loggué et deux
variables d'environnement permettent de corriger le tir sans redéploiement de
code : QLIK_FIELD_ARTICLE_LIBELLE et QLIK_FIELD_FOURNISSEUR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DfqUihgixw4K1AmJhizWiu
This commit is contained in:
Claude committed 2026-07-29 05:05:36 +00:00
1 parent 203c96f6c9
commit 62375d3310
2 files changed
+25 -3

No files matched your search

+11
View File
@@ -35,6 +35,17 @@ ceux-là qu'on veut voir.
Repli : si Qlik est injoignable, la recherche retombe sur `pgSearchProduits()` et
la réponse le signale (`source: "db"`). Résultats mis en cache mémoire 10 min.
Les noms des champs libellé / fournisseur varient d'une app Qlik à l'autre : ils
sont détectés par heuristique, et l'inventaire complet des champs est loggué
(`[qlik-search] champs disponibles=…`). Si la détection tombe à côté, forcer :
```
QLIK_FIELD_ARTICLE_LIBELLE=<nom exact du champ libellé>
QLIK_FIELD_FOURNISSEUR=<nom exact du champ fournisseur>
```
Sans champ libellé exploitable, la recherche fonctionne encore par code centrale.
## Tendance réseau = 12 mois glissants stricts
`computeNetworkTrend()` reconstruit sa fenêtre à partir de la date du jour :
+14 -3
View File
@@ -128,8 +128,9 @@ export async function searchQlikArticles(
if (!csrfToken) throw new Error("[qlik-search] qlik-csrf-token introuvable (client Qlik non chargé ?)");
const result = (await page.evaluate(
({ app, dim, token, terme, limite, maxFieldMatches }: {
({ app, dim, token, terme, limite, maxFieldMatches, champLibelleForce, champFournisseurForce }: {
app: string; dim: string; token: string; terme: string; limite: number; maxFieldMatches: number;
champLibelleForce: string; champFournisseurForce: string;
}) =>
new Promise<InPageSearchResult>((resolve) => {
const loc = (window as unknown as { location: Location }).location;
@@ -182,12 +183,20 @@ export async function searchQlikArticles(
const champCode = champs.find((c) => c === "Article Code")
?? champs.find((c) => has(c, /article/i) && has(c, /code/i))
?? "Article Code";
const champLibelle = champs.find((c) => has(c, /article/i) && has(c, /(libell|designation|désignation|denomination|dénomination)/i))
// Les noms exacts varient selon l'app Qlik : détection par
// heuristique, surchargeable par variable d'environnement si
// l'app expose un intitulé inattendu (cf. les logs [qlik-search]).
const champLibelle = (champLibelleForce && champs.includes(champLibelleForce) ? champLibelleForce : null)
?? champs.find((c) => has(c, /article/i) && has(c, /(libell|designation|désignation|denomination|dénomination)/i))
?? champs.find((c) => has(c, /(libell|designation|désignation)/i) && !has(c, /(magasin|region|région|famille|rayon|fournisseur)/i))
?? null;
const champFournisseur = champs.find((c) => has(c, /fournisseur/i))
const champFournisseur = (champFournisseurForce && champs.includes(champFournisseurForce) ? champFournisseurForce : null)
?? champs.find((c) => has(c, /fournisseur/i))
?? champs.find((c) => has(c, /(fabricant|supplier)/i))
?? null;
// Inventaire complet en trace : sans accès Qlik depuis le poste
// de dev, c'est le seul moyen de régler les surcharges ci-dessus.
trace.push("champs disponibles=" + JSON.stringify(champs));
trace.push("code=" + champCode + " libelle=" + champLibelle + " fournisseur=" + champFournisseur);
// ─── 2. Recherche globale Qlik ───────────────────────────
@@ -295,6 +304,8 @@ export async function searchQlikArticles(
terme: cleaned,
limite: limit,
maxFieldMatches: MAX_FIELD_MATCHES,
champLibelleForce: (process.env.QLIK_FIELD_ARTICLE_LIBELLE ?? "").trim(),
champFournisseurForce: (process.env.QLIK_FIELD_FOURNISSEUR ?? "").trim(),
},
)) as InPageSearchResult;