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>
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
# TieMeasureFlow by Tielogic
|
# TieMeasureFlow by Tielogic
|
||||||
|
|
||||||
Sistema di gestione task per misurazioni con calibro manuale. Soluzione tablet-first, multi-ruolo, con statistiche SPC (Statistical Process Control) integrate.
|
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`](docs/architecture/STATO_PROGETTO.md) e [`docs/architecture/ROADMAP.md`](docs/architecture/ROADMAP.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -14,8 +17,10 @@ Caratteristiche principali:
|
|||||||
- Calcolo pass/fail/warning su quattro limiti di tolleranza (UTL, UWL, LWL, LTL)
|
- 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)
|
- 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
|
- 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
|
- Interfaccia completamente localizzata IT/EN, dark mode, ottimizzata per tablet touch
|
||||||
- Autenticazione API Key, rate limiting sliding window, audit log persistente
|
- 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)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -26,25 +31,25 @@ Browser/Tablet
|
|||||||
|
|
|
|
||||||
Reverse Proxy (Nginx — sviluppo | Traefik+SSL — produzione)
|
Reverse Proxy (Nginx — sviluppo | Traefik+SSL — produzione)
|
||||||
|
|
|
|
||||||
Flask Client :5000 (rendering server-side, Jinja2 + Alpine.js)
|
Flask Frontend :5000 (rendering server-side, Jinja2 + Alpine.js)
|
||||||
| X-API-Key
|
| X-API-Key + X-Forwarded-For
|
||||||
FastAPI Server :8000 (API REST asincrona)
|
FastAPI Backend :8000 (API REST asincrona)
|
||||||
|
|
|
|
||||||
MySQL 8.0
|
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.
|
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
|
## Stack Tecnologico
|
||||||
|
|
||||||
### Backend (server/)
|
### Backend (`src/backend/`)
|
||||||
|
|
||||||
| Componente | Versione | Ruolo |
|
| Componente | Versione | Ruolo |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| FastAPI | ultima stabile | Framework API REST asincrono |
|
| FastAPI | ultima stabile | Framework API REST asincrono |
|
||||||
| SQLAlchemy 2.0 | async | ORM con pool connessioni |
|
| SQLAlchemy 2.0 | async | ORM con pool connessioni 10+20 |
|
||||||
| asyncmy | ultima stabile | Driver MySQL asincrono |
|
| asyncmy | ultima stabile | Driver MySQL asincrono |
|
||||||
| MySQL | 8.0 | Database relazionale |
|
| MySQL | 8.0 | Database relazionale |
|
||||||
| Alembic | ultima stabile | Migrazioni schema |
|
| Alembic | ultima stabile | Migrazioni schema |
|
||||||
@@ -54,35 +59,47 @@ Il client Flask non espone mai le credenziali al browser: ogni chiamata al backe
|
|||||||
| bcrypt | ultima stabile | Hashing password |
|
| bcrypt | ultima stabile | Hashing password |
|
||||||
| Pillow | ultima stabile | Thumbnail automatici upload |
|
| Pillow | ultima stabile | Thumbnail automatici upload |
|
||||||
|
|
||||||
### Frontend (client/)
|
### Frontend (`src/frontend/flask_app/`)
|
||||||
|
|
||||||
| Componente | Versione | Ruolo |
|
| Componente | Versione | Ruolo |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Flask | 3.x | Framework web server-side |
|
| Flask | 3.x | Framework web server-side |
|
||||||
|
| gunicorn | 21+ | WSGI server (5 workers × 4 thread gthread) |
|
||||||
| Jinja2 | incluso in Flask | Template engine |
|
| Jinja2 | incluso in Flask | Template engine |
|
||||||
| Alpine.js | 3.x (CDN) | Reattivita leggera lato client |
|
| Alpine.js | 3.x (CDN) | Reattività leggera lato client |
|
||||||
| TailwindCSS | 3.x | CSS utility-first |
|
| TailwindCSS | 3.x | CSS utility-first |
|
||||||
| Plotly.js | CDN | Grafici SPC interattivi |
|
| Plotly.js | CDN | Grafici SPC interattivi |
|
||||||
| Fabric.js | 5.3.1 (CDN) | Editor annotazioni disegni tecnici |
|
| Fabric.js | 5.3.1 (CDN) | Editor annotazioni disegni tecnici |
|
||||||
|
| html5-qrcode | CDN | Scanner barcode/QR camera |
|
||||||
| Flask-Babel | ultima stabile | i18n IT/EN |
|
| 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
|
## Quick Start con Docker
|
||||||
|
|
||||||
Docker Compose è il metodo raccomandato. Gestisce database, migrazioni e configurazione Nginx in un solo comando.
|
Docker Compose è il metodo raccomandato. Gestisce database, migrazioni, build delle immagini con `uv` e configurazione Nginx in un solo comando.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Clona il repository
|
# 1. Clona il repository
|
||||||
git clone <repository-url>
|
git clone ssh://git@git.tielogic.xyz:222/Adriano/TieMeasureFlow.git
|
||||||
cd TieMeasureFlow
|
cd TieMeasureFlow
|
||||||
|
|
||||||
# 2. Configura le variabili d'ambiente
|
# 2. Configura le variabili d'ambiente
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
# Modifica .env: credenziali DB, chiavi segrete, SETUP_PASSWORD
|
# Modifica .env: credenziali DB, chiavi segrete, SETUP_PASSWORD, STATION_CODE per ogni tablet
|
||||||
|
|
||||||
# 3. Avvia i servizi (ambiente di sviluppo)
|
# 3. Avvia i servizi (ambiente di sviluppo)
|
||||||
docker compose -f docker-compose.dev.yml up -d
|
docker compose -f docker-compose.dev.yml up -d --build
|
||||||
|
|
||||||
# 4. Verifica lo stato dei container
|
# 4. Verifica lo stato dei container
|
||||||
docker compose -f docker-compose.dev.yml ps
|
docker compose -f docker-compose.dev.yml ps
|
||||||
@@ -90,6 +107,7 @@ docker compose -f docker-compose.dev.yml ps
|
|||||||
# 5. Setup iniziale (solo al primo avvio)
|
# 5. Setup iniziale (solo al primo avvio)
|
||||||
# Apri http://localhost/api/setup nel browser
|
# Apri http://localhost/api/setup nel browser
|
||||||
# Usa SETUP_PASSWORD configurata in .env
|
# 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:
|
L'applicazione sarà disponibile su:
|
||||||
@@ -97,8 +115,9 @@ L'applicazione sarà disponibile su:
|
|||||||
- Frontend: http://localhost
|
- Frontend: http://localhost
|
||||||
- API: http://localhost/api
|
- API: http://localhost/api
|
||||||
- Pagina setup: http://localhost/api/setup
|
- Pagina setup: http://localhost/api/setup
|
||||||
|
- Admin stazioni: http://localhost/admin/stations (solo `is_admin`)
|
||||||
|
|
||||||
Per il deployment in produzione (Traefik + SSL) consulta [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md).
|
Per il deployment in produzione (Traefik + SSL) consulta [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -108,12 +127,14 @@ Dopo il primo avvio, la pagina `/api/setup` (protetta da `SETUP_PASSWORD`) perme
|
|||||||
|
|
||||||
- **Initialize Database** — crea tutte le tabelle
|
- **Initialize Database** — crea tutte le tabelle
|
||||||
- **Create Admin User** — crea l'utente amministratore con credenziali da `.env`
|
- **Create Admin User** — crea l'utente amministratore con credenziali da `.env`
|
||||||
- **Seed Demo Data** — carica ricette, misurazioni e utenti di esempio
|
- **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)
|
- **Reset Database** — elimina e ricrea tutte le tabelle (attenzione: cancella tutti i dati)
|
||||||
- **Gestione utenti** — crea, modifica, attiva/disattiva account dalla stessa pagina
|
- **Gestione utenti** — crea, modifica, attiva/disattiva account dalla stessa pagina
|
||||||
|
|
||||||
Se `SETUP_PASSWORD` è vuota o assente nel `.env`, l'endpoint è disabilitato.
|
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)
|
## Setup Manuale (Senza Docker)
|
||||||
@@ -121,8 +142,9 @@ Se `SETUP_PASSWORD` è vuota o assente nel `.env`, l'endpoint è disabilitato.
|
|||||||
### Requisiti
|
### Requisiti
|
||||||
|
|
||||||
- Python 3.11 o superiore
|
- Python 3.11 o superiore
|
||||||
- Node.js 18 o superiore
|
- Node.js 18 o superiore (per TailwindCSS)
|
||||||
- MySQL 8.0
|
- MySQL 8.0
|
||||||
|
- [uv](https://docs.astral.sh/uv/) installato
|
||||||
|
|
||||||
### 1. Database MySQL
|
### 1. Database MySQL
|
||||||
|
|
||||||
@@ -139,35 +161,37 @@ SQL
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
# Imposta DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, SERVER_SECRET_KEY, CLIENT_SECRET_KEY, SETUP_PASSWORD
|
# Imposta DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, SERVER_SECRET_KEY,
|
||||||
|
# CLIENT_SECRET_KEY, SETUP_PASSWORD, STATION_CODE
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Server FastAPI
|
### 3. Installa dipendenze (uv)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd server
|
uv sync --extra server --extra client --extra dev
|
||||||
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
|
### 4. Backend FastAPI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd client
|
uv run alembic -c src/backend/migrations/alembic.ini upgrade head
|
||||||
python -m venv venv
|
uv run uvicorn src.backend.main:app --reload --host 0.0.0.0 --port 8000
|
||||||
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)
|
### 5. Frontend Flask
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd client
|
# 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)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd src/frontend/flask_app
|
||||||
npx tailwindcss -i static/css/input.css -o static/css/tailwind.css --watch
|
npx tailwindcss -i static/css/input.css -o static/css/tailwind.css --watch
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -185,9 +209,9 @@ I ruoli sono combinabili (array JSON per utente). Il flag `is_admin` è separato
|
|||||||
| Ruolo | Descrizione |
|
| 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 |
|
| **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 |
|
| **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 |
|
| **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 |
|
| **Admin** (flag) | Gestione sistema: CRUD utenti, cambio password, attivazione/disattivazione account, **CRUD stazioni e assegnazioni ricette** |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -195,39 +219,53 @@ I ruoli sono combinabili (array JSON per utente). Il flag `is_admin` è separato
|
|||||||
|
|
||||||
```
|
```
|
||||||
TieMeasureFlow/
|
TieMeasureFlow/
|
||||||
├── server/ # FastAPI Backend
|
├── pyproject.toml # Dipendenze monorepo (uv)
|
||||||
│ ├── main.py # Entry point, lifespan, middleware, 10 router
|
├── uv.lock # Lockfile riproducibile
|
||||||
│ ├── config.py # Settings (pydantic_settings.BaseSettings)
|
├── .python-version # 3.11
|
||||||
│ ├── database.py # SQLAlchemy 2.0 async engine
|
├── Dockerfile # Backend (uv + uvicorn)
|
||||||
│ ├── models/ # ORM: User, Recipe, RecipeVersion, RecipeTask,
|
├── Dockerfile.frontend # Frontend (uv + gunicorn + Tailwind + Babel)
|
||||||
│ │ # RecipeSubtask, Measurement, AccessLog,
|
├── docker-compose.dev.yml # Sviluppo (Nginx, porta 80)
|
||||||
│ │ # SystemSetting, RecipeVersionAudit
|
├── docker-compose.yml # Produzione (Traefik, SSL)
|
||||||
│ ├── schemas/ # Pydantic v2 per validazione I/O API
|
├── nginx/ # Config Nginx (dev)
|
||||||
│ ├── routers/ # auth, users, recipes, tasks, measurements,
|
├── uploads/ # Volume Docker file caricati
|
||||||
│ │ # files, settings, statistics, reports, setup
|
├── docs/ # Documentazione (vedi indice docs/README.md)
|
||||||
│ ├── services/ # recipe_service, measurement_service,
|
└── src/
|
||||||
│ │ # spc_service, report_service, auth_service
|
├── backend/ # FastAPI Backend
|
||||||
│ ├── middleware/ # api_key, rate_limit, security_headers, logging
|
│ ├── main.py # Entry point, lifespan, middleware, 11 router
|
||||||
│ ├── migrations/ # Alembic (alembic.ini + env.py)
|
│ ├── config.py # Settings (pydantic_settings.BaseSettings)
|
||||||
│ └── templates/ # Template HTML pagina setup
|
│ ├── database.py # SQLAlchemy 2.0 async engine
|
||||||
├── client/ # Flask Frontend
|
│ ├── api/
|
||||||
│ ├── app.py # Factory pattern, CSRF, Babel
|
│ │ ├── routers/ # auth, users, recipes, tasks, measurements,
|
||||||
│ ├── blueprints/ # auth, maker, measure, statistics, admin
|
│ │ │ # files, settings, statistics, reports,
|
||||||
│ ├── services/ # APIClient singleton (proxy verso FastAPI)
|
│ │ │ # setup, stations
|
||||||
│ ├── templates/ # Jinja2 + Alpine.js
|
│ │ └── middleware/ # api_key, rate_limit, security_headers, logging
|
||||||
│ ├── static/
|
│ ├── models/
|
||||||
│ │ ├── css/ # TailwindCSS compilato
|
│ │ ├── orm/ # SQLAlchemy: User, Recipe, RecipeVersion,
|
||||||
│ │ └── js/ # numpad, caliper, barcode, csv-export,
|
│ │ │ # RecipeTask, RecipeSubtask, Measurement,
|
||||||
│ │ # spc-charts, annotation-editor/viewer
|
│ │ │ # AccessLog, SystemSetting,
|
||||||
│ └── translations/ # Flask-Babel .po/.mo IT/EN
|
│ │ │ # RecipeVersionAudit, Station,
|
||||||
├── nginx/ # Configurazione Nginx (dev)
|
│ │ │ # StationRecipeAssignment
|
||||||
├── docs/ # Documentazione tecnica
|
│ │ └── api/ # Pydantic v2 schemas request/response
|
||||||
│ ├── API.md # Riferimento API REST
|
│ ├── services/ # recipe_service, measurement_service,
|
||||||
│ ├── DEPLOYMENT.md # Guida deployment VPS (Traefik, SSL, DNS)
|
│ │ # spc_service, report_service,
|
||||||
│ └── USER_GUIDE.md # Manuale utente per ruolo
|
│ │ # auth_service, station_service
|
||||||
├── docker-compose.yml # Produzione (Traefik, SSL)
|
│ ├── migrations/ # Alembic (alembic.ini + env.py)
|
||||||
├── docker-compose.dev.yml # Sviluppo (Nginx, porta 80)
|
│ ├── templates/ # Pagina setup (Jinja2)
|
||||||
└── .env.example # Template variabili d'ambiente
|
│ └── 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/
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -238,7 +276,7 @@ TieMeasureFlow/
|
|||||||
|
|
||||||
| Comando | Descrizione |
|
| Comando | Descrizione |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `docker compose -f docker-compose.dev.yml up -d` | Avvia servizi in sviluppo |
|
| `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 -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 server` | Segui log server in tempo reale |
|
||||||
| `docker compose logs -f client` | Segui log client in tempo reale |
|
| `docker compose logs -f client` | Segui log client in tempo reale |
|
||||||
@@ -248,47 +286,62 @@ TieMeasureFlow/
|
|||||||
|
|
||||||
### Alembic (migrations)
|
### Alembic (migrations)
|
||||||
|
|
||||||
Nota: `alembic.ini` si trova dentro `server/migrations/`, è richiesto il flag `-c`.
|
`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.*`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd server
|
uv run alembic -c src/backend/migrations/alembic.ini upgrade head # Applica migrazioni
|
||||||
alembic -c migrations/alembic.ini upgrade head # Applica migrazioni
|
uv run alembic -c src/backend/migrations/alembic.ini revision --autogenerate -m "descrizione" # Genera
|
||||||
alembic -c migrations/alembic.ini revision --autogenerate -m "descrizione" # Genera migrazione
|
uv run alembic -c src/backend/migrations/alembic.ini downgrade -1 # Rollback ultima
|
||||||
alembic -c migrations/alembic.ini downgrade -1 # Rollback ultima
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Via Docker:
|
Via Docker:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec server alembic -c migrations/alembic.ini upgrade head
|
docker compose exec server uv run alembic -c src/backend/migrations/alembic.ini upgrade head
|
||||||
```
|
```
|
||||||
|
|
||||||
### i18n (Traduzioni)
|
### i18n (Traduzioni)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd client
|
cd src/frontend/flask_app
|
||||||
pybabel extract -F babel.cfg -k _ -o translations/messages.pot . # Estrai stringhe
|
uv run --project ../../.. pybabel extract -F babel.cfg -k _ -o translations/messages.pot . # Estrai
|
||||||
pybabel update -i translations/messages.pot -d translations # Aggiorna catalogo
|
uv run --project ../../.. pybabel update -i translations/messages.pot -d translations # Aggiorna
|
||||||
pybabel compile -d translations # Compila .po → .mo
|
uv run --project ../../.. pybabel compile -d translations # Compila .po → .mo
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gestione dipendenze (uv)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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
|
## Testing
|
||||||
|
|
||||||
Il server usa SQLite in-memory tramite `aiosqlite`: i test girano senza MySQL installato.
|
Il backend usa SQLite in-memory tramite `aiosqlite`: i test girano senza MySQL installato.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Server
|
# Tutti i test (backend + frontend)
|
||||||
cd server && pytest # Tutti i test
|
uv run pytest
|
||||||
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
|
# Solo backend
|
||||||
cd client && pytest
|
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
|
## Variabili d'Ambiente
|
||||||
@@ -304,8 +357,11 @@ Copia `.env.example` in `.env` e configura:
|
|||||||
| `SERVER_CORS_ORIGINS` | Origini CORS ammesse |
|
| `SERVER_CORS_ORIGINS` | Origini CORS ammesse |
|
||||||
| `CLIENT_SECRET_KEY` | Chiave segreta Flask (sessioni, CSRF) |
|
| `CLIENT_SECRET_KEY` | Chiave segreta Flask (sessioni, CSRF) |
|
||||||
| `API_SERVER_URL` | URL del backend visto dal client (es. `http://server:8000`) |
|
| `API_SERVER_URL` | URL del backend visto dal client (es. `http://server:8000`) |
|
||||||
| `UPLOAD_DIR` | Percorso upload file (default: `uploads`, relativo a `server/`) |
|
| `STATION_CODE` | **Per-tablet** — codice stazione (es. `ST-001`). Senza, il client mostra errore configurazione. |
|
||||||
| `MAX_UPLOAD_SIZE_MB` | Limite dimensione upload |
|
| `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) |
|
| `NGINX_PORT`, `NGINX_SSL_PORT` | Porte Nginx (solo compose dev) |
|
||||||
| `SETUP_PASSWORD` | Password pagina setup (vuota = endpoint disabilitato) |
|
| `SETUP_PASSWORD` | Password pagina setup (vuota = endpoint disabilitato) |
|
||||||
| `SSL_CERTFILE`, `SSL_KEYFILE` | Certificato SSL (solo setup manuale) |
|
| `SSL_CERTFILE`, `SSL_KEYFILE` | Certificato SSL (solo setup manuale) |
|
||||||
@@ -314,16 +370,35 @@ Copia `.env.example` in `.env` e configura:
|
|||||||
|
|
||||||
## Documentazione
|
## Documentazione
|
||||||
|
|
||||||
|
Indice completo: [`docs/README.md`](docs/README.md).
|
||||||
|
|
||||||
|
### Stato e direzione
|
||||||
|
|
||||||
| Documento | Contenuto |
|
| Documento | Contenuto |
|
||||||
|---|---|
|
|---|---|
|
||||||
| [docs/API.md](docs/API.md) | Riferimento completo API REST (endpoint, parametri, schemi) |
|
| [`docs/architecture/STATO_PROGETTO.md`](docs/architecture/STATO_PROGETTO.md) | Snapshot V2.0.0: cosa funziona oggi, test status, decisioni architetturali |
|
||||||
| [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) | Guida deployment VPS: Docker, Traefik, SSL, DNS, firewall |
|
| [`docs/architecture/ROADMAP.md`](docs/architecture/ROADMAP.md) | Cosa resta da fare (Fasi 2-7 rev04, decisioni cliente aperte, stime) |
|
||||||
| [docs/USER_GUIDE.md](docs/USER_GUIDE.md) | Manuale utente per ruolo (Maker, MeasurementTec, Metrologist) |
|
|
||||||
|
### Riferimenti operativi
|
||||||
|
|
||||||
|
| Documento | Contenuto |
|
||||||
|
|---|---|
|
||||||
|
| [`docs/API.md`](docs/API.md) | Riferimento completo API REST (endpoint, parametri, schemi) |
|
||||||
|
| [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) | Guida deployment VPS: Docker, Traefik, SSL, DNS, firewall |
|
||||||
|
| [`docs/USER_GUIDE.md`](docs/USER_GUIDE.md) | Manuale utente per ruolo (Maker, MeasurementTec, Metrologist) |
|
||||||
|
| [`docs/I18N_SETUP.md`](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`](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`](docs/superpowers/plans/2026-04-17-rev04-phase1-stations.md) | Piano TDD Fase 1 stazioni (completato) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Licenza
|
## Licenza
|
||||||
|
|
||||||
Proprietary - Tielogic. All rights reserved.
|
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.
|
Questo software è di proprietà esclusiva di Tielogic ed è protetto dalle leggi sul copyright. Non è consentita la distribuzione, modifica o utilizzo senza autorizzazione scritta.
|
||||||
|
|||||||
Reference in New Issue
Block a user