diff --git a/init_postgres.sql b/init_postgres.sql new file mode 100644 index 0000000..841c827 --- /dev/null +++ b/init_postgres.sql @@ -0,0 +1,25 @@ +-- Script d'initialisation PostgreSQL pour les annonces +CREATE TABLE IF NOT EXISTS announcements ( + id SERIAL PRIMARY KEY, + title VARCHAR(255) NOT NULL, + content TEXT NOT NULL, + priority VARCHAR(20) DEFAULT 'normal' CHECK (priority IN ('normal', 'important', 'urgent')), + author_id VARCHAR(255) NOT NULL, + group_id INTEGER, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Index pour améliorer les performances +CREATE INDEX IF NOT EXISTS idx_announcements_priority ON announcements(priority); +CREATE INDEX IF NOT EXISTS idx_announcements_created_at ON announcements(created_at); +CREATE INDEX IF NOT EXISTS idx_announcements_group_id ON announcements(group_id); + +-- Insertion de données de test +INSERT INTO announcements (title, content, priority, author_id, group_id) VALUES +('Bienvenue dans le système d''informations', 'Ce nouveau système remplace l''ancienne carte des commandes clients. Vous pouvez maintenant créer et gérer des annonces importantes.', 'important', 'admin', 1), +('Maintenance programmée', 'Une maintenance système aura lieu dimanche prochain de 2h à 4h du matin.', 'normal', 'admin', NULL) +ON CONFLICT DO NOTHING; + +-- Afficher le résultat +SELECT COUNT(*) as total_announcements FROM announcements; \ No newline at end of file diff --git a/server/announcementStorage.ts b/server/announcementStorage.ts index 77cfddd..e3ffd6a 100644 --- a/server/announcementStorage.ts +++ b/server/announcementStorage.ts @@ -103,6 +103,7 @@ class AnnouncementMemoryStorage { const announcement: Announcement = { id, ...announcementData, + priority: announcementData.priority || 'normal', groupId: announcementData.groupId || null, createdAt: new Date(), updatedAt: new Date(), @@ -178,27 +179,18 @@ class AnnouncementMemoryStorage { return deleted; } - - // Méthode utilitaire pour obtenir le nombre d'annonces - getCount(): number { - return this.announcements.size; - } - - // Méthode utilitaire pour nettoyer toutes les annonces (si nécessaire) - clear(): void { - this.announcements.clear(); - this.idCounter = 1; - console.log('🧹 Toutes les annonces ont été supprimées'); - } } -// Instance singleton pour partager entre production et développement -let announcementStorage: AnnouncementMemoryStorage | null = null; +// Instance globale partagée +let globalAnnouncementStorage: AnnouncementMemoryStorage | null = null; -export function getAnnouncementStorage(usersGetter: () => Promise, groupsGetter: () => Promise): AnnouncementMemoryStorage { - if (!announcementStorage) { - announcementStorage = new AnnouncementMemoryStorage(usersGetter, groupsGetter); - console.log('📢 Système d\'annonces en mémoire initialisé (max 5 annonces)'); +export function getAnnouncementStorage( + usersGetter: () => Promise, + groupsGetter: () => Promise +): AnnouncementMemoryStorage { + if (!globalAnnouncementStorage) { + globalAnnouncementStorage = new AnnouncementMemoryStorage(usersGetter, groupsGetter); + console.log('📢 Stockage mémoire des annonces initialisé'); } - return announcementStorage; + return globalAnnouncementStorage; } \ No newline at end of file diff --git a/server/db.ts b/server/db.ts index 8a1c88d..aa22022 100644 --- a/server/db.ts +++ b/server/db.ts @@ -14,15 +14,15 @@ console.log('🔗 Database initialization:', { let db: any; let pool: any; -if (isProduction && dbUrl && (dbUrl.includes('logiflow-db') || dbUrl.includes('localhost') || dbUrl.includes('127.0.0.1'))) { - // Standard PostgreSQL for production Docker - console.log('🐳 PRODUCTION: Using standard PostgreSQL'); +if (dbUrl && (isProduction || process.env.FORCE_POSTGRES === 'true')) { + // Use PostgreSQL for production or when forced + console.log('🐘 Using PostgreSQL database'); const { Pool } = await import('pg'); const { drizzle } = await import('drizzle-orm/node-postgres'); pool = new Pool({ connectionString: dbUrl, - ssl: false, + ssl: dbUrl.includes('localhost') ? false : { rejectUnauthorized: false }, max: 10, idleTimeoutMillis: 30000, connectionTimeoutMillis: 5000, @@ -38,25 +38,15 @@ if (isProduction && dbUrl && (dbUrl.includes('logiflow-db') || dbUrl.includes('l }); } catch (error) { console.error('❌ PostgreSQL connection test failed:', error); - } -} else { - // Fallback: use Neon for development (but will be overridden by MemStorage) - console.log('🔧 DEV: Using Neon (fallback, will use MemStorage)'); - const { Pool, neonConfig } = await import('@neondatabase/serverless'); - const { drizzle } = await import('drizzle-orm/neon-serverless'); - const ws = await import('ws'); - - neonConfig.webSocketConstructor = ws.default; - - if (dbUrl) { - pool = new Pool({ connectionString: dbUrl }); - db = drizzle({ client: pool, schema }); - } else { - // Create dummy instances for development + // Continue anyway, will use MemStorage as fallback pool = null; db = null; - console.log('🔧 DEV: No DATABASE_URL, using MemStorage'); } +} else { + // Development fallback: use MemStorage + console.log('🔧 DEV: Using MemStorage (development fallback)'); + pool = null; + db = null; } export { db, pool }; \ No newline at end of file diff --git a/server/storage.ts b/server/storage.ts index e417c42..a700116 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -68,6 +68,7 @@ import { } from "@shared/schema"; import { db } from "./db"; import { eq, and, inArray, desc, sql, gte, lte, lt, or, isNull, isNotNull, asc } from "drizzle-orm"; +import { getAnnouncementStorage } from "./announcementStorage"; export interface IStorage {