Archivieren fuer Einkaufsliste, Vorratsschrank und Masterpackliste ergaenzen #162

Closed
opened 2026-09-06 19:55:38 +02:00 by lena · 2 comments
Collaborator

Story: Archivieren fuer Einkaufsliste, Vorratsschrank und Masterpackliste ergaenzen

As a Listen-Owner,
I want to eine fertige Einkaufsliste, einen Vorratsschrank oder eine Masterpackliste genauso archivieren koennen wie ich es fuer Todo-Listen bereits kann,
so that ich meine Seitenleiste aufraeumen kann, ohne den Verlauf/die Daten zu loeschen.

Background

ArchiveTodoListCommand/UnarchiveTodoListCommand existieren nur unter Checkly/Features/TodoLists - fuer Shopping, Pantry und MasterPacking gibt es kein Aequivalent, obwohl alle vier Listentypen inzwischen ansonsten (Umbenennen, Loeschen, seit #159 auch Duplizieren) denselben Funktionsumfang im "..."-Menue haben.

Acceptance criteria:

  • Einkaufsliste, Vorratsschrank und Masterpackliste bekommen je ein Archive*Command/Unarchive*Command, das dem bestehenden Todo-Verhalten entspricht (nur der Owner darf archivieren, archivierte Listen verschwinden aus der normalen Seitenleisten-Ansicht, sind aber jederzeit reversibel).
  • Das "..."-Menue der drei Listentypen bekommt Archivieren/Aus Archiv holen als neue Eintraege, analog zu ListActionsMenu.tsxs bestehendem Todo-Muster.
  • Archivieren loescht oder versteckt keine Daten (Eintraege, Kommentare, Aktivitaets-Feed) - nur die Sichtbarkeit in der normalen Listenuebersicht aendert sich.
  • Es gibt eine Moeglichkeit, archivierte Listen dieser drei Typen wiederzufinden und zu entarchivieren (analog zur bestehenden Todo-Loesung).

Out of scope for this story:

  • Massen-Archivieren mehrerer Listen auf einmal.
  • Automatisches Archivieren basierend auf Inaktivitaet oder abgeschlossenem Checkout (z. B. Masterpackliste nach Checkout).

Open questions: (escalate to human if unanswered)

  • Soll das Archivieren eines Vorratsschranks unabhaengig vom Archivieren seiner verknuepften Einkaufsliste sein, oder soll das Archivieren der Einkaufsliste automatisch auch den Vorratsschrank mit-archivieren (da Pantry-Zugriff laut #94 ohnehin von der Mitgliedschaft der Einkaufsliste abhaengt)?
## Story: Archivieren fuer Einkaufsliste, Vorratsschrank und Masterpackliste ergaenzen **As a** Listen-Owner, **I want to** eine fertige Einkaufsliste, einen Vorratsschrank oder eine Masterpackliste genauso archivieren koennen wie ich es fuer Todo-Listen bereits kann, **so that** ich meine Seitenleiste aufraeumen kann, ohne den Verlauf/die Daten zu loeschen. ## Background `ArchiveTodoListCommand`/`UnarchiveTodoListCommand` existieren nur unter `Checkly/Features/TodoLists` - fuer Shopping, Pantry und MasterPacking gibt es kein Aequivalent, obwohl alle vier Listentypen inzwischen ansonsten (Umbenennen, Loeschen, seit #159 auch Duplizieren) denselben Funktionsumfang im "..."-Menue haben. **Acceptance criteria:** - [ ] Einkaufsliste, Vorratsschrank und Masterpackliste bekommen je ein `Archive*Command`/`Unarchive*Command`, das dem bestehenden Todo-Verhalten entspricht (nur der Owner darf archivieren, archivierte Listen verschwinden aus der normalen Seitenleisten-Ansicht, sind aber jederzeit reversibel). - [ ] Das "..."-Menue der drei Listentypen bekommt Archivieren/Aus Archiv holen als neue Eintraege, analog zu `ListActionsMenu.tsx`s bestehendem Todo-Muster. - [ ] Archivieren loescht oder versteckt keine Daten (Eintraege, Kommentare, Aktivitaets-Feed) - nur die Sichtbarkeit in der normalen Listenuebersicht aendert sich. - [ ] Es gibt eine Moeglichkeit, archivierte Listen dieser drei Typen wiederzufinden und zu entarchivieren (analog zur bestehenden Todo-Loesung). **Out of scope for this story:** - Massen-Archivieren mehrerer Listen auf einmal. - Automatisches Archivieren basierend auf Inaktivitaet oder abgeschlossenem Checkout (z. B. Masterpackliste nach Checkout). **Open questions:** (escalate to human if unanswered) - Soll das Archivieren eines Vorratsschranks unabhaengig vom Archivieren seiner verknuepften Einkaufsliste sein, oder soll das Archivieren der Einkaufsliste automatisch auch den Vorratsschrank mit-archivieren (da Pantry-Zugriff laut #94 ohnehin von der Mitgliedschaft der Einkaufsliste abhaengt)?
lena self-assigned this 2026-09-06 19:56:27 +02:00
Author
Collaborator

Claimed. Starting implementation.

Decision on the open question (should archiving a Pantry couple to archiving its linked Shopping list): independent archiving, no coupling. Reasoning: archiving is a pure visibility toggle (not an access/ownership change, unlike deletion), so there's no data-integrity reason to cascade it the way #94's access-derivation works for membership. A household might genuinely want to archive just one side (e.g. stop tracking pantry inventory for a while but keep the shopping list active, or vice versa) - coupling them would remove that flexibility for no real benefit and add cross-entity special-casing to what should stay a simple per-list flag, mirroring exactly how Todo's own Archive/Unarchive already works with zero coupling to anything else.

Planned shape: mirror ArchiveTodoListCommand/UnarchiveTodoListCommand exactly for Shopping, Pantry, and MasterPacking - an IsArchived bool on each entity, owner-only authorization, excluded from the default "my lists" query the sidebar renders from, with Archive/Unarchive items added to each type's "..." menu.

Claimed. Starting implementation. Decision on the open question (should archiving a Pantry couple to archiving its linked Shopping list): independent archiving, no coupling. Reasoning: archiving is a pure visibility toggle (not an access/ownership change, unlike deletion), so there's no data-integrity reason to cascade it the way #94's access-derivation works for membership. A household might genuinely want to archive just one side (e.g. stop tracking pantry inventory for a while but keep the shopping list active, or vice versa) - coupling them would remove that flexibility for no real benefit and add cross-entity special-casing to what should stay a simple per-list flag, mirroring exactly how Todo's own Archive/Unarchive already works with zero coupling to anything else. Planned shape: mirror `ArchiveTodoListCommand`/`UnarchiveTodoListCommand` exactly for Shopping, Pantry, and MasterPacking - an `IsArchived` bool on each entity, owner-only authorization, excluded from the default "my lists" query the sidebar renders from, with Archive/Unarchive items added to each type's "..." menu.
Author
Collaborator

Implemented and merged in commits fd1b37f (backend) and b88c327 (frontend) on master.

Scope: Extended the existing Todo List Archive/Unarchive feature to Shopping Lists, Pantries, and Master Packing Lists. Archiving is a pure visibility toggle (hidden from the default sidebar view under a collapsible "Archived" section, fully reversible) — not an access-control change — and is independent per list type (archiving a Pantry does not affect its target Shopping List's own archived state, and vice versa).

Backend:

  • Added IsArchived (default false) to ShoppingListEntity, PantryEntity, MasterPackingListEntity via 3 separate single-table EF migrations.
  • Added Archive/UnarchiveShoppingListCommandHandler, ...PantryCommandHandler, ...MasterPackingListCommandHandler — each owner-only via the same AuthorizeXOwnerAccessForCurrentUserQuery pattern already used by that list type's Rename/Delete handlers.
  • Shopping's handlers broadcast the change over its existing WS channel (ShoppingListBroadcastDto gained IsArchived); also fixed RenameShoppingListCommandHandler to carry the real IsArchived through instead of implicitly resetting it to false on every rename. Pantry and MasterPacking have no WS channel (matching their existing Rename/Delete), so the frontend refetches after the mutation instead.
  • 12 new backend unit tests (2 per handler: sets/clears the flag, throws EntityNotFoundException for a missing id).

Frontend:

  • Added an owner-only Archive/Unarchive item to ShoppingListItem, PantryItem, and MasterPackingListItem's dropdown menus, gating Rename/Invite alongside it the same way TodoListMenu already gated Todo's.
  • Generalized TodoListMenu's active/archived sidebar split from Todo-only to all 4 list types, and the archived section now renders the correct item component per type instead of always TodoListItem.
  • New/updated frontend tests across all 3 item components plus TodoListMenu (archived-section filtering per type).

Verification: dotnet build clean; new backend tests reach the expected DockerUnavailableException (Docker's daemon isn't reachable in this sandbox), confirming DI/authorization wiring; full frontend suite green (1175 tests, up from 1160); tsc -b and npm run build clean. A dedicated security-review pass confirmed all 6 new handlers correctly mirror their sibling Rename/Delete handlers' owner-only authorization — no IDOR, injection, or data-exposure findings.

Closing as done.

Implemented and merged in commits fd1b37f (backend) and b88c327 (frontend) on master. **Scope:** Extended the existing Todo List Archive/Unarchive feature to Shopping Lists, Pantries, and Master Packing Lists. Archiving is a pure visibility toggle (hidden from the default sidebar view under a collapsible "Archived" section, fully reversible) — not an access-control change — and is independent per list type (archiving a Pantry does not affect its target Shopping List's own archived state, and vice versa). **Backend:** - Added `IsArchived` (default `false`) to `ShoppingListEntity`, `PantryEntity`, `MasterPackingListEntity` via 3 separate single-table EF migrations. - Added `Archive`/`UnarchiveShoppingListCommandHandler`, `...PantryCommandHandler`, `...MasterPackingListCommandHandler` — each owner-only via the same `AuthorizeXOwnerAccessForCurrentUserQuery` pattern already used by that list type's Rename/Delete handlers. - Shopping's handlers broadcast the change over its existing WS channel (`ShoppingListBroadcastDto` gained `IsArchived`); also fixed `RenameShoppingListCommandHandler` to carry the real `IsArchived` through instead of implicitly resetting it to `false` on every rename. Pantry and MasterPacking have no WS channel (matching their existing Rename/Delete), so the frontend refetches after the mutation instead. - 12 new backend unit tests (2 per handler: sets/clears the flag, throws `EntityNotFoundException` for a missing id). **Frontend:** - Added an owner-only Archive/Unarchive item to `ShoppingListItem`, `PantryItem`, and `MasterPackingListItem`'s dropdown menus, gating Rename/Invite alongside it the same way `TodoListMenu` already gated Todo's. - Generalized `TodoListMenu`'s active/archived sidebar split from Todo-only to all 4 list types, and the archived section now renders the correct item component per type instead of always `TodoListItem`. - New/updated frontend tests across all 3 item components plus `TodoListMenu` (archived-section filtering per type). **Verification:** `dotnet build` clean; new backend tests reach the expected `DockerUnavailableException` (Docker's daemon isn't reachable in this sandbox), confirming DI/authorization wiring; full frontend suite green (1175 tests, up from 1160); `tsc -b` and `npm run build` clean. A dedicated security-review pass confirmed all 6 new handlers correctly mirror their sibling Rename/Delete handlers' owner-only authorization — no IDOR, injection, or data-exposure findings. Closing as done.
lena closed this issue 2026-09-06 20:36:59 +02:00
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#162
No description provided.