generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) clerkId String @unique email String @unique firstName String? lastName String? imageUrl String? contracts Contract[] notifications Notification[] blockchainTransactions BlockchainTransaction[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([clerkId]) @@index([email]) } model Contract { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) // File info (user uploads) fileName String fileUrl String fileSize Int mimeType String // AI-determined fields (filled automatically) title String? type ContractType? provider String? policyNumber String? startDate DateTime? endDate DateTime? premium Decimal? @db.Decimal(10, 2) // Processing pipeline status ContractStatus @default(UPLOADED) // AI results extractedText String? @db.Text summary String? @db.Text keyPoints Json? // Blockchain proof-of-deposit documentHash String? // SHA-256 hash of the document txHash String? // Ethereum transaction hash blockNumber Int? // Block number where tx was mined blockTimestamp DateTime? // Timestamp of the block blockchainNetwork String? // 'hardhat' | 'sepolia' contractAddress String? // Smart contract address used // Relations notifications Notification[] ragChunks ContractRagChunk[] blockchainTransactions BlockchainTransaction[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@index([status]) @@index([type]) @@index([endDate]) } model ContractRagChunk { id String @id @default(cuid()) contractId String contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade) chunkIndex Int content String contentHash String embedding Float[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([contractId, chunkIndex]) @@index([contractId]) @@index([contentHash]) @@index([chunkIndex]) } model Notification { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) contractId String? contract Contract? @relation(fields: [contractId], references: [id], onDelete: SetNull) // Notification metadata type NotificationType title String message String icon String? // Icon type for UI // Action metadata actionType String? // e.g., "RENEWAL_REMINDER", "UPLOAD_SUCCESS", "ANALYSIS_COMPLETE" actionData Json? // Additional data for the action // Status tracking read Boolean @default(false) createdAt DateTime @default(now()) expiresAt DateTime? // Notification expiration time @@index([userId]) @@index([contractId]) @@index([type]) @@index([read]) @@index([createdAt]) } model BlockchainTransaction { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) contractId String contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade) documentHash String // SHA-256 hash of the document txHash String @unique // Ethereum transaction hash blockNumber Int // Block number where tx was mined blockTimestamp DateTime // Block timestamp = proof date network String // 'hardhat' | 'sepolia' contractAddress String // Smart contract address used status String @default("CONFIRMED") // PENDING, CONFIRMED, FAILED createdAt DateTime @default(now()) @@index([userId]) @@index([contractId]) @@index([txHash]) @@index([network]) } enum NotificationType { SUCCESS // Successful action WARNING // Warning/Alert ERROR // Error INFO // Informational DEADLINE // Deadline approaching } enum ContractType { INSURANCE_AUTO INSURANCE_HOME INSURANCE_HEALTH INSURANCE_LIFE LOAN CREDIT_CARD INVESTMENT OTHER } enum ContractStatus { UPLOADED // Just uploaded, waiting for processing PROCESSING // AI is analyzing COMPLETED // Everything done FAILED // Processing failed }