Renamed static factory method from 'MultipleMatches' to
'WithMultipleMatches' to avoid conflict with the 'MultipleMatches'
property in the same class.
This resolves the compilation error: "The type 'ReceiptAutoMapResult'
already contains a definition for 'MultipleMatches'".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented automatic mapping of parsed receipts to matching
transactions, with both automatic (after parsing) and manual
(via button) triggers.
New Service - ReceiptAutoMapper:
- AutoMapReceiptAsync: Maps a single receipt to a transaction
- AutoMapUnmappedReceiptsAsync: Bulk maps all unmapped receipts
- FindMatchingTransactionsAsync: Smart matching algorithm using:
- Receipt date (+/- 3 days for processing delays)
- Merchant name (matches against transaction merchant or name)
- Total amount (within $0.10 tolerance)
- Excludes transactions that already have receipts
- Returns single match, multiple matches, or no match
Matching Strategy:
- Single match: Automatically maps
- Multiple matches: Reports count for manual review
- No match: Reports for manual intervention
- Not parsed: Skips (requires merchant, date, or total)
Integration Points:
- OpenAIReceiptParser: Triggers auto-mapping after successful parse
(only for unmapped receipts, errors ignored to not fail parse)
- Receipts page: Added "Auto-Map Unmapped Receipts" button
- Only shows when unmapped parsed receipts exist
- Displays detailed results (mapped count, no match, multi-match)
This enables a streamlined workflow:
1. Upload receipt → 2. Parse receipt → 3. Auto-map to transaction
Users can also trigger bulk auto-mapping for all unmapped receipts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented duplicate detection to warn users when uploading receipts
that may already exist in the system.
Changes:
- Extended ReceiptUploadResult to include DuplicateWarning list
- Added CheckForDuplicatesAsync method to ReceiptManager that checks:
1. Identical file content (same SHA256 hash)
2. Same file name and size (potential duplicate saved/edited)
- Updated upload flow to check for duplicates before saving
- Enhanced Receipts page to:
- Display warning alert when duplicates are detected
- Show details of each potential duplicate (receipt ID, filename,
upload date, mapped transaction, and reason)
- Provide quick link to view the duplicate receipt
- Use TempData to persist warnings across redirect
Duplicate detection runs on every upload and provides actionable
information to help users avoid uploading the same receipt multiple
times. The check uses hash-based detection for exact duplicates and
name+size matching for potential duplicates.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The previous commit had the model changes but the database wasn't
properly migrated. This commit adds the missing migrations to make
TransactionId nullable in the Receipts table.
Changes:
- Updated MoneyMapContext to make Transaction relationship optional
for Receipt (IsRequired(false))
- Created additional migrations to properly handle:
- Making TransactionId column nullable
- Updating the unique index to handle NULL values with WHERE clause
- Applied all migrations to database successfully
The Receipts page should now work correctly for uploading unmapped
receipts without a TransactionId.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added functionality to upload and manage receipts without initially
associating them to a transaction, with the ability to map them later.
Changes:
- Modified Receipt model to make TransactionId nullable
- Updated ReceiptManager service with new methods:
- UploadUnmappedReceiptAsync: Upload receipts without a transaction
- MapReceiptToTransactionAsync: Map an existing receipt to a transaction
- Created Receipts page (Receipts.cshtml) with:
- Upload form for new receipts
- List view of all receipts (mapped and unmapped)
- Status badges (Mapped/Unmapped)
- Map to Transaction modal dialog
- Delete receipt functionality
- Added "Receipts" link to navigation menu
- Fixed Transactions page receipt count query for nullable TransactionId
- Created migration: MakeReceiptTransactionIdNullable
This enables workflows where receipts are uploaded first and matched
to transactions later, useful for batch receipt processing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added convenient buttons for common date ranges:
- Last 30 Days
- Last 60 Days
- Last 90 Days
- Last Year
- This Month
- Last Month
Clicking these buttons automatically populates the Start Date and End
Date filter fields. Users can still manually adjust the dates or use
the Filter button to apply the selected range.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added a search bar that allows users to filter transactions by:
- Transaction name
- Memo
- Category
- Notes
- Merchant name
The search uses a case-sensitive contains filter across all these
fields. The search parameter is preserved across pagination links and
included in the "Clear Filters" button logic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, selecting "(blank)" from the category dropdown would submit
an empty string value, causing no transactions to appear. The backend
expects the literal string "(blank)" to filter for uncategorized items.
Updated the dropdown to submit "(blank)" as the value when the category
is empty, matching the backend's filter logic in Transactions.cshtml.cs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add explicit column type configuration for Confidence field to avoid
SQL Server truncation warnings. Use decimal(5,4) to store values from
0.0000 to 1.0000 with 4 decimal places of precision.
Also add MaxLength constraint for CreatedBy field.
Migration applied successfully to database.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
Add prominent reminders in both CLAUDE.md and AGENTS.md to update
the shared ARCHITECTURE.md file when making architectural changes.
This helps ensure the documentation stays current and both AI tools
have accurate context.
Changes include:
- Added step in development workflow to update docs
- Added "Important: Keep Documentation Updated" section
- Listed specific types of changes that require doc updates
- Emphasized that this keeps both tools in sync
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Split documentation into three files to eliminate duplication:
- ARCHITECTURE.md: Shared technical documentation (domain models,
services, database schema, workflows, patterns)
- CLAUDE.md: Claude Code-specific context referencing ARCHITECTURE.md
- AGENTS.md: Codex agent context referencing ARCHITECTURE.md
This allows both Claude Code and Codex CLI to share the same source
of truth for architecture details while maintaining tool-specific
configuration in separate files.
Benefits:
- Single source of truth for technical details
- Easier maintenance (update once, not twice)
- Consistent documentation across tools
- Clear separation of concerns
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Display the average spend per transaction for each category on the
dashboard's top expense categories table. This helps users understand
spending patterns beyond just total amounts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Ensure merchant data is eagerly loaded when querying transactions
on the Transactions page to avoid N+1 queries.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Allow users to set or change the merchant for a transaction from the
EditTransaction page. Users can select from existing merchants or
create new ones on the fly.
Changes:
- Add merchant dropdown with existing merchants
- Support creating new merchants via custom input
- Update transaction merchant when saving
- Rename "Merchant Name" label to "Transaction Name" for clarity
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Created a dedicated page for viewing and managing merchants:
**Backend (Merchants.cshtml.cs):**
- List all merchants with transaction and mapping counts
- Add new merchant with duplicate name validation
- Edit merchant name (updates all linked transactions/mappings)
- Delete merchant (unlinks from transactions/mappings via SET NULL)
- Full CRUD operations with proper validation
**Frontend (Merchants.cshtml):**
- Clean table view showing merchant name, transaction count, mapping count
- Add modal for creating new merchants
- Edit modal for renaming merchants (click row or Edit button)
- Delete with confirmation showing impact (# of transactions/mappings)
- Success/error message display
- Responsive Bootstrap layout
**Navigation:**
- Added "Merchants" link to main navigation bar
- Positioned between "Categories" and "Recategorize"
**Features:**
- Shows transaction count per merchant (useful for seeing merchant usage)
- Shows mapping count per merchant (useful for seeing pattern coverage)
- Inline edit with modal dialog (consistent with CategoryMappings UI)
- Safe delete with SET NULL (transactions/mappings remain, just unlinked)
- Duplicate name prevention on add/edit
**Benefits:**
- Easy merchant management without SQL queries
- Visual feedback on merchant usage
- Rename propagates to all transactions/mappings automatically
- Consistent UI with rest of application
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Improved UX for adding/editing category mappings:
**Backend Changes:**
- Added AvailableCategories list (distinct categories from existing mappings)
- Added AvailableMerchants list (all merchants from Merchants table)
- Updated LoadDataAsync() to populate both lists
**UI Changes:**
- Replaced plain text input with HTML5 datalist for Category field
- Replaced plain text input with HTML5 datalist for Merchant field
- Both fields support autocomplete while allowing new values
- Added "required" attribute to Category field for validation
- Added helper text to guide users
- Removed custom JavaScript dropdown logic (now using native datalist)
**Benefits:**
- Consistent category naming (autocomplete suggests existing categories)
- Consistent merchant naming (autocomplete suggests existing merchants)
- Better UX with native browser autocomplete behavior
- Still allows creating new categories/merchants on the fly
- Cleaner, simpler code without custom dropdown implementation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This refactors the merchant field from a simple string column to a normalized
entity with proper foreign key relationships:
**Database Changes:**
- Created Merchant entity/table with unique Name constraint
- Replaced Transaction.Merchant (string) with Transaction.MerchantId (FK)
- Replaced CategoryMapping.Merchant (string) with CategoryMapping.MerchantId (FK)
- Added proper foreign key constraints with SET NULL on delete
- Added indexes on MerchantId columns for performance
**Backend Changes:**
- Created MerchantService for finding/creating merchants
- Updated CategorizationResult to return MerchantId instead of merchant name
- Modified TransactionCategorizer to return MerchantId from pattern matches
- Updated Upload, Recategorize, and CategoryMappings to use merchant service
- Updated OpenAIReceiptParser to create/link merchants from parsed receipts
- Registered IMerchantService in dependency injection
**UI Changes:**
- Updated CategoryMappings UI to handle merchant entities (display as Merchant.Name)
- Updated Transactions page merchant filter to query by merchant entity
- Modified category mapping add/edit/import to create merchants on-the-fly
- Updated JavaScript to pass merchant names for edit modal
**Migration:**
- ConvertMerchantToEntity migration handles schema conversion
- Drops old string columns and creates new FK relationships
- All existing merchant data is lost (acceptable for this refactoring)
**Benefits:**
- Database normalization - merchants stored once, referenced many times
- Referential integrity with foreign keys
- Easier merchant management (rename once, updates everywhere)
- Foundation for future merchant features (logos, categories, etc.)
- Improved query performance with proper indexes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This feature enables easy filtering and identification of transactions by merchant name:
- Added Merchant column to Transaction model (nullable, max 100 chars)
- Added Merchant field to CategoryMapping model
- Modified ITransactionCategorizer to return CategorizationResult (category + merchant)
- Updated auto-categorization logic to assign merchant from category mappings
- Updated category mappings UI to include merchant field in add/edit forms
- Added merchant filter dropdown to transactions page with full pagination support
- Updated receipt parser to set transaction merchant from parsed receipt data
- Created two database migrations for the schema changes
- Updated helper methods to support merchant names in default mappings
Benefits:
- Consistent merchant naming across variant patterns (e.g., "Walmart" for all "WAL-MART*" patterns)
- Easy filtering by merchant on transactions page
- No CSV changes required - merchant is derived from category mapping patterns
- Receipt parsing can also populate merchant field automatically
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Show what percentage of total expenses each category represents in the top categories table. This helps quickly identify which categories consume the largest portion of spending.
Changes:
- Add PercentageOfTotal property to TopCategoryRow
- Calculate percentage based on total expenses in the period
- Display percentage as a badge in the table (e.g., "23.5%")
- Add new "% of Total" column header
- Format to 1 decimal place for clarity
Example: If "Groceries" is $500 and total expenses are $2000, it shows 25.0%
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add the ability to export and import category mappings as JSON files:
Export:
- Downloads all category mappings as a formatted JSON file
- Ordered by category and priority
Import:
- Upload JSON file with category mappings
- Option to replace all existing mappings or merge with current ones
- Validates JSON format and data integrity
- Shows clear error messages for invalid files
UI additions:
- Export to JSON button in header
- Import from JSON button with modal dialog
- Shows example JSON format in import modal
- Replace/merge option with clear explanation
This allows users to:
- Backup their custom category mappings
- Share mappings between instances
- Version control their categorization rules
- Easily restore default or custom configurations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Pass the transaction name from the bank statement to OpenAI when parsing receipts. This helps identify merchants when receipts have cryptic or unclear merchant names (e.g., Arby's receipts).
The transaction name is included as additional context in the prompt: "This transaction was recorded as 'XXX' in the bank statement, which may help identify the merchant if the receipt is unclear."
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove the Cards navigation item since card management is now nested under the Accounts page. Users access cards by navigating to Accounts -> View Account -> Manage Cards.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Modify EditCard page to:
- Accept optional accountId parameter to pre-select account for new cards
- Redirect to AccountDetails page after save (if card has linked account)
- Update navigation to go back to Accounts instead of Cards page
This integrates card management into the account-centric workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Make account rows clickable and add View button to navigate to the new AccountDetails page where users can see account info and manage linked cards.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Create a new AccountDetails page that shows account information and all linked cards. This replaces the standalone Cards page and nests card management under accounts, as cards are always linked to accounts.
Features:
- View account details (institution, type, owner, etc.)
- List all cards linked to the account
- Add new cards directly from the account page
- Edit and delete cards within the account context
- Click-through navigation from Accounts list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Optimize duplicate detection to only query existing transactions within the date range of the uploaded CSV file (plus 1-day buffer). This prevents loading the entire transaction history into memory when checking duplicates.
For example, uploading 2800 transactions from Jan-Mar 2024 will now only load existing transactions from that period rather than all historical transactions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Extend session IOTimeout to 5 minutes to accommodate serialization and storage of large transaction preview datasets (e.g., 2800+ transactions).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When uploading files with more than 100 transactions, the preview now displays transactions in pages of 100 rows at a time. This prevents browser freezing when rendering thousands of form inputs and dramatically improves page load performance.
- Show first 100 transactions by default with pagination controls
- All transactions remain in DOM but hidden for instant page switching
- Update counters and form submission to work across all pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Improve performance when uploading thousands of transactions by loading all existing transactions into memory once for duplicate detection, rather than running individual database queries for each transaction. This reduces database calls from O(n) to O(1) for n transactions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated EditTransaction to handle account selection and card filtering
- Added Transfers link to navigation menu
- Updated Transactions page to properly display account labels
- Refined Upload preview UI for account/card selection
These changes support the new account-centric model where every
transaction belongs to an account and optionally uses a card.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added TransferToAccountId to Transaction model for linking transfers
- Created CreateTransfer page for recording account-to-account transfers
- Migration adds the new foreign key relationship
- Transfers are created as paired transactions (debit and credit)
This enables tracking of money movement between bank accounts while
maintaining proper accounting with matching transaction pairs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed Transaction.AccountId from optional to required, reflecting that
every transaction must belong to an account (the source of the CSV file).
Cards remain optional as they represent the payment method used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added account linking functionality to cards with dropdown selector
- Added optional nickname field for easier card identification
- Updated Cards list page to show linked accounts with badges
- Reorganized card display to show issuer and last4 together
- Include account relationship when loading cards
This allows cards to be properly associated with their bank accounts,
which is essential for the transaction import and categorization flow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Condensed the verbose payment method labels to show only the essential
information:
- Card transactions: Show just the card name (e.g., "AJ's Debit Card")
- Direct account transactions: Show just the account name
- Transfers: Show "Transfer → [Destination]"
Removed duplicate display of account information since cards are
already linked to accounts. This makes the Payment/Account column
much less crowded and easier to read.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed the card resolution logic to check transaction memos first
before falling back to the CSV filename. This enables per-transaction
card detection when account CSVs contain card identifiers in memos
(e.g., "usbank.com.2765").
Also prioritize card matches over account matches in TryResolveByLast4
to ensure cards are correctly identified even when they share the same
last4 digits as their linked account.
This fixes the issue where card dropdowns showed "none / direct debit"
even when card information was present in transaction memos.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added automatic seeding of default category mappings to ensure the
transaction categorizer has patterns to match against. This fixes the
issue where all transactions appeared as uncategorized during preview
because the CategoryMappings table was empty.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Model Changes:
- Add Card.AccountId (nullable FK to Account)
- Add Card.Nickname field for friendly names
- Add Card.DisplayLabel computed property
- Add Account.Cards navigation property
- Add Account.DisplayLabel computed property
DbContext Updates:
- Configure Card → Account relationship (optional, restrict delete)
- Add index on Card.AccountId
- Set Card.Owner as required
Migration:
- Add LinkCardsToAccounts migration
- Adds AccountId and Nickname columns to Cards table
- Creates FK constraint from Cards to Accounts
This properly models the real-world relationship where payment cards
are linked to bank accounts (e.g., a Visa card draws from a checking
account, or a credit card is paid from a savings account).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Schema Changes:
- Add Account model (Institution, AccountType enum, Last4, Owner, Nickname)
- Add Transfer model for tracking money movement between accounts
- Update Transaction to support both CardId and AccountId (nullable FKs)
- Rename Transaction.CardLast4 → Last4 (works for both cards and accounts)
- Add PaymentMethodLabel computed property to Transaction
- Create EF Core migration: SplitCardsAndAccounts
Data Model Improvements:
- Accounts: Checking, Savings, Other types
- Transfers: Source/Destination accounts, optional link to original transaction
- Transactions can now link to either a Card OR an Account
- Transfer categories excluded from spending reports via TransactionFilters
UI Pages:
- Add Accounts.cshtml - List all bank accounts with transaction counts
- Add EditAccount.cshtml - Create/edit bank accounts
- Add Accounts link to navigation
- Update all references from CardLast4 to Last4
Service Layer Updates:
- Update CardResolutionResult to use nullable CardId and renamed Last4
- Update TransactionKey record to include AccountId
- Update IsDuplicate check to include both CardId and AccountId
- Update all PaymentMethodLabel usage across pages
This architecture allows proper separation of credit cards from bank
accounts and enables tracking of transfers between accounts without
double-counting in spending reports.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Transaction Filtering:
- Add TransactionFilters helper class to exclude transfer categories from spending reports
- Exclude "Credit Card Payment" and "Banking" categories from dashboard top spending
- Add ExcludeTransfers() extension method for reusable filtering
- Update dashboard header to indicate transfers are excluded
Category Mappings Refactor:
- Split form models into separate AddMappingModel and UpdateMappingModel
- Remove [BindProperty] attributes and use parameter binding instead
- Eliminate cross-validation issues between add/edit forms
- Simplify validation logic by removing manual ModelState cleanup
This fixes the issue where credit card payments were counted as spending
even though they're just transfers between accounts, causing inflated
spending totals on the dashboard.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Features added:
- Cards page with list/create/edit/delete functionality
- EditCard page for modifying card details
- Enhanced CategoryMappings UI with inline add/edit/delete modals
- Category dropdown autocomplete in mapping forms
- Priority badges and visual indicators for high-priority mappings
- Click-to-edit functionality on patterns
Improvements:
- TransactionCategorizer: Add TARGET.COM to online shopping patterns
- TransactionCategorizer: Set Credit Card Payment to priority 200 to catch before Banking
- TransactionCategorizer: Add database migration comments
- Layout: Add Cards link to navigation
- Layout: Fix Bootstrap JS path
- ValidationScriptsPartial: Use Url.Content for script paths
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Created AGENTS.md with detailed documentation covering:
- Project overview and technology stack
- Architecture patterns and service layer design
- Complete domain model documentation
- Service implementations (TransactionImporter, CardResolver, TransactionCategorizer, DashboardService, ReceiptManager, OpenAIReceiptParser)
- Database schema and EF Core configuration
- Key workflows and design patterns
- Security considerations and performance optimizations
- Testing strategies and deployment guidance
Removed unused Privacy.cshtml and Privacy.cshtml.cs pages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>