Add diagnostic tools to view database schema and logs

Integrate a new database debug page for administrators to view database schema, table counts, and relationships, accessible via a new route and sidebar item.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: b163d4c0-de5e-4f4e-a9c0-aed4c7049718
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/b163d4c0-de5e-4f4e-a9c0-aed4c7049718/xTmsprA
This commit is contained in:
michaelschal committed 2025-08-12 08:03:34 +00:00
1 parent fb9bb34702
commit 4ee0fdd206
4 files changed
+170 -4

No files matched your search

@@ -13,6 +13,7 @@ import BLReconciliation from "@/pages/BLReconciliation";
import Publicities from "@/pages/Publicities";
import NocoDBConfig from "@/pages/NocoDBConfig";
import DatabaseDebug from "@/pages/DatabaseDebug";
import CustomerOrders from "@/pages/CustomerOrders";
import DlcPage from "@/pages/DlcPage";
@@ -77,6 +78,7 @@ function RouterProduction() {
<Route path="/dlc" component={DlcPage} />
<Route path="/tasks" component={Tasks} />
<Route path="/nocodb-config" component={NocoDBConfig} />
<Route path="/database-debug" component={DatabaseDebug} />
<Route path="/" component={Dashboard} />
<Route component={NotFound} />
</Switch>
+6
View File
@@ -149,6 +149,12 @@ export default function Sidebar() {
icon: Database,
roles: ["admin"]
},
{
path: "/database-debug",
label: "Debug Base de Données",
icon: Database,
roles: ["admin"]
},
];
const hasPermission = (roles: string[]) => {
+158
View File
@@ -0,0 +1,158 @@
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Database, Eye, Loader2 } from "lucide-react";
import { useAuthSimple } from "@/hooks/useAuthSimple";
export default function DatabaseDebug() {
const { user } = useAuthSimple();
const [isLoading, setIsLoading] = useState(false);
const [result, setResult] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
const handleLogSchema = async () => {
setIsLoading(true);
setError(null);
setResult(null);
try {
const response = await fetch('/api/debug/log-schema', {
method: 'GET',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
});
const data = await response.json();
if (response.ok) {
setResult(data);
} else {
setError(data.message || data.error || 'Erreur inconnue');
}
} catch (err) {
setError('Erreur de connexion au serveur');
} finally {
setIsLoading(false);
}
};
if (!user || user.role !== 'admin') {
return (
<div className="p-6">
<Card>
<CardContent className="pt-6">
<p className="text-center text-gray-500">
Accès refusé. Seuls les administrateurs peuvent accéder à cette page.
</p>
</CardContent>
</Card>
</div>
);
}
return (
<div className="p-6 space-y-6">
<div className="flex items-center space-x-3">
<Database className="h-8 w-8 text-blue-600" />
<div>
<h1 className="text-2xl font-bold text-gray-900">Debug Base de Données</h1>
<p className="text-gray-600">Outils de diagnostic pour la base de données de production</p>
</div>
</div>
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<Eye className="h-5 w-5" />
<span>Scanner le Schéma de la Base</span>
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-gray-600">
Cette action va scanner votre base de données de production et logger toutes les tables,
colonnes et relations dans les logs du serveur.
</p>
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
<p className="text-yellow-800 text-sm">
⚠️ <strong>Note importante :</strong> Cette fonctionnalité ne marche qu'en production
sur votre serveur privé. Les résultats apparaîtront dans les logs de votre serveur.
</p>
</div>
<Button
onClick={handleLogSchema}
disabled={isLoading}
className="w-full"
>
{isLoading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Scan en cours...
</>
) : (
<>
<Database className="mr-2 h-4 w-4" />
Démarrer le Scan du Schéma
</>
)}
</Button>
{error && (
<div className="bg-red-50 border border-red-200 rounded-lg p-4">
<p className="text-red-800 text-sm">
<strong>Erreur :</strong> {error}
</p>
</div>
)}
{result && (
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
<h3 className="font-semibold text-green-800 mb-2">✅ Scan terminé avec succès</h3>
<div className="text-green-700 text-sm space-y-1">
<p><strong>Tables trouvées :</strong> {result.totalTables}</p>
<p><strong>Relations FK :</strong> {result.totalForeignKeys}</p>
<p><strong>Timestamp :</strong> {new Date(result.timestamp).toLocaleString('fr-FR')}</p>
<p className="mt-2 font-medium">
📋 Consultez maintenant les logs de votre serveur pour voir le détail complet du schéma.
</p>
</div>
</div>
)}
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Instructions</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="space-y-2">
<h4 className="font-medium">1. Cliquer sur "Démarrer le Scan du Schéma"</h4>
<p className="text-sm text-gray-600">Cette action va déclencher le scan de votre base de données.</p>
</div>
<div className="space-y-2">
<h4 className="font-medium">2. Consulter les logs du serveur</h4>
<p className="text-sm text-gray-600">
Les résultats apparaîtront dans les logs de votre application Node.js sur votre serveur privé.
Cherchez les lignes qui commencent par "🔍 ===== DÉBUT SCAN SCHÉMA BASE DE DONNÉES =====".
</p>
</div>
<div className="space-y-2">
<h4 className="font-medium">3. Informations récupérées</h4>
<ul className="text-sm text-gray-600 space-y-1 ml-4">
<li>• Liste complète des tables</li>
<li>• Colonnes avec types de données et contraintes</li>
<li>• Nombre d'enregistrements par table</li>
<li>• Relations de clés étrangères</li>
</ul>
</div>
</CardContent>
</Card>
</div>
);
}
+4 -4
View File
@@ -1413,7 +1413,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
ORDER BY table_name
`;
const tablesResult = await storage.db.query(tablesQuery);
const tablesResult = await (storage as any).db.query(tablesQuery);
console.log(`\n📊 TOTAL DES TABLES TROUVÉES: ${tablesResult.rows.length}`);
console.log('==========================================');
@@ -1439,7 +1439,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
ORDER BY ordinal_position
`;
const columnsResult = await storage.db.query(columnsQuery, [tableName]);
const columnsResult = await (storage as any).db.query(columnsQuery, [tableName]);
if (columnsResult.rows.length > 0) {
columnsResult.rows.forEach((col, index) => {
@@ -1453,7 +1453,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
// Compter les enregistrements dans la table
try {
const countQuery = `SELECT COUNT(*) as total FROM "${tableName}"`;
const countResult = await storage.db.query(countQuery);
const countResult = await (storage as any).db.query(countQuery);
console.log(` 📈 Nombre d'enregistrements: ${countResult.rows[0].total}`);
} catch (countError) {
console.log(` ⚠️ Impossible de compter les enregistrements: ${countError.message}`);
@@ -1484,7 +1484,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
ORDER BY tc.table_name, kcu.column_name
`;
const fkResult = await storage.db.query(fkQuery);
const fkResult = await (storage as any).db.query(fkQuery);
if (fkResult.rows.length > 0) {
fkResult.rows.forEach(fk => {