* Delete events older than the retention window.
(retentionDays: number = RETENTION_DAYS_DEFAULT)
| 161 | * Delete events older than the retention window. |
| 162 | */ |
| 163 | async cleanup(retentionDays: number = RETENTION_DAYS_DEFAULT): Promise<number> { |
| 164 | const BATCH_SIZE = 5000; |
| 165 | let totalDeleted = 0; |
| 166 | let batchDeleted: number; |
| 167 | |
| 168 | // Delete in batches to avoid long-running transactions and dead-tuple bloat |
| 169 | do { |
| 170 | const result = await query( |
| 171 | `DELETE FROM catalog_events |
| 172 | WHERE event_id IN ( |
| 173 | SELECT event_id FROM catalog_events |
| 174 | WHERE created_at < NOW() - INTERVAL '1 day' * $1 |
| 175 | ORDER BY event_id |
| 176 | LIMIT $2 |
| 177 | )`, |
| 178 | [retentionDays, BATCH_SIZE] |
| 179 | ); |
| 180 | batchDeleted = result.rowCount ?? 0; |
| 181 | totalDeleted += batchDeleted; |
| 182 | } while (batchDeleted === BATCH_SIZE); |
| 183 | |
| 184 | if (totalDeleted > 0) { |
| 185 | logger.info(`Cleaned up ${totalDeleted} catalog events older than ${retentionDays} days`); |
| 186 | } |
| 187 | return totalDeleted; |
| 188 | } |
| 189 | } |
no test coverage detected