Ticketovaci system: udalosti, externi ID, statistiky a widgety nad konektory
Jakakoliv udalost se muze stat ticketem. Prijem je verejny endpoint na firmu (`POST /webhook/ticket/:token`), takze zalozit ticket jde i bez stavby stromu. Externi ID je unikatni V RAMCI FIRMY: dalsi zprava se stejnym ID se navesi na existujici ticket misto zalozeni druheho, a stejne ID u jine firmy je jiny ticket. Cislo a retezec jsou tentyz klic. Udalosti se drzi cele vcetne prijatych dat a jdou rozbalit v detailu - je to neco jineho nez log. Ticket nove nese firstResponseAt, resolvedAt, resolvedById a reopenCount. Bez nich neslo rict, kdo kolik odbavil ani jak dlouho zakaznik cekal. `getAgentStats` z toho pocita vykon resitelu vcetne medianovych casu a vracenych ticketu. Pocet vyresenych sam o sobe odmenuje toho, kdo tickety zaviral predcasne, proto je vraceni videt vedle nej. Widgety: klient konecne vola /widget-data. Endpoint existoval, ale nikdo ho nepouzival, takze vlastni widget hlasil "nepodarilo se zobrazit". Pribyl zdroj `connector` - co umi zjistit napojena sluzba, jde vytahnout do dlazdice pres tentyz skript, ktery pouziva krok automatizace. Vysledek se cachuje. Akce a widgety uz nejsou v nastaveni, maji vlastni zalozku vedle automatizaci. Telo akce se sklada stromem, ne JSONem v textarei - je to tentyz editor, jen misto karty spoustece je "spousti clovek tlacitkem na ticketu". Nova zalozka Lide se seznamem a detailem osoby. Seznam ticketu i lidi ma dva pohledy, tabulku a dlazdice. Opraveno: createTicket bral typeId, fields, tags i assigneeGroupId, ale nikdy je neukladal. Ticket zalozeny s typem zustaval bez typu a bez vlastnich poli. Dlouhe pomlcky, sipky, vypustky a bullety pryc z celeho projektu. Overeno 21 kontrolami proti bezicimu serveru v rezimu souboru. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6c90372991
commit
29de584df8
@@ -21,6 +21,11 @@ React aplikaci ze slozky `dist/public`.
|
||||
| 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 |
|
||||
| Prijem udalosti do ticketu | hotovo | webhook na firmu, externi ID unikatni za firmu |
|
||||
| Udalosti na ticketu | hotovo | dalsi zprava se navesi na tentyz ticket |
|
||||
| Statistiky resitelu | hotovo | odbaveno, mediany casu, vracene, fronta |
|
||||
| Pohledy tabulka a dlazdice | hotovo | tickety i lide |
|
||||
| Stranka Lide a detail osoby | hotovo | vykon a co ma u sebe |
|
||||
| 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 |
|
||||
@@ -39,7 +44,8 @@ React aplikaci ze slozky `dist/public`.
|
||||
| Osoby a skupiny resitelu | hotovo | ticket lze prehodit na skupinu, ne jen na cloveka |
|
||||
| Typy ticketu a vlastni pole | hotovo | typ rozhoduje, ktere akce se na ticketu ukazou |
|
||||
| Vydefinovane akce na ticketu | hotovo | vazba na typ nebo tag, telo je operace, strom, skript |
|
||||
| Vlastni widgety | hotovo | zdroj dat z ticketu nebo automatizaci, seskupeni |
|
||||
| Vlastni widgety | hotovo | vcetne zdroje z konektoru a vykonu resitelu |
|
||||
| Telo akce jako strom | hotovo | tentyz editor jako automatizace |
|
||||
| Audit a prepnuti na jiny ucet | hotovo | prepnuti je vychozi jen pro cteni, vse v auditu |
|
||||
| Bugs a wishes | chybi | vyvojarska agenda, samostatna evidence vedle ticketu |
|
||||
| Beh automatizaci | chybi | ulozeny strom se nevykonava, neni runtime |
|
||||
@@ -117,4 +123,5 @@ pro frontu, beh kroku a rozpocet na 150 klientu, a
|
||||
| [15-rejstrik-funkci.md](15-rejstrik-funkci.md) | k cemu je jaka funkce a komponenta |
|
||||
| [16-monetizace.md](16-monetizace.md) | **navrh**: cena za krok a balicky |
|
||||
| [17-nastaveni-a-prava.md](17-nastaveni-a-prava.md) | prava, typy, akce, widgety, prepnuti uctu |
|
||||
| [18-ticketovaci-system.md](18-ticketovaci-system.md) | udalosti, externi ID, statistiky, pohledy |
|
||||
| [99-zmeny.md](99-zmeny.md) | zaznam zmen, nejnovejsi nahore |
|
||||
|
||||
@@ -16,6 +16,8 @@ Verejne:
|
||||
| POST | `/api/auth/login` | prihlaseni, vraci JWT |
|
||||
| POST | `/api/contact` | poptavka z webu |
|
||||
| POST | `/webhook/:token` | prijem dat do automatizace |
|
||||
| POST | `/webhook/ticket/:token` | prijem udalosti do ticketu |
|
||||
| GET | `/webhook/ticket/:token` | napoveda k prijmu |
|
||||
|
||||
Vyzaduji `Authorization: Bearer <token>`:
|
||||
|
||||
@@ -30,6 +32,10 @@ Vyzaduji `Authorization: Bearer <token>`:
|
||||
| DELETE | `/api/dashboard/layout` |
|
||||
| GET | `/api/dashboard/summary` |
|
||||
| GET | `/api/dashboard/people` |
|
||||
| GET | `/api/dashboard/people/:id` |
|
||||
| GET | `/api/dashboard/intake` |
|
||||
| POST | `/api/dashboard/intake/regenerate` |
|
||||
| GET | `/api/dashboard/settings/actions/:id/scope` |
|
||||
| GET | `/api/dashboard/tickets` |
|
||||
| GET | `/api/dashboard/tickets/workload` |
|
||||
| GET | `/api/dashboard/tickets/:id` |
|
||||
@@ -204,6 +210,24 @@ s celym chybovym hlasenim a `durationMs`. Cely prubeh se zapise do logu ticketu.
|
||||
Vestavene akce (`type`, `tags`, `group`, `assign`, `status`, `comment`) jsou
|
||||
zvlast: meni ticket sam, ne cizi sluzbu, a kazda ma vlastni pravo.
|
||||
|
||||
## Prijem udalosti do ticketu
|
||||
|
||||
Popis modelu je v [18-ticketovaci-system.md](18-ticketovaci-system.md).
|
||||
|
||||
`POST /webhook/ticket/:token` je **verejny**, autorizuje token firmy v adrese.
|
||||
Vraci 201 kdyz ticket vznikl, 200 kdyz se udalost navesila na existujici:
|
||||
|
||||
```json
|
||||
{ "ok": true, "created": false, "ticketId": "TK-4822", "externalId": "3", "eventId": "tev_2" }
|
||||
```
|
||||
|
||||
`externalId` je unikatni **v ramci firmy**. Token urcuje firmu, takze dve firmy
|
||||
mohou obe poslat objednavku cislo 3 a nedojde ke smichani. Cislo i retezec jsou
|
||||
tentyz klic.
|
||||
|
||||
Neznamy `typeId` se zahodi a zaloguje, ticket vznikne bez typu. Odmitnout celou
|
||||
udalost kvuli jednomu poli by znamenalo ztratu dat.
|
||||
|
||||
## Prava a navigace
|
||||
|
||||
`GET /api/dashboard/access` vraci `permissions` (efektivni prava po slouceni
|
||||
|
||||
@@ -37,6 +37,10 @@ Volající nikdy nezjišťuje, jestli běží Postgres, soubor, nebo pamět.
|
||||
| `hasPermission(...)` | `src/data/permissions.ts` | Jedna kontrola. Používá ji `crudRouter` i ruční handlery. |
|
||||
| `navFor(...)` | `src/data/tenantFeatures.ts` | Průnik toho, co firma má, a toho, na co má člověk právo. Navigace chodí ze serveru. |
|
||||
| `recordAudit(input)` | `src/data/audit.ts` | Zápis do auditu. Nevrací chybu a nečeká se - rozbitý audit nesmí rozbít aplikaci. |
|
||||
| `intakeEvent(input)` | `src/data/ticketStore.ts` | Přijme událost zvenku: podle externího ID buď založí ticket, nebo ji navěsí na existující. Jediná cesta, kterou se událost stává ticketem. |
|
||||
| `getAgentStats(...)` | `src/data/ticketStore.ts` | Výkon řešitelů: odbavené, mediány časů, vrácené, fronta. Používá to widget i detail osoby, aby čísla seděla. |
|
||||
| `findByExternalId(...)` | `src/data/ticketStore.ts` | Ticket firmy podle externího ID. Klíč je dvojice firma a ID. |
|
||||
| `findByIntakeToken(token)` | `src/data/tenants.ts` | Firma podle tokenu příjmu. Určuje i to, v jakém rozsahu je externí ID unikátní. |
|
||||
| `refreshCaches()` | `src/data/bootstrap.ts` | Obnoví všechny kopie v paměti. Volá se po zápisu, který je může změnit. |
|
||||
| `bootstrapData({databaseReady})` | `src/data/bootstrap.ts` | Seznam všech entit a provozních dat. **Nová entita se přidává tady**, ne rozesetě po modulech. |
|
||||
|
||||
@@ -64,10 +68,14 @@ Viz [11-skripty-konektoru.md](11-skripty-konektoru.md).
|
||||
| `parseJsonField` | `components/dashboard/EntityAdmin.tsx` | Textové pole s JSONem na hodnotu, s hlášením, kde je chyba. |
|
||||
| `TicketActions` | `components/dashboard/TicketActions.tsx` | CTA akcí na ticketu plus typ, tagy a vlastní pole. Seznam akcí chodí ze serveru už vyfiltrovaný. |
|
||||
| `ErrorDetail` | `components/dashboard/ErrorDetail.tsx` | Rozbalovací celé chybové hlášení s kopírováním. Chyba se nikdy nezkracuje. |
|
||||
| `CustomWidgetCard` | `components/dashboard/widgets/CustomWidget.tsx` | Vykreslí widget, jehož data počítá server: číslo, pruhy, tabulka výkonu, časová řada, seznam, data z konektoru. |
|
||||
| `TicketEvents` | `components/dashboard/TicketEvents.tsx` | Příchozí události ticketu včetně celého přijatého JSONu. |
|
||||
| `ViewSwitch` | `components/dashboard/ViewSwitch.tsx` | Přepínač tabulka nebo dlaždice. Používají ho všechny seznamy. |
|
||||
| `FlowCanvas` s `start` | `components/dashboard/flow/FlowCanvas.tsx` | Tentýž strom kroků i bez spouštěče - pro tělo akce, které spouští člověk. |
|
||||
| `MappingEditor` | `components/dashboard/flow/MappingEditor.tsx` | Editor transformací v obou režimech (pole na pole, JSON). |
|
||||
| `DataState` | `components/dashboard/DataState.tsx` | Načítání, chyba, prázdno. Ať to každá stránka nekreslí po svém. |
|
||||
| `apiFetch<T>` | `lib/api.ts` | Jediná cesta na API: base path, token, `ApiError` s celým hlášením ze serveru. |
|
||||
| `useApiQuery<T>` | `lib/useApiQuery.ts` | Načtení dat do stránky včetně `reload`. |
|
||||
| `useApiQuery<T>` | `lib/useApiQuery.ts` | Načtení dat do stránky včetně `reload`. S `body` pošle POST (dávkové načtení), s `enabled: false` se neptá vůbec. |
|
||||
| `cn(...)` | `lib/cn.ts` | Skládání tříd. Podmíněné třídy nikdy ručně přes šablonu. |
|
||||
| `format*` | `lib/format.ts` | Čísla, procenta, datum, relativní čas, trvání. Formátování se nepíše v komponentě. |
|
||||
| `serviceIcon(key)` | `lib/serviceIcons.ts` | Klíč ikony ze serveru na komponentu. Server neposílá komponenty. |
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
# Ticketovací systém
|
||||
|
||||
Jak se z události stane ticket, jak se k němu navěsí další, a co se z toho dá
|
||||
vyčíst. Model práv a typů je v [17-nastaveni-a-prava.md](17-nastaveni-a-prava.md).
|
||||
|
||||
## Ticketem se může stát jakákoliv událost
|
||||
|
||||
Vstup je jeden veřejný endpoint na firmu:
|
||||
|
||||
```
|
||||
POST /webhook/ticket/<token>
|
||||
```
|
||||
|
||||
Token patří **firmě**, ne automatizaci. Založit ticket má jít i bez toho, aby
|
||||
se kvůli tomu stavěl strom. Adresu najde ten, kdo spravuje napojení, na
|
||||
`GET /api/dashboard/intake`; přegeneruje se `POST /api/dashboard/intake/regenerate`
|
||||
a stará okamžitě přestane platit.
|
||||
|
||||
Tělo:
|
||||
|
||||
```json
|
||||
{
|
||||
"externalId": 3,
|
||||
"source": "eshop",
|
||||
"event": "order.created",
|
||||
"subject": "Objednávka 3",
|
||||
"typeId": "tt_order",
|
||||
"fields": { "orderNumber": "3", "orderTotal": 2450 },
|
||||
"tags": ["vip"],
|
||||
"payload": { "cokoliv": "co se má uložit celé" }
|
||||
}
|
||||
```
|
||||
|
||||
Povinné není nic kromě těla samotného. Chybí předmět? Použije se popisek nebo
|
||||
typ události. Neznámý `typeId`? Zahodí se a zaloguje, ticket vznikne bez typu -
|
||||
odmítnout celou událost kvůli překlepu v jednom poli by znamenalo ztrátu dat.
|
||||
|
||||
## Externí ID a navěšování
|
||||
|
||||
`externalId` je ID u odesílatele, typicky číslo objednávky. Je **unikátní
|
||||
v rámci firmy**, ne globálně: dvě firmy můžou mít objednávku číslo 3 a nesmí si
|
||||
o sebe zavadit. Firmu určuje token v adrese.
|
||||
|
||||
Když už ticket se stejným externím ID v té firmě je, událost se na něj
|
||||
**navěsí** místo založení druhého:
|
||||
|
||||
```
|
||||
POST /webhook/ticket/<token> {"externalId": 3, "event": "order.created"} -> 201, vznikl TK-4822
|
||||
POST /webhook/ticket/<token> {"externalId": 3, "event": "email.sent"} -> 200, doplněn TK-4822
|
||||
POST /webhook/ticket/<jiná firma> {"externalId": 3} -> 201, vznikl TK-4823
|
||||
```
|
||||
|
||||
Číslo a řetězec jsou tentýž klíč: odesílatel pošle `3`, my držíme `"3"`. Jinak
|
||||
by `3` a `"3"` byly dva tickety a nikdo by nepoznal proč.
|
||||
|
||||
Bez `externalId` se vždycky zakládá nový ticket. Hádat podle předmětu by
|
||||
slučovalo věci, které spolu nesouvisí.
|
||||
|
||||
### Událost není řádek logu
|
||||
|
||||
Dvě různé věci, které se snadno pletou:
|
||||
|
||||
| | Co to je | Kde se bere |
|
||||
| --- | --- | --- |
|
||||
| **Událost** | fakt zvenku, celá přijatá data | poslal odesílatel |
|
||||
| **Řádek logu** | naše stopa toho, co se dělo uvnitř | zapsala aplikace |
|
||||
|
||||
Události se ukazují na detailu ticketu nad logem a dají se rozbalit na celý
|
||||
přijatý JSON. Když se někdo ptá, proč ticket vypadá takhle, je to jediná
|
||||
odpověď. Drží se jich nejvýš 200 na ticket, starší se odmazávají - nekonečně
|
||||
rostoucí ticket by při každém zápisu přepisoval víc a víc dat.
|
||||
|
||||
## Co se u ticketu měří
|
||||
|
||||
Aby šlo říct, kdo kolik odbavil a komu to nejde, nestačí počítat vyřešené.
|
||||
Ticket proto nese:
|
||||
|
||||
| Pole | Kdy se zapíše | K čemu |
|
||||
| --- | --- | --- |
|
||||
| `firstResponseAt` | při prvním přiřazení, komentáři nebo změně stavu | jak dlouho zákazník čekal na reakci |
|
||||
| `resolvedAt` | při přechodu na vyřešeno | doba řešení |
|
||||
| `resolvedById` | tamtéž, je to ten, kdo ho měl u sebe | komu se vyřešení připíše |
|
||||
| `reopenCount` | při návratu z vyřešeno | kolikrát to hotové nebylo |
|
||||
|
||||
`firstResponseAt` se zapisuje **jednou a nepřepisuje**. Je to okamžik, kdy
|
||||
zákazník přestal čekat. Kdyby se přepisoval při každé změně, měřil by poslední
|
||||
dotek, což je úplně jiná veličina.
|
||||
|
||||
`reopenCount` je záměrně vedle počtu vyřešených. Samotný počet vyřešených
|
||||
odměňuje toho, kdo tickety zavíral předčasně.
|
||||
|
||||
## Výkon řešitelů
|
||||
|
||||
Widget **Výkon řešitelů** (`panel.agents`) a detail osoby ukazují za 30 dní:
|
||||
|
||||
- **odbaveno** - kolik vyřešil,
|
||||
- **ve frontě** - kolik má právě teď,
|
||||
- **doba řešení** a **reakce** - mediány,
|
||||
- **vráceno** - kolik se mu jich vrátilo,
|
||||
- **nejstarší** - co mu leží nejdéle.
|
||||
|
||||
Medián, ne průměr: jeden ticket zapomenutý přes dovolenou by průměr úplně
|
||||
rozhodil. Fronta se počítá vždycky celá, bez ohledu na období - leží tam bez
|
||||
ohledu na to, na co se zrovna díváme.
|
||||
|
||||
Čísla počítá `getAgentStats` v `src/data/ticketStore.ts` a používá je widget
|
||||
i detail osoby. Kdyby si je stránka počítala sama, na dvou místech by vyšlo
|
||||
něco jiného.
|
||||
|
||||
## Pohledy
|
||||
|
||||
| Stránka | Co ukazuje |
|
||||
| --- | --- |
|
||||
| Tickety | seznam s filtry, **tabulka nebo dlaždice** |
|
||||
| Detail ticketu | obsah, události, log, akce, typ, tagy, řešitel, skupina |
|
||||
| Lidé | řešitelé firmy a jejich vytížení, **tabulka nebo dlaždice** |
|
||||
| Detail osoby | její výkon, co má u sebe, co naposledy vyřešila |
|
||||
|
||||
Přepínač pohledu je jedna komponenta (`components/dashboard/ViewSwitch.tsx`)
|
||||
a používají ji obě stránky se seznamem.
|
||||
|
||||
## Widgety nad daty i nad konektory
|
||||
|
||||
Widget je dvojice: `render` (jak se to kreslí) a `source` (odkud jsou data).
|
||||
Zdroje:
|
||||
|
||||
| Zdroj | Co dělá |
|
||||
| --- | --- |
|
||||
| `ticketCount` | počet ticketů podle filtru, volitelně seskupený |
|
||||
| `ticketList` | seznam ticketů |
|
||||
| `ticketSeries` | časová řada |
|
||||
| `workload` | kdo co má u sebe |
|
||||
| `agentStats` | výkon řešitelů |
|
||||
| `connector` | **data z napojené služby** |
|
||||
|
||||
Zdroj `connector` zavolá **tentýž skript**, který používá krok automatizace
|
||||
i akce na ticketu, a z výsledku vezme, co je v `path`. Widget nemá vlastní
|
||||
cestu k cizí službě - jinak by se chovala jinak než zbytek aplikace.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "connector",
|
||||
"serviceId": "idoklad",
|
||||
"operationId": "find-issued-invoice",
|
||||
"connectorId": null,
|
||||
"inputs": {},
|
||||
"path": "total",
|
||||
"ttlSec": 300
|
||||
}
|
||||
```
|
||||
|
||||
Výsledek se **drží v mezipaměti** (`ttlSec`, nejméně 30 s). Bez toho by každé
|
||||
otevření přehledu znamenalo volání cizího API za každou dlaždici, a to má
|
||||
limity a někdy se za něj platí. U dat z konektoru se vedle čísla ukazuje jejich
|
||||
stáří a jestli jsou z mezipaměti.
|
||||
|
||||
Data všech dlaždic chodí **jedním requestem** (`POST /api/dashboard/widget-data`).
|
||||
Widget, který selže, hlásí chybu **na své pozici** a celou, nezkrácenou - jeden
|
||||
rozbitý zdroj nesmí zhasnout celý přehled.
|
||||
|
||||
## Kde se co definuje
|
||||
|
||||
Akce a widgety **nejsou v nastavení**. Je to definice toho, co aplikace umí,
|
||||
stejná úroveň jako automatizace, a mají vlastní záložku:
|
||||
|
||||
| Záložka | Co tam patří |
|
||||
| --- | --- |
|
||||
| Automatizace | stromy, které běží samy |
|
||||
| Akce | tlačítka na ticketu, tělo je **tentýž strom** |
|
||||
| Widgety | dlaždice na přehled |
|
||||
| Nastavení | firmy, lidé, role, typy ticketů, audit |
|
||||
|
||||
Tělo akce se skládá stejným editorem jako automatizace. Místo karty spouštěče
|
||||
je karta "spouští člověk tlačítkem na ticketu" a parametry, na které jde
|
||||
v krocích odkazovat, jsou údaje ticketu plus vlastní pole jeho typu. Ty počítá
|
||||
server (`GET /api/dashboard/settings/actions/:id/scope`), aby si klient nedělal
|
||||
druhý seznam, který se časem rozejde.
|
||||
|
||||
## Co zatím nejde
|
||||
|
||||
Uložený strom se **nevykoná** - chybí runtime, stejně jako u automatizací.
|
||||
Akce s jednou operací běží, protože ta se dá poslat rovnou do skriptu. Popis
|
||||
toho, jak má runtime vypadat, je v
|
||||
[10-runtime-a-kapacita.md](10-runtime-a-kapacita.md).
|
||||
|
||||
Externí ID hlídá jedinečnost v paměti procesu. Nad databází k tomu patří
|
||||
částečný unikátní index na dvojici `(tenant_id, external_id)`, aby to platilo
|
||||
i při běhu na víc strojích.
|
||||
@@ -2,6 +2,62 @@
|
||||
|
||||
Nejnovejsi nahore.
|
||||
|
||||
## 2026-08-13 - ticketovaci system: udalosti, externi ID, statistiky, widgety
|
||||
|
||||
Popis v [18-ticketovaci-system.md](18-ticketovaci-system.md).
|
||||
|
||||
### Pridano - prijem udalosti
|
||||
|
||||
- `POST /webhook/ticket/:token`: **jakakoliv udalost se muze stat ticketem**.
|
||||
Token patri firme, ne automatizaci, takze zalozit ticket jde i bez stromu.
|
||||
- `externalId` na ticketu, **unikatni v ramci firmy**. Dalsi udalost se stejnym
|
||||
ID se navesi na existujici ticket misto zalozeni druheho. Cislo a retezec
|
||||
jsou tentyz klic, jinak by `3` a `"3"` byly dva tickety.
|
||||
- Udalosti se u ticketu drzi cele vcetne prijatych dat a jdou rozbalit
|
||||
v detailu. Je to neco jineho nez log: log je nase stopa, udalost fakt zvenku.
|
||||
|
||||
### Pridano - co se meri
|
||||
|
||||
- `firstResponseAt`, `resolvedAt`, `resolvedById` a `reopenCount` na ticketu.
|
||||
Bez nich neslo rict, kdo kolik odbavil ani jak dlouho zakaznik cekal.
|
||||
- `getAgentStats`: odbavene za obdobi, fronta, medianove casy do vyreseni
|
||||
a do prvni reakce, vracene tickety. Median zamerne, ne prumer.
|
||||
- Widget **Vykon resitelu** a detail osoby pouzivaji tutéž funkci, takze
|
||||
cisla sedi na obou mistech.
|
||||
|
||||
### Pridano - widgety
|
||||
|
||||
- Klient konecne vola `/api/dashboard/widget-data`. Predtim endpoint existoval,
|
||||
ale nikdo ho nepouzival, takze vlastni widget hlasil "nepodarilo se zobrazit".
|
||||
- Novy zdroj `connector`: co umi zjistit napojena sluzba, jde vytahnout do
|
||||
dlazdice. Vola se tentyz skript jako v kroku automatizace, vysledek se
|
||||
cachuje (`ttlSec`, nejmene 30 s).
|
||||
- Mrtvy odkaz v rozlozeni jde v rezimu uprav odstranit, ne jen precist.
|
||||
|
||||
### Zmeneno
|
||||
|
||||
- **Akce a widgety maji vlastni zalozku**, uz nejsou v nastaveni. Je to
|
||||
definice toho, co aplikace umi, stejna uroven jako automatizace.
|
||||
- **Telo akce se sklada stromem**, ne JSONem v textarei. Je to tentyz editor
|
||||
jako u automatizaci, jen misto karty spoustece je "spousti clovek".
|
||||
- Nova zalozka **Lide** se seznamem resitelu a detailem osoby.
|
||||
- Seznam ticketu i lidi ma **dva pohledy**, tabulku a dlazdice.
|
||||
- Dlouhe pomlcky pryc z celeho projektu (48 znaku ve 23 souborech).
|
||||
|
||||
### Opraveno
|
||||
|
||||
- `createTicket` bral `typeId`, `fields`, `tags` i `assigneeGroupId`, ale
|
||||
**nikdy je neukladal**. Ticket zalozeny s typem tak zustaval bez typu
|
||||
a bez vlastnich poli.
|
||||
|
||||
### Overeno
|
||||
|
||||
21 kontrol proti bezicimu serveru v rezimu souboru: navazani druhe udalosti na
|
||||
tentyz ticket, oddeleni firem pri stejnem externim ID, ulozeni typu a poli
|
||||
z prijmu, vyreseni s casem i clovekem, zapocteni navratu z vyreseno, cisla ve
|
||||
widgetu vykonu, cele chybove hlaseni u widgetu nad nenapojenym konektorem,
|
||||
detail osoby, rozsah parametru akce, ulozeni stromu akce a navigace.
|
||||
|
||||
## 2026-08-13 - firmy, prava, typy ticketu, akce, widgety a uloziste pro vsechno
|
||||
|
||||
Dodelany cely [navrh rozsireni](09-navrh-rozsireni.md) a vsechna data se
|
||||
|
||||
Reference in New Issue
Block a user