@esfaenza/flow-builder 20.3.53 → 20.3.55

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
@@ -141,7 +141,7 @@ sono opzionali e rifiutano con `MissingService` se non sovrascritti.
141
141
  | `createVersion(flowName, request?)` | astratto |
142
142
  | `activateVersion(flowName, version)` | astratto |
143
143
  | `deactivateFlow(flowName)` | astratto |
144
- | `cloneFlow`, `deleteVersion`, `deleteFlow` | opzionali — senza `cloneFlow` «Duplica» resta disponibile e ripiega su `createFlow` |
144
+ | `cloneFlow`, `deleteVersion`, `deleteFlow` | opzionali — senza `cloneFlow` «Duplica» resta disponibile e ripiega su `createFlow`; `deleteVersion` e' il comando del pannello versioni, mentre **`deleteFlow` non la chiama nessun componente**: eliminare un flow e' dell'ospite (vedi «Versioni») |
145
145
 
146
146
  | §6.3 Validazione | |
147
147
  |---|---|
@@ -162,7 +162,7 @@ sono opzionali e rifiutano con `MissingService` se non sovrascritti.
162
162
  | `listEnumTypes`, `listEvents`, `listSubflowCandidates` | astratti |
163
163
  | `describeObject` | opzionale |
164
164
  | `listFieldValues(object, field)` | opzionale — i valori ammessi di un campo a **scelta chiusa** (`hasClosedValueSet`, §6.4), cioe' l'altra meta' degli insiemi chiusi: quelli di un `Enum` sono del **tipo** (`listEnumValues`), questi della **colonna** — `Ordine.Stato` e `Attivita.Stato` possono ammettere valori diversi pur essendo due `String`, ed e' perche' serve la coppia. Lista vuota = "non lo so": il valore si scrive a mano |
165
- | `listFormulaFunctions(usage?)` | opzionale — le funzioni (e gli operatori, se il motore li dichiara) scrivibili in un'espressione: e' la **palette** di `<fb-formula-editor>`, la terza gamba accanto ai nomi (`getReferences`) e al giudizio (`validateFormula`). `usage` e' lo stesso di `validateFormula` e un motore che non filtra risponde comunque tutto, che e' legittimo. Due regole: lista vuota = «il motore non le dichiara» e la palette non compare (§4.6), e l'elenco **non e' autoritativo** — accusare una funzione fuori catalogo sarebbe un rilievo falso su una formula valida |
165
+ | `listFormulaFunctions(usage?)` | opzionale — le funzioni (e gli operatori, se il motore li dichiara) scrivibili in un'espressione: e' la **palette** di `<fb-formula-editor>`, la terza gamba accanto ai nomi (`getReferences`) e al giudizio (`validateFormula`). `usage` e' lo stesso di `validateFormula` e un motore che non filtra risponde comunque tutto, che e' legittimo. Due regole: lista vuota = «il motore non le dichiara» e la palette non compare (§4.6), e l'elenco **non e' autoritativo** — accusare una funzione fuori catalogo sarebbe un rilievo falso su una formula valida. `requiresPriorValues` marca le funzioni sui valori precedenti del record: la palette le toglie dove un «prima» non c'e' (§6.3) |
166
166
  | `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 |
167
167
  | `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**) |
168
168
 
@@ -428,6 +428,28 @@ rifiuta. Quattro conseguenze:
428
428
  salvataggio» (`START_RECORD_TRIGGER_MISSING`), operazione su un flow che non è innescato da un
429
429
  record è inerte (`START_RECORD_TRIGGER_IGNORED`).
430
430
 
431
+ **I valori precedenti del record non ci sono sempre (§7).** Chi li legge — l'operatore `IsChanged`,
432
+ un riferimento radicato su `$Record__Prior`, il flag `doesRequireRecordChangedToMeetCriteria` — vale
433
+ quanto l'**operazione** che innesca il flow, non quanto il momento. È l'unico codice con **tre**
434
+ gravità: sull'aggiornamento i valori ci sono a ogni esecuzione e non c'è niente da dire; su
435
+ «creazione e aggiornamento» sulla creazione non ci sono, e lì la condizione non è valutabile — il
436
+ flow funziona a metà, quindi `Warning`; sulla creazione e sull'eliminazione non ci sono mai e a
437
+ runtime l'interview **fallisce** davanti a chi stava salvando, quindi `Error`. Su un flow che non è
438
+ innescato da un record resta un avviso: i valori può passarli chi avvia l'interview.
439
+
440
+ La regola sta in `core/record-trigger.ts` — `priorValuesOfDefinition`, `priorValuesSeverity`,
441
+ `priorCriteriaSeverity` — ed è esportata perché la applicano i due capi: l'editor la dice **mentre
442
+ si scrive** la condizione (condition editor, editor dei filtri, reference picker), il backend la
443
+ emette come `PRIOR_VALUES_NOT_AVAILABLE`. Tre conseguenze:
444
+
445
+ - il flag dei criteri di ingresso è l'eccezione: il runtime lo **ignora** invece di fallire, quindi
446
+ non è mai un errore, e su «creazione e aggiornamento» non è nemmeno un rilievo;
447
+ - nel reference picker `$Record__Prior` ha uno stato suo, guardato **prima** degli altri: un host
448
+ che smette di proporre quello scope — ed è giusto che lo faccia dove i valori non ci sono mai — lo
449
+ farebbe altrimenti cadere in «questo nome non esiste», che manda a cercare un nome sbagliato;
450
+ - le **formule** restano fuori: un'espressione che cita `$Record__Prior` non è analizzabile lato
451
+ client, perché la sintassi la conosce solo il motore (§6.3).
452
+
431
453
  **L'attivazione, e la sua seconda meta' (§8).** I tre tipi che non partono da soli vanno **presi in
432
454
  carico** dall'infrastruttura dell'ospite — uno scheduler, un bus, un intercettore delle scritture — e
433
455
  il backend li registra prima di attivare. Da lì due esiti che il pannello dei problemi non spiega,
@@ -642,6 +664,17 @@ ripulitura e' un comando («Togli»), non un effetto dell'apertura del form: can
642
664
  un flow scritto altrove farebbe sparire l'unico indizio di cosa doveva selezionare. Il rilievo si
643
665
  vede in **tutti e due** i posti, elenco e form, come gli altri controlli locali.
644
666
 
667
+ *Da dove vengono i due campi su una collection.* Su `collectionReference` non c'e' nessun `object` a cui
668
+ chiedere i campi: i nomi citabili sono quelli del **tipo degli elementi**, che il form legge da
669
+ `getReferences` (`dataType` + `objectType` della collection scelta, output automatici compresi) — un
670
+ `Object` propone i campi dell'entita', una `Structure` i membri della classe, la stessa strada del
671
+ campo da sommare di un Transform. Su questa sorgente **nessuno dei due e' obbligatorio** (su una
672
+ collection di scalari vanno lasciati vuoti) e la validazione **non li verifica**: un nome sbagliato
673
+ ricade in silenzio sull'elemento intero. Per questo l'elenco si propone davvero, e un nome fuori
674
+ elenco si dice come **avviso senza codice** (`unverified` dello structure member picker): accusarlo
675
+ con `STRUCTURE_MEMBER_UNKNOWN` prometterebbe un rilievo che il backend lì non emette. `object` resta
676
+ vuoto: valorizzarlo per far funzionare il picker sarebbe `CHOICE_SET_SOURCE_AMBIGUOUS`.
677
+
645
678
  *La logica dei filtri.* `filterLogic` **esiste anche sui choice set**, con le stesse forme degli
646
679
  elementi che interrogano il database: `AND` (o assente), `OR`, oppure l'espressione sugli indici
647
680
  1-based dei filtri (`1 AND (2 OR 3)`), che l'editor verifica mentre si scrive e **riscrive** quando
@@ -794,7 +827,15 @@ Due cose che non si devono confondere: elenco vuoto significa «il motore non le
794
827
  il bottone non compare affatto invece di aprire un pannello vuoto; e l'elenco **non e'
795
828
  autoritativo** — a giudicare resta `validateFormula`, e accusare una funzione fuori catalogo
796
829
  sarebbe un rilievo falso su una formula valida, perche' un motore puo' supportare piu' di quanto
797
- dichiara. `signature` e `description` si mostrano e non si parsano: la grammatica resta del motore. Lo usano tutti i punti in cui si scrive
830
+ dichiara. `signature` e `description` si mostrano e non si parsano: la grammatica resta del motore.
831
+ Il solo filtro che la palette applica da sé è `requiresPriorValues` (§6.3): le funzioni che leggono i
832
+ **valori precedenti** del record — `PRIORVALUE`, `ISCHANGED` — non si propongono dove un «prima» non
833
+ c'è mai (creazione, eliminazione) né dove non c'è un record che innesca; su «creazione e
834
+ aggiornamento» restano, perché la metà aggiornamento le usa. La regola è quella di
835
+ `core/record-trigger.ts`, la stessa che il backend applica quando il suo endpoint riceve il
836
+ documento — la `GET` proposta dal contratto non lo porta, quindi filtrare qui è ciò che la fa
837
+ funzionare comunque; e resta una **proposta**, perché a giudicare una `PRIORVALUE` scritta a mano è
838
+ sempre `validateFormula`, con il codice che il motore dichiara. Lo usano tutti i punti in cui si scrive
798
839
  un'espressione: la risorsa `Formula`, la modalita' Formula di una condizione, la `filterFormula`
799
840
  di un filtro, la regola di validazione di un campo di screen dinamico e il `formulaExpression`
800
841
  dentro un valore. A ogni punto corrispondono un `usage` e un `expectedDataType` — `Boolean` per
@@ -911,6 +952,19 @@ flow da sé (come la demo) il tipo lo chiede lì, e lo passa a `emptyFlowDefinit
911
952
  attivazione bloccata finche' ci sono errori, eliminazione dietro una conferma esplicita che
912
953
  spiega il rischio per le esecuzioni sospese.
913
954
 
955
+ **Eliminare il flow intero e' dell'ospite.** Il pannello versioni si ferma alla **versione**: il
956
+ flow lo toglie chi integra, perche' il builder edita un flow già aperto e l'elenco da cui toglierlo
957
+ e' suo. La primitiva e' `deleteFlow` (§6.2, opzionale) e la sequenza e' la parte che leggendo
958
+ l'interfaccia non si indovina: `DELETE /flows/{name}` e' **rifiutata finche' esiste una versione
959
+ attiva**, quindi dove c'e' si chiama prima `deactivateFlow`. Sono due chiamate e non una
960
+ transazione — se la seconda fallisce il flow resta lì, **disattivato**, e l'elenco va ricaricato
961
+ anche sull'errore, altrimenti mostra uno stato che sul backend non esiste piu'. Disattivare ed
962
+ eliminare cancellano anche la presa in carico presso l'infrastruttura (§8), quindi di qui tornano gli
963
+ stessi due errori dell'attivazione: con `MissingService` il comando si spegne — e' così che degrada
964
+ una primitiva concreta — con `RegistrationFailed` il flow c'e' ancora e «riprova» ha senso.
965
+ L'esempio, con la conferma in due passi, sta nella demo
966
+ ([`app.component.ts`](../flow-builder-example/src/app/app.component.ts)).
967
+
914
968
  **Duplica.** Il flow salvato sotto un altro nome, alla versione 1 (§6.2): il comando chiede nome
915
969
  tecnico e nome visibile della copia, e l'editor **continua sulla copia** — restare sull'originale
916
970
  farebbe finire il salvataggio successivo nel flow sbagliato. Due strade, e la differenza conta: