Private
Public Access
1
0

Initial commit: Purrse personal finance app

Self-hosted, plugin-extensible personal finance manager built with
ASP.NET Core 9.0, Vue 3 + Vuetify 3, and PostgreSQL 17.

Backend (8 .NET projects):
- Core: 19 domain models, 6 enums, 14 DTOs, 12 service interfaces
- Data: EF Core DbContext, 16 entity configurations, category seeder
- API: 14 controllers, 15 services, JWT auth, SignalR, middleware
- Plugins: Abstractions + OFX/CSV/QIF file parsers
- Tests: 28 xUnit tests (fingerprinting, duplicate detection, parsers)

Frontend (Vue 3 + Vuetify 3 + TypeScript):
- 13 views, Pinia stores, Axios API services with JWT interceptors
- Dashboard, accounts, transactions, categories, imports, and more

Deployment:
- Docker Compose (PostgreSQL 17 + .NET API + nginx frontend)
- Auto-migration on startup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-02-08 08:56:46 -05:00
commit 6520ebf221
169 changed files with 7180 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
import { format, parseISO } from 'date-fns'
export function formatCurrency(amount: number): string {
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount)
}
export function formatDate(date: string): string {
return format(parseISO(date), 'MM/dd/yyyy')
}
export function formatDateTime(date: string): string {
return format(parseISO(date), 'MM/dd/yyyy h:mm a')
}
export function formatPercent(value: number): string {
return `${value >= 0 ? '+' : ''}${value.toFixed(1)}%`
}
export function accountTypeLabel(type: string): string {
const labels: Record<string, string> = {
Checking: 'Checking',
Savings: 'Savings',
CreditCard: 'Credit Card',
AutoLoan: 'Auto Loan',
PersonalLoan: 'Personal Loan',
Mortgage: 'Mortgage',
LineOfCredit: 'Line of Credit',
Retirement401k: '401(k)',
IRA: 'IRA',
Brokerage: 'Brokerage',
Cash: 'Cash',
}
return labels[type] || type
}
export function accountTypeIcon(type: string): string {
const icons: Record<string, string> = {
Checking: 'mdi-bank',
Savings: 'mdi-piggy-bank',
CreditCard: 'mdi-credit-card',
AutoLoan: 'mdi-car',
PersonalLoan: 'mdi-cash-multiple',
Mortgage: 'mdi-home',
LineOfCredit: 'mdi-credit-card-outline',
Retirement401k: 'mdi-chart-line',
IRA: 'mdi-chart-areaspline',
Brokerage: 'mdi-finance',
Cash: 'mdi-cash',
}
return icons[type] || 'mdi-bank'
}