refactor(app): parse sender once via EmailAddress, drop infra reach

email-processor parsed input.from twice — once via EmailAddress for the
native-feed base, once via the favicon infra helper extractEmailDomain
just to get the domain. CLAUDE.md forbids reaching across a layer to
parse a domain: parse once and derive both siteBaseUrl() and domain.value
from the EmailAddress VO, removing the infrastructure/favicon-fetcher import.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Julien Herr
2026-05-25 18:00:02 +02:00
parent e8078b2673
commit 0f18d4c123
+3 -6
View File
@@ -3,7 +3,6 @@ import { EmailAddress } from "../domain/value-objects/email-address";
import { AttachmentData, EmailMetadata, Env } from "../types"; import { AttachmentData, EmailMetadata, Env } from "../types";
import { bumpCounters } from "../application/stats"; import { bumpCounters } from "../application/stats";
import { dispatchFeedEvents } from "../application/feed-events"; import { dispatchFeedEvents } from "../application/feed-events";
import { extractEmailDomain } from "../infrastructure/favicon-fetcher";
import { parseOneClickUnsubscribe } from "../infrastructure/unsubscribe"; import { parseOneClickUnsubscribe } from "../infrastructure/unsubscribe";
import { getAttachmentBucket } from "../infrastructure/attachments"; import { getAttachmentBucket } from "../infrastructure/attachments";
import { import {
@@ -196,11 +195,9 @@ async function storeEmail(
links: extractLinks(input.content), links: extractLinks(input.content),
}); });
const sender = EmailAddress.parse(input.from);
const nativeFeedList = detectNativeFeeds( const nativeFeedList = detectNativeFeeds(
extractFeedLinks( extractFeedLinks(input.content, sender?.siteBaseUrl() ?? ""),
input.content,
EmailAddress.parse(input.from)?.siteBaseUrl() ?? "",
),
); );
const attachmentBucket = getAttachmentBucket(env); const attachmentBucket = getAttachmentBucket(env);
@@ -247,7 +244,7 @@ async function storeEmail(
// Track the latest sender's domain (feed icon) and capture the RFC 8058 // Track the latest sender's domain (feed icon) and capture the RFC 8058
// one-click unsubscribe link, keyed by sender so each newsletter keeps its // one-click unsubscribe link, keyed by sender so each newsletter keeps its
// own latest URL (fired when the feed is deleted). // own latest URL (fired when the feed is deleted).
const iconDomain = extractEmailDomain(input.from); const iconDomain = sender?.domain.value;
const senderKey = input.senders[0] || iconDomain || input.from; const senderKey = input.senders[0] || iconDomain || input.from;
const unsubUrl = parseOneClickUnsubscribe(input.headers ?? {}); const unsubUrl = parseOneClickUnsubscribe(input.headers ?? {});
const unsub = unsubUrl ? { senderKey, url: unsubUrl } : undefined; const unsub = unsubUrl ? { senderKey, url: unsubUrl } : undefined;