#117 — Einkaufsliste — Produkt-Aktivitäts-Feed #120

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

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, dass
Shopping-Produkte — anders als ursprünglich angenommen — überhaupt keine Aktivitäts-Feed-Infrastruktur
haben; #102s eigene 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 #101 für den Vorratsschrank bereits
etabliert hat.

Architect-Vorentscheidung (folgt #101s eigenem Präzedenzfall): neue ShoppingActivityEventEntity
(Sibling-Entity, keyed auf ShoppingListId) statt einer polymorphen Erweiterung der bestehenden
ActivityEventEntity (hart an TodoListId gebunden) — dieselbe Begründung, die #101s Design-Doc für
PantryActivityEventEntity bereits dokumentiert (docs/features/done/101_pantry_labels_comments_activity_feed_design.md).

Acceptance criteria:

  • Neue ShoppingActivityEventEntity + ShoppingActivityEventKind-Enum (mindestens: Produkt
    angelegt, umbenannt, aktiviert/deaktiviert (Menge-Änderung), in andere Kategorie verschoben) +
    Migration.
  • Neuer CreateShoppingActivityEventCommand (analog CreatePantryActivityEventCommand), verkabelt
    in RenameShoppingProductCommandHandler, MoveShoppingProductCommandHandler,
    ActivateShoppingProductCommandHandler/DeactivateShoppingProductCommandHandler,
    CreateShoppingProductCommandHandler.
  • Neue GetShoppingActivityFeedQuery (Pagination wie GetPantryActivityFeedQuery).
  • Neues Frontend-Panel ShoppingActivityFeedPanel (analog PantryActivityFeedPanel), geöffnet über
    einen Menüpunkt auf ShoppingListPage, inkl. Deep-Link-Klick auf ein Event scrollt/hebt das
    betroffene Produkt hervor (analog #101d).
  • RenameShoppingProductCommand/MoveShoppingProductCommands Aktivitäts-Body zeigt bei einer
    Änderung sowohl den alten als auch den neuen Wert (analog #102s Erweiterung für
    SetPantryProductTargetQuantityCommandHandler), damit ein per Last-Write-Wins überschriebener
    Offline-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. Delete was deliberately left out of the kind enum — not named in this AC, out of scope
for this story. See docs/features/done/117_shopping_product_activity_feed.md.

Out of scope:

  • Kein WS-Live-Sync für den Feed selbst (analog #101d — Refetch-on-Open reicht).
  • Keine rückwirkende Befüllung für vor dieser Story liegende Änderungen.
# 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, dass Shopping-Produkte — anders als ursprünglich angenommen — überhaupt keine Aktivitäts-Feed-Infrastruktur haben; `#102s` eigene 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 `#101` für den Vorratsschrank bereits etabliert hat. **Architect-Vorentscheidung (folgt `#101s` eigenem Präzedenzfall):** neue `ShoppingActivityEventEntity` (Sibling-Entity, keyed auf `ShoppingListId`) statt einer polymorphen Erweiterung der bestehenden `ActivityEventEntity` (hart an `TodoListId` gebunden) — dieselbe Begründung, die `#101s` Design-Doc für `PantryActivityEventEntity` bereits dokumentiert (`docs/features/done/101_pantry_labels_comments_activity_feed_design.md`). **Acceptance criteria:** - [x] Neue `ShoppingActivityEventEntity` + `ShoppingActivityEventKind`-Enum (mindestens: Produkt angelegt, umbenannt, aktiviert/deaktiviert (Menge-Änderung), in andere Kategorie verschoben) + Migration. - [x] Neuer `CreateShoppingActivityEventCommand` (analog `CreatePantryActivityEventCommand`), verkabelt in `RenameShoppingProductCommandHandler`, `MoveShoppingProductCommandHandler`, `ActivateShoppingProductCommandHandler`/`DeactivateShoppingProductCommandHandler`, `CreateShoppingProductCommandHandler`. - [x] Neue `GetShoppingActivityFeedQuery` (Pagination wie `GetPantryActivityFeedQuery`). - [x] Neues Frontend-Panel `ShoppingActivityFeedPanel` (analog `PantryActivityFeedPanel`), geöffnet über einen Menüpunkt auf `ShoppingListPage`, inkl. Deep-Link-Klick auf ein Event scrollt/hebt das betroffene Produkt hervor (analog `#101d`). - [x] `RenameShoppingProductCommand`/`MoveShoppingProductCommand`s Aktivitäts-Body zeigt bei einer Änderung sowohl den alten als auch den neuen Wert (analog `#102s` Erweiterung für `SetPantryProductTargetQuantityCommandHandler`), damit ein per Last-Write-Wins überschriebener Offline-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. `Delete` was deliberately left out of the kind enum — not named in this AC, out of scope for this story. See `docs/features/done/117_shopping_product_activity_feed.md`. **Out of scope:** - Kein WS-Live-Sync für den Feed selbst (analog `#101d` — Refetch-on-Open reicht). - Keine rückwirkende Befüllung für vor dieser Story liegende Änderungen.
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#120
No description provided.