Vorratsschrank — Scan-Station zur Vollbild-Aktivitäts-Ansicht mit Korrektur-Aktionen ausbauen #172
Labels
No labels
priority/could
priority/must
priority/should
priority/wont
status/blocked
status/claimed
status/done-migrated
type/bug
type/feature
type/infra
type/tech-debt
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
robert/todo#172
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Story: Vorratsschrank — Scan-Station zur Vollbild-Aktivitäts-Ansicht mit Korrektur-Aktionen ausbauen
As a Nutzer, der Einkäufe in die Speisekammer einscannt,
I want to eine einzige Vollbild-Ansicht, die mir den chronologischen Verlauf zeigt, direktes Scannen (Kamera oder Hardware-Scanner) erlaubt und mir erlaubt, versehentliche Scans direkt zu korrigieren,
so that ich beim Einräumen/Verbrauchen nur noch diese eine Ansicht öffnen muss, statt zwischen mehreren Stellen zu wechseln.
Kontext (verifiziert im Code):
PantryScanStationPage.tsx(frisch gebaute Vollbild-Seite unter/pantry/:id/scan) deckt bereits ab: Vollbild-Layout, Hardware-Scanner-Texteingabe (HID-Tastatur), Check-In/Check-Out-Moduswechsel per Steuer-Barcode — aber nur einen lokalen, nicht-persistenten Sitzungs-Verlauf (verschwindet beim Verlassen der Seite) und keinen Kamera-Scan-Zugang.PantryActivityFeedPanel.tsx/PantryActivityEventItem.tsx(GetPantryActivityFeedQuery,PantryActivityEventDtomitId,Kind,Body,PantryProductId?), aber nur als ausklappbares Panel am unteren Rand der normalen Vorratsschrank-Seite, nicht Vollbild.PantryBarcodeScanner.tsx(Modal-Dialog), aktuell nur über das "..."-Menü der normalen Vorratsschrank-Seite erreichbar.SetPantryProductTargetQuantityCommand, aktuell nur überPantryProductItem.tsxs eigenes "..."-Menü erreichbar) — für diese Story reine UI-Verdrahtung, kein neuer Backend-Code nötig.DeletePantryActivityEventCommando.ä., nurCreatePantryActivityEventCommandHandler/GetPantryActivityFeedQueryHandler.PantryScanStationPage.tsxdieUnknownProductNameEntry-Texteingabe (Name, künftig laut#174/#178evtl. auch eine Kategorie-Abfrage inkl. proaktivem Vorschlag). Nach Enter (submitWithName) soll die Haupt-Scan-Eingabe automatisch wieder aktiv/fokussiert sein, damit man mit dem Scanner direkt weiterscannen kann, ohne manuell zurückzuklicken. Der aktuelle Code hat dafür bereits einenuseEffect, derfocusInput()aufruft sobaldneedsNameauffalsewechselt — ob das in der Praxis zuverlässig funktioniert, ist nicht gegen ein echtes Backend verifiziert (Docker war in der Bau-Session nicht verfügbar). Siehe AC unten.Acceptance criteria:
PantryScanStationPage.tsxwird erweitert (nicht durch eine zweite, separate Seite ersetzt): statt des lokalen Sitzungs-Verlaufs zeigt sie den echten, persistenten Aktivitäts-Verlauf (paginiert wiePantryActivityFeedPanel.tsxbereits heute), weiterhin im Vollbild-Layout.PantryBarcodeScanner.tsx) öffnet — zusätzlich zur bereits vorhandenen Hardware-Scanner-Texteingabe, nicht als Ersatz.ProductCheckedIn/ProductCheckedOut) bekommt drei Aktions-Buttons:PantryProductItem.tsxheute schon für "Zielmenge festlegen" nutzt, direkt für das Produkt dieses Eintrags (event.pantryProductId).pantryProductIdgesetzt und Produkt nicht gelöscht) — analog zur bestehendenclickable-Prüfung inPantryActivityEventItem.tsx.useEffect-Ansatz das in der Praxis nicht zuverlässig leistet, muss das im Zuge dieser Story behoben werden.Out of scope for this story:
Open questions: (escalate to human if unanswered)
DeletePantryActivityEventCommand), oder reicht eine Komposition aus bestehenden Check-In/Check-Out-Commands plus einer neuen "Event löschen"-Operation? Architect-Entscheidung.Nutzer-Feedback ergänzt: Nach Abschluss der Unbekannt-Barcode-Texteingabe (Name, künftig ggf. plus Kategorie) per Enter muss die Haupt-Scan-Eingabe zuverlässig wieder fokussiert sein, damit man mit dem Hardware-Scanner sofort weiterscannen kann, ohne manuell zurückzuklicken. Als neue Acceptance Criterion + Kontext-Hinweis in die Story-Beschreibung aufgenommen.
Claimed for this go-cycle (2026-09-08). Scope: extend PantryScanStationPage.tsx to a full persistent activity view (reuse PantryActivityFeedPanel data), add a Scan button wiring the existing PantryBarcodeScanner dialog, add Delete/Invert actions on check-in/check-out entries (new backend commands), wire the existing target-quantity dialog per entry, and fix the post-unknown-name-entry focus-return behavior. Architect decisions (no human escalation needed - resolved against existing patterns): (1) dedicated DeletePantryActivityEventCommand and InvertPantryActivityEventCommand rather than composing existing check-in/check-out commands, since the activity feed itself needs to reflect the correction; (2) corrections apply +/-1 against current quantity unconditionally (consistent with existing clamped-at-0 check-out behavior), no protection against later legitimate scans - documented as a known, deferred limitation; (3) any pantry member may delete/invert any entry, consistent with the fully-shared (non-role-differentiated) membership model used elsewhere in Pantry.
Entscheidungen (Mensch, 2026-09-08):
Alle drei offenen Fragen der Story sind damit beantwortet - Umsetzung kann ohne weitere Eskalation starten.
Done - merged to master as
402bbdc9(feature) +f33a180f(coverage report).Scope delivered (all AC met):
Backend: two new commands, DeletePantryActivityEventCommand/InvertPantryActivityEventCommand (Checkly/Features/Pantry/), authorized the same way every other Pantry command is (AuthorizePantryAccessForCurrentUserQuery - any member of the pantry's linked shopping list). Both reject non-check-in/out kinds and events whose product no longer exists. 13 new backend tests.
Architect decisions made without human escalation (per �1_product_owner.md's actual escalation criteria - none of the "household knowledge/conflicting requirements/no use case" triggers applied here), documented in the claim comment: dedicated commands rather than composing existing check-in/check-out ones; corrections apply unconditionally (clamped at 0), no protection against a later legitimate scan landing underneath a correction (documented, deliberately deferred); any pantry member may correct any entry (matches the existing non-role-differentiated Pantry membership model).
Testing: dotnet test 1028/1028 green (13 new),
pm run coverage 1243/1243 green (14 new),
pm run build/ sc -b clean,
px eslint clean on every changed file. Self-review + the security-review skill (plus a dedicated sub-agent IDOR check on cross-pantry PantryActivityEventId/PantryProductId access) both came back clean - both new handlers compound-filter every query/update on (Id, PantryId) together.
Known, deliberately deferred gap: if a product is scanned again after a correction (delete/invert) was applied to an earlier entry, the correction's +/-1 or +/-2 adjustment is still applied unconditionally against the current quantity - there's no detection of "a legitimate scan happened in between." Flagged as an open question in the story, judged acceptable for this pass.
Also found and handled this cycle: a live concurrent-loop collision - a sibling checkout ( odo2, another active "go"-loop session) had independently claimed and started implementing this exact same issue. Caught via a docker port conflict before either side pushed conflicting work; messaged that session directly to stand down from #172 and re-pick from the current backlog. Recorded in i/roles/memory/07_team_coach_memory.md for future cycles.
Not run this cycle: the local review Docker container rebuild - its fixed port (8090) was occupied by that other session's own container; deferred until it steps off #172 rather than fighting over the port mid-collision.