Adriano 2963d3d647 fix(db): portability and dedup in migration 002
- server_default='1' anziche sa.true() per compatibilita con SQLite
  (usato come DB in-memory nei test)
- Rimuove Index ix_stations_code ridondante con UniqueConstraint
  uq_stations_code (InnoDB crea gia un indice per i vincoli UNIQUE)

Feedback da code-reviewer su Task 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 21:40:15 +02:00

TieMeasureFlow by Tielogic

Sistema di gestione task per misurazioni con calibro manuale. Soluzione tablet-first, multi-ruolo, con statistiche SPC (Statistical Process Control) integrate.


Panoramica

TieMeasureFlow guida l'operatore attraverso sequenze di misurazione definite dal Maker, registra i valori (da calibro USB HID o numpad touch), e valuta automaticamente la conformità rispetto alle tolleranze configurate. I dati raccolti alimentano una dashboard SPC con indici di capability e control chart, esportabili in PDF.

Caratteristiche principali:

  • Recipe versioning condizionale (copy-on-write se esistono misurazioni, update in-place altrimenti)
  • Calcolo pass/fail/warning su quattro limiti di tolleranza (UTL, UWL, LWL, LTL)
  • SPC: Cp, Cpk, Pp, Ppk, control chart UCL/LCL, istogramma con curva normale — puro stdlib (no numpy)
  • Annotazioni grafiche su disegni tecnici (Fabric.js) con viewer sincronizzato all'esecuzione
  • Interfaccia completamente localizzata IT/EN, dark mode, ottimizzata per tablet touch
  • Autenticazione API Key, rate limiting sliding window, audit log persistente

Architettura

Browser/Tablet
      |
Reverse Proxy (Nginx — sviluppo | Traefik+SSL — produzione)
      |
Flask Client  :5000  (rendering server-side, Jinja2 + Alpine.js)
      |  X-API-Key
FastAPI Server  :8000  (API REST asincrona)
      |
MySQL 8.0

Il client Flask non espone mai le credenziali al browser: ogni chiamata al backend avviene server-side con l'header X-API-Key estratto dalla sessione Flask.


Stack Tecnologico

Backend (server/)

Componente Versione Ruolo
FastAPI ultima stabile Framework API REST asincrono
SQLAlchemy 2.0 async ORM con pool connessioni
asyncmy ultima stabile Driver MySQL asincrono
MySQL 8.0 Database relazionale
Alembic ultima stabile Migrazioni schema
Pydantic v2 v2 Validazione I/O
WeasyPrint ultima stabile Generazione report PDF
Kaleido ultima stabile Export grafici Plotly in SVG
bcrypt ultima stabile Hashing password
Pillow ultima stabile Thumbnail automatici upload

Frontend (client/)

Componente Versione Ruolo
Flask 3.x Framework web server-side
Jinja2 incluso in Flask Template engine
Alpine.js 3.x (CDN) Reattivita leggera lato client
TailwindCSS 3.x CSS utility-first
Plotly.js CDN Grafici SPC interattivi
Fabric.js 5.3.1 (CDN) Editor annotazioni disegni tecnici
Flask-Babel ultima stabile i18n IT/EN

Quick Start con Docker

Docker Compose è il metodo raccomandato. Gestisce database, migrazioni e configurazione Nginx in un solo comando.

# 1. Clona il repository
git clone <repository-url>
cd TieMeasureFlow

# 2. Configura le variabili d'ambiente
cp .env.example .env
# Modifica .env: credenziali DB, chiavi segrete, SETUP_PASSWORD

# 3. Avvia i servizi (ambiente di sviluppo)
docker compose -f docker-compose.dev.yml up -d

# 4. Verifica lo stato dei container
docker compose -f docker-compose.dev.yml ps

# 5. Setup iniziale (solo al primo avvio)
# Apri http://localhost/api/setup nel browser
# Usa SETUP_PASSWORD configurata in .env

L'applicazione sarà disponibile su:

Per il deployment in produzione (Traefik + SSL) consulta docs/DEPLOYMENT.md.


Setup Iniziale

Dopo il primo avvio, la pagina /api/setup (protetta da SETUP_PASSWORD) permette di:

  • Initialize Database — crea tutte le tabelle
  • Create Admin User — crea l'utente amministratore con credenziali da .env
  • Seed Demo Data — carica ricette, misurazioni e utenti di esempio
  • Reset Database — elimina e ricrea tutte le tabelle (attenzione: cancella tutti i dati)
  • Gestione utenti — crea, modifica, attiva/disattiva account dalla stessa pagina

Se SETUP_PASSWORD è vuota o assente nel .env, l'endpoint è disabilitato.


Setup Manuale (Senza Docker)

Requisiti

  • Python 3.11 o superiore
  • Node.js 18 o superiore
  • MySQL 8.0

1. Database MySQL

mysql -u root -p <<'SQL'
CREATE DATABASE tiemeasureflow CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'tielogic'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON tiemeasureflow.* TO 'tielogic'@'localhost';
FLUSH PRIVILEGES;
SQL

2. Configurazione

cp .env.example .env
# Imposta DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, SERVER_SECRET_KEY, CLIENT_SECRET_KEY, SETUP_PASSWORD

3. Server FastAPI

cd server
python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt
alembic -c migrations/alembic.ini upgrade head
uvicorn main:app --reload --host 0.0.0.0 --port 8000

4. Client Flask

cd client
python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt
pybabel compile -d translations
flask run --host 0.0.0.0 --port 5000

5. TailwindCSS (watch per sviluppo)

cd client
npx tailwindcss -i static/css/input.css -o static/css/tailwind.css --watch

Accesso diretto (senza Nginx):


Ruoli Utente

I ruoli sono combinabili (array JSON per utente). Il flag is_admin è separato dai ruoli funzionali.

Ruolo Descrizione
Maker Crea e gestisce ricette di misurazione: caricamento disegni (PDF/immagini), annotazioni Fabric.js, definizione task/subtask, configurazione tolleranze, versioning copy-on-write
MeasurementTec Esegue misurazioni: scansione barcode per selezione ricetta, interfaccia task-driven, input da calibro USB HID o numpad touch, validazione real-time pass/warning/fail
Metrologist Analisi qualità: dashboard SPC (X-bar, R, Cp, Cpk, Pp, Ppk), filtri multi-dimensionali, export report PDF, analisi capability e control chart
Admin (flag) Gestione sistema: CRUD utenti, cambio password, attivazione/disattivazione account

Struttura Progetto

TieMeasureFlow/
├── server/                      # FastAPI Backend
│   ├── main.py                  # Entry point, lifespan, middleware, 10 router
│   ├── config.py                # Settings (pydantic_settings.BaseSettings)
│   ├── database.py              # SQLAlchemy 2.0 async engine
│   ├── models/                  # ORM: User, Recipe, RecipeVersion, RecipeTask,
│   │                            #   RecipeSubtask, Measurement, AccessLog,
│   │                            #   SystemSetting, RecipeVersionAudit
│   ├── schemas/                 # Pydantic v2 per validazione I/O API
│   ├── routers/                 # auth, users, recipes, tasks, measurements,
│   │                            #   files, settings, statistics, reports, setup
│   ├── services/                # recipe_service, measurement_service,
│   │                            #   spc_service, report_service, auth_service
│   ├── middleware/              # api_key, rate_limit, security_headers, logging
│   ├── migrations/              # Alembic (alembic.ini + env.py)
│   └── templates/               # Template HTML pagina setup
├── client/                      # Flask Frontend
│   ├── app.py                   # Factory pattern, CSRF, Babel
│   ├── blueprints/              # auth, maker, measure, statistics, admin
│   ├── services/                # APIClient singleton (proxy verso FastAPI)
│   ├── templates/               # Jinja2 + Alpine.js
│   ├── static/
│   │   ├── css/                 # TailwindCSS compilato
│   │   └── js/                  # numpad, caliper, barcode, csv-export,
│   │                            #   spc-charts, annotation-editor/viewer
│   └── translations/            # Flask-Babel .po/.mo IT/EN
├── nginx/                       # Configurazione Nginx (dev)
├── docs/                        # Documentazione tecnica
│   ├── API.md                   # Riferimento API REST
│   ├── DEPLOYMENT.md            # Guida deployment VPS (Traefik, SSL, DNS)
│   └── USER_GUIDE.md            # Manuale utente per ruolo
├── docker-compose.yml           # Produzione (Traefik, SSL)
├── docker-compose.dev.yml       # Sviluppo (Nginx, porta 80)
└── .env.example                 # Template variabili d'ambiente

Comandi Utili

Docker

Comando Descrizione
docker compose -f docker-compose.dev.yml up -d Avvia servizi in sviluppo
docker compose -f docker-compose.dev.yml down Ferma e rimuove i container
docker compose logs -f server Segui log server in tempo reale
docker compose logs -f client Segui log client in tempo reale
docker compose ps Stato di tutti i servizi
docker compose build --no-cache Ricostruisci immagini senza cache
docker compose exec mysql mysql -u root -p tiemeasureflow CLI MySQL

Alembic (migrations)

Nota: alembic.ini si trova dentro server/migrations/, è richiesto il flag -c.

cd server
alembic -c migrations/alembic.ini upgrade head                              # Applica migrazioni
alembic -c migrations/alembic.ini revision --autogenerate -m "descrizione"  # Genera migrazione
alembic -c migrations/alembic.ini downgrade -1                              # Rollback ultima

Via Docker:

docker compose exec server alembic -c migrations/alembic.ini upgrade head

i18n (Traduzioni)

cd client
pybabel extract -F babel.cfg -k _ -o translations/messages.pot .   # Estrai stringhe
pybabel update -i translations/messages.pot -d translations         # Aggiorna catalogo
pybabel compile -d translations                                      # Compila .po → .mo

Testing

Il server usa SQLite in-memory tramite aiosqlite: i test girano senza MySQL installato.

# Server
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

Variabili d'Ambiente

Copia .env.example in .env e configura:

Variabile Descrizione
DB_HOST, DB_PORT, DB_NAME Connessione MySQL
DB_USER, DB_PASSWORD Credenziali utente MySQL
DB_ROOT_PASSWORD Password root MySQL (solo Docker)
SERVER_SECRET_KEY Chiave segreta FastAPI
SERVER_CORS_ORIGINS Origini CORS ammesse
CLIENT_SECRET_KEY Chiave segreta Flask (sessioni, CSRF)
API_SERVER_URL URL del backend visto dal client (es. http://server:8000)
UPLOAD_DIR Percorso upload file (default: uploads, relativo a server/)
MAX_UPLOAD_SIZE_MB Limite dimensione upload
NGINX_PORT, NGINX_SSL_PORT Porte Nginx (solo compose dev)
SETUP_PASSWORD Password pagina setup (vuota = endpoint disabilitato)
SSL_CERTFILE, SSL_KEYFILE Certificato SSL (solo setup manuale)

Documentazione

Documento Contenuto
docs/API.md Riferimento completo API REST (endpoint, parametri, schemi)
docs/DEPLOYMENT.md Guida deployment VPS: Docker, Traefik, SSL, DNS, firewall
docs/USER_GUIDE.md Manuale utente per ruolo (Maker, MeasurementTec, Metrologist)

Licenza

Proprietary - Tielogic. All rights reserved.

Questo software è di proprietà esclusiva di Tielogic ed è protetto dalle leggi sul copyright. Non è consentita la distribuzione, modifica o utilizzo senza autorizzazione scritta.

S
Description
No description provided
Readme 903 KiB
Languages
HTML 47.3%
Python 41.5%
JavaScript 9.8%
CSS 1.2%
Dockerfile 0.1%