// Database schema for Personal Finances API generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(uuid()) email String @unique password String name String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt assets Asset[] liabilities Liability[] snapshots NetWorthSnapshot[] clients Client[] invoices Invoice[] incomeSources IncomeSource[] expenses Expense[] transactions Transaction[] debtCategories DebtCategory[] debtAccounts DebtAccount[] @@map("users") } model Asset { id String @id @default(uuid()) userId String name String type String // 'cash' | 'investment' | 'property' | 'vehicle' | 'other' value Float createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@map("assets") } model Liability { id String @id @default(uuid()) userId String name String type String // 'credit_card' | 'loan' | 'mortgage' | 'other' balance Float createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@map("liabilities") } model NetWorthSnapshot { id String @id @default(uuid()) userId String date DateTime totalAssets Float totalLiabilities Float netWorth Float createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId, date]) @@map("net_worth_snapshots") } model Client { id String @id @default(uuid()) userId String name String email String phone String? company String? address String? notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) invoices Invoice[] @@index([userId]) @@map("clients") } model Invoice { id String @id @default(uuid()) userId String clientId String invoiceNumber String status String @default("draft") // 'draft' | 'sent' | 'paid' | 'overdue' | 'cancelled' issueDate DateTime dueDate DateTime subtotal Float tax Float @default(0) total Float notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) client Client @relation(fields: [clientId], references: [id], onDelete: Restrict) lineItems InvoiceLineItem[] @@unique([userId, invoiceNumber]) @@index([userId, status]) @@index([clientId]) @@map("invoices") } model InvoiceLineItem { id String @id @default(uuid()) invoiceId String description String quantity Float unitPrice Float total Float invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade) @@index([invoiceId]) @@map("invoice_line_items") } model IncomeSource { id String @id @default(uuid()) userId String name String amount Float frequency String // 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'once' category String nextDate DateTime? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@map("income_sources") } model Expense { id String @id @default(uuid()) userId String name String amount Float frequency String // 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'once' category String nextDate DateTime? isActive Boolean @default(true) isEssential Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@map("expenses") } model Transaction { id String @id @default(uuid()) userId String type String // 'income' | 'expense' name String amount Float category String date DateTime note String? createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId, date]) @@map("transactions") } model DebtCategory { id String @id @default(uuid()) userId String name String color String @default("#6b7280") isDefault Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) accounts DebtAccount[] @@index([userId]) @@map("debt_categories") } model DebtAccount { id String @id @default(uuid()) userId String categoryId String name String institution String? accountNumber String? // Last 4 digits only originalBalance Float currentBalance Float interestRate Float? minimumPayment Float? dueDay Int? // 1-31 notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) category DebtCategory @relation(fields: [categoryId], references: [id], onDelete: Cascade) payments DebtPayment[] @@index([userId]) @@index([categoryId]) @@map("debt_accounts") } model DebtPayment { id String @id @default(uuid()) accountId String amount Float date DateTime note String? createdAt DateTime @default(now()) account DebtAccount @relation(fields: [accountId], references: [id], onDelete: Cascade) @@index([accountId, date]) @@map("debt_payments") }