Files
iistwin/server/workers/error-logs-retention.ts
Ильяс Султанов abd5d4b65f chore(ci+logs): eslint в CI, npm audit, logger с уровнями, retention error_logs
Шаги 1.6 и 1.7 плана production-готовности:
- eslint flat-config (баг-ловушки, легаси warn), lint блокирующий в pr-check
- npm audit --audit-level=high в CI (отчёт)
- фикс реального бага: условный useRef в TaskTitleInline
- server/utils/logger.ts (LOG_LEVEL/LOG_FORMAT) в 5 горячих местах
- error_logs retention 30 дней (worker), redactSensitive в captureErrorLog
- 0 errors lint, vitest 96/96
2026-09-08 00:11:38 +03:00

51 lines
2.0 KiB
TypeScript

import { db, withSuperAdmin } from "../db";
import { sql } from "drizzle-orm";
import { logger } from "../utils/logger";
/**
* Retention журнала ошибок API (таблица error_logs, см. shared/schema.ts).
*
* Раз в сутки удаляет записи старше RETENTION_DAYS дней. Без отдельной
* миграции: таблица и индексы уже существуют. Таймер unref'нут, чтобы
* не удерживать процесс (и не мешать тестам завершаться).
* Первый запуск — сразу при старте, дальше — каждые 24 часа.
*/
const log = logger("error-logs-retention");
const TICK_MS = 24 * 60 * 60 * 1000; // раз в сутки
const RETENTION_DAYS = 30;
let isRunning = false;
async function cleanup(): Promise<void> {
// withSuperAdmin — единая точка для фоновых задач вне контекста организации
const result = await withSuperAdmin(() =>
db.execute(sql`
DELETE FROM error_logs
WHERE created_at < now() - make_interval(days => ${RETENTION_DAYS})
`)
);
const deleted = (result as { rowCount?: number }).rowCount ?? 0;
if (deleted > 0) {
log.info(`Удалено устаревших записей error_logs: ${deleted} (старше ${RETENTION_DAYS} дней)`);
} else {
log.debug(`Устаревших записей error_logs нет (старше ${RETENTION_DAYS} дней)`);
}
}
export function startErrorLogsRetention(): void {
if (isRunning) return;
isRunning = true;
const timer = setInterval(() => {
cleanup().catch((err) => log.error("Cleanup error:", err));
}, TICK_MS);
timer.unref?.();
// Первый прогон сразу после старта (в фоне, не блокируя listen)
cleanup().catch((err) => log.error("Initial cleanup error:", err));
log.info(`started (retention ${RETENTION_DAYS} дней, тик раз в сутки)`);
}