import { type Product, type InsertProduct, type StockMovement, type InsertStockMovement, type Document, type InsertDocument, type Order, type InsertOrder, type Notification, type InsertNotification } from "@shared/schema"; import { randomUUID } from "crypto"; export interface IStorage { // Products getProducts(): Promise; getProduct(id: string): Promise; getProductBySku(sku: string): Promise; createProduct(product: InsertProduct): Promise; updateProduct(id: string, product: Partial): Promise; deleteProduct(id: string): Promise; searchProducts(query: string): Promise; getLowStockProducts(): Promise; getOutOfStockProducts(): Promise; // Stock movements getStockMovements(productId?: string): Promise; createStockMovement(movement: InsertStockMovement): Promise; // Documents getDocuments(): Promise; getDocument(id: string): Promise; createDocument(document: InsertDocument): Promise; updateDocument(id: string, document: Partial): Promise; deleteDocument(id: string): Promise; // Orders getOrders(): Promise; getOrder(id: string): Promise; createOrder(order: InsertOrder): Promise; updateOrder(id: string, order: Partial): Promise; // Notifications getNotifications(): Promise; createNotification(notification: InsertNotification): Promise; markNotificationAsRead(id: string): Promise; getUnreadNotificationCount(): Promise; } export class MemStorage implements IStorage { private products: Map; private stockMovements: Map; private documents: Map; private orders: Map; private notifications: Map; constructor() { this.products = new Map(); this.stockMovements = new Map(); this.documents = new Map(); this.orders = new Map(); this.notifications = new Map(); // Initialize with sample data this.initializeSampleData(); } private initializeSampleData() { const sampleProducts: Product[] = [ { id: "1", sku: "SH-001", name: "Safety Helmets - White", description: "High-quality safety helmets for construction work", currentStock: 125, minThreshold: 20, unit: "units", price: "29.99", createdAt: new Date(), updatedAt: new Date(), }, { id: "2", sku: "WG-003", name: "Work Gloves - Medium", description: "Durable work gloves for general construction", currentStock: 8, minThreshold: 15, unit: "pairs", price: "12.50", createdAt: new Date(), updatedAt: new Date(), }, { id: "3", sku: "HV-005", name: "Hi-Vis Vests - Large", description: "High-visibility safety vests", currentStock: 0, minThreshold: 10, unit: "units", price: "15.75", createdAt: new Date(), updatedAt: new Date(), }, ]; sampleProducts.forEach(product => { this.products.set(product.id, product); }); // Create notifications for low/out of stock items const lowStockNotification: Notification = { id: "notif-1", type: "low_stock", title: "Low Stock Alert", message: "Work Gloves - Medium is below minimum threshold", isRead: false, relatedId: "2", createdAt: new Date(), }; const outOfStockNotification: Notification = { id: "notif-2", type: "out_of_stock", title: "Out of Stock Alert", message: "Hi-Vis Vests - Large is out of stock", isRead: false, relatedId: "3", createdAt: new Date(), }; this.notifications.set("notif-1", lowStockNotification); this.notifications.set("notif-2", outOfStockNotification); } // Products async getProducts(): Promise { return Array.from(this.products.values()); } async getProduct(id: string): Promise { return this.products.get(id); } async getProductBySku(sku: string): Promise { return Array.from(this.products.values()).find(product => product.sku === sku); } async createProduct(insertProduct: InsertProduct): Promise { const id = randomUUID(); const product: Product = { ...insertProduct, id, description: insertProduct.description ?? null, createdAt: new Date(), updatedAt: new Date(), }; this.products.set(id, product); return product; } async updateProduct(id: string, updates: Partial): Promise { const product = this.products.get(id); if (!product) return undefined; const updatedProduct: Product = { ...product, ...updates, updatedAt: new Date(), }; this.products.set(id, updatedProduct); return updatedProduct; } async deleteProduct(id: string): Promise { return this.products.delete(id); } async searchProducts(query: string): Promise { const products = Array.from(this.products.values()); const lowercaseQuery = query.toLowerCase(); return products.filter(product => product.name.toLowerCase().includes(lowercaseQuery) || product.sku.toLowerCase().includes(lowercaseQuery) || product.description?.toLowerCase().includes(lowercaseQuery) ); } async getLowStockProducts(): Promise { return Array.from(this.products.values()).filter( product => product.currentStock > 0 && product.currentStock <= product.minThreshold ); } async getOutOfStockProducts(): Promise { return Array.from(this.products.values()).filter( product => product.currentStock === 0 ); } // Stock movements async getStockMovements(productId?: string): Promise { const movements = Array.from(this.stockMovements.values()); if (productId) { return movements.filter(movement => movement.productId === productId); } return movements; } async createStockMovement(insertMovement: InsertStockMovement): Promise { const id = randomUUID(); const movement: StockMovement = { ...insertMovement, id, reason: insertMovement.reason ?? null, createdAt: new Date(), }; this.stockMovements.set(id, movement); // Update product stock const product = this.products.get(insertMovement.productId); if (product) { let newStock = product.currentStock; if (insertMovement.type === 'in') { newStock += insertMovement.quantity; } else if (insertMovement.type === 'out') { newStock -= insertMovement.quantity; } else if (insertMovement.type === 'adjustment') { newStock = insertMovement.quantity; } await this.updateProduct(insertMovement.productId, { currentStock: Math.max(0, newStock) }); } return movement; } // Documents async getDocuments(): Promise { return Array.from(this.documents.values()); } async getDocument(id: string): Promise { return this.documents.get(id); } async createDocument(insertDocument: InsertDocument): Promise { const id = randomUUID(); const document: Document = { ...insertDocument, id, content: insertDocument.content ?? {}, status: insertDocument.status ?? "draft", createdAt: new Date(), updatedAt: new Date(), }; this.documents.set(id, document); return document; } async updateDocument(id: string, updates: Partial): Promise { const document = this.documents.get(id); if (!document) return undefined; const updatedDocument: Document = { ...document, ...updates, updatedAt: new Date(), }; this.documents.set(id, updatedDocument); return updatedDocument; } async deleteDocument(id: string): Promise { return this.documents.delete(id); } // Orders async getOrders(): Promise { return Array.from(this.orders.values()); } async getOrder(id: string): Promise { return this.orders.get(id); } async createOrder(insertOrder: InsertOrder): Promise { const id = randomUUID(); const order: Order = { ...insertOrder, id, status: insertOrder.status ?? "pending", createdAt: new Date(), updatedAt: new Date(), }; this.orders.set(id, order); return order; } async updateOrder(id: string, updates: Partial): Promise { const order = this.orders.get(id); if (!order) return undefined; const updatedOrder: Order = { ...order, ...updates, updatedAt: new Date(), }; this.orders.set(id, updatedOrder); return updatedOrder; } // Notifications async getNotifications(): Promise { return Array.from(this.notifications.values()).sort( (a, b) => (b.createdAt?.getTime() || 0) - (a.createdAt?.getTime() || 0) ); } async createNotification(insertNotification: InsertNotification): Promise { const id = randomUUID(); const notification: Notification = { ...insertNotification, id, isRead: insertNotification.isRead ?? false, relatedId: insertNotification.relatedId ?? null, createdAt: new Date(), }; this.notifications.set(id, notification); return notification; } async markNotificationAsRead(id: string): Promise { const notification = this.notifications.get(id); if (!notification) return false; notification.isRead = true; this.notifications.set(id, notification); return true; } async getUnreadNotificationCount(): Promise { return Array.from(this.notifications.values()).filter(n => !n.isRead).length; } } export const storage = new MemStorage();