docs: update CLAUDE.md with accurate project context

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>
This commit is contained in:
2026-02-10 21:42:32 -05:00
parent 3038fca8fa
commit 41e1d452e2

View File

@@ -1,16 +1,58 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
SpendingAnalysis is a Python application that ingests data from various sources to analyze spending habits. The project is in early development.
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
## Development Setup
## Commands
Python project — no build system, dependencies, or test framework configured yet. Standard Python .gitignore is in place covering common tooling (pytest, mypy, ruff, venv, etc.).
```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.