-
-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathcleanup-monthly.mjs
More file actions
107 lines (87 loc) · 2.44 KB
/
Copy pathcleanup-monthly.mjs
File metadata and controls
107 lines (87 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { initAdmin } from "./firebaseAdmin.mjs";
import { getFirestore } from "firebase-admin/firestore";
initAdmin();
const db = getFirestore();
const pageSize = Number(process.env.PAGE_SIZE || 400);
const preserveIds = (process.env.PRESERVE_ROOM_IDS || "")
.split(",")
.map(id => id.trim())
.filter(Boolean);
const preserveSet = new Set(["general", ...preserveIds]);
const deleteBatch = async query => {
const snapshot = await query.get();
if (snapshot.empty) {
return 0;
}
const batch = db.batch();
snapshot.docs.forEach(docSnap => batch.delete(docSnap.ref));
await batch.commit();
return snapshot.size;
};
const deleteCollection = async collectionRef => {
let deletedTotal = 0;
while (true) {
const deleted = await deleteBatch(collectionRef.limit(pageSize));
deletedTotal += deleted;
if (deleted < pageSize) {
break;
}
}
return deletedTotal;
};
const trimRoomMessages = async roomId => {
const messagesRef = db.collection("rooms").doc(roomId).collection("messages");
const keepSnapshot = await messagesRef
.orderBy("createdAt", "desc")
.limit(50)
.get();
if (keepSnapshot.empty) {
return 0;
}
const lastKept = keepSnapshot.docs[keepSnapshot.docs.length - 1];
let deletedTotal = 0;
while (true) {
const snapshot = await messagesRef
.orderBy("createdAt", "desc")
.startAfter(lastKept)
.limit(pageSize)
.get();
if (snapshot.empty) {
break;
}
const batch = db.batch();
snapshot.docs.forEach(docSnap => batch.delete(docSnap.ref));
await batch.commit();
deletedTotal += snapshot.size;
if (snapshot.size < pageSize) {
break;
}
}
return deletedTotal;
};
const cleanup = async () => {
const roomsSnapshot = await db.collection("rooms").get();
let deletedRooms = 0;
let deletedMessages = 0;
for (const roomDoc of roomsSnapshot.docs) {
const roomId = roomDoc.id;
if (preserveSet.has(roomId)) {
deletedMessages += await trimRoomMessages(roomId);
continue;
}
const messagesRef = db
.collection("rooms")
.doc(roomId)
.collection("messages");
deletedMessages += await deleteCollection(messagesRef);
await roomDoc.ref.delete();
deletedRooms += 1;
}
console.log(
`Cleanup complete. Deleted rooms: ${deletedRooms}. Deleted messages: ${deletedMessages}.`,
);
};
cleanup().catch(error => {
console.error("Cleanup failed:", error);
process.exitCode = 1;
});