updated tickets
This commit is contained in:
@@ -17,9 +17,14 @@ React aplikaci ze slozky `dist/public`.
|
||||
| Dashboard | hotovo | prehled, tickety, incidenty, automatizace, nastaveni |
|
||||
| Zivy dashboard pres SSE | hotovo | zmeny se projevi bez obnoveni stranky |
|
||||
| Simulace provozu | hotovo | tlacitko v postrannim menu portalu |
|
||||
| Katalog konektoru | hotovo | 25 sluzeb, 8 kategorii |
|
||||
| Katalog konektoru | hotovo | 26 sluzeb, 9 kategorii |
|
||||
| Builder automatizaci | hotovo | strom akci, vetveni podminkou |
|
||||
| Webhook s registrovanou adresou | hotovo | token generuje server, verejny endpoint validuje data |
|
||||
| Tickety na konkretni lidi | hotovo | resitel, filtr moje, prehled vytizeni tymu |
|
||||
| Log ticketu ve strome | hotovo | vcetne toho, co ktera sluzba vratila |
|
||||
| Kanaly do ticketu | hotovo | WhatsApp, e-mail, hlas a formular jako spoustece |
|
||||
| Parametry od sluzby | hotovo | katalog je deklaruje, server je dosazuje pri ulozeni |
|
||||
| Bugs a wishes | chybi | vyvojarska agenda, samostatna evidence vedle ticketu |
|
||||
| Nastaveni poli akci | chybi | akce zatim neumi cerpat z parametru spoustece |
|
||||
| Beh automatizaci | chybi | ulozeny strom se nevykonava, neni runtime |
|
||||
| Databaze | chybi | data jsou v pameti, restart je vrati na vychozi stav |
|
||||
@@ -37,9 +42,15 @@ miste v `web/src/config/brand.ts`.
|
||||
Zivy stream drzi seznam posluchacu v pameti jedne instance. Pri vice instancich
|
||||
by ho musel nahradit sdileny kanal, napriklad Redis pub/sub.
|
||||
|
||||
Log ticketu zatim plni simulace, ne skutecny beh. Zaznamy jsou realisticke,
|
||||
ale nevznikly vykonanim ulozeneho stromu - runtime neexistuje.
|
||||
|
||||
## Dalsi krok
|
||||
|
||||
Nejuzitecnejsi pristavek je nastaveni poli akci a s nim predavani dat mezi kroky,
|
||||
aby slo rict "do e-mailu dej parametr customer ze spoustece". Je to zasah do
|
||||
datoveho modelu, vyplati se navrhnout drive nez se builder rozsiri dal.
|
||||
Podrobnosti v [05-dashboard-a-builder.md](05-dashboard-a-builder.md).
|
||||
aby slo rict "do e-mailu dej parametr customer ze spoustece". Parametry spoustece
|
||||
uz existuji na obou stranach, chybi jen jejich pouziti v akcich. Podrobnosti
|
||||
v [05-dashboard-a-builder.md](05-dashboard-a-builder.md).
|
||||
|
||||
Vedle toho stoji za rozmysleni evidence bugs a wishes. Zamerne to nejsou tickety,
|
||||
duvod je v [06-tickety.md](06-tickety.md).
|
||||
|
||||
@@ -48,6 +48,33 @@ Vite build ma `base: './'`, tedy relativni odkazy na soubory. Server pri odeslan
|
||||
Bez `<base>` by prohlizec hledal soubory v `/apps/<app-id>/dashboard/assets/...`
|
||||
a dostal by HTML aplikace misto skriptu.
|
||||
|
||||
## Koncove lomitko v adrese aplikace
|
||||
|
||||
Aplikaci je nutne otevirat **s koncovym lomitkem**:
|
||||
|
||||
```
|
||||
https://services.csbot.cz/apps/<app-id>/ funguje
|
||||
https://services.csbot.cz/apps/<app-id> vraci prazdnou odpoved
|
||||
```
|
||||
|
||||
Neni to chyba aplikace. Caddy routuje pres `handle_path /apps/<app-id>/*`,
|
||||
coz sedi na cestu s lomitkem a na vse pod ni, ale ne na holou cestu bez nej.
|
||||
Pozadavek se pak do containeru vubec nedostane.
|
||||
|
||||
Pozna se to podle hlavicek. Odpoved z aplikace ma `X-Powered-By: Express`
|
||||
a `Content-Type`, kdezto prazdna odpoved ma jen `Server: Caddy`:
|
||||
|
||||
```bash
|
||||
curl -sI https://services.csbot.cz/apps/<app-id> | grep -i x-powered-by # nic
|
||||
curl -sI https://services.csbot.cz/apps/<app-id>/ | grep -i x-powered-by # Express
|
||||
```
|
||||
|
||||
Ostatni cesty (`/health`, `/docs/`, `/api/...`) lomitko v sobe uz maji,
|
||||
takze se jich to netyka.
|
||||
|
||||
Opravit se to da jen presmerovanim v konfiguraci Caddy, tedy v repozitari
|
||||
AppFactory. Z aplikacniho repozitare se infrastruktura nemeni, viz AGENTS.md.
|
||||
|
||||
## Povinne endpointy
|
||||
|
||||
| Verejna cesta | Vraci |
|
||||
|
||||
@@ -39,7 +39,8 @@ image jen `dist`, takze staci jedna slozka.
|
||||
| `src/routes/simulate.ts` | vyvolani provoznich udalosti |
|
||||
| `src/routes/webhook.ts` | verejny prijem dat do automatizace |
|
||||
| `src/routes/contact.ts` | poptavkovy formular z webu |
|
||||
| `src/data/ticketStore.ts` | tickety vcetne zmen a udalosti |
|
||||
| `src/data/ticketStore.ts` | tickety, jejich resitele, log prubehu, prehled vytizeni |
|
||||
| `src/data/people.ts` | resitele ticketu - oddeleni od uzivatelu portalu |
|
||||
| `src/data/incidentStore.ts` | incidenty vcetne zmen a udalosti |
|
||||
| `src/data/automationStore.ts` | automatizace, strom akci, tokeny webhooku |
|
||||
| `src/data/connectors.ts` | katalog konektoru, jejich spousteču a akci |
|
||||
@@ -61,6 +62,8 @@ image jen `dist`, takze staci jedna slozka.
|
||||
| `web/src/lib/flow.ts` | ciste funkce nad stromem automatizace |
|
||||
| `web/src/components/dashboard/` | shell portalu, dlazdice, graf, stream, simulace |
|
||||
| `web/src/components/dashboard/flow/` | strom akci a vyber kroku |
|
||||
| `web/src/components/dashboard/TicketTrace.tsx` | log ticketu jako strom |
|
||||
| `web/src/components/dashboard/TicketWorkload.tsx` | prehled, kdo co ma u sebe |
|
||||
| `web/src/components/home/` | sekce homepage |
|
||||
| `web/src/pages/` | jedna stranka je jeden soubor |
|
||||
|
||||
@@ -82,4 +85,11 @@ Kod zustava anglicky.
|
||||
**Data v pameti.** Vedome zjednoduseni prototypu. Uloziste jsou oddelena od rout,
|
||||
takze napojeni na databazi znamena prepsat soubory v `src/data/`, ne endpointy.
|
||||
|
||||
**Resitel neni uzivatel.** Uzivatel se prihlasuje do portalu, resitel ma u sebe
|
||||
tickety. Technik muze mit tickety a ucet nikdy nemit. Spojka je e-mail,
|
||||
podrobnosti v [06-tickety.md](06-tickety.md).
|
||||
|
||||
**Filtrovani ticketu dela server.** Klient posila query parametry a dostane hotovy
|
||||
seznam. Kdyby filtroval sam, ukazoval by jina cisla nez prehled vytizeni.
|
||||
|
||||
**Zadna ticha selhani.** Kazdy `catch` loguje a uzivatel se o chybe dozvi.
|
||||
|
||||
+35
-2
@@ -23,7 +23,13 @@ Vyzaduji `Authorization: Bearer <token>`:
|
||||
| GET | `/api/auth/me` |
|
||||
| POST | `/api/auth/logout` |
|
||||
| GET | `/api/dashboard/summary` |
|
||||
| GET | `/api/dashboard/people` |
|
||||
| GET | `/api/dashboard/tickets` |
|
||||
| GET | `/api/dashboard/tickets/workload` |
|
||||
| GET | `/api/dashboard/tickets/:id` |
|
||||
| POST | `/api/dashboard/tickets/:id/assign` |
|
||||
| POST | `/api/dashboard/tickets/:id/status` |
|
||||
| POST | `/api/dashboard/tickets/:id/comment` |
|
||||
| GET | `/api/dashboard/incidents` |
|
||||
| GET | `/api/dashboard/connectors` |
|
||||
| GET | `/api/dashboard/stream` |
|
||||
@@ -72,8 +78,8 @@ cookie se `Secure` a `SameSite` plus CSRF token.
|
||||
a poslednich par udalosti, pak uz jen nove. Kazdych 25 sekund jde komentarovy
|
||||
radek, aby spojeni neuspalo proxy.
|
||||
|
||||
Typy udalosti: `ticket.created`, `ticket.updated`, `ticket.resolved`,
|
||||
`incident.started`, `incident.updated`, `incident.resolved`,
|
||||
Typy udalosti: `ticket.created`, `ticket.updated`, `ticket.assigned`,
|
||||
`ticket.resolved`, `incident.started`, `incident.updated`, `incident.resolved`,
|
||||
`automation.created`, `automation.updated`, `automation.deleted`,
|
||||
`automation.run`, `webhook.received`.
|
||||
|
||||
@@ -107,6 +113,29 @@ curl -X POST https://services.csbot.cz/apps/<app-id>/webhook/<token> \
|
||||
Prototyp pozadavek prijme, zvaliduje a zapocita do metrik, ale strom akci
|
||||
nevykona - runtime neexistuje.
|
||||
|
||||
## Tickety
|
||||
|
||||
Popis modelu je v [06-tickety.md](06-tickety.md), tady jen to, co se tyka API.
|
||||
|
||||
`GET /api/dashboard/tickets` bere filtry v query: `assignee`, `status`, `channel`.
|
||||
U `assignee` jsou dve zvlastni hodnoty: `me` znamena resitele odpovidajiciho
|
||||
prihlasenemu uzivateli, `unassigned` frontu bez resitele. Neznama hodnota filtru
|
||||
se zaloguje a ignoruje - je lepsi ukazat vic ticketu nez prazdny seznam
|
||||
bez vysvetleni.
|
||||
|
||||
Odpoved nese vedle `items` jeste `meId`. Klient podle nej pozna, ktere tickety
|
||||
jsou jeho, a jestli ma vubec smysl nabizet filtr "moje".
|
||||
|
||||
Filtrovani dela **server**, ne klient. Seznam a prehled vytizeni tak nikdy
|
||||
neukazuji jina cisla. Vyhledavaci pole v portalu je jina vec - to jen dohledava
|
||||
v uz nactenem seznamu.
|
||||
|
||||
`GET /api/dashboard/tickets/:id` vraci navic `trace`, tedy log prubehu vcetne
|
||||
toho, co ktera volana sluzba vratila.
|
||||
|
||||
`POST /api/dashboard/tickets/:id/assign` s telem `{"assigneeId": null}` vrati
|
||||
ticket do fronty. Neznamy resitel vraci 404, ne tiche odpojeni.
|
||||
|
||||
## Simulace
|
||||
|
||||
`POST /api/simulate` vyvola provozni udalost pro nahled ziveho dashboardu.
|
||||
@@ -115,6 +144,10 @@ Zamerne meni skutecna data, ne jen posila falesnou notifikaci.
|
||||
Akce: `ticket.created`, `ticket.resolved`, `incident.started`,
|
||||
`incident.resolved`, `automation.run`.
|
||||
|
||||
U `ticket.created` urcuje `channel`, odkud pozadavek prisel, a podle toho se
|
||||
poskladá i log ticketu. `knownCustomer: false` znamena, ze CRM firmu nedohleda -
|
||||
ticket zustane bez zakaznika i bez resitele a v logu je videt proc.
|
||||
|
||||
Nevyplnena pole server doplni ukazkovou hodnotou. U akci s "resolved" se bez
|
||||
zadaneho id pouzije prvni nevyrizeny zaznam.
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
/dashboard/automatizace seznam a zalozeni nove
|
||||
/dashboard/automatizace/:id builder: strom akci
|
||||
/dashboard/konektory katalog sluzeb, jejich spousteču a akci
|
||||
/dashboard/tickety tabulka ticketu
|
||||
/dashboard/tickety seznam, filtry, prehled vytizeni tymu
|
||||
/dashboard/tickety/:id detail ticketu: prubeh a log, resitel, zakaznik
|
||||
/dashboard/incidenty prehled incidentu
|
||||
/dashboard/nastaveni udaje o uctu
|
||||
```
|
||||
@@ -33,7 +34,8 @@ az do 15 sekund, aby pri vypadku serveru neubijel provoz.
|
||||
|
||||
Modalni okno se otevre tlacitkem Simulace. Umoznuje:
|
||||
|
||||
- zalozit ticket s vlastnim predmetem, zadavatelem a prioritou,
|
||||
- zalozit ticket z vybraneho kanalu vcetne celeho logu, ktery k nemu vede,
|
||||
a s prepinacem, jestli se zakaznik v CRM dohleda nebo ne,
|
||||
- vyvolat incident s vlastnim popisem, sluzbou a zavaznosti,
|
||||
- vyresit prvni nevyrizeny ticket nebo bezici incident,
|
||||
- spustit automatizaci uspesne nebo s chybou.
|
||||
@@ -69,11 +71,21 @@ existujici podminky nerozbije.
|
||||
Misto vlozeni urcuje `FlowPath` v `web/src/lib/flow.ts`: prazdne pole je hlavni
|
||||
sekvence, `[{ stepId, branch }]` je vetev konkretni podminky.
|
||||
|
||||
## Webhook a vstupni parametry
|
||||
## Odkud se berou vstupni parametry
|
||||
|
||||
Jsou dva druhy spousteču a lisi se tim, kdo urcuje jejich parametry.
|
||||
|
||||
**Parametry deklaruje uzivatel** (webhook, formular). V katalogu maji
|
||||
`customPayload: true`. V builderu se pridavaji rucne: nazev, typ (text, cislo,
|
||||
ano-ne, datum) a povinnost.
|
||||
|
||||
**Parametry urcuje sluzba** (e-mail, WhatsApp, hlasova linka, ticket). V katalogu
|
||||
je nese `providedFields`. Builder je ukazuje jen ke cteni a server je pri ulozeni
|
||||
stromu vzdy dosadi z katalogu, jeste pred validaci. Podrobnosti a duvody jsou
|
||||
v [06-tickety.md](06-tickety.md), sekce "Parametry od sluzby".
|
||||
|
||||
U spoustece typu webhook vygeneruje server pri ulozeni adresu
|
||||
`POST <verejna-adresa>/webhook/<token>`. U spoustece se deklaruji vstupni
|
||||
parametry: nazev, typ (text, cislo, ano-ne, datum) a povinnost.
|
||||
`POST <verejna-adresa>/webhook/<token>`.
|
||||
|
||||
Podminky pak porovnavaji hodnotu parametru, napriklad `score >= 15`. Nabidka
|
||||
operatoru se ridi typem, na cislo nejde pustit "obsahuje". Tabulka operatoru je
|
||||
@@ -104,6 +116,8 @@ Rozdelana prace se nikdy nezahazuje.
|
||||
Musi existovat v `lucide-react`.
|
||||
3. Pokud patri do nove kategorie, doplnit ji do `connectorCategories` a do typu
|
||||
`ConnectorCategory` na obou stranach.
|
||||
4. Pokud spoustec predava vlastni data, deklarovat je v `providedFields`. ID
|
||||
parametru musi zustat stabilni, odkazuji se na ne podminky v ulozenych stromech.
|
||||
|
||||
Builder i katalog ji vezmou automaticky.
|
||||
|
||||
@@ -112,6 +126,7 @@ Builder i katalog ji vezmou automaticky.
|
||||
| Chybi | Poznamka |
|
||||
| --------------------------- | -------------------------------------------------------- |
|
||||
| Nastaveni poli akci | `fields` u akci se zobrazuji jen jako napoveda |
|
||||
| Vazba logu ticketu na beh | log plni simulace, ne vykonany strom |
|
||||
| Predavani dat do akci | chybi syntaxe odkazu, navrh je `{{trigger.customer}}` |
|
||||
| Kombinovane podminky | jedna podminka je jedno porovnani, AND a OR jen vnorenim |
|
||||
| Beh automatizaci | ulozeny strom se nevykonava |
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
# 06 - Tickety
|
||||
|
||||
## 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 **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,
|
||||
ze ani jedna nefunguje poradne.
|
||||
|
||||
## Tri veci, na kterych to stoji
|
||||
|
||||
**Kanaly ustuji do ticketu.** WhatsApp, e-mail, hlasova linka a formular jsou
|
||||
plnohodnotne spoustece. Automatizace zacne prichozi zpravou a skonci zalozenym
|
||||
ticketem.
|
||||
|
||||
**Ticket ma sveho cloveka.** `assignee` neni volny text, ale odkaz na konkretniho
|
||||
resitele. Da se rict "hod to na Karla Vomacku" a Karel to ma mezi svymi tickety.
|
||||
Nad tym je prehled pres cely tym, kde je videt, kdo co u sebe ma.
|
||||
|
||||
**Kazdy ticket je dohledatelny.** Nese si strom zaznamu o tom, co se s nim delo
|
||||
a **co ktera sluzba vratila**. Kdyz neco nesedi, neni potreba hadat.
|
||||
|
||||
## Datovy model
|
||||
|
||||
`src/data/ticketStore.ts`
|
||||
|
||||
```ts
|
||||
interface Ticket {
|
||||
id: string;
|
||||
subject: string;
|
||||
channel: 'whatsapp' | 'email' | 'voice' | 'form' | 'portal';
|
||||
customer: TicketCustomer;
|
||||
status: 'new' | 'open' | 'waiting' | 'resolved';
|
||||
priority: 'low' | 'normal' | 'high' | 'critical';
|
||||
assignee: { id: string; name: string } | null; // null = ceka ve fronte
|
||||
automationId: string | null; // null = zalozeno rucne
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
interface TicketCustomer {
|
||||
id: string | null; // null = firmu se nepodarilo dohledat v CRM
|
||||
company: string;
|
||||
contact: string;
|
||||
reply: string; // adresa nebo cislo, kam se odpovida
|
||||
}
|
||||
```
|
||||
|
||||
`customer.id` je zamerne nullable. Prave na nej se pta podminka "mame zakaznika?"
|
||||
ve strome automatizace. Bez toho by nesla postavit vetev "firmu neznam, zaloz
|
||||
obchodni pripad a nekomu to dej".
|
||||
|
||||
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.
|
||||
|
||||
## Resitele
|
||||
|
||||
`src/data/people.ts`
|
||||
|
||||
Resitel je oddeleny od uzivatele. **Uzivatel** je ten, kdo se prihlasi do portalu,
|
||||
**resitel** je ten, na koho jde ticket. Casto je to tyz clovek, ale ne vzdy -
|
||||
technik muze mit tickety a do portalu se nikdy neprihlasit.
|
||||
|
||||
Spojka mezi obojim je e-mail. Podle ni funguje filtr "moje tickety"
|
||||
(`?assignee=me`). Kdyz prihlaseny ucet zadnemu resiteli neodpovida, filtr se
|
||||
v portalu nabidne jako nedostupny misto toho, aby vracel prazdno bez vysvetleni.
|
||||
|
||||
Kazdy resitel ma `capacity`, tedy pocet nevyrizenych ticketu, ktery je pro nej
|
||||
jeste zdrava zatez. Neni to limit, nic se podle nej neodmita - jen se v prehledu
|
||||
oznaci, kdo je nad ni.
|
||||
|
||||
## Prehled nad firmou
|
||||
|
||||
`GET /api/dashboard/tickets/workload` vraci pres cely tym: kolik ma kdo
|
||||
nevyrizenych, kolik celkem, kolik kritickych, jak stary je jeho nejstarsi ticket
|
||||
a jestli je nad kapacitu. K tomu pocet ticketu ve fronte bez resitele.
|
||||
|
||||
V portalu je to postranni panel na strance Tickety. Radek je zaroven filtr
|
||||
seznamu - kliknutim na cloveka se seznam zuzi na jeho tickety. Bez toho by to
|
||||
byl jen obrazek.
|
||||
|
||||
Sirka pruhu se pocita proti nejvytizenejsimu clenovi tymu, ne proti kapacite.
|
||||
Jde o porovnani lidi mezi sebou.
|
||||
|
||||
## Log ticketu
|
||||
|
||||
Log je **strom**, ne seznam. Vetev podminky visi na zaznamu te podminky, takze je
|
||||
videt i to, ktera cast behu se vubec nespustila.
|
||||
|
||||
```ts
|
||||
interface TicketTraceEntry {
|
||||
id: string;
|
||||
parentId: string | null; // null = hlavni sekvence
|
||||
kind: 'trigger' | 'action' | 'condition' | 'note';
|
||||
connectorId: string | null; // ktera sluzba to byla
|
||||
operationId: string | null;
|
||||
label: string;
|
||||
status: 'ok' | 'error' | 'skipped' | 'info';
|
||||
response: string | null; // co sluzba vratila
|
||||
durationMs: number | null;
|
||||
at: string;
|
||||
}
|
||||
```
|
||||
|
||||
`response` je duvod, proc log existuje. V portalu se zobrazuje rovnou, ne po
|
||||
rozkliknuti - kvuli nemu se do logu chodi.
|
||||
|
||||
Zapisuje se zanorene (`TraceInput` s `children`) a uklada zplostele s `parentId`.
|
||||
Klient si strom zase poskladá. Zaznam s neznamym rodicem se nezahodi, prida se
|
||||
do korene a zaloguje - ztratit radek logu je horsi nez ho ukazat spatne zanoreny.
|
||||
|
||||
Komentare jsou taky zaznamy logu (`kind: 'note'`). Diky tomu je vsechno na jedne
|
||||
casove ose a nemusi se nikde skladat dohromady dva ruzne seznamy.
|
||||
|
||||
## Konektor Tickety
|
||||
|
||||
Kategorie `servicedesk`, driv byl pod Nastroji. Ma obe strany:
|
||||
|
||||
| Spoustec | Kdy |
|
||||
| ------------------ | ------------------------------------------------------ |
|
||||
| `created` | zalozen ticket, at uz z kanalu nebo rucne |
|
||||
| `unknown-customer` | k ticketu se nepodarilo dohledat firmu |
|
||||
| `assigned` | ticket dostal konkretniho cloveka |
|
||||
| `status-changed` | prechod do jineho stavu vcetne vyreseni |
|
||||
|
||||
| Akce | Co dela |
|
||||
| --------------- | --------------------------------------------- |
|
||||
| `create` | zalozi pozadavek |
|
||||
| `assign` | preda ticket cloveku |
|
||||
| `set-status` | posune stav |
|
||||
| `link-customer` | doplni firmu z CRM |
|
||||
| `comment` | zapise komentar do logu |
|
||||
|
||||
Typicky retez, ktery z toho jde postavit:
|
||||
|
||||
```
|
||||
Prijata zprava z WhatsApp
|
||||
Zaradit do kategorie (AI)
|
||||
Dohledat firmu podle telefonu (CRM)
|
||||
knownCustomer?
|
||||
ANO Zalozit ticket, Priradit resiteli
|
||||
NE Zalozit ticket, Zalozit obchodni pripad, Upozornit servicedesk
|
||||
```
|
||||
|
||||
## Parametry od sluzby
|
||||
|
||||
Nektere spoustece si data urcuji samy. E-mail posila `from`, `subject`, `body`.
|
||||
WhatsApp posila `phone`, `text`. Ticket posila `knownCustomer`. Uzivatel si je
|
||||
nevymysli, ale potrebuje nad nimi stavet podminky.
|
||||
|
||||
Katalog je proto deklaruje v `providedFields` u operace. Chovaji se pak takhle:
|
||||
|
||||
- builder je ukazuje **jen ke cteni**, pridat ani prejmenovat nejdou,
|
||||
- server je pri ulozeni stromu **vzdy dosadi z katalogu** a to, co poslal klient,
|
||||
zahodi (`normalizeTriggerFields` v `src/routes/dashboard.ts`),
|
||||
- dosazeni probiha **pred validaci**, jinak by podminky odkazujici na katalogova
|
||||
ID vypadaly jako rozbite.
|
||||
|
||||
ID techto parametru (`email.from`, `ticket.knownCustomer`) musi zustat stabilni.
|
||||
Odkazuji se na ne podminky v ulozenych stromech, prejmenovani ID je rozbije.
|
||||
|
||||
Spoustece bez `providedFields` (webhook, formular) funguji jako predtim -
|
||||
parametry si deklaruje uzivatel.
|
||||
|
||||
## Stranky portalu
|
||||
|
||||
```
|
||||
/dashboard/tickety seznam, filtry, prehled vytizeni
|
||||
/dashboard/tickety/:id detail: prubeh a log, resitel, zakaznik, puvod
|
||||
```
|
||||
|
||||
## Co chybi
|
||||
|
||||
| Chybi | Poznamka |
|
||||
| ---------------------------- | ------------------------------------------------------- |
|
||||
| Bugs a wishes | vyvojarska agenda, samostatna evidence |
|
||||
| Skutecny beh automatizaci | log ticketu zatim plni simulace, ne runtime |
|
||||
| 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 |
|
||||
| Databaze | data v pameti, restart je vrati na vychozi sadu |
|
||||
@@ -2,6 +2,48 @@
|
||||
|
||||
Nejnovejsi nahore.
|
||||
|
||||
## 2026-08-03
|
||||
|
||||
Tickety predelane na plnohodnotny konektor. Prestavaji byt polozkou v seznamu
|
||||
a stavaji se prichozim pozadavkem, ktery ma sveho cloveka a dohledatelny prubeh.
|
||||
Popis modelu je v [06-tickety.md](06-tickety.md).
|
||||
|
||||
### Pridano
|
||||
|
||||
- Kanaly do ticketu: WhatsApp jako novy konektor, e-mail a hlasova linka
|
||||
jako plnohodnotne spoustece.
|
||||
- Konektor Tickety presunut do nove kategorie `servicedesk`, rozsiren
|
||||
o spoustece `created`, `unknown-customer`, `assigned`, `status-changed`
|
||||
a akce `assign`, `set-status`, `link-customer`.
|
||||
- Resitele (`src/data/people.ts`) oddelene od uzivatelu portalu, spojka e-mailem.
|
||||
- Log ticketu ve strome vcetne toho, co ktera volana sluzba vratila.
|
||||
- Prehled vytizeni tymu, kdo co ma u sebe, zaroven jako filtr seznamu.
|
||||
- Detail ticketu `/dashboard/tickety/:id`: prubeh a log, prirazeni, stav,
|
||||
zakaznik, komentare.
|
||||
- Filtry seznamu ticketu na serveru: resitel (vcetne `me` a `unassigned`),
|
||||
stav, kanal.
|
||||
- `providedFields` v katalogu konektoru: parametry, ktere spoustec predava sam.
|
||||
- Udalost `ticket.assigned` na sbernici i v portalu.
|
||||
- Endpointy `/api/dashboard/people`, `/tickets/workload`, `/tickets/:id`
|
||||
a POST varianty pro assign, status a comment. Vse ve Swaggeru.
|
||||
|
||||
### Zmeneno
|
||||
|
||||
- `Ticket` ma misto volneho `requester` strukturovaneho `customer` s nullable
|
||||
`id` firmy v CRM, k tomu `channel`, `assignee` jako odkaz na cloveka
|
||||
a `automationId`.
|
||||
- `customer.id === null` je nosna informace, ne chybejici udaj. Prave na ni se
|
||||
pta podminka "mame zakaznika?" ve strome automatizace.
|
||||
- Simulace ticketu bere kanal a prepinac, jestli se zakaznik dohleda.
|
||||
Zakladany ticket dostane cely realisticky log.
|
||||
- Builder ukazuje parametry od sluzby jen ke cteni. Server je pri ulozeni
|
||||
vzdy dosadi z katalogu, a to jeste pred validaci stromu.
|
||||
|
||||
### Vedome neudelano
|
||||
|
||||
Bugs a wishes zustavaji mimo. Vyvojarska agenda ma jiny zivotni cyklus a slucovat
|
||||
ji s tickety by znamenalo, ze ani jedna evidence nefunguje poradne.
|
||||
|
||||
## 2026-07-31
|
||||
|
||||
Prvni nasazeni aplikace do repozitare csbot-prototype.
|
||||
|
||||
Reference in New Issue
Block a user