mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-16 19:56:32 +02:00
Refactor announcement system to use in-memory storage
Move announcement data management from SQL to an in-memory solution with a limit of 5 entries. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e437ffed-c31b-44eb-9fd5-b6f9faa8e7ce Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/e437ffed-c31b-44eb-9fd5-b6f9faa8e7ce/aVFsaJG
This commit is contained in:
1 parent
48b784d0f1
commit
f2d056ee5d
3 files changed
+181
-78
No files matched your search
@@ -0,0 +1,150 @@
|
||||
import { Announcement, InsertAnnouncement, AnnouncementWithRelations, User, Group } from "@shared/schema";
|
||||
|
||||
// Stockage en mémoire partagé pour les annonces (maximum 5)
|
||||
class AnnouncementMemoryStorage {
|
||||
private announcements = new Map<number, Announcement>();
|
||||
private idCounter = 1;
|
||||
private readonly MAX_ANNOUNCEMENTS = 5;
|
||||
|
||||
// Référence vers les utilisateurs et groupes pour les relations
|
||||
private usersGetter: () => Promise<User[]>;
|
||||
private groupsGetter: () => Promise<Group[]>;
|
||||
|
||||
constructor(usersGetter: () => Promise<User[]>, groupsGetter: () => Promise<Group[]>) {
|
||||
this.usersGetter = usersGetter;
|
||||
this.groupsGetter = groupsGetter;
|
||||
this.initializeTestData();
|
||||
}
|
||||
|
||||
private initializeTestData() {
|
||||
// Créer quelques annonces de test
|
||||
const testAnnouncement: Announcement = {
|
||||
id: this.idCounter++,
|
||||
title: "Bienvenue dans le système d'informations",
|
||||
content: "Ce nouveau système remplace l'ancienne carte des commandes clients. Vous pouvez maintenant créer et gérer des annonces importantes.",
|
||||
priority: 'important',
|
||||
authorId: 'admin',
|
||||
groupId: 1,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.announcements.set(testAnnouncement.id, testAnnouncement);
|
||||
|
||||
const testAnnouncement2: Announcement = {
|
||||
id: this.idCounter++,
|
||||
title: "Maintenance programmée",
|
||||
content: "Une maintenance système aura lieu dimanche prochain de 2h à 4h du matin.",
|
||||
priority: 'normal',
|
||||
authorId: 'admin',
|
||||
groupId: null, // Annonce globale
|
||||
createdAt: new Date(Date.now() - 24 * 60 * 60 * 1000), // Hier
|
||||
updatedAt: new Date(Date.now() - 24 * 60 * 60 * 1000),
|
||||
};
|
||||
this.announcements.set(testAnnouncement2.id, testAnnouncement2);
|
||||
}
|
||||
|
||||
async getAnnouncements(groupIds?: number[]): Promise<AnnouncementWithRelations[]> {
|
||||
const announcements = Array.from(this.announcements.values());
|
||||
|
||||
let filteredAnnouncements = announcements;
|
||||
|
||||
// Filtrer par groupIds si fourni (pour le filtrage admin par magasin)
|
||||
if (groupIds && groupIds.length > 0) {
|
||||
filteredAnnouncements = announcements.filter(announcement =>
|
||||
!announcement.groupId || groupIds.includes(announcement.groupId)
|
||||
);
|
||||
}
|
||||
|
||||
// Récupérer les utilisateurs et groupes pour les relations
|
||||
const [users, groups] = await Promise.all([
|
||||
this.usersGetter(),
|
||||
this.groupsGetter()
|
||||
]);
|
||||
|
||||
const usersMap = new Map(users.map(u => [u.id, u]));
|
||||
const groupsMap = new Map(groups.map(g => [g.id, g]));
|
||||
|
||||
// Ajouter les relations
|
||||
const announcementsWithRelations = filteredAnnouncements.map(announcement => {
|
||||
const author = usersMap.get(announcement.authorId);
|
||||
const group = announcement.groupId ? groupsMap.get(announcement.groupId) : undefined;
|
||||
|
||||
return {
|
||||
...announcement,
|
||||
author: author!,
|
||||
group,
|
||||
};
|
||||
}).filter(a => a.author); // Filtrer celles sans auteur valide
|
||||
|
||||
// Trier par priorité (urgent > important > normal) puis par date (plus récent d'abord)
|
||||
return announcementsWithRelations.sort((a, b) => {
|
||||
const priorityOrder = { urgent: 3, important: 2, normal: 1 };
|
||||
const priorityDiff = (priorityOrder[b.priority as keyof typeof priorityOrder] || 1) -
|
||||
(priorityOrder[a.priority as keyof typeof priorityOrder] || 1);
|
||||
if (priorityDiff !== 0) return priorityDiff;
|
||||
return new Date(b.createdAt!).getTime() - new Date(a.createdAt!).getTime();
|
||||
});
|
||||
}
|
||||
|
||||
async createAnnouncement(announcementData: InsertAnnouncement): Promise<Announcement> {
|
||||
// Vérifier la limite de 5 annonces maximum
|
||||
if (this.announcements.size >= this.MAX_ANNOUNCEMENTS) {
|
||||
// Supprimer l'annonce la plus ancienne (par ordre de création)
|
||||
const oldestAnnouncement = Array.from(this.announcements.values())
|
||||
.sort((a, b) => new Date(a.createdAt!).getTime() - new Date(b.createdAt!).getTime())[0];
|
||||
|
||||
if (oldestAnnouncement) {
|
||||
this.announcements.delete(oldestAnnouncement.id);
|
||||
console.log(`🗑️ Annonce supprimée automatiquement (limite de ${this.MAX_ANNOUNCEMENTS}): ${oldestAnnouncement.title}`);
|
||||
}
|
||||
}
|
||||
|
||||
const id = this.idCounter++;
|
||||
const announcement: Announcement = {
|
||||
id,
|
||||
...announcementData,
|
||||
groupId: announcementData.groupId || null,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
this.announcements.set(id, announcement);
|
||||
console.log(`✅ Nouvelle annonce créée: ${announcement.title} (${this.announcements.size}/${this.MAX_ANNOUNCEMENTS})`);
|
||||
|
||||
return announcement;
|
||||
}
|
||||
|
||||
async deleteAnnouncement(id: number): Promise<boolean> {
|
||||
const existed = this.announcements.has(id);
|
||||
const deleted = this.announcements.delete(id);
|
||||
|
||||
if (deleted) {
|
||||
console.log(`🗑️ Annonce supprimée: ID ${id} (${this.announcements.size}/${this.MAX_ANNOUNCEMENTS} restantes)`);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
export function getAnnouncementStorage(usersGetter: () => Promise<User[]>, groupsGetter: () => Promise<Group[]>): AnnouncementMemoryStorage {
|
||||
if (!announcementStorage) {
|
||||
announcementStorage = new AnnouncementMemoryStorage(usersGetter, groupsGetter);
|
||||
console.log('📢 Système d\'annonces en mémoire initialisé (max 5 annonces)');
|
||||
}
|
||||
return announcementStorage;
|
||||
}
|
||||
+30
-77
@@ -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.js";
|
||||
|
||||
export interface IStorage {
|
||||
// User operations
|
||||
@@ -1591,51 +1592,27 @@ export class DatabaseStorage implements IStorage {
|
||||
|
||||
// Announcement operations
|
||||
async createAnnouncement(announcementData: InsertAnnouncement): Promise<Announcement> {
|
||||
const [announcement] = await db.insert(announcements).values(announcementData).returning();
|
||||
return announcement;
|
||||
const announcementStorage = getAnnouncementStorage(
|
||||
() => this.getUsers(),
|
||||
() => this.getGroups()
|
||||
);
|
||||
return await announcementStorage.createAnnouncement(announcementData);
|
||||
}
|
||||
|
||||
async getAnnouncements(groupIds?: number[]): Promise<AnnouncementWithRelations[]> {
|
||||
let query = db
|
||||
.select({
|
||||
announcement: announcements,
|
||||
author: users,
|
||||
group: groups,
|
||||
})
|
||||
.from(announcements)
|
||||
.leftJoin(users, eq(announcements.authorId, users.id))
|
||||
.leftJoin(groups, eq(announcements.groupId, groups.id));
|
||||
|
||||
// Filter by groupIds if provided (for admin filtering by store)
|
||||
if (groupIds && groupIds.length > 0) {
|
||||
query = query.where(
|
||||
or(
|
||||
isNull(announcements.groupId), // Global announcements (no group)
|
||||
inArray(announcements.groupId, groupIds)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const results = await query.orderBy(
|
||||
// Sort by priority (urgent > important > normal) then by date (newest first)
|
||||
sql`CASE
|
||||
WHEN ${announcements.priority} = 'urgent' THEN 3
|
||||
WHEN ${announcements.priority} = 'important' THEN 2
|
||||
ELSE 1
|
||||
END DESC`,
|
||||
desc(announcements.createdAt)
|
||||
const announcementStorage = getAnnouncementStorage(
|
||||
() => this.getUsers(),
|
||||
() => this.getGroups()
|
||||
);
|
||||
|
||||
return results.map(result => ({
|
||||
...result.announcement,
|
||||
author: result.author!,
|
||||
group: result.group,
|
||||
}));
|
||||
return await announcementStorage.getAnnouncements(groupIds);
|
||||
}
|
||||
|
||||
async deleteAnnouncement(id: number): Promise<boolean> {
|
||||
const result = await db.delete(announcements).where(eq(announcements.id, id));
|
||||
return result.rowCount ? result.rowCount > 0 : false;
|
||||
const announcementStorage = getAnnouncementStorage(
|
||||
() => this.getUsers(),
|
||||
() => this.getGroups()
|
||||
);
|
||||
return await announcementStorage.deleteAnnouncement(id);
|
||||
}
|
||||
|
||||
// SAV operations
|
||||
@@ -3335,51 +3312,27 @@ export class MemStorage implements IStorage {
|
||||
|
||||
// Announcement operations
|
||||
async createAnnouncement(announcementData: InsertAnnouncement): Promise<Announcement> {
|
||||
const id = this.idCounters.announcement++;
|
||||
const announcement: Announcement = {
|
||||
id,
|
||||
...announcementData,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.announcements.set(id, announcement);
|
||||
return announcement;
|
||||
const announcementStorage = getAnnouncementStorage(
|
||||
async () => Array.from(this.users.values()),
|
||||
async () => Array.from(this.groups.values())
|
||||
);
|
||||
return await announcementStorage.createAnnouncement(announcementData);
|
||||
}
|
||||
|
||||
async getAnnouncements(groupIds?: number[]): Promise<AnnouncementWithRelations[]> {
|
||||
const announcements = Array.from(this.announcements.values());
|
||||
|
||||
let filteredAnnouncements = announcements;
|
||||
|
||||
// Filter by groupIds if provided (for admin filtering by store)
|
||||
if (groupIds && groupIds.length > 0) {
|
||||
filteredAnnouncements = announcements.filter(announcement =>
|
||||
!announcement.groupId || groupIds.includes(announcement.groupId)
|
||||
);
|
||||
}
|
||||
|
||||
// Add relations
|
||||
return filteredAnnouncements.map(announcement => {
|
||||
const author = this.users.get(announcement.authorId);
|
||||
const group = announcement.groupId ? this.groups.get(announcement.groupId) : undefined;
|
||||
|
||||
return {
|
||||
...announcement,
|
||||
author: author!,
|
||||
group,
|
||||
};
|
||||
}).sort((a, b) => {
|
||||
// Sort by priority (urgent > important > normal) then by date (newest first)
|
||||
const priorityOrder = { urgent: 3, important: 2, normal: 1 };
|
||||
const priorityDiff = (priorityOrder[b.priority as keyof typeof priorityOrder] || 1) -
|
||||
(priorityOrder[a.priority as keyof typeof priorityOrder] || 1);
|
||||
if (priorityDiff !== 0) return priorityDiff;
|
||||
return new Date(b.createdAt!).getTime() - new Date(a.createdAt!).getTime();
|
||||
});
|
||||
const announcementStorage = getAnnouncementStorage(
|
||||
async () => Array.from(this.users.values()),
|
||||
async () => Array.from(this.groups.values())
|
||||
);
|
||||
return await announcementStorage.getAnnouncements(groupIds);
|
||||
}
|
||||
|
||||
async deleteAnnouncement(id: number): Promise<boolean> {
|
||||
return this.announcements.delete(id);
|
||||
const announcementStorage = getAnnouncementStorage(
|
||||
async () => Array.from(this.users.values()),
|
||||
async () => Array.from(this.groups.values())
|
||||
);
|
||||
return await announcementStorage.deleteAnnouncement(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user