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>
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.mdv1.0. Target deployment: Scenario B — containertmflow-clientdistribuito a ogni tablet/PC industriale, untmflow-servercentralizzato 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
GaiaClientviene comunque disegnata in M1 (per non accumulare debito) ma in M1 resta implementata da unImportOnlyGaiaClientche legge da file/DB senza contattare GAIA. I comandi produzione (start/pause/resume/end) in M1 scrivono suproduction_eventslocali — a M2 aggiungiamo l'implementazione che li invia a GAIA. - Il deploy M1 usa un singolo
docker-compose.ymlsu 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 condocker 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 viaSTATION_IDnel.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_IDnel client Flask, letta a startup, usata per filtrare/api/recipesinselect_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+ dependencyrequire_supervisor. - Tabella
supervisor_overrides(id, requested_by, authorized_by, override_type, target_ref, created_at, consumed_at, reason). - Endpoint
POST /api/supervisor/overrideche valida credenziali supervisor e ritornaoverride_tokenJWT-like (firmato, TTL 60s). - Endpoint
POST /api/supervisor/override/verifyusato da altri router prima di eseguire azioni protette. - Componente Alpine.js
supervisor-modalriusabile: 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 deprequire_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')emeasurement_interval_seconds INT NULL,max_retries INT NOT NULL DEFAULT 3,preparation_content LONGTEXT NULLarecipe_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_secondsemax_retriessono 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), nuovoclient/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. |
| Rimandato a M2. In M1 nessun feedback sonoro: al tick 0 del timer si mostra solo notifica visiva (toast + highlight subtask). | |
| 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), nuovoclient/static/js/idle-timer.js, nuovoclient/static/js/production-timer.js,client/static/js/caliper.js(hook conferma esplicita). - Server: aggiunge
measurement_sessionstable (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
GaiaClientdisegnata per intero (tutti i metodi previsti). - Implementazione
ImportOnlyGaiaClient:fetch_station_articleslegge da DB popolato via import one-shot; i comandistart/pause/resume/endscrivono in una nuova tabellaproduction_eventslocale (sorgente di verità per la demo, poi verrà replicata a GAIA in M2). - Endpoint admin
POST /api/admin/gaia-importche accetta un file (CSV o JSON) esportato dal cliente e popolastation_recipe_assignments+ articoli. Parser tollerante con report errori riga per riga. - UI admin
/admin/gaia-importper uploadare il file, previeware i dati, confermare l'import. - Export retro-compatibile:
GET /api/admin/production-events/exportrestituisce il JSON/CSV deiproduction_eventsaccumulati (il cliente può caricarlo manualmente in GAIA in M1 se gli serve). - Nessuna rete verso GAIA, nessuna credenziale GAIA richiesta per M1.
- Interfaccia astratta
- M2: implementazione concreta
LiveGaiaClientdel protocollo definitivo (REST/DB/altro) in base a D-0.1, credenziali, rete cliente, circuit breaker, monitoring. Iproduction_eventsaccumulati da M1 diventano la coda cheLiveGaiaClientdrena 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-importcon preview e conferma. - Endpoint
GET /api/admin/production-events/exportper 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, aggiornastation_recipe_assignments. - Drain iniziale dei
production_eventsaccumulati 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_eventse 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 deldocker-compose.ymlprod esistente con Traefik + Let's Encrypt puntato a dominiodemo.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-importcon 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.shche fa build, push via SSH alla VPS demo, restart condocker 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.examplecon solo variabili necessarie al client:STATION_ID,STATION_API_KEY,API_SERVER_URL,CLIENT_SECRET_KEY,LANG_DEFAULT, ecc.Dockerfile.clientottimizzato: multi-stage, Tailwind build + Babel compile + gunicorn.- GitHub Actions
.github/workflows/release.yml: su tagv*.*.*builda e pushatmflow-serveretmflow-cliental registry. - Script di provisioning
scripts/provision-tablet.sh: installa docker, crea.env, genera STATION_ID, pulla e avvia. - Documento
docs/DEPLOYMENT_B.mdcon 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 seguonolatest; 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)
- Retrocompatibilità dati: ogni migration deve avere
downgradetestato. Mai DROP di colonne con dati senza passo di deprecazione. - Feature flags: nuove integrazioni (GAIA, Supervisor) dietro flag config (
GAIA_ENABLED,SUPERVISOR_ENABLED) → rollout graduale e rollback veloce. - Test prima: seguire TDD sui sotto-piani. Ogni endpoint ha almeno un happy path + un negative path + un permission test.
- 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. - Audit log: ogni operazione critica (override, GAIA command, station assign) scrive su
access_logs. - i18n: ogni nuova stringa passa da
{{ _('...') }}o equivalente client-side. Niente testo hardcoded in italiano nei template. - 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)
- Decisioni chiuse: D-0.4 (cicalino → M2), D-0.7 (autologout configurabile), scelta (b) "dati reali senza live GAIA" in M1.
- 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.
- 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.
- 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.
- Dettagliare il sotto-piano
phase1-stationsin TDD eseguibile (prima fase sbloccante per tutte le altre di M1). - Eseguire le fasi di M1 (1 → 2/3/5-import in parallelo → 4 → Demo deploy) via
superpowers:subagent-driven-developmentoppuresuperpowers:executing-plans, con review + verifier tra una fase e l'altra. - Consegnare demo al cliente → raccogliere feedback → aprire M2.
- In M2: chiudere decisioni residue, sviluppare
LiveGaiaClient+ cicalino + Fase 6 (Deploy B) + Fase 7 (hardening/rollout).