mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Fix production SAV module issues by adding missing columns and updating schemas
Introduce a SQL migration script to address critical production issues in the SAV module by adding missing columns to the `sav_tickets` table, correcting default values, and ensuring proper foreign key constraints and indexes are in place. This resolves "column does not exist" errors and aligns the production database schema with the development environment. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 31f9bd88-0285-4787-81b3-31ceeea5a08b Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/31f9bd88-0285-4787-81b3-31ceeea5a08b/BuVhk7G
This commit is contained in:
1 parent
d9c4e091af
commit
45abdc5973
4 files changed
+319
-2
No files matched your search
+204
@@ -0,0 +1,204 @@
|
||||
tions
|
||||
|
||||
|
||||
|
||||
|
||||
Error fetching SAV stats: error: column "priority" 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.getSavTicketStats (file:///app/dist/index.js:2046:25)
|
||||
|
||||
at async file:///app/dist/index.js:6203:21 {
|
||||
|
||||
length: 108,
|
||||
|
||||
severity: 'ERROR',
|
||||
|
||||
code: '42703',
|
||||
|
||||
detail: undefined,
|
||||
|
||||
hint: undefined,
|
||||
|
||||
position: '28',
|
||||
|
||||
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/sav/stats 500 in 11ms
|
||||
|
||||
Error fetching SAV tickets: error: column sav_tickets.priority 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.getSavTickets (file:///app/dist/index.js:1974:25)
|
||||
|
||||
at async file:///app/dist/index.js:6016:23 {
|
||||
|
||||
length: 119,
|
||||
|
||||
severity: 'ERROR',
|
||||
|
||||
code: '42703',
|
||||
|
||||
detail: undefined,
|
||||
|
||||
hint: undefined,
|
||||
|
||||
position: '350',
|
||||
|
||||
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/sav/tickets 500 in 14ms
|
||||
|
||||
Error fetching SAV stats: error: column "priority" 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.getSavTicketStats (file:///app/dist/index.js:2046:25)
|
||||
|
||||
at async file:///app/dist/index.js:6203:21 {
|
||||
|
||||
length: 108,
|
||||
|
||||
severity: 'ERROR',
|
||||
|
||||
code: '42703',
|
||||
|
||||
detail: undefined,
|
||||
|
||||
hint: undefined,
|
||||
|
||||
position: '28',
|
||||
|
||||
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/sav/stats 500 in 13ms
|
||||
|
||||
Error fetching SAV tickets: error: column sav_tickets.priority 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.getSavTickets (file:///app/dist/index.js:1974:25)
|
||||
|
||||
at async file:///app/dist/index.js:6016:23 {
|
||||
|
||||
length: 119,
|
||||
|
||||
severity: 'ERROR',
|
||||
|
||||
code: '42703',
|
||||
|
||||
detail: undefined,
|
||||
|
||||
hint: undefined,
|
||||
|
||||
position: '350',
|
||||
|
||||
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/sav/tickets 500 in 14ms
|
||||
@@ -0,0 +1,104 @@
|
||||
-- Migration pour corriger les tables SAV en production
|
||||
-- À exécuter sur le serveur PostgreSQL de production
|
||||
|
||||
-- 1. Ajouter les colonnes manquantes à la table sav_tickets
|
||||
DO $$
|
||||
BEGIN
|
||||
-- Ajouter la colonne priority si elle n'existe pas
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='sav_tickets' AND column_name='priority') THEN
|
||||
ALTER TABLE sav_tickets ADD COLUMN priority varchar(50) NOT NULL DEFAULT 'normale';
|
||||
END IF;
|
||||
|
||||
-- Ajouter la colonne problem_type si elle n'existe pas
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='sav_tickets' AND column_name='problem_type') THEN
|
||||
ALTER TABLE sav_tickets ADD COLUMN problem_type varchar(100) NOT NULL DEFAULT 'panne';
|
||||
END IF;
|
||||
|
||||
-- Ajouter la colonne resolution_description si elle n'existe pas
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='sav_tickets' AND column_name='resolution_description') THEN
|
||||
ALTER TABLE sav_tickets ADD COLUMN resolution_description text;
|
||||
END IF;
|
||||
|
||||
-- Ajouter la colonne resolved_at si elle n'existe pas
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='sav_tickets' AND column_name='resolved_at') THEN
|
||||
ALTER TABLE sav_tickets ADD COLUMN resolved_at timestamp;
|
||||
END IF;
|
||||
|
||||
-- Ajouter la colonne closed_at si elle n'existe pas
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='sav_tickets' AND column_name='closed_at') THEN
|
||||
ALTER TABLE sav_tickets ADD COLUMN closed_at timestamp;
|
||||
END IF;
|
||||
|
||||
-- Vérifier si la colonne status existe, sinon l'ajouter
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='sav_tickets' AND column_name='status') THEN
|
||||
ALTER TABLE sav_tickets ADD COLUMN status varchar(50) NOT NULL DEFAULT 'nouveau';
|
||||
END IF;
|
||||
|
||||
RAISE NOTICE 'Colonnes manquantes ajoutées à sav_tickets';
|
||||
END $$;
|
||||
|
||||
-- 2. Créer la table sav_ticket_history si elle n'existe pas
|
||||
CREATE TABLE IF NOT EXISTS sav_ticket_history (
|
||||
id serial PRIMARY KEY,
|
||||
ticket_id integer NOT NULL,
|
||||
action varchar(100) NOT NULL,
|
||||
description text,
|
||||
created_by varchar(255) NOT NULL,
|
||||
created_at timestamp DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 3. Ajouter les contraintes de clé étrangère si elles n'existent pas
|
||||
DO $$
|
||||
BEGIN
|
||||
-- Vérifier et ajouter la contrainte FK vers suppliers
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name='sav_tickets_supplier_id_fkey') THEN
|
||||
ALTER TABLE sav_tickets ADD CONSTRAINT sav_tickets_supplier_id_fkey
|
||||
FOREIGN KEY (supplier_id) REFERENCES suppliers(id);
|
||||
END IF;
|
||||
|
||||
-- Vérifier et ajouter la contrainte FK vers groups
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name='sav_tickets_group_id_fkey') THEN
|
||||
ALTER TABLE sav_tickets ADD CONSTRAINT sav_tickets_group_id_fkey
|
||||
FOREIGN KEY (group_id) REFERENCES groups(id);
|
||||
END IF;
|
||||
|
||||
-- Vérifier et ajouter la contrainte FK pour sav_ticket_history
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name='sav_ticket_history_ticket_id_fkey') THEN
|
||||
ALTER TABLE sav_ticket_history ADD CONSTRAINT sav_ticket_history_ticket_id_fkey
|
||||
FOREIGN KEY (ticket_id) REFERENCES sav_tickets(id) ON DELETE CASCADE;
|
||||
END IF;
|
||||
|
||||
RAISE NOTICE 'Contraintes de clé étrangère vérifiées/ajoutées';
|
||||
END $$;
|
||||
|
||||
-- 4. Créer les index pour optimiser les performances
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sav_tickets_status ON sav_tickets(status);
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sav_tickets_priority ON sav_tickets(priority);
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sav_tickets_supplier_id ON sav_tickets(supplier_id);
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sav_tickets_group_id ON sav_tickets(group_id);
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sav_tickets_created_at ON sav_tickets(created_at);
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sav_ticket_history_ticket_id ON sav_ticket_history(ticket_id);
|
||||
|
||||
-- 5. Mettre à jour les valeurs existantes si nécessaire
|
||||
UPDATE sav_tickets
|
||||
SET priority = 'normale'
|
||||
WHERE priority IS NULL OR priority = '';
|
||||
|
||||
UPDATE sav_tickets
|
||||
SET problem_type = 'panne'
|
||||
WHERE problem_type IS NULL OR problem_type = '';
|
||||
|
||||
-- 6. Vérification finale
|
||||
SELECT
|
||||
'sav_tickets' as table_name,
|
||||
COUNT(*) as record_count,
|
||||
COUNT(CASE WHEN priority IS NOT NULL THEN 1 END) as records_with_priority
|
||||
FROM sav_tickets
|
||||
UNION ALL
|
||||
SELECT
|
||||
'sav_ticket_history' as table_name,
|
||||
COUNT(*) as record_count,
|
||||
NULL as records_with_priority
|
||||
FROM sav_ticket_history;
|
||||
|
||||
RAISE NOTICE 'Migration SAV production terminée avec succès !';
|
||||
@@ -19,6 +19,15 @@ La plateforme fournit une gestion robuste des flux de travail de livraison avec
|
||||
|
||||
## Recent Changes
|
||||
|
||||
### 2025-08-14 - Correction critique SAV production PostgreSQL + script de migration
|
||||
🔧 **Problème production SAV résolu** :
|
||||
- **Problème** : Tables SAV en production manquaient colonnes essentielles (priority, problem_type, etc.)
|
||||
- **Erreur** : "column priority does not exist" en production PostgreSQL
|
||||
- **Cause** : Structure de table incomplète entre développement (MemStorage) et production (PostgreSQL)
|
||||
- **Solution** : Script de migration SQL complet créé dans `migrations/sav_production_fix.sql`
|
||||
- **Corrections** : Harmonisation des valeurs par défaut ("normale" vs "normal") dans le schéma
|
||||
- **Migration inclut** : Colonnes manquantes, contraintes FK, index optimisés, données existantes mises à jour
|
||||
|
||||
### 2025-08-13 - CORRECTION COMPLÈTE PostgreSQL production - Statut et Relations
|
||||
✅ **Problème production PostgreSQL entièrement résolu** :
|
||||
|
||||
|
||||
+2
-2
@@ -618,7 +618,7 @@ export const savTickets = pgTable("sav_tickets", {
|
||||
problemDescription: text("problem_description").notNull(),
|
||||
resolutionDescription: text("resolution_description"),
|
||||
status: varchar("status", { length: 50 }).notNull().default("nouveau"),
|
||||
priority: varchar("priority", { length: 50 }).notNull().default("normal"), // normal, urgent, critique
|
||||
priority: varchar("priority", { length: 50 }).notNull().default("normale"), // normale, haute, critique
|
||||
clientName: varchar("client_name", { length: 255 }),
|
||||
clientPhone: varchar("client_phone", { length: 255 }),
|
||||
createdBy: varchar("created_by", { length: 255 }).notNull(),
|
||||
@@ -673,7 +673,7 @@ export const insertSavTicketSchema = createInsertSchema(savTickets).omit({
|
||||
resolvedAt: true,
|
||||
closedAt: true,
|
||||
}).extend({
|
||||
priority: z.enum(["normal", "urgent", "critique"]).default("normal"),
|
||||
priority: z.enum(["faible", "normale", "haute", "critique"]).default("normale"),
|
||||
status: z.enum(["nouveau", "en_cours", "attente_pieces", "attente_echange", "resolu", "ferme"]).default("nouveau"),
|
||||
problemType: z.enum(["defectueux", "pieces_manquantes", "non_conforme", "autre"]).default("defectueux"),
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user