Files
TieMeasureFlow/TieMeasureFlow_modifiche_2026-07-28.md
Adriano Dal Pastro e7889f80a3 docs: aggiungi il documento delle modifiche del 28/07/2026
Elenco dei 15 punti concordati con Trafilo, con lo stato verificato sul codice al
commit 2a56632, l'architettura d'installazione decisa il 28/07 e le nove domande
la cui risposta dipende dal cliente. E' il riferimento del lavoro su V3.0.0.

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

29 KiB

TieMeasureFlow — modifiche da apportare

Data: 28 luglio 2026 (agg. serale: architettura d'installazione, punti 7-8 precisati, punti 14-15 nuovi, timer bidirezionale nel punto 3) Riferimento codice: branch V2.0.0, commit 2a56632 Destinatari: Parte 1 leggibile da cliente e rivenditore · Parte 2 per chi mette mano al codice


Come leggere questo documento

La Parte 1 dice cosa deve fare il sistema e perché: si può mandare a Ricerca e Misure e a Tràfilo. La Parte 2 dice dove si interviene, con file e criteri di completamento. La Parte 3 elenca le domande la cui risposta non dipende da noi.

Ogni punto porta lo stato verificato sul codice, non riferito: già fatto, parziale, da fare. Serve a evitare l'equivoco emerso in questi giorni — diverse funzioni risultano "già implementate" perché l'interfaccia c'è, ma dietro non succede nulla.

Fonti: specifica Schema sviluppo SW TieFlow rev. 04-2026; MODIFICHE TIEMEASURE v260519; call del 28/07/2026; rettifica di Marco Menoncin del 28/07; lettura diretta del codice.


Il punto che regge tutti gli altri

Lo stato della produzione oggi vive dentro una pagina del browser.

Il timer, il conteggio dei cicli, il flag "produzione avviata" e le misure in corso sono variabili del componente Alpine di task_execute.html. La navigazione fra un task e l'altro è un ricaricamento completo di pagina (window.location.href).

Conseguenza diretta: cambiando task si perde tutto. Il timer smette di esistere, il conteggio dei cicli riparte, "produzione avviata" si dimentica.

Questo spiega, senza bisogno di altre ipotesi:

  • perché il loop di misura non regge quando la ricetta ha altri task dopo la misura;
  • perché con più task di misura non si sa a quale tornare allo scadere del timer;
  • perché fermo linea e fine produzione non hanno nulla da fermare o da chiudere;
  • perché non esiste storico di cosa è successo durante una produzione.

Va risolto per primo: i punti 2, 3, 6 e 8 dipendono da questa scelta, e affrontarli prima significa rifarli dopo.


Architettura d'installazione (decisa il 28/07)

Chiude la domanda D-3 lato Tielogic. L'installazione a Tràfilo è così composta:

SERVER (uno, del cliente)          STAZIONE (una per PC, installata in locale)
┌─────────────────────────┐        ┌──────────────────────────────────────┐
│ MySQL                   │◄──API──│ App di stazione:                     │
│ Backend dati (API)      │        │  · interfaccia operatore (frontend)  │
│ File dei disegni        │        │  · agente hardware: calibro USB,     │
│ Migrazioni dello schema │        │    driver camera, colonnina/cicalino │
│ Adattatore GAIA         │        │  · elaborazione visione (futura:     │
└─────────────────────────┘        │    XF compare, pattern matching)     │
                                   └──────────────────────────────────────┘
  • Sul server vive tutto ciò che è stato: il database, i file dei disegni, le migrazioni dello schema e l'unico punto di contatto col gestionale GAIA. Aggiornare la logica dati = un deploy, in un posto solo.
  • Sulla stazione vive tutto ciò che tocca l'hardware: calibro, telecamera, segnalazione luminosa/acustica, e in prospettiva l'elaborazione visione — che così non carica il server (rilevante per il dimensionamento, D-4). L'app di stazione è senza stato: non tocca il database direttamente, parla col backend dati via API e gli manda risultati e immagini.
  • L'identità della stazione è data dall'installazione (configurata sul PC), non più dal container sul server: il vincolo "una stazione = un container" decade.
  • La licenza per postazione ha l'aggancio naturale nell'app di stazione installata.

Correzione a quanto detto in call: i disegni non stanno nel database — stanno su filesystem (uploads/), serviti dal backend. Con questa architettura restano sul server, in un posto solo: nessuna cartella da sincronizzare fra i PC.

Conseguenza per lo sviluppo: lo stato della produzione (punto 1) va nel database per obbligo architetturale, non per scelta — con 20 app di stazione non esiste altro posto dove possa vivere.


Parte 1 — Cosa deve fare il sistema

Quadro: cosa già funziona

Da mettere a verbale, perché in parte era dato per mancante:

Funzione Stato
Stazioni e assegnazione ricette alle stazioni presente
Ruolo capoturno con autorizzazione a login presente
Timer d'intervallo misura con conto alla rovescia a video e cicalino presente
Logout automatico per inattività, configurabile presente
Tolleranze con soglie di attenzione (UTL/UWL/LWL/LTL) ed esito per quota presente
Versionamento delle ricette con storico delle modifiche presente
Registrazione del tempo di inserimento di ogni misura presente (28/07)
Pulsanti Fermo linea, Fine produzione, Avvio produzione ⚠️ solo interfaccia

L'ultima riga è la più importante: i tre pulsanti esistono, chiedono correttamente l'autorizzazione del capoturno, e poi non fanno nulla.


1. Memoria della produzione in corso da fare · prerequisito

Oggi: lo stato di una produzione esiste solo finché l'operatore resta sulla stessa schermata.

Deve: la produzione diventa un'entità con una vita propria — si apre quando parte, registra ciò che accade (avvio, cicli di misura, fermo linea, ripresa, chiusura) e si chiude quando il capoturno la chiude. Se l'operatore cambia task, esce e rientra, o il tablet si riavvia, la produzione è ancora lì con il suo timer.

Perché conta: senza questo, fermo linea e fine produzione non possono funzionare, il loop di misura non è realizzabile e non esiste il dato storico su cui poggiano sia la statistica sia l'integrazione col gestionale.


2. Tipo di task esplicito da fare

Oggi: il sistema distingue un task di misura da un task documentale deducendolo: se ha delle quote è una misura, altrimenti è una nota. Non esiste un tipo dichiarato.

Deve: ogni task nasce con un tipo scelto da chi crea la ricetta — nota, misura, disegno — predisposto per i tipi futuri (confronto profilo/DXF, misura con camera).

Perché conta: è la richiesta n. 1 di Menoncin, ed è ciò a cui si agganciano timer e loop. Con la deduzione attuale un task di misura a cui non sono ancora state inserite le quote viene trattato come una nota: il sistema si comporta in modo diverso a seconda di quanto è completa la ricetta.


3. Loop di misura e ripetizione parziale

Oggi: allo scadere del timer suona il cicalino e il ciclo si riazzera — ma solo se l'operatore è rimasto su quella schermata.

Deve:

  • l'operatore esegue i task in sequenza fino al primo task di misura;
  • da lì resta in loop sulla misura finché la produzione non viene chiusa;
  • il conto alla rovescia di quanto manca alla prossima misura è sempre visibile;
  • arrivato a zero, il contatore riparte nell'altro senso: mostra da quanto tempo si è oltre l'intervallo di misura, in evidenza — così il ritardo si vede, non si deduce (richiesta dell'operatore, 28/07);
  • allo scadere del timer la misura si ripropone ovunque si trovi l'operatore;
  • se la ricetta ha più task di misura, il timer riparte alla fine dell'ultimo;
  • dev'essere possibile girare il pezzo e rimisurare senza chiudere il ciclo.

Perché conta: è la seconda richiesta di Menoncin e il comportamento descritto al punto 4.10 della specifica del 19/05. La logica c'è già in gran parte: manca che sopravviva al cambio di schermata (punto 1).


4. Limite di tentativi prima del capoturno da fare

Oggi: l'operatore può ripetere la misura quante volte vuole.

Deve: dopo un numero di tentativi definito nella ricetta, per proseguire serve l'autorizzazione del capoturno.

Perché conta: è nella specifica ed è la contromisura al caso in cui si ripete finché non "viene bene". Il meccanismo di autorizzazione esiste già: manca il contatore e la soglia.


5. Avanzamento solo se in tolleranza da verificare

Deve: si passa alla quota successiva in autonomia solo se la quota è in tolleranza; per confermare una quota fuori tolleranza serve il capoturno.

Nota: il gate del capoturno per il fuori tolleranza è implementato. Va verificato sul campo che blocchi davvero l'avanzamento e non sia solo una richiesta di conferma. Se blocca, il punto si chiude senza sviluppo.


6. Fermo linea e Fine produzione: dare effetto parziale

Oggi: entrambi chiedono l'autorizzazione del capoturno, poi non succede niente.

Deve:

  • Fermo linea — sospende il timer e la produzione; il capoturno può riattivarla;
  • Fine produzione — chiude la produzione, ferma il timer definitivamente e invia i dati di misura dell'intera produzione al file di statistica.

Perché conta: il comportamento verso il gestionale è ancora da definire (Parte 3), ma tutto ciò che sta prima del gestionale si può e si deve fare adesso: sospendere, riprendere, chiudere, registrare. Consegnare i pulsanti funzionanti senza il gestionale è possibile; il contrario no.


7. Gestione delle stazioni parziale

Deve:

  • la lista stazioni mostra, oltre a codice e postazione, le ricette collegate;
  • esiste un reset della stazione, con un pulsante per riga nella lista: la stazione torna senza ricette associate e si riassegna (precisazione dell'operatore, 28/07);
  • la stazione corrente si può cambiare al volo, per poter provare più stazioni da un solo computer senza riconfigurare l'installazione.

Perché conta: è la terza richiesta di Menoncin. Il cambio al volo non è un vezzo da sviluppatori: senza, la sessione di collaudo con Menoncin richiede tanti PC quante sono le stazioni da provare.


8. Tracciabilità obbligatoria parziale

Oggi: numero di lotto e numero seriale sono facoltativi e si inseriscono nella lista task, cioè dopo aver iniziato.

Deve: l'obbligatorietà di lotto e seriale si decide alla creazione della ricetta (obbligatori sì/no); l'operatore li inserisce alla selezione della ricetta, e finché mancano il pulsante Avvia non si attiva (precisazione dell'operatore, 28/07).

Perché conta: una misura senza lotto non è tracciabile a posteriori, e la tracciabilità è metà del valore del sistema in un audit.


9. Blocco dell'inserimento manuale da fare

Oggi: il sistema registra come è stata inserita una misura (calibro o tastiera), ma accetta sempre entrambi.

Deve: un'impostazione della ricetta consente o vieta l'inserimento manuale, con divieto come impostazione predefinita: si misura col calibro.

Perché conta: è il punto sollevato in call — senza questo vincolo un valore in tolleranza si può digitare. Il dato su come è stata inserita c'è già: manca la regola che lo impedisce.


10. Interfaccia operatore: sequenza e conferme da fare

Richieste del 19/05, tutte di interfaccia:

  • un pulsante che avvia i task in sequenza, senza sceglierli a uno a uno;
  • la lista completa dei task retrocessa a secondo livello, per tornare a vedere i task precedenti;
  • «inizia misure» rinominato «visualizza singolo TASK»;
  • dentro il task, «Riepilogo» sostituito da «Completato» per passare al successivo;
  • un task lasciato a metà resta incompiuto e si vede;
  • «fine ciclo misura» cliccabile solo quando tutte le quote hanno un valore.

11. Formattazione delle descrizioni da fare

Deve: le descrizioni dei task accettano andate a capo e grassetto.

Perché conta: chi crea le ricette fa copia e incolla dal PDF della scheda tecnica; oggi il testo arriva appiattito e va risistemato a mano ogni volta.


12. Funzionamento senza internet da fare · bloccante per l'installazione

Oggi: l'applicazione non funziona senza collegamento a internet. Cinque librerie vengono scaricate al volo da servizi esterni ogni volta che si apre una pagina.

In una rete di produzione isolata — la norma in fabbrica — il risultato è una pagina bianca. Non un degrado: l'interfaccia non parte proprio, e senza le altre non si vedono i disegni tecnici né i grafici statistici.

Deve: tutte le librerie sono incluse nell'installazione e l'applicazione funziona a rete staccata.

Perché conta ora: l'installazione a Tràfilo è on-premise e prevista per settembre. È poco lavoro, ma va fatto prima, non in fabbrica il giorno dell'installazione.

Beneficio collaterale non ovvio: oggi una delle librerie è agganciata a una versione "qualunque della serie 3" — cioè l'applicazione cambia da sola quando gli autori pubblicano un aggiornamento, senza che nessuno l'abbia validata. Per un sistema che produce evidenze per audit ISO 9001 / IATF 16949 questo è di per sé un problema. Includendo le librerie le versioni si congelano: da difetto diventa argomento di vendita.


13. Generazione dei task dalla scheda tecnica con l'AI fuori offerta

Richiesta: leggere il PDF della scheda tecnica e creare un task per blocco, invece del copia-incolla manuale.

Storia: posta il 19/05/2026 nel documento delle modifiche, rimasta senza risposta; rilanciata da Tràfilo il 28/07 come elaborazione massiva iniziale delle schede, «senza installare agenti nel sistema».

Stato: non è in nessuna offerta. Prima di quotare servono tre informazioni: quante sono le schede, se il formato è standard, e se l'elaborazione è una-tantum in fase di avviamento o una funzione permanente del prodotto. Sono domande da fare, non da supporre — vedi Parte 3.


14. Stabilità del layout da fare · da circoscrivere

Oggi: le dimensioni delle viste cambiano a seconda del menu: passando da una schermata all'altra la finestra non mantiene proporzioni stabili.

Deve: il layout resta stabile nel passaggio fra le viste.

Nota: segnalazione dell'operatore del 28/07, non ancora circoscritta sul codice — prima di intervenire va riprodotta e va stilato l'elenco delle viste interessate.


15. Statistica: si registra sempre, si consulta a parte già fatto · da confermare sul campo

Richiesta (28/07): a fine misura l'operatore non va portato nella pagina della statistica. I dati entrano comunque in statistica: cambia solo chi la consulta — serve l'utente con il ruolo adeguato, che apre la pagina dedicata.

Verificato sul codice: è già così. Tutte le pagine di statistica richiedono il ruolo Metrologo (role_required("Metrologist") su ogni route), e a fine ciclo l'operatore viene portato al riepilogo, non alla statistica.

Resta da fare: niente sviluppo; il requisito entra come criterio di collaudo (l'operatore non deve poter raggiungere la statistica da nessun percorso) e va tenuto fermo quando il punto 10 ridisegna la navigazione a fine task.


Parte 2 — Dove si interviene

Riferimenti al branch V2.0.0, commit 2a56632.

Ordine consigliato

12 (offline)  ──────────────►  indipendente, si può fare subito
                               bloccante per l'installazione

 1 (stato produzione)  ──┬───►   3 (loop misura)
                         ├───►   6 (fermo linea / fine produzione)
                         └───►   4 (limite tentativi)

 2 (tipo task)  ─────────────►   3, 10

 7 (stazioni) · 8 (tracciabilità) · 9 (inserimento manuale) · 11 (formattazione)
   indipendenti fra loro

 5 (avanzamento in tolleranza)  ──►  prima verificare, forse è già a posto

14 (layout)  ────────────────►  prima riprodurre e circoscrivere le viste

15 (statistica riservata)  ──►  già a posto: solo criterio di collaudo,
                                da non rompere lavorando sul punto 10

La separazione backend dati sul server / app di stazione in locale (vedi Architettura d'installazione) non è un punto di questa lista: è il contesto in cui i punti 1, 3, 6 e 7 vanno progettati. In pratica: API senza stato, stato solo nel database, niente dipendenze dal container per l'identità della stazione.

1 · Stato della produzione lato server

Problema tecnico: task_execute.html tiene in variabili Alpine (timerActive, timerRemaining, _timerInterval, cycleCount, cycleConfirmed, productionStarted, measurements) uno stato che deve sopravvivere alla pagina. goToNextTask() fa window.location.href → il componente viene distrutto. Lato server la sessione conserva soltanto lot_number e serial_number.

Intervento:

  • nuove tabelle production_runs e production_events (avvio, ciclo completato, fermo linea, ripresa, chiusura), con station_id, recipe_version_id, operator_id, supervisor_id dove serve, timestamp;
  • endpoint REST per aprire, interrogare e aggiornare la produzione corrente della stazione;
  • il frontend legge lo stato all'apertura di ogni pagina invece di tenerlo in memoria; il conto alla rovescia si ricalcola dall'orario di scadenza salvato lato server, non da un contatore locale;
  • gli endpoint vanno progettati senza stato in memoria di processo: con l'app di stazione installata su ogni PC (vedi Architettura d'installazione) il database è l'unico posto condiviso.

File: src/backend/models/orm/ (nuovo modulo), src/backend/migrations/versions/ (migrazione 005), src/backend/api/routers/, src/frontend/flask_app/blueprints/measure.py, src/frontend/flask_app/templates/measure/task_execute.html.

Fatto quando: avviata una produzione, si naviga fra i task, si esce e si rientra, e il timer prosegue coerente; il riavvio del browser non azzera nulla.


2 · Tipo di task

Problema tecnico: RecipeTask non ha campo tipo; il frontend decide con subtasks.length > 0 (task_execute.html, task_list.html).

Intervento: campo type su recipe_tasks con valori note | measure | drawing (predisposto per xf_compare, camera_measure), migrazione con valorizzazione dei dati esistenti secondo la regola attuale, selezione del tipo nell'editor ricetta, sostituzione dei controlli su subtasks.length con il tipo.

File: src/backend/models/orm/task.py, nuova migrazione, src/backend/models/api/, src/frontend/flask_app/templates/maker/task_editor.html, templates/measure/task_execute.html, templates/measure/task_list.html.

Fatto quando: una ricetta con un task di misura ancora privo di quote si comporta da task di misura.


3 · Loop di misura

Base già presente: confirmCycle(), startMeasurementTimer(), onTimerExpired(), timerDisplay, playBuzzer() in task_execute.html (righe ~955-1050). La logica è corretta; il problema è la persistenza (punto 1) e il fatto che allo scadere non si può riportare l'operatore sul task giusto.

Intervento: spostare la scadenza sul server; alla scadenza, redirezione al task di misura della produzione corrente; con più task di misura far ripartire il timer al completamento dell'ultimo; aggiungere «rimisura» che riapre il ciclo senza chiuderlo.

Timer bidirezionale: oggi il contatore solo decrementa e si ferma a zero (timerRemaining--, poi onTimerExpired()); timerDisplay formatta minuti:secondi dal residuo. Va esteso: sotto zero il valore continua in negativo e la visualizzazione passa a "oltre da m:s", con stile in evidenza. Calcolando dal timestamp di scadenza lato server (come sopra), il ritardo è coerente su qualunque schermata e sopravvive al ricaricamento.

Fatto quando: con una ricetta a due task di misura e task documentali in coda, allo scadere del timer l'operatore viene riportato alla misura da qualunque schermata.


4 · Limite di tentativi

Problema tecnico: nessun max_retries nel codice.

Intervento: campo sulla ricetta (accanto a measurement_interval_minutes, che segue lo stesso schema), contatore per quota nella produzione corrente, superata la soglia riuso del modale capoturno esistente con motivo max_retries.

File: src/backend/models/orm/recipe.py, migrazione, templates/maker/recipe_editor.html (accanto al timer), task_execute.html.


5 · Avanzamento in tolleranza — prima verificare

Il modale capoturno gestisce già out_of_tolerance (task_execute.html, openSupervisorModal, validateSupervisor, endpoint measure.validate_supervisor). Prima di sviluppare, provare: se il rifiuto blocca l'avanzamento, il punto è chiuso. Se è solo una conferma, va reso vincolante.


6 · Fermo linea e Fine produzione

Problema tecnico: in task_execute.html i due pulsanti aprono il modale e poi ricadono su un commento: fermo_linea and fine_produzione are handled by GAIA integration (future). startProduction() è un TODO con la chiamata commentata.

Intervento (senza gestionale): scrivere gli eventi su production_events, sospendere e riprendere il timer, chiudere la produzione, ed emettere il file di statistica con tutte le misure della produzione. L'invio al gestionale resta un adattatore separato da riempire quando il protocollo sarà definito (Parte 3): va previsto il punto d'innesto, non l'implementazione.

Fatto quando: fermo linea congela il timer e solo il capoturno lo riattiva; fine produzione chiude e produce il file.


7 · Stazioni

Base presente: Station e StationRecipeAssignment (models/orm/station.py, migrazione 002).

Intervento: ricette collegate nella lista stazioni; pulsante di reset per riga che rimuove le assegnazioni; selezione della stazione corrente da parametro URL con ricaduta sulla variabile d'ambiente, per il collaudo da una sola macchina.

Nota (28/07, chiude il dubbio che era in D-3): in produzione l'identità della stazione è data dall'installazione locale dell'app di stazione, non dal container. Il cambio al volo via URL resta come strumento di collaudo.


8 · Tracciabilità

Base presente: lot_number e serial_number su Measurement, salvataggio in sessione (measure.save_traceability), inserimento in task_list.html.

Intervento: flag sulla ricetta (richiede lotto, richiede seriale); spostare l'inserimento sull'avvio produzione; Avvia disabilitato finché mancano.


9 · Inserimento manuale

Base presente: Measurement.input_method (manual | usb_caliper), valorizzato dal frontend.

Intervento: flag sulla ricetta consente inserimento manuale, predefinito falso; validazione lato server — un flag solo nel frontend non protegge da nulla; tastierino nascosto quando vietato.


10 · Interfaccia operatore

Interventi su templates/measure/task_list.html e task_execute.html: pulsante di avvio in sequenza, retrocessione della lista a secondo livello, rinomina dei due pulsanti, stato «incompiuto» sui task abbandonati, «fine ciclo misura» abilitato solo a quote complete.


11 · Formattazione descrizioni

RecipeTask.description è già Text. Serve un editor minimale (grassetto e a capo) e la resa corrispondente in esecuzione, con sanificazione dell'HTML in ingresso.

File: templates/maker/task_editor.html, templates/measure/task_execute.html.


12 · Funzionamento senza internet

Verificato sul codice. Cinque librerie esterne in sei template:

Libreria Dove Senza rete si perde
Alpine.js 3.x.x base.html tutta l'interfaccia
Plotly 2.32.0 statistics/dashboard.html carte di controllo e istogrammi
PDF.js 3.11.174 task_execute, recipe_preview, task_drawing, task_editor visualizzazione dei disegni
Fabric.js 5.3.1 maker/task_drawing.html editor delle annotazioni
Google Fonts base.html estetica e attese al caricamento

Intervento: scaricare le librerie in src/frontend/flask_app/static/vendor/ (la cartella esiste già ed è vuota), ripuntare i tag, chiudere la policy di sicurezza in security_headers.py da elenco-di-CDN a solo-origine-locale.

⚠️ Trappola da non mancare: PDF.js ha una seconda referenza al CDN, pdfjsLib.GlobalWorkerOptions.workerSrc, presente in quattro file. Ripuntando solo lo script principale la libreria si carica in locale e il worker continua a cercare internet: sembra funzionare finché non si apre un disegno.

Fatto quando: con la rete staccata si percorre login → scelta ricetta → esecuzione task → annotazione disegno → statistiche → report, senza errori in console.


Parte 3 — Decisioni che non dipendono da noi

Da chiudere prima che i punti collegati entrino in sviluppo. Vanno girate a Tràfilo tramite Menoncin.

# Domanda Blocca Chi risponde
D-1 Protocollo del gestionale GAIA: come si scambiano i dati — servizi web, database condiviso, file? avvio produzione, fermo linea, fine produzione verso il gestionale; lettura dei codici articolo per stazione IT Tràfilo + fornitore GAIA
D-2 Rete e credenziali per raggiungere GAIA dal server dove sarà installato come sopra IT Tràfilo
D-3 Una applicazione per stazione o una sola per tutte? Decisa il 28/07 lato Tielogic: backend dati sul server, app di stazione installata su ogni PC — vedi Architettura d'installazione. Resta la validazione con l'IT di Tràfilo (macchina e rete) chiusa (noi); validazione in D-4
D-4 Server: quale macchina, quanto spazio disco. Sul server stanno database e file dei disegni (uploads/); l'elaborazione visione non è sul server (sta sull'app di stazione), quindi pesa lo spazio disco, non la potenza di calcolo installazione IT Tràfilo
D-5 Cicalino: basta il suono del browser o serve una segnalazione luminosa? La specifica chiede luce e suono accesi per tutta la misura, visibili da lontano. Con l'architettura del 28/07 l'app di stazione può pilotare una colonnina: la domanda diventa quale hardware punto 3 Tràfilo
D-6 Autorizzazione capoturno: username e password come oggi, o PIN rapido / badge? Venti volte al giorno la password è un attrito punti 4, 5, 6 Tràfilo
D-7 Numero di tentativi consentiti prima del capoturno: quanti, e uguali per tutte le ricette? punto 4 Tràfilo
D-8 Schede tecniche: quante sono, il formato è standard, e serve una conversione una-tantum o una funzione permanente? punto 13 e la sua quotazione Tràfilo
D-9 Modificare i parametri di una ricetta (timer, tentativi) crea una nuova versione o no? Sono parametri di esercizio, non di prodotto punti 4, 3 noi, con conferma cliente

Nota su D-1 e D-2: finché non hanno risposta, del gestionale si può solo predisporre il punto d'innesto. Tutto il resto del punto 6 — sospendere, riprendere, chiudere, registrare, produrre il file — si fa comunque e va fatto adesso.


Appendice — Come è stato verificato

Ogni «già fatto» e ogni «da fare» viene dalla lettura del codice al commit 2a56632, non dai documenti. In particolare:

  • il tipo di task è dedotto da subtasks.length > 0 in task_execute.html:117 e task_list.html:169;
  • il ruolo capoturno esiste come Supervisor (api/middleware/api_key.py:71, blueprints/measure.py:350);
  • fermo linea / fine produzione / avvio produzione hanno interfaccia e gate ma nessun effetto (task_execute.html:1017-1021, 1118);
  • il timer è un setInterval locale alla pagina (task_execute.html:968-995) e la navigazione fra task è un ricaricamento (task_execute.html:1054);
  • max_retries e production_events non compaiono in nessun file;
  • le cinque librerie da CDN sono ai riferimenti citati al punto 12, e static/vendor/ contiene solo .gitkeep;
  • i disegni stanno su filesystem, non nel database: cartella uploads/ servita dal backend (api/routers/files.py:201, FileResponse) — verifica del 28/07 sera, corregge quanto detto in call;
  • la statistica è già riservata: ogni route di blueprints/statistics.py porta @role_required("Metrologist"); a fine ciclo il frontend va al riepilogo (task_execute.html:1126), non alla statistica;
  • il timer si ferma a zero: decremento in task_execute.html:974-975 con uscita su onTimerExpired() — il conteggio del ritardo (punto 3) oggi non esiste;
  • lo stack attuale è a 4 container (docker-compose.yml): MySQL 8, backend FastAPI, frontend Flask, nginx — base della sezione Architettura d'installazione.

Il punto 14 (layout) è l'unico non verificato sul codice: è una segnalazione dell'operatore del 28/07, da riprodurre.