feat: işlenmiş ham kayıtları 24 saat sonra otomatik sil

PRD'nin auto-purge lifecycle'ı: RawSegment analiz tamamlanmış
(PROCESSED/DISCARDED) ve hiçbir candidate'i PENDING_STT'de değilse
(yani hâlâ transkribe edilmeyi bekleyen yoksa) 24 saatten (yapılandırı-
labilir: RAW_SEGMENT_TTL_HOURS) eskiyse DB kaydı + dosyası siliniyor.
Saatlik kontrol ediliyor, api-daemon başlarken de bir kere çalışıyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-01 12:27:36 +03:00
co-authored by Claude Sonnet 5
parent 775633bfd0
commit 783125b8f2
5 changed files with 50 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
import { unlink } from "node:fs/promises";
import { prisma } from "@streamclipper/db";
import { env } from "./env";
const CHECK_INTERVAL_MS = 60 * 60 * 1000; // hourly
/**
* PRD's auto-purge lifecycle: processed raw recordings get deleted 24h after
* capture. Only segments that are done being analyzed (PROCESSED/DISCARDED)
* and have no candidate still waiting on STT are eligible — deleting a raw
* file mid-analysis or mid-transcription would break the pipeline for it.
*/
async function cleanupOnce(): Promise<void> {
const cutoff = new Date(Date.now() - env.rawSegmentTtlHours * 60 * 60 * 1000);
const staleSegments = await prisma.rawSegment.findMany({
where: {
createdAt: { lt: cutoff },
status: { in: ["PROCESSED", "DISCARDED"] },
candidates: { none: { status: "PENDING_STT" } },
},
});
for (const segment of staleSegments) {
await prisma.candidateSegment.deleteMany({ where: { rawSegmentId: segment.id } });
await prisma.rawSegment.delete({ where: { id: segment.id } });
await unlink(segment.filePath).catch(() => {});
}
if (staleSegments.length > 0) {
console.log(`[cleanup] removed ${staleSegments.length} raw segment(s) older than ${env.rawSegmentTtlHours}h`);
}
}
export function startCleanupLoop(): NodeJS.Timeout {
console.log(`[cleanup] checking every ${CHECK_INTERVAL_MS}ms, TTL ${env.rawSegmentTtlHours}h`);
cleanupOnce().catch((err) => console.error("[cleanup] initial run failed:", err));
return setInterval(() => {
cleanupOnce().catch((err) => console.error("[cleanup] run failed:", err));
}, CHECK_INTERVAL_MS);
}