frontend: kanal silme özelliği

Kanal detay sayfasına "Kanalı Sil" eklendi — kanal + tüm session/
segment/candidate geçmişini (dosyalar dahil) siler, ana sayfaya
yönlendirir. Yanlışlıkla/test amaçlı eklenen kanalları temizlemek için.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 21:44:26 +03:00
co-authored by Claude Sonnet 5
parent 2b8035ba68
commit ef1dc1b7ac
2 changed files with 27 additions and 2 deletions
+20
View File
@@ -3,6 +3,7 @@
import { unlink } from "node:fs/promises";
import { prisma } from "@streamclipper/db";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
export async function addChannel(formData: FormData) {
const name = String(formData.get("name") ?? "").trim();
@@ -39,6 +40,25 @@ export async function deleteCandidateSegment(candidateId: string) {
revalidatePath("/", "layout");
}
export async function deleteChannel(channelId: string) {
const sessions = await prisma.streamSession.findMany({
where: { channelId },
include: { segments: true },
});
const rawSegmentIds = sessions.flatMap((s) => s.segments.map((seg) => seg.id));
const filePaths = sessions.flatMap((s) => s.segments.map((seg) => seg.filePath));
await prisma.candidateSegment.deleteMany({ where: { rawSegmentId: { in: rawSegmentIds } } });
await prisma.rawSegment.deleteMany({ where: { sessionId: { in: sessions.map((s) => s.id) } } });
await prisma.streamSession.deleteMany({ where: { channelId } });
await prisma.channel.delete({ where: { id: channelId } });
await Promise.all(filePaths.map((p) => unlink(p).catch(() => {})));
revalidatePath("/", "layout");
redirect("/");
}
export async function updateYtdlpCookies(formData: FormData) {
const value = String(formData.get("cookies") ?? "").trim();
+7 -2
View File
@@ -2,7 +2,7 @@ import { notFound } from "next/navigation";
import Link from "next/link";
import { prisma } from "@streamclipper/db";
import { fetchChannelStatuses } from "../../../lib/apiDaemon";
import { deleteRawSegment, deleteCandidateSegment } from "../../actions";
import { deleteRawSegment, deleteCandidateSegment, deleteChannel } from "../../actions";
import { DeleteButton } from "../../components/DeleteButton";
export const dynamic = "force-dynamic";
@@ -51,7 +51,12 @@ export default async function ChannelDetailPage({ params }: { params: Promise<{
<>
<p><Link href="/">&larr; Kanal Durumu</Link></p>
<h1>{channel.name}</h1>
<div className="card-head">
<h1>{channel.name}</h1>
<form action={deleteChannel.bind(null, channel.id)}>
<DeleteButton confirmText="Bu kanalı ve tüm kayıt geçmişini silmek istediğine emin misin? Geri alınamaz." label="Kanalı Sil" />
</form>
</div>
<p className="mono">{channel.youtubeHandle} · {channel.channelId}</p>
<div className="card">