fix(reliability): дневной лимит imggen в БД + ретеншн error_log (Спринт3)
- imggen: дневной счётчик генераций перенесён из in-memory Map в таблицу imggen_usage (миграция 070) — переживает рестарт. Cooldown остаётся в памяти, но добавлена периодическая чистка Map + старых строк imggen_usage (>7 дн). - classroom-cleanup: ретеншн error_log (app_settings.error_log_retention_days, по умолч. 30; 0 = выкл) в том же суточном джобе. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -50,16 +50,31 @@ function cleanupClassroomData() {
|
||||
return { sessions: ids.size, strokes, files };
|
||||
}
|
||||
|
||||
/* Ретеншн error_log: не копим бесконечно (период app_settings.error_log_retention_days,
|
||||
по умолчанию 30; 0 = выключено). */
|
||||
function cleanupErrorLog() {
|
||||
let days = 30;
|
||||
try {
|
||||
const r = db.prepare("SELECT value FROM app_settings WHERE key='error_log_retention_days'").get();
|
||||
if (r && r.value != null) { const n = Number(r.value); if (Number.isFinite(n) && n >= 0) days = n; }
|
||||
} catch (e) {}
|
||||
if (!days) return 0;
|
||||
try { return db.prepare("DELETE FROM error_log WHERE created_at < datetime('now', ?)").run('-' + days + ' days').changes; }
|
||||
catch (e) { return 0; }
|
||||
}
|
||||
|
||||
/* Раз в сутки + один прогон через минуту после старта. unref — не держит процесс. */
|
||||
function schedule() {
|
||||
const run = () => {
|
||||
try {
|
||||
const r = cleanupClassroomData();
|
||||
if (r && (r.strokes || r.files)) logger.info('classroom-cleanup', r);
|
||||
const errLogged = cleanupErrorLog();
|
||||
if (errLogged) logger.info('error-log-cleanup', { deleted: errLogged });
|
||||
} catch (e) {}
|
||||
};
|
||||
setTimeout(run, 60_000).unref();
|
||||
setInterval(run, 24 * 60 * 60 * 1000).unref();
|
||||
}
|
||||
|
||||
module.exports = { cleanupClassroomData, schedule };
|
||||
module.exports = { cleanupClassroomData, cleanupErrorLog, schedule };
|
||||
|
||||
Reference in New Issue
Block a user