more package declarations
This commit is contained in:
@@ -21,22 +21,22 @@ model User {
|
||||
name String?
|
||||
image String?
|
||||
role UserRole @default(user)
|
||||
|
||||
|
||||
// Relationships
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
familyGroups FamilyGroupMember[]
|
||||
familyGroupOwned FamilyGroup[] @relation("FamilyGroupOwner")
|
||||
subscriptions Subscription[]
|
||||
alerts Alert[]
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
familyGroups FamilyGroupMember[]
|
||||
familyGroupOwned FamilyGroup[] @relation("FamilyGroupOwner")
|
||||
subscriptions Subscription[]
|
||||
alerts Alert[]
|
||||
voiceEnrollments VoiceEnrollment[]
|
||||
voiceAnalyses VoiceAnalysis[]
|
||||
spamFeedback SpamFeedback[]
|
||||
spamRules SpamRule[]
|
||||
|
||||
voiceAnalyses VoiceAnalysis[]
|
||||
spamFeedback SpamFeedback[]
|
||||
spamRules SpamRule[]
|
||||
|
||||
// Audit
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([email])
|
||||
@@index([role])
|
||||
@@ -50,7 +50,7 @@ enum UserRole {
|
||||
}
|
||||
|
||||
model Account {
|
||||
id String @id @default(uuid())
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
provider String
|
||||
providerAccountId String
|
||||
@@ -59,11 +59,11 @@ model Account {
|
||||
expires_at Int?
|
||||
token_type String?
|
||||
scope String?
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([userId, provider, providerAccountId])
|
||||
@@index([userId])
|
||||
@@ -74,11 +74,11 @@ model Session {
|
||||
userId String
|
||||
sessionToken String @unique
|
||||
expires DateTime
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([sessionToken])
|
||||
@@index([userId])
|
||||
@@ -89,30 +89,30 @@ model Session {
|
||||
// ============================================
|
||||
|
||||
model FamilyGroup {
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
ownerId String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
owner User @relation("FamilyGroupOwner", fields: [ownerId], references: [id])
|
||||
members FamilyGroupMember[]
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
ownerId String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
owner User @relation("FamilyGroupOwner", fields: [ownerId], references: [id])
|
||||
members FamilyGroupMember[]
|
||||
subscriptions Subscription[]
|
||||
|
||||
|
||||
@@index([ownerId])
|
||||
@@index([name])
|
||||
}
|
||||
|
||||
model FamilyGroupMember {
|
||||
id String @id @default(uuid())
|
||||
groupId String
|
||||
userId String
|
||||
role FamilyMemberRole @default(member)
|
||||
joinedAt DateTime @default(now())
|
||||
|
||||
group FamilyGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
id String @id @default(uuid())
|
||||
groupId String
|
||||
userId String
|
||||
role FamilyMemberRole @default(member)
|
||||
joinedAt DateTime @default(now())
|
||||
|
||||
group FamilyGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@ -128,25 +128,28 @@ enum FamilyMemberRole {
|
||||
}
|
||||
|
||||
model Subscription {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
familyGroupId String?
|
||||
stripeId String? @unique
|
||||
tier SubscriptionTier @default(basic)
|
||||
status SubscriptionStatus @default(active)
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
familyGroupId String?
|
||||
stripeId String? @unique
|
||||
tier SubscriptionTier @default(basic)
|
||||
status SubscriptionStatus @default(active)
|
||||
currentPeriodStart DateTime
|
||||
currentPeriodEnd DateTime
|
||||
cancelAtPeriodEnd Boolean @default(false)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
familyGroup FamilyGroup? @relation(fields: [familyGroupId], references: [id])
|
||||
|
||||
watchlistItems WatchlistItem[]
|
||||
exposures Exposure[]
|
||||
alerts Alert[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
currentPeriodEnd DateTime
|
||||
cancelAtPeriodEnd Boolean @default(false)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
familyGroup FamilyGroup? @relation(fields: [familyGroupId], references: [id])
|
||||
|
||||
watchlistItems WatchlistItem[]
|
||||
exposures Exposure[]
|
||||
alerts Alert[]
|
||||
propertyWatchlistItems PropertyWatchlistItem[]
|
||||
propertySnapshots PropertySnapshot[]
|
||||
propertyChanges PropertyChange[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
@@index([familyGroupId])
|
||||
@@ -173,18 +176,18 @@ enum SubscriptionStatus {
|
||||
// ============================================
|
||||
|
||||
model WatchlistItem {
|
||||
id String @id @default(uuid())
|
||||
id String @id @default(uuid())
|
||||
subscriptionId String
|
||||
type WatchlistType
|
||||
value String
|
||||
hash String // SHA-256 hash for deduplication
|
||||
isActive Boolean @default(true)
|
||||
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
exposures Exposure[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
type WatchlistType
|
||||
value String
|
||||
hash String // SHA-256 hash for deduplication
|
||||
isActive Boolean @default(true)
|
||||
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
exposures Exposure[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([subscriptionId, type, hash])
|
||||
@@index([subscriptionId])
|
||||
@@ -201,7 +204,7 @@ enum WatchlistType {
|
||||
}
|
||||
|
||||
model Exposure {
|
||||
id String @id @default(uuid())
|
||||
id String @id @default(uuid())
|
||||
subscriptionId String
|
||||
watchlistItemId String?
|
||||
source ExposureSource
|
||||
@@ -209,16 +212,16 @@ model Exposure {
|
||||
identifier String
|
||||
identifierHash String
|
||||
severity ExposureSeverity @default(info)
|
||||
metadata Json? // Additional source-specific data
|
||||
isFirstTime Boolean @default(false)
|
||||
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
watchlistItem WatchlistItem? @relation(fields: [watchlistItemId], references: [id])
|
||||
alerts Alert[]
|
||||
|
||||
detectedAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
metadata Json? // Additional source-specific data
|
||||
isFirstTime Boolean @default(false)
|
||||
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
watchlistItem WatchlistItem? @relation(fields: [watchlistItemId], references: [id])
|
||||
alerts Alert[]
|
||||
|
||||
detectedAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([subscriptionId])
|
||||
@@index([watchlistItemId])
|
||||
@@ -228,7 +231,7 @@ model Exposure {
|
||||
}
|
||||
|
||||
enum ExposureSource {
|
||||
hibp // Have I Been Pwned
|
||||
hibp // Have I Been Pwned
|
||||
securityTrails
|
||||
censys
|
||||
darkWebForum
|
||||
@@ -247,24 +250,27 @@ enum ExposureSeverity {
|
||||
// ============================================
|
||||
|
||||
model Alert {
|
||||
id String @id @default(uuid())
|
||||
subscriptionId String
|
||||
userId String
|
||||
exposureId String?
|
||||
type AlertType
|
||||
title String
|
||||
message String
|
||||
severity AlertSeverity @default(info)
|
||||
isRead Boolean @default(false)
|
||||
readAt DateTime?
|
||||
channel AlertChannel[] // Array of notification channels
|
||||
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
exposure Exposure? @relation(fields: [exposureId], references: [id])
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(uuid())
|
||||
subscriptionId String
|
||||
userId String
|
||||
exposureId String?
|
||||
type AlertType
|
||||
title String
|
||||
message String
|
||||
severity AlertSeverity @default(info)
|
||||
isRead Boolean @default(false)
|
||||
readAt DateTime?
|
||||
channel AlertChannel[] // Array of notification channels
|
||||
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
exposure Exposure? @relation(fields: [exposureId], references: [id])
|
||||
propertyChange PropertyChange? @relation("PropertyAlerts", fields: [propertyChangeId], references: [id])
|
||||
|
||||
propertyChangeId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([subscriptionId])
|
||||
@@index([userId])
|
||||
@@ -297,37 +303,37 @@ enum AlertChannel {
|
||||
// ============================================
|
||||
|
||||
model VoiceEnrollment {
|
||||
id String @id @default(uuid())
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
name String
|
||||
voiceHash String // FAISS embedding hash
|
||||
audioMetadata Json? // Sample rate, duration, etc.
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
analyses VoiceAnalysis[]
|
||||
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
voiceHash String // FAISS embedding hash
|
||||
audioMetadata Json? // Sample rate, duration, etc.
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
analyses VoiceAnalysis[]
|
||||
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
@@index([voiceHash])
|
||||
}
|
||||
|
||||
model VoiceAnalysis {
|
||||
id String @id @default(uuid())
|
||||
enrollmentId String?
|
||||
userId String
|
||||
audioHash String // Content hash of audio file
|
||||
isSynthetic Boolean
|
||||
confidence Float // 0.0 to 1.0
|
||||
analysisResult Json // Full ML analysis results
|
||||
audioUrl String // S3 storage URL
|
||||
|
||||
enrollment VoiceEnrollment? @relation(fields: [enrollmentId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
id String @id @default(uuid())
|
||||
enrollmentId String?
|
||||
userId String
|
||||
audioHash String // Content hash of audio file
|
||||
isSynthetic Boolean
|
||||
confidence Float // 0.0 to 1.0
|
||||
analysisResult Json // Full ML analysis results
|
||||
audioUrl String // S3 storage URL
|
||||
|
||||
enrollment VoiceEnrollment? @relation(fields: [enrollmentId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([userId])
|
||||
@@index([enrollmentId])
|
||||
@@ -339,19 +345,19 @@ model VoiceAnalysis {
|
||||
// ============================================
|
||||
|
||||
model SpamFeedback {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
phoneNumber String
|
||||
phoneNumberHash String // SHA-256 hash
|
||||
isSpam Boolean
|
||||
confidence Float? // ML model confidence
|
||||
feedbackType FeedbackType
|
||||
metadata Json? // Call duration, time, etc.
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
phoneNumber String
|
||||
phoneNumberHash String // SHA-256 hash
|
||||
isSpam Boolean
|
||||
confidence Float? // ML model confidence
|
||||
feedbackType FeedbackType
|
||||
metadata Json? // Call duration, time, etc.
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
@@index([phoneNumberHash])
|
||||
@@ -366,19 +372,19 @@ enum FeedbackType {
|
||||
}
|
||||
|
||||
model SpamRule {
|
||||
id String @id @default(uuid())
|
||||
userId String?
|
||||
isGlobal Boolean @default(false)
|
||||
ruleType RuleType
|
||||
pattern String
|
||||
action RuleAction
|
||||
priority Int @default(0)
|
||||
isActive Boolean @default(true)
|
||||
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(uuid())
|
||||
userId String?
|
||||
isGlobal Boolean @default(false)
|
||||
ruleType RuleType
|
||||
pattern String
|
||||
action RuleAction
|
||||
priority Int @default(0)
|
||||
isActive Boolean @default(true)
|
||||
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
@@index([isGlobal])
|
||||
@@ -405,16 +411,16 @@ enum RuleAction {
|
||||
// ============================================
|
||||
|
||||
model AuditLog {
|
||||
id String @id @default(uuid())
|
||||
userId String?
|
||||
action String
|
||||
resource String
|
||||
id String @id @default(uuid())
|
||||
userId String?
|
||||
action String
|
||||
resource String
|
||||
resourceId String?
|
||||
changes Json? // Before/after values
|
||||
metadata Json?
|
||||
ipAddress String?
|
||||
userAgent String?
|
||||
|
||||
changes Json? // Before/after values
|
||||
metadata Json?
|
||||
ipAddress String?
|
||||
userAgent String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([userId])
|
||||
@@ -429,8 +435,8 @@ model KPISnapshot {
|
||||
metricName String
|
||||
metricValue Float
|
||||
metadata Json?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([metricName])
|
||||
@@index([date])
|
||||
@@ -441,23 +447,23 @@ model KPISnapshot {
|
||||
// ============================================
|
||||
|
||||
model WaitlistEntry {
|
||||
id String @id @default(uuid())
|
||||
email String
|
||||
name String?
|
||||
source String? // landing_page, blog, referral, social, paid_search
|
||||
tier SubscriptionTier? // interest level
|
||||
utmSource String?
|
||||
utmMedium String?
|
||||
utmCampaign String?
|
||||
metadata Json? // Browser, device, location, etc.
|
||||
|
||||
id String @id @default(uuid())
|
||||
email String
|
||||
name String?
|
||||
source String? // landing_page, blog, referral, social, paid_search
|
||||
tier SubscriptionTier? // interest level
|
||||
utmSource String?
|
||||
utmMedium String?
|
||||
utmCampaign String?
|
||||
metadata Json? // Browser, device, location, etc.
|
||||
|
||||
// Conversion tracking
|
||||
convertedAt DateTime?
|
||||
convertedToUserId String?
|
||||
convertedAt DateTime?
|
||||
convertedToUserId String?
|
||||
convertedToSubscriptionId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([email])
|
||||
@@index([source])
|
||||
@@ -465,22 +471,127 @@ model WaitlistEntry {
|
||||
}
|
||||
|
||||
model BlogPost {
|
||||
id String @id @default(uuid())
|
||||
slug String @unique
|
||||
id String @id @default(uuid())
|
||||
slug String @unique
|
||||
title String
|
||||
excerpt String?
|
||||
content String
|
||||
authorName String?
|
||||
coverImageUrl String?
|
||||
tags String[] // Array of tag strings
|
||||
published Boolean @default(false)
|
||||
tags String[] // Array of tag strings
|
||||
published Boolean @default(false)
|
||||
publishedAt DateTime?
|
||||
viewCount Int @default(0)
|
||||
viewCount Int @default(0)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([slug])
|
||||
@@index([published, publishedAt])
|
||||
@@index([tags])
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Home Title Property Monitoring Models
|
||||
// ============================================
|
||||
|
||||
model PropertyWatchlistItem {
|
||||
id String @id @default(uuid())
|
||||
subscriptionId String
|
||||
address String
|
||||
parcelId String
|
||||
ownerName String
|
||||
streetAddress String
|
||||
city String
|
||||
state String
|
||||
zipCode String
|
||||
latitude Float?
|
||||
longitude Float?
|
||||
isActive Boolean @default(true)
|
||||
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
snapshots PropertySnapshot[]
|
||||
changes PropertyChange[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([subscriptionId, parcelId])
|
||||
@@index([subscriptionId])
|
||||
@@index([parcelId])
|
||||
@@index([address])
|
||||
}
|
||||
|
||||
model PropertySnapshot {
|
||||
id String @id @default(uuid())
|
||||
propertyWatchlistItemId String
|
||||
subscriptionId String
|
||||
ownerName String
|
||||
ownerAddress String?
|
||||
assessmentValue Int?
|
||||
assessedYear Int?
|
||||
taxAmount Float?
|
||||
taxYear Int?
|
||||
lienData Json? // Array of liens with amounts, types, dates
|
||||
deedData Json? // Latest deed information
|
||||
metadata Json? // Additional property data from sources
|
||||
|
||||
propertyWatchlistItem PropertyWatchlistItem @relation(fields: [propertyWatchlistItemId], references: [id], onDelete: Cascade)
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
changes PropertyChange[] @relation("SnapshotChanges")
|
||||
|
||||
snapshotDate DateTime
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([propertyWatchlistItemId])
|
||||
@@index([subscriptionId])
|
||||
@@index([snapshotDate])
|
||||
}
|
||||
|
||||
model PropertyChange {
|
||||
id String @id @default(uuid())
|
||||
propertyWatchlistItemId String?
|
||||
subscriptionId String
|
||||
snapshotId String? // Reference to the snapshot where change was detected
|
||||
changeType PropertyChangeType
|
||||
severity PropertyChangeSeverity @default(info)
|
||||
previousValue Json? // Before state
|
||||
newValue Json? // After state
|
||||
diff Json? // Computed diff between states
|
||||
title String // Short description
|
||||
description String // Detailed explanation
|
||||
isResolved Boolean @default(false)
|
||||
resolvedAt DateTime?
|
||||
resolvedByUserId String?
|
||||
|
||||
propertyWatchlistItem PropertyWatchlistItem? @relation(fields: [propertyWatchlistItemId], references: [id])
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
snapshot PropertySnapshot? @relation("SnapshotChanges", fields: [snapshotId], references: [id])
|
||||
alerts Alert[] @relation("PropertyAlerts")
|
||||
|
||||
detectedAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([propertyWatchlistItemId])
|
||||
@@index([subscriptionId])
|
||||
@@index([changeType])
|
||||
@@index([severity])
|
||||
@@index([detectedAt])
|
||||
@@index([isResolved])
|
||||
}
|
||||
|
||||
enum PropertyChangeType {
|
||||
ownership_transfer
|
||||
deed_change
|
||||
lien_filing
|
||||
tax_change
|
||||
assessment_change
|
||||
}
|
||||
|
||||
enum PropertyChangeSeverity {
|
||||
info
|
||||
warning
|
||||
critical
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user