CLAUDE.md was outdated — claimed no build system, dependencies, or tests when all three exist. Rewrote with commands, architecture, conventions, gotchas, and dependency info. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.3 KiB
2.3 KiB
CLAUDE.md
Project Overview
SpendingAnalysis is a PySide6 desktop GUI application for importing bank/credit card CSV statements and analyzing spending habits. Uses SQLAlchemy ORM with SQLite and matplotlib for charts.
Repository
- Remote: https://gitea.conlon.fun/andy/SpendingAnalysis.git
- Branch: main
Commands
# Setup
python -m venv .venv
.venv\Scripts\activate # Windows
pip install -e ".[dev]"
# Run
python -m src.main # or: spending-analysis
# Test
pytest
Architecture
Three-layer structure under src/:
- models/ — SQLAlchemy ORM: Transaction, Account, Category, Rule, HouseholdMember, CsvMapping
- services/ — Pure Python business logic (no Qt dependencies): importer, categorizer, analysis, forecasting, recurring detection, transfer detection, normalizer, csv_reader
- ui/ — PySide6 views: ImportView (3-stage wizard), TransactionsView (table + inline editing), AnalysisView (matplotlib charts), RecurringView, SettingsView
Entry point: src/main.py → initializes DB, seeds defaults, launches MainWindow.
Database: ~/.spending_analysis/spending.db (SQLite, auto-created on first run).
Theme: Cyberpunk "Matrix 2026" defined in src/ui/themes/ (palette in __init__.py, stylesheet in dark.qss).
Key Conventions
- Services are pure Python with no UI imports — keep them testable independently
- Categorizer uses a Protocol interface — future AI categorizers can implement the same protocol
- Tests use in-memory SQLite (
sqlite:///:memory:) - Transactions store both
description(normalized) andraw_description(original) - Amounts are signed: negative = expense, positive = income
Gotchas
- Rule cache:
RuleBasedCategorizercaches rules in memory; callinvalidate_cache()after editing rules in Settings - CSV first-row heuristic: csv_reader checks if the first row looks like data (contains dates/numbers) to handle headerless CSVs (e.g., Wells Fargo)
- SQLite threading: Import runs on QThread but SQLAlchemy sessions aren't thread-isolated — avoid concurrent DB writes
- pandas imported but unused: Listed in dependencies but not actively used in current code
Dependencies
Runtime: PySide6, SQLAlchemy, pandas, matplotlib
Dev: pytest, pytest-qt
Configured in pyproject.toml. No CI/CD or linting tools configured.