Vorratsschrank - Benachrichtigung bei bald ablaufenden/abgelaufenen Produkten #186
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#186
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 - Benachrichtigung bei bald ablaufenden/abgelaufenen Produkten
As a Mitglied eines Vorratsschranks,
I want to proaktiv benachrichtigt zu werden, wenn ein Produkt bald ablaeuft oder bereits abgelaufen ist,
so that ich es rechtzeitig verbrauchen oder wegwerfen kann, ohne jeden Tag manuell durch den Vorratsschrank zu scrollen und auf die "laeuft bald ab"-Markierung zu achten.
Kontext (verifiziert im Code): #164 hat
PantryProductBestBeforeDateplus eine rein visuelle "laeuft bald ab"/"abgelaufen"-Markierung (isExpiringSoon/isExpiredaufPantryDto,PantryBestBeforeDateDialog.tsx) eingefuehrt - aber keine proaktive Benachrichtigung. Fuer Todos existiert bereits ein analoges Muster (NotificationKind.TodoDueToday/TodoOverdue, taeglicher Check) - siehedocs/-Kontext zu Due-Date-Reminders. Dieses Muster ist direkt auf Vorratsschrank-Produkte mit Mindesthaltbarkeitsdatum uebertragbar.Acceptance criteria:
NotificationKind-WertePantryProductExpiringSoon/PantryProductExpired(analog zuTodoDueToday/TodoOverdue).Out of scope for this story:
Open questions: (escalate to human if unanswered)
Claiming this for the current autonomous cycle. Plan: mirror the existing TodoDueToday/TodoOverdue daily-check pattern onto pantry best-before dates. Add NotificationKind.PantryProductExpiringSoon / PantryProductExpired, a daily background check (reusing the same scheduling mechanism as the Todo due-date reminders) that scans PantryProductEntity rows with a BestBeforeDate, computes the same expiring-soon/expired thresholds already used by PantryDto.isExpiringSoon/isExpired (from #164), and emits one notification per pantry member the first time a product newly enters either state (no repeat spam for a product that stays expired/expiring). Delivery goes through the existing CreateNotificationCommand infra so email/push digest pickup is automatic, no new send path. No change to the existing visual badge itself. Not overlapping with the #181 work currently in progress on the appearance/color-icon feature (different files/domain).
Implemented and merged (
47de9873).Scope: two new NotificationKind values (PantryProductExpiringSoon, PantryProductExpired), a daily background sweep (CreatePantryDueNotificationsCommandHandler, bundled into the existing DueNotificationJob loop alongside the todo due-notification sweep) that notifies every member of a pantry-s target shopping list once when a product newly enters the expiring-soon (3-day, same threshold as #164-s visual badge) or expired state. No repeat for the same product/status on later runs (deliberately stricter idempotency than the todo pattern, which repeats once per day) - enforced by a new filtered unique index (RecipientId, PantryId, PantryProductId, Kind), no day component.
Design decisions:
Tests: 8 new backend handler tests (CreatePantryDueNotificationsCommandHandlerTests: expiring-soon, expired, no-date, far-from-expiry, archived-pantry, multi-member fan-out, idempotency-across-runs, WS-publish) plus 4 new frontend tests (NotificationItem: routes to /pantry/:id vs /list/:id, shows pantry title, marks read). Full backend suite (1093 tests) and frontend suite (1299 tests) green after the change.
Migration: 20260910200509_AddPantryNotificationTarget (TodoListId now nullable, PantryId/PantryProductId added, check constraint, new filtered unique index).