Initial commit: backend API, data models, and test suite

FastAPI backend for personal health and skincare data with MCP export.
Includes SQLModel models for products, inventory, medications, lab results,
routines, and skin condition snapshots. Pytest suite with 111 tests running
on SQLite in-memory (no PostgreSQL required).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Piotr Oleszczyk 2026-02-26 15:10:24 +01:00
commit 8f7d893a63
32 changed files with 6282 additions and 0 deletions

52
CLAUDE.md Normal file
View file

@ -0,0 +1,52 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository structure
This is a monorepo. The backend lives in `backend/`; a frontend will be added in the future.
## Commands
Run all backend commands from the `backend/` directory:
```bash
# Run scripts
cd backend && uv run python main.py
# Linting / formatting
cd backend && uv run ruff check .
cd backend && uv run black .
cd backend && uv run isort .
```
No test suite exists yet.
## Architecture
**innercontext** collects personal health and skincare data and exposes it via MCP to an LLM agent. Stack: Python 3.12, SQLModel (0.0.37) + SQLAlchemy, Pydantic v2, FastAPI, PostgreSQL (psycopg3).
### Models (`backend/innercontext/models/`)
| File | Tables |
|------|--------|
| `product.py` | `products`, `product_inventory` |
| `health.py` | `medication_entries`, `medication_usages`, `lab_results` |
| `routine.py` | `routines`, `routine_steps` |
| `skincare.py` | `skin_condition_snapshots` |
**`Product`** is the core model. JSON columns store `inci` (list), `actives` (list of `ActiveIngredient`), `recommended_for`, `targets`, `incompatible_with`, `synergizes_with`, `context_rules`, and `product_effect_profile`. The `to_llm_context()` method returns a token-optimised dict for MCP.
**`ProductInventory`** tracks physical packages (opened status, expiry, remaining weight). One product → many inventory entries.
**`Routine` / `RoutineStep`** record daily AM/PM skincare sessions. A step references either a `Product` or a free-text `action` (e.g. shaving).
**`SkinConditionSnapshot`** is a weekly LLM-filled record (skin state, metrics 15, active concerns).
### Key conventions
- All `table=True` models use `Column(DateTime(timezone=True), onupdate=utc_now)` for `updated_at` via raw SQLAlchemy column — do not use plain `Field(default_factory=...)` for auto-update.
- List/complex fields stored as JSON use `sa_column=Column(JSON, nullable=...)` pattern (DB-agnostic; not JSONB).
- `model_validator(mode="after")` **does not fire** on `table=True` SQLModel instances (SQLModel 0.0.37 + Pydantic v2 bug). Validators in `Product` are present for documentation but are unreliable at construction time.
- `backend/skincare.yaml` is a legacy notes file — ignore it, it is not part of the data model and will not be imported.
- `_ev()` helper in `product.py` normalises enum values when fields may be raw dicts (as returned from DB) or Python enum instances.