Files
TieMeasureFlow/CLAUDE.md
T
Adriano cf2bf427fc docs: rewrite CLAUDE.md with comprehensive project guidance for Claude Code
Add dev commands (test, migrations, i18n, Docker), architecture overview,
critical patterns (copy-on-write versioning, pass/fail, SPC, auth flow),
and dependency/configuration reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 18:45:32 +01:00

7.4 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Panoramica

TieMeasureFlow by Tielogic - Sistema di gestione task per misurazioni con calibro manuale. Monorepo con server FastAPI (backend API, porta 8000) e client Flask (frontend tablet, porta 5000), orchestrati con Docker Compose + Nginx reverse proxy + MySQL 8.0.

Comandi di Sviluppo

Avvio servizi (Docker)

docker compose up -d                    # Avvia tutto
docker compose logs -f server           # Log server
docker compose logs -f client           # Log client
docker compose ps                       # Stato servizi

Avvio manuale (senza Docker)

# Server (terminale 1)
cd server && uvicorn main:app --reload --host 0.0.0.0 --port 8000

# Client (terminale 2)
cd client && flask run --host 0.0.0.0 --port 5000

# TailwindCSS watch (terminale 3)
cd client && npx tailwindcss -i static/css/input.css -o static/css/tailwind.css --watch

Database & Migrations

cd server && alembic upgrade head                              # Applica migrazioni
cd server && alembic revision --autogenerate -m "descrizione"  # Genera migrazione
cd server && alembic downgrade -1                              # Rollback ultima
docker compose exec server alembic upgrade head                # Via Docker

Test

# Server (usa SQLite in-memory via aiosqlite, no MySQL richiesto)
cd server && pytest                          # Tutti i test
cd server && pytest tests/test_auth.py       # Singolo modulo
cd server && pytest tests/test_auth.py::test_login_success  # Singolo test
cd server && pytest --cov                    # Con copertura

# Client
cd client && pytest
cd client && pytest tests/test_auth.py

i18n (Traduzioni)

# Estrai stringhe
cd client && pybabel extract -F babel.cfg -k _ -o translations/messages.pot .

# Aggiorna catalogo
cd client && pybabel update -i translations/messages.pot -d translations

# Compila .po → .mo
cd client && pybabel compile -d translations
# oppure
cd client && python compile_translations.py

Setup iniziale

Dopo primo avvio, aprire http://localhost/api/setup (o :8000/api/setup senza Nginx) con la SETUP_PASSWORD dal .env per: inizializzare DB, creare admin, caricare dati demo.

Architettura

Flusso richieste

Browser/Tablet → Nginx (:80/443) → Flask Client (:5000) → APIClient → FastAPI Server (:8000) → MySQL

Il client Flask è un frontend server-side che comunica col backend via REST API. Ogni richiesta dal client al server include l'header X-API-Key per autenticazione.

Server (FastAPI) — server/

  • main.py: entry point, registra middleware (RateLimit → SecurityHeaders → CORS → AccessLog) e 10 router
  • config.py: Settings Pydantic che legge da .env
  • database.py: SQLAlchemy 2.0 async engine con AsyncSession, pool 10+20 overflow
  • routers/: auth, recipes, tasks, measurements, statistics, reports, files, users, settings, setup
  • services/: recipe_service (versioning copy-on-write), measurement_service (calcolo pass/fail), spc_service (Cp/Cpk/control chart, puro stdlib senza numpy), report_service (WeasyPrint PDF + Kaleido SVG), auth_service (bcrypt + API key)
  • middleware/: api_key.py (auth dependency), rate_limit.py (sliding window per-IP), security_headers.py (CSP, HSTS), logging.py (audit trail async su DB)
  • models/: User, Recipe, RecipeVersion, RecipeTask, RecipeSubtask, Measurement, AccessLog, SystemSetting
  • schemas/: Pydantic v2 per validazione I/O API
  • migrations/: Alembic con alembic.ini nella directory migrations
  • tests/: pytest + pytest-asyncio, database SQLite in-memory (aiosqlite), fixture pre-popolate (admin_user, maker_user, etc.), WeasyPrint mockato

Client (Flask) — client/

  • app.py: factory pattern create_app(), CSRF protection, Babel i18n
  • blueprints/: auth (login/logout/session), maker (editor ricette con Fabric.js), measure (esecuzione misurazioni), statistics (dashboard SPC con Plotly.js)
  • services/api_client.py: singleton APIClient — wrapper HTTP (get/post/put/delete) con gestione errori normalizzata, timeout 30s, header X-API-Key da session
  • templates/: Jinja2 con {{ _('string') }} per i18n
  • static/js/: Alpine.js components, Fabric.js editor, locales JSON (it.json, en.json)
  • translations/: Flask-Babel, cataloghi .po/.mo per IT/EN

Pattern Critici

Recipe Versioning (Copy-on-Write)

Le ricette usano un versioning immutabile: ogni modifica crea una nuova RecipeVersion con deep-copy di tasks e subtasks. Le misurazioni restano sempre legate alla versione originale. La versione corrente ha is_current=True, le precedenti False. Audit trail in recipe_version_audit (CREATE, UPDATE, RETIRE). Logica in server/services/recipe_service.py.

Calcolo Pass/Fail

Ogni subtask ha 4 limiti di tolleranza: UTL (upper tolerance), UWL (upper warning), LWL (lower warning), LTL (lower tolerance) più un valore nominale. Il calcolo in server/services/measurement_service.py:

  • Fuori UTL/LTL → fail
  • Fuori UWL/LWL ma dentro UTL/LTL → warning
  • Dentro UWL/LWL → pass

SPC (Statistical Process Control)

Calcoli in server/services/spc_service.py usando solo math e statistics stdlib (no numpy/scipy): summary (conteggi pass/warning/fail), capability (Cp, Cpk, Pp, Ppk), control chart (UCL/LCL = mean ± 3σ), histogram (20 bin + curva normale).

Autenticazione

  1. Login con username/password → server ritorna api_key (64 char random)
  2. Client salva api_key in Flask session
  3. Ogni richiesta API include header X-API-Key
  4. Middleware get_current_user() autentica, require_role() autorizza
  5. Dependency pre-built: require_maker, require_measurement_tec, require_metrologist, require_admin_user

Ruoli Utente

Combinabili (JSON array): Maker (crea ricette), MeasurementTec (esegue misurazioni), Metrologist (dashboard SPC). Flag is_admin separato.

File Storage

Upload in uploads/{recipe_id}/{version_id}/. Tipi ammessi: JPEG, PNG, GIF, WebP, PDF. Limite 50MB. Thumbnail auto-generate per immagini (Pillow). Sanitizzazione filename.

Convenzioni Codice

  • Python 3.11+, type hints ovunque
  • async/await per tutte le operazioni DB (server)
  • Pydantic v2 per validazione I/O API
  • Nomi variabili e commenti in inglese, UI strings in IT/EN via i18n
  • Import ordinati: stdlib → third-party → local, nessun wildcard
  • DB queries: selectinload() per eager loading, scalar_one_or_none() per single-row

Dipendenze Chiave

  • Server: fastapi, uvicorn, sqlalchemy[asyncio], asyncmy, alembic, pydantic, bcrypt, pillow, plotly, kaleido, weasyprint, jinja2
  • Client: flask, flask-babel, flask-wtf, requests
  • Test server: pytest, pytest-asyncio, httpx, aiosqlite (SQLite in-memory per test)
  • Test client: pytest, coverage

Configurazione

Variabili d'ambiente in .env (copiare da .env.example):

  • DB: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
  • Server: SERVER_HOST, SERVER_PORT, SERVER_SECRET_KEY, SERVER_CORS_ORIGINS
  • Client: CLIENT_HOST, CLIENT_PORT, CLIENT_SECRET_KEY, API_SERVER_URL
  • Upload: UPLOAD_DIR, MAX_UPLOAD_SIZE_MB
  • Setup: SETUP_PASSWORD (vuota = endpoint disabilitato)
  • SSL: SSL_CERTFILE, SSL_KEYFILE

Brand

  • Colore primario: #2563EB (blu industriale)
  • Colore secondario: #64748B (grigio acciaio)
  • Font UI: Inter
  • Font numeri: JetBrains Mono