feat(admin): show email count and last-email date per feed
Surface each feed's email count on its Emails button and a "Last email …" freshness line under the title, in both dashboard views. The values are projected into feeds:list (kept to a single KV read) via the Feed aggregate, so toListItemDTO now maps the whole aggregate through its intention-revealing accessors instead of threading scalar projections. Also fixes long titles overflowing into the Feed ID column in the table view. Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
1 parent
e258206384
commit
fd3ff8c40a
11 files changed
+273
-51
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { FeedConfig, FeedListItem } from "../types";
|
||||
import { FeedState } from "../domain/feed-state";
|
||||
import { FeedId } from "../domain/value-objects/feed-id";
|
||||
import { Feed } from "../domain/feed.aggregate";
|
||||
|
||||
/**
|
||||
* The translation seam between the Feed aggregate's domain state (camelCase) and
|
||||
@@ -44,20 +44,23 @@ export function toConfigDTO(state: FeedState): FeedConfig {
|
||||
};
|
||||
}
|
||||
|
||||
/** Domain state → the projection cached in the global `feeds:list` registry. */
|
||||
export function toListItemDTO(
|
||||
id: FeedId,
|
||||
state: FeedState,
|
||||
pendingConfirmation = false,
|
||||
hasNativeFeed = false,
|
||||
): FeedListItem {
|
||||
/**
|
||||
* The Feed aggregate → the projection cached in the global `feeds:list` registry.
|
||||
* Unlike the config DTO, the list item is a read-model view: it folds in the
|
||||
* aggregate's metadata-derived signals (pending confirmation, native feed,
|
||||
* email count/last-received) alongside the config fields, so it reads the whole
|
||||
* aggregate through its intention-revealing accessors.
|
||||
*/
|
||||
export function toListItemDTO(feed: Feed): FeedListItem {
|
||||
return {
|
||||
id: id.value,
|
||||
title: state.title,
|
||||
description: state.description,
|
||||
mailbox_id: state.mailboxId,
|
||||
expires_at: state.expiresAt,
|
||||
pendingConfirmation,
|
||||
hasNativeFeed,
|
||||
id: feed.id.value,
|
||||
title: feed.title,
|
||||
description: feed.description,
|
||||
mailbox_id: feed.mailboxId.value,
|
||||
expires_at: feed.expiresAt,
|
||||
pendingConfirmation: feed.pendingConfirmation,
|
||||
hasNativeFeed: feed.hasNativeFeed(),
|
||||
emailCount: feed.emailCount,
|
||||
lastEmailAt: feed.lastEmailAt,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user