import { boolean, date, doublePrecision, index, pgTable, text, uuid, integer, } from "drizzle-orm/pg-core"; import { createdAt, unitEnum } from "./_shared.js"; import { households } from "./households.js"; import { canonicalIngredients } from "./ingredients.js"; import { products } from "./products.js"; /** Kvitton (spec §12): lager + budget + prishistorik + matsvinnsvärde. */ export const receipts = pgTable( "receipts", { id: uuid("id").primaryKey().defaultRandom(), householdId: uuid("household_id") .notNull() .references(() => households.id, { onDelete: "cascade" }), storeName: text("store_name"), purchaseDate: date("purchase_date"), totalMinor: integer("total_minor"), discountMinor: integer("discount_minor"), imageUrl: text("image_url"), scanJobId: uuid("scan_job_id"), status: text("status").notNull().default("pending"), createdAt: createdAt(), }, (t) => [index("receipts_household_idx").on(t.householdId, t.purchaseDate)], ); export const receiptLines = pgTable( "receipt_lines", { id: uuid("id").primaryKey().defaultRandom(), receiptId: uuid("receipt_id") .notNull() .references(() => receipts.id, { onDelete: "cascade" }), rawText: text("raw_text").notNull(), normalizedName: text("normalized_name"), canonicalIngredientId: text("canonical_ingredient_id").references( () => canonicalIngredients.id, ), productId: uuid("product_id").references(() => products.id), quantity: doublePrecision("quantity"), unit: unitEnum("unit"), unitPriceMinor: integer("unit_price_minor"), totalPriceMinor: integer("total_price_minor"), confidence: doublePrecision("confidence").notNull().default(0), verifiedByUser: boolean("verified_by_user").notNull().default(false), addedToInventory: boolean("added_to_inventory").notNull().default(false), }, (t) => [index("receipt_lines_receipt_idx").on(t.receiptId)], ); /** Prishistorik per ingrediens/produkt – grund för budget och prognoser (spec §12, §26). */ export const priceObservations = pgTable( "price_observations", { id: uuid("id").primaryKey().defaultRandom(), canonicalIngredientId: text("canonical_ingredient_id").references( () => canonicalIngredients.id, ), productId: uuid("product_id").references(() => products.id), storeName: text("store_name"), priceMinor: integer("price_minor").notNull(), quantity: doublePrecision("quantity"), unit: unitEnum("unit"), pricePerKgMinor: integer("price_per_kg_minor"), observedAt: date("observed_at").notNull(), source: text("source").notNull().default("receipt"), createdAt: createdAt(), }, (t) => [index("price_observations_ingredient_idx").on(t.canonicalIngredientId, t.observedAt)], );