211 lines
4.8 KiB
Plaintext
211 lines
4.8 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum SubscriptionTier {
|
|
BASIC
|
|
PLUS
|
|
PREMIUM
|
|
}
|
|
|
|
enum IdentifierType {
|
|
EMAIL
|
|
PHONE
|
|
SSN
|
|
}
|
|
|
|
enum WatchListStatus {
|
|
ACTIVE
|
|
PAUSED
|
|
}
|
|
|
|
enum Severity {
|
|
INFO
|
|
WARNING
|
|
CRITICAL
|
|
}
|
|
|
|
enum AlertChannel {
|
|
EMAIL
|
|
PUSH
|
|
SMS
|
|
}
|
|
|
|
enum AlertStatus {
|
|
PENDING
|
|
SENT
|
|
READ
|
|
}
|
|
|
|
enum ScanJobStatus {
|
|
PENDING
|
|
RUNNING
|
|
COMPLETED
|
|
FAILED
|
|
}
|
|
|
|
enum DataSource {
|
|
HIBP
|
|
SECURITY_TRAILS
|
|
CENSYS
|
|
SHODAN
|
|
HONEYPOT
|
|
}
|
|
|
|
enum AnalysisJobStatus {
|
|
PENDING
|
|
RUNNING
|
|
COMPLETED
|
|
FAILED
|
|
}
|
|
|
|
enum AnalysisType {
|
|
SYNTHETIC_DETECTION
|
|
VOICE_MATCH
|
|
BATCH
|
|
}
|
|
|
|
enum DetectionVerdict {
|
|
NATURAL
|
|
SYNTHETIC
|
|
UNCERTAIN
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
email String @unique
|
|
name String?
|
|
subscriptionTier SubscriptionTier @default(BASIC)
|
|
familyGroupId String?
|
|
watchListItems WatchListItem[]
|
|
alerts Alert[]
|
|
scanJobs ScanJob[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([email])
|
|
}
|
|
|
|
model WatchListItem {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
identifierType IdentifierType
|
|
identifierValue String
|
|
identifierHash String @unique
|
|
status WatchListStatus @default(ACTIVE)
|
|
exposures Exposure[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([userId])
|
|
@@index([identifierHash])
|
|
}
|
|
|
|
model Exposure {
|
|
id String @id @default(uuid())
|
|
watchListItemId String
|
|
watchListItem WatchListItem @relation(fields: [watchListItemId], references: [id], onDelete: Cascade)
|
|
dataSource DataSource
|
|
breachName String
|
|
exposedAt DateTime
|
|
dataType String[]
|
|
severity Severity
|
|
details String?
|
|
contentHash String @unique
|
|
alert Alert?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([watchListItemId])
|
|
@@index([contentHash])
|
|
@@index([dataSource])
|
|
}
|
|
|
|
model Alert {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
exposureId String @unique
|
|
exposure Exposure @relation(fields: [exposureId], references: [id], onDelete: Cascade)
|
|
severity Severity
|
|
channel AlertChannel
|
|
status AlertStatus @default(PENDING)
|
|
dedupKey String
|
|
sentAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([userId, status])
|
|
@@index([dedupKey])
|
|
}
|
|
|
|
model ScanJob {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
status ScanJobStatus @default(PENDING)
|
|
source DataSource?
|
|
resultCount Int @default(0)
|
|
errorMessage String?
|
|
completedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([userId, status])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model VoiceEnrollment {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
label String
|
|
embeddingVector Float[]
|
|
embeddingDim Int @default(192)
|
|
audioFilePath String?
|
|
sampleRate Int @default(16000)
|
|
durationSec Float?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([userId])
|
|
@@index([embeddingDim])
|
|
}
|
|
|
|
model AnalysisJob {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
analysisType AnalysisType
|
|
audioFilePath String
|
|
status AnalysisJobStatus @default(PENDING)
|
|
result AnalysisResult?
|
|
errorMessage String?
|
|
completedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([userId, status])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model AnalysisResult {
|
|
id String @id @default(uuid())
|
|
analysisJobId String @unique
|
|
analysisJob AnalysisJob @relation(fields: [analysisJobId], references: [id], onDelete: Cascade)
|
|
syntheticScore Float
|
|
verdict DetectionVerdict
|
|
matchedEnrollmentId String?
|
|
matchedSimilarity Float?
|
|
confidence Float
|
|
processingTimeMs Int
|
|
modelVersion String?
|
|
metadata String?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([analysisJobId])
|
|
@@index([verdict])
|
|
}
|