Bootstrap CSS/JS and jQuery were gitignored (wwwroot/lib/) so they
were missing from Docker builds, causing all dropdown menus and
styling to break on the deployed version.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both the doughnut chart and top categories table are now hidden
when there's only a single category, as they provide no useful
breakdown in that case. The net cash flow chart expands to full
width when the category chart is hidden.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the "Select all on page" checkbox from the card header into the
first column header of the transactions table, aligned with per-row
checkboxes for a cleaner layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the generic Bootstrap dark theme with a polished light theme
featuring an indigo primary color, refined cards with subtle shadows,
uppercase table headers, and updated chart palettes. Pure CSS restyle
with no layout or functionality changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip <think>...</think> blocks from reasoning model output (e.g.
Qwen3-VL-Thinking) and increase max_tokens from 4096 to 16384 to
accommodate thinking token overhead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ReviewAISuggestions and ReviewAISuggestionsWithProposals were a two-page
workflow superseded by AICategorizePreview, which handles batch approval,
tabs, and TempData storage in a single page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restructure the flat 7-item navbar into logical dropdown groups (Transactions,
Receipts, Accounts), add a prominent Upload button, settings gear icon, breadcrumb
navigation on 11 deep pages, and dashboard quick-action cards with hover effects.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document AI tool-use framework, receipt parse queue system, background
worker, bulk upload, ParseStatus enum, and updated AIReceiptParser flow
with tool-aware vs enriched-prompt paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change receipt storage to \TRUENAS\receipts, Kestrel port to 5005,
and add AI section with ModelsEndpoint and default ReceiptParsingModel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Transactions page now defaults to last 30 days when no date filters are
set. ViewReceipt page adds collapsible raw LLM response payload on
parse logs for debugging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add error message alert for failed proposal applications. Derive AI
provider name from model prefix instead of separate config key.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split proposals into High Confidence / Needs Review tabs. Extract
proposal table into _ProposalTable partial view. Show rule status
(Create/Update/Exists) based on existing category mappings. Persist
proposals in hidden form field to survive app restarts. Add per-tab
select-all and improved error reporting on apply.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Categorizer now pre-fetches existing rules and includes matching rules
in prompts so the AI respects established mappings. Unified model
routing via CallModelAsync replaces separate provider branching.
Improved pattern instructions require exact transaction name substrings.
Add rule update support (RuleUpdated) when a pattern exists with a
different category.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ReceiptQueue page with tabbed dashboard (queued/completed/failed),
AJAX polling for live status updates, and per-receipt retry. Update
Receipts page with multi-file upload modal, file preview, upload
spinner, and bulk retry for failed parses.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ReceiptParseQueue (Channel-based singleton) and
ReceiptParseWorkerService (BackgroundService) for sequential receipt
parsing. Replaces fire-and-forget Task.Run with a proper queue.
ReceiptManager now enqueues uploaded receipts and supports bulk upload
via UploadManyUnmappedReceiptsAsync. Worker recovers pending items on
startup. Register IAIToolExecutor and IAIVisionClientResolver in DI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ParseStatus field to Receipt model with states: NotRequested,
Queued, Parsing, Completed, Failed. Includes indexed column and EF Core
migration for tracking receipt parse queue progress.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AIReceiptParser now routes to tool-aware or standard vision clients.
Tool-capable models (OpenAI, Claude, LlamaCpp) call search_categories,
search_transactions, and search_merchants during parsing. Ollama gets
pre-fetched DB context injected into the prompt. Adds suggestedCategory
and suggestedTransactionId fields with AI-driven transaction mapping.
Includes NullableLongConverter for resilient JSON deserialization and
restructured receipt prompt with strict field types.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add IAIToolAwareVisionClient interface and OpenAIToolUseHelper for
function-calling via /v1/chat/completions. OpenAI and LlamaCpp clients
now support multi-round tool calls, letting the AI query the database
during receipt image analysis.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce provider-agnostic tool definitions (AIToolRegistry) and an
executor (AIToolExecutor) that lets AI models query MoneyMap's database
during receipt parsing via search_categories, search_transactions, and
search_merchants tools. Includes an enriched-context fallback for
providers that don't support function calling (Ollama).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store user-provided parsing notes in the database so they persist
across parsing attempts. Notes are displayed in Receipt Information
and pre-populated in the textarea for future parses.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Settings page for AI model selection with load status indicators
- Add ModelWarmupService to preload configured model on app startup
- Consolidate AI model config to single AI:ReceiptParsingModel setting
- Simplify ViewReceipt and AICategorizePreview to use Settings model
- Improve AI categorization confidence prompt for varied scores
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Simplify model dropdown to single flat list with local models first
- Show loaded/unloaded status with bullet indicators
- Remove separate Ollama:BaseUrl and LlamaCpp:BaseUrl configs
- All AI vision clients now use AI:ModelsEndpoint (default: athena.lan:11434)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enhance receipt parsing model selection:
- Fetch available models from LlamaCpp server dynamically
- Show loaded/unloaded status in model dropdown
- Persist selected model to appsettings.json
- Read default model from AI:ReceiptParsingModel config
- Inject LlamaCppVisionClient and IConfiguration dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Switch from cookie-based to session-based TempData to avoid
cookie size limits when storing AI categorization proposals.
Chain AddSessionStateTempDataProvider() to AddRazorPages().
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new card for AI categorization alongside rule-based:
- Rename existing section to "Rule-Based Categorization"
- Add "AI-Powered Categorization" section with provider badge
- Link to AICategorizePreview for AI category suggestions
- Display explanation of how AI categorization works
- Inject IConfiguration to read AI provider setting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add selection UI to Transactions page:
- Add checkbox column for selecting transactions
- Add sticky selection bar showing selected count
- Add Select All / Clear Selection controls
- Wire up form to send selected IDs to AICategorizePreview page
- Preserve row click navigation for unselected areas
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enhance AI categorization with multi-provider support:
- Add configurable AI:CategorizationProvider setting (OpenAI/LlamaCpp)
- Add CallLlamaCppAsync() for local LLM categorization
- Improve prompt with existing categories for consistency
- Include additional transaction context (card, account, transfer info)
- Fix batch processing to avoid DbContext concurrency issues
- Add model parameter to interface methods
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add GetAvailableModelsAsync() to LlamaCppVisionClient that:
- Queries llama.cpp /v1/models endpoint for available models
- Filters out multimodal projector models (mmproj-*)
- Tracks loaded/unloaded status for each model
- Returns sorted list with loaded models first
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new page that allows users to:
- Generate AI categorization suggestions for uncategorized transactions
- Review proposals with confidence levels before applying
- Select specific transactions from Transactions page for AI review
- Choose to create mapping rules for high-confidence matches
- Support both OpenAI and LlamaCpp providers with model selection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Store only filename in database instead of full relative path.
GetReceiptPhysicalPath now combines config base path with filename.
AIReceiptParser uses ReceiptManager for consistent path resolution.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New page shows unmapped receipts with scored transaction candidates,
allowing manual mapping or bulk auto-map. Displays confidence scores
and match quality indicators. Also shows recently mapped receipts
for verification with unmap option.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace simple matching with weighted scoring algorithm (40% amount,
25% date, 35% merchant, 10% due date). Uses confidence thresholds:
- 85%+ auto-maps immediately
- 50-85% uses LLM to decide
- Below 50% returns candidates for manual review
Transactions can no longer match before receipt date since receipts
are issued at time of purchase.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add LlamaCppVisionClient and OllamaVisionClient for local AI inference
as alternatives to OpenAI and Claude. Includes text-only prompt support
for LLM-assisted receipt matching.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add documentation for:
- FinancialAuditService responsibilities and methods
- Audit flag types and severities
- /api/audit endpoint with query parameters and response
- Version bump to 1.4 with recent changes section
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Improves readability of percentage text when progress bar
is in warning state (80-99% of budget used).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevents form submission with empty pattern, keeping modal open
for validation instead of closing and showing error after redirect.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Budget model with Weekly/Monthly/Yearly periods
- BudgetService for CRUD and spending calculations
- New /Budgets page for managing budgets
- Dashboard integration with progress bars
- Support for category-specific or total spending budgets
- Period boundaries calculated from budget start date
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add RunningBalance to SpendTrends model
- Calculate cumulative balance over 30 days
- Display as smooth filled line chart (neutral blue)
- Cleaner date labels (MMM d format)
- Better tooltip formatting with $ values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enable data-bs-theme="dark" on html element
- Update navbar to dark variant
- Replace text-dark links with text-body (theme-aware)
- Replace bg-white/bg-light with bg-body/bg-body-secondary
- Update sticky table headers to dark theme
- Fix Chart.js legend and axis colors for dark backgrounds
- Adjust focus ring color for better visibility on dark
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use environment variables in docker-compose for secrets/paths
- Add .env.example template for required variables
- Add .env to .gitignore to prevent secret exposure
- Add docker-build-and-push.cmd helper script
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add PageNumber and PageSize query parameters (default 25 per page)
- Implement server-side pagination with Skip/Take
- Display "Showing X-Y of Z" count in header
- Add Bootstrap pagination controls with sliding page window
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Dockerfile with multi-stage build for .NET 8
- Include ImageMagick dependencies for Magick.NET
- Add docker-compose.yml with volume mount for receipts
- Add .dockerignore to exclude build artifacts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Move the upload form from a card panel at the top of the page
to a modal triggered by an "Upload Receipt" button in the header.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>