Implement Phase 1: AI-powered categorization with manual review
Add AI categorization service that suggests categories, merchants, and
rules for uncategorized transactions. Users can review and approve
suggestions before applying them.
Features:
- TransactionAICategorizer service using OpenAI GPT-4o-mini
- Batch processing (5 transactions at a time) to avoid rate limits
- Confidence scoring (0-100%) for each suggestion
- AI suggests category, canonical merchant name, and pattern rule
- ReviewAISuggestions page to list uncategorized transactions
- ReviewAISuggestionsWithProposals page for manual review
- Apply individual suggestions or bulk apply high confidence (≥80%)
- Optional rule creation for future auto-categorization
- Cost: ~$0.00015 per transaction (~$0.015 per 100)
CategoryMapping enhancements:
- Confidence field to track AI confidence score
- CreatedBy field ("AI" or "User") to track rule origin
- CreatedAt timestamp for audit trail
Updated ARCHITECTURE.md with complete documentation of:
- TransactionAICategorizer service details
- ReviewAISuggestions page descriptions
- AI categorization workflow (Phase 1)
- Updated CategoryMappings schema
Next steps (Phase 2):
- Auto-apply high confidence suggestions
- Background job processing
- Batch API requests for better efficiency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
121
MoneyMap/Pages/ReviewAISuggestions.cshtml
Normal file
121
MoneyMap/Pages/ReviewAISuggestions.cshtml
Normal file
@@ -0,0 +1,121 @@
|
||||
@page
|
||||
@model MoneyMap.Pages.ReviewAISuggestionsModel
|
||||
@{
|
||||
ViewData["Title"] = "AI Categorization Suggestions";
|
||||
}
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2>AI Categorization Suggestions</h2>
|
||||
<div class="d-flex gap-2">
|
||||
<a asp-page="/Transactions" asp-route-category="(blank)" class="btn btn-outline-secondary">
|
||||
View Uncategorized
|
||||
</a>
|
||||
<a asp-page="/Index" class="btn btn-outline-secondary">Back to Dashboard</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.SuccessMessage))
|
||||
{
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
@Model.SuccessMessage
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.ErrorMessage))
|
||||
{
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
@Model.ErrorMessage
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">How AI Categorization Works</h5>
|
||||
<p class="card-text">
|
||||
This tool uses AI to analyze your uncategorized transactions and suggest:
|
||||
</p>
|
||||
<ul>
|
||||
<li><strong>Category</strong> - The most appropriate expense category</li>
|
||||
<li><strong>Merchant Name</strong> - A normalized merchant name (e.g., "Walmart" from "WAL-MART #1234")</li>
|
||||
<li><strong>Pattern Rule</strong> - An optional rule to auto-categorize similar transactions in the future</li>
|
||||
</ul>
|
||||
<p class="card-text">
|
||||
<strong>Cost:</strong> Approximately $0.00015 per transaction (~1.5 cents per 100 transactions)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<strong>Uncategorized Transactions (@Model.TotalUncategorized)</strong>
|
||||
<form method="post" asp-page-handler="GenerateSuggestions" class="d-inline">
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
Generate AI Suggestions (up to 20)
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if (!Model.Transactions.Any())
|
||||
{
|
||||
<p class="text-muted">No uncategorized transactions found. Great job!</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-muted mb-3">
|
||||
Showing the @Model.Transactions.Count most recent uncategorized transactions.
|
||||
Click "Generate AI Suggestions" to analyze up to 20 transactions.
|
||||
</p>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Name</th>
|
||||
<th>Memo</th>
|
||||
<th class="text-end">Amount</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.Transactions)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Transaction.Date.ToString("yyyy-MM-dd")</td>
|
||||
<td>@item.Transaction.Name</td>
|
||||
<td class="text-truncate" style="max-width: 300px;">@item.Transaction.Memo</td>
|
||||
<td class="text-end">
|
||||
<span class="@(item.Transaction.Amount < 0 ? "text-danger" : "text-success")">
|
||||
@item.Transaction.Amount.ToString("C")
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a asp-page="/EditTransaction" asp-route-id="@item.Transaction.Id" class="btn btn-sm btn-outline-primary">
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<strong>Quick Tips</strong>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="small mb-0">
|
||||
<li>AI suggestions are based on transaction name, memo, amount, and date</li>
|
||||
<li>You can accept, reject, or modify each suggestion</li>
|
||||
<li>Creating rules helps auto-categorize future transactions</li>
|
||||
<li>High confidence suggestions (>80%) are more reliable</li>
|
||||
<li>You can manually edit any transaction from the Transactions page</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user