mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-11 17:26:32 +02:00
feat: implement FF Nancy API client including data models and functions for suppliers, articles, movements, and stock.
This commit is contained in:
1 parent
7b209292b9
commit
c056750ea7
2 files changed
+136
-71
No files matched your search
+55
-59
@@ -1,69 +1,65 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { db } from "@/db";
|
||||
import { ventesProduits } from "@/db/schema";
|
||||
import { sql, eq } from "drizzle-orm";
|
||||
import { sql } from "drizzle-orm";
|
||||
|
||||
const FF_API_BASE = process.env.FF_API_BASE_URL ?? "https://api.ffnancy.fr";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const codeFournisseur = searchParams.get("fournisseur");
|
||||
const target = searchParams.get("target") ?? "all";
|
||||
|
||||
if (!codeFournisseur) {
|
||||
return NextResponse.json({
|
||||
error: "Paramètre 'fournisseur' manquant.",
|
||||
usage: "/api/diag?fournisseur=VOTRE_CODE"
|
||||
}, { status: 400 });
|
||||
const result: Record<string, unknown> = {
|
||||
timestamp: new Date().toISOString(),
|
||||
env: {
|
||||
FF_API_BASE_URL: process.env.FF_API_BASE_URL ?? "(not set — using default)",
|
||||
FF_API_BASE_resolved: FF_API_BASE,
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
},
|
||||
};
|
||||
|
||||
// ── Test FF Nancy API ────────────────────────────────────────────────────
|
||||
if (target === "all" || target === "ff") {
|
||||
const ffTests: Record<string, unknown> = {};
|
||||
|
||||
// Test fournisseurs
|
||||
try {
|
||||
const url = `${FF_API_BASE}/api/fournisseurs?limit=5`;
|
||||
const res = await fetch(url, { cache: "no-store" });
|
||||
const text = await res.text();
|
||||
let parsed: unknown = null;
|
||||
try { parsed = JSON.parse(text); } catch { parsed = text.slice(0, 500); }
|
||||
ffTests.fournisseurs = { status: res.status, url, raw: parsed };
|
||||
} catch (e) {
|
||||
ffTests.fournisseurs = { error: String(e) };
|
||||
}
|
||||
|
||||
// Test articles (avec un code fournisseur de test)
|
||||
const codefou = searchParams.get("codefou");
|
||||
if (codefou) {
|
||||
try {
|
||||
const url = `${FF_API_BASE}/api/articles?codefou=${codefou}&limit=3`;
|
||||
const res = await fetch(url, { cache: "no-store" });
|
||||
const text = await res.text();
|
||||
let parsed: unknown = null;
|
||||
try { parsed = JSON.parse(text); } catch { parsed = text.slice(0, 500); }
|
||||
ffTests.articles = { status: res.status, url, raw: parsed };
|
||||
} catch (e) {
|
||||
ffTests.articles = { error: String(e) };
|
||||
}
|
||||
}
|
||||
|
||||
result.ffNancyApi = ffTests;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`\n--- [DIAG API] Starting check for supplier: ${codeFournisseur} ---`);
|
||||
|
||||
// 1. Raw Count
|
||||
const countAll = await db.execute(sql`
|
||||
SELECT COUNT(*) as count FROM ventes_produits
|
||||
WHERE code_fournisseur = ${codeFournisseur}
|
||||
`);
|
||||
const totalRows = Number(countAll.rows[0].count);
|
||||
|
||||
// 2. Distinct Products
|
||||
const countDistinctTotal = await db.execute(sql`
|
||||
SELECT COUNT(DISTINCT codein) as count FROM ventes_produits
|
||||
WHERE code_fournisseur = ${codeFournisseur}
|
||||
`);
|
||||
const totalDistinct = Number(countDistinctTotal.rows[0].count);
|
||||
|
||||
// 3. Sample of data (to see if it's truncated by DB query)
|
||||
const sample = await db.execute(sql`
|
||||
SELECT codein, libelle1, magasin, periode FROM ventes_produits
|
||||
WHERE code_fournisseur = ${codeFournisseur}
|
||||
LIMIT 5
|
||||
`);
|
||||
|
||||
console.log(`- DB sees ${totalRows} total rows.`);
|
||||
console.log(`- DB sees ${totalDistinct} distinct products.`);
|
||||
|
||||
return NextResponse.json({
|
||||
timestamp: new Date().toISOString(),
|
||||
supplier: codeFournisseur,
|
||||
database: {
|
||||
totalRowsInTable: totalRows,
|
||||
distinctProducts: totalDistinct,
|
||||
sampleData: sample.rows
|
||||
},
|
||||
serverConfig: {
|
||||
nextVersion: "16.1.6",
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
bodySizeLimit: "50mb"
|
||||
},
|
||||
message: totalDistinct > 1000
|
||||
? "La base de données contient plus de 1000 produits. Si la grille en affiche 999, le problème est dans le transport (Application/RSC)."
|
||||
: "La base de données renvoie moins de 1000 produits uniques. Le problème vient de l'import ou du filtrage SQL."
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
console.error("[DIAG API] Error:", error);
|
||||
return NextResponse.json({
|
||||
error: "Failed to fetch diagnostic data",
|
||||
details: error.message
|
||||
}, { status: 500 });
|
||||
// ── Test PostgreSQL ──────────────────────────────────────────────────────
|
||||
if (target === "all" || target === "db") {
|
||||
try {
|
||||
const countResult = await db.execute(sql`SELECT COUNT(*) as count FROM session_snapshots`);
|
||||
result.postgresql = { ok: true, snapshots: Number(countResult.rows[0]?.count ?? 0) };
|
||||
} catch (e) {
|
||||
result.postgresql = { ok: false, error: String(e) };
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(result, { status: 200 });
|
||||
}
|
||||
Reference in new issue
Block a user