mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-21 06:13:48 +00:00
refactor: introduce domain events for feed side effects (Track E — point 5)
Light "collect + dispatch" variant: the Feed aggregate records FeedEvents (FeedCreated, EmailIngested) on the mutations that have consequences, exposed via pullEvents(). A new application dispatcher (feed-events.applyFeedEvents) maps those events to their side effects — counters (awaited) plus WebSub pings and favicon fetches handed to a BackgroundScheduler. This removes the inline, scattered side effects from the ingest hot path (email-processor) and from createFeedRecord; the aggregate is now the source of truth for "what happened". Side effects with no aggregate mutation (rejected email, feed deletion bypassing the aggregate, bulk admin ops, the cron, unsubscribes-sent) stay imperative by design — there is no aggregate event for them to ride on. BackgroundScheduler type moved to infrastructure/worker.ts (shared). CLAUDE.md updated. 355 tests pass (+4 event tests); tsc --noEmit clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Domain events the Feed aggregate records when it mutates. They describe *what
|
||||
* happened* in business terms; the application layer decides which side effects
|
||||
* to run (counters, WebSub pings, favicon caching) via a dispatcher. This keeps
|
||||
* the aggregate ignorant of infrastructure and the orchestration code free of
|
||||
* scattered, inline side effects.
|
||||
*
|
||||
* Only mutations that currently have side effects emit events — feed creation
|
||||
* and email ingestion. Edits and removals carry no side effect, so they emit
|
||||
* nothing. Side effects that don't flow through the aggregate (a rejected email,
|
||||
* a feed deletion that bypasses the aggregate, bulk admin operations) stay
|
||||
* outside this mechanism by design — they have no aggregate event to ride on.
|
||||
*/
|
||||
export type FeedEvent =
|
||||
| { type: "FeedCreated" }
|
||||
| { type: "EmailIngested"; iconDomain?: string };
|
||||
Reference in New Issue
Block a user