generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(uuid()) email String @unique passwordHash String fullName String? phone String? companyName String? addressLine1 String? addressLine2 String? city String? state String? postalCode String? country String? emailVerified Boolean @default(false) twoFactorEnabled Boolean @default(false) twoFactorSecret String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt accounts Account[] rules Rule[] exports ExportLog[] auditLogs AuditLog[] googleConnection GoogleConnection? emailVerificationToken EmailVerificationToken? passwordResetTokens PasswordResetToken[] refreshTokens RefreshToken[] subscription Subscription? taxReturns TaxReturn[] } model Account { id String @id @default(uuid()) userId String institutionName String accountType String mask String? plaidAccessToken String? plaidItemId String? plaidAccountId String? @unique currentBalance Decimal? availableBalance Decimal? isoCurrencyCode String? lastBalanceSync DateTime? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id]) transactionsRaw TransactionRaw[] } model TransactionRaw { id String @id @default(uuid()) accountId String bankTransactionId String @unique date DateTime amount Decimal description String rawPayload Json ingestedAt DateTime @default(now()) source String account Account @relation(fields: [accountId], references: [id]) derived TransactionDerived? ruleExecutions RuleExecution[] } model TransactionDerived { id String @id @default(uuid()) rawTransactionId String @unique userCategory String? userNotes String? isHidden Boolean @default(false) modifiedAt DateTime @default(now()) modifiedBy String raw TransactionRaw @relation(fields: [rawTransactionId], references: [id]) } model Rule { id String @id @default(uuid()) userId String name String priority Int conditions Json actions Json isActive Boolean @default(true) createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) executions RuleExecution[] } model RuleExecution { id String @id @default(uuid()) ruleId String transactionId String executedAt DateTime @default(now()) result Json rule Rule @relation(fields: [ruleId], references: [id]) transaction TransactionRaw @relation(fields: [transactionId], references: [id]) } model ExportLog { id String @id @default(uuid()) userId String filters Json rowCount Int createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) } model AuditLog { id String @id @default(uuid()) userId String action String metadata Json createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) } model GoogleConnection { id String @id @default(uuid()) userId String @unique googleEmail String refreshToken String accessToken String? spreadsheetId String? isConnected Boolean @default(true) connectedAt DateTime @default(now()) lastSyncedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model EmailVerificationToken { id String @id @default(uuid()) userId String @unique token String @unique expiresAt DateTime createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model PasswordResetToken { id String @id @default(uuid()) userId String token String @unique expiresAt DateTime usedAt DateTime? createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model RefreshToken { id String @id @default(uuid()) userId String tokenHash String @unique expiresAt DateTime revokedAt DateTime? createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model Subscription { id String @id @default(uuid()) userId String @unique plan String @default("free") stripeCustomerId String? stripeSubId String? currentPeriodEnd DateTime? cancelAtPeriodEnd Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model TaxReturn { id String @id @default(uuid()) userId String taxYear Int filingType String jurisdictions Json status String @default("draft") summary Json @default("{}") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id]) documents TaxDocument[] } model TaxDocument { id String @id @default(uuid()) taxReturnId String docType String metadata Json @default("{}") createdAt DateTime @default(now()) taxReturn TaxReturn @relation(fields: [taxReturnId], references: [id], onDelete: Cascade) }