Il punto di partenza.
Il dominio comprendeva sessioni archivistiche, tipologie, codici ente, storage input/output, pacchetti sorgente, pacchetti risultanti e lifecycle del workflow. Gli operatori avevano bisogno di un percorso pratico per capire come quei record si muovevano insieme.
La funzionalità doveva vivere in una piattaforma single-spa più ampia, che forniva già header, footer, navigazione e microfrontend riutilizzabili. Riutilizzare quei componenti era un obiettivo primario, non una rifinitura visiva successiva.
Un’applicazione React autonoma avrebbe duplicato la shell della piattaforma e creato un secondo punto di manutenzione per navigazione e chrome. Il confine utile era un’esperienza archivistica mirata che la piattaforma esistente potesse comporre.
Cosa doveva risolvere il design.
Il confine utile si trovava tra stato del processo, azione dell’operatore e piattaforma host:
- Sessione, pacchetti sorgente e output dovevano restare comprensibili lungo nove passaggi.
- Le azioni dell’operatore dovevano corrispondere a transizioni valide.
- La nuova esperienza doveva riutilizzare header, footer, navigazione e convenzioni dei componenti esistenti invece di distribuire una shell parallela.
- Il microfrontend React single-spa richiedeva un mount point e un contratto d’integrazione stretti, così le regole archivistiche non si disperdevano nell’host.
- Regole backend, stato Camunda e azioni frontend non potevano divergere in interpretazioni diverse dello stesso workflow.
La diagnosi.
Camunda poteva coordinare il processo, ma l’orchestrazione da sola non costituiva l’esperienza operativa. Mancava un confine applicativo coerente attorno al workflow.
La piattaforma host aveva già risolto composizione e chrome. Ricostruire quelle parti avrebbe aumentato il codice senza migliorare il workflow archivistico, quindi ho limitato il microfrontend alla superficie di dominio mancante.
Ho separato deliberatamente le responsabilità: l’host mantiene navigazione e componenti condivisi; Spring Boot possiede regole applicative, riferimenti storage S3-compatible e integrazione Camunda; il microfrontend React single-spa presenta stato corrente e azioni valide.
La sezione applicativa risultante.
La shell single-spa esistente monta il microfrontend React dentro header, footer e navigazione condivisi. Il microfrontend offre soltanto la superficie archivistica. Un servizio Spring mirato traduce le azioni in operazioni workflow e riferimenti storage, mentre Camunda coordina il processo dalla creazione della sessione al tracking dell’output.
Perché questi confini erano adatti alla piattaforma host.
Non era una selezione greenfield dello stack. Shell, motore di workflow e convenzioni di storage appartenevano a una piattaforma esistente; il compito era aggiungere una capacità coerente senza duplicare o aggirare quei confini.
Un servizio Spring Boot con un confine mirato
- Perché
- Il servizio assegnava a regole applicative, azioni valide, integrazione Camunda e riferimenti storage un solo proprietario backend. React poteva consumare un modello applicativo senza conoscere i meccanismi del motore di processo.
- Cosa ho escluso
- Chiamare Camunda direttamente dal browser o distribuire le regole archivistiche tra servizi condivisi avrebbe esposto dettagli di orchestrazione e creato più interpretazioni del comportamento valido.
- Quanto è costata
- L’API e il livello di mappatura aggiuntivi devono evolvere insieme al processo; gli errori tra servizio e motore richiedono una gestione esplicita.
Camunda per il processo in nove passaggi
- Perché
- Camunda coordinava già il workflow; mantenere lì le transizioni conservava una sola fonte dell’avanzamento, mentre il servizio traduceva quello stato per gli operatori.
- Cosa ho escluso
- Una macchina a stati personalizzata, soprattutto se rappresentata principalmente nello stato della UI, avrebbe duplicato la logica e messo il browser in concorrenza con il motore come autorità sul processo.
- Quanto è costata
- Definizioni del processo e modello applicativo devono restare allineati, e la diagnosi operativa attraversa sia il servizio sia il motore.
React nella composizione single-spa esistente
- Perché
- Un microfrontend circoscritto poteva riutilizzare header, footer, navigazione e convenzioni della piattaforma, possedendo soltanto la route archivistica e il suo modello d’interazione.
- Cosa ho escluso
- Riscrivere la shell o distribuire un’applicazione React autonoma avrebbe ampliato il progetto oltre la capacità mancante e creato navigazione e chrome duplicati da mantenere.
- Quanto è costata
- Il microfrontend dipende da un contratto stabile di montaggio e integrazione; i cambiamenti condivisi richiedono coordinamento invece di un controllo completamente locale.
Storage S3-compatible per pacchetti di input e output
- Perché
- Il contenuto dei pacchetti restava al confine dello storage a oggetti, mentre servizio e workflow lo referenziavano, separando record archivistici e responsabilità dei payload binari.
- Cosa ho escluso
- Blob nel database avrebbero legato i pacchetti al ciclo di vita dei dati relazionali; file locali li avrebbero legati a una specifica istanza del servizio e al suo percorso di deploy.
- Quanto è costata
- Bucket, endpoint, credenziali e casi di oggetto mancante diventano responsabilità operative esplicite che il servizio deve rappresentare con chiarezza.
Regole per un workflow realmente operativo.
L’architettura offre una sola fonte di verità sul processo; queste regole la trasformano in un’esperienza che l’operatore può leggere, considerare affidabile e riprendere dopo un problema.
Mostrare lo stato prima dell’azione
La sessione corrente, i pacchetti sorgente e risultanti e la fase del processo restano visibili prima che l’operatore scelga il passaggio successivo. Un’azione priva di questo contesto non viene presentata come progresso.
Il compromessoL’interfaccia deve spiegare gli stati indisponibili, in attesa e falliti invece di ottimizzare soltanto il percorso ideale.
Derivare le azioni valide dallo stato del backend
L’interfaccia presenta le transizioni supportate dal modello applicativo, mentre il servizio rifiuta quelle non valide. Lo stato locale del browser non diventa mai una seconda autorità sul passaggio successivo.
Il compromessoLo scambio e l’aggiornamento dello stato devono essere espliciti, ma una schermata obsoleta non può inventare un passaggio valido.
Preservare la continuità tra sessione e pacchetti
La sessione, i pacchetti sorgente e quelli risultanti restano collegati lungo il percorso in nove fasi. La verifica segue lo stesso viaggio, dalla creazione e associazione fino all’elaborazione e al tracciamento dell’output.
Il compromessoIl modello e l’interfaccia trasportano più contesto di una schermata dedicata a un solo task, ma l’operatore può seguire il legame tra il lavoro e il suo risultato.
Rendere visibili errore e nuovo tentativo
Uno stato incompleto, in attesa o fallito resta visibile. Se l’azione successiva valida permette di riprovare o proseguire, viene mostrata soltanto dopo la conferma del backend.
Il compromessoAumentano gli stati e i percorsi di errore da spiegare, ma attesa, fallimento e ripresa restano distinti invece di lasciare l’operatore nell’incertezza.
Delivery e verifica.
La verifica segue i nove passaggi operativi: creare la sessione, collegare i pacchetti sorgente, avviare il workflow, osservare le transizioni valide e seguire i pacchetti in output.
Ho verificato anche il confine di composizione: la nuova route doveva vivere dentro header, footer e navigazione esistenti senza introdurre una seconda shell o spingere lo stato archivistico nei componenti condivisi.
Gli altri casi critici sono ai confini. Il servizio deve rifiutare transizioni non valide, la UI deve mostrare con onestà stati incompleti o in attesa e l’integrazione deve mantenere il processo come fonte dello stato.
Il risultato qualitativo.
La sezione risultante copre gestione delle sessioni, elaborazione dei pacchetti e controllo del workflow, dall’interfaccia dell’operatore fino al processo Camunda.
Gli operatori hanno un solo luogo in cui capire il lavoro e farlo avanzare. La piattaforma mantiene header, footer, navigazione e convenzioni visive già conosciute.
La piattaforma ottiene una capacità contenuta invece di un’applicazione parallela: nessuna shell duplicata, nessun secondo modello di navigazione e nessuna regola archivistica distribuita tra microfrontend non correlati.
Organizzazione, prodotto, tipologie interne, endpoint, bucket, credenziali e date di consegna sono omessi. Il ciclo operativo deriva dal record di progetto.