Files
TieMeasureFlow/docs/superpowers/plans/2026-04-17-rev04-master-roadmap.md
Adriano f71bbf398e docs: add rev04 migration master roadmap and phase1 plan
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>
2026-04-17 21:13:01 +02:00

31 KiB

TieMeasureFlow V1.0.7 → V1.1.0 (rev04-2026) — Master Roadmap

Tipo documento: Master plan / roadmap. Non contiene task eseguibili TDD — rimanda ai sotto-piani per-fase. Spec sorgente: Schema sviluppo SW TieFlow_rev04-2026.docx + PIANO_IMPLEMENTAZIONE.md v1.0. Target deployment: Scenario B — container tmflow-client distribuito a ogni tablet/PC industriale, un tmflow-server centralizzato su VPS.

Goal: Portare TieMeasureFlow da V1.0.7 (funzionalità base: ricette, misure, SPC) a V1.1.0 allineata alla rev04: integrazione GAIA, stazioni per-tablet, ruolo capoturno, editor ricetta a blocchi, workflow operatore stretto (retry/timer/cicalino/avvio produzione), deploy docker per-tablet con registry privato.

Strategia di Rilascio (revisione 2026-04-17)

Priorità aggiornata dal committente: consegnare al cliente un sistema funzionante di test il prima possibile. Il deploy Scenario B (registry + Watchtower + immagini pubblicate) è esplicitamente rimandato alla fine dello sviluppo.

Il programma si articola quindi in due milestone:

Milestone Contenuto Obiettivo
M1 — Demo cliente Fasi 1-5 del piano (modello dati, capoturno, editor blocchi, workflow operatore, GAIA import-only con dati reali) + deploy "demo" semplice (single docker-compose su VPS demo, senza registry) Sistema testabile end-to-end dal cliente con i suoi dati, per raccogliere feedback sul workflow operatore prima di integrare GAIA live e andare in produzione.
M2 — Produzione Fase 6 (Deploy B industriale) + Fase 7 (hardening, E2E, rollout pilota) + eventuali aggiustamenti post-feedback M1 Rollout su tablet/PC reali del cliente.

Conseguenze operative:

  • Dati reali, non mock: M1 parte con contenuti veri del cliente (articoli, ricette, stazioni). Niente MockGaiaClient: in Fase 5 per M1 sviluppiamo solo il canale di import one-shot (endpoint admin che accetta un export GAIA in CSV/JSON, più UI Maker per editing manuale). L'integrazione GAIA live (polling, comandi produzione real-time) slitta a M2. Il cliente ci fornirà una snapshot dati all'inizio di M1.
  • L'interfaccia astratta GaiaClient viene comunque disegnata in M1 (per non accumulare debito) ma in M1 resta implementata da un ImportOnlyGaiaClient che legge da file/DB senza contattare GAIA. I comandi produzione (start/pause/resume/end) in M1 scrivono su production_events locali — a M2 aggiungiamo l'implementazione che li invia a GAIA.
  • Il deploy M1 usa un singolo docker-compose.yml su VPS di test con porte esposte a dominio di demo (HTTPS con Let's Encrypt tramite Traefik già presente in V1.0.7). Nessun registry privato, nessun Watchtower, build locale + push con docker compose up --build.
  • Durante M1 il cliente testa da browser direttamente contro la VPS demo; i "tablet" in quella fase sono semplicemente browser puntati all'URL demo.
  • Il feedback M1 può rimodulare le fasi di M2 (es. scoprire che serve un ruolo in più, che il cicalino va cambiato, che il protocollo GAIA va rivisto).

Architecture:

  • Server FastAPI centralizzato su VPS — unico nodo che parla a GAIA, detiene DB MySQL, genera report, calcola SPC.
  • Client Flask impacchettato come tmflow-client:<version> pubblicato su registry privato della VPS; ogni tablet/PC industriale pulla la propria copia e si identifica via STATION_ID nel .env.
  • Capoturno come ruolo separato con flusso di override a token a scadenza breve.
  • Ricetta estesa a blocchi tipizzati: preparazione documentale + misura vincolata a tolleranze.
  • Parametri volatili di ricetta (timer, max_retries) isolati dalla versione immutabile.

Tech Stack (invariato rispetto a V1.0.7):

  • Server: FastAPI, SQLAlchemy 2.0 async, MySQL 8, Alembic, Pydantic v2, WeasyPrint, Plotly+Kaleido, APScheduler (nuovo, per sync GAIA).
  • Client: Flask, Jinja2, Alpine.js, TailwindCSS, Fabric.js, Plotly.js, html5-qrcode, Web Serial, Flask-Babel.
  • Nuove integrazioni: adapter GAIA (protocollo TBD col cliente).
  • Deploy: Docker registry privato (registry:2) sulla VPS + Watchtower sui tablet per auto-update.

0. Precondizioni e Decisioni Aperte (RISOLVERE PRIMA DI INIZIARE)

Queste scelte sono prerequisiti: iniziare senza risolverle produce rework sicuro.

# Decisione Opzioni Chi decide Stato
D-0.1 Protocollo integrazione GAIA REST, DB shared, OPC-UA, file scambio Cliente + noi Aperta
D-0.2 Credenziali e rete GAIA VPN, firewall, whitelist IP IT cliente Aperta
D-0.3 Target hardware "tablet" Tablet Windows consumer, PC touch industriale Linux, tablet Android Cliente Aperta (critica per B)
D-0.4 Cicalino/luce avviso Audio browser HTML5, hardware USB locale, entrambi Cliente Rimandato a M2 (non bloccante M1)
D-0.5 Parametri runtime modificabili vs versione immutabile A: ogni modifica crea versione; B: separare volatili da strutturali Noi (raccomandato B) Aperta
D-0.6 Autenticazione capoturno durante override Login sovrapposto modale, PIN rapido, badge RFID Cliente Aperta
D-0.7 Timeout auto-logout Valore default + configurabilità Cliente Risolta: configurabile via system_settings (chiave auto_logout_minutes, default 15), con override opzionale per-utente in colonna users.auto_logout_minutes (NULL = usa globale).
D-0.8 Naming ruolo capoturno Supervisor, ShiftLeader, Capoturno Noi Proposta: Supervisor (già inglese come gli altri)
D-0.9 Tag versione immagine docker latest, SemVer, git sha Noi Proposta: SemVer + latest
D-0.10 Registry esposto su Internet o solo VPN Internet+auth, solo VPN Cliente + noi Proposta: solo VPN cliente

Azione richiesta: aprire una riunione di allineamento col cliente su D-0.1, D-0.2, D-0.3, D-0.4, D-0.6 prima di Fase 1.


Fasi (ordine consigliato)

Capoturno (Fase 2) è precondizione del workflow operatore (Fase 4). GAIA (Fase 5) può partire in parallelo a Fase 2-3 dopo Fase 1. Fase 6 (deploy industriale B) parte solo dopo il feedback cliente su M1.

  ┌─────────────────────────── M1 — Demo per cliente ────────────────────────────┐
  │                                                                               │
  │   ┌───────────────────────────────────────────────────┐                       │
  │   │  Fase 1 — Stazioni + identità per-tablet           │  1.5-2 settimane     │
  │   └───────────────┬──────────────────────────────────┘                       │
  │                   │                                                           │
  │       ┌───────────┼─────────────────────┐                                    │
  │       │           │                     │                                    │
  │       ▼           ▼                     ▼                                    │
  │   Fase 2      Fase 3                Fase 5 (import-only)                     │
  │   Capoturno   Editor a blocchi      ImportOnlyGaiaClient + UI import          │
  │       │           │                     │          (paralleli, ~2-3 sett.)   │
  │       └─────┬─────┘                     │                                    │
  │             ▼                           │                                    │
  │         Fase 4 — Workflow operatore    │           2-3 settimane              │
  │         (retry/timer/autologout/avvio) │                                     │
  │             │                           │                                    │
  │             └──────────┬───────────────┘                                    │
  │                        ▼                                                     │
  │               Demo deploy su VPS test                ~2 giorni               │
  │               (docker-compose single-file,                                    │
  │                Traefik+LE, no registry,                                       │
  │                dati reali cliente importati)                                  │
  │                        │                                                     │
  └────────────────────────┼─────────────────────────────────────────────────────┘
                           │
                 ═══  CHECKPOINT: feedback cliente su M1  ═══
                           │
  ┌─────────────────────── M2 — Produzione ─────────────────────────────────────┐
  │                        │                                                     │
  │                        ▼                                                     │
  │               Adjustments post-feedback            variabile                 │
  │               (modifiche workflow, UX, GAIA reale)                            │
  │                        │                                                     │
  │                        ▼                                                     │
  │               Fase 5 reale — GAIA integrazione     1-2 settimane              │
  │               (protocollo definitivo, credenziali,                            │
  │                rete cliente, feature flag)                                    │
  │                        ▼                                                     │
  │               Fase 6 — Deploy B industriale        1 settimana                │
  │               (registry + watchtower + compose                                │
  │                split server/client, STATION_ID,                               │
  │                CI release)                                                    │
  │                        ▼                                                     │
  │               Fase 7 — Hardening & rollout         1-2 settimane              │
  │               (security review, e2e sito pilota,                              │
  │                docs aggiornati, i18n delta)                                   │
  │                                                                              │
  └──────────────────────────────────────────────────────────────────────────────┘

Stima a M1 (sistema demo testabile): ~6-7 settimane full-time; ~4-5 settimane con 2 fasi in parallelo. Stima totale fino a M2: ~9-11 settimane full-time (include feedback cycle stimato 1-2 settimane).


Fase 1 — Stazioni e Identità per-tablet

Obiettivo: modellare il concetto di "stazione di controllo", associare ricette a stazioni, far sì che ogni client carichi solo le ricette della propria stazione identificata da STATION_ID.

Sotto-piano: docs/superpowers/plans/2026-04-17-rev04-phase1-stations.md

Deliverable:

  • Tabelle stations, station_recipe_assignments + migration Alembic.
  • Endpoint GET /api/stations, POST /api/stations, PUT /api/stations/{id}, GET /api/stations/{id}/recipes.
  • Schema auth: API key del client associata a una stazione → ogni request porta identità di stazione implicita.
  • Variabile d'ambiente STATION_ID nel client Flask, letta a startup, usata per filtrare /api/recipes in select_recipe.
  • UI admin per gestire stazioni + assegnazioni.
  • Test: un client con STATION_ID=A vede solo le ricette assegnate ad A.

File impattati principali:

  • Nuovi: server/models/station.py, server/routers/stations.py, server/schemas/station.py, server/services/station_service.py, client/templates/admin/stations.html, server/migrations/versions/<hash>_add_stations.py.
  • Modificati: server/main.py (registra router), server/models/__init__.py, server/routers/recipes.py (filtro by station), client/config.py (STATION_ID), client/blueprints/measure.py (passa STATION_ID alle query), client/blueprints/admin.py (CRUD stazioni), client/blueprints/auth.py (usa API key specifica di stazione).

Rischi: rotture retrocompatibilità API se cambiamo signature endpoint esistenti → mitigare con parametro opzionale station_id e default None = backward compat.


Fase 2 — Ruolo Capoturno (Supervisor) e Override

Obiettivo: introdurre ruolo Supervisor, endpoint di override a token breve, UI login-sovrapposto per autorizzazioni puntuali.

Sotto-piano: docs/superpowers/plans/2026-04-17-rev04-phase2-supervisor.md

Deliverable:

  • Estensione enum ruoli con Supervisor + dependency require_supervisor.
  • Tabella supervisor_overrides (id, requested_by, authorized_by, override_type, target_ref, created_at, consumed_at, reason).
  • Endpoint POST /api/supervisor/override che valida credenziali supervisor e ritorna override_token JWT-like (firmato, TTL 60s).
  • Endpoint POST /api/supervisor/override/verify usato da altri router prima di eseguire azioni protette.
  • Componente Alpine.js supervisor-modal riusabile: apertura modale, login, callback con token.
  • Audit trail: ogni override consumato logga consumed_at + contesto.

Tipi di override previsti:

  • FORCE_OUT_OF_TOLERANCE — operatore vuole confermare misura fuori tolleranza.
  • RESET_RETRY_COUNTER — sbloccare dopo N tentativi falliti.
  • PAUSE_PRODUCTION — fermo linea (invierà comando GAIA in Fase 5).
  • END_PRODUCTION — fine produzione (chiude timer GAIA in Fase 5).
  • EDIT_RUNTIME_PARAMS — modificare timer/max_retries della ricetta in corsa.

File impattati principali:

  • Nuovi: server/models/supervisor_override.py, server/routers/supervisor.py, server/services/supervisor_service.py, server/schemas/supervisor.py, client/templates/components/supervisor_modal.html, client/static/js/supervisor-modal.js.
  • Modificati: server/models/user.py (commento ruoli), server/middleware/api_key.py (nuova dep require_supervisor), client/blueprints/measure.py (consuma token).

Fase 3 — Editor Ricetta a Blocchi (Preparazione + Misura)

Obiettivo: estendere il concetto di RecipeTask a blocchi tipizzati: preparation (documentale: materiali, imballo, temperatura) e measurement (con subtask + tolleranze + timer intervallo).

Sotto-piano: docs/superpowers/plans/2026-04-17-rev04-phase3-block-editor.md

Deliverable:

  • Migration: aggiunge block_type ENUM('preparation', 'measurement') e measurement_interval_seconds INT NULL, max_retries INT NOT NULL DEFAULT 3, preparation_content LONGTEXT NULL a recipe_tasks.
  • Backfill: tutti i task esistenti → block_type='measurement'.
  • Editor UI: toggle tipo blocco nel task editor; blocchi preparazione usano rich-text editor (TipTap light o textarea con markdown + preview) e accettano upload PDF/immagine opzionale.
  • MeasurementTec UI: blocchi preparazione visualizzati come "scheda documentale" con pulsante "Ho letto, procedi"; blocchi misura invariati.
  • Parametri volatili: nuove colonne measurement_interval_seconds e max_retries sono modificabili senza creare nuova versione (Decisione D-0.5 opzione B).

File impattati principali:

  • Migration Alembic.
  • Modificati: server/models/task.py, server/schemas/task.py, server/services/recipe_service.py (copy-on-write copia anche nuovi campi), client/templates/maker/task_editor.html, client/static/js/annotation-editor.js (skip per blocchi prep), client/templates/measure/task_execute.html (branch per tipo blocco), nuovo client/templates/measure/preparation_view.html.

Fase 4 — Workflow Operatore: Retry, Timer, Autologout, Avvio Produzione

Nota: feedback sonoro (cicalino avvio misura + luce continua) rimandato a M2. M1 usa solo notifiche visive.

Obiettivo: implementare le regole stringenti della rev04 sul flusso operatore.

Sotto-piano: docs/superpowers/plans/2026-04-17-rev04-phase4-workflow.md

Deliverable:

Feature Implementazione
N tentativi max poi Supervisor Contatore in session Flask per (measurement_session_id, subtask_id). Al superamento: modale Supervisor (Fase 2) per reset.
Auto-avanzamento solo se pass Logica JS: se pass_fail != 'pass', bottone "Avanti" disabilitato finché operatore non richiede conferma Supervisor (override FORCE_OUT_OF_TOLERANCE).
Log-out bloccato durante attività Flag measurement_session.is_active. Link "Logout" in navbar nascosto/disabilitato se attiva. Endpoint POST /api/auth/logout respinge con 409 se sessione attiva senza override.
Auto-logout inattività Alpine store idle-timer con event listeners pointermove/keydown. Alla scadenza (default 15m, config per-utente o globale) → redirect a /logout.
Cicalino avvio misura Rimandato a M2. In M1 nessun feedback sonoro: al tick 0 del timer si mostra solo notifica visiva (toast + highlight subtask).
Luce/cicalino continuo Rimandato a M2.
Timer intervallo tra misure Countdown JS che legge measurement_interval_seconds. Al tick 0: notifica visiva + mostra subtask + sblocca input calibro.
"Avvio produzione" post-prima-misura Bottone UI visibile solo dopo prima misura confermata. Chiamata POST /api/gaia/production/start (Fase 5).
"Fermo linea" / "Fine produzione" Due bottoni protetti da Supervisor override. Chiamate GAIA (Fase 5).

File impattati principali:

  • Modificati: client/blueprints/measure.py, client/templates/measure/task_execute.html, client/static/js/numpad.js (estende con retry counter), nuovo client/static/js/idle-timer.js, nuovo client/static/js/production-timer.js, client/static/js/caliper.js (hook conferma esplicita).
  • Server: aggiunge measurement_sessions table (id, user_id, recipe_version_id, station_id, started_at, ended_at, is_active), endpoint start/end.

Dipendenza: Fase 2 (Supervisor) e Fase 3 (blocchi con timer) devono essere completate.


Fase 5 — Adapter GAIA

Obiettivo: integrare il MES GAIA per sync ricette-stazioni e comandi produzione.

Sotto-piano: docs/superpowers/plans/2026-04-17-rev04-phase5-gaia.md

Scope per milestone:

  • M1 (dati reali, no live GAIA):
    • Interfaccia astratta GaiaClient disegnata per intero (tutti i metodi previsti).
    • Implementazione ImportOnlyGaiaClient: fetch_station_articles legge da DB popolato via import one-shot; i comandi start/pause/resume/end scrivono in una nuova tabella production_events locale (sorgente di verità per la demo, poi verrà replicata a GAIA in M2).
    • Endpoint admin POST /api/admin/gaia-import che accetta un file (CSV o JSON) esportato dal cliente e popola station_recipe_assignments + articoli. Parser tollerante con report errori riga per riga.
    • UI admin /admin/gaia-import per uploadare il file, previeware i dati, confermare l'import.
    • Export retro-compatibile: GET /api/admin/production-events/export restituisce il JSON/CSV dei production_events accumulati (il cliente può caricarlo manualmente in GAIA in M1 se gli serve).
    • Nessuna rete verso GAIA, nessuna credenziale GAIA richiesta per M1.
  • M2: implementazione concreta LiveGaiaClient del protocollo definitivo (REST/DB/altro) in base a D-0.1, credenziali, rete cliente, circuit breaker, monitoring. I production_events accumulati da M1 diventano la coda che LiveGaiaClient drena verso GAIA al primo avvio.

Contratto comune (disegnato in M1, usato da entrambe le implementazioni):

# server/services/gaia_client.py
class GaiaClient(Protocol):
    async def fetch_station_articles(self, station_code: str) -> list[StationArticle]: ...
    async def start_production(self, article_code: str, station_code: str, operator_id: str) -> None: ...
    async def pause_production(self, article_code: str, station_code: str, reason: str) -> None: ...
    async def resume_production(self, article_code: str, station_code: str) -> None: ...
    async def end_production(self, article_code: str, station_code: str, stats: ProductionStats) -> None: ...

Deliverable M1 — ImportOnlyGaiaClient:

  • Lettura articoli/ricette dal DB interno popolato via import one-shot.
  • Comandi produzione persistiti in tabella production_events (no rete esterna).
  • Endpoint POST /api/admin/gaia-import (upload CSV/JSON export GAIA) + UI /admin/gaia-import con preview e conferma.
  • Endpoint GET /api/admin/production-events/export per esportare gli eventi accumulati (JSON/CSV) da caricare manualmente su GAIA se serve.
  • Endpoint POST /api/gaia/production/{start,pause,resume,end} usati dal client Flask.
  • Config .env: GAIA_MODE=import_only (default in M1).

Deliverable M2 — LiveGaiaClient:

  • Implementazione concreta del protocollo definitivo (REST/DB/altro) in base a D-0.1.
  • Job APScheduler ogni 60s: per ogni stazione attiva, chiama fetch_station_articles, aggiorna station_recipe_assignments.
  • Drain iniziale dei production_events accumulati verso GAIA.
  • Config .env: GAIA_MODE=live, GAIA_BASE_URL, GAIA_AUTH_TOKEN, GAIA_POLL_INTERVAL_SECONDS.
  • Circuit breaker: se GAIA giù, non bloccare operazioni interne; accoda su production_events e degrada a warning in UI.

File impattati principali:

  • Nuovi in M1: server/services/gaia_client.py (Protocol + ImportOnlyGaiaClient), server/services/gaia_import.py, server/routers/gaia.py (production events), server/routers/admin_gaia.py (import), server/schemas/gaia.py, server/models/production_event.py, client/blueprints/admin.py (aggiunge route import), client/templates/admin/gaia_import.html, server/tests/test_gaia_import_only.py.
  • Aggiunti in M2: server/services/gaia_live_client.py, server/services/gaia_sync.py (scheduler), server/tests/test_gaia_live.py.
  • Modificati: server/main.py (lifespan avvia APScheduler solo in modalità live), server/config.py (nuove variabili).

Fase M1-Demo — Deploy Demo per Cliente (tra Fase 4 e checkpoint feedback)

Obiettivo: dopo Fasi 1-4 e Fase 5 import-only, mettere online una demo accessibile al cliente via HTTPS su dominio di test, con i dati reali del cliente (articoli, ricette, stazioni).

Deliverable:

  • docker-compose.demo.yml: estensione del docker-compose.yml prod esistente con Traefik + Let's Encrypt puntato a dominio demo.tielogic.<tld> (o sottodominio dedicato), MySQL vuoto pronto per l'import, server e client buildati localmente (no registry).
  • Seed minimo: solo utenti di esempio per ogni ruolo (MeasurementTec, Maker, Metrologist, Supervisor, Admin) + una stazione "default". Articoli e ricette non vengono seedati: vengono importati dal cliente (o da noi a suo nome) via /admin/gaia-import con il file export GAIA reale.
  • Pagina /admin/demo-reset (protetta da SETUP_PASSWORD) che ripulisce misure + production events lasciando utenti, articoli e ricette (così il cliente ri-testa più volte senza perdere i dati importati).
  • Script scripts/deploy-demo.sh che fa build, push via SSH alla VPS demo, restart con docker compose up -d --build.
  • Credenziali demo consegnate al cliente insieme alla guida di test (scenari guidati: "prova come operatore", "prova come capoturno", "prova come maker", ecc.).

Non incluso (rimandato a M2/Fase 6): registry privato, Watchtower, compose split server/client, CI release automation, deploy su hardware cliente, LiveGaiaClient in tempo reale.


Fase 6 — Deploy Scenario B (Docker per-tablet + Registry + Watchtower) [M2]

Obiettivo: package del client come immagine pubblicata su registry privato della VPS; ogni tablet pulla + auto-update via Watchtower. Parte solo dopo checkpoint feedback M1.

Sotto-piano: docs/superpowers/plans/2026-04-17-rev04-phase6-deploy-b.md

Deliverable:

  • docker-compose.server.yml (VPS): mysql + server + traefik + registry + watchtower-server.
  • docker-compose.client.yml (per-tablet): client + watchtower-client, image: vps.tielogic.local:5000/tielogic/tmflow-client:latest.
  • .env.client.example con solo variabili necessarie al client: STATION_ID, STATION_API_KEY, API_SERVER_URL, CLIENT_SECRET_KEY, LANG_DEFAULT, ecc.
  • Dockerfile.client ottimizzato: multi-stage, Tailwind build + Babel compile + gunicorn.
  • GitHub Actions .github/workflows/release.yml: su tag v*.*.* builda e pusha tmflow-server e tmflow-client al registry.
  • Script di provisioning scripts/provision-tablet.sh: installa docker, crea .env, genera STATION_ID, pulla e avvia.
  • Documento docs/DEPLOYMENT_B.md con procedura manuale operatore IT cliente.

Scelte tecniche:

  • Registry self-hosted su VPS con auth basic (htpasswd) su registry:2, esposto solo via VPN cliente (D-0.10).
  • Watchtower WATCHTOWER_POLL_INTERVAL=300, WATCHTOWER_ROLLING_RESTART=true, label-filtered (com.centurylinklabs.watchtower.enable=true) per evitare update indesiderati.
  • Tag strategia: ogni release push tmflow-client:1.1.0 + tmflow-client:latest. Tablet seguono latest; rollback = retag del latest a versione precedente.

Caveat D-0.3: se i tablet target sono Windows consumer, B è fragile (docker desktop + licenze). Documentare come prerequisito mini-PC Linux industriale oppure scivolare a C (che è comunque B+LAN). Questo blocco deve essere chiarito prima.


Fase 7 — Hardening, E2E, Rollout [M2]

Obiettivo: fare il sistema robusto per produzione e rilasciarlo su un sito pilota prima del rollout generale.

Sotto-piano: docs/superpowers/plans/2026-04-17-rev04-phase7-hardening.md

Deliverable:

  • Security review completa (oh-my-claudecode:security-reviewer): nuovi endpoint GAIA, override Supervisor, registry esposto.
  • Test E2E manuali + script Playwright/Selenium su: flusso completo operatore + capoturno override + sync GAIA + avvio/fine produzione.
  • Rollback plan: procedura di ritorno a V1.0.7 se necessario (backup DB pre-migration, tag immagine precedente).
  • Aggiornamento stringhe i18n IT/EN per tutti i nuovi messaggi (capoturno, cicalino, timer, GAIA errori).
  • Aggiornamento CLAUDE.md + README.md + API.md + USER_GUIDE.md.
  • Sito pilota: una singola postazione per una settimana prima del rollout sugli altri.
  • Monitoring: log centralizzato + alert su errori GAIA persistenti, override Supervisor eccessivi per stazione, misure fuori tolleranza per ricetta.

Vincoli Trasversali (applicare in ogni fase)

  1. Retrocompatibilità dati: ogni migration deve avere downgrade testato. Mai DROP di colonne con dati senza passo di deprecazione.
  2. Feature flags: nuove integrazioni (GAIA, Supervisor) dietro flag config (GAIA_ENABLED, SUPERVISOR_ENABLED) → rollout graduale e rollback veloce.
  3. Test prima: seguire TDD sui sotto-piani. Ogni endpoint ha almeno un happy path + un negative path + un permission test.
  4. Envelope response: iniziare ad allineare nuovi endpoint allo standard {success, data, error} della spec 2026-04-01, anche se V1.0.7 non lo usa. Minimizza rework futuro.
  5. Audit log: ogni operazione critica (override, GAIA command, station assign) scrive su access_logs.
  6. i18n: ogni nuova stringa passa da {{ _('...') }} o equivalente client-side. Niente testo hardcoded in italiano nei template.
  7. Commit granulari: un commit per task TDD (test rosso → verde → commit). Usa il git-master agent per il formato commit.

Scelte Architetturali Confermate / Deviate dalla Spec 2026-04-01

Scelta Spec 2026-04-01 V1.1.0 Motivazione
Struttura cartelle src/backend/ + src/frontend/ server/ + client/ V1.0.7 ha già cementato questa struttura. Rework > costo beneficio.
Package manager uv requirements.txt Migrazione a uv rimandata a V1.2.0 (task dedicato).
Frontend Gradio o React Flask server-side Vincolo cliente: tablet kiosk, i18n server-side, no SPA. Deviazione documentata.
Messaging NATS obbligatorio Nessuno Monolite a 2 processi, NATS rimandato a v2.x (quando compariranno moduli camera/ML).
API Envelope {success,data,error} Obbligatorio Adozione incrementale sui nuovi endpoint rev04 Evita rework totale ma allinea il nuovo codice.
Auth header X-Api-Key Obbligatorio ✓ Già presente (X-API-Key) Allineato (case-insensitive per HTTP).
Registry privato + Watchtower Raccomandato ✓ Adottato in Fase 6 Necessario per scenario B.

Rischi e Mitigazioni

Rischio Probabilità Impatto Mitigazione
Protocollo GAIA live non decidibile prima di M2 Media Medio M1 non dipende dal protocollo live: usa ImportOnlyGaiaClient con dati reali importati. Il protocollo definitivo si chiude durante M1, pronto per Fase 5-live in M2.
Export GAIA fornito dal cliente in formato non documentato Media Medio Parser gaia_import.py tollerante + anteprima UI + possibilità di caricare più volte; prevedere 1-2 giorni di fitting iniziale del parser sullo specifico formato fornito.
Tablet Windows consumer rendono B non praticabile Media Alto Documentare prerequisito hardware, prevedere fallback a C (edge NUC per sito).
Cliente cambia idea sul ruolo capoturno Bassa Medio Astrazione override generica: il ruolo può essere rinominato o scomposto senza toccare il flusso.
Prestazioni Watchtower con N tablet Bassa Basso poll_interval=300s, update scaglionati (rolling_restart), banda registry limitata ma accettabile.
i18n delta si accumula e va in produzione non tradotto Media Medio Lint in CI che fallisce se ci sono stringhe _('...') non in messages.po.
Migration Alembic rompe DB produzione Bassa Critico Backup pre-deploy obbligatorio, staging con dump produzione, downgrade testato.

Prossimi passi (focus M1)

  1. Decisioni chiuse: D-0.4 (cicalino → M2), D-0.7 (autologout configurabile), scelta (b) "dati reali senza live GAIA" in M1.
  2. Decisioni ancora aperte per M1: D-0.5 (parametri volatili separati dalla versione — raccomandato B) e D-0.6 (UX capoturno: default modale login sovrapposto). Da confermare al volo col cliente o decise da noi di default.
  3. Decisioni rinviabili a M2: D-0.1 (protocollo GAIA live), D-0.2 (rete/credenziali GAIA), D-0.3 (target hardware tablet), D-0.10 (registry esposto o solo VPN). Da chiudere durante M1, non bloccano la demo.
  4. Richiesta al cliente per sbloccare Fase 5 import-only: farci avere un export GAIA d'esempio (CSV/JSON) degli articoli + ricette per una o due stazioni, così adattiamo il parser.
  5. Dettagliare il sotto-piano phase1-stations in TDD eseguibile (prima fase sbloccante per tutte le altre di M1).
  6. Eseguire le fasi di M1 (1 → 2/3/5-import in parallelo → 4 → Demo deploy) via superpowers:subagent-driven-development oppure superpowers:executing-plans, con review + verifier tra una fase e l'altra.
  7. Consegnare demo al cliente → raccogliere feedback → aprire M2.
  8. In M2: chiudere decisioni residue, sviluppare LiveGaiaClient + cicalino + Fase 6 (Deploy B) + Fase 7 (hardening/rollout).