import { eq, sql } from "drizzle-orm"; import { db as prodDb } from "../../db/index.ts"; import { categories, items, setupItems, setups } from "../../db/schema.ts"; import type { CreateSetup, UpdateSetup } from "../../shared/types.ts"; type Db = typeof prodDb; export function createSetup(db: Db = prodDb, data: CreateSetup) { return db.insert(setups).values({ name: data.name }).returning().get(); } export function getAllSetups(db: Db = prodDb) { return db .select({ id: setups.id, name: setups.name, createdAt: setups.createdAt, updatedAt: setups.updatedAt, itemCount: sql`COALESCE(( SELECT COUNT(*) FROM setup_items WHERE setup_items.setup_id = setups.id ), 0)`.as("item_count"), totalWeight: sql`COALESCE(( SELECT SUM(items.weight_grams) FROM setup_items JOIN items ON items.id = setup_items.item_id WHERE setup_items.setup_id = setups.id ), 0)`.as("total_weight"), totalCost: sql`COALESCE(( SELECT SUM(items.price_cents) FROM setup_items JOIN items ON items.id = setup_items.item_id WHERE setup_items.setup_id = setups.id ), 0)`.as("total_cost"), }) .from(setups) .all(); } export function getSetupWithItems(db: Db = prodDb, setupId: number) { const setup = db.select().from(setups).where(eq(setups.id, setupId)).get(); if (!setup) return null; const itemList = db .select({ id: items.id, name: items.name, weightGrams: items.weightGrams, priceCents: items.priceCents, categoryId: items.categoryId, notes: items.notes, productUrl: items.productUrl, imageFilename: items.imageFilename, createdAt: items.createdAt, updatedAt: items.updatedAt, categoryName: categories.name, categoryIcon: categories.icon, }) .from(setupItems) .innerJoin(items, eq(setupItems.itemId, items.id)) .innerJoin(categories, eq(items.categoryId, categories.id)) .where(eq(setupItems.setupId, setupId)) .all(); return { ...setup, items: itemList }; } export function updateSetup( db: Db = prodDb, setupId: number, data: UpdateSetup, ) { const existing = db .select({ id: setups.id }) .from(setups) .where(eq(setups.id, setupId)) .get(); if (!existing) return null; return db .update(setups) .set({ name: data.name, updatedAt: new Date() }) .where(eq(setups.id, setupId)) .returning() .get(); } export function deleteSetup(db: Db = prodDb, setupId: number) { const existing = db .select({ id: setups.id }) .from(setups) .where(eq(setups.id, setupId)) .get(); if (!existing) return false; db.delete(setups).where(eq(setups.id, setupId)).run(); return true; } export function syncSetupItems( db: Db = prodDb, setupId: number, itemIds: number[], ) { return db.transaction((tx) => { // Delete all existing items for this setup tx.delete(setupItems).where(eq(setupItems.setupId, setupId)).run(); // Re-insert new items for (const itemId of itemIds) { tx.insert(setupItems).values({ setupId, itemId }).run(); } }); } export function removeSetupItem( db: Db = prodDb, setupId: number, itemId: number, ) { db.delete(setupItems) .where( sql`${setupItems.setupId} = ${setupId} AND ${setupItems.itemId} = ${itemId}`, ) .run(); }