Obsah ticketu, nastaveni kroku a vystupy kroku

Ticket dostal telo (body) a odkaz na zdrojovou zpravu. Predmet je shrnuti,
telo je cely text pozadavku.

Akce maji nastavitelna pole (inputs) se sablonami {{parametr}}. Zatim ticket,
kanaly, CRM a AI, ostatni maji jen napovedu.

Krok vidi parametry spoustece plus vystupy kroku pred nim, takze jde vlozit
predvalidaci a vetvit se podle jejiho vysledku. Vetev podminky nepridava nic
do sekvence za podminkou.

Nove konektory Facebook Messenger a Instagram, nova akce RAYNET Dohledat firmu.

Ctyri vzorove automatizace v rozdeleni jedna na kanal pro prijem
a jedna spolecna pro smerovani na resitele.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
JiriUhlir
2026-08-03 12:29:26 +02:00
parent 52b190bfbc
commit dd021b5f69
24 changed files with 1651 additions and 80 deletions
+155 -4
View File
@@ -2,9 +2,9 @@
## Co ticket je a co neni
Ticket je **prichozi pozadavek odkudkoliv**. Prisla zprava na WhatsApp, prisel
e-mail, nekdo zavolal na hlasovou linku, odeslal formular. Z toho vznikne ticket,
ktery ma sveho cloveka a dohledatelny prubeh.
Ticket je **prichozi pozadavek odkudkoliv**. Prisla zprava na WhatsApp, Messenger
nebo Instagram, prisel e-mail, nekdo zavolal na hlasovou linku, odeslal formular.
Z toho vznikne ticket, ktery ma sveho cloveka a dohledatelny prubeh.
Ticket **neni** bug ani wish. Vyvojarska agenda je jina vec s jinym zivotnim
cyklem a v prototypu zatim neexistuje. Michat je do jedne evidence by znamenalo,
@@ -31,6 +31,8 @@ a **co ktera sluzba vratila**. Kdyz neco nesedi, neni potreba hadat.
interface Ticket {
id: string;
subject: string;
body: string; // cely text pozadavku, prazdny = krok ho nenaplnil
sourceRef: string | null; // odkaz na zdrojovou zpravu u poskytovatele
channel: 'whatsapp' | 'email' | 'voice' | 'form' | 'portal';
customer: TicketCustomer;
status: 'new' | 'open' | 'waiting' | 'resolved';
@@ -53,6 +55,11 @@ interface TicketCustomer {
ve strome automatizace. Bez toho by nesla postavit vetev "firmu neznam, zaloz
obchodni pripad a nekomu to dej".
`subject` je kratke shrnuti do seznamu, `body` je cely text pozadavku. Do `body`
patri telo e-mailu, zprava z WhatsApp nebo prepis hovoru. Kdyz je prazdne,
znamena to, ze krok "Zalozit ticket" nemel nastavene pole Obsah - detail ticketu
to napise nahlas misto toho, aby ukazal prazdne misto.
Uvnitr ulozista se drzi jen `assigneeId`, jmeno se dopocitava pri cteni. Kdyz
resitel ze seznamu zmizi, ticket nespadne - jen se zaloguje a tvari se jako
neprirazeny.
@@ -146,6 +153,125 @@ Prijata zprava z WhatsApp
NE Zalozit ticket, Zalozit obchodni pripad, Upozornit servicedesk
```
## Co se ticketu preda
Akce "Zalozit ticket" ma nastavitelna pole. Klikni na krok ve strome a vyplnis
je primo tam. Hodnota je **sablona**: `{{nazev}}` se nahradi parametrem
spoustece.
| Pole | Typicka hodnota u WhatsApp |
| ------------ | --------------------------------- |
| Predmet | `Zprava od {{profileName}}` |
| Obsah | `{{text}}` |
| Firma | necha se prazdne, doplni CRM krok |
| Kontakt | `{{profileName}}` |
| Odpoved na | `{{phone}}` |
| Priorita | vyber ze seznamu |
| Resitel | vyber ze seznamu lidi |
Nabidka parametru je pod poli. Kliknuti vlozi `{{nazev}}` na pozici kurzoru,
takze se nemusi psat rucne a neudela se preklep.
Vyber resitele se plni ze seznamu v `people.ts`, ne z rucne psaneho ID. Novy
clovek v tymu se v nabidce objevi sam.
## Co je kde videt
Krok vidi **parametry spoustece plus vystupy vsech kroku, ktere jsou pred nim**.
Diky tomu jde do stromu vlozit predvalidaci a vetvit se podle jeji odpovedi.
Dve pravidla:
- krok vidi to, co je pred nim ve stejne sekvenci, a to, co videl jeho rodic,
- **vetev podminky nepridava nic do sekvence za podminkou**. Vetev nemusela
probehnout, spolehat se na jeji vystup by byla past.
Vystupy akci deklaruje katalog v `outputFields`. Ma je napriklad "Dohledat firmu"
(`customerKnown`, `companyId`, `companyName`), "Zaradit do kategorie"
(`category`, `confidence`) nebo "Zalozit ticket" (`newTicketId`).
Vypocet je v `src/data/flowScope.ts`, kopie pro UI v `web/src/lib/flow.ts`.
## Jak udelat podminku
Tri ruzne pripady, kazdy se resi jinak.
**Na prichozi zpravu.** `text` je parametr spoustece, funguje rovnou:
```
Prijata zprava z WhatsApp
text obsahuje "faktura"
ANO ...
```
**Na vysledek mezikroku.** Tohle je ta predvalidace. Krok "Dohledat firmu" vrati
`customerKnown` a podminka se na nej zepta:
```
Prijata zprava z WhatsApp
Dohledat firmu Telefon {{phone}}
customerKnown je splneno
ANO Zalozit ticket Firma {{companyName}}, Obsah {{text}}
NE Zalozit ticket bez firmy
Zalozit obchodni pripad
```
`{{companyName}}` je uvnitr vetve dostupne, protoze krok "Dohledat firmu" je
pred podminkou. Presne tenhle strom je ve vzorovych automatizacich.
**Na obsah uz zalozeneho ticketu.** Ve stejnem strome nejde, ticket v tu chvili
teprve vznika a "Zalozit ticket" vraci jen `newTicketId`, ne cely ticket. Dela se
**druhou automatizaci** se spoustecem "Zalozen ticket":
```
Zalozen ticket
assigned neni splneno
ANO body obsahuje "faktur"
ANO Priradit resiteli ID {{ticketId}}, Martin Kriz
NE body obsahuje "voicebot"
ANO Priradit Eva Novakova
NE Priradit Karel Vomacka
```
Rozdeleni neni obchazeni omezeni, ale zamer. Prijem z kanalu je jedna
automatizace na kanal, smerovani je jedna spolecna nad vsemi tickety.
## Vzorove automatizace
V `automationStore.ts` jsou nasazene presne v tomhle rozdeleni:
| Automatizace | Co ukazuje |
| -------------------------------- | --------------------------------------------- |
| WhatsApp: zprava do ticketu | predvalidace v CRM a vetveni podle vysledku |
| Facebook: zprava do ticketu | prijem bez predvalidace, nemame podle ceho hledat |
| E-mail: pozadavky do ticketu | dohledani podle `{{from}}`, plus odpoved zadavateli |
| Smerovani ticketu na resitele | jedna spolecna logika nad vsemi tickety |
Prijmove automatizace zamerne **neprirazuji resitele**. Nechavaji ticket ve
fronte a smerovani si ho prevezme. Podminka `assigned neni splneno` na zacatku
smerovani zaridi, ze rucni prirazeni se neprepise.
## Sablony
Odkazuje se **jmenem** parametru (`{{subject}}`), ne jeho ID. Jmeno uzivatel
vidi a pise, `{{f_42}}` by nikdo neprecetl.
Cenou je, ze prejmenovani parametru sablonu rozbije. Proto se to hlida:
- builder podtrhne pole a napise, ktery parametr chybi,
- server to vraci mezi `issues`, tedy jako **nedodelek**, ne jako chybu.
Rozdelana prace se ulozi, jen automatizace nepujde zapnout.
Naopak **chyba (400)** je nastaveni pole, ktere akce v katalogu nema. To uz neni
nedodelek, ale rozbity strom - ulozit ho by znamenalo drzet data, ktera nikdo
neprecte.
Chybejici parametr se pri behu dosadi jako prazdny retezec a zaloguje. Nechat
v textu `{{neco}}` by znamenalo poslat to zakaznikovi.
Akce, ktere `inputs` zatim nemaji, to v builderu napisou primo na karte kroku.
Lepsi nez nechat cloveka hledat nastaveni, ktere neexistuje.
## Parametry od sluzby
Nektere spoustece si data urcuji samy. E-mail posila `from`, `subject`, `body`.
@@ -173,12 +299,37 @@ parametry si deklaruje uzivatel.
/dashboard/tickety/:id detail: prubeh a log, resitel, zakaznik, puvod
```
## Otevrene rozhodnuti pro runtime
Model nema zadne "prvni shoda vyhrava". **Vsechny automatizace se stejnym
spoustecem se spusti, vsechny.** Podminka je uvnitr stromu, ne na spousteci,
takze automatizaci nezastavi pred prvnim krokem.
Doporucene rozdeleni (jedna automatizace na kanal, jedna spolecna na smerovani)
na to nenarazi, protoze kazdy prijem ma jiny spoustec a smerovani je jen jedno.
Problem vznikne, jakmile nekdo udela vic automatizaci nad stejnym spoustecem:
- tri automatizace na "Prijat e-mail", kazda s jinym `obsahuje`, udelaji
z jednoho e-mailu tri tickety,
- dve smerovaci automatizace provedou dve prirazeni a poradi neni dane.
Dnes se to neprojevi, protoze runtime neexistuje. Az se bude psat, je potreba
to rozhodnout vedome, ne omylem. Varianty od nejlevnejsi:
1. **Nechat jak je** a drzet se pravidla jedna automatizace na spoustec.
Funguje dnes, nic se nemeni, ale nikdo to nevynucuje.
2. **Filtr na spousteci.** Automatizace by umela rict "tenhle e-mail neni muj"
jeste pred prvnim krokem. Umozni jednu automatizaci na pravidlo.
3. **Poradi a prvni shoda vyhrava.** Nejmocnejsi, ale chovani zavisle
na neviditelnem poradi se spatne ladi. Nedoporucuje se.
## Co chybi
| Chybi | Poznamka |
| ---------------------------- | ------------------------------------------------------- |
| Bugs a wishes | vyvojarska agenda, samostatna evidence |
| Skutecny beh automatizaci | log ticketu zatim plni simulace, ne runtime |
| Skutecny beh automatizaci | sablony se ukladaji, ale nikdo je nevyhodnocuje |
| `inputs` u zbylych konektoru | zatim ticket, kanaly, CRM a AI, ostatni maji jen napovedu |
| Napojeni logu na beh | `automationId` je odkaz, historie behu ale neexistuje |
| Odpoved zakaznikovi z detailu| akce `send` u kanalu se z portalu nevola |
| SLA a eskalace | zadne lhuty, `capacity` je jen orientacni |