Address the review of PR #176 (Feature 21, task 96e2dc3f):
- MQ-176-01: useUpdates drops its list as soon as the sheet closes
(gcTime 0), so each opening reads GET /api/v1/updates afresh and only
marks seen through the newest of that read, never a cached list.
- MQ-176-02: parseUpdate checks each url with appPath from
push/notification.ts, by parsed origin, instead of a prefix check that
tabs and newlines got past; the url kept is the path as parsed.
- MQ-176-03: TestMarkUpdatesSeen asserts updated_at is kept and settings
subscribers are not told.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /api/v1/updates lists the last 10 distinct notification events from
the outbox, newest first and one per event key whatever its channels.
POST /api/v1/updates/seen {"through": created_at} moves
household_settings.updates_seen_at forward, so /api/v1/home's
recentUpdates.unread is true only for an event stored since. The Home
bell opens a Sheet listing the updates with relative times; a row opens
its URL, and opening the sheet marks the updates seen, clearing the
grape dot optimistically and putting it back if the mark fails.
Maestro task 96e2dc3f-1f8a-4114-bcb5-e0f93c349165.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>