From 1d624dfd88729f879e2ff48deb2630e2c06debad Mon Sep 17 00:00:00 2001 From: LironEr Date: Fri, 15 Sep 2023 10:02:01 +0200 Subject: [PATCH] chore: script to delete old records --- README.md | 1 + service/scripts/deleteOldRecords.ts | 116 ++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 service/scripts/deleteOldRecords.ts diff --git a/README.md b/README.md index 68bda0d..204ad26 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,7 @@ Limitations of the free hosted service: - Records created by a PR will be deleted after 30 days. - Records in branches without activity (new commits) will be deleted after 180 days. +- After 90 days only the latest record per day will be kept. More limitations may be added in the future as more and more projects use the free hosted service. diff --git a/service/scripts/deleteOldRecords.ts b/service/scripts/deleteOldRecords.ts new file mode 100644 index 0000000..907f41e --- /dev/null +++ b/service/scripts/deleteOldRecords.ts @@ -0,0 +1,116 @@ +// Keep the latest record per day after AGGREGATE_RECORDS_OLDER_THAN_DAYS days + +import { closeMongoClient } from '@/framework/mongo/client'; +import { getCommitRecordsCollection } from '@/framework/mongo/commitRecords'; +import { ObjectId } from 'mongodb'; + +const AGGREGATE_RECORDS_OLDER_THAN_DAYS = 90; + +(async () => { + try { + console.log('Fetch records...'); + const commitRecordsCollection = await getCommitRecordsCollection(); + const agg = await commitRecordsCollection + .aggregate<{ + projectId: string; + subProject?: string; + branch: string; + aggDate: string; + idsToDelete: string[]; + }>([ + { + $sort: { + creationDate: -1, + }, + }, + { + $match: { + creationDate: { + $lt: new Date(new Date().setDate(new Date().getDate() - AGGREGATE_RECORDS_OLDER_THAN_DAYS)), + }, + }, + }, + { + $group: { + _id: { + projectId: '$projectId', + subProject: '$subProject', + branch: '$branch', + aggDate: { + $dateToString: { + format: '%Y-%m-%d', + date: '$creationDate', + }, + }, + }, + records: { + $push: '$_id', + }, + }, + }, + { + // check that the records has at least 2 records + $match: { + 'records.1': { + $exists: true, + }, + }, + }, + { + $project: { + projectId: '$_id.projectId', + subProject: '$_id.subProject', + branch: '$_id.branch', + aggDate: '$_id.aggDate', + // the first id is the last record per that period, so we keep it + idsToDelete: { + $slice: [ + '$records', + 1, + { + $subtract: [ + { + $size: '$records', + }, + 1, + ], + }, + ], + }, + }, + }, + { + $unset: '_id', + }, + ]) + .toArray(); + + const idsToDelete = agg.map((x) => x.idsToDelete).flat(); + + console.log(`Total records to delete: ${idsToDelete.length}`); + + console.log('Are you sure you want to delete all these records? (y/n)'); + const answer = await new Promise((resolve) => { + process.stdin.on('data', (data) => { + resolve(data.toString().trim()); + }); + }); + + if (answer !== 'y') { + console.log('Abort'); + process.exit(0); + } + + console.log('Deleting records...'); + + const result = await commitRecordsCollection.deleteMany({ + _id: { $in: idsToDelete.map((id) => new ObjectId(id)) }, + }); + + console.log(`Deleted records: ${result.deletedCount}`); + + process.exit(0); + } finally { + await closeMongoClient(); + } +})();