# 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 ```bash # 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) and `raw_description` (original) - Amounts are signed: negative = expense, positive = income ## Gotchas - **Rule cache**: `RuleBasedCategorizer` caches rules in memory; call `invalidate_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.