import { users, sellers, categories, stores, products, orders, orderItems, cartItems, type User, type InsertUser, type Seller, type InsertSeller, type Category, type InsertCategory, type Store, type InsertStore, type Product, type InsertProduct, type Order, type InsertOrder, type OrderItem, type InsertOrderItem, type CartItem, type InsertCartItem } from "@shared/schema"; import { db } from "./db"; import { eq, desc, and, like, or, inArray } from "drizzle-orm"; export interface IStorage { // Users getUser(id: string): Promise; getUserByUsername(username: string): Promise; getUserByEmail(email: string): Promise; createUser(user: InsertUser): Promise; updateUser(id: string, user: Partial): Promise; getAllUsers(): Promise; // Sellers getSeller(id: string): Promise; getSellerByUsername(username: string): Promise; createSeller(seller: InsertSeller): Promise; getAllSellers(): Promise; deleteSeller(id: string): Promise; // Categories getCategory(id: string): Promise; getAllCategories(): Promise; createCategory(category: InsertCategory): Promise; updateCategory(id: string, category: Partial): Promise; deleteCategory(id: string): Promise; // Stores getStore(id: string): Promise; getStoreBysellerId(sellerId: string): Promise; getStoresBySeller(sellerId: string): Promise; getAllStores(): Promise; createStore(store: InsertStore): Promise; updateStore(id: string, store: Partial): Promise; deleteStore(id: string): Promise; // Products getProduct(id: string): Promise; getAllProducts(): Promise; getProductsByCategory(categoryId: string): Promise; getProductsBySeller(sellerId: string): Promise; getFeaturedProducts(limit?: number): Promise; searchProducts(query: string): Promise; createProduct(product: InsertProduct): Promise; updateProduct(id: string, product: Partial): Promise; deleteProduct(id: string): Promise; // Orders getOrder(id: string): Promise; getOrdersByUser(userId: string): Promise; getAllOrders(): Promise; getOrdersForSeller(productIds: string[]): Promise; createOrder(order: InsertOrder): Promise; updateOrderStatus(id: string, status: string): Promise; updateOrderPaymentStatus(id: string, paymentStatus: string): Promise; updateOrderStatusAndPayment(id: string, updates: { status?: string; paymentStatus?: string }): Promise; // Order Items getOrderItems(orderId: string): Promise; createOrderItem(orderItem: InsertOrderItem): Promise; // Cart getCartItems(userId: string): Promise; addToCart(cartItem: InsertCartItem): Promise; updateCartItem(id: string, quantity: number): Promise; removeFromCart(id: string): Promise; clearCart(userId: string): Promise; } export class DatabaseStorage implements IStorage { // Users async getUser(id: string): Promise { const [user] = await db.select().from(users).where(eq(users.id, id)); return user || undefined; } async getUserByUsername(username: string): Promise { const [user] = await db.select().from(users).where(eq(users.username, username)); return user || undefined; } async getUserByEmail(email: string): Promise { const [user] = await db.select().from(users).where(eq(users.email, email)); return user || undefined; } async createUser(insertUser: InsertUser): Promise { // Convert latitude/longitude numbers to strings for database storage const userData = { ...insertUser, latitude: insertUser.latitude ? String(insertUser.latitude) : undefined, longitude: insertUser.longitude ? String(insertUser.longitude) : undefined, }; const [user] = await db.insert(users).values([userData]).returning(); return user; } async getAllUsers(): Promise { return await db.select().from(users).orderBy(desc(users.createdAt)); } async updateUser(id: string, updateUser: Partial): Promise { // Convert latitude/longitude numbers to strings for database storage const userData = { ...updateUser, latitude: updateUser.latitude ? String(updateUser.latitude) : undefined, longitude: updateUser.longitude ? String(updateUser.longitude) : undefined, }; const [user] = await db.update(users) .set(userData) .where(eq(users.id, id)) .returning(); return user; } // Sellers async getSeller(id: string): Promise { const [seller] = await db.select().from(sellers).where(eq(sellers.id, id)); return seller || undefined; } async getSellerByUsername(username: string): Promise { const [seller] = await db.select().from(sellers).where(eq(sellers.username, username)); return seller || undefined; } async createSeller(insertSeller: InsertSeller): Promise { const [seller] = await db.insert(sellers).values([insertSeller]).returning(); return seller; } async getAllSellers(): Promise { return await db.select().from(sellers).orderBy(desc(sellers.createdAt)); } async deleteSeller(id: string): Promise { await db.delete(sellers).where(eq(sellers.id, id)); } // Categories async getCategory(id: string): Promise { const [category] = await db.select().from(categories).where(eq(categories.id, id)); return category || undefined; } async getAllCategories(): Promise { return await db.select().from(categories).orderBy(categories.name); } async createCategory(insertCategory: InsertCategory): Promise { const [category] = await db.insert(categories).values([insertCategory]).returning(); return category; } async updateCategory(id: string, updateCategory: Partial): Promise { const [category] = await db.update(categories) .set(updateCategory) .where(eq(categories.id, id)) .returning(); return category; } async deleteCategory(id: string): Promise { await db.delete(categories).where(eq(categories.id, id)); } // Stores async getStore(id: string): Promise { const [store] = await db.select().from(stores).where(eq(stores.id, id)); return store || undefined; } async getStoreBysellerId(sellerId: string): Promise { const [store] = await db.select().from(stores).where(eq(stores.sellerId, sellerId)); return store || undefined; } async getAllStores(): Promise { return await db.select().from(stores).orderBy(desc(stores.createdAt)); } async createStore(insertStore: InsertStore): Promise { const [store] = await db.insert(stores).values([insertStore]).returning(); return store; } async updateStore(id: string, updateStore: Partial): Promise { const [store] = await db.update(stores) .set(updateStore) .where(eq(stores.id, id)) .returning(); return store; } async getStoresBySeller(sellerId: string): Promise { return await db.select().from(stores).where(eq(stores.sellerId, sellerId)); } async deleteStore(id: string): Promise { await db.delete(stores).where(eq(stores.id, id)); } // Products async getProduct(id: string): Promise { const [product] = await db.select().from(products).where(eq(products.id, id)); return product || undefined; } async getAllProducts(): Promise { return await db.select() .from(products) .where(eq(products.isActive, true)) .orderBy(desc(products.createdAt)); } async getProductsByCategory(categoryId: string): Promise { return await db.select() .from(products) .where(and(eq(products.categoryId, categoryId), eq(products.isActive, true))) .orderBy(desc(products.createdAt)); } async getProductsBySeller(sellerId: string): Promise { return await db.select() .from(products) .where(and(eq(products.sellerId, sellerId), eq(products.isActive, true))) .orderBy(desc(products.createdAt)); } async getFeaturedProducts(limit = 8): Promise { return await db.select() .from(products) .where(eq(products.isActive, true)) .orderBy(desc(products.createdAt)) .limit(limit); } async getFeaturedProductsByCategories(): Promise { // Get all categories const allCategories = await this.getAllCategories(); const allFeaturedProducts: Product[] = []; // For each category, get up to 5 products for (const category of allCategories) { const categoryProducts = await db.select() .from(products) .where(and(eq(products.categoryId, category.id), eq(products.isActive, true))) .orderBy(desc(products.createdAt)) .limit(5); // If category has less than 5 products, we'll need to create more later allFeaturedProducts.push(...categoryProducts); } return allFeaturedProducts; } async searchProducts(query: string): Promise { return await db.select() .from(products) .where(and( eq(products.isActive, true), or( like(products.title, `%${query}%`), like(products.description, `%${query}%`) ) )) .orderBy(desc(products.createdAt)); } async createProduct(insertProduct: InsertProduct): Promise { const [product] = await db.insert(products).values([insertProduct]).returning(); return product; } async updateProduct(id: string, updateProduct: Partial): Promise { const [product] = await db.update(products) .set(updateProduct) .where(eq(products.id, id)) .returning(); return product; } async deleteProduct(id: string): Promise { await db.delete(products).where(eq(products.id, id)); } // Orders async getOrder(id: string): Promise { const [order] = await db.select().from(orders).where(eq(orders.id, id)); return order || undefined; } async getOrdersByUser(userId: string): Promise { return await db.select() .from(orders) .where(eq(orders.userId, userId)) .orderBy(desc(orders.createdAt)); } async getAllOrders(): Promise { return await db.select() .from(orders) .orderBy(desc(orders.createdAt)); } async getOrdersForSeller(productIds: string[]): Promise { if (productIds.length === 0) return []; // Find distinct orders that contain any of the seller's products const orderIdsResult = await db.selectDistinct({ orderId: orderItems.orderId }) .from(orderItems) .where(inArray(orderItems.productId, productIds)); const orderIds = orderIdsResult.map(row => row.orderId); if (orderIds.length === 0) return []; return await db.select() .from(orders) .where(inArray(orders.id, orderIds)) .orderBy(desc(orders.createdAt)); } async createOrder(insertOrder: InsertOrder): Promise { const [order] = await db.insert(orders).values([insertOrder]).returning(); return order; } async updateOrderStatus(id: string, status: string): Promise { const [order] = await db.update(orders) .set({ status }) .where(eq(orders.id, id)) .returning(); return order; } async updateOrderPaymentStatus(id: string, paymentStatus: string): Promise { const [order] = await db.update(orders) .set({ paymentStatus }) .where(eq(orders.id, id)) .returning(); return order; } async updateOrderStatusAndPayment(id: string, updates: { status?: string; paymentStatus?: string }): Promise { const [order] = await db.update(orders) .set(updates) .where(eq(orders.id, id)) .returning(); return order; } // Order Items async getOrderItems(orderId: string): Promise { return await db.select().from(orderItems).where(eq(orderItems.orderId, orderId)); } async createOrderItem(insertOrderItem: InsertOrderItem): Promise { const [orderItem] = await db.insert(orderItems).values([insertOrderItem]).returning(); return orderItem; } // Cart async getCartItems(userId: string): Promise { return await db.select() .from(cartItems) .where(eq(cartItems.userId, userId)) .orderBy(desc(cartItems.createdAt)); } async addToCart(insertCartItem: InsertCartItem): Promise { // Check if item already exists in cart const [existingItem] = await db.select() .from(cartItems) .where(and( eq(cartItems.userId, insertCartItem.userId), eq(cartItems.productId, insertCartItem.productId) )); if (existingItem) { // Update quantity const [updatedItem] = await db.update(cartItems) .set({ quantity: existingItem.quantity + (insertCartItem.quantity || 1) }) .where(eq(cartItems.id, existingItem.id)) .returning(); return updatedItem; } const [cartItem] = await db.insert(cartItems).values([insertCartItem]).returning(); return cartItem; } async updateCartItem(id: string, quantity: number): Promise { const [cartItem] = await db.update(cartItems) .set({ quantity }) .where(eq(cartItems.id, id)) .returning(); return cartItem; } async removeFromCart(id: string): Promise { await db.delete(cartItems).where(eq(cartItems.id, id)); } async clearCart(userId: string): Promise { await db.delete(cartItems).where(eq(cartItems.userId, userId)); } } export const storage = new DatabaseStorage();