mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-21 22:18:17 +02:00
Add missing email column to suppliers to fix order and delivery errors
Adds the 'email' column to the 'suppliers' table via SQL script to resolve 500 errors on `/api/orders` and `/api/deliveries` caused by missing schema information required by Drizzle ORM. 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/FyjZ5oh
This commit is contained in:
1 parent
c79ac79a91
commit
c8a8b138e7
6 files changed
+605
No files matched your search
@@ -0,0 +1,26 @@
|
|||||||
|
-- CORRECTION URGENTE : Ajouter la colonne email manquante dans suppliers
|
||||||
|
-- Cette colonne est requise par le code Drizzle mais n'existe pas en production
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Ajouter la colonne email après phone
|
||||||
|
ALTER TABLE suppliers ADD COLUMN email character varying(255);
|
||||||
|
|
||||||
|
-- Mettre à jour la timestamp
|
||||||
|
UPDATE suppliers SET updated_at = CURRENT_TIMESTAMP;
|
||||||
|
|
||||||
|
-- Vérifier le résultat
|
||||||
|
SELECT
|
||||||
|
column_name,
|
||||||
|
data_type,
|
||||||
|
is_nullable,
|
||||||
|
column_default
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'suppliers'
|
||||||
|
AND table_schema = 'public'
|
||||||
|
ORDER BY ordinal_position;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- Message de confirmation
|
||||||
|
SELECT 'Colonne email ajoutée avec succès à la table suppliers' as status;
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# CORRECTION URGENTE PRODUCTION - Commandes et Livraisons
|
||||||
|
|
||||||
|
## Problème identifié
|
||||||
|
La colonne `email` manque dans la table `suppliers` en production, ce qui cause des erreurs 500 sur les API `/api/orders` et `/api/deliveries`.
|
||||||
|
|
||||||
|
## Erreurs constatées
|
||||||
|
```
|
||||||
|
Error fetching orders: error: column orders_supplier.email does not exist
|
||||||
|
Error fetching deliveries: error: column deliveries_supplier.email does not exist
|
||||||
|
```
|
||||||
|
|
||||||
|
## Solution immédiate
|
||||||
|
|
||||||
|
### 1. Exécuter le script SQL
|
||||||
|
Connectez-vous à votre base de données de production et exécutez :
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Ajouter la colonne email manquante
|
||||||
|
ALTER TABLE suppliers ADD COLUMN email character varying(255);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Vérification
|
||||||
|
Après exécution, vérifiez que la colonne a été ajoutée :
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT column_name, data_type, is_nullable
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'suppliers'
|
||||||
|
AND table_schema = 'public'
|
||||||
|
ORDER BY ordinal_position;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Redémarrer l'application
|
||||||
|
Une fois la colonne ajoutée, redémarrez votre application Node.js.
|
||||||
|
|
||||||
|
## Colonnes attendues vs réelles
|
||||||
|
|
||||||
|
### Actuellement en production (8 colonnes)
|
||||||
|
1. id
|
||||||
|
2. name
|
||||||
|
3. contact
|
||||||
|
4. phone
|
||||||
|
5. has_dlc
|
||||||
|
6. created_at
|
||||||
|
7. updated_at
|
||||||
|
8. automatic_reconciliation
|
||||||
|
|
||||||
|
### Attendu par le code Drizzle (9 colonnes)
|
||||||
|
1. id
|
||||||
|
2. name
|
||||||
|
3. contact
|
||||||
|
4. phone
|
||||||
|
5. **email** ← MANQUANTE
|
||||||
|
6. address
|
||||||
|
7. has_dlc
|
||||||
|
8. automatic_reconciliation
|
||||||
|
9. created_at
|
||||||
|
10. updated_at
|
||||||
|
|
||||||
|
## Diagnostic complet
|
||||||
|
- 40 fournisseurs en base
|
||||||
|
- Relations Drizzle tentent d'accéder à supplier.email
|
||||||
|
- Colonne n'existe pas → erreur SQL → erreur 500
|
||||||
|
|
||||||
|
## Test après correction
|
||||||
|
Les pages Orders et Deliveries devraient fonctionner normalement une fois la colonne ajoutée.
|
||||||
+200
@@ -0,0 +1,200 @@
|
|||||||
|
GET /api/deliveries 500 in 24ms
|
||||||
|
|
||||||
|
GET /api/orders 500 in 27ms
|
||||||
|
|
||||||
|
🔍 getUserWithGroups called for user: admin_local
|
||||||
|
|
||||||
|
🔍 getUserWithGroups called for user: admin_local
|
||||||
|
|
||||||
|
🔍 Querying user_groups for user: admin_local
|
||||||
|
|
||||||
|
🔍 Found 0 group assignments for user admin_local
|
||||||
|
|
||||||
|
🔍 Raw query result: []
|
||||||
|
|
||||||
|
✅ Processed 0 groups for user admin_local
|
||||||
|
|
||||||
|
🔍 getUserWithGroups called for user: admin_local
|
||||||
|
|
||||||
|
🔍 Querying user_groups for user: admin_local
|
||||||
|
|
||||||
|
🔍 Found 0 group assignments for user admin_local
|
||||||
|
|
||||||
|
🔍 Raw query result: []
|
||||||
|
|
||||||
|
✅ Processed 0 groups for user admin_local
|
||||||
|
|
||||||
|
🔍 getUserWithGroups called for user: admin_local
|
||||||
|
|
||||||
|
🔍 Querying user_groups for user: admin_local
|
||||||
|
|
||||||
|
🔍 Found 0 group assignments for user admin_local
|
||||||
|
|
||||||
|
🔍 Raw query result: []
|
||||||
|
|
||||||
|
✅ Processed 0 groups for user admin_local
|
||||||
|
|
||||||
|
Orders API called with: {
|
||||||
|
|
||||||
|
startDate: '2025-08-01',
|
||||||
|
|
||||||
|
endDate: '2025-08-31',
|
||||||
|
|
||||||
|
storeId: undefined,
|
||||||
|
|
||||||
|
userRole: 'admin'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Admin filtering with groupIds: undefined
|
||||||
|
|
||||||
|
Fetching orders by date range: 2025-08-01 to 2025-08-31
|
||||||
|
|
||||||
|
Error fetching orders: error: column orders_supplier.email does not exist
|
||||||
|
|
||||||
|
at /app/node_modules/pg-pool/index.js:45:11
|
||||||
|
|
||||||
|
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||||
|
|
||||||
|
at async file:///app/node_modules/drizzle-orm/node-postgres/session.js:83:22
|
||||||
|
|
||||||
|
at async DatabaseStorage.getOrdersByDateRange (file:///app/dist/index.js:1127:16)
|
||||||
|
|
||||||
|
at async file:///app/dist/index.js:3633:21 {
|
||||||
|
|
||||||
|
length: 120,
|
||||||
|
|
||||||
|
severity: 'ERROR',
|
||||||
|
|
||||||
|
code: '42703',
|
||||||
|
|
||||||
|
detail: undefined,
|
||||||
|
|
||||||
|
hint: undefined,
|
||||||
|
|
||||||
|
position: '555',
|
||||||
|
|
||||||
|
internalPosition: undefined,
|
||||||
|
|
||||||
|
internalQuery: undefined,
|
||||||
|
|
||||||
|
where: undefined,
|
||||||
|
|
||||||
|
schema: undefined,
|
||||||
|
|
||||||
|
table: undefined,
|
||||||
|
|
||||||
|
column: undefined,
|
||||||
|
|
||||||
|
dataType: undefined,
|
||||||
|
|
||||||
|
constraint: undefined,
|
||||||
|
|
||||||
|
file: 'parse_relation.c',
|
||||||
|
|
||||||
|
line: '3665',
|
||||||
|
|
||||||
|
routine: 'errorMissingColumn'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GET /api/orders 500 in 13ms
|
||||||
|
|
||||||
|
🔍 Querying user_groups for user: admin_local
|
||||||
|
|
||||||
|
🔍 Found 0 group assignments for user admin_local
|
||||||
|
|
||||||
|
🔍 Raw query result: []
|
||||||
|
|
||||||
|
✅ Processed 0 groups for user admin_local
|
||||||
|
|
||||||
|
🔍 getUserWithGroups called for user: admin_local
|
||||||
|
|
||||||
|
🔍 Querying user_groups for user: admin_local
|
||||||
|
|
||||||
|
🔍 Found 0 group assignments for user admin_local
|
||||||
|
|
||||||
|
🔍 Raw query result: []
|
||||||
|
|
||||||
|
✅ Processed 0 groups for user admin_local
|
||||||
|
|
||||||
|
🔍 getUserWithGroups called for user: admin_local
|
||||||
|
|
||||||
|
🔍 Querying user_groups for user: admin_local
|
||||||
|
|
||||||
|
🔍 Found 0 group assignments for user admin_local
|
||||||
|
|
||||||
|
🔍 Raw query result: []
|
||||||
|
|
||||||
|
✅ Processed 0 groups for user admin_local
|
||||||
|
|
||||||
|
Deliveries API called with: {
|
||||||
|
|
||||||
|
startDate: '2025-08-01',
|
||||||
|
|
||||||
|
endDate: '2025-08-31',
|
||||||
|
|
||||||
|
storeId: undefined,
|
||||||
|
|
||||||
|
withBL: undefined,
|
||||||
|
|
||||||
|
userRole: 'admin'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Admin filtering deliveries with groupIds: undefined
|
||||||
|
|
||||||
|
Fetching deliveries by date range: 2025-08-01 to 2025-08-31
|
||||||
|
|
||||||
|
Error fetching deliveries: error: column deliveries_supplier.email does not exist
|
||||||
|
|
||||||
|
at /app/node_modules/pg-pool/index.js:45:11
|
||||||
|
|
||||||
|
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||||
|
|
||||||
|
at async file:///app/node_modules/drizzle-orm/node-postgres/session.js:83:22
|
||||||
|
|
||||||
|
at async DatabaseStorage.getDeliveriesByDateRange (file:///app/dist/index.js:1186:25)
|
||||||
|
|
||||||
|
at async file:///app/dist/index.js:3848:25 {
|
||||||
|
|
||||||
|
length: 124,
|
||||||
|
|
||||||
|
severity: 'ERROR',
|
||||||
|
|
||||||
|
code: '42703',
|
||||||
|
|
||||||
|
detail: undefined,
|
||||||
|
|
||||||
|
hint: undefined,
|
||||||
|
|
||||||
|
position: '856',
|
||||||
|
|
||||||
|
internalPosition: undefined,
|
||||||
|
|
||||||
|
internalQuery: undefined,
|
||||||
|
|
||||||
|
where: undefined,
|
||||||
|
|
||||||
|
schema: undefined,
|
||||||
|
|
||||||
|
table: undefined,
|
||||||
|
|
||||||
|
column: undefined,
|
||||||
|
|
||||||
|
dataType: undefined,
|
||||||
|
|
||||||
|
constraint: undefined,
|
||||||
|
|
||||||
|
file: 'parse_relation.c',
|
||||||
|
|
||||||
|
line: '3665',
|
||||||
|
|
||||||
|
routine: 'errorMissingColumn'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GET /api/deliveries 500 in 42ms
|
||||||
|
|
||||||
|
HEAD /api/health 200 in 1ms
|
||||||
|
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script de debug pour vérifier le schéma de la table suppliers en production
|
||||||
|
* et corriger les colonnes manquantes si nécessaire
|
||||||
|
*/
|
||||||
|
|
||||||
|
import pg from 'pg';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
const { Pool } = pg;
|
||||||
|
|
||||||
|
// Configuration de la base de données de production
|
||||||
|
const pool = new Pool({
|
||||||
|
connectionString: process.env.DATABASE_URL,
|
||||||
|
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
|
||||||
|
});
|
||||||
|
|
||||||
|
async function checkSuppliersSchema() {
|
||||||
|
console.log('🔍 Vérification du schéma de la table suppliers en production...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Vérifier les colonnes existantes
|
||||||
|
const result = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
column_name,
|
||||||
|
data_type,
|
||||||
|
is_nullable,
|
||||||
|
column_default
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'suppliers'
|
||||||
|
AND table_schema = 'public'
|
||||||
|
ORDER BY ordinal_position
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n📊 Colonnes actuelles dans la table suppliers:');
|
||||||
|
console.log('='.repeat(60));
|
||||||
|
|
||||||
|
const columns = result.rows;
|
||||||
|
columns.forEach((col, index) => {
|
||||||
|
const nullable = col.is_nullable === 'YES' ? 'NULL' : 'NOT NULL';
|
||||||
|
const defaultVal = col.column_default ? ` DEFAULT ${col.column_default}` : '';
|
||||||
|
console.log(`${index + 1:2}. ${col.column_name.padEnd(25)} : ${col.data_type} ${nullable}${defaultVal}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Vérifier les colonnes requises
|
||||||
|
const requiredColumns = ['email', 'automatic_reconciliation'];
|
||||||
|
const existingColumns = columns.map(col => col.column_name);
|
||||||
|
const missingColumns = requiredColumns.filter(col => !existingColumns.includes(col));
|
||||||
|
|
||||||
|
if (missingColumns.length > 0) {
|
||||||
|
console.log(`\n❌ Colonnes manquantes: ${missingColumns.join(', ')}`);
|
||||||
|
console.log('\n📝 Script SQL généré pour corriger le problème:');
|
||||||
|
console.log('='.repeat(60));
|
||||||
|
|
||||||
|
let sqlScript = 'BEGIN;\n\n';
|
||||||
|
|
||||||
|
if (missingColumns.includes('email')) {
|
||||||
|
sqlScript += 'ALTER TABLE suppliers ADD COLUMN email VARCHAR;\n';
|
||||||
|
sqlScript += 'COMMENT ON COLUMN suppliers.email IS \'Email du fournisseur\';\n\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingColumns.includes('automatic_reconciliation')) {
|
||||||
|
sqlScript += 'ALTER TABLE suppliers ADD COLUMN automatic_reconciliation BOOLEAN DEFAULT false;\n';
|
||||||
|
sqlScript += 'COMMENT ON COLUMN suppliers.automatic_reconciliation IS \'Mode rapprochement automatique BL/Factures\';\n\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlScript += 'COMMIT;';
|
||||||
|
|
||||||
|
console.log(sqlScript);
|
||||||
|
|
||||||
|
// Sauvegarder le script
|
||||||
|
fs.writeFileSync('fix-suppliers-missing-columns.sql', sqlScript);
|
||||||
|
console.log('\n💾 Script sauvegardé dans: fix-suppliers-missing-columns.sql');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log('\n✅ Toutes les colonnes requises sont présentes');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compter les enregistrements
|
||||||
|
const countResult = await pool.query('SELECT COUNT(*) as total FROM suppliers');
|
||||||
|
console.log(`\n📈 Nombre de fournisseurs: ${countResult.rows[0].total}`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Erreur lors de la vérification:', error.message);
|
||||||
|
process.exit(1);
|
||||||
|
} finally {
|
||||||
|
await pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exécuter le script
|
||||||
|
checkSuppliersSchema()
|
||||||
|
.then(() => {
|
||||||
|
console.log('\n✅ Vérification terminée');
|
||||||
|
process.exit(0);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('❌ Erreur:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script de correction d'urgence pour résoudre les erreurs de colonnes manquantes
|
||||||
|
* qui empêchent l'affichage des commandes et livraisons en production
|
||||||
|
*/
|
||||||
|
|
||||||
|
import pg from 'pg';
|
||||||
|
|
||||||
|
const { Pool } = pg;
|
||||||
|
|
||||||
|
// Configuration de la base de données de production
|
||||||
|
const pool = new Pool({
|
||||||
|
connectionString: process.env.DATABASE_URL,
|
||||||
|
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fixProductionSchema() {
|
||||||
|
console.log('🚨 CORRECTION D\'URGENCE - Schéma de production pour commandes/livraisons');
|
||||||
|
console.log('='.repeat(70));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Vérifier et corriger la table suppliers
|
||||||
|
console.log('\n1️⃣ Vérification de la table suppliers...');
|
||||||
|
|
||||||
|
const suppliersColumns = await pool.query(`
|
||||||
|
SELECT column_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'suppliers'
|
||||||
|
AND table_schema = 'public'
|
||||||
|
`);
|
||||||
|
|
||||||
|
const existingSupplierColumns = suppliersColumns.rows.map(row => row.column_name);
|
||||||
|
console.log(' Colonnes existantes:', existingSupplierColumns.join(', '));
|
||||||
|
|
||||||
|
// Ajouter les colonnes manquantes pour suppliers
|
||||||
|
if (!existingSupplierColumns.includes('email')) {
|
||||||
|
console.log(' 🔧 Ajout de la colonne email...');
|
||||||
|
await pool.query('ALTER TABLE suppliers ADD COLUMN email VARCHAR');
|
||||||
|
console.log(' ✅ Colonne email ajoutée');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingSupplierColumns.includes('automatic_reconciliation')) {
|
||||||
|
console.log(' 🔧 Ajout de la colonne automatic_reconciliation...');
|
||||||
|
await pool.query('ALTER TABLE suppliers ADD COLUMN automatic_reconciliation BOOLEAN DEFAULT false');
|
||||||
|
console.log(' ✅ Colonne automatic_reconciliation ajoutée');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Vérifier les relations et contraintes
|
||||||
|
console.log('\n2️⃣ Vérification des relations de clés étrangères...');
|
||||||
|
|
||||||
|
const foreignKeys = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
tc.table_name,
|
||||||
|
kcu.column_name,
|
||||||
|
ccu.table_name AS foreign_table_name,
|
||||||
|
ccu.column_name AS foreign_column_name
|
||||||
|
FROM information_schema.table_constraints AS tc
|
||||||
|
JOIN information_schema.key_column_usage AS kcu
|
||||||
|
ON tc.constraint_name = kcu.constraint_name
|
||||||
|
JOIN information_schema.constraint_column_usage AS ccu
|
||||||
|
ON ccu.constraint_name = tc.constraint_name
|
||||||
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||||||
|
AND tc.table_schema = 'public'
|
||||||
|
AND (tc.table_name = 'orders' OR tc.table_name = 'deliveries')
|
||||||
|
ORDER BY tc.table_name, kcu.column_name
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log(' Relations trouvées:');
|
||||||
|
foreignKeys.rows.forEach(fk => {
|
||||||
|
console.log(` - ${fk.table_name}.${fk.column_name} → ${fk.foreign_table_name}.${fk.foreign_column_name}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Test des requêtes problématiques
|
||||||
|
console.log('\n3️⃣ Test des requêtes de commandes et livraisons...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(' 🧪 Test requête orders avec relations...');
|
||||||
|
const testOrders = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
o.id,
|
||||||
|
o.planned_date,
|
||||||
|
o.status,
|
||||||
|
s.name as supplier_name,
|
||||||
|
g.name as group_name
|
||||||
|
FROM orders o
|
||||||
|
LEFT JOIN suppliers s ON o.supplier_id = s.id
|
||||||
|
LEFT JOIN groups g ON o.group_id = g.id
|
||||||
|
LIMIT 1
|
||||||
|
`);
|
||||||
|
console.log(` ✅ Test orders réussi (${testOrders.rows.length} résultat)`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(` ❌ Erreur test orders: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(' 🧪 Test requête deliveries avec relations...');
|
||||||
|
const testDeliveries = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
d.id,
|
||||||
|
d.scheduled_date,
|
||||||
|
d.status,
|
||||||
|
s.name as supplier_name,
|
||||||
|
g.name as group_name
|
||||||
|
FROM deliveries d
|
||||||
|
LEFT JOIN suppliers s ON d.supplier_id = s.id
|
||||||
|
LEFT JOIN groups g ON d.group_id = g.id
|
||||||
|
LIMIT 1
|
||||||
|
`);
|
||||||
|
console.log(` ✅ Test deliveries réussi (${testDeliveries.rows.length} résultat)`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(` ❌ Erreur test deliveries: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Statistiques finales
|
||||||
|
console.log('\n4️⃣ Statistiques des tables...');
|
||||||
|
|
||||||
|
const tablesStats = ['suppliers', 'orders', 'deliveries', 'groups'];
|
||||||
|
for (const table of tablesStats) {
|
||||||
|
try {
|
||||||
|
const countResult = await pool.query(`SELECT COUNT(*) as total FROM ${table}`);
|
||||||
|
console.log(` 📊 ${table}: ${countResult.rows[0].total} enregistrements`);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(` ❌ Erreur comptage ${table}: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n✅ CORRECTION TERMINÉE - Redémarrez votre application');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('\n❌ ERREUR CRITIQUE:', error.message);
|
||||||
|
console.error('Stack:', error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
} finally {
|
||||||
|
await pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier que nous sommes en production
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
console.error('❌ Ce script ne doit être exécuté qu\'en production');
|
||||||
|
console.error(' NODE_ENV =', process.env.NODE_ENV);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!process.env.DATABASE_URL) {
|
||||||
|
console.error('❌ DATABASE_URL manquante');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exécuter la correction
|
||||||
|
fixProductionSchema()
|
||||||
|
.then(() => {
|
||||||
|
console.log('\n🎉 Script de correction exécuté avec succès');
|
||||||
|
process.exit(0);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('\n💥 Échec du script de correction:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
-- Fix pour ajouter la colonne email manquante dans la table suppliers en production
|
||||||
|
-- Cette colonne est définie dans le schéma Drizzle mais n'existe pas en base
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Vérifier si la colonne email existe déjà
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
-- Essayer d'ajouter la colonne email si elle n'existe pas
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'suppliers'
|
||||||
|
AND column_name = 'email'
|
||||||
|
AND table_schema = 'public'
|
||||||
|
) THEN
|
||||||
|
ALTER TABLE suppliers ADD COLUMN email VARCHAR;
|
||||||
|
RAISE NOTICE 'Colonne email ajoutée à la table suppliers';
|
||||||
|
ELSE
|
||||||
|
RAISE NOTICE 'Colonne email existe déjà dans la table suppliers';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Vérifier si la colonne automatic_reconciliation existe déjà
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'suppliers'
|
||||||
|
AND column_name = 'automatic_reconciliation'
|
||||||
|
AND table_schema = 'public'
|
||||||
|
) THEN
|
||||||
|
ALTER TABLE suppliers ADD COLUMN automatic_reconciliation BOOLEAN DEFAULT false;
|
||||||
|
RAISE NOTICE 'Colonne automatic_reconciliation ajoutée à la table suppliers';
|
||||||
|
ELSE
|
||||||
|
RAISE NOTICE 'Colonne automatic_reconciliation existe déjà dans la table suppliers';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Vérifier l'état final des colonnes
|
||||||
|
SELECT
|
||||||
|
column_name,
|
||||||
|
data_type,
|
||||||
|
is_nullable,
|
||||||
|
column_default
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'suppliers'
|
||||||
|
AND table_schema = 'public'
|
||||||
|
ORDER BY ordinal_position;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
Reference in new issue
Block a user