fix: Only count unread items within 30-day retention period

- Add date filter to channel unread counts (UNREAD_RETENTION_DAYS = 30)
- Update getUnreadCount to also filter by date
- Prevents inflated counts from old accumulated items

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ricardo
2026-02-08 13:58:55 +01:00
parent 2ffce9a74f
commit 1009a2d6f6
3 changed files with 18 additions and 2 deletions

View File

@@ -83,6 +83,9 @@ export async function createChannel(application, { name, userId }) {
return channel; return channel;
} }
// Retention period for unread count (only count recent items)
const UNREAD_RETENTION_DAYS = 30;
/** /**
* Get all channels for a user * Get all channels for a user
* @param {object} application - Indiekit application * @param {object} application - Indiekit application
@@ -101,12 +104,17 @@ export async function getChannels(application, userId) {
.sort({ order: 1 }) .sort({ order: 1 })
.toArray(); .toArray();
// Get unread counts for each channel // Calculate cutoff date for unread counts (only count recent items)
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - UNREAD_RETENTION_DAYS);
// Get unread counts for each channel (only recent items)
const channelsWithCounts = await Promise.all( const channelsWithCounts = await Promise.all(
channels.map(async (channel) => { channels.map(async (channel) => {
const unreadCount = await itemsCollection.countDocuments({ const unreadCount = await itemsCollection.countDocuments({
channelId: channel._id, channelId: channel._id,
readBy: { $ne: userId }, readBy: { $ne: userId },
published: { $gte: cutoffDate },
}); });
return { return {

View File

@@ -562,6 +562,9 @@ export async function deleteItemsForFeed(application, feedId) {
return result.deletedCount; return result.deletedCount;
} }
// Retention period for unread count (only count recent items)
const UNREAD_RETENTION_DAYS = 30;
/** /**
* Get unread count for a channel * Get unread count for a channel
* @param {object} application - Indiekit application * @param {object} application - Indiekit application
@@ -574,9 +577,14 @@ export async function getUnreadCount(application, channelId, userId) {
const objectId = const objectId =
typeof channelId === "string" ? new ObjectId(channelId) : channelId; typeof channelId === "string" ? new ObjectId(channelId) : channelId;
// Only count items from the last UNREAD_RETENTION_DAYS
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - UNREAD_RETENTION_DAYS);
return collection.countDocuments({ return collection.countDocuments({
channelId: objectId, channelId: objectId,
readBy: { $ne: userId }, readBy: { $ne: userId },
published: { $gte: cutoffDate },
}); });
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@rmdes/indiekit-endpoint-microsub", "name": "@rmdes/indiekit-endpoint-microsub",
"version": "1.0.25", "version": "1.0.26",
"description": "Microsub endpoint for Indiekit. Enables subscribing to feeds and reading content using the Microsub protocol.", "description": "Microsub endpoint for Indiekit. Enables subscribing to feeds and reading content using the Microsub protocol.",
"keywords": [ "keywords": [
"indiekit", "indiekit",