- Modified TypeScript configuration to disable strict mode and allow importing TypeScript extensions. - Updated Prisma schema to enhance the User model with a new debtAccounts field and refined asset/liability types. - Adjusted environment variable parsing for PORT to use coercion for better type handling. - Refactored various controllers and repositories to utilize type imports for better clarity and maintainability. - Enhanced service layers with new methods for retrieving assets by type and calculating invoice statistics. - Introduced new types for invoice statuses and asset types to ensure consistency across the application.
245 lines
6.1 KiB
Plaintext
245 lines
6.1 KiB
Plaintext
// 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")
|
|
}
|