groceries: add PLUS, Xenos and Amazing Oriental stores, is_food flag, PLUS EAN backfill
All checks were successful
Deploy production / deploy (push) Successful in 1m7s

This commit is contained in:
2026-10-25 17:17:53 +00:00
parent b23f7b3475
commit 3f30bb883f
14 changed files with 30444 additions and 38 deletions

View File

@@ -78,6 +78,8 @@ export const groceryGroups = groceriesSchema.table(
minPriceCents: integer('min_price_cents'),
promoCount: integer('promo_count').notNull().default(0),
imageUrl: text('image_url'),
/** True when any item is edible (refreshGroupStats); homeware-only groups are false. */
isFood: boolean('is_food').notNull().default(true),
searchText: text('search_text').notNull().default(''),
...timestamps
},
@@ -102,7 +104,7 @@ export const groceryItems = groceriesSchema.table(
storeId: integer('store_id')
.notNull()
.references(() => groceryStores.id, { onDelete: 'cascade' }),
storeProductId: text('store_product_id').notNull(), // AH webshopId, Jumbo SKU
storeProductId: text('store_product_id').notNull(), // AH webshopId, Jumbo/Plus/Xenos/AO SKU
name: text('name').notNull(),
brand: text('brand'),
sizeText: text('size_text'), // as the store prints it, e.g. "6 x 330 ml"
@@ -122,6 +124,8 @@ export const groceryItems = groceriesSchema.table(
imageUrl: text('image_url'),
url: text('url'),
available: boolean('available').notNull().default(true),
/** Edible (food/drink). False for drugstore, household and homeware (Xenos décor, woks…). */
isFood: boolean('is_food').notNull().default(true),
firstSeenAt: timestamptz('first_seen_at').notNull().defaultNow(),
lastSeenAt: timestamptz('last_seen_at').notNull().defaultNow(),
groupId: integer('group_id').references(() => groceryGroups.id, { onDelete: 'set null' }),