Add backend API for personal finance management application
- 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.
This commit is contained in:
251
backend-api/prisma/schema.prisma
Normal file
251
backend-api/prisma/schema.prisma
Normal file
@@ -0,0 +1,251 @@
|
||||
// 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")
|
||||
}
|
||||
Reference in New Issue
Block a user