fix: POST /products 500 — invalid unit FK on unrecognized items

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>
This commit is contained in:
dbastrikin
2026-03-19 23:05:19 +02:00
parent 9e7fc09f4b
commit 6861e5e754
2 changed files with 11 additions and 6 deletions

View File

@@ -248,10 +248,14 @@ class _ItemTileState extends State<_ItemTile> {
const SizedBox(width: 8), const SizedBox(width: 8),
widget.units.isEmpty widget.units.isEmpty
? const SizedBox(width: 48) ? const SizedBox(width: 48)
: DropdownButton<String>( : Builder(builder: (builderContext) {
value: widget.units.containsKey(widget.item.unit) // Reconcile item.unit with valid server codes so that the
? widget.item.unit // submitted value matches what the dropdown displays.
: widget.units.keys.first, if (!widget.units.containsKey(widget.item.unit)) {
widget.item.unit = widget.units.keys.first;
}
return DropdownButton<String>(
value: widget.item.unit,
underline: const SizedBox(), underline: const SizedBox(),
items: widget.units.entries items: widget.units.entries
.map((e) => DropdownMenuItem(value: e.key, child: Text(e.value))) .map((e) => DropdownMenuItem(value: e.key, child: Text(e.value)))
@@ -262,7 +266,8 @@ class _ItemTileState extends State<_ItemTile> {
widget.onChanged(); widget.onChanged();
} }
}, },
), );
}),
IconButton( IconButton(
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
onPressed: widget.onDelete, onPressed: widget.onDelete,

View File

@@ -39,7 +39,7 @@ class RecognizedItem {
return RecognizedItem( return RecognizedItem(
name: json['name'] as String? ?? '', name: json['name'] as String? ?? '',
quantity: (json['quantity'] as num?)?.toDouble() ?? 1.0, quantity: (json['quantity'] as num?)?.toDouble() ?? 1.0,
unit: json['unit'] as String? ?? 'шт', unit: json['unit'] as String? ?? 'pcs',
category: json['category'] as String? ?? 'other', category: json['category'] as String? ?? 'other',
confidence: (json['confidence'] as num?)?.toDouble() ?? 0.0, confidence: (json['confidence'] as num?)?.toDouble() ?? 0.0,
mappingId: json['mapping_id'] as String?, mappingId: json['mapping_id'] as String?,