Il gate del fuori tolleranza vale per l'acquisizione e non per la quota:
la regola era pensata per la misura sequenziale e su un evento simultaneo
produceva un blocco permanente.
Piu' il bi-ambiente Python, la versione del motore timbrata al build, la
motivazione della divisione degli extra corretta, e due cose promesse e non
mantenute -- expected_json e image_path -- dichiarate come consegne del
piano 1b invece che lasciate come intenzioni.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BBnuACZSCJqXrMYC3LUMU
Sei task TDD: grafo sul task, runner condiviso, worker separato,
esecuzione con salvataggio misure, prova del confine server/VisionSuite,
immagini di riferimento.
Primo dei quattro piani. Si collauda interamente via API, senza camera.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BBnuACZSCJqXrMYC3LUMU
Otto decisioni dal brainstorming, con il motivo di ognuna: motore su
entrambi i lati con versione in lockstep, agente sottile, server che non
importa mai VisionSuite, device a livello PC, esecuzione decisa dalla
stazione, verdetto tenuto fuori dal grafo, sorgente immagine astratta.
Modello dati, API, errori e le quattro domande che restano aperte.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BBnuACZSCJqXrMYC3LUMU
Tredici punti su quindici sono in esercizio e nessuno li ha percorsi. Finora il
collaudo era «provare le ricette COLLAUDO-A e B», che è un invito a scoprire da
soli in che ordine e con quali valori — cioè a perdere mezza giornata prima di
misurare qualcosa di utile.
Ordinata perché ogni prova prepari la successiva, e perché le due che vanno fatte
adesso vengano prima: il layout, che si vede solo da un monitor largo, e le
richieste di rete, ora che la Content-Security-Policy è appena entrata in vigore.
Due dettagli verificati sul codice prima di scriverla, perché mandavano a caccia
di pulsanti inesistenti: il timer non parte finché non si preme «Avvio
Produzione», che compare solo dopo il primo ciclo confermato — il primo pezzo è
attrezzaggio, non produzione; e una quota già presa si rimisura cliccandola in
alto, che è la via d'uscita dal blocco fuori tolleranza senza chiamare nessuno.
Detto anche cosa la scaletta non copre, incluso il fatto che su una VPS pubblica
staccare la rete non prova niente: si guarda dove vanno le richieste, e il giro
vero si fa in reparto.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
Punto 14. La segnalazione dell'operatore del 28/07 non era stata circoscritta sul
codice: «le dimensioni delle viste cambiano a seconda del menu». Sono quattro
meccanismi distinti, tutti leggibili senza avere il tablet in mano.
Ogni vista si dichiarava la propria larghezza: sette valori diversi su diciassette
template, e nessuno coincideva con quello della navbar, che sta a max-w-7xl su
tutte. Il contenuto era quindi disallineato dalla barra sopra di sé, e il
disallineamento cambiava a ogni pagina. Il percorso dell'operatore faceva
1280 → 1024 → tutto schermo → 1280 in quattro passaggi.
Il padding verticale mescolava py-8 e py-6 fra viste consecutive, così la prima
card cambiava altezza a ogni schermata.
La barra di scorrimento è classica da 8px e occupa spazio: una pagina lunga la
mostrava, una corta no, e la schermata di misura la toglie sempre. A ogni
navigazione tutto il contenuto centrato — navbar compresa — si spostava di 8px.
La schermata di misura era alta 100vh, che su Android e iOS è l'altezza con la
barra dell'indirizzo nascosta: su un tablet il piede, dove stanno «Fine ciclo
misura» e il tastierino, finiva sotto il bordo.
Ora: .tmf-page e .tmf-page-narrow in themes.css, con i valori esatti della navbar;
scrollbar-gutter: stable; 100dvh dove serve. Due larghezze in tutto il prodotto al
posto di sette, e il criterio è il tipo di pagina — liste, tabelle e tele stanno
larghe, i moduli stanno stretti.
Login e schermata di misura tengono la loro geometria, per i motivi scritti in
docs/architecture/LAYOUT.md e ripetuti in EXEMPT dentro il test: la prima non ha
navbar a cui allinearsi, la seconda non deve scorrere mentre si misura.
Il test è statico e guarda i sorgenti: la vista scritta domani copierà la cornice
dalla vicina, ed è lì che la deriva ricomincia.
Resta da chiedere all'operatore su quale schermo l'ha vista: in verticale su un
tablet quasi tutte quelle larghezze collassano e il difetto non si nota.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
STATO_PROGETTO.md
- Bumped snapshot date to 2026-04-27.
- Added "Hardening post-restructure (smoke test 2026-04-26)" section
recording the four runtime regressions surfaced by the local smoke
test (env_file path, missing Station import, UPLOAD_DIR default,
apostrophe-in-translation in Alpine), plus the recipe-assignment
modal UX rework and the new node-based JS syntax test guard.
- Added "Smoke test status" section listing the verified end-to-end
flow (MySQL up, alembic, seed, login, admin pages, MeasurementTec
workflow, hot reload).
- Bumped frontend test count 44 → 46 to reflect
test_template_js_syntax.py.
ROADMAP.md
- Added a tech-debt entry for the user-reported task_complete
riepilogo rendering anomaly (still under investigation: the curl
fetch returns the table populated, but the user reports an empty
body in the browser).
- Added a tech-debt entry for the still-pending Docker container
smoke test of the new uv-based Dockerfiles.
src/frontend/flask_app/templates/measure/task_complete.html
- Replaced sort(attribute='task_info.order_index,subtask.marker_number')
with two chained stable sorts. Jinja's sort filter does not accept a
comma-separated multi-attribute string; the previous form sorted on
a non-existent attribute and only worked by accident because the
API already returned rows in the desired order.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Stations were the headline V2.0.0 feature but had no user-facing
documentation outside the architecture page. Filled the gap across
the three operational docs.
USER_GUIDE.md
- New entries in "Key Concepts": Station and Station assignment.
- New "Recipes you see are filtered by station" subsection in the
MeasurementTec workflow, explaining why the Select Recipe page may
legitimately show fewer recipes than expected and what the
"Stazione non configurata" error means at the operator level.
- New "Station Management" section under Admin Workflow covering:
the mental model, station create/edit/delete, the two-column
recipe-assignment modal, the immutable-code rule, the role of the
ST-DEFAULT seed station, and the tablet deployment cheat sheet.
- Admin role description updated to mention stations.
DEPLOYMENT.md
- Environment Variables Reference: added STATION_CODE row and noted
that an empty value triggers the deliberate fail-fast HTTP 503 on
/measure/select. Updated RATE_LIMIT_GENERAL default (300, per the
V2.0.0 perf change). Clarified UPLOAD_DIR resolves against the
project root.
API.md
- New "Stations" endpoint section listing all eight routes with
request/response examples and the 401/403/404/409 error contract:
GET / POST /stations, GET /stations/{id}, PUT /stations/{id},
DELETE /stations/{id}, GET /stations/{id}/recipes,
GET /stations/by-code/{code}/recipes (the operator-facing one used
by the Flask client), POST /stations/{id}/recipes,
DELETE /stations/{id}/recipes/{recipe_id}.
- TOC updated with the new "Stations" anchor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cleanup
- Remove src/backend/Dockerfile.legacy and
src/frontend/flask_app/Dockerfile.legacy (history is in git, build
uses the new uv-based root Dockerfile / Dockerfile.frontend).
- Remove src/frontend/flask_app/verify_i18n.py (had hardcoded paths
pointing at the old client/ tree).
Group docs/
- New docs/README.md indexes everything in one place.
- New docs/architecture/STATO_PROGETTO.md: snapshot of what works in
V2.0.0 (inherited V1.0.7 features, rev04 Phase 1 stations,
worker scaling, src/ restructure, test status, stack, decisions).
- New docs/architecture/ROADMAP.md: what's next — Phases 2-7 of the
rev04 migration with status, open client decisions (D-0.1 through
D-0.10), tech debt and time estimates for M1 / M2.
- Move PIANO_IMPLEMENTAZIONE.md (90KB V1.0.0 plan) to
docs/archive/2026-02-06-piano-implementazione-v1.md (historical).
- Move Schema sviluppo SW TieFlow_rev04-2026.docx to docs/specs/
with ISO date filename so the customer spec is now tracked.
- Move src/frontend/flask_app/I18N_SETUP.md to docs/I18N_SETUP.md
and rewrite paths to the new src/frontend/flask_app/ tree.
.dockerignore: simplified now that legacy Dockerfiles are gone;
docs/ stays excluded from the build context.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aggiunge il master plan di migrazione V1.0.7 -> V1.1.0 (rev04-2026)
con le sette fasi organizzate in milestone M1 (demo cliente) e M2
(produzione), piu il piano TDD dettagliato della Fase 1 (Stazioni e
identita per-tablet) con 17 task eseguibili.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Security hardening: CORS lockdown, rate limiting middleware con sliding
window e eviction IP stale, security headers (CSP, HSTS, X-Frame-Options),
session cookie hardening, filename sanitization upload.
i18n completion: internazionalizzati barcode.js e csv-export.js con bridge
window.BARCODE_I18N/CSV_I18N, aggiornati .po IT/EN con 27 nuove stringhe.
Tablet UX: touch target 44px per dispositivi coarse pointer.
Test suite: 101 test totali (76 server + 25 client), copertura completa
di tutti i router API, autenticazione, ruoli, CRUD, SPC, file upload,
security integration. Infrastruttura SQLite async in-memory con fixtures.
Fix critici: MissingGreenlet in recipe_service (selectinload eager),
route ordering tasks.py, auth_service bcrypt diretto, Measurement.id
Integer per SQLite.
Documentazione: API.md (riferimento completo 40+ endpoint),
DEPLOYMENT.md (guida produzione con Docker/Nginx/SSL),
USER_GUIDE.md (manuale utente per ruolo).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>