// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client" output = "../src/generated/prisma" } datasource db { provider = "postgresql" // Connection URLs moved to prisma.config.ts (Prisma 7 no longer supports // `url`/`directUrl` in the schema). The app passes a driver adapter to // PrismaClient; Migrate reads its connection from prisma.config.ts. } model Group { id String @id name String information String? @db.Text currency String @default("$") currencyCode String? participants Participant[] expenses Expense[] activities Activity[] createdAt DateTime @default(now()) deleteAt DateTime? } model Participant { id String @id name String group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) groupId String expensesPaidBy Expense[] expensesPaidFor ExpensePaidFor[] } model Category { id Int @id @default(autoincrement()) grouping String name String Expense Expense[] } model Expense { id String @id group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) expenseDate DateTime @default(dbgenerated("CURRENT_DATE")) @db.Date title String category Category? @relation(fields: [categoryId], references: [id]) categoryId Int @default(0) amount Int originalAmount Int? originalCurrency String? conversionRate Decimal? paidBy Participant @relation(fields: [paidById], references: [id], onDelete: Cascade) paidById String paidFor ExpensePaidFor[] groupId String isReimbursement Boolean @default(false) splitMode SplitMode @default(EVENLY) createdAt DateTime @default(now()) documents ExpenseDocument[] notes String? recurrenceRule RecurrenceRule? @default(NONE) recurringExpenseLink RecurringExpenseLink? recurringExpenseLinkId String? } model ExpenseDocument { id String @id url String width Int height Int Expense Expense? @relation(fields: [expenseId], references: [id]) expenseId String? } enum SplitMode { EVENLY BY_SHARES BY_PERCENTAGE BY_AMOUNT } model RecurringExpenseLink { id String @id groupId String currentFrameExpense Expense @relation(fields: [currentFrameExpenseId], references: [id], onDelete: Cascade) currentFrameExpenseId String @unique // Note: We do not want to link to the next expense because once it is created, it should be // treated as it's own independent entity. This means that if a user wants to delete an Expense // and any prior related recurring expenses, they'll need to delete them one by one. nextExpenseCreatedAt DateTime? nextExpenseDate DateTime // Day of month (1-31) a monthly series repeats on. Null for daily and weekly. // A 31st clamps in February and returns to the 31st in March. anchorDay Int? @@index([groupId]) @@index([groupId, nextExpenseCreatedAt, nextExpenseDate(sort: Desc)]) } enum RecurrenceRule { NONE DAILY WEEKLY MONTHLY } model ExpensePaidFor { expense Expense @relation(fields: [expenseId], references: [id], onDelete: Cascade) participant Participant @relation(fields: [participantId], references: [id], onDelete: Cascade) expenseId String participantId String shares Int @default(1) @@id([expenseId, participantId]) } model Activity { id String @id group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) groupId String time DateTime @default(now()) activityType ActivityType participantId String? expenseId String? data String? } enum ActivityType { UPDATE_GROUP CREATE_EXPENSE UPDATE_EXPENSE DELETE_EXPENSE SCHEDULE_GROUP_DELETION RESTORE_GROUP }