final touches for beta skymoney (at least i think)

This commit is contained in:
2026-01-18 00:00:44 -06:00
parent 4eae966f96
commit f4f0ae5df2
161 changed files with 26016 additions and 1966 deletions

View File

@@ -9,16 +9,40 @@ datasource db {
url = env("DATABASE_URL")
}
enum IncomeFrequency {
weekly
biweekly
monthly
}
enum IncomeType {
regular
irregular
}
model User {
id String @id @default(uuid())
email String @unique
createdAt DateTime @default(now())
id String @id @default(uuid())
email String @unique
passwordHash String?
displayName String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
incomeFrequency IncomeFrequency @default(biweekly)
incomeType IncomeType @default(regular)
firstIncomeDate DateTime? // Track when user's first income was received for accurate pay period calculation
pendingScheduledIncome Boolean @default(false) // Flag set when user dismisses payday overlay, cleared when paycheck is entered
timezone String @default("America/New_York") // IANA timezone identifier for accurate date calculations
fixedExpensePercentage Int @default(40) // Irregular income: percent of new income to auto-fund fixed expenses
totalBudgetCents BigInt?
budgetPeriod String @default("monthly")
variableCategories VariableCategory[]
fixedPlans FixedPlan[]
incomes IncomeEvent[]
allocations Allocation[]
transactions Transaction[]
budgetSessions BudgetSession[]
}
model VariableCategory {
@@ -30,6 +54,8 @@ model VariableCategory {
priority Int @default(100)
isSavings Boolean @default(false)
balanceCents BigInt @default(0)
savingsTargetCents BigInt?
transactions Transaction[] @relation("TransactionCategory")
@@unique([userId, name])
@@index([userId, priority])
@@ -44,9 +70,31 @@ model FixedPlan {
dueOn DateTime
totalCents BigInt
fundedCents BigInt @default(0)
currentFundedCents BigInt @default(0)
priority Int @default(100)
fundingMode String @default("auto-on-deposit")
scheduleJson Json?
periodDays Int @default(30)
frequency String? // "one-time", "weekly", "biweekly", "monthly"
autoRollover Boolean @default(true)
lastRollover DateTime?
lastFundingDate DateTime?
lastFundedPayPeriod DateTime? // Track when plan was last funded in a pay period
needsFundingThisPeriod Boolean @default(true) // Simple flag to track funding needs
// Auto-payment fields
autoPayEnabled Boolean @default(false)
paymentSchedule Json? // { frequency: "monthly", dayOfMonth: 1, minFundingPercent: 100 }
nextPaymentDate DateTime?
lastAutoPayment DateTime?
maxRetryAttempts Int @default(3)
// Overdue tracking fields
isOverdue Boolean @default(false)
overdueAmount BigInt @default(0)
overdueSince DateTime?
transactions Transaction[] @relation("TransactionPlan")
@@unique([userId, name])
@@index([userId, dueOn])
@@ -59,6 +107,8 @@ model IncomeEvent {
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
postedAt DateTime
amountCents BigInt
note String?
isScheduledIncome Boolean @default(false) // True if this is a regular paycheck (vs bonus/extra income)
allocations Allocation[]
@@index([userId, postedAt])
@@ -83,8 +133,31 @@ model Transaction {
occurredAt DateTime
kind String
categoryId String?
category VariableCategory? @relation("TransactionCategory", fields: [categoryId], references: [id], onDelete: SetNull)
planId String?
plan FixedPlan? @relation("TransactionPlan", fields: [planId], references: [id], onDelete: SetNull)
amountCents BigInt
note String?
receiptUrl String?
isAutoPayment Boolean @default(false)
isReconciled Boolean @default(false)
@@index([userId, occurredAt])
}
model BudgetSession {
id String @id @default(uuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
periodStart DateTime
periodEnd DateTime
totalBudgetCents BigInt
allocatedCents BigInt @default(0)
fundedCents BigInt @default(0)
availableCents BigInt @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([userId, periodStart])
@@index([userId, periodStart])
}