Files
TieMeasureFlow/docs/architecture/STATO_PROGETTO.md
T
Adriano Dal Pastro 2101b9b2c9 docs: porta stato e roadmap ai fatti del 28/07
Erano fermi allo snapshot V2.0.0 di fine aprile: parlavano di Fasi rev04 da
iniziare, di quattro test rotti e di uno stack che scaricava le librerie da CDN.
Niente di tutto questo è più vero, e un documento di stato sbagliato è peggio di
un documento di stato assente — qualcuno ci si fida.

STATO_PROGETTO: i quindici punti con il loro stato e dove vivono nel codice, cosa
è entrato in V3.0.0 raggruppato per tema, le dieci migrazioni, la suite a 360
pass. In fondo la sezione che conta di più, «cosa non è stato provato»: tredici
punti sono in esercizio e nessuno li ha percorsi su un tablet, il punto 14 non è
mai stato riprodotto su un dispositivo, il punto 12 non è mai stato provato a rete
staccata. Serve a non confondere «i test passano» con «funziona in reparto».

ROADMAP: riscritta intorno a quello che resta e in che ordine — il collaudo prima
di tutto, perché è l'unico lavoro che non aspetta risposte da nessuno, con la
tabella di cosa guardare e come si vede che è giusto. Poi il punto 4 (due o tre
giorni, a decisioni chiuse), l'innesto GAIA e l'installazione di settembre.

Le decisioni aperte sono ora le D-1…D-9 del documento del 28/07, non più le
D-0.x di aprile: la corrispondenza è scritta, così chi torna sui vecchi documenti
non si perde. Stessa cosa per le sette Fasi rev04, con dove è finita ciascuna:
due assorbite, una sostituita, una ridimensionata dal fatto che una rete isolata
rende l'aggiornamento automatico privo di senso.

Lo snapshot V2.0.0 è conservato in docs/archive/ invece di essere sovrascritto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 22:03:40 +00:00

10 KiB
Raw Blame History

Stato Progetto TieMeasureFlow — V3.0.0

Snapshot al 2026-07-28. Aggiornare ad ogni milestone. Lo snapshot V2.0.0 è in ../archive/STATO_PROGETTO_V2.0.0_2026-04-27.md.

Versione corrente

V3.0.0 (in sviluppo, branch V3.0.0). Versione precedente: V2.0.0.

In esercizio su tieflow.tielogic.xyz (Docker Compose + Traefik + Let's Encrypt), schema alla migrazione 010_meas_authorisation.

Sintesi esecutiva

V2.0.0 aveva chiuso stazioni per-tablet, ristrutturazione monorepo con uv e la tenuta multi-tablet. V3.0.0 nasce dal sopralluogo del 28/07 e lavora sui quindici punti raccolti in TieMeasureFlow_modifiche_2026-07-28.md.

Il filo che li tiene insieme: fino a V2.0.0 il sistema registrava misure ma non governava la produzione. Le regole vivevano nell'interfaccia — una modale che si poteva chiudere, un timer che moriva al cambio pagina, un tipo di task dedotto dalla presenza di quote. V3.0.0 le sposta sul server, dove non si aggirano.

Tredici punti su quindici sono fatti e in esercizio. Uno è fermo sulle risposte del cliente, uno è fuori offerta.

I quindici punti

# Punto Stato Dove vive
1 Memoria della produzione in corso production_runs, production_service
2 Tipo di task esplicito RecipeTask.task_type, migrazione 007
3 Loop di misura e ripetizione production-clock.js, production_service, migrazione 008
4 Limite di tentativi prima del capoturno Fermo su D-6, D-7, D-9
5 Avanzamento solo se in tolleranza measurement_service.pending_authorisation, migrazione 010
6 Fermo linea e Fine produzione con effetto production_service, production_export_service
7 Gestione delle stazioni station_service, /admin/stations
8 Tracciabilità obbligatoria Recipe.requires_lot/serial, migrazione 009
9 Blocco dell'inserimento manuale Recipe.allow_manual_input, numpad.js
10 Interfaccia operatore: sequenza e conferme /measure/start, task-progress, task_list, task_execute
11 Formattazione delle descrizioni filtro rich_text, rich-text.js
12 Funzionamento senza internet static/vendor/, CSP in app.py
13 Generazione task dalla scheda tecnica con l'AI Fuori offerta
14 Stabilità del layout .tmf-page in themes.css, LAYOUT.md
15 Statistica separata dalla registrazione @role_required("Metrologist"), test dedicato

Cosa è entrato in V3.0.0

Produzione come stato, non come pulsante (punti 1, 6)

  • Tabelle production_runs e production_events; una produzione si apre su una stazione, accumula eventi (start, cycle_completed, task_measured, remeasure, line_stop, resume, close) e si chiude.
  • Fermo linea, ripresa e fine produzione richiedono le credenziali del capoturno e cambiano lo stato: prima erano modali che si chiudevano.
  • La fine produzione emette il file di statistica dell'intera produzione (production_export_service), CSV con i delimitatori configurati, marcando le misure come esportate. Il punto d'innesto verso GAIA è lì accanto, in attesa di D-1 e D-2.

Il ciclo di misura (punto 3)

  • L'intervallo della ricetta è calcolato dal server (seconds_to_next_measurement, overdue, server_time): sopravvive al cambio task, che è un ricaricamento di pagina, e non si azzera cambiando schermata.
  • Il conteggio prosegue oltre lo zero: il ritardo si vede, in rosso.
  • A scadenza l'operatore viene riportato al primo task di misura della ricetta, con cinque secondi di preavviso; chi sta già misurando viene lasciato finire.
  • Cicalino via WebAudio, nessun file audio da caricare.
  • remeasure distingue una seconda lettura dello stesso pezzo da un ciclo nuovo: girare il pezzo e rimisurare non deve far ripartire l'intervallo.

Le regole della ricetta (punti 8, 9)

  • requires_lot, requires_serial, allow_manual_input per ricetta, verificati in measurement_service: ogni porta d'ingresso passa di lì, barcode compreso.
  • Con allow_manual_input a falso il tastierino non viene disegnato — non nascosto: il markup non esiste — e il server rifiuta comunque un valore digitato a mano.
  • Il rilevamento del calibro USB è stato reso più tollerante (Enter veloce), perché con la regola stretta una lettura corta come 9.5 veniva scambiata per digitazione.

Il fuori tolleranza (punto 5)

  • Una quota fuori tolleranza e non autorizzata blocca il salvataggio della quota successiva e la chiusura del ciclo (409).
  • Conta l'ultima lettura di ogni quota: rimisurare la stessa quota resta possibile — il calibro scivola, il pezzo si riposiziona — e una lettura dentro i limiti scioglie il blocco senza chiamare nessuno.
  • L'autorizzazione del capoturno resta scritta sulla misura (supervisor_id, authorised_at) e finisce in due colonne del CSV di produzione: il file mostra il guasto e la decisione.
  • Quanti tentativi siano ammessi è il punto 4, non questo.

L'interfaccia dell'operatore (punti 10, 11, 14, 15)

  • La ricetta si apre sul primo task (/measure/start/<id>), non su un elenco. La lista scende a secondo livello e mostra quali task sono rimasti incompiuti (GET /api/measurements/task-progress, contato per quota e non per tentativo).
  • «Fine ciclo misura» è visibile da subito e spento finché mancano quote, con scritto quante ne mancano.
  • Descrizioni con **grassetto** e a capo: marcatura, non HTML, così la sanificazione è per costruzione.
  • Una cornice sola per tutte le viste, allineata alla navbar — vedi LAYOUT.md.
  • Nessun percorso dell'operatore porta alla statistica, ed è un test.

Fuori dalla rete (punto 12)

  • Alpine, Plotly, PDF.js (+ worker), Fabric e i font sono nell'installazione, con versione nel nome e impronta SHA-256 verificata da un test.
  • Content-Security-Policy a sola origine locale servita dal client Flask: prima esisteva solo sul backend, cioè sulle risposte API e non sulle pagine.
  • Tailwind fissato a 3.4.19 nel Dockerfile.frontend.

Migrazioni

# Contenuto
001004 image_path, stazioni, intervallo di misura + auto-logout, input_duration_ms
005006 production_runs, misure legate alla produzione
007 task_type dichiarato
008 tipi di evento del ciclo + task_id sull'evento
009 requires_lot, requires_serial, allow_manual_input
010 supervisor_id, authorised_at sulla misura

Le 008 e 010 usano il batch mode per compatibilità SQLite (i test) e sono state verificate anche in resa MySQL (alembic upgrade X:Y --sql) prima del deploy.

La 009 imposta allow_manual_input = 1 sulle ricette esistenti: conserva il comportamento in essere invece di irrigidire di colpo ricette già in uso. È una scelta, e va confermata dal cliente ricetta per ricetta.

Test status

Test Fail
Backend (src/backend/tests/) 212 0
Frontend (src/frontend/flask_app/tests/) 148 0
Totale 360 0

I quattro fallimenti pre-esistenti tracciati nello snapshot V2.0.0 non ci sono più.

Tre file di test non renderizzano niente e leggono i sorgenti, perché guardano proprietà che sopravvivono solo se qualcuno le controlla:

File Cosa impedisce
test_offline.py Una libreria caricata dalla rete, un worker PDF.js lasciato sul CDN, una libreria sostituita senza aggiornare l'impronta
test_layout_shell.py Una vista che torna a dichiararsi la propria larghezza
test_template_js_syntax.py Una traduzione con l'apostrofo dentro una stringa JS a virgolette singole, che spegne Alpine su tutta la pagina

Cosa non è stato provato

Va detto perché non si confonda «i test passano» con «funziona in reparto».

  • Il collaudo sul campo non è mai stato percorso. Le ricette COLLAUDO-A e COLLAUDO-B sono state seminate sul sistema in esercizio (scripts/seed_collaudo.py) insieme a un utente capoturno, ma nessuno ha ancora guidato il flusso su un tablet vero.
  • Il punto 14 non è stato riprodotto su un dispositivo: è dimostrato che il layout poteva muoversi per quattro motivi e che ora non può più, non che l'operatore vedesse esattamente quelli.
  • Il punto 12 non è stato provato a rete staccata. È dimostrato che nessuna risorsa esterna viene richiesta. Il giro con la rete staccata va fatto, ed è ora il momento giusto perché la CSP è appena entrata in vigore.
  • Il cicalino è il suono del browser. Se serva una colonnina luminosa è D-5.

Stack

  • Backend: FastAPI + SQLAlchemy 2.0 async + MySQL 8 + Alembic + Pydantic v2 + WeasyPrint + Plotly/Kaleido. 12 router.
  • Frontend: Flask + Jinja2 + Alpine.js 3.15.12 + TailwindCSS 3.4.19 + Fabric.js 5.3.1 + PDF.js 3.11.174 + Plotly.js 2.32.0 + Flask-Babel — tutte copie locali, nessun CDN.
  • Deploy: Docker Compose. Dev = Nginx; Prod = Traefik + Let's Encrypt.
  • Tooling: uv, pytest + pytest-asyncio + httpx + aiosqlite.

Decisioni architetturali rilevanti

Decisione Stato Note
Le regole di misura stanno sul server, non sullo schermo Confermata (V3.0.0) Tracciabilità, inserimento manuale, fuori tolleranza: la schermata può nasconderle, il server le rifiuta.
Una app di stazione per PC, dati sul server Decisa il 28/07 (D-3) Validazione con l'IT di Tràfilo aperta come D-4.
Descrizioni in marcatura, non in HTML Confermata Niente HTML accettato in ingresso: la sanificazione è per costruzione, non per filtro.
Frontend Flask invece di React (deroga vs spec §8) Confermata Tablet UX server-side, calibri USB, editor Fabric.js, i18n Babel collaudato.
NATS messaging (spec §7) Skippato Monorepo single-host, nessun microservizio.
Envelope risposta {success,data,error} (spec §6) Rimandato Costo alto, rotture client. Eventuale API v2.
Header X-API-Key vs spec X-Api-Key Mantenuto attuale Rinominare è breaking per i deploy esistenti.

Branch git

  • Corrente: V3.0.0
  • Precedenti: V2.0.0, V1.0.0V1.0.7 (release storiche)