Adriano 563b7789f4 docs(readme): rewrite for V2.0.0 — uv, src/ layout, stations, docs index
Brings the entry-point README in line with the V2.0.0 restructure:

- Replace all server/ + client/ paths with src/backend/ +
  src/frontend/flask_app/.
- Replace pip install -r requirements.txt with the uv workflow
  (uv sync --extra server --extra client --extra dev).
- Manual setup section uses uv run uvicorn / uv run flask /
  uv run alembic / uv run pybabel, all driven from the project root.
- Document the V2.0.0 additions: STATION_CODE per-tablet, /admin/
  stations GUI, gunicorn 5x4 + uvicorn 4 worker scaling, X-Forwarded
  -For-aware rate limiting (RATE_LIMIT_GENERAL default 300).
- Add tooling section (uv, pyproject.toml, uv.lock, .python-version,
  pytest stack).
- Documentation section now points at the new docs/ index plus the
  STATO_PROGETTO + ROADMAP architecture pair as the canonical "what
  is done / what is next" references.
- Variabili d'Ambiente: add STATION_CODE, RATE_LIMIT_LOGIN,
  RATE_LIMIT_GENERAL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 12:48:51 +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, identità per-stazione e rate limiting per-tablet.

Versione corrente: V2.0.0 (in sviluppo) — branch default V2.0.0. Per stato dettagliato e prossimi passi vedi docs/architecture/STATO_PROGETTO.md e docs/architecture/ROADMAP.md.


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
  • Identità per-stazione (STATION_CODE): ogni tablet vede solo le ricette assegnate alla propria stazione, gestione assegnazioni via GUI admin
  • Interfaccia completamente localizzata IT/EN, dark mode, ottimizzata per tablet touch
  • Autenticazione API Key, rate limiting sliding window per-IP reale (X-Forwarded-For-aware), audit log persistente
  • Capacità testata per ~20 tablet contemporanei (gunicorn 5 workers × 4 thread + uvicorn 4 workers async)

Architettura

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

Il frontend 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. L'IP reale del tablet è propagato in X-Forwarded-For per il rate limiter.


Stack Tecnologico

Backend (src/backend/)

Componente Versione Ruolo
FastAPI ultima stabile Framework API REST asincrono
SQLAlchemy 2.0 async ORM con pool connessioni 10+20
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 (src/frontend/flask_app/)

Componente Versione Ruolo
Flask 3.x Framework web server-side
gunicorn 21+ WSGI server (5 workers × 4 thread gthread)
Jinja2 incluso in Flask Template engine
Alpine.js 3.x (CDN) Reattività 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
html5-qrcode CDN Scanner barcode/QR camera
Flask-Babel ultima stabile i18n IT/EN

Tooling

Componente Ruolo
uv Package manager Python (no requirements.txt)
pyproject.toml Dipendenze monorepo con extra server/client/dev
uv.lock Lockfile per build riproducibili
.python-version Pin Python 3.11
pytest + pytest-asyncio + httpx + aiosqlite Test stack

Quick Start con Docker

Docker Compose è il metodo raccomandato. Gestisce database, migrazioni, build delle immagini con uv e configurazione Nginx in un solo comando.

# 1. Clona il repository
git clone ssh://git@git.tielogic.xyz:222/Adriano/TieMeasureFlow.git
cd TieMeasureFlow

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

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

# 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
# Lo script seed crea anche la stazione ST-DEFAULT con tutte le ricette assegnate

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 + crea stazione ST-DEFAULT con tutte le ricette assegnate
  • 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.

Per gestire stazioni e assegnazioni ricette dopo il setup: /admin/stations (richiede login admin).


Setup Manuale (Senza Docker)

Requisiti

  • Python 3.11 o superiore
  • Node.js 18 o superiore (per TailwindCSS)
  • MySQL 8.0
  • uv installato

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, STATION_CODE

3. Installa dipendenze (uv)

uv sync --extra server --extra client --extra dev

4. Backend FastAPI

uv run alembic -c src/backend/migrations/alembic.ini upgrade head
uv run uvicorn src.backend.main:app --reload --host 0.0.0.0 --port 8000

5. Frontend Flask

# Compila i cataloghi i18n una volta
cd src/frontend/flask_app && uv run --project ../../.. pybabel compile -d translations && cd -

# Avvia (development)
cd src/frontend/flask_app && uv run --project ../../.. flask run --host 0.0.0.0 --port 5000

6. TailwindCSS (watch per sviluppo)

cd src/frontend/flask_app
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. Vede solo le ricette assegnate alla propria stazione (STATION_CODE)
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, CRUD stazioni e assegnazioni ricette

Struttura Progetto

TieMeasureFlow/
├── pyproject.toml              # Dipendenze monorepo (uv)
├── uv.lock                     # Lockfile riproducibile
├── .python-version             # 3.11
├── Dockerfile                  # Backend (uv + uvicorn)
├── Dockerfile.frontend         # Frontend (uv + gunicorn + Tailwind + Babel)
├── docker-compose.dev.yml      # Sviluppo (Nginx, porta 80)
├── docker-compose.yml          # Produzione (Traefik, SSL)
├── nginx/                      # Config Nginx (dev)
├── uploads/                    # Volume Docker file caricati
├── docs/                       # Documentazione (vedi indice docs/README.md)
└── src/
    ├── backend/                # FastAPI Backend
    │   ├── main.py             # Entry point, lifespan, middleware, 11 router
    │   ├── config.py           # Settings (pydantic_settings.BaseSettings)
    │   ├── database.py         # SQLAlchemy 2.0 async engine
    │   ├── api/
    │   │   ├── routers/        # auth, users, recipes, tasks, measurements,
    │   │   │                   #   files, settings, statistics, reports,
    │   │   │                   #   setup, stations
    │   │   └── middleware/     # api_key, rate_limit, security_headers, logging
    │   ├── models/
    │   │   ├── orm/            # SQLAlchemy: User, Recipe, RecipeVersion,
    │   │   │                   #   RecipeTask, RecipeSubtask, Measurement,
    │   │   │                   #   AccessLog, SystemSetting,
    │   │   │                   #   RecipeVersionAudit, Station,
    │   │   │                   #   StationRecipeAssignment
    │   │   └── api/            # Pydantic v2 schemas request/response
    │   ├── services/           # recipe_service, measurement_service,
    │   │                       #   spc_service, report_service,
    │   │                       #   auth_service, station_service
    │   ├── migrations/         # Alembic (alembic.ini + env.py)
    │   ├── templates/          # Pagina setup (Jinja2)
    │   └── tests/              # pytest + httpx + aiosqlite
    └── frontend/
        └── flask_app/          # Flask Frontend
            ├── app.py          # Factory + ProxyFix + CSRF + Babel
            ├── config.py       # STATION_CODE, API_SERVER_URL, ecc.
            ├── compile_translations.py
            ├── blueprints/     # auth, maker, measure, statistics, admin
            ├── services/       # APIClient (proxy verso FastAPI con XFF)
            ├── 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
            └── tests/

Comandi Utili

Docker

Comando Descrizione
docker compose -f docker-compose.dev.yml up -d --build Avvia servizi in sviluppo (build incluso)
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)

alembic.ini si trova in src/backend/migrations/, è richiesto il flag -c. env.py aggiunge la project root a sys.path per risolvere src.backend.*.

uv run alembic -c src/backend/migrations/alembic.ini upgrade head                              # Applica migrazioni
uv run alembic -c src/backend/migrations/alembic.ini revision --autogenerate -m "descrizione"  # Genera
uv run alembic -c src/backend/migrations/alembic.ini downgrade -1                              # Rollback ultima

Via Docker:

docker compose exec server uv run alembic -c src/backend/migrations/alembic.ini upgrade head

i18n (Traduzioni)

cd src/frontend/flask_app
uv run --project ../../.. pybabel extract -F babel.cfg -k _ -o translations/messages.pot .   # Estrai
uv run --project ../../.. pybabel update -i translations/messages.pot -d translations         # Aggiorna
uv run --project ../../.. pybabel compile -d translations                                     # Compila .po → .mo

Gestione dipendenze (uv)

uv add <pacchetto>                           # core (entrambi)
uv add --optional server <pacchetto>         # solo backend
uv add --optional client <pacchetto>         # solo frontend
uv add --optional dev <pacchetto>            # solo dev/test
uv sync --extra server --extra client --extra dev  # reinstalla
uv lock                                      # rigenera uv.lock

Testing

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

# Tutti i test (backend + frontend)
uv run pytest

# Solo backend
uv run pytest src/backend/tests/
uv run pytest src/backend/tests/test_auth.py
uv run pytest src/backend/tests/test_auth.py::test_login_success
uv run pytest --cov src/backend

# Solo frontend
uv run pytest src/frontend/flask_app/tests/

Stato corrente: 171 pass, 4 fail pre-esistenti (vedi docs/architecture/STATO_PROGETTO.md).


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)
STATION_CODE Per-tablet — codice stazione (es. ST-001). Senza, il client mostra errore configurazione.
UPLOAD_DIR Percorso upload file (default: uploads, project root)
MAX_UPLOAD_SIZE_MB Limite dimensione upload (default 50)
RATE_LIMIT_LOGIN Login req/min/IP (default 5)
RATE_LIMIT_GENERAL Richieste req/min/IP (default 300, per-tablet)
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

Indice completo: docs/README.md.

Stato e direzione

Documento Contenuto
docs/architecture/STATO_PROGETTO.md Snapshot V2.0.0: cosa funziona oggi, test status, decisioni architetturali
docs/architecture/ROADMAP.md Cosa resta da fare (Fasi 2-7 rev04, decisioni cliente aperte, stime)

Riferimenti operativi

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)
docs/I18N_SETUP.md Setup e workflow traduzioni (Flask-Babel + Alpine.js)

Piani dettagliati

Documento Contenuto
docs/superpowers/plans/2026-04-17-rev04-master-roadmap.md Master plan rev04 (M1 + M2, decisioni aperte, stime)
docs/superpowers/plans/2026-04-17-rev04-phase1-stations.md Piano TDD Fase 1 stazioni (completato)

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%