mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-22 22:48:08 +02:00
feat: Add a diagnostic API route and implement server-side logic for fetching and scoring product grid data.
This commit is contained in:
1 parent
d616da8b91
commit
ab603e3a6f
2 files changed
+33
-21
No files matched your search
+20
-20
@@ -41,6 +41,7 @@ export async function GET(req: NextRequest) {
|
|||||||
// Récupérer un codefou réel + un codein réel depuis l'API
|
// Récupérer un codefou réel + un codein réel depuis l'API
|
||||||
let codefou = searchParams.get("codefou");
|
let codefou = searchParams.get("codefou");
|
||||||
let firstCodein: string | null = searchParams.get("codein");
|
let firstCodein: string | null = searchParams.get("codein");
|
||||||
|
const forcedNoid = searchParams.get("noid"); // ex: ?noid=129632
|
||||||
|
|
||||||
if (!codefou) {
|
if (!codefou) {
|
||||||
try {
|
try {
|
||||||
@@ -61,25 +62,27 @@ export async function GET(req: NextRequest) {
|
|||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Si un noid est forcé, on probe directement mensuel + referentiel pour cet article
|
||||||
|
const mensuelNoidForced = forcedNoid
|
||||||
|
? probe(`${FF_API_BASE}/api/articles/${encodeURIComponent(forcedNoid)}/mensuel?dateDebut=${dateDebut}&dateFin=${dateFin}`)
|
||||||
|
: Promise.resolve({ skipped: "no ?noid= param" });
|
||||||
|
const referentielNoidForced = forcedNoid
|
||||||
|
? probe(`${FF_API_BASE}/api/articles/${encodeURIComponent(forcedNoid)}/referentiel`)
|
||||||
|
: Promise.resolve({ skipped: "no ?noid= param" });
|
||||||
|
|
||||||
const [
|
const [
|
||||||
fournisseurs,
|
fournisseurs,
|
||||||
articles,
|
articles,
|
||||||
mvt_dateDebut,
|
mvt_dateDebut,
|
||||||
// Nouveaux endpoints
|
|
||||||
mensuel_codein,
|
|
||||||
mensuel_noid,
|
mensuel_noid,
|
||||||
stock_periode,
|
|
||||||
referentiel,
|
referentiel,
|
||||||
mvt_types,
|
mensuel_forced,
|
||||||
|
referentiel_forced,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
probe(`${FF_API_BASE}/api/fournisseurs?limit=2`),
|
probe(`${FF_API_BASE}/api/fournisseurs?limit=2`),
|
||||||
probe(`${FF_API_BASE}/api/articles?codefou=${codefou}&limit=2`),
|
probe(`${FF_API_BASE}/api/articles?codefou=${codefou}&limit=2`),
|
||||||
probe(`${FF_API_BASE}/api/mouvements/articles?codefou=${codefou}&dateDebut=${dateDebut}&dateFin=${dateFin}&limit=2`),
|
probe(`${FF_API_BASE}/api/mouvements/articles?codefou=${codefou}&dateDebut=${dateDebut}&dateFin=${dateFin}&limit=2`),
|
||||||
// Test mensuel avec codein
|
// Test mensuel avec no_id auto-résolu
|
||||||
firstCodein
|
|
||||||
? probe(`${FF_API_BASE}/api/articles/${encodeURIComponent(firstCodein)}/mensuel?dateDebut=${dateDebut}&dateFin=${dateFin}`)
|
|
||||||
: Promise.resolve({ skipped: "no codein available" }),
|
|
||||||
// Test mensuel avec no_id (si dispo)
|
|
||||||
firstCodein
|
firstCodein
|
||||||
? (async () => {
|
? (async () => {
|
||||||
try {
|
try {
|
||||||
@@ -92,20 +95,13 @@ export async function GET(req: NextRequest) {
|
|||||||
return { skipped: "no no_id available" };
|
return { skipped: "no no_id available" };
|
||||||
})()
|
})()
|
||||||
: Promise.resolve({ skipped: "no article" }),
|
: Promise.resolve({ skipped: "no article" }),
|
||||||
// Test stock/periode
|
|
||||||
firstCodein
|
|
||||||
? probe(`${FF_API_BASE}/api/stock/article/${encodeURIComponent(firstCodein!)}/periode?dateDebut=${dateDebut}&dateFin=${dateFin}`)
|
|
||||||
: Promise.resolve({ skipped: "no codein available" }),
|
|
||||||
probe(`${FF_API_BASE}/api/mouvements/types`),
|
|
||||||
// Referentiel complet (nomenclature + gamme + stock + prix)
|
// Referentiel complet (nomenclature + gamme + stock + prix)
|
||||||
firstCodein
|
firstCodein
|
||||||
? (async () => {
|
? (async () => {
|
||||||
try {
|
try {
|
||||||
// Récupère le no_id de l'article
|
|
||||||
const res = await fetch(`${FF_API_BASE}/api/articles?codefou=${codefou}&limit=5`, { cache: "no-store" });
|
const res = await fetch(`${FF_API_BASE}/api/articles?codefou=${codefou}&limit=5`, { cache: "no-store" });
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
const list = Array.isArray(data) ? data : (Object.values(data).find(v => Array.isArray(v)) as unknown[] ?? []);
|
const list = Array.isArray(data) ? data : (Object.values(data).find(v => Array.isArray(v)) as unknown[] ?? []);
|
||||||
// Prend le 5e article pour avoir plus de chances d'avoir des données
|
|
||||||
const art = (list[4] ?? list[0]) as Record<string, unknown> | undefined;
|
const art = (list[4] ?? list[0]) as Record<string, unknown> | undefined;
|
||||||
const noId = art?.no_id as string ?? null;
|
const noId = art?.no_id as string ?? null;
|
||||||
if (noId) return probe(`${FF_API_BASE}/api/articles/${encodeURIComponent(noId)}/referentiel`);
|
if (noId) return probe(`${FF_API_BASE}/api/articles/${encodeURIComponent(noId)}/referentiel`);
|
||||||
@@ -113,6 +109,8 @@ export async function GET(req: NextRequest) {
|
|||||||
return { skipped: "no no_id" };
|
return { skipped: "no no_id" };
|
||||||
})()
|
})()
|
||||||
: Promise.resolve({ skipped: "no codefou" }),
|
: Promise.resolve({ skipped: "no codefou" }),
|
||||||
|
mensuelNoidForced,
|
||||||
|
referentielNoidForced,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Test PostgreSQL + diagnostic ventesProduits
|
// Test PostgreSQL + diagnostic ventesProduits
|
||||||
@@ -158,16 +156,18 @@ export async function GET(req: NextRequest) {
|
|||||||
dateRange: { dateDebut, dateFin },
|
dateRange: { dateDebut, dateFin },
|
||||||
codefouTested: codefou,
|
codefouTested: codefou,
|
||||||
firstCodeinTested: firstCodein,
|
firstCodeinTested: firstCodein,
|
||||||
|
forcedNoid: forcedNoid ?? "(none — pass ?noid=129632 to test a specific article)",
|
||||||
fournisseurs,
|
fournisseurs,
|
||||||
articles,
|
articles,
|
||||||
mouvements_dateDebut: mvt_dateDebut,
|
mouvements_dateDebut: mvt_dateDebut,
|
||||||
nouveaux_endpoints: {
|
endpoints_auto: {
|
||||||
"articles/:codein/mensuel": mensuel_codein,
|
|
||||||
"articles/:no_id/mensuel": mensuel_noid,
|
"articles/:no_id/mensuel": mensuel_noid,
|
||||||
"stock/article/:codein/periode": stock_periode,
|
|
||||||
"mouvements/types": mvt_types,
|
|
||||||
"articles/:no_id/referentiel": referentiel,
|
"articles/:no_id/referentiel": referentiel,
|
||||||
},
|
},
|
||||||
|
endpoints_forced_noid: {
|
||||||
|
"articles/:noid/mensuel": mensuel_forced,
|
||||||
|
"articles/:noid/referentiel": referentiel_forced,
|
||||||
|
},
|
||||||
postgresql,
|
postgresql,
|
||||||
ventesProduitsDiag,
|
ventesProduitsDiag,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,6 +82,13 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
|
|||||||
// ─── Phase 5 : Agréger données mensuelles → sales12m + stock12m ──────
|
// ─── Phase 5 : Agréger données mensuelles → sales12m + stock12m ──────
|
||||||
const filterSite = magasin !== "TOTAL" ? magasin : null;
|
const filterSite = magasin !== "TOTAL" ? magasin : null;
|
||||||
|
|
||||||
|
// Log des sites distincts reçus (premier article avec données — diagnostic)
|
||||||
|
const firstEntries = mensuelMap.values().next().value as import("@/lib/api-ff-client").FfMensuelEntry[] | undefined;
|
||||||
|
if (firstEntries) {
|
||||||
|
const distinctSites = [...new Set(firstEntries.map(e => e.site))];
|
||||||
|
console.log(`[getProductRows] Sites distincts dans mensuel: ${JSON.stringify(distinctSites)}`);
|
||||||
|
}
|
||||||
|
|
||||||
for (const [codein, entries] of mensuelMap.entries()) {
|
for (const [codein, entries] of mensuelMap.entries()) {
|
||||||
const product = productMap.get(codein);
|
const product = productMap.get(codein);
|
||||||
if (!product) continue;
|
if (!product) continue;
|
||||||
@@ -91,7 +98,12 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
|
|||||||
const storeMonths = new Map<string, Set<string>>(); // site → Set<YYYYMM>
|
const storeMonths = new Map<string, Set<string>>(); // site → Set<YYYYMM>
|
||||||
|
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (filterSite && entry.site !== filterSite) continue;
|
// Garder uniquement les sites physiques (292, 579) — exclure la centrale (agrégat)
|
||||||
|
if (filterSite) {
|
||||||
|
if (entry.site !== filterSite) continue;
|
||||||
|
} else {
|
||||||
|
if (entry.site !== "292" && entry.site !== "579") continue;
|
||||||
|
}
|
||||||
|
|
||||||
const periode = entry.mois.replace("-", ""); // "2026-02" → "202602"
|
const periode = entry.mois.replace("-", ""); // "2026-02" → "202602"
|
||||||
if (!allowedPeriods.has(periode)) continue;
|
if (!allowedPeriods.has(periode)) continue;
|
||||||
|
|||||||
Reference in new issue
Block a user