docs: fix middleware order and add missing details to CLAUDE.md

Correct the middleware stack order (was documented backwards due to
Starlette's add_middleware wrapping behavior), document fabric-debug.js
local copy, and note full 50-900 shade palettes for Tailwind colors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Adriano
2026-02-25 14:24:02 +01:00
parent 1578398f0f
commit 767bd7f947
+4 -4
View File
@@ -84,7 +84,7 @@ Il client Flask è un frontend server-side che comunica col backend via REST API
- **database.py**: SQLAlchemy 2.0 async engine con `AsyncSession`, pool 10+20 overflow, `pool_recycle=3600`, `expire_on_commit=False` - **database.py**: SQLAlchemy 2.0 async engine con `AsyncSession`, pool 10+20 overflow, `pool_recycle=3600`, `expire_on_commit=False`
- **routers/**: auth, users, recipes, tasks, measurements, files, settings, statistics, reports, setup. Il task router (`tasks.py`) usa URL pattern misti: `/api/recipes/{id}/tasks` (list/create), `/api/tasks/{id}` (get/update/delete), `/api/tasks/reorder`, `/api/tasks/{id}/subtasks`, `/api/subtasks/{id}` - **routers/**: auth, users, recipes, tasks, measurements, files, settings, statistics, reports, setup. Il task router (`tasks.py`) usa URL pattern misti: `/api/recipes/{id}/tasks` (list/create), `/api/tasks/{id}` (get/update/delete), `/api/tasks/reorder`, `/api/tasks/{id}/subtasks`, `/api/subtasks/{id}`
- **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) - **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/**: Stack order (outermost→innermost): RateLimitMiddleware → SecurityHeadersMiddleware → CORSMiddleware → AccessLogMiddleware. api_key.py (auth dependency `get_current_user()`), rate_limit.py (sliding window 60s per-IP, in-memory dicts), security_headers.py (CSP con `unsafe-eval` per Plotly.js, HSTS solo con SSL), logging.py (audit trail async su DB, esclude /api/health, /docs, /openapi.json, /redoc) - **middleware/**: Stack order (outermost→innermost): AccessLogMiddleware → CORSMiddleware → SecurityHeadersMiddleware → RateLimitMiddleware. Nota: `add_middleware()` in Starlette wrappa l'app, quindi l'ultimo aggiunto (AccessLog) è il più esterno. Il commento in `main.py` dice "outermost" per RateLimit ma è fuorviante. api_key.py (auth dependency `get_current_user()`), rate_limit.py (sliding window 60s per-IP, in-memory dicts), security_headers.py (CSP con `unsafe-eval` per Plotly.js, HSTS solo con SSL), logging.py (audit trail async su DB, esclude /api/health, /docs, /openapi.json, /redoc)
- **models/**: User (include `email`, `language_pref`, `theme_pref`), Recipe (`image_path` per preview), RecipeVersion, RecipeTask, RecipeSubtask (`image_path` per immagine specifica), Measurement (`synced_to_csv`, `input_method`), AccessLog, SystemSetting, RecipeVersionAudit - **models/**: User (include `email`, `language_pref`, `theme_pref`), Recipe (`image_path` per preview), RecipeVersion, RecipeTask, RecipeSubtask (`image_path` per immagine specifica), Measurement (`synced_to_csv`, `input_method`), AccessLog, SystemSetting, RecipeVersionAudit
- **schemas/**: Pydantic v2 per validazione I/O API - **schemas/**: Pydantic v2 per validazione I/O API
- **migrations/**: Alembic con `alembic.ini` e `env.py` nella directory `server/migrations/` - **migrations/**: Alembic con `alembic.ini` e `env.py` nella directory `server/migrations/`
@@ -95,7 +95,7 @@ Il client Flask è un frontend server-side che comunica col backend via REST API
- **blueprints/**: auth (login/logout/session), maker (editor ricette con Fabric.js), measure (esecuzione misurazioni), statistics (dashboard SPC con Plotly.js), admin (gestione utenti CRUD, cambio password, toggle attivo — solo `is_admin`) - **blueprints/**: auth (login/logout/session), maker (editor ricette con Fabric.js), measure (esecuzione misurazioni), statistics (dashboard SPC con Plotly.js), admin (gestione utenti CRUD, cambio password, toggle attivo — solo `is_admin`)
- **services/api_client.py**: singleton `APIClient` — wrapper HTTP (get/post/put/delete) con gestione errori normalizzata, timeout 30s, header X-API-Key da session - **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. Context processor inietta `current_user`, `current_theme`, `current_language`, `company_logo`, `languages` in tutti i template. Filtro custom `tojson_attr` per JSON sicuro in attributi HTML (escapa `"``&#34;`) - **templates/**: Jinja2 con `{{ _('string') }}` per i18n. Context processor inietta `current_user`, `current_theme`, `current_language`, `company_logo`, `languages` in tutti i template. Filtro custom `tojson_attr` per JSON sicuro in attributi HTML (escapa `"``&#34;`)
- **static/js/**: Alpine.js 3.x (CDN), Fabric.js 5.3.1 (CDN), locales JSON (it.json, en.json), alpine-init.js (theme store). Componenti specializzati: `numpad.js` (input numerico touch con rilevamento burst USB HID), `caliper.js` (monitor calibro USB passivo), `barcode.js` (scanner QR/barcode con camera via html5-qrcode), `csv-export.js` (export CSV con locale italiano: `;` separatore, `,` decimale), `spc-charts.js` (grafici SPC con Plotly.js), `annotation-editor.js` / `annotation-viewer.js` (editor/viewer annotazioni Fabric.js) - **static/js/**: Alpine.js 3.x (CDN), Fabric.js 5.3.1 (CDN) + `fabric-debug.js` (copia locale 5.3.0 per debug), locales JSON (it.json, en.json), alpine-init.js (theme store). Componenti specializzati: `numpad.js` (input numerico touch con rilevamento burst USB HID), `caliper.js` (monitor calibro USB passivo), `barcode.js` (scanner QR/barcode con camera via html5-qrcode), `csv-export.js` (export CSV con locale italiano: `;` separatore, `,` decimale), `spc-charts.js` (grafici SPC con Plotly.js), `annotation-editor.js` / `annotation-viewer.js` (editor/viewer annotazioni Fabric.js)
- **translations/**: Flask-Babel, cataloghi .po/.mo per IT/EN. Locale selector: `session["language"]` → Accept-Language → `"it"` - **translations/**: Flask-Babel, cataloghi .po/.mo per IT/EN. Locale selector: `session["language"]` → Accept-Language → `"it"`
- **config.py**: `PERMANENT_SESSION_LIFETIME=28800` (8h), cookie secure in produzione, `BABEL_DEFAULT_TIMEZONE="Europe/Rome"` - **config.py**: `PERMANENT_SESSION_LIFETIME=28800` (8h), cookie secure in produzione, `BABEL_DEFAULT_TIMEZONE="Europe/Rome"`
@@ -238,8 +238,8 @@ Variabili d'ambiente in `.env` (copiare da `.env.example`):
- SSL: `SSL_CERTFILE`, `SSL_KEYFILE` - SSL: `SSL_CERTFILE`, `SSL_KEYFILE`
## Brand & Tailwind Custom Colors ## Brand & Tailwind Custom Colors
- Colore primario: #2563EB (blu industriale) → `primary` in tailwind.config.js - Colore primario: #2563EB (blu industriale) → `primary` in tailwind.config.js (palette completa 50900)
- Colore secondario: #64748B (grigio acciaio) → `steel` in tailwind.config.js - Colore secondario: #64748B (grigio acciaio) → `steel` in tailwind.config.js (palette completa 50900)
- Colori misurazioni: `measure-pass` (#059669), `measure-warning` (#D97706), `measure-fail` (#DC2626) - Colori misurazioni: `measure-pass` (#059669), `measure-warning` (#D97706), `measure-fail` (#DC2626)
- Font UI: Inter - Font UI: Inter
- Font numeri: JetBrains Mono - Font numeri: JetBrains Mono