Private
Public Access
1
0
Commit Graph

60 Commits

Author SHA1 Message Date
Catherine Renelle e742b0fbe7 Make AI categorization prompts user-configurable
Add SystemPrompt and UserPromptTemplate fields to AI categorization
settings so users can customize the prompts sent to Ollama without
code changes. Null/empty values fall back to built-in defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 19:30:26 -05:00
Catherine Renelle 1c7abb7ffc Add AI categorization with Ollama: settings, auto-classify on sync/import, and manual classify from Transactions
Adds local LLM-based transaction categorization using Ollama:
- Settings UI to configure Ollama URL, model, confidence threshold
- Auto-categorization during bank sync and file import
- Manual "Classify Uncategorized" button on Transactions screen that respects active filters
- Payee default category learning loop for classified transactions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 18:41:12 -05:00
Catherine Renelle 57d1051213 Add JsonStringEnumConverter for proper enum serialization
Without this, enums serialize as integers (0, 1, 2) instead of
strings ("Debit", "Credit", "Transfer"). This caused synced
transactions to have numeric type values and broke editing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:12:08 -05:00
Catherine Renelle 5e7c664896 Fix Unspecified DateTime kind for PostgreSQL timestamptz columns
DateOnly.ToDateTime() produces Kind=Unspecified which Npgsql rejects
for timestamptz. Specify UTC kind on Plaid transaction dates and add
a safety net in BankSyncService for all parsed dates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:02:02 -05:00
Catherine Renelle 9d6a006045 Make Plaid credentials per-user, configurable via Settings UI
Plaid ClientId/Secret are now stored per-user in the database
(encrypted) instead of in appsettings.json. Users enter their own
Plaid developer credentials in the Settings > Bank Connections tab.

- New BankSyncSettings model (1:1 with User) for encrypted credentials
- PlaidSyncProvider is now stateless, receives credentials per-call
- Settings UI shows a credentials card with save form
- Connect via Plaid button disabled until credentials are configured
- Removed Plaid section from appsettings.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:50:48 -05:00
Catherine Renelle 3e0446c9be Implement Phase 6: automated bank sync (Plaid + SimpleFIN) & settings
Add automated transaction syncing via Plaid and SimpleFIN providers,
a Settings page for managing connections and account mappings,
background scheduled syncing, and sync history logging.

New backend: BankSync plugin project with PlaidSyncProvider and
SimpleFinSyncProvider, SyncConnection/LinkedAccount/SyncLog models,
AES-256 encryption service, BankSyncService orchestration,
BankSyncBackgroundService (15-min tick), and BankSyncController
(13 endpoints). EF migration creates sync_connections,
linked_accounts, and sync_logs tables.

New frontend: Settings view with 3 tabs (Profile, Bank Connections,
Sync History), bankSync API service, BankSyncComplete SignalR
notifications, and Settings nav item in sidebar + avatar dropdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:08:23 -05:00
Catherine Renelle eb49147080 Implement Phase 5: reconciliation, SignalR notifications, payees, splits & plugins
Add full frontend UI for five backend features: bank reconciliation (3-step
stepper workflow), payee management (CRUD with alias chips), transaction splits
(expandable rows + split editor), plugins (card grid), and real-time SignalR
notifications (bell dropdown with badge). Fix backend PayeeResponse to expose
alias IDs for deletion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:14:23 -05:00
Catherine Renelle 2ace39c544 Implement Phase 2: end-to-end import system
Complete the import flow from file upload through duplicate resolution
to transaction creation. Previously, ResolveDuplicatesAsync was a stub
that only incremented counters, FileWatcherService detected files but
didn't process them, and ImportsView.vue ignored the API response.

Backend:
- Add ParsedDataJson column to ImportBatch to persist parsed data
  between upload and confirm steps
- Rewrite ImportService.ResolveDuplicatesAsync to deserialize parsed
  transactions and create/merge/skip based on user decisions, with
  payee matching, fingerprinting, and account balance updates
- Add GetBatchesAsync for import history
- Complete FileWatcherService: wait for file ready, resolve account by
  filename, call UploadAsync, send SignalR notification, archive file
- Add GET /api/imports/batches endpoint

Frontend:
- Create imports API service (frontend/src/services/imports.ts)
- Add ImportBatch, DuplicateResolution types
- Rewrite ImportsView.vue with 3-step Vuetify stepper wizard:
  upload, review with duplicate handling, completion summary,
  plus import history table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:16:39 -05:00
Catherine Renelle 3db02f8472 Change frontend port to 9080 to avoid conflicts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:06:29 -05:00
Catherine Renelle 6520ebf221 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>
2026-02-08 08:56:46 -05:00