fix: exempt own posts from timeline retention cleanup

The cleanup was deleting own posts when remote posts pushed the total
past the retention limit. Own posts are your content — they should
never be deleted by retention. Now filters to only count and delete
remote posts (author.url != profile.url).
This commit is contained in:
Ricardo
2026-04-02 23:55:04 +02:00
parent 40eb2f8f09
commit b71b4a9dbd
2 changed files with 23 additions and 10 deletions
+22 -9
View File
@@ -19,19 +19,32 @@ export async function cleanupTimeline(collections, retentionLimit) {
return { removed: 0, interactionsRemoved: 0 }; return { removed: 0, interactionsRemoved: 0 };
} }
const totalCount = await collections.ap_timeline.countDocuments(); // Get the local profile URL to exempt own posts from cleanup.
if (totalCount <= retentionLimit) { // Own posts are your content — they should never be deleted by retention.
const profile = collections.ap_profile
? await collections.ap_profile.findOne({})
: null;
const ownerUrl = profile?.url || null;
// Only count remote posts toward retention limit
const remoteFilter = ownerUrl
? { "author.url": { $ne: ownerUrl } }
: {};
const remoteCount = await collections.ap_timeline.countDocuments(remoteFilter);
if (remoteCount <= retentionLimit) {
return { removed: 0, interactionsRemoved: 0 }; return { removed: 0, interactionsRemoved: 0 };
} }
// Use aggregation to get exact UIDs beyond the retention limit. // Find remote items beyond the retention limit, sorted newest-first.
// This avoids race conditions: we delete by UID, not by date. // Own posts are excluded from the aggregation pipeline entirely.
const pipeline = [
...(ownerUrl ? [{ $match: { "author.url": { $ne: ownerUrl } } }] : []),
{ $sort: { published: -1 } },
{ $skip: retentionLimit },
{ $project: { uid: 1 } },
];
const toDelete = await collections.ap_timeline const toDelete = await collections.ap_timeline
.aggregate([ .aggregate(pipeline)
{ $sort: { published: -1 } },
{ $skip: retentionLimit },
{ $project: { uid: 1 } },
])
.toArray(); .toArray();
if (!toDelete.length) { if (!toDelete.length) {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@rmdes/indiekit-endpoint-activitypub", "name": "@rmdes/indiekit-endpoint-activitypub",
"version": "3.13.3", "version": "3.13.4",
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.", "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
"keywords": [ "keywords": [
"indiekit", "indiekit",