Files
Ghost_Kitchen/src/db/seed.ts
T
lukasandClaude Opus 5.5 edd34a00a7 Collect ready items from pickup boxes instead of "I picked this up"
A ready Order Item now gets the lowest-numbered free Pickup Box (or waits
for one to free up), shown as "Pickup box N" on its status. The customer
opens the box from their order and closes it again; closing marks the
item picked up and hands the box to the next waiting item.

On the order card the box button comes first, full width on mobile, with
a padlock that lifts on open and snaps shut before the button collapses
away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 11:31:23 +02:00

202 lines
5.5 KiB
TypeScript

import type { NodePgDatabase } from 'drizzle-orm/node-postgres'
import * as schema from '#/db/schema.ts'
// Sample Brand/menu/hardware data for local dev and as the shared fixture
// tests seed against. Specific menu items are explicitly out of scope for
// the ordering spec — Pizza/Burger here are illustrative, not final content.
export const seedGhostKitchen = async (db: NodePgDatabase<typeof schema>) => {
const [brand] = await db
.insert(schema.brands)
.values({ name: 'Ghost Kitchen' })
.returning()
const [prepTag] = await db
.insert(schema.machineTags)
.values({ name: 'prep' })
.returning()
const [ovenTag] = await db
.insert(schema.machineTags)
.values({ name: 'oven' })
.returning()
const [grillTag] = await db
.insert(schema.machineTags)
.values({ name: 'grill' })
.returning()
const [assemblyTag] = await db
.insert(schema.machineTags)
.values({ name: 'assembly' })
.returning()
const [prep1] = await db
.insert(schema.machines)
.values({ name: 'Prep Station 1', machineTagId: prepTag.id })
.returning()
const [oven1] = await db
.insert(schema.machines)
.values({ name: 'Oven 1', machineTagId: ovenTag.id })
.returning()
const [grill1] = await db
.insert(schema.machines)
.values({ name: 'Grill 1', machineTagId: grillTag.id })
.returning()
const [assembly1] = await db
.insert(schema.machines)
.values({ name: 'Assembly Station 1', machineTagId: assemblyTag.id })
.returning()
const pickupBoxes = await db
.insert(schema.pickupBoxes)
.values([1, 2, 3, 4].map((number) => ({ number })))
.returning()
const [pizza] = await db
.insert(schema.menuItems)
.values({
brandId: brand.id,
name: 'Pizza',
description: 'Classic oven-baked pizza.',
priceCents: 1299,
})
.returning()
await db.insert(schema.menuItemSteps).values([
{
menuItemId: pizza.id,
sequence: 1,
name: 'Flattening dough',
machineTagId: prepTag.id,
estimatedDurationSeconds: 30,
},
{
menuItemId: pizza.id,
sequence: 2,
name: 'Spreading sauce',
machineTagId: prepTag.id,
estimatedDurationSeconds: 20,
},
{
menuItemId: pizza.id,
sequence: 3,
name: 'Adding toppings',
machineTagId: prepTag.id,
estimatedDurationSeconds: 30,
},
{
menuItemId: pizza.id,
sequence: 4,
name: 'Baking in the oven',
machineTagId: ovenTag.id,
estimatedDurationSeconds: 600,
},
{
menuItemId: pizza.id,
sequence: 5,
name: 'Slicing',
machineTagId: assemblyTag.id,
estimatedDurationSeconds: 20,
},
{
menuItemId: pizza.id,
sequence: 6,
name: 'Packaging',
machineTagId: assemblyTag.id,
estimatedDurationSeconds: 20,
},
])
const pizzaOptions = await db
.insert(schema.menuItemOptions)
.values([
{ menuItemId: pizza.id, name: 'Extra cheese', priceDeltaCents: 150 },
{ menuItemId: pizza.id, name: 'No onions', priceDeltaCents: 0 },
{ menuItemId: pizza.id, name: 'Extra sauce', priceDeltaCents: 0 },
])
.returning()
const [burger] = await db
.insert(schema.menuItems)
.values({
brandId: brand.id,
name: 'Burger',
description: 'Grilled burger, assembled to order.',
priceCents: 999,
})
.returning()
await db.insert(schema.menuItemSteps).values([
{
menuItemId: burger.id,
sequence: 1,
name: 'Grilling patty',
machineTagId: grillTag.id,
estimatedDurationSeconds: 240,
},
{
menuItemId: burger.id,
sequence: 2,
name: 'Assembling burger',
machineTagId: assemblyTag.id,
estimatedDurationSeconds: 90,
},
])
const burgerOptions = await db
.insert(schema.menuItemOptions)
.values([
{ menuItemId: burger.id, name: 'Extra cheese', priceDeltaCents: 100 },
{ menuItemId: burger.id, name: 'No pickles', priceDeltaCents: 0 },
{ menuItemId: burger.id, name: 'Extra patty', priceDeltaCents: 250 },
])
.returning()
const allergens = await db
.insert(schema.allergens)
.values([
{ name: 'Gluten' },
{ name: 'Dairy' },
{ name: 'Eggs' },
{ name: 'Soy' },
{ name: 'Peanuts' },
{ name: 'Tree nuts' },
{ name: 'Sesame' },
])
.returning()
const allergenByName = Object.fromEntries(
allergens.map((allergen) => [allergen.name, allergen]),
)
await db.insert(schema.menuItemAllergens).values([
{ menuItemId: pizza.id, allergenId: allergenByName['Gluten'].id },
{ menuItemId: pizza.id, allergenId: allergenByName['Dairy'].id },
{ menuItemId: burger.id, allergenId: allergenByName['Gluten'].id },
{ menuItemId: burger.id, allergenId: allergenByName['Sesame'].id },
])
return {
brand,
machineTags: {
prep: prepTag,
oven: ovenTag,
grill: grillTag,
assembly: assemblyTag,
},
machines: { prep1, oven1, grill1, assembly1 },
pickupBoxes,
menuItems: { pizza, burger },
menuItemOptions: { pizza: pizzaOptions, burger: burgerOptions },
allergens,
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
const { config } = await import('dotenv')
config({ path: ['.env.local', '.env'] })
const { drizzle } = await import('drizzle-orm/node-postgres')
const db = drizzle(process.env.DATABASE_URL!, { schema })
await seedGhostKitchen(db)
console.log('Seeded Ghost Kitchen sample data.')
process.exit(0)
}