Files
screenclipper/packages/db/prisma/schema.prisma
T
ayrisdevandClaude Sonnet 5 fb8485d638 feat: panele auth sistemi ekle (kullanıcı/şifre + oturum + middleware)
Panel şu ana kadar herkese açıktı — URL'yi bilen herkes kanal
ekleyip/silebilir, cookie güncelleyebilir, kayıt indirebilirdi.

- users tablosu (bcrypt şifre hash'i)
- /login: hiç kullanıcı yoksa "ilk admin hesabı oluştur" formu, varsa
  normal giriş formu
- jose ile imzalanmış, httpOnly çerezde tutulan 30 günlük oturum
- middleware.ts: /login hariç tüm rotaları korur (video stream route'u
  dahil — aynı origin istekleri çerezi otomatik taşır)
- layout: oturum yoksa nav hiç gösterilmiyor, varsa kullanıcı adı +
  çıkış butonu ekleniyor

SESSION_SECRET production'da zorunlu (docker-compose derleme zamanında
kontrol ediyor); Coolify'a rastgele bir değer eklendi.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 11:26:42 +03:00

96 lines
2.7 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum RawSegmentStatus {
PENDING
PROCESSED
DISCARDED
}
enum CandidateSegmentStatus {
PENDING_STT
TRANSCRIBED
FAILED
}
model Channel {
id String @id @default(cuid())
name String
youtubeHandle String @map("youtube_handle")
channelId String @unique @map("channel_id")
isActive Boolean @default(true) @map("is_active")
lastCheckedAt DateTime? @map("last_checked_at")
createdAt DateTime @default(now()) @map("created_at")
sessions StreamSession[]
@@map("channels")
}
model StreamSession {
id String @id @default(cuid())
channelId String @map("channel_id")
channel Channel @relation(fields: [channelId], references: [id])
liveVideoId String? @map("live_video_id")
startedAt DateTime @default(now()) @map("started_at")
endedAt DateTime? @map("ended_at")
totalSegments Int @default(0) @map("total_segments")
segments RawSegment[]
@@map("stream_sessions")
}
model RawSegment {
id String @id @default(cuid())
sessionId String @map("session_id")
session StreamSession @relation(fields: [sessionId], references: [id])
filePath String @map("file_path")
duration Int
startedAt DateTime @map("started_at")
status RawSegmentStatus @default(PENDING)
createdAt DateTime @default(now()) @map("created_at")
candidates CandidateSegment[]
@@map("raw_segments")
}
model CandidateSegment {
id String @id @default(cuid())
rawSegmentId String @map("raw_segment_id")
rawSegment RawSegment @relation(fields: [rawSegmentId], references: [id])
startSec Int @map("start_sec")
endSec Int @map("end_sec")
audioPeakScore Float? @map("audio_peak_score")
chatVelocityScore Float? @map("chat_velocity_score")
transcriptJson Json? @map("transcript_json")
status CandidateSegmentStatus @default(PENDING_STT)
createdAt DateTime @default(now()) @map("created_at")
@@map("candidate_segments")
}
model AppSetting {
key String @id
value String
updatedAt DateTime @updatedAt @map("updated_at")
@@map("app_settings")
}
model User {
id String @id @default(cuid())
username String @unique
passwordHash String @map("password_hash")
createdAt DateTime @default(now()) @map("created_at")
@@map("users")
}