Parent
#6
What to build
Digest deliveries for webhook and Slack destinations currently get recorded with status "sent" without any HTTP request leaving the server. Make delivery real: during a due-digest run, webhook destinations receive the digest as a JSON POST to the configured URL; Slack destinations receive a Slack-compatible message payload posted to the incoming-webhook URL. Outbound calls use the established AbortController timeout pattern. Delivery status becomes honest: sent, failed (persisting the failure reason), or preview. A failed delivery leaves the digest due so the next run retries it. Destination URLs must be HTTPS — non-HTTPS destinations are rejected at preference save and skipped defensively at delivery time. Email destinations remain record-only. An in-app notification is still recorded for every digest run regardless of channel.
Acceptance criteria
Blocked by
None - can start immediately
Parent
#6
What to build
Digest deliveries for webhook and Slack destinations currently get recorded with status "sent" without any HTTP request leaving the server. Make delivery real: during a due-digest run, webhook destinations receive the digest as a JSON POST to the configured URL; Slack destinations receive a Slack-compatible message payload posted to the incoming-webhook URL. Outbound calls use the established AbortController timeout pattern. Delivery status becomes honest: sent, failed (persisting the failure reason), or preview. A failed delivery leaves the digest due so the next run retries it. Destination URLs must be HTTPS — non-HTTPS destinations are rejected at preference save and skipped defensively at delivery time. Email destinations remain record-only. An in-app notification is still recorded for every digest run regardless of channel.
Acceptance criteria
globalThis.fetchswapped and a temporary database via DATABASE_FILE;npm testgreenBlocked by
None - can start immediately