diff --git a/TECH_DEBT.md b/TECH_DEBT.md index ca77eda..054aacf 100644 --- a/TECH_DEBT.md +++ b/TECH_DEBT.md @@ -27,12 +27,12 @@ Generated: 2026-05-22 ## Phase 3 — Ongoing / Infrastructure -| # | Task | Priority | -| ----- | ---------------------------------------------------- | -------- | -| P1-4 | Structured logging + error aggregation | 36 | -| P1-5 | Rate limiting (Cloudflare WAF rules) | 24 | -| P2-10 | Extract constants module (`src/config/constants.ts`) | 12 | -| P2-11 | Split `admin.ts` into sub-modules | 8 | +| # | Task | Priority | Status | +| ----- | ---------------------------------------------------- | -------- | ------------------------- | +| P1-4 | Structured logging + error aggregation | 36 | DONE | +| P1-5 | Rate limiting (Cloudflare WAF rules) | 24 | Infrastructure (see TODO) | +| P2-10 | Extract constants module (`src/config/constants.ts`) | 12 | DONE | +| P2-11 | Split `admin.ts` into sub-modules | 8 | DONE | --- diff --git a/TODO.md b/TODO.md index 34392af..518912d 100644 --- a/TODO.md +++ b/TODO.md @@ -24,4 +24,6 @@ Feature gaps identified by comparing with [kill-the-newsletter](https://github.c - [ ] **WebSub (PubSubHubbub) push notifications** — notify subscribers in real time when a new email arrives, instead of requiring them to poll the feed. Requires either integrating a public WebSub hub or implementing the hub protocol directly. +- [ ] **Rate limiting via Cloudflare WAF rules** — protect `/api/inbound` and `/admin` against abuse. Configure WAF custom rules in the Cloudflare dashboard (or via Terraform): rate-limit `/api/inbound` to ~60 req/min per IP, and `/admin` to ~20 req/min per IP. No code changes required; this is pure infrastructure configuration. + - [ ] **Migrate feed metadata to Durable Objects for atomic writes** — the current KV-based metadata store has a read-modify-write race condition: two concurrent emails to the same feed can silently overwrite each other's changes. Cloudflare Durable Objects serialise access per feed and eliminate the race entirely. Requires replacing `feed::metadata` KV writes in `src/lib/email-processor.ts` with a Durable Object that exposes an `appendEmail()` RPC, updating `wrangler.toml` with a DO binding, and migrating existing metadata at deploy time.