- Introduced a comprehensive backend API using TypeScript, Fastify, and PostgreSQL. - Added essential files including architecture documentation, environment configuration, and Docker setup. - Implemented RESTful routes for managing assets, liabilities, clients, invoices, and cashflow. - Established a robust database schema with Prisma for data management. - Integrated middleware for authentication and error handling. - Created service and repository layers to adhere to SOLID principles and clean architecture. - Included example environment variables for development, staging, and production setups.
252 lines
5.4 KiB
Plaintext
252 lines
5.4 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[]
|
|
|
|
@@map("users")
|
|
}
|
|
|
|
model Asset {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
name String
|
|
type AssetType
|
|
value Float
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@map("assets")
|
|
}
|
|
|
|
enum AssetType {
|
|
CASH
|
|
INVESTMENT
|
|
PROPERTY
|
|
VEHICLE
|
|
OTHER
|
|
}
|
|
|
|
model Liability {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
name String
|
|
type LiabilityType
|
|
balance Float
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@map("liabilities")
|
|
}
|
|
|
|
enum LiabilityType {
|
|
CREDIT_CARD
|
|
LOAN
|
|
MORTGAGE
|
|
OTHER
|
|
}
|
|
|
|
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 InvoiceStatus @default(DRAFT)
|
|
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")
|
|
}
|
|
|
|
enum InvoiceStatus {
|
|
DRAFT
|
|
SENT
|
|
PAID
|
|
OVERDUE
|
|
CANCELLED
|
|
}
|
|
|
|
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
|
|
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
|
|
category ExpenseCategory
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@map("expenses")
|
|
}
|
|
|
|
enum ExpenseCategory {
|
|
ESSENTIAL
|
|
DISCRETIONARY
|
|
}
|
|
|
|
model Transaction {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
description String
|
|
amount Float
|
|
type String
|
|
date DateTime
|
|
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
|
|
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())
|
|
categoryId String
|
|
name String
|
|
balance Float
|
|
interestRate Float?
|
|
minimumPayment Float?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
category DebtCategory @relation(fields: [categoryId], references: [id], onDelete: Cascade)
|
|
payments DebtPayment[]
|
|
|
|
@@index([categoryId])
|
|
@@map("debt_accounts")
|
|
}
|
|
|
|
model DebtPayment {
|
|
id String @id @default(uuid())
|
|
accountId String
|
|
amount Float
|
|
date DateTime
|
|
createdAt DateTime @default(now())
|
|
|
|
account DebtAccount @relation(fields: [accountId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([accountId, date])
|
|
@@map("debt_payments")
|
|
}
|