diff --git a/.replit b/.replit index 2e1a3ae..853b5d3 100644 --- a/.replit +++ b/.replit @@ -37,4 +37,4 @@ args = "npm run dev" waitForPort = 5000 [agent] -integrations = ["javascript_object_storage==1.0.0", "javascript_database==1.0.0", "javascript_log_in_with_replit==1.0.0"] +integrations = ["javascript_database==1.0.0", "javascript_object_storage==1.0.0", "javascript_log_in_with_replit==1.0.0"] diff --git a/attached_assets/Pasted-LOGIFLOW-RAPPORT-SCH-MA-BASE-DE-DONN-ES-PRODUCTION--1756906995381_1756906995382.txt b/attached_assets/Pasted-LOGIFLOW-RAPPORT-SCH-MA-BASE-DE-DONN-ES-PRODUCTION--1756906995381_1756906995382.txt new file mode 100644 index 0000000..6cd3282 --- /dev/null +++ b/attached_assets/Pasted-LOGIFLOW-RAPPORT-SCH-MA-BASE-DE-DONN-ES-PRODUCTION--1756906995381_1756906995382.txt @@ -0,0 +1,589 @@ +LOGIFLOW - RAPPORT SCHÉMA BASE DE DONNÉES PRODUCTION +=============================================== + +GÉNÉRÉ LE : 2025-09-03T13:42:55.993Z +SERVEUR : Production privé LogiFlow +ENVIRONNEMENT : PostgreSQL Docker +UTILISATEUR : admin + +=============================================== +RÉSUMÉ DU SCAN +=============================================== + +TOTAL DES TABLES TROUVÉES: 34 +========================================== + +TABLE: CALENDAR_EVENTS +===================== + + 01. id : integer NOT NULL DEFAULT nextval('calendar_events_id_seq'::regclass) + 02. title : character varying(255) NOT NULL + 03. description : text NULL + 04. start_date : timestamp without time zone NOT NULL + 05. end_date : timestamp without time zone NOT NULL + 06. event_type : character varying(50) NULL DEFAULT 'custom'::character varying + 07. group_id : integer NULL + 08. created_by : character varying(255) NULL + 09. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 10. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: CLIENT_ORDERS +=================== + + 01. id : integer NOT NULL DEFAULT nextval('client_orders_id_seq'::regclass) + 02. order_number : character varying(255) NOT NULL + 03. client_name : character varying(255) NOT NULL + 04. client_contact : character varying(255) NULL + 05. product_description : text NOT NULL + 06. quantity : integer NOT NULL DEFAULT 1 + 07. unit_price : numeric NULL + 08. total_amount : numeric NULL + 09. status : character varying(50) NULL DEFAULT 'pending'::character varying + 10. delivery_date : date NULL + 11. notes : text NULL + 12. group_id : integer NULL + 13. created_by : character varying(255) NULL + 14. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 15. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: COMMAND_ITEMS +=================== + + 01. id : integer NOT NULL DEFAULT nextval('command_items_id_seq'::regclass) + 02. command_id : integer NULL + 03. product_name : character varying(255) NOT NULL + 04. product_reference : character varying(255) NULL + 05. quantity : integer NOT NULL + 06. unit_price : numeric NULL + 07. total_price : numeric NULL + 08. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: COMMANDS +============== + + 01. id : integer NOT NULL DEFAULT nextval('commands_id_seq'::regclass) + 02. command_number : character varying(255) NOT NULL + 03. supplier_id : integer NULL + 04. group_id : integer NULL + 05. command_date : date NOT NULL + 06. expected_delivery_date : date NULL + 07. status : character varying(50) NULL DEFAULT 'pending'::character varying + 08. total_amount : numeric NULL + 09. notes : text NULL + 10. created_by : character varying(255) NULL + 11. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 12. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: CUSTOMER_ORDERS +===================== + + 01. id : integer NOT NULL DEFAULT nextval('customer_orders_id_seq'::regclass) + 02. order_taker : character varying(255) NOT NULL + 03. customer_name : character varying(255) NOT NULL + 04. customer_phone : character varying(255) NULL + 05. customer_email : character varying(255) NULL + 06. product_designation : text NOT NULL + 07. product_reference : character varying(255) NULL + 08. gencode : character varying(255) NULL + 09. quantity : integer NULL DEFAULT 1 + 10. supplier_id : integer NULL + 11. status : character varying(100) NULL DEFAULT 'En attente de Commande'::character varying + 12. deposit : numeric NULL DEFAULT 0.00 + 13. is_promotional_price : boolean NULL DEFAULT false + 14. customer_notified : boolean NULL DEFAULT false + 15. notes : text NULL + 16. group_id : integer NULL + 17. created_by : character varying(255) NULL + 18. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 19. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 50 + +TABLE: CUSTOMERS +=============== + + 01. id : integer NOT NULL DEFAULT nextval('customers_id_seq'::regclass) + 02. name : character varying(255) NOT NULL + 03. contact_person : character varying(255) NULL + 04. phone : character varying(255) NULL + 05. email : character varying(255) NULL + 06. address : text NULL + 07. city : character varying(255) NULL + 08. postal_code : character varying(20) NULL + 09. notes : text NULL + 10. group_id : integer NULL + 11. created_by : character varying(255) NULL + 12. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 13. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: DASHBOARD_MESSAGES +======================== + + 01. id : integer NOT NULL DEFAULT nextval('dashboard_messages_id_seq'::regclass) + 02. title : character varying(255) NOT NULL + 03. content : text NOT NULL + 04. type : character varying(50) NOT NULL DEFAULT 'info'::character varying + 05. store_id : integer NULL + 06. created_by : character varying(255) NOT NULL + 07. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 2 + +TABLE: DATABASE_BACKUPS +====================== + + 01. id : character varying(255) NOT NULL + 02. filename : character varying(255) NOT NULL + 03. description : text NULL + 04. size : bigint NULL DEFAULT 0 + 05. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 06. created_by : character varying(255) NOT NULL + 07. tables_count : integer NULL DEFAULT 0 + 08. status : character varying(50) NULL DEFAULT 'creating'::character varying + 09. backup_type : character varying(10) NULL DEFAULT 'manual'::character varying + 📈 Nombre d'enregistrements: 7 + +TABLE: DELIVERIES +================ + + 01. id : integer NOT NULL DEFAULT nextval('deliveries_id_seq'::regclass) + 02. order_id : integer NULL + 03. supplier_id : integer NULL + 04. group_id : integer NULL + 05. scheduled_date : date NOT NULL + 06. delivered_date : timestamp without time zone NULL + 07. quantity : integer NOT NULL + 08. unit : character varying(50) NOT NULL + 09. status : character varying(50) NULL DEFAULT 'pending'::character varying + 10. notes : text NULL + 11. bl_number : character varying(255) NULL + 12. bl_amount : numeric NULL + 13. invoice_reference : character varying(255) NULL + 14. invoice_amount : numeric NULL + 15. reconciled : boolean NULL DEFAULT false + 16. validated_at : timestamp without time zone NULL + 17. created_by : character varying(255) NULL + 18. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 19. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 133 + +TABLE: DELIVERY_ITEMS +==================== + + 01. id : integer NOT NULL DEFAULT nextval('delivery_items_id_seq'::regclass) + 02. delivery_id : integer NULL + 03. product_name : character varying(255) NOT NULL + 04. product_reference : character varying(255) NULL + 05. quantity : integer NOT NULL + 06. unit : character varying(50) NULL + 07. notes : text NULL + 08. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: DLC_PRODUCTS +================== + + 01. id : integer NOT NULL DEFAULT nextval('dlc_products_id_seq'::regclass) + 02. product_name : character varying(255) NOT NULL + 03. expiry_date : date NOT NULL + 04. date_type : character varying(50) NOT NULL DEFAULT 'DLC'::character varying + 05. quantity : integer NOT NULL DEFAULT 1 + 06. unit : character varying(50) NOT NULL DEFAULT 'unité'::character varying + 07. supplier_id : integer NOT NULL + 08. location : character varying(255) NOT NULL DEFAULT 'Magasin'::character varying + 09. status : character varying(50) NOT NULL DEFAULT 'active'::character varying + 10. notes : text NULL + 11. alert_threshold : integer NOT NULL DEFAULT 15 + 12. validated_at : timestamp without time zone NULL + 13. validated_by : character varying(255) NULL + 14. group_id : integer NOT NULL + 15. created_by : character varying(255) NOT NULL + 16. created_at : timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP + 17. updated_at : timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP + 18. gencode : character varying(255) NULL + 19. name : character varying(255) NULL + 20. dlc_date : date NULL + 21. product_code : character varying(255) NULL + 22. description : text NULL + 23. stock_epuise : boolean NOT NULL DEFAULT false + 24. stock_epuise_by : character varying(255) NULL + 25. stock_epuise_at : timestamp without time zone NULL + 📈 Nombre d'enregistrements: 501 + +TABLE: GROUPS +============ + + 01. id : integer NOT NULL DEFAULT nextval('groups_id_seq'::regclass) + 02. name : character varying(255) NOT NULL + 03. color : character varying(20) NULL DEFAULT '#1976D2'::character varying + 04. nocodb_config_id : integer NULL + 05. nocodb_table_id : character varying(255) NULL + 06. nocodb_table_name : character varying(255) NULL + 07. invoice_column_name : character varying(255) NULL + 08. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 09. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 10. nocodb_bl_column_name : character varying(255) NULL + 11. nocodb_amount_column_name : character varying(255) NULL + 12. nocodb_supplier_column_name : character varying(255) NULL + 13. webhook_url : character varying(500) NULL + 📈 Nombre d'enregistrements: 2 + +TABLE: INVOICE_VERIFICATION_CACHE +================================ + + 01. id : integer NOT NULL DEFAULT nextval('invoice_verification_cache_id_seq'::regclass) + 02. cache_key : character varying(255) NOT NULL + 03. group_id : integer NOT NULL + 04. invoice_reference : character varying(255) NOT NULL + 05. supplier_name : character varying(255) NULL + 06. exists : boolean NOT NULL + 07. match_type : character varying(50) NOT NULL + 08. error_message : text NULL + 09. cache_hit : boolean NULL DEFAULT false + 10. api_call_time : integer NULL + 11. expires_at : timestamp without time zone NOT NULL + 12. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 13. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 122 + +TABLE: INVOICE_VERIFICATIONS +=========================== + + 01. id : integer NOT NULL DEFAULT nextval('invoice_verifications_id_seq'::regclass) + 02. delivery_id : integer NOT NULL + 03. group_id : integer NOT NULL + 04. invoice_reference : character varying(255) NOT NULL + 05. supplier_name : character varying(255) NULL + 06. exists : boolean NOT NULL + 07. match_type : character varying(50) NULL + 08. verified_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 09. is_valid : boolean NULL DEFAULT true + 10. last_checked_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 15 + +TABLE: INVOICES +============== + + 01. id : integer NOT NULL DEFAULT nextval('invoices_id_seq'::regclass) + 02. invoice_number : character varying(255) NOT NULL + 03. supplier_id : integer NULL + 04. group_id : integer NULL + 05. invoice_date : date NOT NULL + 06. due_date : date NULL + 07. amount : numeric NOT NULL + 08. status : character varying(50) NULL DEFAULT 'pending'::character varying + 09. payment_date : date NULL + 10. notes : text NULL + 11. created_by : character varying(255) NULL + 12. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 13. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: NOCODB_CONFIG +=================== + + 01. id : integer NOT NULL DEFAULT nextval('nocodb_config_id_seq'::regclass) + 02. name : character varying(255) NOT NULL + 03. base_url : character varying(255) NOT NULL + 04. project_id : character varying(255) NOT NULL + 05. api_token : character varying(255) NOT NULL + 06. description : text NULL + 07. is_active : boolean NULL DEFAULT true + 08. created_by : character varying(255) NULL + 09. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 10. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 1 + +TABLE: ORDERS +============ + + 01. id : integer NOT NULL DEFAULT nextval('orders_id_seq'::regclass) + 02. supplier_id : integer NULL + 03. group_id : integer NULL + 04. planned_date : date NOT NULL + 05. quantity : integer NULL + 06. unit : character varying(50) NULL + 07. status : character varying(50) NULL DEFAULT 'pending'::character varying + 08. notes : text NULL + 09. created_by : character varying(255) NULL + 10. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 11. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 85 + +TABLE: PERMISSIONS +================= + + 01. id : integer NOT NULL DEFAULT nextval('permissions_id_seq'::regclass) + 02. name : character varying(255) NOT NULL + 03. display_name : character varying(255) NOT NULL + 04. description : text NULL + 05. category : character varying(255) NOT NULL + 06. action : character varying(255) NOT NULL + 07. resource : character varying(255) NOT NULL + 08. is_system : boolean NULL DEFAULT true + 09. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 7 + +TABLE: PUBLICITIES +================= + + 01. id : integer NOT NULL DEFAULT nextval('publicities_id_seq'::regclass) + 02. pub_number : character varying(255) NOT NULL + 03. designation : text NOT NULL + 04. start_date : date NOT NULL + 05. end_date : date NOT NULL + 06. year : integer NOT NULL + 07. created_by : character varying(255) NULL + 08. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 09. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 48 + +TABLE: PUBLICITY_PARTICIPATIONS +============================== + + 01. publicity_id : integer NOT NULL + 02. group_id : integer NOT NULL + 📈 Nombre d'enregistrements: 46 + +TABLE: ROLE_PERMISSIONS +====================== + + 01. role_id : integer NOT NULL + 02. permission_id : integer NOT NULL + 📈 Nombre d'enregistrements: 21 + +TABLE: ROLES +=========== + + 01. id : integer NOT NULL DEFAULT nextval('roles_id_seq'::regclass) + 02. name : character varying(255) NOT NULL + 03. display_name : character varying(255) NOT NULL + 04. description : text NULL + 05. color : character varying(7) NULL DEFAULT '#6b7280'::character varying + 06. is_system : boolean NULL DEFAULT false + 07. is_active : boolean NULL DEFAULT true + 08. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 09. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 4 + +TABLE: SAV_TICKET_HISTORY +======================== + + 01. id : integer NOT NULL DEFAULT nextval('sav_ticket_history_id_seq'::regclass) + 02. ticket_id : integer NOT NULL + 03. action : character varying(100) NOT NULL + 04. description : text NULL + 05. created_by : character varying(255) NOT NULL + 06. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 3 + +TABLE: SAV_TICKETS +================= + + 01. id : integer NOT NULL DEFAULT nextval('sav_tickets_id_seq'::regclass) + 02. ticket_number : character varying(50) NOT NULL + 03. supplier_id : integer NOT NULL + 04. group_id : integer NOT NULL + 05. product_gencode : character varying(255) NOT NULL + 06. product_reference : character varying(255) NULL + 07. product_designation : character varying(500) NOT NULL + 08. problem_type : character varying(100) NOT NULL + 09. problem_description : text NOT NULL + 10. resolution_description : text NULL + 11. status : character varying(50) NOT NULL DEFAULT 'nouveau'::character varying + 12. created_by : character varying(255) NOT NULL + 13. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 14. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 15. resolved_at : timestamp without time zone NULL + 16. closed_at : timestamp without time zone NULL + 17. client_name : character varying(255) NULL + 18. client_phone : character varying(255) NULL + 19. priority : character varying(50) NOT NULL DEFAULT 'normale'::character varying + 📈 Nombre d'enregistrements: 1 + +TABLE: SESSION +============= + + 01. sid : character varying NOT NULL + 02. sess : json NOT NULL + 03. expire : timestamp without time zone NOT NULL + 📈 Nombre d'enregistrements: 13 + +TABLE: SESSIONS +============== + + 01. id : integer NOT NULL DEFAULT nextval('sessions_id_seq'::regclass) + 02. user_id : character varying(255) NULL + 03. session_token : character varying(255) NOT NULL + 04. expires_at : timestamp without time zone NOT NULL + 05. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: STORES +============ + + 01. id : integer NOT NULL DEFAULT nextval('stores_id_seq'::regclass) + 02. name : character varying(255) NOT NULL + 03. address : text NULL + 04. city : character varying(255) NULL + 05. postal_code : character varying(20) NULL + 06. phone : character varying(255) NULL + 07. manager_id : character varying(255) NULL + 08. is_active : boolean NULL DEFAULT true + 09. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 10. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 0 + +TABLE: SUPPLIERS +=============== + + 01. id : integer NOT NULL DEFAULT nextval('suppliers_id_seq'::regclass) + 02. name : character varying(255) NOT NULL + 03. contact : character varying(255) NULL + 04. phone : character varying(255) NULL + 05. has_dlc : boolean NULL DEFAULT false + 06. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 07. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 08. automatic_reconciliation : boolean NULL DEFAULT false + 📈 Nombre d'enregistrements: 39 + +TABLE: TASKS +=========== + + 01. id : integer NOT NULL DEFAULT nextval('tasks_id_seq'::regclass) + 02. title : character varying(255) NOT NULL + 03. description : text NULL + 04. status : character varying(50) NOT NULL DEFAULT 'pending'::character varying + 05. priority : character varying(50) NOT NULL DEFAULT 'medium'::character varying + 06. assigned_to : character varying(255) NULL + 07. due_date : date NULL + 08. group_id : integer NOT NULL + 09. created_by : character varying(255) NOT NULL + 10. created_at : timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP + 11. updated_at : timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP + 12. start_date : timestamp without time zone NULL + 13. completed_at : timestamp without time zone NULL + 14. completed_by : character varying(255) NULL + 📈 Nombre d'enregistrements: 63 + +TABLE: USER_GROUPS +================= + + 01. user_id : character varying(255) NOT NULL + 02. group_id : integer NOT NULL + 📈 Nombre d'enregistrements: 7 + +TABLE: USER_ROLES +================ + + 01. user_id : character varying(255) NOT NULL + 02. role_id : integer NOT NULL + 03. assigned_by : character varying(255) NULL + 04. assigned_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 1 + +TABLE: USERS +=========== + + 01. id : character varying(255) NOT NULL + 02. username : character varying(255) NOT NULL + 03. email : character varying(255) NULL + 04. name : character varying(255) NULL + 05. first_name : character varying(255) NULL + 06. last_name : character varying(255) NULL + 07. profile_image_url : text NULL + 08. password : character varying(255) NULL + 09. role : character varying(50) NULL DEFAULT 'employee'::character varying + 10. password_changed : boolean NULL DEFAULT false + 11. created_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 12. updated_at : timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 8 + +TABLE: WEATHER_DATA +================== + + 01. id : integer NOT NULL DEFAULT nextval('weather_data_id_seq'::regclass) + 02. date : date NOT NULL + 03. location : text NOT NULL + 04. temp_max : text NOT NULL + 05. temp_min : text NOT NULL + 06. icon : text NOT NULL + 07. conditions : text NOT NULL + 08. is_current_year : boolean NOT NULL DEFAULT true + 09. created_at : timestamp with time zone NULL DEFAULT CURRENT_TIMESTAMP + 10. updated_at : timestamp with time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 39 + +TABLE: WEATHER_SETTINGS +====================== + + 01. id : integer NOT NULL DEFAULT nextval('weather_settings_id_seq'::regclass) + 02. api_key : text NOT NULL + 03. location : text NOT NULL DEFAULT 'Paris, France'::text + 04. is_active : boolean NOT NULL DEFAULT true + 05. created_at : timestamp with time zone NULL DEFAULT CURRENT_TIMESTAMP + 06. updated_at : timestamp with time zone NULL DEFAULT CURRENT_TIMESTAMP + 📈 Nombre d'enregistrements: 1 + +CONTRAINTES DE CLÉS ÉTRANGÈRES: +=================================== + + calendar_events.created_by → users.id + calendar_events.group_id → groups.id + client_orders.created_by → users.id + client_orders.group_id → groups.id + command_items.command_id → commands.id + commands.created_by → users.id + commands.group_id → groups.id + commands.supplier_id → suppliers.id + customer_orders.created_by → users.id + customer_orders.group_id → groups.id + customer_orders.supplier_id → suppliers.id + customers.created_by → users.id + customers.group_id → groups.id + dashboard_messages.store_id → groups.id + database_backups.created_by → users.id + deliveries.created_by → users.id + deliveries.group_id → groups.id + deliveries.order_id → orders.id + deliveries.supplier_id → suppliers.id + delivery_items.delivery_id → deliveries.id + dlc_products.created_by → users.id + dlc_products.group_id → groups.id + dlc_products.supplier_id → suppliers.id + dlc_products.validated_by → users.id + invoice_verification_cache.group_id → groups.id + invoice_verifications.delivery_id → deliveries.id + invoice_verifications.group_id → groups.id + invoices.created_by → users.id + invoices.group_id → groups.id + invoices.supplier_id → suppliers.id + nocodb_config.created_by → users.id + orders.created_by → users.id + orders.group_id → groups.id + orders.supplier_id → suppliers.id + publicities.created_by → users.id + publicity_participations.group_id → groups.id + publicity_participations.publicity_id → publicities.id + role_permissions.permission_id → permissions.id + role_permissions.role_id → roles.id + sav_ticket_history.ticket_id → sav_tickets.id + sav_tickets.group_id → groups.id + sav_tickets.supplier_id → suppliers.id + sessions.user_id → users.id + stores.manager_id → users.id + tasks.completed_by → users.id + tasks.created_by → users.id + tasks.group_id → groups.id + user_groups.group_id → groups.id + user_groups.user_id → users.id + user_roles.assigned_by → users.id + user_roles.role_id → roles.id + user_roles.user_id → users.id + +=============================================== +FIN DU RAPPORT - 2025-09-03T13:42:55.993Z +=============================================== \ No newline at end of file diff --git a/attached_assets/{46180463-FA29-4E9B-B202-45BF0FC27BE6}_1756906944671.png b/attached_assets/{46180463-FA29-4E9B-B202-45BF0FC27BE6}_1756906944671.png new file mode 100644 index 0000000..8d456a0 Binary files /dev/null and b/attached_assets/{46180463-FA29-4E9B-B202-45BF0FC27BE6}_1756906944671.png differ diff --git a/create-webhook-bap-table-production.sql b/create-webhook-bap-table-production.sql new file mode 100644 index 0000000..2a4fda0 --- /dev/null +++ b/create-webhook-bap-table-production.sql @@ -0,0 +1,43 @@ +-- Script DEFINITIF pour créer la table webhook_bap_config en production +-- À exécuter directement sur votre PostgreSQL de production +-- ATTENTION : Remplacez YOUR_DATABASE par le nom de votre base + +\c YOUR_DATABASE; + +-- Créer la table webhook_bap_config +DROP TABLE IF EXISTS webhook_bap_config CASCADE; + +CREATE TABLE webhook_bap_config ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL DEFAULT 'Configuration BAP', + webhook_url TEXT NOT NULL, + description TEXT, + is_active BOOLEAN NOT NULL DEFAULT true, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Insérer la configuration par défaut avec VOTRE URL +INSERT INTO webhook_bap_config (name, webhook_url, description, is_active) VALUES ( + 'Configuration BAP', + 'https://workflow.ffnancy.fr/webhook-test/a3d03176-b72f-412d-8fb9-f920b9fbab4d', + 'Configuration pour envoi des fichiers BAP vers n8n', + true +); + +-- Créer la table migrations si elle n'existe pas +CREATE TABLE IF NOT EXISTS migrations ( + id SERIAL PRIMARY KEY, + filename VARCHAR(255) UNIQUE NOT NULL, + executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Marquer la migration comme appliquée +INSERT INTO migrations (filename) VALUES ('20250903141000_create_webhook_bap_config.sql') +ON CONFLICT (filename) DO NOTHING; + +-- Vérifier que tout est créé +SELECT 'Table webhook_bap_config créée avec succès' as message; +SELECT * FROM webhook_bap_config; +SELECT 'Table migrations mise à jour' as message; +SELECT * FROM migrations WHERE filename LIKE '%webhook_bap%'; \ No newline at end of file diff --git a/server/migrations.ts b/server/migrations.ts index c5917cc..ad25715 100644 --- a/server/migrations.ts +++ b/server/migrations.ts @@ -34,54 +34,67 @@ export async function runMigrations() { const appliedMigrations = await db.execute(sql`SELECT filename FROM migrations`); const appliedFilenames = new Set(appliedMigrations.rows.map((row: any) => row.filename)); - // Lire tous les fichiers de migration - const migrationsDir = path.join(__dirname, '..', 'migrations'); + // Ajouter les migrations hardcodées directement dans le code pour éviter les problèmes de chemins + const hardcodedMigrations = [ + { + filename: '20250903141000_create_webhook_bap_config.sql', + content: `CREATE TABLE IF NOT EXISTS webhook_bap_config ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL DEFAULT 'Configuration BAP', + webhook_url TEXT NOT NULL, + description TEXT, + is_active BOOLEAN NOT NULL DEFAULT true, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +INSERT INTO webhook_bap_config (name, webhook_url, description, is_active) +SELECT + 'Configuration BAP', + 'https://workflow.ffnancy.fr/webhook-test/a3d03176-b72f-412d-8fb9-f920b9fbab4d', + 'Configuration par défaut pour envoi des fichiers BAP vers n8n', + true +WHERE NOT EXISTS (SELECT 1 FROM webhook_bap_config);` + } + ]; - if (!fs.existsSync(migrationsDir)) { - console.log('📁 Création du dossier migrations...'); - fs.mkdirSync(migrationsDir, { recursive: true }); - } + // Ignorer les fichiers de migrations pour éviter les erreurs SQL + // Utiliser uniquement les migrations hardcodées + const allMigrations = hardcodedMigrations; - const migrationFiles = fs.readdirSync(migrationsDir) - .filter(file => file.endsWith('.sql')) - .sort(); // Important : tri pour exécuter dans l'ordre - - if (migrationFiles.length === 0) { + if (allMigrations.length === 0) { console.log('✅ Aucune migration à exécuter'); return; } let executedCount = 0; - for (const filename of migrationFiles) { - if (appliedFilenames.has(filename)) { - console.log(`⏭️ Migration déjà appliquée: ${filename}`); + for (const migration of allMigrations) { + if (appliedFilenames.has(migration.filename)) { + console.log(`⏭️ Migration déjà appliquée: ${migration.filename}`); continue; } - console.log(`🔄 Exécution migration: ${filename}`); - - const filePath = path.join(migrationsDir, filename); - const migrationSql = fs.readFileSync(filePath, 'utf8'); + console.log(`🔄 Exécution migration: ${migration.filename}`); try { // Exécuter la migration dans une transaction await db.transaction(async (tx: any) => { // Exécuter le SQL de migration - await tx.execute(sql.raw(migrationSql)); + await tx.execute(sql.raw(migration.content)); // Marquer comme appliquée await tx.execute(sql` INSERT INTO migrations (filename) - VALUES (${filename}) + VALUES (${migration.filename}) `); }); - console.log(`✅ Migration appliquée avec succès: ${filename}`); + console.log(`✅ Migration appliquée avec succès: ${migration.filename}`); executedCount++; } catch (error) { - console.error(`❌ Erreur lors de la migration ${filename}:`, error); + console.error(`❌ Erreur lors de la migration ${migration.filename}:`, error); throw error; } } diff --git a/server/routes.ts b/server/routes.ts index 8aa9ba3..7165907 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -88,6 +88,20 @@ export async function registerRoutes(app: Express): Promise { } catch (error: any) { console.error('❌ Erreur récupération config webhook BAP:', error); + + // Si la table n'existe pas, retourner une configuration par défaut + if (error.code === '42P01') { // Relation does not exist + console.log('⚠️ Table webhook_bap_config n\'existe pas, retour config par défaut'); + return res.json({ + id: 1, + name: "Configuration BAP", + webhookUrl: "https://workflow.ffnancy.fr/webhook-test/a3d03176-b72f-412d-8fb9-f920b9fbab4d", + description: "Configuration par défaut (table non créée)", + isActive: true, + needsTableCreation: true + }); + } + res.status(500).json({ error: 'Erreur serveur', details: error.message }); } });