#104 — Bug — Barcode-Scan fragt bei unbekanntem Produkt nicht nach Kategorie, erneutes Scannen erhöht Menge statt es abzuschalten #107

Closed
opened 2026-08-18 13:14:06 +02:00 by lena · 0 comments
lena commented 2026-08-18 13:14:06 +02:00 (Migrated from git.butzei.de)

Story: Bug — Barcode-Scan fragt bei unbekanntem Produkt nicht nach Kategorie, erneutes Scannen erhöht Menge statt es abzuschalten

As a Nutzer der Einkaufsliste,
I want to beim Scannen eines unbekannten Barcodes nach der Kategorie gefragt zu werden, und beim
erneuten Scannen desselben Barcodes die Menge erhöht statt das Produkt von der Liste zu entfernen,
so that neu gescannte Produkte sofort richtig einsortiert sind und mehrfaches Scannen (z. B. mehrere
gleiche Packungen) korrekt gezählt wird statt das Produkt versehentlich abzuschalten.

Klärung vom 2026-08-08 (PO-Rückfrage beantwortet): Erneutes Scannen eines bereits auf der Liste
aktiven Produkts soll die Menge erhöhen (nicht abhaken/deaktivieren, nicht duplizieren).

Verifiziert im Code:

  • ScanShoppingProductBarcodeCommandHandler: Trifft der Barcode ein existierendes, bereits aktives
    Produkt, wird es aktuell deaktiviert (existing.IsOnList ? deactivateHandler : activateHandler) —
    das ist das beobachtete "verschwindet von der Liste".
  • Bei unbekanntem Barcode + FallbackName ruft der Handler CreateShoppingProductCommandHandler ohne
    explizite CategoryId auf; dieser versucht zwar die globale Kategorie-Wissensbasis
    (ShoppingCategoryResolver.ResolveFromKnowledgeBase), aber wenn der Produktname dort unbekannt ist,
    bleibt das Produkt kategorielos ("Sonstiges") — ShoppingBarcodeScanDialog.tsx fragt in diesem Fall
    aktuell nie nach einer Kategorie.

Acceptance criteria:

  • Trifft ein Scan (Kamera oder Zahlen-Eingabe) auf ein bereits aktives Produkt derselben Liste, wird
    dessen Menge um 1 erhöht (rein numerische Mengen; bei nicht-numerischer oder fehlender Menge greift
    dieselbe Fallback-Logik wie bei #90's Mengen-Konsolidierung), statt es zu deaktivieren.
  • Trifft ein Scan auf ein inaktives (aber schon bekanntes) Produkt derselben Liste, wird es wie bisher
    aktiviert.
  • Trifft ein Scan auf einen unbekannten Barcode und wird — nach Eingabe eines Namens — kein passender
    Eintrag in der globalen Kategorie-Wissensbasis gefunden, fragt der Dialog vor dem Anlegen nach einer
    Kategorie (analog zum Kategorie-Picker aus Smart-Add), statt das Produkt kommentarlos in "Sonstiges"
    einzusortieren.
  • Wird die Kategorie automatisch aus der Wissensbasis aufgelöst, entfällt die Nachfrage (kein Bruch mit
    Story #103's "keine überflüssige Nachfrage, wenn das System es schon weiß").

Delivered 2026-08-08:

  • ScanShoppingProductBarcodeCommandHandler: matching an existing product now always (re)activates via
    ActivateShoppingProductCommand; the deactivate-on-rescan branch and its IHandler<DeactivateShoppingProductCommand,...>
    dependency were removed entirely. A newly-added IncrementQuantity helper bumps a purely-numeric quantity
    by one (missing quantity → "2"), leaves non-numeric quantities untouched, and is skipped entirely when
    reactivating an inactive product (quantity carried over unchanged).
  • ShoppingBarcodeScanDialog.tsx gained the same category-picker step #103 added to SmartAddInput: if the
    product returned after typing a fallback name has no categoryId, the dialog shows the category list
    instead of closing, and picking one calls MoveShoppingProductCommand on the already-created product
    (no duplicate). ShoppingListPage.tsx now passes categories/products through to the dialog.
  • Backend: 4 new/replaced tests in ScanShoppingProductBarcodeCommandHandlerTests.cs (increment from no
    quantity, increment from numeric, non-numeric left untouched, activation-only leaves quantity unchanged).
    Frontend: 3 new tests in ShoppingBarcodeScanDialog.test.tsx for the category-picker step.
  • Manually verified live against the running dev app: unknown barcode with an unresolvable fallback name
    triggers the category picker; picking a category moves rather than duplicates the product; rescanning an
    active product increments its quantity across repeated scans (null → "2" → "3") instead of toggling it
    off the list.
  • Lesson learned: removing a constructor parameter is a hot-reload "rude edit" that dotnet watch can
    silently fail to auto-restart from when run backgrounded/non-interactively — a stale process kept serving
    pre-fix behavior during manual verification. Worked around by killing the stale dotnet/CqsTodo.WebApi
    processes and restarting dotnet watch fresh; worth remembering for future backend signature changes.

Out of scope for this story:

  • Änderungen an der Wissensbasis-Auflösung selbst (siehe #103).
  • Kamera-/Scanner-Hardware-Verhalten — unverändert, nur der Anwendungsfall "gleicher Barcode zweimal".
# Story: Bug — Barcode-Scan fragt bei unbekanntem Produkt nicht nach Kategorie, erneutes Scannen erhöht Menge statt es abzuschalten **As a** Nutzer der Einkaufsliste, **I want to** beim Scannen eines unbekannten Barcodes nach der Kategorie gefragt zu werden, und beim erneuten Scannen desselben Barcodes die Menge erhöht statt das Produkt von der Liste zu entfernen, **so that** neu gescannte Produkte sofort richtig einsortiert sind und mehrfaches Scannen (z. B. mehrere gleiche Packungen) korrekt gezählt wird statt das Produkt versehentlich abzuschalten. **Klärung vom 2026-08-08 (PO-Rückfrage beantwortet):** Erneutes Scannen eines bereits auf der Liste aktiven Produkts soll die Menge erhöhen (nicht abhaken/deaktivieren, nicht duplizieren). **Verifiziert im Code:** - `ScanShoppingProductBarcodeCommandHandler`: Trifft der Barcode ein existierendes, bereits aktives Produkt, wird es aktuell **deaktiviert** (`existing.IsOnList ? deactivateHandler : activateHandler`) — das ist das beobachtete "verschwindet von der Liste". - Bei unbekanntem Barcode + `FallbackName` ruft der Handler `CreateShoppingProductCommandHandler` ohne explizite `CategoryId` auf; dieser versucht zwar die globale Kategorie-Wissensbasis (`ShoppingCategoryResolver.ResolveFromKnowledgeBase`), aber wenn der Produktname dort unbekannt ist, bleibt das Produkt kategorielos ("Sonstiges") — `ShoppingBarcodeScanDialog.tsx` fragt in diesem Fall aktuell nie nach einer Kategorie. **Acceptance criteria:** - [x] Trifft ein Scan (Kamera oder Zahlen-Eingabe) auf ein bereits aktives Produkt derselben Liste, wird dessen Menge um 1 erhöht (rein numerische Mengen; bei nicht-numerischer oder fehlender Menge greift dieselbe Fallback-Logik wie bei `#90`'s Mengen-Konsolidierung), statt es zu deaktivieren. - [x] Trifft ein Scan auf ein inaktives (aber schon bekanntes) Produkt derselben Liste, wird es wie bisher aktiviert. - [x] Trifft ein Scan auf einen unbekannten Barcode und wird — nach Eingabe eines Namens — kein passender Eintrag in der globalen Kategorie-Wissensbasis gefunden, fragt der Dialog vor dem Anlegen nach einer Kategorie (analog zum Kategorie-Picker aus Smart-Add), statt das Produkt kommentarlos in "Sonstiges" einzusortieren. - [x] Wird die Kategorie automatisch aus der Wissensbasis aufgelöst, entfällt die Nachfrage (kein Bruch mit Story `#103`'s "keine überflüssige Nachfrage, wenn das System es schon weiß"). **Delivered 2026-08-08:** - `ScanShoppingProductBarcodeCommandHandler`: matching an existing product now always (re)activates via `ActivateShoppingProductCommand`; the deactivate-on-rescan branch and its `IHandler<DeactivateShoppingProductCommand,...>` dependency were removed entirely. A newly-added `IncrementQuantity` helper bumps a purely-numeric quantity by one (missing quantity → `"2"`), leaves non-numeric quantities untouched, and is skipped entirely when reactivating an inactive product (quantity carried over unchanged). - `ShoppingBarcodeScanDialog.tsx` gained the same category-picker step `#103` added to `SmartAddInput`: if the product returned after typing a fallback name has no `categoryId`, the dialog shows the category list instead of closing, and picking one calls `MoveShoppingProductCommand` on the already-created product (no duplicate). `ShoppingListPage.tsx` now passes `categories`/`products` through to the dialog. - Backend: 4 new/replaced tests in `ScanShoppingProductBarcodeCommandHandlerTests.cs` (increment from no quantity, increment from numeric, non-numeric left untouched, activation-only leaves quantity unchanged). Frontend: 3 new tests in `ShoppingBarcodeScanDialog.test.tsx` for the category-picker step. - Manually verified live against the running dev app: unknown barcode with an unresolvable fallback name triggers the category picker; picking a category moves rather than duplicates the product; rescanning an active product increments its quantity across repeated scans (null → "2" → "3") instead of toggling it off the list. - Lesson learned: removing a constructor parameter is a hot-reload "rude edit" that `dotnet watch` can silently fail to auto-restart from when run backgrounded/non-interactively — a stale process kept serving pre-fix behavior during manual verification. Worked around by killing the stale `dotnet`/`CqsTodo.WebApi` processes and restarting `dotnet watch` fresh; worth remembering for future backend signature changes. **Out of scope for this story:** - Änderungen an der Wissensbasis-Auflösung selbst (siehe `#103`). - Kamera-/Scanner-Hardware-Verhalten — unverändert, nur der Anwendungsfall "gleicher Barcode zweimal".
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
robert/todo#107
No description provided.