Seed z repozitare, zatezove testy, worker bez spanku, dialogy bez rozmazani

Nastaveni prezije nasazeni: seed/records.json se pri prazdnem ulozisti
nacte misto ukazkovych dat (zive uloziste se nikdy neprepisuje). Soubor
nese soucasny stav produkce (firmy s provozovatelem, role, typ ticketu,
akce, widgety, skupiny, rozlozeni). Novy GET /api/admin/export a skript
npm run seed:export pro dalsi exporty, Dockerfile slozku kopiruje.

Vykonnostni testy (npm run test:perf) nad 200 firmami a 10 000 tickety
a zatezovy skript (npm run load) proti bezici instanci vcetne davky
udalosti na webhook. Mereni odhalilo strop workeru: po obsazeni vsech
mist spal sekundu, takze fronta odbavila nejvys 4 behy za sekundu. Ted
ceka na prvni dokonceny beh: 500 udalosti za 1,3 s (395 behu/s). Strop
posluchacu streamu zvednut na 2 000.

Dialogy: prekryv modalu a menu v portalu bez backdrop-blur, tecka Zive
pulzuje jen pri navazovani spojeni - rozmazani cele obrazovky pod trvalou
animaci sekalo video vedle portalu. Bublina udalosti drzi 0,5 s.

Dokumentace 14, 19, 20, 22, 04, 01, 03, 15 a 99 aktualizovana.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
JiriUhlir
2026-09-09 20:41:42 +02:00
co-authored by Claude Fable 5.1
parent c25e826766
commit ea9387bea9
44 changed files with 3512 additions and 28 deletions
+81
View File
@@ -2,6 +2,87 @@
Nejnovejsi nahore.
## 2026-09-09 - Vykonnostni a zatezove testy, worker uz nespi pri plnem bazenu
Aplikace ma zvladat stovky uzivatelu a tisice kroku automatizaci, ale merit
to nebylo cim. Pribyly dve sady:
- `npm run test:perf` (`tests/perf/*`, `vitest.perf.config.ts`): horka
mista v procesu nad syntetickymi daty (200 firem, 1 000 uctu, 10 000
ticketu): seznamy a filtry ticketu, vytizeni a statistiky, prijem udalosti
s deduplikaci, prava a pristup, beh stromu se smyckou, fronta (zarazeni
a odbaveni 5 000 behu), data widgetu pro 24 dlazdic, sbernice udalosti pro
500 klientu. Kazdy test tiskne median ze tri behu a hlida rozpocet 3 az 5x
nad zmerenym casem, aby nekolisal. Mimo `npm test`, bezi na vyzadani.
- `npm run load` (`scripts/load-test.mjs`, bez zavislosti): zatez proti
bezici instanci (lokalni build i Postgres): virtualni uzivatele s realnou
smesi dotazu, otevrene SSE, volitelne davka udalosti webhooku a mereni,
jak rychle ji fronta odbavi. Vystup p50/p95/p99 na endpoint, propustnost,
chyby, `load-report.json`. Cisla z prvniho mereni jsou
v [19-kapacita-200-firem.md](19-kapacita-200-firem.md): 100 uzivatelu,
2 800 dotazu za sekundu, 0 chyb, p99 pod 45 ms v rezimu souboru.
Mereni naslo skutecnou brzdu: `worker.ts` po obsazeni vsech ctyr mist spal
sekundu (`IDLE_MS`) a pak teprve zkusil frontu znovu, takze strop byl presne
4 behy za sekundu bez ohledu na to, jak rychle behy konci. Davka 2 000
udalosti webhooku se za tri minuty odbavila jen z 724. Ted worker pri plnem
bazenu ceka na prvni dokonceny beh (`Promise.race` nad bezicimi) a spi jen
pri prazdne fronte. Strop posluchacu sbernice zvednut z 200 na 2 000
(`MAX_STREAM_LISTENERS`), 500 otevrenych portalu uz nehlasi varovani.
Sekani videa vedle portalu s tim nesouviselo: bylo to rozmazani cele
obrazovky pod dialogem, viz zaznam nize.
## 2026-09-09 - Nastaveni prezije nasazeni: seed z repozitare
Nasazeni bezi v rezimu `file` bez svazku a bez `DATABASE_URL`, takze kazdy
redeploy smazal data a spravce platformy zadaval znovu provozovatele, ucty,
widgety a rozlozeni. Spravne reseni je databaze nebo svazek (infrastruktura
mimo repo). Do te doby se konfigurace drzi v repu a pri startu se nasype sama.
| Co | Jak |
| ------- | -------------------------------------------------------------------------------------------- |
| soubor | `seed/records.json` (`SEED_FILE`, vychozi `./seed/records.json`, prazdne = vypnuto) |
| tvar | `{ exportedAt, kinds: { <druh>: [zaznam] } }`, druh je `store.kind` |
| druhy | `tenant`, `user`, `role`, `personGroup`, `tenantFeatures`, `ticketType`, `ticketAction`, `customWidget`, `dashboardLayout`, `automation`, `tenantScript` (`SEED_KINDS`) |
| kdy | jen do prazdneho uloziste, na stejnem miste jako seed z kodu; druh v souboru vyhrava, i prazdny |
| kde | `seedFromFile(kind, seed)` v `src/data/store/seedFile.ts`, vola ho `defineStore` v `init`; uloziste ani `bootstrap.ts` se nemeni |
| chyby | chybejici soubor ticho, rozbity soubor `console.error` a kod, cizi druh varovani |
| export | `GET /api/admin/export` (spravce platformy, `audit.view`, audit `admin.export`), `exportSeed` v `src/data/seedExport.ts` |
| skript | `npm run seed:export` (`scripts/export-seed.mjs`, cisty Node): `SEED_EXPORT_URL`, `SEED_EXPORT_EMAIL`, `SEED_EXPORT_PASSWORD` |
Co v souboru neni: konektory (udaje sifrovane klicem, ktery se meni
s nasazenim), pozvanky (prosle), tickety, incidenty, audit, upozorneni,
prilohy, fronta. Ucty jsou v nem **vcetne `passwordHash`**, jinak by se po
nasazeni nikdo neprihlasil; repozitar proto musi zustat soukromy.
Testy: `tests/data/seedFile.test.ts` (9, rezim souboru nad docasnou
slozkou: prazdne uloziste bere soubor, neprazdne si necha svoje, prazdny
druh vyhrava, cizi druh se ignoruje, rozbity a chybejici soubor),
`tests/routes/adminExport.test.ts` (5: 401, 403, druhy a hashe, bez
konektoru a provoznich dat, audit). V `tests/setup.ts` je `SEED_FILE`
prazdny, aby testy v pameti nezavisely na obsahu repa. Nove `scripts/**/*.mjs`
v eslintu jako Node ESM, `SEED_FILE` v `.env.example`.
## 2026-09-09 - Otevreny dialog sekal video (podruhe)
Po predchozi oprave (`.glass` bez rozmazani) zustalo rozmazani na podkladu
modalu a na prekryvu menu v portalu. Obe vrstvy jsou pres celou obrazovku
a pod nimi lezi lepici hlavicka, ktera je rozmazana taky. V hlavicce navic
trvale pulzovala tecka "Zive" (`animate-pulse`, nekonecna animace). Vysledek:
s kazdym otevrenym dialogem prohlizec 60x za sekundu prepocitaval rozmazani
cele plochy, vnorene dvakrat, a vedle portalu sekalo video.
Podklad modalu i prekryv menu jsou ted jen tmava plocha bez `backdrop-blur`
(`Modal.tsx`, `DashboardLayout.tsx`). Tecka "Zive" pulzuje jen pri
navazovani a obnove spojeni, ve stavu "Zive" stoji (`LiveIndicator.tsx`).
Rozmazani zustava jen na lepicich hlavickach a na menu verejneho webu,
viz [22-znacka-a-design.md](22-znacka-a-design.md).
Bublina o udalosti (`EventToasts.tsx`) drzi pul sekundy misto sesti
(rozhodnuti zadavatele): je to zablesk "neco se stalo", podrobnosti jsou
v seznamu, na ktery ukazuje, a cislo u zalozky zustava.
## 2026-09-09 - Kolacovy graf ve vlastnim widgetu
Vlastni widget s kreslenim "Graf" bral jen casovou radu; pokus o graf