From 1532ea0af7ec0ff8d220104610523c0b79e26177 Mon Sep 17 00:00:00 2001 From: JiriUhlir <149317995+JiriUhlir@users.noreply.github.com> Date: Mon, 7 Sep 2026 09:01:09 +0200 Subject: [PATCH] Automatizace zavirala tickety uz pri zvoneni MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Na instanci nebyl ani jeden nevyrizeny ticket: vsech 131 melo closed true, takze dlazdice "Moje tickety" i "Fronta bez resitele" ukazovaly nulu. Widget pocital spravne, spatna byla data. Strom se ptal `result neq "Chybějící informace"` a ve vetvi ANO ticket zaviral. Jenze jeden hovor posle vic zprav a ta prvni jen ohlasi, ze zacal: data je null, takze {{result}} je prazdne. evaluate prevadi chybejici hodnotu na prazdny retezec, a prazdno se opravdu nerovna "Chybějící informace" - podminka tedy sedla a ticket se zavrel uz pri zvoneni. Odtud i druha vec: prirazovaly se i tickety, ktere nemely. Jedna zprava hovoru mela result "Chybějící informace", takze ticket sel na servicedesk a na cloveka. Dalsi zprava tehoz hovoru prinesla "Přesměrování" a ticket zavrela, ale resitele uz neodebrala. Z dvaceti ticketu prirazenych jednomu cloveku jich melo "Chybějící informace" jen deset. Opraveny strom se nejdriv pta, jestli vysledek vubec prisel, a teprve pak kladne, jestli je to "Chybějící informace": result isNotEmpty ANO result eq "Chybějící informace" ANO priorita vysoka, sekce Servicedesk, prirazeni nejvolnejsimu NE zavrit NE nic, vysledek jeste nedorazil Puvodni neq znamenalo "vsechno ostatni vcetne toho, co jeste nevime". To je u nepovinneho parametru, ktery dorazi az pozdejsi zpravou, past. Radek podminky v logu rikal jen "splneno". Ted nese i to, s cim se porovnavalo, a rozlisuje nedorazilo od prazdneho - prvni radek je presne ta informace, ktera chybela: Podmínka: result isNotEmpty: nesplněno | result = nedorazilo Podmínka: result eq Chybějící informace | result = "Přesměrování", porovnáno s "Chybějící informace" Overeno prehranim celeho hovoru na bezici instanci: prvni zprava bez dat ticket zalozi a nechá otevreny, druha s "Chybějící informace" ho preda a priradi, treti s "Přesměrování" ho zavre. Pred opravou byl vyrizeny uz po prvni zprave. Zustava k rozhodnuti: pri prehodnoceni hovoru resitel na zavrenem ticketu zustane. Do "Mych ticketu" nespadne, ty ukazuji jen nevyrizene, ale ve vsech ticketech u nej to jmeno stoji. Co-Authored-By: Claude Opus 5 --- documentation/20-fronta-a-runtime.md | 22 +++++++ documentation/99-zmeny.md | 69 ++++++++++++++++++++++ src/data/automationStore.ts | 85 ++++++++++++++++++++-------- src/runtime/executor.ts | 38 ++++++++++++- 4 files changed, 188 insertions(+), 26 deletions(-) diff --git a/documentation/20-fronta-a-runtime.md b/documentation/20-fronta-a-runtime.md index 850a974..7dbce46 100644 --- a/documentation/20-fronta-a-runtime.md +++ b/documentation/20-fronta-a-runtime.md @@ -209,3 +209,25 @@ Ověřeno 19 kontrolami proti běžícímu serveru. `scripts/http.ts` je. - **Dlouhé čekání** (pošli e-mail za tři dny) přes běh naplánovaný na později. Krok `flow/pause` umí nejvýš minutu, protože blokuje běh. + +## Podminka nad parametrem, ktery jeste nedorazil + +`evaluate` prevadi chybejici hodnotu na **prazdny retezec**. Pro porovnani je +tedy "nedorazilo" totez co "prazdne", a to je u nepovinneho parametru past: + +```text +result neq "Chybějící informace" +``` + +znamena "vsechno ostatni **vcetne toho, co jeste nevime**". Prvni zprava hovoru +vysledek nenese, podminka sedne a strom udela to, co mel udelat az na konci. + +**Ptat se kladne a napred na existenci:** `isNotEmpty`, a teprve uvnitr `eq`. + +Radek podminky v logu proto nese i to, s cim se porovnavalo, a rozlisuje +`nedorazilo` od `prázdné`: + +```text +Podmínka: result isNotEmpty: nesplněno | result = nedorazilo +Podmínka: result eq Chybějící informace | result = "Přesměrování", porovnáno s "Chybějící informace" +``` diff --git a/documentation/99-zmeny.md b/documentation/99-zmeny.md index 0b938f1..6083655 100644 --- a/documentation/99-zmeny.md +++ b/documentation/99-zmeny.md @@ -2,6 +2,75 @@ Nejnovejsi nahore. +## 2026-09-07 - Automatizace zavirala tickety uz pri zvoneni + +Na instanci nebyl ani jeden nevyrizeny ticket: **vsech 131 melo `closed: true`**, +takze dlazdice "Moje tickety" i "Fronta bez resitele" ukazovaly nulu. Widget +pocital spravne, spatna byla data. + +### Cim to bylo + +Strom se ptal `result neq "Chybějící informace"` a ve vetvi ANO ticket zaviral. + +Jenze jeden hovor posle vic zprav a **ta prvni jen ohlasi, ze zacal**: `data` je +null, takze `{{result}}` je prazdne. `evaluate` prevadi chybejici hodnotu na +prazdny retezec, a prazdno se opravdu nerovna "Chybějící informace" - podminka +tedy sedla a ticket se zavrel uz pri zvoneni. Vsechno ostatni, co pak prislo, +uz jen doplnovalo zavreny ticket. + +Odtud i druha vec: **prirazovaly se i tickety, ktere nemely.** Jedna zprava +hovoru mela `result: "Chybějící informace"`, takze ticket sel na servicedesk +a na cloveka. Dalsi zprava tehoz hovoru prinesla `"Přesměrování"` a ticket +zavrela, ale **resitele uz neodebrala**. Z dvaceti ticketu prirazenych jednomu +cloveku jich melo "Chybějící informace" jen deset. + +### Oprava stromu + +Nejdriv se ptame, jestli vysledek vubec prisel, a teprve pak **kladne**, jestli +je to "Chybějící informace": + +```text +result isNotEmpty + ANO result eq "Chybějící informace" + ANO priorita vysoka, sekce Servicedesk, prirazeni nejvolnejsimu + NE zavrit + NE nic, vysledek jeste nedorazil +``` + +Puvodni `neq` znamenalo "vsechno ostatni **vcetne toho, co jeste nevime**". +To je u nepovinneho parametru, ktery dorazi az pozdejsi zpravou, past. + +### Aby to slo poznat z logu + +Radek podminky rikal jen "splneno". Ted nese i to, **s cim se porovnavalo**, +a rozlisuje nedorazilo od prazdneho: + +```text +Podmínka: result isNotEmpty: nesplněno | result = nedorazilo +Podmínka: result eq Chybějící informace | result = "Přesměrování", porovnáno s "Chybějící informace" +``` + +Prvni radek je presne ta informace, ktera chybela. Bez ni log tvrdil, ze +podminka sedi, a nikdo nemel jak zjistit proc. + +### Overeno prehranim celeho hovoru + +| Zprava | Vysledek | +| ----------------------------- | ----------------------------------------------- | +| in-progress, bez dat | ticket vznikl, **neni vyrizeny**, bez resitele | +| completed, Chybějící informace| priorita vysoka, prirazen clenu Servicedesku | +| completed, Přesměrování | zavren | + +Pred opravou byl ticket vyrizeny uz po prvni zprave. + +### Co zustava k rozhodnuti + +Kdyz se hovor prehodnoti z "Chybějící informace" na neco jineho, ticket se +zavre, ale **resitel na nem zustane**. Do "Mych ticketu" uz nespadne, ty ukazuji +jen nevyrizene, ale ve vsech ticketech u nej to jmeno stoji. Odebrat resitele +pri zavreni by slo, jen na to zatim neni krok - `ticket/assign` bez resitele +skonci chybou. + ## 2026-09-02 - Nazev znacky uz neni v kodu natvrdo Server mel "Automia" napsanou primo v titulku Swaggeru a v OpenAPI - zbytek po diff --git a/src/data/automationStore.ts b/src/data/automationStore.ts index 168336e..edf761e 100644 --- a/src/data/automationStore.ts +++ b/src/data/automationStore.ts @@ -1106,39 +1106,74 @@ function seedRealAutomations(): void { priority: 'low', }, }, + /* + * **Nejdriv se ptame, jestli vysledek vubec prisel.** + * + * Jeden hovor posle vic zprav a ta prvni jen ohlasi, ze zacal: + * `data` je null, takze `{{result}}` je prazdne. Bez teto podminky + * spadlo prazdno rovnou do vetve "neni to Chybejici informace" + * a ticket se zavrel uz pri zvoneni. Na instanci to znamenalo, ze + * vsech 131 ticketu bylo vyrizenych a ve frontě nezustalo nic. + */ { id: 'st_mtjqwey5_4', kind: 'condition', fieldId: 'f_mtjqv4qj_1', - operator: 'neq', - value: 'Chybějící informace', - // Vyresene hovory se rovnou zaviraji. + operator: 'isNotEmpty', + value: '', yes: [ + /* + * Az ted se rozhoduje podle vysledku, a **kladne**: hledame + * "Chybejici informace". Puvodni `neq` znamenalo "vsechno + * ostatni vcetne toho, co jeste nevime". + */ { - id: 'st_mtjqx6t1_5', - kind: 'action', - serviceId: 'ticket', - operationId: 'upsert', - inputs: { - externalId: '{{callSid}}', - closed: 'true', - }, - }, - ], - // Chybejici informace jde na servicedesk a s vyssi prioritou. - no: [ - { - id: 'st_mtjqxs41_6', - kind: 'action', - serviceId: 'ticket', - operationId: 'upsert', - inputs: { - externalId: '{{callSid}}', - priority: 'high', - groupId: 'grp_servicedesk', - }, + id: 'st_mtml9001_2', + kind: 'condition', + fieldId: 'f_mtjqv4qj_1', + operator: 'eq', + value: 'Chybějící informace', + // Chybejici informace jde na servicedesk a s vyssi prioritou. + yes: [ + { + id: 'st_mtjqxs41_6', + kind: 'action', + serviceId: 'ticket', + operationId: 'upsert', + inputs: { + externalId: '{{callSid}}', + priority: 'high', + groupId: 'grp_servicedesk', + }, + }, + { + id: 'st_mtml8hx0_1', + kind: 'action', + serviceId: 'ticket', + operationId: 'assign-group', + inputs: { + groupId: 'grp_servicedesk', + autoAssign: 'true', + }, + }, + ], + // Hovor dopadl, ticket se zavira. + no: [ + { + id: 'st_mtjqx6t1_5', + kind: 'action', + serviceId: 'ticket', + operationId: 'upsert', + inputs: { + externalId: '{{callSid}}', + closed: 'true', + }, + }, + ], }, ], + // Vysledek jeste nedorazil. Ticket uz existuje, vic se ted delat nema. + no: [], }, ], }, diff --git a/src/runtime/executor.ts b/src/runtime/executor.ts index ba9a9da..082312d 100644 --- a/src/runtime/executor.ts +++ b/src/runtime/executor.ts @@ -151,7 +151,15 @@ export async function runFlow( ok: true, branch, summary: branch === 'yes' ? 'splněno' : 'nesplněno', - detail: null, + /* + * Do logu i to, **s cim se porovnavalo**. + * + * "splneno" samo nerekne nic. Kdyz podminka "vysledek neni + * Chybejici informace" sedla proto, ze vysledek jeste nedorazil + * a prazdno se opravdu nerovna, nikdo to z logu nepozna - a strom + * tise zavira tickety pri zvoneni. + */ + detail: conditionDetail(step, working, options), durationMs: 0, }); @@ -523,6 +531,34 @@ function conditionValue( return getPath(context, fieldId); } +/** + * Co se v podmince porovnavalo, do logu. + * + * Rozlisuje **nedorazilo** a **prazdne**: prvni je bezny stav u nepovinneho + * parametru, ktery prijde az pozdejsi zpravou, druhy je prazdny retezec. + * Pro porovnani jsou obe totez, pro cloveka, ktery hleda chybu, ne. + */ +function conditionDetail( + step: Extract, + context: RunContext, + options: RunOptions, +): string { + const raw = conditionValue(step.fieldId, context, options); + const name = options.fieldNames?.[step.fieldId] ?? step.fieldId; + + const got = + raw === undefined + ? 'nedorazilo' + : raw === null + ? 'null' + : stringify(raw) === '' + ? 'prázdné' + : JSON.stringify(stringify(raw)); + + if (isUnary(step.operator)) return `${name} = ${got}`; + return `${name} = ${got}, porovnáno s ${JSON.stringify(step.value ?? '')}`; +} + /** Vyhodnoti podminku nad kontextem. */ function evaluate( step: Extract,