Vai al contenuto

Compila RAS v2 - Piano refactor foto

Data: 2026-07-31

Decisione

Procedere con un refactor incrementale, non con fix puntuali sparsi.

La prima fase deve restare compatibile con il payload attuale, per non rompere stampa, draft e dati gia salvati.

Step 0 - Freeze regole

Documento sorgente:

  • docs/operativo/ras_compila_v2_photo_spec_20260731.md

Regole accettate:

  • foto visibili subito;
  • refresh non deve far sparire foto;
  • cancellazione recuperabile tramite cestino;
  • parcheggio mantenuto;
  • duplicati gestiti per singola tessera/assegnazione;
  • stampa tecnica sempre consentita;
  • offline supportato davvero.

Step 1 - Ledger client-only

Obiettivo: introdurre un modello centrale senza cambiare DB.

Da creare nel pack:

  • normalizzazione ensurePhotoLedger();
  • photo_assets;
  • photo_assignments;
  • photo_ops_queue.

Compatibilita:

  • leggere dati legacy da images, detail.image, detail.gallery.items, photo_tray;
  • scrivere ancora payload legacy per export/stampa;
  • non rimuovere subito le vecchie strutture.

Output atteso:

  • nessun cambio visibile all'utente;
  • base dati interna piu stabile.

Stato 2026-07-31:

  • avviato in build compila-v2-roem-pilot-20260731-photo-ledger-b12;
  • aggiunte funzioni client-only per derivare photo_ledger dal payload legacy;
  • photo_ledger viene incluso in snapshot locale e draft server solo quando Compila v2 e attiva;
  • import/restore/merge riallineano il ledger alle strutture legacy;
  • nessuna modifica intenzionale alla v1.

Riallineamento architetturale:

  • build compila-v2-roem-pilot-20260731-photo-ledger-module-b13;
  • spostata la logica ledger in app/static/ras/compila_v2_photo_ledger.js;
  • il pack monolitico mantiene solo bridge minimi verso window.CompilaV2PhotoLedger;
  • il modulo viene caricato solo quando il pack gira con compila_v2=1.

Step 2 - Upload via ledger

Obiettivo: una foto aggiunta crea sempre asset + assignment.

Flusso:

  1. salva blob locale;
  2. crea asset local;
  3. crea assignment nella domanda;
  4. aggiorna payload compatibile;
  5. prova upload se online;
  6. se upload riesce, asset passa a server;
  7. se fallisce, asset resta local/pending.

Test:

  • upload online;
  • upload offline;
  • refresh con blob locale;
  • refresh dopo upload server.

Step 3 - Cancellazione recuperabile

Obiettivo: cancellare significa spostare assignment nel cestino, non distruggere asset.

Flusso:

  1. la tessera sparisce dalla domanda;
  2. assignment passa a trash;
  3. viene salvata origine domanda/sezione;
  4. se offline, op delete_pending;
  5. se online, sync best effort.

UI:

  • pulsante/voce "Cestino foto RAS";
  • lista con origine;
  • ripristina;
  • sposta in parcheggio.

Test:

  • cancellazione online;
  • cancellazione offline;
  • refresh dopo cancellazione;
  • ripristino da cestino;
  • duplicato stessa domanda.

Stato 2026-07-31:

  • avviato in build compila-v2-roem-pilot-20260731-photo-trash-b14;
  • aggiunta funzione modulare trashAssignment() in compila_v2_photo_ledger.js;
  • cancellazione foto principale, galleria extra e galleria sottoscheda registrano un assignment trash;
  • in v2 la cancellazione non elimina subito il blob locale IndexedDB;
  • resta da aggiungere UI cestino e ripristino.

Step 4 - Parcheggio su assignment

Obiettivo: parcheggio come stato/assignment, non solo array di chiavi.

Flusso:

  • "metti in parcheggio" sposta assignment a tray;
  • "usa in domanda" crea o sposta assignment verso domanda;
  • mantenere PACK.photo_tray come compatibilita.

Test:

  • spostamento domanda -> parcheggio;
  • parcheggio -> altra domanda;
  • foto server;
  • foto locale.

Step 5 - Offline ops queue

Obiettivo: tutte le operazioni foto sono idempotenti e recuperabili.

Operazioni:

  • upload_pending;
  • delete_pending;
  • restore_pending;
  • move_pending;
  • park_pending;
  • trash_pending.

Ogni op:

  • op_id;
  • created_at;
  • device_id;
  • asset_id;
  • assignment_id;
  • from;
  • to;
  • status;
  • retry_count;
  • last_error.

Test:

  • offline upload + online retry;
  • offline delete + online sync;
  • offline move + online sync;
  • conflitto con draft server piu recente.

Step 6 - Stampa tecnica permissiva

Obiettivo: rimuovere blocco stampa per local/pending.

Comportamento:

  • se foto server: stampa normale;
  • se foto locale disponibile nel browser: preview locale se possibile;
  • se renderer server non puo vederla: placeholder;
  • se foto orfana: placeholder;
  • warning, ma non blocco.

Prima modifica da fare:

  • cambiare _rasV2ImmediatePrintBlockReason();
  • cambiare _rasEnsureV2ConsolidatedForPrint();
  • evitare disable pulsanti stampa per solo pending/local.

Test:

  • stampa con foto server;
  • stampa con foto locale;
  • stampa con foto pending;
  • stampa con orfana.

Step 7 - Eventuale server ledger

Solo dopo stabilita client.

Opzioni:

  • mantenere ledger dentro legacy_dynamic_draft.payload_json;
  • aggiungere tabelle dedicate;
  • endpoint operazioni foto.

Decisione rimandata.

Sequenza consigliata di lavoro

  1. Implementare Step 1 con test unitari JS estraibili o test testuali sul pack.
  2. Collegare solo upload nuova foto allo Step 2.
  3. Collegare cancellazione principale allo Step 3.
  4. Collegare galleria/parcheggio.
  5. Rendere stampa permissiva.
  6. Solo alla fine ripulire vecchie funzioni globali per chiave.

Cosa non fare

  • Non eliminare fisicamente blob server durante cancellazione domanda.
  • Non usare deleteImageKeyEverywhere() come comportamento standard v2.
  • Non bloccare stampa tecnica per foto locali.
  • Non nascondere errori/orfani: mostrarli come stato recuperabile.
  • Non togliere il parcheggio.