/// // Retention for the client_logs diagnostics (feedback 2 §4). These are for // live debugging, not an archive — delete everything older than 14 days daily // so the collection can't grow unbounded. Runs in PocketBase's cron scheduler. // // Every stale row goes in one run. The first version deleted a single page of // 500 records a night while ~1275 rows arrived a day, so on 2026-09-13 about // 14400 rows past the cutoff were still there, the oldest from 2026-08-19. // // Plain SQL rather than $app.delete() per record: client_logs has no file // fields, no collection has a relation pointing at it and no hook watches its // deletes, so the record path would only add a transaction and a cascade lookup // per row. Batches keep each write lock short so app requests are not held up. // The run leaves one line in PocketBase's logs (dashboard, /api/logs). cronAdd("trimClientLogs", "0 4 * * *", () => { const BATCH = 2000 const cutoff = new Date(Date.now() - 14 * 24 * 60 * 60 * 1000) .toISOString().replace("T", " ").slice(0, 19) + ".000Z" let deleted = 0 try { for (;;) { const n = $app.db().newQuery( "DELETE FROM client_logs WHERE id IN " + "(SELECT id FROM client_logs WHERE created < {:c} LIMIT {:n})" ).bind({ c: cutoff, n: BATCH }).execute().rowsAffected() deleted += n if (n < BATCH) break } $app.logger().info("trimClientLogs", "deleted", deleted, "cutoff", cutoff) } catch (e) { $app.logger().error("trimClientLogs failed", "error", String(e), "deleted", deleted, "cutoff", cutoff) } })