@esfaenza/flow-builder 20.3.21 → 20.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # flow-builder
2
2
 
3
3
  Editor visuale per i flow descritti in [`FRONTEND.md`](../../FRONTEND.md): un componente
4
- **standalone Angular** che disegna il grafo, edita ogni tipo di elemento, valida, versiona e
5
- prova un flow.
4
+ **standalone Angular** che disegna il grafo, edita ogni tipo di elemento, valida, versiona un
5
+ flow e ne consegna l'esecuzione all'applicazione ospite.
6
6
 
7
7
  Requisiti: **Angular ≥ 18** (sviluppato e verificato su 19.2), TypeScript.
8
8
 
@@ -146,9 +146,10 @@ sono opzionali e rifiutano con `MissingService` se non sovrascritti.
146
146
  | `listEnumValues(enumType)` | opzionale — i **valori** di un tipo di enumerazione, cioe' i nomi scrivibili in `enumValue` (§4.2, §4.6). `listEnumTypes` e' l'altra meta' e non basta: quella dice quali tipi esistono, questa quali valori ha un tipo. `enumType` e' esattamente l'`objectType` della risorsa, del parametro o del **membro** di una classe (§4.7.1): la risposta e' del tipo, non del punto di uso, e la cache e' per nome del tipo. Lista vuota = "non lo so" — il valore si scrive a mano, e un tipo sconosciuto risponde vuoto, non 404 |
147
147
  | `listStructures`, `describeStructure(className)` | opzionali — le classi e i loro membri per le risorse `Structure` (§4.7). `listStructures` e' l'**elenco delle classi** senza membri; `describeStructure` restituisce la **descrizione** di una classe (`className`, `label`, `members`), non un array nudo (§4.7.1). Senza, le classi non sono verificabili e il nome si scrive a mano: "non lo so", non "non esiste". I tre esiti sono distinti: `members` popolato = elenco autorevole, `members: []` = membri non dichiarati (si digita, nessuna accusa), rifiuto `StructureNotFound` = classe non registrata (si segnala la **classe**) |
148
148
 
149
- | §6.5 Esecuzione | |
149
+ | Esecuzione dall'editor | |
150
150
  |---|---|
151
- | `startInterview`, `respondToScreen`, `resumeInterview`, `inspectInterview`, `abandonInterview` | opzionalisenza, il pannello «Prova» segnala che la funzione non c'e' |
151
+ | `runFlow(request)`, `debugFlow(request)` | opzionali — i comandi **Esegui** e **Debug** della barra. Non sono primitive del contratto: l'editor raccoglie i valori di ingresso in una finestra e passa la mano all'ospite, che sa dove gira il motore. Senza implementazione il comando fallisce con `MissingService` e l'editor lo dice non finge un avvio. Sono due metodi e non un flag perche' quasi sempre sono due strade diverse, e perche' un ambiente puo' esporre l'una senza l'altra. **Il ritorno e' facoltativo e conta**: un `FlowRunOutcome` finisce nel pannello «Debug» dell'editor stato, traccia, risorse, output — mentre `void` significa «guardo altrove». Restituirlo e' quasi obbligatorio sui flow **senza schermate**, dove non esiste nessun'altra interfaccia in cui vedere cos'e' successo |
152
+ | `startInterview`, `respondToScreen`, `resumeInterview`, `inspectInterview`, `abandonInterview` | opzionali — le primitive §6.5 dell'interview. **L'editor non le usa**: servono a chi implementa `runFlow`/`debugFlow` con un runner proprio (la demo lo fa) |
152
153
  | `completeStageStep(request)` | opzionale — conclude uno step di orchestrazione (§5.14) |
153
154
 
154
155
  **Errori.** Ogni metodo, in caso di rifiuto, deve fallire con un `FlowApiError`
@@ -505,13 +506,32 @@ versione **salvata** e le modifiche appena scritte spariscono senza dirlo. La st
505
506
  ripiego dove `cloneFlow` non c'e' (e' opzionale). Un nome già usato lo rifiuta il backend con
506
507
  `AlreadyExists`, e il modulo resta aperto sul nome da correggere.
507
508
 
508
- **Prova.** Interview con form generato dalle variabili di input, form generico per gli screen
509
- (valori in ingresso più i campi da restituire), `canGoBack` / `canFinish` / `canPause` come
510
- verita' runtime, traccia navigabile e tabella delle risorse con l'avviso in chiaro che la
511
- traccia riporta anche i dati personali. Su un'orchestrazione sospesa distingue le due attese
512
- (`isWaitingForEvent` / `isWaitingForStageStep`) e consente di concludere uno step al posto
513
- dell'assegnatario, rifiuto compreso: la risposta puo' portare una `interviewKey` **nuova**, e il
514
- pannello sostituisce quella vecchia invece di conservarla.
509
+ **Esegui e Debug.** Due comandi nella barra e una finestra: il form dei valori di ingresso,
510
+ generato dalle variabili `isInput` del documento tipo dichiarato rispettato anche in scrittura,
511
+ istanze di classe compilate un membro alla volta (§4.7), enum per **nome** da `listEnumValues`
512
+ (§4.6). Un campo lasciato vuoto non viene mandato: non valorizzato e stringa vuota sono cose
513
+ diverse. Poi l'editor **passa la mano**: chiama `runFlow` o `debugFlow` e non esegue niente per
514
+ conto suo. Si esegue la versione **salvata**, quindi i comandi sono spenti su un flow mai scritto
515
+ e la finestra avverte quando ci sono modifiche non salvate. Senza implementazione — categoria
516
+ `MissingService` — il banner dice quale delle due primitive manca, con parole comprensibili a chi
517
+ ha appena premuto «Esegui».
518
+
519
+ **Il pannello «Debug».** Cosa l'ospite ha restituito dall'ultima esecuzione: stato, output,
520
+ traccia degli elementi eseguiti — ogni riga porta all'elemento sul canvas — e risorse. Esiste per
521
+ un caso che altrimenti non ha risposta: un flow **senza schermate** (`AutoLaunched`, o
522
+ un'orchestrazione tutta in background) non apre nessuna interfaccia del runtime, quindi senza
523
+ questo pannello non ci sarebbe **nessun** posto in cui vedere cosa e' successo. `trace` e
524
+ `resources` arrivano solo con `debug: true` (§6.5), e riportano i valori di tutte le risorse —
525
+ dati personali compresi: l'avviso e' in chiaro. Il pannello non conduce niente: guarda, e basta.
526
+
527
+ Come si implementa l'altra metà si vede nella demo
528
+ (`projects/demo/src/app/runner`), e la scelta interessante e' **quando** aprire una finestra: un
529
+ flow che non ha niente da chiedere finisce da solo e l'esito torna subito all'editor, mentre uno
530
+ interattivo apre il runner e restituisce l'ultimo risultato alla chiusura — così la traccia resta
531
+ comunque lì dove si stava lavorando. Il runner guida l'interview con le primitive della §6.5,
532
+ distingue le due attese di `Suspended` (`isWaitingForEvent` / `isWaitingForStageStep`), conclude
533
+ uno step al posto dell'assegnatario — rifiuto compreso, con la `interviewKey` nuova che sostituisce
534
+ la vecchia — e mostra traccia e risorse solo in debug, dove riportano anche i dati personali.
515
535
 
516
536
  **Import/export.** Export JSON indentato; import via `POST /flows/parse`, che normalizza il
517
537
  documento o lo rifiuta con `InvalidDefinition`.
@@ -544,7 +564,7 @@ src/lib/
544
564
  screen-field.util.ts l'albero dei campi di uno screen dinamico: percorsi, nomi, mutazioni
545
565
  ui/
546
566
  flow-builder.component.ts il componente da montare
547
- canvas/ palette/ inspector/ resources/ problems/ versions/ debug/ shared/
567
+ canvas/ palette/ inspector/ resources/ problems/ versions/ run/ debug/ shared/
548
568
  styles/
549
569
  flow-builder.css variabili del tema, controlli di form, stili degli archi
550
570
  ```
@@ -635,7 +655,7 @@ distribuire e nessuna dipendenza da un font di icone dell'applicazione ospite.
635
655
  | 9 | `Step` ed `Experiment` non sono supportati; `OrchestratedStage` lo e' | I due non supportati sono filtrati dalla palette via `isSupported` e, se arrivano da un import, l'inspector li mostra in sola lettura spiegando perche'. Lo stage ha il suo form: step non presentati come sequenza, e la condizione che referenzia l'output di un altro step segnalata con la via d'uscita |
636
656
  | 10 | Un `Delete` senza filtri e' un **errore**, un `Update` senza filtri un **avviso** | `RecordWriteInspectorComponent`: severita' diverse, e l'update di massa chiede una conferma esplicita |
637
657
  | 11 | Non cablare enum e operatori | Ogni tendina legge da `getDictionaries()`; le mappe locali intervengono solo come fallback quando il dizionario non e' disponibile |
638
- | 12 | Il **token di continuazione e' opaco** | `DebugPanelComponent` lo rimanda tale e quale, non lo legge e non lo mette in nessun URL |
658
+ | 12 | Il **token di continuazione e' opaco** | Non lo tocca nessuno nella libreria: l'editor non esegue, quindi il token nasce e muore nel runner dell'ospite. Quello della demo (`projects/demo/src/app/runner/interview-runner.component.ts`) lo rimanda tale e quale, non lo legge e non lo mette in nessun URL |
639
659
  | 13 | **Testo e numero non si confrontano** (`CONDITION_TYPE_MISMATCH`) | `ConditionEditorComponent` conosce il tipo del lato sinistro da `POST /flows/references`: filtra gli operatori applicabili, guida il campo del letterale del secondo operando e segnala la coppia vietata. La regola sta in `core/condition-types.util.ts`, che salta gli operatori con semantica propria (`Contains`, `In`, …). I numeri si scrivono in cultura invariante: `1234,50` viene tradotto in `1234.50`, non troncato |
640
660
  | 14 | **`None` non e' un operatore, e' un "da completare"** | Condizione evidenziata come incompleta, con il conteggio in testa alla sezione e la frase «la bozza si salva, l'attivazione no»; il validatore della demo lo emette come **errore** |
641
661
  | 15 | **Un valore data senza `Z` significa ora locale** | `ValueEditorComponent` ha un selettore «Ora locale / UTC (Z)», dice che cambiare fuso riscrive l'orario e non lo converte, e toglie il suffisso solo per il controllo `datetime-local`, che con il fuso resterebbe vuoto |
@@ -673,7 +693,7 @@ possibile anche con errori e attivazione bloccata dagli errori (§8).
673
693
  (`elementFromPoint` per il contenitore piu' interno, i rettangoli dei fratelli per la
674
694
  posizione).
675
695
  - **L'esecutore della demo non valuta le condizioni**: prende il primo ramo disponibile e lo
676
- scrive nella traccia. È un mock per esercitare il pannello, non il motore.
696
+ scrive nella traccia. È un mock per esercitare il runner dell'ospite, non il motore.
677
697
  - **Nessun test automatico**: la libreria e' stata verificata a mano sull'app demo (canvas,
678
698
  inspector, salvataggio, attivazione, interview completa). Casi su `condition-logic.util`,
679
699
  `flow-name.util`, `element-outlets` e `FlowDocumentStore` sarebbero il primo investimento