Centralise the KV key schema and all get/put access behind a FeedRepository
class under src/domain/. Every feed/email/list/icon/websub/counter key was
previously inlined across ~12 modules with two divergent storeEmail and
addFeedToList implementations; the dead src/utils/storage.ts write path is
removed and the email key convention unified on feed:<id>:<ts>.
Behaviour-preserving: existing tests pass unchanged in logic, plus a new
feed-repository.test.ts covering CRUD, key builders, list ops and counters.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Resolve each feed's most recent sender domain and serve its favicon at
GET /favicon/:feedId, falling back to the project icon. Icons are fetched
in the background on ingestion (direct /favicon.ico then a DuckDuckGo
fallback), cached base64 in KV keyed by domain with a 1-week TTL so the
fetch only fires when absent. Exposed via RSS <image> / Atom <icon>/<logo>
and rendered in the admin feed list, plus a landing-page feature card.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Serve an inline SVG icon at /favicon.svg and /favicon.ico and link it
from the shared Layout and the standalone entry view, so the admin UI,
status page, and entry pages stop emitting /favicon.ico 404s. Doubles
as the fallback for the upcoming per-feed favicon feature.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>