import { Database } from "bun:sqlite"; import { unlink } from "node:fs/promises"; import { drizzle } from "drizzle-orm/bun-sqlite"; import { migrate } from "drizzle-orm/bun-sqlite/migrator"; import * as schema from "../src/db/schema"; const DB_PATH = "./e2e/test.db"; export async function seedTestDatabase() { // Remove old test DB if it exists try { await unlink(DB_PATH); } catch { // File doesn't exist, that's fine } const sqlite = new Database(DB_PATH); sqlite.run("PRAGMA journal_mode = WAL"); sqlite.run("PRAGMA foreign_keys = ON"); const db = drizzle(sqlite, { schema }); migrate(db, { migrationsFolder: "./drizzle" }); // ── Categories ── const [uncategorized] = db .insert(schema.categories) .values({ name: "Uncategorized", icon: "package" }) .returning() .all(); const [shelter] = db .insert(schema.categories) .values({ name: "Shelter", icon: "tent" }) .returning() .all(); const [sleep] = db .insert(schema.categories) .values({ name: "Sleep System", icon: "moon" }) .returning() .all(); const [cook] = db .insert(schema.categories) .values({ name: "Cook Kit", icon: "flame" }) .returning() .all(); // ── Items ── const tent = db .insert(schema.items) .values({ name: "Zpacks Duplex", weightGrams: 539, priceCents: 67900, categoryId: shelter.id, notes: "DCF shelter, 2-person", }) .returning() .get(); db.insert(schema.items) .values({ name: "Borah Gear Tarp", weightGrams: 156, priceCents: 11000, categoryId: shelter.id, }) .run(); const quilt = db .insert(schema.items) .values({ name: "Enlightened Equipment Enigma 20", weightGrams: 595, priceCents: 34000, categoryId: sleep.id, notes: "20F quilt", }) .returning() .get(); const pad = db .insert(schema.items) .values({ name: "Therm-a-Rest NeoAir XLite", weightGrams: 354, priceCents: 20999, categoryId: sleep.id, }) .returning() .get(); const stove = db .insert(schema.items) .values({ name: "BRS-3000T Stove", weightGrams: 25, priceCents: 2000, categoryId: cook.id, }) .returning() .get(); db.insert(schema.items) .values({ name: "Toaks 750ml Pot", weightGrams: 103, priceCents: 3000, categoryId: cook.id, }) .run(); // ── Active Thread with 3 Candidates ── const activeThread = db .insert(schema.threads) .values({ name: "New Backpack", status: "active", categoryId: uncategorized.id, }) .returning() .get(); db.insert(schema.threadCandidates) .values({ threadId: activeThread.id, name: "ULA Circuit", weightGrams: 1077, priceCents: 27500, categoryId: uncategorized.id, pros: "Great hip belt\nLarge capacity", cons: "Heavier than competitors", sortOrder: 1000, status: "researching", }) .run(); db.insert(schema.threadCandidates) .values({ threadId: activeThread.id, name: "Gossamer Gear Mariposa", weightGrams: 737, priceCents: 28500, categoryId: uncategorized.id, pros: "Very lightweight\nGood ventilation", cons: "Smaller hip belt pockets", sortOrder: 2000, status: "researching", }) .run(); db.insert(schema.threadCandidates) .values({ threadId: activeThread.id, name: "Granite Gear Crown2 38", weightGrams: 850, priceCents: 18000, categoryId: uncategorized.id, sortOrder: 3000, status: "ordered", }) .run(); // ── Resolved Thread ── const resolvedThread = db .insert(schema.threads) .values({ name: "Camp Stove", status: "resolved", categoryId: cook.id, resolvedCandidateId: 1, }) .returning() .get(); db.insert(schema.threadCandidates) .values({ threadId: resolvedThread.id, name: "BRS-3000T", weightGrams: 25, priceCents: 2000, categoryId: cook.id, sortOrder: 1000, status: "arrived", }) .run(); // ── Setup with Items ── const setup = db .insert(schema.setups) .values({ name: "Weekend Overnighter" }) .returning() .get(); db.insert(schema.setupItems) .values([ { setupId: setup.id, itemId: tent.id, classification: "base" }, { setupId: setup.id, itemId: quilt.id, classification: "base" }, { setupId: setup.id, itemId: pad.id, classification: "base" }, { setupId: setup.id, itemId: stove.id, classification: "consumable" }, ]) .run(); // ── API Key for E2E Authentication ── const rawKey = "e2e-test-api-key-for-gearbox-testing"; const keyHash = await Bun.password.hash(rawKey); const keyPrefix = rawKey.slice(0, 8); db.insert(schema.apiKeys) .values({ name: "E2E Test Key", keyHash, keyPrefix }) .run(); // ── Settings ── db.insert(schema.settings) .values([ { key: "weightUnit", value: "g" }, { key: "currency", value: "USD" }, { key: "onboardingComplete", value: "true" }, ]) .run(); sqlite.close(); console.log("E2E test database seeded at", DB_PATH); }