#117 — Einkaufsliste — Produkt-Aktivitäts-Feed #120
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#120
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: Einkaufsliste — Produkt-Aktivitäts-Feed
Depends on:
#90(Einkaufsliste-Grundlage), keine weiteren.As a Haushaltsmitglied,
I want to nachvollziehen können, wer wann welches Einkaufslisten-Produkt umbenannt, in eine andere
Kategorie verschoben, hinzugefügt oder aktiviert/deaktiviert hat,
so that die Einkaufsliste dieselbe Nachvollziehbarkeit wie Todos (
#25) und der Vorratsschrank (#101d)erreicht, und ein per Last-Write-Wins überschriebener Zwischenstand (
#102) nicht spurlos verschwindet.Hintergrund: Beim Aufgreifen von
#102("Offline-Verfügbarkeit Phase 2") stellte sich heraus, dassShopping-Produkte — anders als ursprünglich angenommen — überhaupt keine Aktivitäts-Feed-Infrastruktur
haben;
#102seigene AC ("ein überschriebener Zwischenstand landet sichtbar im jeweiligen Aktivitäts-Feed")konnte deshalb für Shopping nur teilweise erfüllt werden (Last-Write-Wins ja, Sichtbarkeit im Feed nein).
Diese Story schließt genau diese Lücke, nach demselben Muster, das
#101für den Vorratsschrank bereitsetabliert hat.
Architect-Vorentscheidung (folgt
#101seigenem Präzedenzfall): neueShoppingActivityEventEntity(Sibling-Entity, keyed auf
ShoppingListId) statt einer polymorphen Erweiterung der bestehendenActivityEventEntity(hart anTodoListIdgebunden) — dieselbe Begründung, die#101sDesign-Doc fürPantryActivityEventEntitybereits dokumentiert (docs/features/done/101_pantry_labels_comments_activity_feed_design.md).Acceptance criteria:
ShoppingActivityEventEntity+ShoppingActivityEventKind-Enum (mindestens: Produktangelegt, umbenannt, aktiviert/deaktiviert (Menge-Änderung), in andere Kategorie verschoben) +
Migration.
CreateShoppingActivityEventCommand(analogCreatePantryActivityEventCommand), verkabeltin
RenameShoppingProductCommandHandler,MoveShoppingProductCommandHandler,ActivateShoppingProductCommandHandler/DeactivateShoppingProductCommandHandler,CreateShoppingProductCommandHandler.GetShoppingActivityFeedQuery(Pagination wieGetPantryActivityFeedQuery).ShoppingActivityFeedPanel(analogPantryActivityFeedPanel), geöffnet übereinen Menüpunkt auf
ShoppingListPage, inkl. Deep-Link-Klick auf ein Event scrollt/hebt dasbetroffene Produkt hervor (analog
#101d).RenameShoppingProductCommand/MoveShoppingProductCommands Aktivitäts-Body zeigt bei einerÄnderung sowohl den alten als auch den neuen Wert (analog
#102sErweiterung fürSetPantryProductTargetQuantityCommandHandler), damit ein per Last-Write-Wins überschriebenerOffline-Zwischenstand nachvollziehbar bleibt.
Delivered 2026-08-10 — Activate/Deactivate only record an event on the actual on↔off transition,
not every quantity re-confirm of an already-active product (matches Pantry's "record after the real
change" convention); Move only records on a genuine cross-category change, not a same-category drag
reorder.
Deletewas deliberately left out of the kind enum — not named in this AC, out of scopefor this story. See
docs/features/done/117_shopping_product_activity_feed.md.Out of scope:
#101d— Refetch-on-Open reicht).