feat: implement product grid data fetching with schema self-healing and add a database verification script.

This commit is contained in:
Michael committed 2026-03-10 13:53:33 +01:00
1 parent 08d361e980
commit 1b09994087
5 files changed
+133 -1

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@ const nextConfig = {
serverExternalPackages: ["pg"],
experimental: {
serverActions: {
bodySizeLimit: "10mb",
bodySizeLimit: "50mb",
},
},
typescript: {
+48
View File
@@ -0,0 +1,48 @@
const { Pool } = require('pg');
const fs = require('fs');
const path = require('path');
async function main() {
console.log("--- DB DIAGNOSIS Start (Node) ---");
let connectionString = process.env.DATABASE_URL;
try {
const CONFIG_PATH = path.join(process.cwd(), "data", ".db-config.json");
if (fs.existsSync(CONFIG_PATH)) {
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
if (config.url) {
connectionString = config.url;
}
}
} catch (err) {}
if (!connectionString) {
console.error("No connection string found.");
return;
}
const pool = new Pool({ connectionString });
try {
const res = await pool.query(`
SELECT
code_fournisseur,
nom_fournisseur,
COUNT(*) as total_rows,
COUNT(DISTINCT codein) as distinct_products
FROM ventes_produits
GROUP BY code_fournisseur, nom_fournisseur
ORDER BY total_rows DESC
`);
console.table(res.rows);
} catch (error) {
console.error("Diagnosis failed:", error);
} finally {
await pool.end();
}
}
main();
+27
View File
@@ -0,0 +1,27 @@
import { db } from "@/db";
import { ventesProduits } from "@/db/schema";
import { sql } from "drizzle-orm";
async function main() {
console.log("--- DB DIAGNOSIS Start ---");
try {
const results = await db.execute(sql`
SELECT
code_fournisseur,
nom_fournisseur,
COUNT(*) as total_rows,
COUNT(DISTINCT codein) as distinct_products
FROM ventes_produits
GROUP BY code_fournisseur, nom_fournisseur
ORDER BY total_rows DESC
`);
console.table(results.rows);
} catch (error) {
console.error("Diagnosis failed:", error);
}
console.log("--- DB DIAGNOSIS End ---");
}
main();
+20
View File
@@ -5,6 +5,8 @@ import { ventesProduits } from "@/db/schema";
import { eq, and, ne, like, sql } from "drizzle-orm";
import type { ProductRow, GammeCode, GridFilters } from "@/types/grid";
import { computeProductScores } from "@/lib/score-engine";
import fs from "fs";
import path from "path";
let isSchemaInitialized = false;
@@ -70,6 +72,21 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
// Group by codein and aggregate monthly sales + track store participation
const productMap = new Map<string, ProductRow>();
// DEBUG: Log counts
console.log(`\n--- [getProductRows] DIAGNOSTIC for Supplier ${codeFournisseur} ---`);
const rawCount = await db.execute(sql`
SELECT COUNT(DISTINCT codein) as count FROM ventes_produits
WHERE code_fournisseur = ${codeFournisseur}
`);
console.log(`- TOTAL DISTINCT codein for this supplier in DB (unfiltered): ${rawCount.rows[0].count}`);
console.log(`- DB Rows retrieved for current filters: ${rows.length}`);
// Count distinct products in the DB results
const distinctInDb = new Set(rows.map(r => r.codein)).size;
console.log(`- Distinct Products in DB results: ${distinctInDb}`);
const storeParticipationMap = new Map<string, Map<string, Set<string>>>(); // codein -> magasin -> Set of periods
for (const row of rows) {
@@ -164,6 +181,9 @@ export async function getProductRows(input: GetProductRowsInput): Promise<Produc
}
}
// DEBUG: Log final product count
console.log(`- Final ProductMap Size: ${productMap.size}`);
return computeProductScores(Array.from(productMap.values()));
} catch (error) {
console.error(`[getProductRows] Error for supplier ${codeFournisseur}:`, error);
+37
View File
@@ -0,0 +1,37 @@
const { Pool } = require('pg');
const fs = require('fs');
const path = require('path');
const CONFIG_PATH = path.join(process.cwd(), "data", ".db-config.json");
let url = "";
if (fs.existsSync(CONFIG_PATH)) {
url = JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8")).url;
}
if (!url) url = process.env.DATABASE_URL;
const pool = new Pool({ connectionString: url });
async function check() {
try {
console.log("Checking DB URL:", url.replace(/:([^@]+)@/, ":****@"));
const resTotal = await pool.query('SELECT COUNT(*) FROM ventes_produits');
console.log("Total rows in table:", resTotal.rows[0].count);
const resSuppliers = await pool.query('SELECT code_fournisseur, COUNT(*) as count FROM ventes_produits GROUP BY code_fournisseur ORDER BY count DESC LIMIT 10');
console.log("Top suppliers by row count:", resSuppliers.rows);
// Check for specific supplier in user screenshot (if any, but I'll check all)
for (const s of resSuppliers.rows) {
const resDistinct = await pool.query('SELECT COUNT(DISTINCT codein) FROM ventes_produits WHERE code_fournisseur = $1', [s.code_fournisseur]);
console.log(`Supplier ${s.code_fournisseur}: Distinct Products = ${resDistinct.rows[0].count}`);
}
} catch (e) {
console.error("DB Error:", e);
} finally {
await pool.end();
}
}
check();