feat: improved receipt recognition, batch product add, and scan UX

- 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>
This commit is contained in:
dbastrikin
2026-03-26 23:09:57 +02:00
parent b2bdcbae6f
commit 5c5ed25e5b
38 changed files with 1221 additions and 115 deletions

View File

@@ -1161,6 +1161,60 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Added to pantry'**
String get productAddedToShelf;
/// No description provided for @recognitionFoundProducts.
///
/// In en, this message translates to:
/// **'Found {count} products'**
String recognitionFoundProducts(int count);
/// No description provided for @recognitionAddAll.
///
/// In en, this message translates to:
/// **'Add all'**
String get recognitionAddAll;
/// No description provided for @recognitionAddToStock.
///
/// In en, this message translates to:
/// **'Add to pantry'**
String get recognitionAddToStock;
/// No description provided for @recognitionAdded.
///
/// In en, this message translates to:
/// **'Added {count} products'**
String recognitionAdded(int count);
/// No description provided for @recognitionProductsFailed.
///
/// In en, this message translates to:
/// **'Failed to add products'**
String get recognitionProductsFailed;
/// No description provided for @recognitionEmpty.
///
/// In en, this message translates to:
/// **'No products found'**
String get recognitionEmpty;
/// No description provided for @recognitionConfidence.
///
/// In en, this message translates to:
/// **'{percent}% confidence'**
String recognitionConfidence(int percent);
/// No description provided for @recognitionReplaceProduct.
///
/// In en, this message translates to:
/// **'Replace product'**
String get recognitionReplaceProduct;
/// No description provided for @scanJobCloseHint.
///
/// In en, this message translates to:
/// **'You can close the app — this scan will appear in Recent Scans on the Products screen'**
String get scanJobCloseHint;
}
class _AppLocalizationsDelegate