Adriano 1a0431366f chore(v2): restructure monorepo to src/ layout with uv
Aligns the repo with the python-project-spec-design.md template chosen
for V2.0.0. Big move, no logic changes. The 3 pre-existing test
failures (test_recipes::test_update_recipe, test_recipes::
test_recipe_versioning, test_tasks::test_reorder_tasks, plus the
client test_save_measurement_proxy) survive unchanged.

Layout changes
- server/        -> src/backend/
- server/middleware/ -> src/backend/api/middleware/
- server/routers/    -> src/backend/api/routers/
- server/models/     -> src/backend/models/orm/
- server/schemas/    -> src/backend/models/api/
- server/uploads/    -> uploads/ (project root, mounted volume)
- server/tests/      -> src/backend/tests/
- client/            -> src/frontend/flask_app/ (Flask kept; React
  deroga is documented in CLAUDE.md, justified by tablet UX, USB
  caliper/barcode workflow and Fabric.js integration)

Tooling
- pyproject.toml: monorepo with [project] core deps and
  optional-dependencies server / client / dev. Replaces both
  server/requirements.txt and client/requirements.txt.
- uv.lock + .python-version (3.11) committed for reproducible builds.
- Dockerfile (root, backend) and Dockerfile.frontend rewritten to use
  uv sync --frozen --no-dev --extra server|client; legacy Dockerfiles
  preserved as Dockerfile.legacy for reference but excluded from build
  context via .dockerignore.
- docker-compose.dev.yml + docker-compose.yml: build context now ".",
  dockerfile pointing to the root files.

Code adjustments forced by the move
- Every "from config|database|models|schemas|services|routers|middleware
  import ..." rewritten to its src.backend.* equivalent (50+ files
  including indented inline imports inside test bodies).
- src/backend/migrations/env.py: insert project root into sys.path so
  alembic can resolve src.backend.* imports regardless of cwd.
- src/backend/config.py: env_file ../../.env (was ../.env), upload_path
  resolves project root via parents[2].
- src/backend/tests/conftest.py + tests: import ... from src.backend.*
  instead of bare names; old per-directory pytest.ini files removed in
  favor of root pyproject.toml [tool.pytest.ini_options].
- .gitignore: uploads/ at root, src/frontend/flask_app/static/css/
  tailwind.css path; .dockerignore tightened.
- CLAUDE.md: rewrote sections "Layout del repository", "Comandi di
  Sviluppo", "Database & Migrations", "Test", "i18n", and all path
  references throughout the architecture sections.

Verified
- uv lock resolves 77 packages; uv sync --extra server --extra client
  --extra dev installs cleanly.
- uv run pytest: 171 passed, 4 pre-existing failures.
- uv run alembic -c src/backend/migrations/alembic.ini check loads
  config and metadata (errors only on the absent local MySQL).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 12:26:47 +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%