feat: category import from CSV + budget auto-assign rules

Category:
- Add categoryColumn to NormalizerConfig and NormalizedRow
- Map 'Category' column for Discover CC profile
- Write category to Transaction on upload

Budget rules:
- Add BudgetRule model (userId, budgetId, pattern)
- API: GET/POST /api/budget-rules, DELETE /api/budget-rules/:id
- Apply rules during upload (first case-insensitive match wins)
- Budgets page fetches and passes rules per budget
- BudgetCard 'Rules' menu item opens BudgetRulesDialog for add/delete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jerick
2026-04-20 22:56:41 -04:00
parent efe42ac366
commit 60fc836b73
10 changed files with 234 additions and 10 deletions

View File

@@ -8,13 +8,14 @@ datasource db {
}
model User {
id String @id @default(cuid())
email String @unique
id String @id @default(cuid())
email String @unique
passwordHash String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
accounts Account[]
budgets Budget[]
budgetRules BudgetRule[]
}
enum AccountType {
@@ -80,10 +81,24 @@ model Budget {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
transactions Transaction[]
rules BudgetRule[]
@@index([userId])
}
model BudgetRule {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
budgetId String
budget Budget @relation(fields: [budgetId], references: [id], onDelete: Cascade)
pattern String
createdAt DateTime @default(now())
@@index([userId])
@@index([budgetId])
}
model CsvUpload {
id String @id @default(cuid())
accountId String