{"repo": "arshad1416/grocery-app", "files": {"GroceryApp/src/services/BARCODE_FEATURE.md": {"f11a4b3a2b118d37a368e0a3180b37220a7940c2": {"t": 1785596356.2584512, "n": 7136, "h": "9d904c2f73bb380b", "c": "# Barcode Scanner + Product Database Feature\n\n## What Was Built\n\n### New Files\n\n| File | Purpose |\n|------|---------|\n| `src/types/product.ts` | ProductInfo, ScanResult, NewProductSubmission types |\n| `src/services/productCache.ts` | In-memory session cache (max 200 items) |\n| `src/services/catalogClient.ts` | Client for the relay's `/api/catalog/*` endpoints (no DB credential) |\n| `relay-server/catalog/turso-client.js` | **Relay-side** Turso client — the only place a token exists |\n| `relay-server/catalog/catalog-server.js` | The six fixed catalog operations; no SQL passthrough |\n| `relay-server/catalog/migrations.js` | SQL migrations for `products` + `product_prices` tables |\n| `src/services/productLookup.ts` | Lookup chain: cache → relay catalog → Open Food Facts → USDA |\n| `src/services/aiCleanup.ts` | Heuristic + AI product name normalization (MiMo via OpenCode Go) |\n| `src/components/BarcodeScannerScreen.tsx` | Full-screen barcode scanner (expo-camera, EAN-13/UPC) |\n\n### Modified Files\n\n| File | Change |\n|------|--------|\n| `src/types/index.ts` | Added `tursoEnabled` to AppSettings (catalog on/off) |\n| `App.tsx` | No database client is initialised — catalog calls go through the relay |\n| `src/screens/AddItemSheet.tsx` | Scan button, scanner overlay, lookup, new-product form |\n\n---\n\n## What You Need to Do to Activate\n\n### 1. Install expo-camera (barcode scanning)\n\n```bash\nnpx expo install expo-camera\n```\n\nThis is the same library already used dynamically in `CameraScanner.tsx`. Installing it makes the real camera available.\n\n### 2. Create a Turso database (operator step — never the app)\n\n```bash\n# Install Turso CLI\ncurl -sSfL https://get.turso.tech/install.sh | bash\n\n# Login\nturso auth login\n\n# Create a database for PantryRun products\nturso db create pantryrun-products\n\n# Get the database URL + token\nturso db show pantryrun-products --url # → https://pantryrun-products-.turso.io\nturso db tokens create pantryrun-products --read-only # prefer read-only where the product allows\n\n# Initialize the schema\nturso db shell pantryrun-products < schema.sql\n```\n\n### 3. Apply the schema\n\nThe statements below also live in `relay-server/catalog/migrations.js`. Run\nthem against your Turso DB to create the tables:\n\n```sql\nCREATE TABLE IF NOT EXISTS products (\n barcode TEXT PRIMARY KEY,\n product_name TEXT NOT NULL,\n brand TEXT,\n category TEXT,\n image_url TEXT,\n quantity_label TEXT,\n source TEXT NOT NULL DEFAULT 'user',\n raw_input TEXT,\n ai_cleaned INTEGER DEFAULT 0,\n first_seen_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS product_prices (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n barcode TEXT NOT NULL REFERENCES products(barcode),\n price REAL NOT NULL,\n store_name TEXT NOT NULL,\n store_id TEXT NOT NULL,\n quantity REAL,\n unit TEXT,\n scanned_at TEXT NOT NULL DEFAULT (datetime('now')),\n submitted_by TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_prices_barcode ON product_prices(barcode);\nCREATE INDEX IF NOT EXISTS idx_prices_scanned ON product_prices(scanned_at);\nCREATE INDEX IF NOT EXISTS idx_products_category ON products(category);\n```\n\n### 4. Get a USDA API key (free)\n\nSign up at https://fdc.nal.usda.gov/api-key-signup.html — instant, no wait.\n\nThen add to `.env`:\n```\nEXPO_PUBLIC_USDA_API_KEY=your_key_here\nEXPO_PUBLIC_AI_CLEANUP_URL=https://opencode.ai/zen/go/v1/chat/completions\nEXPO_PUBLIC_AI_CLEANUP_KEY=your_opencode_go_key\n```\n\n### 5. Set the Turso credentials on the RELAY — never in the app\n\n```bash\n# On the relay host only. These never appear in this repository, in a .env\n# that is committed, or in any EXPO_PUBLIC_* variable.\nTURSO_URL=https://pantryrun-products-.turso.io\nTURSO_TOKEN=\n```\n\n⚠️ **Do not add a Turso URL or token field to SettingsScreen, and do not\nintroduce an `EXPO_PUBLIC_*` variable carrying either.** An earlier build did\nboth. Expo inlines\nevery `EXPO_PUBLIC_*` value into the JS bundle at build time, and a value in\napp settings ends up in the bundle or on the device either way — both are\nextractable from a shipped APK with `unzip` and `strings`. A read-write token\ncommitted this way is why the credentials in this repo's history had to be\nrevoked. See `GOAL_PROMPT_NOTES.md`.\n\n---\n\n## Architecture Diagram\n\n```\nUser scans barcode (expo-camera → ML Kit)\n │\n ▼\nBarcodeScannerScreen ── onScan(barcode) ──► AddItemSheet\n │\n ▼\n lookupProduct(barcode)\n │\n ┌──────────┼──────────┐\n ▼ ▼ ▼\n In-memory Relay Open Food Facts\n cache /api/catalog (free, no key)\n (session (your products) │\n only) ▼\n USDA\n (free fallback)\n │\n ┌──────────┘\n ▼\n Found? ──Yes──► Pre-fill form\n │\n No\n │\n ▼\n Show \"New Product\"\n form → user types name\n │\n ▼\n submitNewProduct()\n │\n ▼\n AI Cleanup → POST /api/catalog/product-submit\n (heuristic + MiMo) (relay writes to Turso)\n```\n\n## Edge Cases Handled\n\n1. **Camera not available** → falls back to manual barcode entry (type digits)\n2. **No network** → cache hit works, otherwise shows error\n3. **Relay catalog unavailable** → lookup still works (OFF + USDA), save disabled\n4. **Product not in any DB** → new product form, user enters name\n5. **All-caps names** → AI cleanup normalizes to title case\n6. **Rapid scanning** → `scanned` flag prevents duplicate triggers\n7. **Non-retail barcodes** → regex validates 8-14 digit codes only\n\n## What's Not Built (For Your Next Session)\n\n1. ~~Turso settings UI in SettingsScreen (URL + token fields)~~ — **deliberately\n never building this.** The app holds no database credential; see step 5.\n2. **Schema auto-migration** on relay start (the `migrations` table check)\n3. **AI cleanup server endpoint** (currently configured to hit OpenCode Go API directly — a Cloudflare Worker wrapper would be cleaner)\n4. **Price history view** in ItemEditScreen (data is stored, UI not wired)\n5. **expo-camera install** — you need to `npx expo install expo-camera`\n6. **Turso database creation** — via CLI, by the relay operator\n"}}}}