# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview F1tness Parser is a FastAPI-based web application that parses fitness training data from two note formats: - **Obsidian Notes**: Markdown tables with `# DD.MM.YYYY (trainer-session)` headers - **Apple Notes**: Bold markdown tables with `**DD.MM.YYYY (trainer-session)**` headers The application uses a layered architecture with parsers, models, services, and API endpoints. ## Development Commands The project is developed and run **only in Docker**: there is no local Python setup. Everything below runs inside the `fastapi-app` container (`.env` must have `POSTGRES_DATABASE_HOST=postgres`, see `.env.example`). ### Docker Development ```bash # Start the app + PostgreSQL (applies migrations on start, hot reload for app/) docker compose up --build # Apply migrations manually (Alembic; the app itself does NOT migrate on startup) docker compose exec fastapi-app alembic upgrade head # Create a migration after changing models in app/core/database/models/ # (-u keeps the generated file owned by you instead of root) docker compose exec -u "$(id -u):$(id -g)" fastapi-app alembic revision --autogenerate -m "describe change" # Import all Obsidian + Apple notes into the database docker compose exec fastapi-app python -m app.cli import [--replace] # Stop (keeps the data) / stop and drop the database volume docker compose down docker compose down -v ``` Rebuild (`--build`) is needed only after changing `requirements*.txt`, `Dockerfile` or `pyproject.toml`. ### Testing Tests that need a database use a separate `_test` database (`TEST_DATABASE_URL`, created automatically). Without it they are skipped. ```bash # Run all tests docker compose exec fastapi-app pytest # Run specific test file docker compose exec fastapi-app pytest tests/test_core/test_obsidian_parser.py # Without a running stack (starts postgres, runs once, removes the container) docker compose run --rm fastapi-app pytest ``` ### Type Checking ```bash docker compose exec fastapi-app mypy app/ ``` ## Architecture ### Core Components **Parser Architecture**: The system uses a base parser class (`app/core/parsers/base.py`) with format-specific implementations: - `ObsidianNotesParser` - handles Obsidian markdown format - `AppleNotesParser` - handles Apple notes format - Each parser includes exercise name mapping for normalization **Data Models**: Located in `app/core/dto/training.py`: - `Training` - represents a workout session - `Exercise` - individual exercise with multiple approaches - `Approach` - single set with weight and reps **API Structure**: - `/api/v1/` - REST API endpoints - `/app/` - Web interface endpoints - Static files served from `app/static/` - Templates in `app/templates/` ### Database The application uses PostgreSQL through async SQLAlchemy (asyncpg). ORM models live in `app/core/database/models/`, `TrainingRepository` (`app/core/database/repository.py`) is the data access layer, and a session is injected into endpoints with `Depends(get_session)`. Schema migrations are handled by Alembic (`alembic.ini`, `migrations/`); the URL is taken from `app/config.py`. Configuration is managed through `app/config.py` using Pydantic settings with `.env` file support. ### Key Files - `app/main.py` - FastAPI application setup with lifespan management - `app/config.py` - Application configuration and database settings - `run.py` - Standalone uvicorn runner (unused: Docker starts uvicorn from `compose.yaml`) - `migrations/` - Alembic environment and versions - `compose.yaml` - Docker Compose setup with PostgreSQL ## Environment Setup Copy `.env.example` to `.env` and configure: - PostgreSQL connection settings - Debug mode - PYTHONPATH (for Docker) The application will run database migrations automatically on startup through the FastAPI lifespan event.