- Rewrite receipt OCR prompt: completes truncated names, preserves fat%
and flavour attributes, extracts weight/volume from line, infers
typical package sizes for solid goods with quantity_confidence field
- Add quantity_confidence to RecognizedItem, EnrichedItem, and
ProductJobResultItem; propagate through item enricher and worker
- Replace per-item create loop with single POST /user-products/batch call
from RecognitionConfirmScreen
- Rebuild RecognitionConfirmScreen: amber qty border for low
quantity_confidence, tappable product name → catalog picker,
sort items by confidence, full L10n (no hardcoded strings)
- Add timestamps (HH:mm / d MMM HH:mm) to recent scan chips
- Show close-app hint on ProductJobWatchScreen (queued + processing)
- Refresh recentProductJobsProvider on watch screen init so new job
appears without a manual pull-to-refresh
- App-level WidgetsBindingObserver refreshes product and dish job lists
on resume, fixing stale lists after background/foreground transitions
- Add 9 new L10n keys across all 12 locales
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename catalog: ingredient/* → product/* (canonical_name, barcode, nutrition per 100g)
- Rename pantry: product/* → userproduct/* (user-owned items with expiry)
- Squash migrations into single 001_initial_schema.sql (clean-db baseline)
- product_categories: add English canonical name column; fix COALESCE in queries
- Remove product_translations: product names are stored in their original language
- Add default_unit_name to product API responses via unit_translations JOIN
- Add cmd/importoff: bulk import from OpenFoodFacts JSONL dump (COPY + ON CONFLICT)
- Diary: support product_id entries alongside dish_id (CHECK num_nonnulls = 1)
- Home: getLoggedCalories joins both recipes and catalog products
- Flutter: rename models/providers/services to match backend rename
- Flutter: add barcode scan flow for diary (mobile_scanner, product_portion_sheet)
- Flutter: localise 6 new keys across 12 languages (barcode scan, portion weight)
- Routes: GET /products/search, GET /products/barcode/{barcode}, /user-products
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs caused a FK constraint violation on products.unit:
1. RecognizedItem.fromJson fell back to 'шт' (Cyrillic, not a valid
units.code) when the AI returned a null unit — changed to 'pcs'.
2. The unit dropdown in RecognitionConfirmScreen displayed units.keys.first
for invalid units but never updated item.unit, so the invalid value was
still submitted. Added a reconcile step in build() that syncs item.unit
to units.keys.first whenever the stored value is not in the valid set.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add units + unit_translations tables with FK constraints on products and ingredient_mappings
- Normalize products.unit from Russian strings (г, кг) to English codes (g, kg)
- Load units at startup (in-memory registry) and serve via GET /units (language-aware)
- Replace hardcoded _units lists and _mapUnit() functions in Flutter with unitsProvider FutureProvider
- Re-fetches automatically when language changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>