Files
money.sori.studio/prisma/schema.prisma
2026-08-13 17:47:01 +09:00

158 lines
4.2 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum TransactionType {
income
expense
}
enum AssetBalanceType {
cumulative
monthly_reset
}
enum RecurrenceFrequency {
none
daily
weekly
monthly
yearly
}
model User {
id String @id @default(cuid())
email String @unique
name String
passwordHash String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
assets Asset[]
categories Category[]
transactions Transaction[]
recurringTransactions RecurringTransaction[]
shareLinks ShareLink[]
}
model Asset {
id String @id @default(cuid())
userId String
name String
balanceType AssetBalanceType @default(cumulative)
initialBalance Int @default(0)
active Boolean @default(true)
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
transactions Transaction[]
@@index([userId, active, sortOrder])
}
model Category {
id String @id @default(cuid())
userId String
type TransactionType
name String
parentId String?
sortOrder Int @default(0)
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
parent Category? @relation("CategoryTree", fields: [parentId], references: [id], onDelete: Restrict)
children Category[] @relation("CategoryTree")
transactions Transaction[]
@@index([userId, type, active, sortOrder])
@@index([parentId])
}
model Transaction {
id String @id @default(cuid())
userId String
type TransactionType
occurredAt DateTime
assetId String
categoryId String
amount Int
title String
latitude Decimal? @db.Decimal(10, 7)
longitude Decimal? @db.Decimal(10, 7)
memo String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
asset Asset @relation(fields: [assetId], references: [id], onDelete: Restrict)
category Category @relation(fields: [categoryId], references: [id], onDelete: Restrict)
attachments TransactionAttachment[]
@@index([userId, occurredAt])
@@index([assetId])
@@index([categoryId])
}
model TransactionAttachment {
id String @id @default(cuid())
transactionId String
fileName String
filePath String
mimeType String
size Int
createdAt DateTime @default(now())
transaction Transaction @relation(fields: [transactionId], references: [id], onDelete: Cascade)
@@index([transactionId])
}
model RecurringTransaction {
id String @id @default(cuid())
userId String
type TransactionType
assetId String
categoryId String
amount Int
title String
memo String?
frequency RecurrenceFrequency @default(none)
interval Int @default(1)
repeatCount Int?
endDate DateTime?
nextRunAt DateTime?
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId, active, nextRunAt])
}
model ShareLink {
id String @id @default(cuid())
userId String
token String @unique
name String
expiresAt DateTime
revokedAt DateTime?
lastViewedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId, createdAt])
@@index([token, expiresAt, revokedAt])
}