import type { ItemId, StoreItem } from "@/app/types"; import { CATALOG } from "./catalog"; // --------------------------------------------------------------------------- // PriceProvider: the single seam between "where prices come from" and the // rest of the app. The cost math only ever calls `getItem`. // // To use live retailer prices later: // 1. Fetch prices on the SERVER (a Server Action or route handler) so the // API key never reaches the browser. // 2. Build a snapshot `StoreItem[]` from the response. // 3. Pass `new SnapshotPriceProvider("Live grocery prices", snapshot)` into // the grocery/planner functions instead of `averageGroceryProvider`. // The math stays synchronous and testable because it works on a snapshot. // --------------------------------------------------------------------------- export interface PriceProvider { /** Shown in the UI so users know where prices came from. */ readonly label: string; getItem(id: ItemId): StoreItem | undefined; } export class SnapshotPriceProvider implements PriceProvider { private readonly byId: Map; constructor( readonly label: string, items: StoreItem[], ) { this.byId = new Map(items.map((item) => [item.id, item])); } getItem(id: ItemId): StoreItem | undefined { return this.byId.get(id); } } export const averageGroceryProvider: PriceProvider = new SnapshotPriceProvider( "Based on average grocery prices as of October 2026", CATALOG, );