mirror of
https://github.com/wekan/wekan.git
synced 2026-11-08 03:22:32 -05:00
Maintainer decision of 2026-09-30: receipts are compacted after 90 days to a permanent minimal id and outcome. A stored webhook plan keeps each target's URL, its X-Wekan-Token credential and the request body; a response row keeps the receiver's reply and a comment plan the comment text - all forever, and the plan had no completion evidence of its own. The notification plan retention becomes a shared kit (syncPlanRetention.js) and webhooks use it: once every target's delivery is confirmed, a completion receipt with its time is written. After SYNC_RECEIPT_METADATA_DAYS (90) the sweep first removes the plan's response and comment-plan rows - read only while a delivery receipt is missing - then compacts the plan in place. A late replay of the compact form returns as delivered; delivery and comment receipts, already minimal, stay. A MongoDB test covers what is removed and what an undelivered plan keeps, replay of the compact form and its refusals; the full-app webhook test compacts a really delivered plan, checks the URL and token are gone, and replays it without touching the comment. 565 server tests pass. Thanks to xet7 !
30 lines
1.6 KiB
JavaScript
30 lines
1.6 KiB
JavaScript
'use strict';
|
|
// Retention for stored Sync webhook plans (maintainer decision of 2026-09-30),
|
|
// through the shared plan retention (syncPlanRetention.js). A webhook plan
|
|
// keeps each target's URL, its X-Wekan-Token credential and the request body;
|
|
// a response row keeps the receiver's reply, and a comment plan the comment
|
|
// text. After every target's delivery is confirmed a completion receipt is
|
|
// written, and SYNC_RECEIPT_METADATA_DAYS (90) later the response and comment
|
|
// plan rows - read only while a delivery receipt is missing - are removed and
|
|
// the plan is compacted. Delivery and comment receipts, already minimal, stay.
|
|
const kit = require('./syncPlanRetention').createPlanRetentionKit('sync-webhook');
|
|
|
|
// The rows only an uncompleted plan could need.
|
|
function webhookDependents({ responses, commentPlans }) {
|
|
return async row => {
|
|
const { deliveryId } = require('./syncWebhookPlan');
|
|
const ids = (row.plan?.targets || []).map(target => deliveryId(row.plan.activityId, target.integrationId));
|
|
if (!ids.length) return;
|
|
await responses.deleteMany({ _id: { $in: ids } });
|
|
await commentPlans.deleteMany({ _id: { $in: ids } });
|
|
};
|
|
}
|
|
|
|
function createSyncWebhookRetention({ plans, receipts, responses, commentPlans, ...options }) {
|
|
return kit.createPlanRetention({ plans, receipts, ...options,
|
|
beforeCompact: webhookDependents({ responses, commentPlans }) });
|
|
}
|
|
|
|
module.exports = { isCompactWebhookPlan: kit.isCompactPlan, recordWebhookCompletion: kit.recordPlanCompletion,
|
|
readCompactedWebhook: kit.readCompactedPlan, createSyncWebhookRetention, webhookDependents };
|