18. Audit historyworkers — technická dokumentace
18. Audit historyworkers — technická dokumentace
www.iskasa.eu · návod k modulu Akce
Kompletní dokumentace auditu historyworkers / HW_Log — stejný obsah je dostupný i na samostatné stránce
AuditHistoryWorkers.asp
(vhodné pro tisk a odkazování mimo návod).
Uživatelský přehled: 18. Audit a historie změn u akce.
Audit systému historyworkers — DOVIS / ISKASA
Kompletní technická a uživatelská dokumentace zápisu do tabulky historyworkers,
zobrazení v historie.x a forenzního standardu HW_Log.
· stav implementace: Fáze 0–7 hotovo (červen 2026)
· soubor: AuditHistoryWorkers.asp
aa=3753, aa=6512 (opakování/kopie), aa=6482 (step15/step50).
Zbývá provozně: nasadit SQL oprávnění na DB, pravidelná archivace, volitelně audit role zz.
- Shrnutí — jsou všechny položky u akcí auditovány dostatečně?
- Forenzní audit — co je potřeba a proč
- Postup přestavby — krok za krokem
- Fáze 5 — detail kroků (5.1 → 5.9)
- Test opakování aa=6512
- Test kopie + kolize aa=6512
- Prompty pro implementaci (Cursor)
- Přehled architektury
- Schéma tabulky
- Tři mechanismy zápisu
- Výjimky a filtry
- Explicitní audit (významné akce)
- Pasivní audit (každá stránka)
- Filtry a vyhledávání historie.x (Fáze 6)
- Integrita a provoz (Fáze 7)
- 16. Návod pro uživatele — co historie.x umí
- Zobrazení v historie.x
- Známé problémy a kolize
- Návrh lepšího řešení
- Plán implementace
- Životní cyklus akce — vložení
- Matice všech položek akce
- Vložení / editace / mazání podle operace
- Audit podle uživatele — identifikace a kolize
- Konkrétní zlepšení pro historie.x?aa=
Shrnutí — jsou všechny položky u akcí auditovány dostatečně?
HW_Log / HW_LogDiff s TypAkce, Modul, EntitaTyp,
EntitaId, Vysledek a diff DataPred/DataPo.
UI historie.x (Fáze 6) umožňuje filtrovat, exportovat CSV a skrýt legacy šum.
Stále slabé nebo mimo rozsah: Colosseum, step99 úkoly, pasivní prohlížení (skryté ve forenzním pohledu),
staré řádky bez TypAkce, volitelně vypnutý audit role admin=zz.
Co je v pořádku (audit funguje)
Tyto oblasti mají strukturovaný zápis přes HW_Log / HW_LogDiff (Fáze 2–5):
- Základ akce — vložení, editace, mazání (
step01Vloz,AkceDel) - Prostory — step02 / step021
- Mobiliář — step03
- Personál — step04 včetně Multi (
step04vlozMulti— Fáze 5.5) - Služby — step07 včetně Multi
- Kalkulace — step06 (referenční implementace HW_LogDiff, 22+ větví)
- Technika / nabídky — step08–10
- Auta (step50) —
step50HistLib.x+ kalkulace step06 - Nákladové listy (step15) —
step15HistLib.x - Opakování / kopie akce —
step01HistLib,AkceKopieHistLib - Energie — step94 / step95
- Smlouvy — step60 (
SmlouvuVloz,SmlouvyDel, náhled/tisksmlouva01.x) přesSmlouvyHistLib.x/HW_LogDiff - Přílohy / dokumenty — upload, mazání (
FilesAkceUpload,FilesDokumentUpload,Akce*Del) - DigiSign / podpis (step75) — odeslání, stavy obálky, příjemci, stažení auditní stopy PDF (
DigiSignHistLib.x)
Co auditováno není nebo jen slabě
| Položka / modul | Stav auditu | Poznámka |
|---|---|---|
Kopie / opakování akce (akceopakuj, step01OpakujRun) | HW_Log | Fáze 5.1 — CREATE + DENIED při kolizi prostor; viz test aa=6512 |
Jednorázová kopie (akcekopiruj, akcekopie_vloz.x) | HW_Log | Fáze 5.9 — CREATE + KOLIZE + DENIED; ověřeno aa=6512 → 6572 |
| DigiSign / podpis (step75) | HW_Log | Odeslání, sync/webhook stavy, příjemci, auditní stopa PDF — viz 4.8 DigiSign |
| Nákladové listy (step15) | HW_Log | step15HistLib.x, step15Vloz.x, step15Del.x — Fáze 5.3 |
| Auta (step50) | HW_Log | step50HistLib.x + TimeLine — Fáze 5.4 |
| Catering step43 — mazání nabídky | HW_Log | step43NabidkaDel.x — Fáze 5.6 |
| Technika po dnech (step14) | HW_Log | step14VlozPoDnech.x |
Hromadné vložení (*vlozMulti.x step03/04/07) | HW_Log | Jednotlivě + souhrn ids= — Fáze 5.5 |
| Mazání catering nabídky (step43) | HW_Log | step43NabidkaDel.x — Fáze 5.6 |
| Colosseum, protokol, step99 úkoly | Pasivní | Jen „Stranka:" nebo nic |
| Mazání dokumentů akce (step70) | HW_Log | AkceDokumentyDel.x, snapshot názvu souboru — Fáze 5.8 |
Proč to u starých záznamů stále nestačí
U řádků zapsaných přes HW_Log (Fáze 2–5) jsou mezery vyřešeny. U legacy zápisů (jen PopisXX) nebo u modulů mimo rozsah migrace platí:
- Duplicitní záznamy — u legacy handlerů stále možné; u HW_Log blokuje
HistLoggedpasivní CESTU C - Pasivní šum — ve výchozím pohledu
view=forensicskryt; staré řádkyStranka:zůstávají v DB - Legacy bez EntitaId — staré logy mají text „Opraven personál: XY" bez
EntitaId - Legacy bez diff — u starých UPDATE bez
DataPred/DataPo - Duplicita step04 vs step06 — stejná položka může mít 2 záznamy (krok + kalkulace)
- Referer vs handler — URL stále ukazuje handler, ne dialog kde uživatel klikl
Celkové hodnocení pokrytí
| Oblast akce | Odhad pokrytí operací | Dostatečnost pro spory |
|---|---|---|
| Jádro akce (step01–07, step06 kalkulace) | ~90 % operací přes HW_Log | Vysoká — TypAkce, EntitaId, diff u migrace |
| Technika (step08–10, step14) | ~85 % | Vysoká — step14 po dnech hotovo (5.7) |
| Vedlejší moduly (15, 43, 50, kopie akce…) | ~80 % (step15/50/43 hotovo Fáze 5) | Dobrá — ověřeno aa=6482, aa=6512 |
| Kvalita záznamu (forenzní analýza) | HW_Log moduly splněny; legacy řádky bez TypAkce | MVP splněno — filtry, export, diff v UI (Fáze 6) |
Nejvyšší priority doplnění
- hotovo Kopie akce (opakování) — 5.1
- hotovo DigiSign — 5.2 / 4.8
- hotovo + ověřeno Nákladové listy — 5.3
- hotovo + ověřeno Auta — 5.4
- hotovo Multi vložení — 5.5
- hotovo Mazání catering nabídky — 5.6
- hotovo Technika po dnech — 5.7
- hotovo Mazání dokumentů — 5.8
- hotovo Kopie + kolize — 5.9
- hotovo Hotfix — pasivní
Stranka:skryto ve forenzním pohledu;HistLoggedproti duplicitám (Fáze 1)
Detailní matice položek: kapitola 12 · operace CREATE/UPDATE/DELETE: kapitola 13 · uživatel a kolize: kapitola 14 · co konkrétně chybí pro forenzní audit.
Forenzní audit — co je potřeba a proč
Forenzní audit (v kontextu DOVIS) znamená schopnost po letech nebo při sporu
jednoznačně odpovědět na otázky typu: kdo, kdy, co přesně změnil
u akce aa=3753, z jaké hodnoty na jakou, zda operace proběhla nebo byla zamítnuta,
a zda záznam nebyl duplicitní nebo zavádějící.
Běžný provozní přehled v historie.x (všechny kroky včetně prohlížení) stále obsahuje šum —
pro forenzní analýzu používejte výchozí pohled view=forensic a filtry Fáze 6 (viz návod).
Co forenzní audit musí umět odpovědět
| Otázka při sporu | Proč je důležitá | Dnes v DOVIS |
|---|---|---|
| Kdo provedl krok? | Identifikace odpovědné osoby — personální, smluvní, disciplinární důsledky | Ano — KodU + Jmeno ze session |
| Kdy přesně (s vteřinou)? | Časová posloupnost — „kdo smazal dřív než druhý uložil" | Ano — sloupec DatumCas + Den/Hodin/Minuta/Sekunda |
| Co se změnilo (konkrétní položka)? | „Smazal personál" vs. „změnil cenu personálu" — jiná odpovědnost | Ano u HW_Log — TypAkce, Modul, EntitaTyp, EntitaId |
| Z čeho na co (diff)? | Dokázat rozsah škody — cena 10 000 → 1 000, termín posunut o týden | Ano u HW_Log — DataPred/DataPo; UI fdiff=1 |
| Typ operace — vložení / editace / mazání / zamítnuto? | Rozlišit neúspěšný pokus od skutečné změny dat | Ano — sloupec TypAkce (CREATE/UPDATE/DELETE/DENIED/AUTH_*) |
| Kde uživatel klikl vs. kde běžel kód? | Handler akcedelpotvrd.x ≠ stránka se seznamem akcí |
Částečně — URL = handler; Referer v Odkud nespolehlivý; RefererPage zatím ne |
| Byla operace úspěšná? | Neoprávněné smazání musí být vidět i když data zůstala | Ano — sloupec Vysledek (ok/denied/error) + barevné řádky UI |
| Je záznam jediný za akci? | Dva řádky ve stejnou vteřinu = nejasnost co se stalo | Částečně — HistLogged snižuje duplicity; step02/04 vs step06 stále 2 záznamy |
| Byly všechny moduly akce sledovány? | Kopie akce, nákladové listy, auta — stejná váha jako personál | Ano u hlavních modulů — Fáze 5; výjimky: Colosseum, step99 |
| Přihlášení / odhlášení uživatele? | Dokázat, že v daný čas pracoval konkrétní účet (sdílené PC, únik hesla) | Ano — Fáze 1.5, KodAkce=0, historie.x bez aa |
1. Identita uživatele — co doplnit a proč
| Požadavek | Proč | Stav dnes | Implementace |
|---|---|---|---|
| KodU + Jmeno u každého záznamu | Primární důkaz „kdo" — musí být v okamžiku zápisu, ne dopočítáno | OK | Zachovat; u admin=zz zvážit logování (dnes vypnuto) |
| SessionId / RequestId | Propojit více kroků jedné operace; odhalit duplicitní INSERT | OK | Sloupec RequestId — Fáze 2.2, generován v !StrUvodConfig.x |
| Audit přihlášení / odhlášení / neúspěšného loginu | Časová osa: „účet B byl přihlášen 14:00–16:30" — korelace s kroky akce | OK | PrihlaseniDokonceni.x, logoff.x — Fáze 1.5 |
| IP adresa (s poznámkou k proxy) | Doplňkový důkaz — stejná IP u dvou KodU = sdílené prostředí | Ukládá se | Doplnit do exportu; ne spoléhat jako jediný důkaz |
2. Entita a operace — co doplnit a proč
Forenzní analýza potřebuje strojově filtrovatelné údaje, ne parsování HTML v poli Popis.
Text „Opraven personál: [název položky]" nestačí — musí existovat vazba na řádek v dovakcepersonal.
| Požadavek | Proč | Příklad |
|---|---|---|
| TypAkce (enum) | Filtr: jen mazání, jen zamítnuté pokusy — bez hledání v textu | CREATE, UPDATE, DELETE, DENIED, AUTH_LOGIN, PAGE_VIEW |
| Modul | Který krok akce — step04, step06, akce… | step04 |
| EntitaTyp | Druh položky v rámci modulu | personal, misto, technika, smlouva, priloha |
| EntitaId | Jednoznačná vazba na smazanou/upravenou položku — i po smazání z DB | KodAkcePersonal=8842 |
| Vysledek (ok / denied / error) | Neúspěšné smazání musí být v historii oddělené od úspěšného — jinak „kdo smazal" nejde dokázat u zamítnutých pokusů | denied — Nesprávná zodpovědná osoba |
| DataPred / DataPo (JSON nebo key=value) | Diff — bez toho nelze prokázat rozsah změny ceny, termínu, kusů | cena: 5000→4500; terminOd: 1.3.→5.3. |
HW_Log / HW_LogDiff používají strukturovaná pole (TypAkce, EntitaId, diff).
Staré řádky (jen PopisXX) nelze spolehlivě filtrovat bez textového hledání — ve UI použijte checkbox „Skrýt legacy" (Fáze 6.1b).
3. Kompletní pokrytí modulů — co doplnit a proč
Každá položka akce musí mít symetrický audit pro vložení, editaci i mazání. Mezery = díry v důkazním řetězci.
| Modul | Proč je pro forenzní audit kritický | Priorita |
|---|---|---|
Kopie akce (akceopakuj) | Originál vs. kopie — kdo vytvořil duplicitní akci a kdy | hotovo 5.1 · 6512 |
Jednorázová kopie + kolize (akcekopiruj) | Kdo zkopíroval akci, přes jakou kolizi prostor/sklad, ProstoryOK | hotovo 5.9 · 6512→6572 |
| DigiSign step75 | Právní stopa — odeslání, stavy, příjemci, auditní PDF | hotovo (4.8) |
| Nákladové listy step15 | Finanční dopad — kdo schválil / smazal náklad | hotovo 5.3 |
| Auta step50 | Náklady akce — HW_Log + TimeLine | hotovo 5.4 |
| Multi vložení step03/04/07 | Hromadná operace — souhrn ids= | hotovo 5.5 |
| Mazání dokumentů step70 | Symetrie k uploadu — kdo smazal smlouvu / PDF | hotovo 5.8 |
| Technika step14 (po dnech) | Alternativní cesta editace techniky mimo step10 | hotovo 5.7 |
4. Integrita a spolehlivost záznamu — co doplnit a proč
| Požadavek | Proč | Řešení v DOVIS |
|---|---|---|
| Jeden záznam za jednu business operaci | Při sporu „který řádek je pravda?" — duplicity znehodnocují důkaz | SESSION("HistLogged") + přeskočit pasivní zápis v !StrErrorKonec |
| Bez falešných kroků z prohlížení | „Uživatel A navštívil step04" ≠ „Uživatel A editoval personál" — zavádí při výslechu | Nelogovat PAGE_VIEW pro /step*.x v historii akce; nebo TypAkce=PAGE_VIEW skrýt ve výchozím filtru |
| Zápis před redirectem | Po RR() se session může změnit; handler musí logovat před opuštěním stránky | Inline ActiveHistoryWorkers před každým RR() — již částečně dodrženo |
| Log i u zamítnutých operací | „Kdo se pokusil smazat akci" je forenzně důležitější než ticho | TypAkce=DENIED, prefix [ZAMÍTNUTO], Vysledek=denied |
| Append-only log (neměnit, nemazat) | Důkazní hodnota — auditní záznam nesmí jít upravit z aplikace | hotovo skript historyworkers_integrita + archivace (Fáze 7) |
| Index (KodAkce, DatumCas, KodU) | Rychlé dotazy „vše od uživatele X u akce Y v den D" | hotovo Fáze 3 — sloupec DatumCas + indexy |
5. Kontext akce — co doplnit a proč
- KodAkce — vždy explicitně z handleru, ne odvozovat z URL pro pasivní kroky (jinak falešná vazba)
- RefererPage + ActionPage — dvě URL: odkud přišel formulář, kde se zpracoval (řeší kolizi handler vs. kliknutí)
- Snapshot smazané položky — při DELETE uložit název, termín, cenu do PopisAkce (data v DB už nejsou)
- Korelace s cenovou historií —
AkceHistorieCenGraf.x+ historyworkers musí mít stejné EntitaId pro stejnou změnu ceny
6. Zobrazení a export pro forenzní analýzu — co doplnit a proč
V historie.x?aa= musí být možné:
| Funkce UI | Proč | Stav |
|---|---|---|
Výchozí filtr bez Stranka: | Provozní šum maže signál — forenzní timeline jen DATA_* a DENIED | hotovo view=forensic |
| Filtr podle KodU | „Vše co udělal uživatel (KodU) u této akce" — základ výslechu | hotovo select + fq |
| Filtr TypAkce (CREATE/UPDATE/DELETE/DENIED) | Izolovat mazání nebo neúspěšné pokusy | hotovo ftyp |
| Filtr oblasti / Modul / EntitaTyp | Jen personál, jen prostory — bez LIKE na Popis | hotovo fkat, fmod ve formuláři |
| Filtr období / konkrétní den | „Co se stalo v květnu / 15. 10." | hotovo Obdobi+rok, dd, fq |
| Rychlé vyhledávání (více kritérií najednou) | person nikol kveten bez ručního klikání v tabulkách | hotovo fq + krok 6.1 |
| Text v popisu / diff | Doplnění nerozpoznaných tokenů nebo volný text | hotovo ftxt |
| Barevné rozlišení Vysledek | Ok = zelená, Denied = červená — okamžitá orientace | hotovo badge v detailu |
| Sloupec EntitaId + odkaz na detail (pokud existuje) | Propojení log ↔ data | hotovo sloupec Entita |
| Export CSV / PDF | Předání právníkovi, archiv — HTML tabulka v prohlížeči nestačí | hotovo krok 6.3 (AkceHistorieExport.x) |
| Detail diff (DataPred → DataPo) | Bez otevírání SQL nebo hádání z PopisXX | hotovo + fdiff=1 |
7. Rozdíl: provozní audit vs. forenzní audit
| Provozní audit (dnes) | Forenzní audit (cíl) | |
|---|---|---|
| Účel | Přehled aktivity u akce | Důkaz o konkrétní změně a odpovědnosti |
| Formát | Volný text PopisXX + pasivní Stranka: | Strukturovaná pole HW_Log + diff |
| Pokrytí | Hlavní kroky + pasivní návštěvy | ~80–90 % mutací HW_Log; legacy + Colosseum/step99 mimo |
| Neúspěšné operace | DENIED u AkceDel; Vysledek=denied | Stejné — konzistentní u migrace |
| Duplicity | Sníženo HistLogged; step04/06 duplicita zůstává | RequestId + 1 business záznam na request |
| Export | CSV (Fáze 6.3) + obrazovka | CSV: DatumCas, KodU, TypAkce, EntitaId, diff, IP |
| Spolehlivost u soudu / sporu | Střední u HW_Log; nízká u legacy | Vysoká u nových záznamů s diff |
8. Checklist implementace forenzního auditu
Pořadí doporučené pro maximální dopad při minimálním rozsahu:
- F0 hotfix — HistLogged proti duplicitám; audit login/logout; [ZAMÍTNUTO] u denied; skrýt Stranka: v historie.x
- F1 knihovna —
HistoryWorkersLib.xs HW_Log(TypAkce, Modul, EntitaTyp, EntitaId, …) - F2 schéma DB — TypAkce, Vysledek, EntitaTyp, EntitaId, DataPred, DataPo, RequestId, DatumCas + indexy
- F3 mezery modulů — akceopakuj, step15, step50, *Multi, mazání dokumentů
- F4 diff u UPDATE — step01 termíny, step04/06 ceny — načíst starý stav před UPDATE
- F5 UI + export — filtry, CSV, diff sloupec v AkceHistorieShow.x
- F6 integrita — INSERT-only oprávnění (SQL), archivace, audit admin=zz volitelně, monitoring INSERT/min — viz Fáze 7
Detailní postup implementace: kapitola 3 — krok za krokem.
KodU · DatumCas · TypAkce · EntitaTyp · EntitaId · KodAkce · Vysledek · popis + diff.
Bez EntitaId a bez Vysledek nelze spolehlivě řešit spory „kdo smazal" a „kdo změnil cenu".
Související kapitoly: schéma tabulky · kolize kdo vs. kde · návrh HW_Log · operace CREATE/UPDATE/DELETE · audit podle uživatele.
3. Postup přestavby auditu — krok za krokem
Níže je doporučené pořadí práce od nejmenšího rizika k plnému forenznímu standardu.
Každá fáze je samostatně nasaditelná — po Fázi 0–1 uvidíte okamžité zlepšení v
historie.x?aa= bez změny databáze.
- Hlavní reference —
KodAkce = 3753(historie.x?aa=3753): většina kroků Fáze 1–4, baseline a id v tabulkách. - Opakování a mazání kopií —
KodAkce = 6512(test 30. 6. 2026): 28 kopií6568–6595, potéAkceDelKopiehard delete.
FÁZE 0 — Příprava (1 den)
Krok 0.1 — Testovací akce a baseline
| Parametr | Hodnota |
|---|---|
| Testovací akce (hlavní) | KodAkce = 3753 |
| Testovací akce (opakování) | KodAkce = 6512 — kopie 6568–6595, viz § test 6512 |
| URL historie | historie.x?aa=3753 |
| Baseline před začátkem úprav | 2 467 záznamů v historyworkers |
baseline_max_id | 1 660 945 (MAX(id) pro KodAkce = 3753) |
| Datum baseline | 21. 6. 2026 |
nove_od_baseline po ručním testu | 42 (stav před Fází 1, 22. 6. 2026) |
- Používat výhradně akci
aa=3753— nevytvářet novou testovací akci. - Před první úpravou kódu ověřit baseline:
SELECT COUNT(*) AS pocet FROM historyworkers WHERE KodAkce = 3753; -- Očekáváno před testem: 2467
- Uložit si také nejvyšší
id(pro výpis jen nových zápisů):SELECT MAX(id) AS baseline_max_id FROM historyworkers WHERE KodAkce = 3753; -- Baseline: baseline_max_id = 1660945
- Po každém testovacím kroku zjistit, kolik záznamů přibylo:
-- Kolik nových oproti baseline 2467 SELECT COUNT(*) - 2467 AS nove_od_baseline FROM historyworkers WHERE KodAkce = 3753; -- Výsledek po ručním testu (22. 6. 2026): nove_od_baseline = 42 -- Jen záznamy vložené po začátku testu (id > baseline_max_id) SELECT id, KodU, Den, Mesic, Rok, Hodin, Minuta, Sekunda, Popis, URL FROM historyworkers WHERE KodAkce = 3753 AND id > 1660945 ORDER BY id DESC LIMIT 20;
- Ruční scénáře na
aa=3753— po každém kroku zapsatnove_od_baseline(očekávání uvedeno u kroků Fáze 1):- Prohlížení
step04.x?aa=3753bez uložení - Vložení / oprava personálu (
step04vloz) - Oprava ceny v kalkulaci (
step06) - Neúspěšné smazání akce (špatná zodpovědná osoba)
- Prohlížení
- Screenshot
historie.x?aa=3753před Fází 1 a po každé dokončené fázi.
| Operace (aa=3753) | Před úpravami (typicky) | Cíl po Fázi 1 |
|---|---|---|
| Jen otevřít step04 / step06 | +1 řádek „Stranka: …" | +0 |
| Uložit personál | +2 (detail + Stranka:) | +1 |
| Opravit cenu v step06 | +2 | +1 |
| Zamítnuté smazání | +1 až +2 | +1 s [ZAMÍTNUTO] |
Výsledek ručního testu před Fází 1 (22. 6. 2026)
Po scénářích z bodu 5 (prohlížení step04/step06, oprava personálu, hromadná oprava v step06):
nove_od_baseline = 42. Níže posledních 20 řádků s id > 1660945
(celkem 42 nových záznamů — v LIMIT 20 nejsou starší z testu, např. zamítnuté smazání).
- Šum „Stranka:“ id 1660985–1660987, 1660990 — pasivní návštěva step04/step06 (+4 řádky bez editace).
- Duplicita při uložení personálu: id 1660988 (detail) + 1660989 (souhrn „Změna v personálu“) + 1660990 (Stranka: po redirectu) — 1 akce = 3 řádky.
- Hromadná oprava step06: id 1660971–1660984 — 14 řádků „Oprava personál“ z jednoho uložení kalkulace (bez souhrnného řádku, ale s následným Stranka: 1660985).
| id | KodU | Datum/čas | Popis (zkráceno) | URL |
|---|---|---|---|---|
| 1660990 | 37 | 22.06.2026 6:12:17 | Stranka: /step04.x | /step04.x |
| 1660989 | 37 | 22.06.2026 6:12:16 | Změna v personálu u akce (souhrn s Kod akce, odkaz na akci) | /!step04/step04vloz.x |
| 1660988 | 37 | 22.06.2026 6:12:16 | Opraven personál: Security - Technický vchod, OD/DO 12.05.2026 | /!step04/step04vloz.x |
| 1660987 | 37 | 22.06.2026 6:12:10 | Stranka: /step04.x | /step04.x |
| 1660986 | 37 | 22.06.2026 6:12:02 | Stranka: /step04.x | /step04.x |
| 1660985 | 37 | 22.06.2026 6:11:58 | Stranka: /step06.x | /step06.x |
| 1660984 | 37 | 22.06.2026 6:11:39 | Oprava personál: Úklid - pracovní den, Kusů:2, Cena:5600, Nakup:4160 | /!step06/step06vloz.x |
| 1660983 | 37 | 22.06.2026 6:11:39 | Oprava personál: Úklid - pracovní den, Kusů:2, Cena:5600, Nakup:2880 | /!step06/step06vloz.x |
| 1660982 | 37 | 22.06.2026 6:11:39 | Oprava personál: Úklid - pracovní den, Kusů:2, Cena:4900, Nakup:2520 | /!step06/step06vloz.x |
| 1660981 | 37 | 22.06.2026 6:11:39 | Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920 | /!step06/step06vloz.x |
| 1660980 | 37 | 22.06.2026 6:11:39 | Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920 | /!step06/step06vloz.x |
| 1660979 | 37 | 22.06.2026 6:11:39 | Oprava personál: Správce DOV, Kusů:1, Cena:3000, Nakup:3200 | /!step06/step06vloz.x |
| 1660978 | 37 | 22.06.2026 6:11:39 | Oprava personál: Správce DOV, Kusů:1, Cena:2700, Nakup:2610 | /!step06/step06vloz.x |
| 1660977 | 37 | 22.06.2026 6:11:39 | Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920 | /!step06/step06vloz.x |
| 1660976 | 37 | 22.06.2026 6:11:38 | Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920 | /!step06/step06vloz.x |
| 1660975 | 37 | 22.06.2026 6:11:38 | Oprava personál: Security - Technický vchod, Kusů:1, Cena:3960, Nakup:3060 | /!step06/step06vloz.x |
| 1660974 | 37 | 22.06.2026 6:11:38 | Oprava personál: Security - Technický vchod, Kusů:1, Cena:1100, Nakup:850 | /!step06/step06vloz.x |
| 1660973 | 37 | 22.06.2026 6:11:38 | Oprava personál: Security - Technický vchod, Kusů:1, Cena:4400, Nakup:3400 | /!step06/step06vloz.x |
| 1660972 | 37 | 22.06.2026 6:11:38 | Oprava personál: Security - Technický vchod, Kusů:1, Cena:3080, Nakup:2380 | /!step06/step06vloz.x |
| 1660971 | 37 | 22.06.2026 6:11:38 | Oprava personál: Security - Technický vchod, Kusů:1, Cena:3080, Nakup:2380 | /!step06/step06vloz.x |
Krok 0.2 — Záloha a větev splněno
historyworkers, záloha celé aplikace DOVIS
a změny schématu tabulky jsou hotové — lze pokračovat Fází 1 (úpravy ASP).
| Úkol | Stav | Poznámka |
|---|---|---|
Záloha tabulky historyworkers |
hotovo | Export SQL / kopie tabulky před úpravami schématu a testy |
| Záloha celé aplikace | hotovo | Kompletní kopie webu (včetně /ActiveHistoryWorkers.x,
!StrErrorKonec.x, !StrUvod2.x a zbytku DOVIS) |
| Produkční / testovací DB — typ | zdokumentováno | MySQL, engine InnoDB, charset utf8mb3
(dump !!MySQL/DOVIS, MySQL Administrator) |
Změny schématu historyworkers |
provedeno | Sloupce a indexy z plánované Fáze 3 již nasazeny — viz tabulka níže |
Nasazené sloupce (odpovídá Kroku 3.1 — provedeno předčasně při přípravě):
DatumCasDATETIMETypAkce,Vysledek(výchozí'o'),ModulEntitaTyp,EntitaId,DataPred,DataPo,RequestId- Indexy:
idx_hw_akce_cas,idx_hw_u_cas,idx_hw_typ
FÁZE 1 — Hotfix bez změny DB (1–2 dny) · okamžitý dopad
Krok 1.1 — Zastavit duplicitní zápis implementováno
Soubory: /ActiveHistoryWorkers.x, /!StrErrorKonec.x, /!StrUvodConfig.x
Stranka: na konci stránky). Prochody mezi stránkami zůstávají — každá nová návštěva
(nový request) zapíše Stranka: … | odkud: … včetně sloupce Odkud (HTTP referer).
- Po úspěšném INSERT v
ActiveHistoryWorkers.x:SESSION("HistLogged") = True - V
!StrErrorKonec.x: pokudSESSION("HistLogged") = True, přeskočit pasivní zápis na konci requestu - Na začátku requestu v
!StrUvodConfig.x:SESSION("HistLogged") = False - Navigační záznamy: pasivní
Stranka:obsahuje cestu + query string a| odkud: referer(jen u procházení, ne u explicitních PopisXX)
Ověření (aa=3753):
- Uložit personál v step04 → bez druhého řádku
Stranka:ze stejného requestu jako explicitní zápis; po redirectu na step04 může přibýt 1 navigační řádek (to je žádoucí) - Jen proklik step04 → step06 → 2 řádky
Stranka: … | odkud: …(stopa chování) - Stále možné 2+ explicitní řádky z jedné akce (např. detail personálu + souhrn z
KontrolaZodpovedneOsoby) — řeší se později, ne HistLogged
Výsledek ověření po nasazení (aa=3753, id > 1660990)
Dotaz: SELECT id, Popis, URL, Odkud FROM historyworkers WHERE KodAkce = 3753 AND id > 1660990 ORDER BY id DESC
Přibylo 35 záznamů (id 1660991–1661025). Nový referenční baseline_max_id = 1661025 pro další testy.
step06vloz) 30 explicitních řádků
bez jediného duplicitního Stranka: /step06vloz.x na konci requestu.
Navigační prochody mezi stránkami zůstaly — 5 řádků s | odkud:.
| Skupina | Počet | id | Závěr |
|---|---|---|---|
| Navigace (proklik) | 5 | 1660991–1660995 | Stopa chování — kam + odkud v Popis i sloupci Odkud |
| Uložení step06 (1× submit) | 30 | 1660996–1661025 | Po jedné položce kalkulace jeden řádek; žádný pasivní Stranka: po uložení |
Navigační řetězec (od nejstaršího k nejnovějšímu prokliku před uložením):
| id | Kam (Popis) | Odkud (DB sloupec) |
|---|---|---|
| 1660991 | Stranka: /akce.x | step04.x?aa=3753 |
| 1660992 | Stranka: /akce.x?action=view&aa=3753 | historie.x?aa=3753 |
| 1660993 | Stranka: /step01.x?aa=3753 | akce.x?action=view&aa=3753 |
| 1660994 | Stranka: /step04.x?aa=3753 | step01.x?aa=3753 |
| 1660995 | Stranka: /step06.x?aa=3753 | step04.x?aa=3753 |
Uložení kalkulace (step06vloz.x, id 1660996–1661025):
- 6×
Oprava prostor:(GONG, Compress Hall…) - 4×
Oprava služby: - 1×
Oprava inventář: - 19×
Oprava personál: - Všechny řádky:
URL=/!step06/step06vloz.x,Odkud=step06.x?aa=3753(formulář — očekávané)
| id | Typ (zkráceno) | URL |
|---|---|---|
| 1661025 | Oprava personál: Úklid - pracovní den, Cena:5600 | /!step06/step06vloz.x |
| 1661024 | Oprava personál: Úklid - pracovní den, Cena:5600 (jiný nakup) | /!step06/step06vloz.x |
| 1661023 | Oprava personál: Úklid - pracovní den, Cena:4900 | /!step06/step06vloz.x |
| 1661000 | Oprava prostor: 1.NP - Compress Hall | /!step06/step06vloz.x |
| 1660996 | Oprava prostor: GONG - Celý objekt (příprava/úklid) | /!step06/step06vloz.x |
| … celkem 30 řádků (1660996–1661025), každá změněná položka kalkulace zvlášť | ||
Krok 1.2 — Odstranit dvojitý zápis z !StrUvod2 implementováno
Soubor: /!StrUvod2.x
!StrUvod2 byl odstraněn časný #include ActiveHistoryWorkers.x
(zápis před zpracováním handleru). Stránky s !StrUvod2 + !StrKonec2 logují jednou —
explicitně v těle skriptu nebo pasivně na konci přes !StrErrorKonec (s HistLogged z Kroku 1.1).
- hotovo Odstraněn řádek
#include ActiveHistoryWorkers.xz!StrUvod2.x - Ověření na
aa=3753(id > 1661025) — viz tabulka níže
| Handler | Cesta zápisu | Očekávaný počet řádků / operaci |
|---|---|---|
FilesAkceUpload.x |
Explicitní PopisXX = Vložena příloha… + volitelně KontrolaZodpovedneOsoby; StrKonec2 přeskočen (HistLogged) |
1 (příloha) + 0–1 (ZO souhrn) |
OvereniUzivatele.x |
Před přihlášením KodU prázdné → žádný zápis; po úspěchu redirect, případně 1× pasivní na konci requestu |
0–1 přihlášení přes PrihlaseniDokonceni (Krok 1.5) |
Delete handlery bez explicitního PopisXX (např. FilesDel.x) |
Pouze !StrKonec2 → Stranka: … | odkud: |
1 |
Handlery s explicitním zápisem (např. AkceDel.x) |
Explicitní PopisXX; StrKonec2 přeskočen |
1 na větev kódu |
SQL ověření po testu:
-- Upload přílohy k akci 3753 SELECT id, Popis, URL, Odkud FROM historyworkers WHERE KodAkce = 3753 AND id > 1661025 AND URL LIKE '%filesakceupload%' ORDER BY id DESC; -- Nesmí být dvojice stejného času: Stranka: /filesakceupload + Vložena příloha
Výsledek ověření uploadu (aa=3753, 22. 6. 2026)
Dotaz výše, id > 1661025 → 2 záznamy (id 1661028–1661029).
Nový referenční baseline_max_id = 1661029. Žádný řádek Stranka: /filesakceupload.
!StrUvod2 a bez pasivní duplicity
na konci requestu — jen explicitní záznamy.
| id | Popis (zkráceno) | URL | Odkud | Zdroj |
|---|---|---|---|---|
| 1661028 | Vložena příloha: priloha-test.pdf |
/filesakceupload.x | step05.x?aa=3753 | FilesAkceUpload.x (CESTA B) |
| 1661029 | Nová příloha v akci (souhrn ZO, Kod akce, odkaz na akci) | /filesakceupload.x | step05.x?aa=3753 | KontrolaZodpovedneOsobyZaAkci.x |
Krok 1.3 — Potlačit pasivní šum u kroků akce odloženo
Soubor: /ActiveHistoryWorkers.x
step01–step06 žádoucí —
uživatel vidí cestu historie → akce → kroky. Tento krok implementovat jen pokud se šum filtruje ve view (historie.x), ne v zápisu.
- Rozšířit podmínku jako u kontakty/hledej: pokud PATH =
/stepXX.xa PopisXX začíná „Stranka:" → neukládat. - Alternativa: ukládat s prefixem do Popis, ale ve Fázi 5 filtrovat — preferované je neukládat vůbec.
Ověření: jen otevřít step06?aa=… → v historyworkers 0 nových řádků.
Krok 1.4 — Označit zamítnuté operace implementováno
[ZAMÍTNUTO] jen u větví, kde operace selhala (práva, špatná ZO, špatné potvrzení smazání).
KontrolaZodpovedneOsobyZaAkci.x sem nepatří — zapisuje úspěšné změny provedené jiným uživatelem než ZO (notifikace), ne zamítnutí.
Upravené soubory:
| Soubor | Větev (PopisXX) | Zápis před RR |
|---|---|---|
!akce/AkceDel.x |
Špatné potvrzení čísla akce (kod <> opravdusmazat) |
ano → akcedelpotvrd |
!akce/AkceDel.x |
Obchodník nemá práva (admin=b, cizí KodU) |
ano → chybaakce2 |
!akce/AkceDel.x |
Nesprávná zodpovědná osoba |
ano → chybaakce2 |
akcedelpotvrd.x |
Nesprávná zodpovědná osoba (zobrazení formuláře smazání) |
ano → chybaakce2 |
Další handlery bez zápisu do historie (zatím jen redirect na chybovou stránku — Krok 1.4+ / Fáze 4):
FilesDel.x,AkceFilesDel.x—chybafile.x?kod=opr(cizí uploader)AkceDel.x— větevsmazat2bez shody, konecchybaakce.xbez PopisXXAkceDelKopie.x—chybaakcekopiedel.xbez historie (žádné kopie k smazání); úspěšné mazání logujeAkceDel_Log
Ověření (aa=3753, uživatel bez ZO):
SELECT id, Popis, URL FROM historyworkers WHERE KodAkce = 3753 AND id > 1661029 AND Popis LIKE '[ZAMÍTNUTO]%' ORDER BY id DESC;
Výsledek ověření (aa=3753, 22. 6. 2026)
Dotaz výše → 1 záznam (id = 1661049). Nový referenční baseline_max_id = 1661049.
[ZAMÍTNUTO].
| id | Popis | URL | Větev |
|---|---|---|---|
| 1661049 | [ZAMÍTNUTO] Obchodník nemá práva |
/!akce/akcedel.x | AkceDel.x — obchodník (admin=b) bez práv ke smazání cizí akce |
Krok 1.5 — Audit přihlášení a odhlášení implementováno
Soubory: /PrihlaseniDokonceni.x, /logoff.x
historyworkers přes ActiveHistoryWorkers.x
(stejné sloupce jako u kroků akce). KodAkce = 0 — záznam není vázaný na akci.
| Událost | Kde | PopisXX | KodAkce |
|---|---|---|---|
| Úspěšné přihlášení | PrihlaseniDokonceni.x (include z OvereniUzivatele.x, MFA…) |
Přihlášení uživatele |
0 |
| Odhlášení | logoff.x — před SESSION.Abandon |
Odhlášení uživatele |
0 |
| Neúspěšný login | OvereniUzivatele.x |
neimplementováno — bez KodU ActiveHistoryWorkers nezapisuje; zůstává error.log / budoucí tabulka |
|
Ověření:
-- Po přihlášení a odhlášení (globální záznamy, ne vázané na aa=3753) SELECT id, KodU, Popis, URL, Odkud FROM historyworkers WHERE KodAkce = 0 AND id > 1661049 AND (Popis LIKE 'Přihlášení%' OR Popis LIKE 'Odhlášení%') ORDER BY id DESC LIMIT 10;
Výsledek ověření (22. 6. 2026)
Dotaz výše v rozsahu id 1661051–1661057 → 4 auth záznamy
(2× přihlášení, 2× odhlášení, dva různí uživatelé KodU 37 a 38).
Referenční baseline_max_id = 1661057.
historyworkers s KodAkce=0;
navigační řádky po loginu (např. vynucená změna hesla) zůstávají jako Stranka: … | odkud: — to je žádoucí.
| id | KodU | Popis | URL | Odkud |
|---|---|---|---|---|
| 1661056 | 38 | Přihlášení uživatele | /overeniuzivatele.x | signin.x |
| 1661053 | 37 | Přihlášení uživatele | /overeniuzivatele.x | signin.x |
| 1661052 | 37 | Odhlášení uživatele | /logoff.x | step05.x?aa=3753 |
| 1661051 | 38 | Odhlášení uživatele | /logoff.x | / (úvod) |
Navigace po přihlášení (stejný test, KodAkce=0):
| id | KodU | Popis (zkráceno) |
|---|---|---|
| 1661057 | 38 | Stranka: /users/userheslozmena.x | odkud: signin.x |
| 1661055 | 37 | Stranka: /default.x | odkud: userheslozmena.x |
| 1661054 | 37 | Stranka: /users/userheslozmena.x | odkud: signin.x |
Krok 1.6 — Výchozí filtr v historie.x implementováno
Soubory: !akce/AkceHistorieHistLib.x, !akce/AkceHistorieShow.x
Stranka: v SQL i ve souhrnech.
Navigační stopa zůstává v DB — zobrazí se přes ?view=all nebo odkaz v UI.
| Parametr | Chování |
|---|---|
(bez parametru) nebo ?view=forensic | Výchozí — bez řádků Stranka: |
?view=all | Kompletní historie včetně procházení stránek |
SQL filtr (AkceHistSqlForensicClause v AkceHistSqlWhere a AkceHistSqlWhereSouhrn):
AND LOWER(IFNULL(historyworkers.popis,'')) NOT LIKE 'stranka:%'
UI: lišta nad souhrnem — odkaz „Zobrazit i prohlížení stránek“ / „Pouze forenzní pohled“; parametr view se drží v paginaci a filtrech (AkceHistQueryString).
Ověření (aa=3753):
historie.x?aa=3753— méně řádků, bezStranka: /step04…v detailuhistorie.x?aa=3753&view=all— včetně navigačních řádků z Kroku 1.1
FÁZE 2 — Knihovna HW_Log (2–3 dny) · sjednocení zápisu
Krok 2.1 — Vytvořit HistoryWorkersLib.x implementováno
Soubor: /HistoryWorkersLib.x (vzor: WebSpinani HistoryWorkersLogAction.x)
- hotovo
HW_InitRequest()—SESSION("HW_RequestId")ve tvaruKodU-YYYYMMDDHHMMSS-ms(jen pokud ještě není). - hotovo
HW_Log(typAkce, modul, entitaTyp, entitaId, kodAkce, popis, detail, vysledek) - hotovo Legacy INSERT (stejné sloupce jako
ActiveHistoryWorkers.x) +PopisXX,KodAkceHistorie,SESSION("HistLogged")=True. - hotovo
PopisAkce= detail (+ volitelněentitaTyp=id);Popiss prefixem[UPDATE]/[CREATE]/[DELETE]/[ZAMÍTNUTO](sloupceTypAkceaž Fáze 3.3).
Pomocné funkce: HW_SqlText, HW_TypAkcePrefix, HW_ApplyTypPrefix, HW_InsertLegacy.
Krok 2.2 — Include knihovny globálně implementováno
Soubory:
| Soubor | Úprava |
|---|---|
!!nastaveni/DB.x | hotovo po DB.OPEN → #include /HistoryWorkersLib.x (jednou na request, bez duplicity při dvojím StrUvodConfig) |
/!StrUvodConfig.x | hotovo hned po SESSION("HistLogged")=False → Call HW_InitRequest() (idempotentní; druhý include requestu ID nepřepíše) |
Řetězec: !StrUvod.x / !StrUvod2.x / !StrUvod3.x → DB.x (knihovna) → !StrUvodConfig.x (InitRequest).
Ověření: po načtení libovolné stránky s přihlášením je SESSION("HW_RequestId") neprázdné; HW_Log je volatelné bez lokálního include.
Krok 2.3 — Pilot na 3 souborech (referenční vzor) implementováno
Migrováno z inline PopisXX + ActiveHistoryWorkers na HW_Log:
| Soubor | TypAkce | Volání |
|---|---|---|
!step04/step04VlozJeden.x | CREATE | HW_Log("CREATE", "step04", "personal", Kod, KodAkce, …) |
!step04/step04vloz.x | CREATE / UPDATE | stejný vzor — hlavní formulář personálu (test aa=3753) |
!akce/AkcePersonalDel.x | DELETE | HW_Log("DELETE", …) + NazevPersonal před DELETE |
akcedelpotvrd.x | krok1 / DENIED | požadavek bez prefixu; špatná ZO → [ZAMÍTNUTO] |
!akce/AkceDel.x | DENIED ×3 | špatné potvrzení, obchodník bez práv, špatná ZO — prefix [ZAMÍTNUTO], vysledek=denied |
!akce/AkceDel.x | DELETE ×3 | skrytí akce, skrytí opakující, kompletní smazání — prefix [DELETE] |
Ověření (aa=3753, id > baseline):
- CREATE přes
step04VlozJeden(nestep04vlozMulti— ten zůstává legacy do Fáze 4.3):Popis LIKE '[CREATE]%Vložen personál%' - DELETE personál:
Popis LIKE '[DELETE]%Smazán personál%',PopisAkce LIKE '%personal=<per>%' - DENIED:
Popis LIKE '[ZAMÍTNUTO]%'— jeden řádek, bez pasivní duplicityStranka:(Krok 1.1) - Navigační
Stranka:řádky zůstávají (pasivní zápis na konci requestu) — to je očekávané
| id | Výsledek | Poznámka |
|---|---|---|
| 1661086 | OK | [DELETE] Smazán personál, NazevAkce=AkcePersonalDel, PopisAkce=personal=4232 — název chyběl (URL bez kodp, PersonalInfo až po DELETE); opraveno SELECT NazevPersonal před DELETE |
| 1661089–1661090, 1661096–1661097 | legacy | CREATE přes step04vloz.x bez [CREATE] — opraveno migrací step04vloz.x |
| 1661092, 1661099 | legacy | akcedelpotvrd.x krok1 — opraveno (prefix u krok1 zůstává prázdný jako dříve) |
| 1661093, 1661100 | OK | [ZAMÍTNUTO] Obchodník nemá práva (AkceDel) |
| 1661095–1661098 | očekáváno | navigační Stranka: |
Po migraci step04vloz.x + akcedelpotvrd.x (doplněno k pilotu 2.3): CREATE → [CREATE]%Vložen personál%, krok1 mazání beze změny textu, DENIED beze změny.
FÁZE 3 — Rozšíření databáze (1 den + test)
Krok 3.1 — ALTER TABLE historyworkers již provedeno v Kroku 0.2
ALTER TABLE historyworkers ADD COLUMN DatumCas DATETIME NULL AFTER Sekunda, ADD COLUMN TypAkce VARCHAR(32) NULL DEFAULT NULL, ADD COLUMN Vysledek CHAR(1) NULL DEFAULT 'o', ADD COLUMN Modul VARCHAR(32) NULL, ADD COLUMN EntitaTyp VARCHAR(32) NULL, ADD COLUMN EntitaId INT NULL DEFAULT 0, ADD COLUMN DataPred TEXT NULL, ADD COLUMN DataPo TEXT NULL, ADD COLUMN RequestId VARCHAR(40) NULL; CREATE INDEX idx_hw_akce_cas ON historyworkers (KodAkce, DatumCas); CREATE INDEX idx_hw_u_cas ON historyworkers (KodU, DatumCas); CREATE INDEX idx_hw_typ ON historyworkers (TypAkce, Modul);
Krok 3.2 — Backfill DatumCas u starých záznamů provedeno
UPDATE historyworkers SET DatumCas =
STR_TO_DATE(CONCAT(Rok,'-',LPAD(Mesic,2,'0'),'-',LPAD(Den,2,'0'),' ',
LPAD(Hodin,2,'0'),':',LPAD(Minuta,2,'0'),':',LPAD(Sekunda,2,'0')), '%Y-%m-%d %H:%i:%s')
WHERE DatumCas IS NULL;
Ověření:
-- žádný starý řádek bez času (kromě nových INSERTů před 3.3) SELECT COUNT(*) AS bez_datumcas FROM historyworkers WHERE DatumCas IS NULL; -- vzorek: sloupce Den/Mesic/… vs DatumCas SELECT id, Rok, Mesic, Den, Hodin, Minuta, Sekunda, DatumCas FROM historyworkers WHERE KodAkce = 3753 ORDER BY id DESC LIMIT 5;
Krok 3.3 — Upravit HW_Log a ActiveHistoryWorkers implementováno
- hotovo
HW_InsertRecord—DatumCas,TypAkce,Vysledek(o/d/e),Modul,EntitaTyp,EntitaId,RequestId - hotovo
ActiveHistoryWorkers.x— legacy:DatumCas=NOW(),TypAkce/ModulNULL,Vysledek='o',RequestIdze session - hotovo Prefix v
Popiszůstává (kompatibilita UI); filtry mohou používatTypAkce
Ověření po nasazení (aa=3753, id > 1661130, 22. 6. 2026):
| id | TypAkce | Modul | Entita | Vysl. | Poznámka |
|---|---|---|---|---|---|
| 1661135 | CREATE | step04 | personal=4983 | o | HW_Log — prefix + sloupce 3.3 |
| 1661132 | DENIED | AkceDel | akce=3753 | d | HW_Log — zamítnutí obchodníka |
| 1661131 | (prázdné) | akcedelpotvrd | akce=3753 | o | krok1 mazání — bez prefixu (záměrně) |
| 1661133–1661137 | NULL | — | 0 | o | pasivní Stranka: / notifikace ZO — legacy, DatumCas + RequestId OK |
-- nový řádek z HW_Log SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek, RequestId, Popis FROM historyworkers WHERE id > 1661130 ORDER BY id DESC; -- doplnění mezery 1661085–1661130 (INSERTy před 3.3): znovu Krok 3.2 UPDATE
Krok 4.1 — Kalkulace step06Vloz.x implementováno
- hotovo
!step06/step06HistLib.x—Step06_PredSnap,Step06_PoCena,Step06_PoMisto,Step06_PoCatering,Step06_PoSleva,Step06_PoAuto,Step06_Log - hotovo
step06Vloz.x— všech 22 míst:PopisXX+ActiveHistoryWorkers.x→Step06_Log/HW_LogDiff - hotovo U UPDATE:
DataPredpředDB.Execute,DataPopo změně (ceny, slevy, km…) - hotovo Entity:
misto,sluzba,inventar,personal,catering,spotreba,auto,akce
Ověření (aa=3753, uložení kalkulace 22. 6. 2026, id > 1661137):
| id | TypAkce | Modul | Entita | Diff | Poznámka |
|---|---|---|---|---|---|
| 1661150 | UPDATE | step06 | inventar=5127 | stejné | uložení beze změny ceny |
| 1661151–1661161 | UPDATE | step06 | personal=… | stejné | 11× personál, 1 request 07:44:46 |
Rozhodnutí 4.1b — logovat jen při rozdílu?
- Zápis do DB: zatím bez filtru — každé uložení kalkulace loguje všechny dotčené položky (1:1 s dřívějším
ActiveHistoryWorkers). - UI filtr: hotovo v
historie.x?aa=…&fdiff=1— zobrazí jen řádky kdeDataPred≠DataPo(forenzní pohled bez „prázdných“ uložení). - Volitelně později:
IF dataPred = dataPo THEN EXIT SUBvStep06_Log/HW_LogDiff— až po odsouhlasení (méně řádků v DB). - Další krok: Fáze 4.3 — migrace step04 (část už pilotně v HW_Log).
Krok 4.1c — UI historie.x hotovo
- hotovo Detail kroků: sloupce Typ (
TypAkce), Modul (sloupec DB + fallback URL), Entita (EntitaTyp=Id). - hotovo Diff porovnává hodnoty po polích (ne pořadí klíčů v řetězci) — falešné „Změna“ u prostor opraveno.
- hotovo Layout 5 sloupců — popis v posledním sloupci (bez zalomení pod datum).
- hotovo Odkaz Jen skutečné změny (diff) — parametr
fdiff=1. - hotovo Fáze 6.1 — kompaktní formulář filtrů + rychlé vyhledávání
fq(viz krok 6.1). - hotovo Fáze 6 — filtry, badge, barevné řádky, export CSV, kategorie Modul/EntitaTyp (kroky 6.1–6.4).
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek,
LEFT(Popis,80) AS Popis, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661137
AND Modul = 'step06'
ORDER BY id DESC;
-- UI: historie.x?aa=3753&Obdobi=105&rok=2026&KodU=42&fkat=Person%C3%A1l&ftyp=UPDATE
-- UI: historie.x?aa=3753&dd=20.05.2026&fq=georg+15.10
-- UI: historie.x?aa=3753&fdiff=1 (jen řádky se změnou hodnot)
Krok 4.2 — Základ akce step01 implementováno
- hotovo
!step01/step01HistLib.x—Step01_PredSnap,Step01_PoAkce,Step01_PoTerminy,Step01_PoFakturace,Step01_PoMistoBalicek,Step01_Log,Step01_LogTerminZmena - hotovo
step01Vloz.x— 7 míst: Oprava akce (UPDATE + diff), 5× změna termínů (služby/inventář/personál/technika/prostory), Nová akce (CREATE) - hotovo Fakturace:
step01VlozFakturace.x,step01VlozFakturace2.x,step01VlozFakturace3.x— UPDATEfakturace*s diff před/po - hotovo Balíčky:
step01VlozBalickyMista.x— Prostory u akce (UPDATE), Vložen prostor (CREATEmisto) - hotovo Kolize:
step01TestMista.x— varování obsazeného místa (bez diff)
Ověření (aa=3753, uložení akce 22. 6. 2026, id > 1661161):
| id | TypAkce | Modul | Entita | Diff | Poznámka |
|---|---|---|---|---|---|
| 1661168, 1661172 | UPDATE | step01 | akce=3753 | falešný (cas) | uložení beze změny před Step01_NormCas |
| 1661179 | UPDATE | step01 | akce=3753 | stejné | uložení beze změny po normalizaci casod/casdo |
oprava Step01_NormCas — normalizace casod/casdo přes cDateHodin v Pred i Po (stejný formát jako při zápisu do DB).
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek,
LEFT(Popis,80) AS Popis, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661179
AND Modul = 'step01'
ORDER BY id DESC;
Krok 4.3 — Personál step04 hotovo + ověřeno
- hotovo
!step04/step04HistLib.x—Step04_PredSnap,Step04_PersonalFields,Step04_NormCas,Step04_Log - hotovo
step04vloz.x— UPDATE/CREATE s diff (EntitaId= Kod řádkudovakcepersonal) - hotovo
step04VlozJeden.x— CREATE (voláno zstep04vlozMulti.x) - hotovo
step04VlozVice.x— CREATE při rozepsání více kusů - hotovo
AkcePersonalDel.x— DELETE sDataPredpřed mazáním,Modul=step04
Diff pole: Kusu,Cena,terminod,termindo,casod,casdo,hodin,sleva,SazbaNakup,poznamka — Po po UPDATE/CREATE z DB (stejný formát jako Pred).
Ověření (aa=3753, 22. 6. 2026, id > 1661179):
| id | TypAkce | Entita | Diff | Poznámka |
|---|---|---|---|---|
| 1661183–1661190 | DELETE | personal=4947…4983 | Pred OK | 8× smazání, DataPred snapshot, DataPo prázdné |
| 1661193, 1661195 | DELETE | personal=4686, 4948 | Pred OK | další mazání |
| 1661197, 1661199 | CREATE | personal=4981, 4982 | Po OK | vložení přes step04, DataPred prázdné, DataPo z DB |
| 1661203 | UPDATE | personal=4982 | stejné | uložení beze změny — DataPred = DataPo |
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek,
LEFT(Popis,80) AS Popis, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661203
AND Modul = 'step04'
ORDER BY id DESC;
Krok 4.4 — Prostory step02/step021 hotovo + ověřeno
- hotovo
!step02/step02HistLib.x—Step02_PredSnap,Step02_MistoFields,Step02_NormCas,Step02_Log - hotovo
step02vloz.x— CREATE (2 cesty + legacy duplicitní zápis), DELETE - hotovo
step021vloz.x— CREATE/DELETE,Modul=step021; DELETE i přesajaxDel=1 - hotovo
AkceMistnostiDel.x— DELETE sDataPred,Modul=step02
Diff pole: kusu,sleva,SazbaJednotkova,SazbaNakup,NazevMistnosti,terminod,termindo,casod,casdo,DPH,poznamka — shodné pořadí klíčů se step06 kalkulací prostor.
oprava Step02_MistoPredDel — DELETE ve step02 hledá řádek podle Kod nebo idd (ř. 1661263 měl prázdný DataPred).
Ověření (aa=3753, 22. 6. 2026, id > 1661203):
| id | Typ | Modul | Entita | Poznámka |
|---|---|---|---|---|
| 1661222, 1661269 | CREATE | step02 | misto=19469… | DataPo z DB |
| 1661225, 1661250 | DELETE | step02 | misto=19469 | DataPred OK (AkceMistnostiDel / idd) |
| 1661260 | DELETE | step021 | misto=19257 | AJAX mazání ze step021 UI |
| 1661263 | DELETE | step02 | misto=19469 | prázdný Pred — opraveno idd lookup |
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId,
LEFT(Popis,80) AS Popis, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661269
AND Modul IN ('step02','step021')
AND EntitaTyp = 'misto'
ORDER BY id DESC;
Krok 4.5 — Technika step08–10 hotovo
- hotovo
!technika/TechnikaHistLib.x—Technika_PredSnap,Technika_AkceRowFields,Technika_NabidkaFields,Technika_Log - hotovo
step08NabidkaVloz.x— CREATE/UPDATE nabídka (EntitaTyp=nabidka) - hotovo
step08NabidkaDel.x— DELETE nabídka (1× souhrn místo 4× legacy) - hotovo
NabidkuAktivuj.x— UPDATE nabídka/akce (aktivace/deaktivace) - hotovo
step09Vloz.x— CREATE/UPDATE/DELETE technika, DELETE balíček - hotovo
step10Vloz.x,step10VlozNovouTechniku.x— CREATE/UPDATE/DELETE, hromadné DELETE - hotovo
step10NabidkaKopiruj.x—Technika_LogKopieNabidka(odkud→kam,Modul=step08přikam=08),step10NabidkaVyber.x - hotovo
step10ZmenaAkce.x,step10ZmenaTerminu.x,step10ZmenaMista2.x— step14 nastavení akce/termínu/místa (Modul=step14) - hotovo
step14VlozPoDnech.x— UPDATE rozpis po dnech po jednotlivých dnech (KusuDen,CenaDen,SlevaDen,datum) - hotovo
step10Vloz.xpřikam=14loguje jakostep14(jen historie) - hotovo
step10VlozPoDnechHromadne.x— hromadné slevy po dnech (step14přikam=14) - hotovo UI historie — zvýraznění názvu techniky/nabídky v popisu (
uact-hist-ent-nazev), název nabídky z DB proEntitaTyp=nabidka - mimo scope
step08NabidkaForm.x— jen zobrazení formuláře (legacy PAGE)
Diff pole technika (hlavička): kusu,Cena,sleva,PocetDnu,CenaDodavatel,cenadodavatel,DPH,NazevTechnika,terminod,termindo,casod,casdo,chybikusu,poznamka
Diff pole technika (den): KusuDen,CenaDen,SlevaDen,datum — Technika_DatumRowFields()
Diff pole nabídka: NabidkaNazev,NabidkaPopis,terminod,termindo,aktivni + KodAkce (přiřazení akce)
EntitaId: dovakcetechnika.Kod (řádek v akci), dovakcetechnikanabidka.Kod (nabídka). Pozor: ve step10 je neukladej=1 = ukládat (opačně než step08/09).
Ověřeno v testu aa=3753 (~338 nových řádků): step08 aktivace/deaktivace/kopie nabídky; step09 oprava techniky; step10 výběr nabídky; step14 přiřazení akce, termín, místo, rozpis po dnech (1 řádek/den/technika), hromadné slevy (1 řádek/den); CREATE/UPDATE/DELETE techniky v nabídce.
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId,
LEFT(Popis,80) AS Popis, LEFT(PopisAkce,120) AS Detail, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661269
AND Modul IN ('step08','step09','step10','step14')
ORDER BY id DESC;
Krok 4.6 — Mobiliář / služby (step03, step07) hotovo
- hotovo
!step03/step03HistLib.x—Step03_PredSnap,Step03_InventarFields,Step03_Log(Modul=step03,EntitaTyp=inventar) - hotovo
!step07/step07HistLib.x—Step07_PredSnap,Step07_SluzbaFields,Step07_Log(Modul=step07,EntitaTyp=sluzba) - hotovo
step03Vloz.x,step03VlozJeden.x— CREATE/UPDATE mobiliáře - hotovo
AkceInventarDel.x— DELETE mobiliáře - hotovo
step07vloz.x,step07VlozJeden.x— CREATE/UPDATE služby - hotovo
AkceSluzbyDel.x— DELETE služby - hotovo UI historie —
AkceHistNazevEntitaproinventar/sluzba, kategorie Mobiliář/Služby (oprava mapování URL) - hotovo
step03vlozMulti.x,step04vlozMulti.x,step07vlozMulti.x— souhrnný logids=+ jednotlivé CREATE z*VlozJeden.x(Fáze 5.5)
Diff pole inventář: Kusu,Cena,mj,terminod,termindo,casod,casdo,sleva,SazbaNakup,poznamka,NazevInventare
Diff pole služba: Kusu,Cena,mj,terminod,termindo,casod,casdo,sleva,SazbaNakup,poznamka,NazevSluzby,PopisSluzby
EntitaId: dovakceinventar.Kod, dovakcesluzby.Kod. Log při neukladej = 0 (stejně jako step08/09).
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId,
LEFT(Popis,80) AS Popis, LEFT(PopisAkce,120) AS Detail, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661607
AND Modul IN ('step03','step07')
ORDER BY id DESC;
Krok 4.7 — Lifecycle akce (mazání) hotovo
Audit celého řetězce smazání akce: požadavek (krok 1), validace, soft delete (archiv), hard delete, zamítnutí.
| Soubor | Kde v kódu | TypAkce | Co se loguje |
|---|---|---|---|
akcedelpotvrd.x |
Řádky u formuláře „Potvrdit smazání“ — větev AkceDelKontrola=0 nebo správná ZO |
(prázdný) | Požadavek na smazání krok1 (bez prefixu [DELETE]) |
akcedelpotvrd.x |
Větev KontrolaZodpovedneOsoby ≠ KodU → RR(chybaakce2) |
DENIED | [ZAMÍTNUTO] Nesprávná zodpovědná osoba, Vysledek=d |
!akce/AkceDel.x |
Před redirectem: aa ≠ opravdusmazat |
DENIED | Špatné potvrzení kódu akce |
!akce/AkceDel.x |
admin=b a KodU ≠ SESSION(KodU) |
DENIED | Obchodník nemá práva smazat cizí akci |
!akce/AkceDel.x |
AkceDelKontrola=1 a uživatel není ZO |
DENIED | Neoprávněné smazání — špatná ZO |
!akce/AkceDel.x |
SmazatAkci=0, tlačítko smazat — po UPDATE StavAkce=0 |
DELETE | Soft delete jedné akce; DataPred/DataPo vč. StavAkce |
!akce/AkceDel.x |
SmazatAkci=0, tlačítko smazat2 — skrytí všech s KodKopie |
DELETE | Soft delete opakujících akcí |
!akce/AkceDel.x |
SmazatAkci=1 — před DELETE FROM dovakce |
DELETE | Kompletní smazání; DataPred = snapshot hlavičky akce |
!akce/AkceDelKopie.x |
SmazatAkci=0 — po UPDATE StavAkce=0 WHERE kodkopie=… |
DELETE | Skrytí všech kopií opakující akce (Modul=AkceDelKopie) |
!akce/AkceDelKopie.x |
SmazatAkci=1 — po hromadném DELETE child tabulek + dovakce |
DELETE | Kompletní smazání kopií; detail KodKopie=…| pocet=N |
- hotovo
!akce/AkceDelHistLib.x—AkceDel_PredSnap,AkceDel_AkceFields,AkceDel_DetAkce,AkceDel_Log - hotovo
akcedelpotvrd.x+!akce/AkceDel.x— pilot Krok 1.4/2.3; DELETE větve doplněny oDataPred/DataPo(Fáze 4.7) - hotovo
!akce/AkceDelKopie.x— nahrazenActiveHistoryWorkers, log i u hard delete kopií - hotovo UI —
AkceHistModulPopisproAkceDel/AkceDelKopie, název akce znazevakceve snapshotech - mimo scope 4.7
!akce/AkceDelZavrit.x— uzavření workflow (Fáze 5+)
Diff pole akce (hlavička): nazevakce,terminod,termindo,casod,casdo,StavAkce,KodKopie,pocetosob
EntitaId: dovakce.Kod (EntitaTyp=akce). U kopií log podle KodKopie zdrojové akce.
Tok uživatele: menu akce → akcedelpotvrd.x?aa= (krok 1) → POST !akce/AkceDel.x (krok 2). Kopie: !akce/akcedelkopie.x?aa= (stejná logika jako AkceDelKopie.x).
Hard delete kopií (KolikAkci > 1): maže i historyworkers u kopií — forenzní stopa zůstává na zdrojové akci (CREATE opakování + DELETE AkceDelKopie). Volitelné vylepšení: do detailu doplnit smazane_aa=6568,6569,….
Ověřeno v testu aa=3753 (22.06.2026, id 1661688–1661696): krok1 bez prefixu; DENIED obchodníka (Vysledek=d, [ZAMÍTNUTO]).
Ověřeno aa=6512 — mazání kopií (30.06.2026): hard delete 28 kopií přes !akce/akcedelkopie.x?aa=6512 → id 1662397, Modul AkceDelKopie, detail KodKopie=6512| pocet=28. Historie u smazaných kopií (6568–6595) se při hard delete maže spolu s akcemi — na zdroji 6512 zůstávají CREATE z opakování + tento DELETE.
| id | TypAkce | Modul | Vysledek | Poznámka |
|---|---|---|---|---|
| 1661696, 1661689 | DENIED | AkceDel | d | OK — aa=3753, [ZAMÍTNUTO] Obchodník nemá práva |
| 1661688 | (prázdné) | akcedelpotvrd | o | OK — aa=3753, krok1 bez [DELETE] |
| 1662397 | DELETE | AkceDelKopie | o | OK — aa=6512, Kompletní smazání kopií, pocet=28 |
-- Mazání kopií (aa=6512, ověřeno 30. 6. 2026)
SELECT id, DatumCas, TypAkce, Modul, Popis, PopisAkce
FROM historyworkers
WHERE KodAkce = 6512 AND Modul = 'AkceDelKopie' AND TypAkce = 'DELETE'
ORDER BY id DESC LIMIT 5;
-- DENIED / krok1 (aa=3753)
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek,
LEFT(Popis,80) AS Popis, LEFT(PopisAkce,120) AS Detail
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661660
AND Modul IN ('AkceDel','akcedelpotvrd','AkceDelKopie')
ORDER BY id DESC;
Krok 4.8 — Soubory, dokumenty, DigiSign hotovo
Audit uploadu příloh/dokumentů a odeslání k podpisu přes DigiSign.
| Soubor | Kde v kódu | TypAkce | EntitaTyp / Modul |
|---|---|---|---|
FilesAkceUpload.x |
Po uploadu volá !akce/AkceFilesKopirujPrilohy.x (log tam po INSERT) |
CREATE | priloha / step05, EntitaId=dovakceprilohy.id |
!akce/AkceFilesKopirujPrilohy.x |
Po INSERT INTO dovakceprilohy v cyklu souborů |
CREATE | Files_LogPrilohaCreate |
FilesDokumentUpload.x |
Po uploadu volá /DokumentKopiruj.x |
CREATE | dokument / step70 (nebo step<sekce>) |
/DokumentKopiruj.x |
Po INSERT do dovakcedokumenty (nebo prilohy u Donio) |
CREATE | Files_LogDokumentCreate / Files_LogPrilohaCreate |
!akce/AkceFilesDel.x |
Po ověření uploadera, před/po DELETE FROM dovakceprilohy |
DELETE | priloha / step05, DataPred snapshot |
!akce/AkceDokumentyDel.x |
Po ověření uploadera, po DELETE dokumentu (dříve bez logu) | DELETE | dokument / step70 |
step75PodpisOdeslat.x |
Po úspěšném DS_EnvelopeOdeslat (DigiSign); při chybě API Vysledek=e |
CREATE | digisign / step75, detail envelopeId=…| zt=…| zi=… |
DigiSign — kompletní právní stopa hotovo 2026-06
Knihovna /DigiSignHistLib.x (include v DigiSignEnvelopeLib.x). Všechny záznamy: Modul=step75, EntitaTyp=digisign, EntitaId=zdroj_id (ID přílohy/dokumentu v dovakce*).
| Událost | Kde v kódu | TypAkce | Popis / DataPo |
|---|---|---|---|
| Odeslání k podpisu | step75PodpisOdeslat.x → DSH_LogOdeslat |
CREATE | Odeslání k podpisu DigiSign: …; DataPo: stav=odeslano;envelopeId=…;zdroj=odeslat |
| Změna stavu obálky | DS_PodpisAktualizovatZApi, auto-sync F5, step75PodpisSync*.x → DSH_LogStavZmena |
UPDATE | DigiSign stav: … → …; diff stav, envelopeId, api_status, zdroj (api_sync / auto_sync) |
| Změna stavu příjemce | DS_PodpisAuditRecipientsDiff při uložení JSON z API → DSH_LogRecipientZmena |
UPDATE | DigiSign prijemce: email — Ceka na podpis → Podepsano; DataPo: prijemce;email;stav; deduplikace per (aa, zi, email, stav, envelopeId) |
| Webhook obálka | DigiSignWebhookLib.x → DSH_LogWebhook |
UPDATE | DigiSign webhook: …; event, stav_envelope |
| Webhook příjemce | DigiSignWebhookLib.x → DSH_LogRecipientWebhook |
UPDATE | DigiSign webhook prijemce: … |
| Chyba DigiSign API | sync / auto-sync / fetch → DSH_LogApiChyba |
UPDATE | DigiSign API chyba; Vysledek=error |
| Stažení auditní stopy PDF | DS_PodpisStahnoutAuditStopu (sync, webhook, auto-doplnění F5) → DSH_LogAuditStopa |
UPDATE | DigiSign auditni stopa stazena: digisign_audit_{id}.pdf; DataPo: audit_filename;audit_folder;podpis_id;envelopeId;zdroj |
| PDF smlouvy (step75) | !step75/step75SmlouvaPdfLib.x |
CREATE / UPDATE | Generování/obnova PDF smlouvy do dovakcedokumenty (EntitaTyp=dokument) |
Soubory auditní stopy na disku: digisign_audit_{digisign_podpis.id}.pdf ve složce zdrojového souboru (např. /!files/document/digisign_audit_10.pdf). Ikona štítu v UI step75 i v historie.x (AkceHistDigiSignAuditLink, třída uact-hist-audit-ikon).
Poznámky implementace: popisky stavů příjemců v ASCII (bez poškozené diakritiky v DB); snapshot příjemců při zobrazení stránky vypnut — loguje se jen skutečná změna stavu; webhook běží pod systémovým uživatelem DigiSign webhook (DSH_EnsureHwSession).
- hotovo
/FilesHistLib.x— snapshot,Files_Log*, DigiSign helper - hotovo Log až po INSERT do DB (ne před kopírováním — oprava duplicitního/ prázdného EntitaId)
- hotovo UI historie — kategorie Přílohy/Dokumenty/DigiSign, název z
nazev/audit_filenameve snapshotech - hotovo
DigiSignHistLib.x— stavy obálky, API sync (auto/manual/ajax), webhook, API chyby, příjemci, auditní PDF - hotovo Sync handlery:
step75PodpisSync.x,step75PodpisSyncAjax.x,DS_PodpisAutoSyncAkceZApi(F5) - hotovo ZO notifikace příloh — volitelná entita
hwZoEntitaTyp/IdvKontrolaZodpovedneOsobyZaAkci.x
Diff pole příloha: nazev,popis,filename,folder,size,mime,sekce
Diff pole dokument: nazev,original,popis,filename,folder,size,mime,sekce
Diff pole digisign (obálka): stav,envelopeId,api_status,zdroj
Diff pole digisign (příjemce): prijemce,email,stav
Diff pole digisign (audit PDF): podpis_id,audit_folder,audit_filename,envelopeId,zdroj
-- Vše step75 / digisign
SELECT id, DatumCas, TypAkce, EntitaId, LEFT(Popis,100) AS Popis, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND Modul = 'step75' AND EntitaTyp = 'digisign'
ORDER BY id DESC;
-- Příjemci (změna stavu)
SELECT id, DatumCas, LEFT(Popis,120), DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND Modul = 'step75' AND EntitaTyp = 'digisign'
AND Popis LIKE '%prijemce%'
ORDER BY id DESC;
-- Auditní stopa PDF
SELECT id, DatumCas, LEFT(Popis,120), DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND Modul = 'step75' AND EntitaTyp = 'digisign'
AND Popis LIKE '%auditni stopa%'
ORDER BY id DESC;
-- Soubory (přílohy/dokumenty) po 4.8
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek,
LEFT(Popis,80) AS Popis, LEFT(PopisAkce,120) AS Detail, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND id > 1661696
AND Modul IN ('step05','step70','step75')
AND EntitaTyp IN ('priloha','dokument','digisign')
ORDER BY id DESC;
Krok 4.9 — Smlouvy hotovo
Audit HTML smluv v tabulce dovakcesmlouvy — editor, soft delete/obnovení, náhled/tisk. Knihovna !smlouvy/SmlouvyHistLib.x.
| Soubor | Kde v kódu | TypAkce | EntitaTyp / Modul |
|---|---|---|---|
!smlouvy/SmlouvuVloz.x |
Po INSERT INTO dovakcesmlouvy (nová smlouva) |
CREATE | smlouva / step60, EntitaId=dovakcesmlouvy.kod |
!smlouvy/SmlouvuVloz.x |
Po UPDATE dovakcesmlouvy (editor HTML) |
UPDATE | Smlouvy_LogUpdate — diff DataPred/DataPo před a po uložení |
!smlouvy/SmlouvyDel.x |
Soft delete smazano=1 (jen admin t/b) |
DELETE | Smlouvy_LogDelete, detail soft delete |
!smlouvy/SmlouvyDel.x |
Obnovení smazano=0 (smazano=1 v URL) |
UPDATE | Smlouvy_LogObnovit — logicky obnovení, TypAkce UPDATE kvůli změně smazano |
!DOC/smlouva01.x |
Při otevření náhledu/tisku (auto window.print()) |
PAGE_VIEW | Smlouvy_LogNahledTisk; modul step60 nebo step75 (?mod=step75 ze step75) |
Smlouvy — snapshot a popisy hotovo 2026-06
Všechny záznamy: EntitaTyp=smlouva, EntitaId=Kod smlouvy. Výchozí Modul=step60; náhled ze step75 používá Modul=step75.
| Událost | Funkce | Popis (vzor) | DataPo / diff |
|---|---|---|---|
| Nová smlouva | Smlouvy_LogCreate |
Nová smlouva akci: {název akce} — {kód 4místně} |
datum;aktualizace;smazano;obsah_len (délka HTML, ne celý text) |
| Úprava v editoru | Smlouvy_LogUpdate |
Úprava smlouvy pro akci: … — 0003 |
diff obsah_len, aktualizace, smazano |
| Smazání (soft) | Smlouvy_LogDelete |
Smazána smlouva akci: … — 0003 |
DataPred snapshot, DataPo prázdné |
| Obnovení | Smlouvy_LogObnovit |
Obnovena smlouva akci: … — 0003 |
diff smazano 1→0 |
| Náhled / tisk | Smlouvy_LogNahledTisk |
Náhled/tisk smlouvy: … — 0003 |
detail smlouva01.x| aa=…| sml=…; badge PAGE_VIEW v UI historie |
Související (mimo 4.9, ale navázané): generování PDF smlouvy pro DigiSign ve step75 — !step75/step75SmlouvaPdfLib.x loguje jako EntitaTyp=dokument / Modul=step75 (fáze 4.8), ne jako smlouva.
Ještě nemigrováno: !step60/step60vloz.x — starší handler polí OD/DO u aut ve smlouvě (bez HW_Log).
- hotovo
SmlouvyHistLib.x—Smlouvy_PredSnap,Smlouvy_Log* - hotovo Migrace z
PopisXX+ActiveHistoryWorkersnaHW_LogDiff - hotovo UI historie — kategorie Smlouvy, badge
PAGE_VIEWpro náhled/tisk - hotovo Náhled ze step75 —
smlouva01.x?mod=step75
Diff pole smlouva: datum,aktualizace,smazano,obsah_len (obsah HTML se do logu neukládá — jen délka)
-- Vše smlouvy akce
SELECT id, DatumCas, TypAkce, Modul, EntitaId, LEFT(Popis,100) AS Popis, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND EntitaTyp = 'smlouva'
ORDER BY id DESC;
-- CREATE / UPDATE / DELETE editoru
SELECT id, DatumCas, TypAkce, LEFT(Popis,120), DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND EntitaTyp = 'smlouva' AND Modul = 'step60'
AND TypAkce IN ('CREATE','UPDATE','DELETE')
ORDER BY id DESC;
-- Náhled / tisk (PAGE_VIEW)
SELECT id, DatumCas, TypAkce, Modul, LEFT(Popis,120), LEFT(PopisAkce,80)
FROM historyworkers
WHERE KodAkce = 3753 AND EntitaTyp = 'smlouva' AND TypAkce = 'PAGE_VIEW'
ORDER BY id DESC;
Krok 4.10 — Detail, energie, školní pomůcky hotovo + ověřeno (step20, step95)
Migrace tří oblastí na HW_LogDiff: detail akce (step20), spotřeba energie (step94/step95), školní pomůcky (step80).
| Knihovna | Handler | TypAkce | EntitaTyp / tabulka |
|---|---|---|---|
!step20/step20HistLib.x |
step20vloz.x — hlavní blok dovakcedetail |
CREATE / UPDATE | detail / dovakcedetail, EntitaId=KodDetail |
step20HistLib |
step20vloz.x — vlastní řádky dovakcedetailvlastni |
CREATE / UPDATE | detail_polozka, EntitaId=dovakcedetailvlastni.kod |
step20HistLib |
step20newVloz.x — hromadný přepis vlastních detailů |
UPDATE | akce (EntitaId=KodAkce), souhrn bez diff polí |
!step94/step94HistLib.x |
step94vloz.x, step95vloz.x, step94mereni.x (Premier import) |
CREATE / UPDATE | spotreba / import → dovakcespotreba; import KodAkce=0 |
!step80/step80HistLib.x |
step80Vloz.x |
CREATE / UPDATE | inventar / dovakceinventar, modul step80 (stejná tabulka jako mobiliář step03) |
Detail, energie, pomůcky — snapshot a popisy ověřeno 22. 6. 2026
| Událost | Funkce | Popis (vzor) | Diff pole |
|---|---|---|---|
| Nový detail akce | Step20_LogDetailCreate |
Vlozen detail akce: {název akce} |
splatnostfaktury, adresadokladu, poznamka, harmonogram, technika, … |
| Úprava detailu | Step20_LogDetailUpdate |
Uprava detailu akce: {název akce} |
diff všech polí hlavního bloku |
| Vlastní položka detailu | Step20_LogPolozkaCreate/Update |
Vlozena polozka detailu: … / Oprava detailu akce: … |
DetailNazev, DetailText, kodD, aktualizace |
| Přepis vlastních detailů | Step20_LogVlastniPrepis |
Aktualizace vlastnich detailu akce: … |
bez DataPred/DataPo (souhrn + počet řádků) |
| Energie — vložení / oprava (akce) | Step94_LogCreate/Update |
Vlozeni energii: … / Oprava energii: … |
step94/95, KodAkce=aa; diff spotřeb a sazeb |
| Premier import měření | Step94_LogImportPremier, Step94_LogImportRow |
Import mereni Premier: Únor 2026 + řádky Import energie (UPDATE): … |
EntitaTyp=import souhrn; řádky spotreba, KodAkce=0 |
| Školní pomůcka | Step80_Log |
{NazevInventare} — Vlozeni/Oprava skolni pomucky: OD … DO … |
Kusu, Cena, mj, termíny, casod/casdo, SazbaNakup, poznamka, NazevInventare |
UI historie: kategorie Detail akce, Energie, Import energie; inventář z step80 jako Školní pomůcky. Premier import (KodAkce=0) se nezobrazí v historie.x?aa=… — jen v SQL / globální historii uživatele.
Poznámka: energie se v kalkulaci loguje také ve step06Vloz.x (EntitaTyp=spotreba) — duplicitní zápisy při úpravě v obou krocích jsou známé (viz matice step06).
- hotovo
step20HistLib.x,step94HistLib.x,step80HistLib.x - hotovo Migrace z
ActiveHistoryWorkersnaHW_LogDiffve všech uvedených handlerech - hotovo
AkceHistorieHistLib.x— moduly step20/step80, kategorie detail/spotreba/pomůcky - hotovo + ověřeno step20 (
step20newVlozid 1661861), step95 energie (CREATE id 1661850, 1661852; UPDATE diff id 1661857) - hotovo + ověřeno Premier import (
step94mereniid souhrn 1662331, řádky 1662311–1662330) - k ověření step80 — uložit školní pomůcku a dotaz na
Modul='step80'
Výsledek ověření Premier import (30. 6. 2026)
URL: step94.x?action=import&Obdobi=102&rok=2026&zapis=1 →
37 UPDATE řádků + souhrn EntitaTyp=import.
Referenční baseline_max_id = 1662331.
Dvojitý souhrn id 1662293 + 1662331 = import spuštěn 2× (4 s interval).
KodAkce=3753, popis Vlozeni energii:). Import → KodAkce=0,
popis Import energie (UPDATE): / souhrn Import mereni Premier:.
| id | Typ | EntitaTyp | EntitaId | Popis (zkráceno) |
|---|---|---|---|---|
| 1662331 | CREATE | import | 0 | Import mereni Premier: Únor 2026 — radku=37, aktualizovano=37 |
| 1662330 | UPDATE | spotreba | 573 | Import energie (UPDATE): … Landek elektřina |
| 1662311 | UPDATE | spotreba | 481 | Import energie (UPDATE): ENC Vnější rozvaděč … |
| 1662254 | CREATE | spotreba | 577 | Vlozeni energii: … plyn Landek (KodAkce=3753, step95) |
Výsledek ověření (aa=3753, 22. 6. 2026)
Dotazy výše, po baseline fáze 4.9 (id > 1661766) → 4 forenzní záznamy step20/step95
(id 1661850–1661857, 1661861). Nový referenční baseline_max_id = 1661861.
step80 zatím bez testovacího zápisu.
DataPo
(idrozvadece, spotřeby, sazby). UPDATE id 1661857 — diff sazby
SazbaJednotkova/SazbaNakup 159→199 u EntitaId=567 (U6 - Voda).
| id | TypAkce | Modul | EntitaTyp | EntitaId | Popis (zkráceno) | Poznámka |
|---|---|---|---|---|---|---|
| 1661861 | UPDATE | step20 | akce | 3753 | Aktualizace vlastnich detailu akce: konference PULSE 2026 | Step20_LogVlastniPrepis — prázdné DataPred/DataPo (souhrn) |
| 1661857 | UPDATE | step95 | spotreba | 567 | Oprava energii: 42008383013 - U6 - Voda | DataPo — sazba 199, spotřeba 37 m³ |
| 1661852 | CREATE | step95 | spotreba | 567 | Vlozeni energii: 42008383013 - U6 - Voda | nový řádek spotřeby |
| 1661850 | CREATE | step95 | spotreba | 566 | Vlozeni energii: 859182413450000167 - Areál - DICR - Elektrická energie | 40 kWh, sazba 9,5 |
-- Detail akce (step20)
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, LEFT(Popis,100) AS Popis, DataPred, DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND Modul = 'step20'
ORDER BY id DESC;
-- Energie (step94 / step95)
SELECT id, DatumCas, TypAkce, Modul, EntitaId, LEFT(Popis,100), DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND EntitaTyp = 'spotreba' AND Modul IN ('step94','step95')
ORDER BY id DESC;
-- Premier import (KodAkce=0, EntitaTyp=import / spotreba)
SELECT id, DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, LEFT(Popis,100), LEFT(PopisAkce,120)
FROM historyworkers
WHERE EntitaTyp = 'import' AND Modul = 'step94'
ORDER BY id DESC;
SELECT id, DatumCas, TypAkce, EntitaId, LEFT(Popis,100)
FROM historyworkers
WHERE Modul = 'step94' AND KodAkce = 0 AND Popis LIKE '%Import energie%'
ORDER BY id DESC;
-- Školní pomůcky (step80)
SELECT id, DatumCas, TypAkce, EntitaId, LEFT(Popis,100), DataPo
FROM historyworkers
WHERE KodAkce = 3753 AND Modul = 'step80' AND EntitaTyp = 'inventar'
ORDER BY id DESC;
FÁZE 4 — Migrace handlerů po modulech (2–3 týdny)
Pořadí podle dopadu na forenzní audit a počtu operací:
| Pořadí | Modul | Soubory k úpravě | Co logovat | Odhad |
|---|---|---|---|---|
| 4.1 | Kalkulace | step06Vloz.x (22 míst) | UPDATE cen — s diff DataPred/DataPo | hotovo |
| 4.2 | Základ akce | step01Vloz.x, fakturace, balíčky | CREATE/UPDATE akce, termíny | hotovo |
| 4.3 | Personál | step04vloz*, AkcePersonalDel, step04vlozMulti | CREATE/UPDATE/DELETE + EntitaId | hotovo |
| 4.4 | Prostory | step02vloz, step021vloz, AkceMistnostiDel | CREATE/DELETE misto | hotovo |
| 4.5 | Technika | step08–10*, NabidkuAktivuj, step08NabidkaDel | CREATE/UPDATE/DELETE technika | hotovo |
| 4.6 | Služby / inventář | step03*, step07*, Akce*Del | CREATE/UPDATE/DELETE | hotovo |
| 4.7 | Lifecycle akce | AkceDel, akcedelpotvrd, AkceDelKopie | DELETE, DENIED | hotovo |
| 4.8 | Soubory + DigiSign | Files*, Akce*Del, step75Podpis*, DigiSignHistLib, webhook/sync | CREATE/DELETE soubory; DigiSign odeslání, stavy, příjemci, audit PDF | hotovo |
| 4.9 | Smlouvy | SmlouvyHistLib, SmlouvuVloz, SmlouvyDel, smlouva01 | CREATE/UPDATE/DELETE + PAGE_VIEW; diff obsah_len | hotovo |
| 4.10 | Detail, energie | step20HistLib, step94HistLib, step80HistLib; step20vloz, step94/95vloz, step80Vloz | CREATE/UPDATE s diff DataPred/DataPo | hotovo + ověřeno step20/95 (1661861, 1661850–57); step80 čeká test |
Krok 4.x — Vzor migrace jednoho handleru
Pro každý *vloz.x / *Del.x:
- Najít místo po úspěšném
DB.Execute(sqluloz=1). - Před UPDATE načíst starý stav do proměnných (SELECT … WHERE Kod=).
- Nahradit blok PopisXX + include tímto:
CALL HW_Log("UPDATE", "step04", "personal", KodAkcePersonal, KodAkce, _
"Opraven personál: " & PersonalZkratka, _
"terminOd=" & terminOdOld & "→" & terminOd & "; cena=" & cenaOld & "→" & cena, _
"ok", cenaOld, cena)
- Smazat duplicitní include ActiveHistoryWorkers na stejném místě.
- Test na testovací akci — 1 řádek, správný TypAkce v DB.
FÁZE 5 — Doplnění kritických mezer (1 týden) hotovo 5.1–5.9 (6. 2026)
| Krok | Soubor | HW_Log volání | Stav |
|---|---|---|---|
| 5.1 | step01OpakujRun.x, step01HistLib.x | CREATE kopie akce — zdroj_aa v detail; souhrn po dávce | hotovo + ověřeno |
| 5.2 | step75PodpisOdeslat.x, DigiSignHistLib.x | Odeslání, stavy obálky/příjemců, webhook, auditní stopa PDF | hotovo · viz 4.8 |
| 5.3 | !step15/step15HistLib.x, step15Vloz/Del, !DOC/nakladovy01.x | CREATE/DELETE/PAGE_VIEW tisk — ids=… | hotovo + ověřeno |
| 5.4 | !step50/step50HistLib.x, step50vloz.x, !akce/AkceAutaDel.x | CREATE/UPDATE/DELETE auto (+ TimeLine zachován) | hotovo + ověřeno |
| 5.5 | step03/04/07 vlozMulti.x, *VlozJeden.x | Jednotlivé CREATE + souhrnný řádek ids=… | hotovo |
| 5.6 | !step43/step43NabidkaDel.x | DELETE catering nabídka — diff NabidkaNazev, soubor, sklad | hotovo |
| 5.7 | !step14/step14VlozPoDnech.x | UPDATE rozpis po dnech — diff kusu/cena/sleva per den | hotovo |
| 5.8 | !akce/AkceDokumentyDel.x, FilesHistLib.x | DELETE dokument — snapshot názvu souboru před smazáním | hotovo |
| 5.9 | !akce/AkceKopieHistLib.x, akcekopie_vloz.x, OpakujAkceLib.x | CREATE / KOLIZE / DENIED kopie + kolize prostor/sklad; oprava detekce | hotovo + ověřeno |
Krok 5.1 — Opakování akce ověřeno aa=6512
Tok: akceopakuj.x?aa=… → formulář → step01OpakujVloz.x → AJAX step01OpakujAjax.x → step01OpakujRun.x + AkceKopiruj2.x. Kopie dostanou KodKopie=zdroj_aa.
Po každé úspěšné kopii:
Step01_LogOpakujCreate— log na novéaa(Kopie akce (opakování)) i na zdrojovéaa(Opakování — vytvořena kopie aa=…)Step01_LogOpakujKolizePreskoc— při kolizi prostor termín přeskočen: DENIED na zdroji s detailem konfliktních akcíStep01_LogOpakujSouhrn— po dokončení dávky na zdroji:vytvoreno=N,preskoceno_kolize=M,nove_aa=6568,6569,…
Ověření — akce 6512 (30. 6. 2026)
Opakování týdenní, 28 kopií (6568–6595). Celkem 57 CREATE řádků (28×2 + 1 souhrn). Poté hard delete kopií → id 1662397 (4.7 AkceDelKopie).
| id (příklad) | KodAkce | Popis (zkráceně) | PopisAkce (klíč) |
|---|---|---|---|
| 1662340–1662394 | 6512 | Opakování — vytvořena kopie aa=… | zdroj_aa=6512 | aa=6568…6595 | termin=… |
| 1662395 | 6512 | Dokončeno opakování akce | vytvoreno=28 | nove_aa=6568,…,6595 |
| 1662339–1662393 | 6568–6595 | Kopie akce (opakování) | zdroj_aa=6512 | aa=… | termin=… |
-- Zdrojová akce 6512 (CREATE z opakování + souhrn) SELECT id, KodAkce, LEFT(Popis,55) AS Popis, PopisAkce FROM historyworkers WHERE KodAkce = 6512 AND Modul = 'step01' AND TypAkce = 'CREATE' AND (Popis LIKE '%opakov%' OR PopisAkce LIKE '%zdroj_aa%') ORDER BY id DESC; -- Každá kopie (6568–6595) SELECT id, KodAkce, LEFT(Popis,55) AS Popis, PopisAkce FROM historyworkers WHERE KodAkce BETWEEN 6568 AND 6595 AND Modul = 'step01' AND TypAkce = 'CREATE' AND Popis LIKE '%Kopie akce%' ORDER BY KodAkce; -- UI historie.x?aa=6512&ftyp=CREATE&fq=opakov historie.x?aa=6568&ftyp=CREATE
Poznámka Jedno opakování = hodně řádků (57). Volitelně později zredukovat duplicitní log „vytvořena kopie“ na zdroji a nechat souhrn + log na každé nové aa.
Krok 5.2 — DigiSign / podpis (step75) hotovo
Implementace je součástí Fáze 4.8 — knihovna /DigiSignHistLib.x (+ FilesHistLib.x pro PDF smlouvy). V plánu Fáze 5 je krok 5.2 jen připomínka, že podpis není mezera.
- CREATE — odeslání k podpisu (
step75PodpisOdeslat.x) - UPDATE — stav obálky, příjemci, webhook, auditní stopa PDF
- Modul
step75, entitadigisign/dokument
Detailní tabulka událostí, SQL a test id 1661819: Krok 4.8 — DigiSign.
-- UI historie.x?aa=3753&fkat=DigiSign&fq=digisign
Krok 5.3 — Nákladové listy (step15) hotovo + ověřeno
step15HistLib.x — entita nakladovy_list, modul step15:
- CREATE — po uložení (
step15Vloz.x), detailids=… - DELETE — mazání (
step15Del.x), diff před smazáním - PAGE_VIEW — tisk (
!DOC/nakladovy01.x?aa=&nb=), detailnakladovy01.x| aa=…| nb=…| pocet=…| ids=…
-- Tisk nákladového listu (aa=6482, nabídka N1036) SELECT id, TypAkce, LEFT(Popis,70), PopisAkce FROM historyworkers WHERE KodAkce = 6482 AND Modul = 'step15' AND TypAkce = 'PAGE_VIEW' AND PopisAkce LIKE '%nakladovy01%' ORDER BY id DESC; -- UI historie.x?aa=6482&ftyp=PAGE_VIEW&fq=nakladovy
Krok 5.4 — Auta u akce (step50) hotovo + ověřeno
step50HistLib.x — entita auto, modul step50:
- CREATE — vložení (
step50vloz.xINSERT), detailid=…, diff po uložení - UPDATE — úprava rezervace (
step50vloz.xUPDATE), detailid=…, diff před/po - DELETE — smazání (
!akce/AkceAutaDel.x), detailid=…, diff před smazáním; TimeLinedel=1beze změny
Notifikace ZO „Změna auta u akce“ zůstává v modulu akce (KontrolaZodpovedneOsobyZaAkci) — odděleně od datového diffu step50.
-- Auta u akce aa=6482 SELECT id, TypAkce, LEFT(Popis,70), PopisAkce FROM historyworkers WHERE KodAkce = 6482 AND Modul = 'step50' AND EntitaTyp = 'auto' ORDER BY id DESC; -- UI historie.x?aa=6482&fkat=Auta&fq=auto
Krok 5.5 — Hromadné vložení (step03 / step04 / step07) hotovo
Multi handlery doplňují audit, který u jednotlivých kroků chyběl pro hromadný formulář:
| Modul | Handler | Knihovna | Entita |
|---|---|---|---|
| step03 | step03vlozMulti.x → step03VlozJeden.x | step03HistLib.x | inventar (mobiliář) |
| step04 | step04vlozMulti.x → step04VlozJeden.x | step04HistLib.x | personal |
| step07 | step07vlozMulti.x → step07VlozJeden.x | step07HistLib.x | sluzba |
- Každý nový řádek — samostatný CREATE s diffem (
*VlozJeden.x) - Po dávce — souhrnný CREATE:
Hromadné vložení … (N), detailids=1,2,3,…(Step0x_LogMultiSouhrn)
SELECT id, Modul, TypAkce, LEFT(Popis,70), PopisAkce FROM historyworkers WHERE KodAkce = @aa AND TypAkce = 'CREATE' AND Popis LIKE '%Hromadné vložení%' ORDER BY id DESC;
Krok 5.6 — Mazání catering nabídky (step43) hotovo
Handler: !step43/step43NabidkaDel.x · tabulka cateringnabidka (+ kaskáda dovakcecatering, skladové pohyby).
- DELETE —
Technika_Log("step43", …, "nabidka", …) - Diff před smazáním:
NabidkaNazev,NabidkaPopis,filename - Detail: popis nabídky +
soubor=… | včetně catering a skladu - Oprávnění: smazat může pouze
KodU, který nabídku vložil
SELECT id, Modul, TypAkce, LEFT(Popis,70), PopisAkce FROM historyworkers WHERE KodAkce = @aa AND Modul = 'step43' AND TypAkce = 'DELETE' AND EntitaTyp = 'nabidka' ORDER BY id DESC;
Krok 5.7 — Technika — rozpis po dnech (step14) hotovo
Handler: !step14/step14VlozPoDnech.x · alternativní editace kusu/ceny/slevy po dnech mimo step10.
- UPDATE —
Step14_LogDenZmenajen při skutečné změně (porovnáníhwPredvshwPo) - Entita
technika, modulstep14,EntitaId= řádek vdovakcetechnika - Popis:
{název techniky} — Rozpis po dnech dne DD.MM.RRRR: kusu=… cena=… sleva=… - Detail:
datum=…, diff polí řádkudovakcetechnikadatum
SELECT id, Modul, TypAkce, LEFT(Popis,70), PopisAkce FROM historyworkers WHERE KodAkce = @aa AND Modul = 'step14' AND TypAkce = 'UPDATE' AND Popis LIKE '%Rozpis po dnech%' ORDER BY id DESC;
Krok 5.8 — Mazání dokumentů akce (step70) hotovo
Handler: !akce/AkceDokumentyDel.x · knihovna /FilesHistLib.x · tabulka dovakcedokumenty.
- DELETE —
Files_Log("DELETE", "step70", "dokument", …) - Snapshot před smazáním (
Files_PredSnap): název, soubor, složka - Popis:
Smazán dokument: {název} - {filename} - Oprávnění: smazat může pouze uploader (
uploader = SESSION(KodU)) - TimeLine:
timeline.del=1prodokumenty={id}
Symetrické k uploadu (FilesDokumentUpload.x, Fáze 4.8). Přílohy step05 mazání: AkceFilesDel.x.
SELECT id, Modul, TypAkce, LEFT(Popis,70), LEFT(PopisAkce,80) FROM historyworkers WHERE KodAkce = @aa AND Modul = 'step70' AND TypAkce = 'DELETE' AND EntitaTyp = 'dokument' ORDER BY id DESC;
Krok 5.9 — Jednorázová kopie akce a kolize ověřeno aa=6512
Tok: akcekopiruj.x?aa=… → formulář (AJAX kontrola akcekopie_kontrola.x) → !akce/akcekopie_vloz.x → AkceKopiruj2.x.
Soubory: !akce/AkceKopieHistLib.x (modul AkceKopie), !step01/OpakujAkceLib.x (OpakujKolizeInfo — detekce kolizí prostor).
| Situace | TypAkce | Popis / detail |
|---|---|---|
| Úspěšná kopie bez kolizí | CREATE | Na novém i zdrojovém aa; zdroj_aa=… | aa=… | termin=… |
Kopie přes kolizi prostor (ProstoryOK + tlačítko „Vložit“) | CREATE + KOLIZE | pres_kolizi_prostor=1 + samostatný řádek TypAkce=KOLIZE |
| Kolize služeb / mobiliáře / personálu | DENIED + KOLIZE | Detail kolizí všech kategorií |
| Kolize prostor bez oprávnění / bez tlačítka přes kolizi | DENIED | Text chyby + detail kolizí prostor |
| Neplatný termín / validace data | DENIED | Text validace, bez kolizí |
Selhání AkceKopiruj2 | DENIED | Vysledek=error, text chyby SQL |
| Opakování — termín přeskočen (kolize prostor) | DENIED | Modul step01, Step01_LogOpakujKolizePreskoc |
AJAX kontrola (akcekopie_kontrola.x) se neloguje — záznam až při odeslání formuláře (žádný šum z opakovaného pollingu).
Oprava 6/2026 Detekce kolizí prostor (OpakujKolizeInfo): (1) zahrnout i rozpracované kopie StavAkce=0, (2) filtr nájemce dovakce.najemce včetně legacy najemce=0, (3) nefiltrovat přes neexistující dovakcemista.najemce.
Ověření — kopie s kolizí prostor (30. 6. 2026)
Zdroj 6512 → kopie 6572 na termín 16. 6. 2026 13:00–15:00, kolize s akcí 6568 (3.NP Zasedací místnost), přes ProstoryOK. Dva řádky na zdrojovém aa:
| id | Modul | TypAkce | Popis (zkráceně) | PopisAkce (klíč) |
|---|---|---|---|---|
| 1662476 | AkceKopie | CREATE | Kopie akce — vytvořena kopie aa=6572 | pres_kolizi_prostor=1 | kolize: … akce 6568 … |
| 1662477 | AkceKopie | KOLIZE | Kolize prostor — kopie aa=6572 (přes ProstoryOK) | stejný detail jako CREATE |
-- Jedna kopie s kolizí (zdroj 6512, nové aa=6572)
SELECT id, Modul, TypAkce, LEFT(Popis,70), PopisAkce
FROM historyworkers
WHERE KodAkce = 6512
AND PopisAkce LIKE '%aa=6572%'
AND (LOWER(IFNULL(Modul,'')) = 'akcekopie' OR TypAkce = 'KOLIZE')
ORDER BY id;
-- Všechny kolize u kopírování akce 6512
SELECT id, TypAkce, LEFT(Popis,70), PopisAkce
FROM historyworkers
WHERE KodAkce = 6512
AND TypAkce IN ('KOLIZE','DENIED')
AND PopisAkce LIKE '%kolize:%'
ORDER BY id DESC;
-- Kolize při opakování (přeskočený termín)
SELECT id, KodAkce, TypAkce, LEFT(Popis,60) AS Popis, PopisAkce
FROM historyworkers
WHERE LOWER(IFNULL(Modul,'')) = 'step01'
AND (Popis LIKE '%přeskočen%kolize%' OR PopisAkce LIKE '%kolize%')
ORDER BY id DESC;
-- UI
historie.x?aa=6512&fq=kolize
historie.x?aa=6512&ftyp=CREATE&fq=Kopie%20akce
FÁZE 6 — UI historie.x pro forenzní analýzu (1 týden)
Krok 6.1 — Filtry a rychlé vyhledávání v AkceHistorieShow.x implementováno (6. 2026)
Soubory: !akce/AkceHistorieShow.x, !akce/AkceHistorieHistLib.x, users/UserActivityHist.css, !SQL/SQLHledejLib.x (HledejBezDiakritiky)
Kompaktní formulář (jeden řádek)
| Pole | Parametr URL | Popis |
|---|---|---|
| Období | Obdobi + rok | Měsíc (101–112) a rok; změna rovnou odešle formulář (onchange) |
| Uživatel | KodU | Seznam osob z historie akce |
| Oblast | fkat | Personál, Služby, Technika… (AkceHistKategorieExpr) |
| Modul | fmod | Odvozený popis stránky (AkceHistUrlPopisExpr) — dropdown ve formuláři |
| Typ | ftyp | CREATE / UPDATE / DELETE / PAGE_VIEW / DENIED |
| Stav | fvysl | ok / d (zamítnuto) |
| Legacy | flegacy=1 | Skrýt záznamy bez TypAkce (checkbox ve formuláři) |
| Rychlé hledání | fq | Textové pole — viz níže; tlačítko Vyhledat (fqGo=1) |
| Zobrazení | zobrazit | oba / souhrn / detail |
Stávající parametry zachovány: view (forensic/all), fdiff=1, fmod, flegacy=1, dd (detail dne), ftxt (text v popisu/diff), paginace sr/str. Odkazy v souhrnných tabulkách filtry drží (AkceHistLinkCommon). Reset → historie.x?aa=… bez filtrů.
Rychlé vyhledávání (fq)
Po kliknutí Vyhledat (fqGo=1) se řetězec rozdělí na tokeny (čárka, středník, svislítko, mezera) a každý token se mapuje na filtr. Diakritika se ignoruje (HledejBezDiakritiky — stejný princip jako hledej.x). Po parsování redirect na čistou URL; původní fq zůstane v adrese i ve formuláři pro další zpřesnění.
| Token (příklad) | Nastaví |
|---|---|
person, personal | Oblast → Personál (fkat) |
kveten, leden… | Obdobi + rok (aktuální rok, pokud není uveden) |
2026 | rok |
20.5.2026, 20.5, 20/5 | dd — jeden den (rok z tokenu nebo aktuální) |
nikol, georg… | KodU — shoda jména z historie akce |
uprava, vlozeni, smazani | ftyp |
sluzby, technika, energie… | fkat (aliasy + DB kategorie akce) |
| nerozpoznané | ftxt — fulltext v popisu a diff |
Příklady (aa=3753, po Vyhledat): person nikol kveten → Personál + uživatel Nikol + květen aktuálního roku georg 15.10 → uživatel Georg + den 15. 10. (aktuální rok) personal, 20.5.2026, uprava → Personál + 20. 5. 2026 + typ UPDATE URL po parsování (zkráceně): historie.x?aa=3753&Obdobi=105&rok=2026&KodU=…&fkat=Person%C3%A1l&fq=person+nikol+kveten&hledat=1
Poznámky
- Duplicitní select
fent(EntitaTyp) z formuláře odstraněn — oblast pokrýváfkat. - Konkrétní den (
dd) má prioritu před měsíčním obdobím; skrytéddv formuláři už nepřepisuje měsíc. - Rychlé parsování jen při
fqGo=1— změna měsíce/roku v selectu nevolá parserfq. - Oprava VBScript: u data
15.10se nepřistupuje kparts(2)bez kontrolyUBound(AND nezkracuje).
SQL: AkceHistSqlWhereBase — období z Obdobi+rok nebo jeden den z dd; AkceHistSqlWhereExtra — KodU, fkat, fmod, ftyp, fvysl, ftxt, fdiff, flegacy.
Krok 6.1b — Co z 6.1 ještě chybí hotovo 6. 2026
- hotovo Dropdown Modul (
fmod) ve formuláři — stejná logika jako odkazy ze souhrnu „Nejnavštěvovanější oblasti" (AkceHistUrlPopisExpr). - hotovo Checkbox Skrýt legacy (
flegacy=1) — filtrTypAkce IS NOT NULL; ve forenzním pohledu výchozí zaškrtnuto. - hotovo Barevné badge Vysledek v detailu — OK (zelená), Zamítnuto (červená), Chyba (tmavě červená) vedle badge TypAkce.
Krok 6.2 — Detail řádku hotovo 6. 2026
- hotovo Sloupce: DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek (krok 4.1c).
- hotovo Rozbalitelný diff DataPred → DataPo.
- hotovo Barva řádku (
AkceHistRowCssClass): ok=zelená, denied=červená, error=oranžová — třídyuact-hist-row--ok/denied/errorvUserActivityHist.css.
Krok 6.3 — Export CSV hotovo 6. 2026
Soubor: !akce/AkceHistorieExport.x — stejné WHERE jako filtr (AkceHistSqlWhere), UTF-8 CSV se středníkem (Excel cs-CZ), max 50 000 řádků.
- hotovo Tlačítko Export CSV u „Kroků celkem" — předá aktuální filtry z URL.
- hotovo Sloupce:
id;DatumCas;KodU;Jmeno;KodAkce;TypAkce;Modul;ModulPopis;Oblast;EntitaTyp;EntitaId;Vysledek;Popis;PopisAkce;DataPred;DataPo;Url - hotovo
Vysledekjako textok|denied|error; při >50 000 řádcích chybová hláška (zúžit filtr).
Krok 6.4 — Kategorie z Modul/EntitaTyp hotovo 6. 2026
Soubor: AkceHistorieHistLib.x — AkceHistKategorieExpr() bez Popis LIKE; pořadí: EntitaTyp → Modul (AkceHistModulKategorieSql) → fallback URL (legacy).
- hotovo Nové entity:
smlouva,nakladovy_list. - hotovo Modul mapuje step01–step99, AkceDel, AkceKopie, akce (ZO).
- hotovo Rychlé hledání
fqdoplněno o „nákladový“ → Nákladové listy.
FÁZE 7 — Integrita a provoz implementováno 6. 2026
Krok 7.1 — DB uživatel: pouze INSERT na historyworkers
Soubor: !!MySQL/historyworkers_integrita — vzorové GRANT SELECT, INSERT + REVOKE UPDATE, DELETE pro aplikační účet. Spustit ručně na MySQL (ne z ASP).
Krok 7.2 — Archivace do historyworkers_archive
Soubory: !!MySQL/historyworkers_integrita (DDL), /HistoryWorkersArchive.x, /HistoryWorkersIntegritaLib.x (HW_ArchiveRunBatch).
- Výchozí stáří: 7 let (
Application("HW_ArchiveYears")nebo parametr?years=7). - Dry run:
/HistoryWorkersArchive.x?years=7— jen počet k přesunu. - Spuštění:
…&run=1(adminzznebot), dávky po 5000 řádcích.
Krok 7.3 — Audit admin=zz (volitelně)
Soubor: HistoryWorkersIntegritaLib.x — HW_LogSkipAdminZz() nahrazuje pevné SESSION("admin")=zz v HistoryWorkersLib.x a ActiveHistoryWorkers.x.
Zapnutí auditních stop pro konfigurátora menu: v !StrUvodConfig.x nebo Global.asa nastavit Application("HW_LogAdminZz") = True (výchozí False = dosavadní chování).
Krok 7.4 — Monitoring INSERT/min
Po každém úspěšném INSERT volá HW_MonitorInsertAfterSuccess() — počítadlo v Application, limit výchozí 100/min (Application("HW_InsertAlertPerMin")).
Při překročení zápis do /!error/historyworkers_alert.log (jednou za minutu).
- hotovo SQL skript oprávnění + DDL archivu
- hotovo Archivace ASP + batch přesun
- hotovo Volitelný audit zz (
HW_LogAdminZz) - hotovo Alert INSERT/min
- hotovo Dokumentace pro uživatele — sekce Návod pro uživatele
3.1 Testovací checklist po každé fázi
Hlavní testy na aa=3753 (baseline 2 467 záznamů). Opakování a mazání kopií — aa=6512 (detail).
| Test | Očekávání / stav |
|---|---|
| Otevřít step04?aa=3753 bez uložení | +0 nových řádků (po Fázi 1.3) |
| Vložit 1 personál (3753) | +1 (po Fázi 1.1, ne +2) |
| Opravit cenu v step06 (3753) | +1 s diff (Fáze 4.1) |
| Pokus o smazání — špatná ZO (3753) | +1 DENIED, [ZAMÍTNUTO] |
| Opakování akce (6512 → 6568–6595) | ověřeno 57× CREATE step01 — 5.1 |
| Kopie + kolize prostor (6512 → 6572) | ověřeno id 1662476 CREATE + 1662477 KOLIZE — 5.9 |
Mazání kopií akcedelkopie.x?aa=6512 | ověřeno id 1662397, AkceDelKopie, pocet=28 |
| historie.x?aa=3753 forensic view | Filtry KodU/fkat/ftyp/období/fq (Fáze 6.1) |
| Export CSV | hotovo krok 6.3 — AkceHistorieExport.x |
3.2 Časový odhad celkem
| Fáze | Obsah | Odhad | Kumulativně |
|---|---|---|---|
| 0 | Příprava | 1 den | 1 den |
| 1 | Hotfix bez DB | 1–2 dny | ~3 dny |
| 2 | Knihovna HW_Log + pilot | 2–3 dny | ~1 týden |
| 3 | ALTER TABLE | 1 den | ~1,5 týdne |
| 4 | Migrace handlerů | 2–3 týdny | ~1 měsíc |
| 5 | Kritické mezery | 1 týden | ~5 týdnů |
| 6 | UI + export | 1 týden | ~6 týdnů |
| 7 | Integrita | průběžně | — |
HistoryWorkersArchive.x).
3.3 Prompty pro implementaci v Cursoru
Stav kódu: Fáze 0–7 hotovo (červen 2026). Dokumentace synchronizována s implementací.
Fáze 0 — ruční (bez Cursoru)
Krok 0.1 splněn: aa=3753, baseline 2 467,
baseline_max_id = 1660945, ruční test nove_od_baseline = 42.
Krok 0.2 splněn: záloha historyworkers + celá aplikace DOVIS;
DB MySQL / InnoDB; schéma rozšířeno (sloupce Fáze 3.1 již v tabulce).
Fáze 1 — hotfix (zkopírujte do chatu)
Krok 1.1 — duplicitní zápis
Krok 1.2 — !StrUvod2 hotovo
Krok 1.3 — šum step*.x
Krok 1.4 — [ZAMÍTNUTO] hotovo
Krok 1.5 — login/logout hotovo
Krok 1.6 — filtr historie hotovo
Celá Fáze 1 najednou
Fáze 2 — knihovna HW_Log
Krok 2.1–2.3 hotovo — knihovna, globální include, pilot na 3 souborech.
Fáze 3 — databáze
Krok 3.1–3.3 hotovo — schéma, backfill, ASP INSERT.
Fáze 4 — migrace modulů (po jednom)
Krok 4.1 hotovo — step06Vloz.x + step06HistLib.x, 22× Step06_Log s diff. Ověřeno aa=3753 (id 1661150–1661161).
Krok 4.1b–c hotovo — diff filtr (fdiff=1), sloupce Typ/Modul/Entita; 6.1 formulář filtrů + fq (detail).
Krok 4.2 hotovo + ověřeno — id 1661179, DataPred = DataPo při uložení beze změny.
Krok 4.3 hotovo + ověřeno — CREATE/UPDATE/DELETE, id 1661203 DataPred = DataPo.
Krok 4.4 hotovo + ověřeno — step02/step021 CREATE/DELETE, baseline 1661269.
Krok 4.5 hotovo — TechnikaHistLib, step08–10, NabidkuAktivuj, step08NabidkaDel.
Krok 4.6 hotovo + ověřeno — Step03/07 HistLib, baseline 1661660.
Krok 4.7 hotovo + ověřeno — AkceDelHistLib, baseline 1661696 (krok1 + DENIED obchodníka).
Krok 4.8 hotovo + ověřeno — FilesHistLib, upload/del příloh a dokumentů, DigiSign kompletní stopa (odeslání, stavy, příjemci, audit PDF id 1661819).
Krok 4.9 hotovo + ověřeno — SmlouvyHistLib, editor CREATE/UPDATE, soft DELETE/obnovení, PAGE_VIEW náhled/tisk (id 1661766). Viz detail 4.9.
Krok 4.10 hotovo + ověřeno — step20 (id 1661861), step95 energie (1661850–1661857); step80HistLib nasazen, test chybí. Viz detail 4.10.
SmlouvyHistLib.x, SmlouvuVloz, SmlouvyDel, náhled/tisk !DOC/smlouva01.x (PAGE_VIEW, EntitaTyp=smlouva, id 1661766). Viz krok 4.9.step20HistLib, step94HistLib, step80HistLib; ověřeno aa=3753: přepis vlastních detailů id 1661861, energie step95 CREATE/UPDATE id 1661850, 1661852, 1661857 (EntitaTyp=spotreba, diff sazby). Viz krok 4.10. Zbývá test step80.Fáze 5 — kritické mezery hotovo 5.1–5.9
Fáze 6 — UI historie.x
Souvisí s: forenzní požadavky · původní plán F0–F4 · matice položek · shrnutí mezer.
1. Přehled architektury
Systém sleduje kroky přihlášených uživatelů v DOVIS. Jádrem je soubor
/ActiveHistoryWorkers.x, který provede INSERT INTO historyworkers.
Data se pak zobrazují v historie.x?aa=3753 (kroky akce) nebo
historie.x?kt=… (kroky kontaktu).
┌─────────────────────────────────────────────────────────────────────────┐
│ HTTP požadavek (uživatel přihlášen, SESSION("KodU") <> "") │
└─────────────────────────────────────────────────────────────────────────┘
│
├─► CESTA A — !StrUvod2.x (začátek) zrušeno Krok 1.2
│
├─► CESTA B — business logika nastaví PopisXX, KodAkceHistorie…
│ → include ActiveHistoryWorkers.x (inline po operaci)
│
└─► CESTA C — !StrKonec.x / !StrKonec2.x / !StrKonec3.x
→ !StrErrorKonec.x (konec stránky)
→ ActiveHistoryWorkers.x (výchozí „Stranka: /cesta.x")
!StrKonec*.x dříve zapisoval dvakrát — dnes SESSION("HistLogged") blokuje pasivní CESTU C
ve stejném requestu. CESTA A ze !StrUvod2 je odstraněna.
2. Schéma tabulky historyworkers
Sloupce zapisované v ActiveHistoryWorkers.x (řádky 26–139):
| Sloupec | Zdroj | Účel |
|---|---|---|
| najemce | SESSION("najemce") | Multi-tenant (volitelně) |
| KodU, Jmeno | SESSION("KodU"), SESSION("Osoba") | Kdo provedl krok |
| Den…Sekunda | NOW() | Čas (rozložený na sloupce) |
| Tyden, DenNazev, MesicNazev, Ctvrtleti | výpočet z NOW() | Agregace / reporty |
| URL | PATH_INFO (lowercase) | Který skript běžel |
| URLp | QUERY_STRING | GET parametry |
| Odkud | HTTP_REFERER | Předchozí stránka (nen spolehlivé) |
| IPAdresa | REMOTE_ADDR | IP klienta |
| Popis | PopisXX (proměnná stránky) | Hlavní text kroku — volný formát HTML |
| KodAkce | KodAkceHistorie → Request("aa") → Request("KodAkce") | Vazba na akci |
| NazevAkce | NazevAkceHistorie | Název / zkratka entity |
| PopisAkce | PopisAkceHistorie / HW_Log detail | Detailní popis (terminy, diff text…) |
| KodKontaktu | KodKontaktu | Vazba na kontakt |
| DatumCas | NOW() při INSERT | Jednotné řazení v čase (Fáze 3) |
| TypAkce | HW_Log | CREATE, UPDATE, DELETE, DENIED, AUTH_LOGIN, PAGE_VIEW… |
| Modul | HW_Log | step01, step04, step06, akce… |
| EntitaTyp, EntitaId | HW_Log | personal, misto, technika… + ID řádku |
| Vysledek | HW_Log | ok, denied, error |
| DataPred, DataPo | HW_LogDiff | Diff key=value před/po UPDATE/DELETE |
| RequestId | !StrUvodConfig.x | Korelace kroků v jednom requestu |
Legacy řádky (jen PopisXX) nemají TypAkce/EntitaId — ve UI filtr „Skrýt legacy".
Archivace starších než 7 let: tabulka historyworkers_archive (Fáze 7).
3. Tři mechanismy zápisu
3.1 Automatický zápis na začátku — CESTA A zrušeno u !StrUvod2
Dříve /!StrUvod2.x — include hned po auth (Krok 1.2 odstraněn). Upload/delete/login handlery nyní logují explicitně (CESTA B) nebo přes !StrKonec2 (CESTA C).
3.2 Automatický zápis na konci — CESTA C
/!StrKonec.x, !StrKonec2.x, !StrKonec3.x
→ !StrErrorKonec.x → ActiveHistoryWorkers.x.
Téměř každá běžná stránka s !StrUvod.x + !StrKonec.x zapisuje
pasivní návštěvu. Výchozí popis: Stranka: /cesta.x.
Detekce vyhledávání: !hledej/HledejHistoryLib.x funkce HledejHistoryDetect()
— při parametrech q, slovo, nazevakce… vytvoří Vyhledávání: modul: text [režim].
3.3 Explicitní zápis po operaci — CESTA B
Vzor v kódu:
KodAkceHistorie = KodAkce NazevAkceHistorie = nazevakce PopisAkceHistorie = popisakce PopisXX = "<b>Vložen personál:</b> …" %><!--#include virtual="/ActiveHistoryWorkers.x"--><%
Volá se hned po úspěšném SQL (insert/update/delete), ještě před redirectem.
4. Výjimky a filtry v ActiveHistoryWorkers.x
| Podmínka | Chování |
|---|---|
| SESSION("KodU") = "" | Žádný zápis (nepřihlášený) |
| SESSION("admin") = "zz" | Žádný zápis (výchozí); volitelně Application("HW_LogAdminZz")=True — Fáze 7.3 |
| PATH: /404.x, /zz.x, /z.x | Přeskočeno |
| PATH: /historie.x, /users.x | Přeskočeno (šetření DB) |
| Popis = „Stranka: /kontakty.x" (triviální) | Neukládat (prohlížení kontaktu) |
| Popis = „Stranka: /hledej.x" | Neukládat (hledání má vlastní záznam) |
| Vyhledávání globální, stejný dotaz < 120 s | Debounce přes Application lock |
| !StrErrorKonec: kontakty.x?action=view&dd= | Celý zápis přeskočen (knHistSkip) |
Přihlášení / odhlášení se zapisují od Kroku 1.5 (PrihlaseniDokonceni.x, logoff.x), KodAkce=0, TypAkce=AUTH_*.
5. Explicitní audit — soupis souborů a co se audituje
Soubory s přímým #include ActiveHistoryWorkers.x (bez záloh PAJO-DATA):
5.1 Základ akce (step01, step00, fakturace)
| Soubor | Co se audituje (PopisXX / PopisAkceHistorie) |
|---|---|
!step01/step01Vloz.x | Nová akce, oprava akce, změna termínů (služby, inventář, personál, technika, prostory), stav techniky (1/2/3) |
!step01/step01VlozFakturace.x | Fakturační údaje akce |
!step01/step01VlozFakturace2.x | Fakturační údaje akce (varianta 2) |
!step01/step01VlozFakturace3.x | Fakturační údaje akce (varianta 3) |
!step01/step01VlozBalickyMista.x | Balíčky míst u akce |
!step01/step01TestMista.x | Kolize obsazeného místa (varování) |
!step00/step00Vloz.x | Úvodní krok / metadata akce |
!!SHOP/!step01/step01Vloz.x | Shop varianta vložení akce |
!akce/AkceInfo.x | Vložení nové akce (PopisXX — zápis přes StrErrorKonec, ne inline) |
5.2 Prostory (step02, step021, step07)
| Soubor | Co se audituje |
|---|---|
!step02/step02vloz.x | Vložení / smazání prostoru, cena, nákup |
!step02/step02datum.x | Změna data prostoru |
!step02/step02vlozPriprava.x | Příprava místa |
!step021/step021vloz.x | Vložení / smazání prostoru (nový UI) |
!step07/step07vloz.x | Vložení / oprava služby (prostorový modul) |
!step07/step07VlozJeden.x | Vložení jedné služby |
!akce/AkceMistnostiDel.x | Smazání prostoru v akci |
5.3 Mobiliář / inventář (step03)
| Soubor | Co se audituje |
|---|---|
!step03/step03Vloz.x | Vložení / oprava mobiliáře |
!step03/step03VlozJeden.x | Vložení jedné položky mobiliáře |
!akce/AkceInventarDel.x | Smazání mobiliáře z akce |
5.4 Personál (step04)
| Soubor | Co se audituje |
|---|---|
!step04/step04vloz.x | Vložení / oprava personálu, termíny OD/DO |
!step04/step04VlozJeden.x | Vložení jednoho člena personálu |
!step04/step04aVloz.x | Hromadné vložení personálu (varianta A) |
!step04/step04bVloz.x | Varianta B personálu |
!step04/step04VlozVice.x | Více personálu najednou |
!akce/AkcePersonalDel.x | Smazání personálu z akce |
5.5 Kalkulace / objednávka (step06) — nejvíce zápisů
| Soubor | Co se audituje |
|---|---|
!step06/step06Vloz.x | 20+ větví: oprava prostor, služeb, techniky, cateringu, personálu; vložení služby; poznámka v objednávce; změny cen, slev, nákupů |
5.6 Technika a nabídky (step08–10, step14)
| Soubor | Co se audituje |
|---|---|
!step08/step08NabidkaVloz.x | Vložení nabídky techniky |
!step08/step08NabidkaForm.x | Formulář nabídky |
!step08/step08NabidkaDel.x | Smazání nabídky / techniky |
!step09/step09Vloz.x | Technika — vložení / oprava |
!step10/step10Vloz.x | Mažu techniku, oprava kusů, ceny prodej/dodavatel |
!step10/step10VlozNovouTechniku.x | Nová technika (kusu, dny, ceny) |
!step10/step10NabidkaKopiruj.x | Kopie nabídky techniky |
!step10/step10NabidkaVyber.x | Výběr nabídky |
!technika/NabidkuAktivuj.x | Aktivace nabídky |
5.7 Detail, energie, školní pomůcky
| Soubor | Co se audituje | Stav |
|---|---|---|
!step20/step20HistLib.x | Centrální HW_LogDiff pro detail akce a vlastní položky | 4.10 |
!step20/step20vloz.x | CREATE/UPDATE dovakcedetail + vlastní položky | 4.10 |
!step20/step20newVloz.x | Hromadný přepis vlastních detailů (EntitaTyp=akce) | 4.10 |
!step94/step94HistLib.x | Centrální log pro dovakcespotreba | 4.10 |
!step94/step94vloz.x | Energie u akce — CREATE/UPDATE (KodAkce=aa) | 4.10 |
!step95/step95vloz.x | Energie u akce — CREATE/UPDATE | 4.10 |
!step94/step94mereni.x | Premier import → dovakcespotreba (KodAkce=0) | 4.10 + ověřeno |
!step95/step95vloz.x | Energie (modul step95) — CREATE/UPDATE | 4.10 |
!step80/step80HistLib.x | Školní pomůcky v dovakceinventar | 4.10 |
!step80/step80Vloz.x | CREATE/UPDATE školní pomůcky | 4.10 — k testu |
!akce/AkceSluzbyDel.x | Smazání služby z akce | bez HW_Log |
5.8 Mazání a lifecycle akce
| Soubor | Co se audituje |
|---|---|
akcedelpotvrd.x | Požadavek smazání krok1, chyba zodpovědné osoby |
!akce/AkceDel.x | Smazání krok1, chyba práv, neoprávněné smazání, skrytí, kompletní smazání |
!akce/AkceDelKopie.x | Skrytí kopií akce |
!akce/AkceDelZavrit.x | Uzavření / smazání workflow |
zodpovedna/KontrolaZodpovedneOsobyZaAkci.x | Kontrola zodpovědné osoby (PopisXX = ZakladniTextZO) |
5.9 Smlouvy a dokumenty
| Soubor | Co se audituje | Stav |
|---|---|---|
!smlouvy/SmlouvyHistLib.x | Centrální HW_LogDiff pro smlouvy — snapshot obsah_len | 4.9 |
!smlouvy/SmlouvuVloz.x | CREATE nová / UPDATE editor HTML smlouvy | 4.9 |
!smlouvy/SmlouvyDel.x | DELETE soft / UPDATE obnovení (smazano) | 4.9 |
!DOC/smlouva01.x | PAGE_VIEW náhled/tisk; mod=step75 ze step75 | 4.9 |
!step60/step60vloz.x | Starší pole OD/DO aut ve smlouvě | bez HW_Log |
FilesAkceUpload.x | Vložena příloha k akci | 4.8 |
FilesDokumentUpload.x | Upload dokumentu | 4.8 |
!akce/AkceFilesDel.x | Smazán soubor akce | 4.8 |
!akce/AkceDokumentyDel.x | Smazán dokument akce | 4.8 |
nakupy/filedel.x | Smazán soubor nákupů | legacy |
donio_dokument/DokumentDel.x | Smazán dokument Donio | legacy |
5.10 Kontakty
| Soubor | Co se audituje |
|---|---|
!DOV/KontaktyVloz.x | Nový / úprava kontaktu (IČO, DIČ, ARES datová schránka) — KodKontaktu |
!DOV/KontaktyPoznamkaVloz.x | Poznámka kontaktu uložena |
!DOV/KontaktyOsobaVloz.x | Osoba u kontaktu — vložení / úprava |
5.11 Nákupy / Webcollab shop
| Soubor | Co se audituje |
|---|---|
webcoll_shopping/ShopVloz.x | Nákup, koupeno, dokončeno, smazána položka, vrácení, oprava |
!!SHOP/!step02/step02vloz.x | Shop prostory |
!!SHOP/!step03/step03vloz.x | Shop mobiliář |
5.12 Infrastruktura (ne business logika)
| Soubor | Úloha |
|---|---|
/ActiveHistoryWorkers.x | Jádro INSERT |
/!StrUvod2.x | Lehká hlavička handlerů (bez auto-zápisu od Kroku 1.2) |
/!StrErrorKonec.x | Auto-zápis na konci requestu |
!hledej/HledejHistoryLib.x | Detekce hledání + volitelný HledejHistoryZapis() |
6. Pasivní audit — každá navštívená stránka
Všechny stránky používající !StrUvod.x + !StrKonec.x automaticky
zapisují krok typu Stranka: /step02.x, Stranka: /akce.x atd.
To zahrnuje stovky vstupních souborů v kořeni DOVIS, např.:
step01.x…step99.x— prohlížení kroků bez uloženíakce.x,kontakty.x,personal.x,technika.xhledej.x— jen při odeslání formuláře (hledat=1), s debounce 60–120 s- Moduly: majetek, nakupy, donio, webcollab, graf, nastenka…
historie.x?aa=3753 je většina záznamů „šum" — prohlížení stránek se stejným
KodAkce odvozeným z URL parametru aa, i když uživatel nic nezměnil.
7. Zobrazení dat — historie.x
| URL | Include | Co zobrazuje |
|---|---|---|
historie.x?aa=3753 |
!akce/AkceHistorieShow.x |
Souhrn kroků akce: kompaktní formulář filtrů (období, uživatel, oblast, typ, stav, rychlé hledání fq),
aktivita po dnech, kategorie (EntitaTyp + Modul + fallback Popis/URL),
uživatelé, detail kroků, graf cen (AkceHistorieCenGraf.x).
Viz Fáze 6.1.
|
historie.x?kt=… |
/ActiveHistoryView.x |
Prostý chronologický seznam podle KodKontaktu |
Kategorizace v AkceHistorieHistLib.x (AkceHistKategorieExpr) primárně z
EntitaTyp a sloupce Modul; u legacy záznamů bez těchto polí fallback podle URL.
Filtr oblasti ve formuláři (fkat) používá stejné názvy kategorií.
8. Známé problémy a kolize
8.1 Dvojitý zápis za jeden request
- Handler +
!StrKonec.x→ dříve 2×; nyníHistLogged(Krok 1.1) blokuje druhý zápis !StrUvod2+!StrKonec2→ dříve CESTA A + C; CESTA A odstraněna (Krok 1.2)
8.2 Kolize „kdo udělal chybu" vs „kde"
-
Smazání akce: uživatel klikne na
akcedelpotvrd.x, validace selže → log na handleru s textem „Nesprávná zodpovědná osoba", ale referer může být jiná stránka; po redirectu další generický krok. -
KodAkce z Request: pasivní návštěva
step04.x?aa=3753přiřadí akci 3753 i bez editace — v historii vypadá jako aktivita na akci. -
Chyba vs úspěch: sloupec
VysledekaTypAkce=DENIEDu zamítnutých operací; UI barevně zvýrazňuje denied (červená) a error (oranžová) — Fáze 6.2. - HTTP_REFERER: nespolehlivý (privacy, HTTPS→HTTP, bookmark); sloupec Odkud nelze použít pro forenzní analýzu.
8.3 Chybějící nebo slabý audit
- hotovo Přihlášení / odhlášení (Fáze 1.5)
- Colosseum, step99 úkoly — bez HW_Log handlerů
step01RozsireniVloz.x— superadmin rozšíření bez auditu!akce/AkceSluzbyDel.x,step60vloz.x(starší pole) — bez HW_Log- Exporty, tisky — jen pasivní Stranka (záměrně ne forenzní)
- AJAX volání přes
!StrUvod3.x— bez automatického zápisu (explicitní HW_Log nutný)
8.4 Datová kvalita
- PopisXX obsahuje HTML (<b>, <br>) — u legacy; HW_Log má strukturovaný diff
- Duplicitní informace v Popis + PopisAkce + NazevAkce u starých zápisů
- Legacy čas v Den…Sekunda; nové řádky mají
DatumCas(Fáze 3) - Indexy na KodAkce/DatumCas doplněny ve Fázi 3; velmi staré akce mohou být pomalé
10. Plán implementace (fáze)
| Fáze | Úkol | Náročnost |
|---|---|---|
| F0 — hotfix | SESSION flag proti dvojitému zápisu; audit přihlášení/odhlášení; prefix [ZAMÍTNUTO] u permission denied | 1–2 dny |
| F1 — knihovna |
Vytvořit /HistoryWorkersLib.x podle WebSpinani vzoru;
postupně nahradit inline PopisXX v top 10 souborech (step01, step06, AkceDel)
|
1 týden |
| F2 — schéma | ALTER TABLE historyworkers — TypAkce, Vysledek, DatumCas, RequestId; index (KodAkce, DatumCas) | 2–3 dny + test |
| F3 — UI historie | Filtry v AkceHistorieShow.x; rychlé hledání fq; skrýt PAGE_VIEW; export CSV |
1 týden |
| F4 — migrace | Projít zbývajících ~60 handlerů; sjednotit PopisXX → HW_Log(); vypnout pasivní log u step*.x | 2–3 týdny |
Prioritní soubory pro F1 (největší dopad na historie.x?aa=)
!step06/step06Vloz.x— nejvíce větví a zápisů!step01/step01Vloz.x— základ akce!step02/step02vloz.x,!step021/step021vloz.x— prostory!step04/step04vloz.x— personál!step10/step10Vloz.x— technika!akce/AkceDel.x,akcedelpotvrd.x— kolize chyb
11. Životní cyklus akce — vložení a všechny položky
Tato kapitola se zaměřuje výhradně na akci (KodAkce / parametr aa)
a na vše, co k ní v DOVIS patří — od založení po smazání. Cíl auditu:
u každého kroku v historie.x?aa=3753 vidět kdo (KodU/Jmeno),
co (typ operace + entita), kdy a výsledek (OK / zamítnuto / chyba).
11.1 Vytvoření nové akce
| Fáze | Handler | Audit dnes | Co se loguje | Mezery |
|---|---|---|---|---|
| Formulář step01 | step01.x |
Jen prohlížení | Stranka: /step01.x?aa=… (pasivně) | Neaudituje se otevření formuláře — OK |
| Uložení nové akce | !step01/step01Vloz.x |
HW_Log | CREATE/UPDATE, diff termínů, EntitaTyp=akce |
Volitelně doplnit KodKontaktu ve diff |
| Opakování akce | !step01/step01OpakujRun.x, akceopakuj.x |
HW_Log | CREATE nových akcí, DENIED při kolizi — Fáze 5.1 | Ověřeno aa=6512 |
| Fakturační údaje | step01VlozFakturace*.x |
HW_Log | UPDATE s DataPred/DataPo (IČO, adresa, splatnost…) |
— |
| Balíčky míst | step01VlozBalickyMista.x |
HW_Log | CREATE/UPDATE prostor v balíčku | — |
| Kolize místa při vkládání | step01TestMista.x |
Explicitní | Obsazené místo, termíny, v akci X | Dobré — varování je auditováno |
11.2 Editace základních údajů akce
| Operace | Handler | Audit | Logovaná pole | Doporučení |
|---|---|---|---|---|
| Oprava názvu, popisu, termínů | step01Vloz.x (UPDATE větev) |
Ano | Oprava akce, PopisAkceHistorie s termíny, změny termínů podřízených modulů (služby, inventář, personál, technika, prostory) | hotovo — diff termínů v HW_Log; UI filtr fdiff=1 |
| Rozšířené údaje (superadmin) | step01RozsireniVloz.x |
Ne | — | Přidat HW_Log DATA_UPDATE, modul step01 |
| Detail akce (step20) | !step20/step20vloz.x |
Ano | Vložen/opraven detail — harmonogram, security, personální role | Logovat která pole se změnila (technika, catering, security…) |
| Step90 — souhrny / bilance | !step90/*.x (sync cache) |
Pasivní | Stranka: /step90.x | Sync operace neauditovat; auditovat jen ruční změny cen v souhrnu |
11.3 Smazání / skrytí celé akce
| Krok | Handler | Audit | Popis v DB |
|---|---|---|---|
| Požadavek smazání (krok 1) | akcedelpotvrd.x | Ano | Požadavek na smazání krok1 / Nesprávná zodpovědná osoba |
| Validace práv / ZO | !akce/AkceDel.x | Ano | Chyba smazání, neoprávněné smazání, Obchodník nemá práva |
| Skrytí (soft delete) | AkceDel.x, AkceDelKopie.x | Ano | Akce je zkrytá |
| Kompletní smazání | AkceDel.x | Ano | Kompletně i s příslušenstvím smazána |
| Uzavření workflow | AkceDelZavrit.x | Ano | Uzavření |
Jmeno a TypAkce=DELETE/DENIED.
URL stále ukazuje handler (/!akce/akcedel.x), ne stránku kde uživatel potvrdil —
pro forenzní účely kombinujte s časovou posloupností a filtrem podle KodU.
12. Matice všech položek akce — audit stav
Menu akce řídí tabulka configmenu (MenuAkce = číslo kroku).
Legenda stavu auditu:
Plný explicitní PopisXX + KodAkceHistorie ·
Částečný jen některé operace ·
Chybí jen pasivní Stranka ·
Pasivní pouze návštěva stránky
| Menu | Krok / stránka | Položka / tabulka | Vložení | Editace | Mazání | Stav auditu | Handler(y) |
|---|---|---|---|---|---|---|---|
| 1 | step01 / akce.x | Základ akce — dovakce |
✓ | ✓ | ✓ (AkceDel) | Plný | step01Vloz, AkceDel, akcedelpotvrd |
| 2 / 21 | step02, step021 | Prostory — dovakcemista |
✓ | ✓ (datum, ceny) | ✓ | Plný | step02vloz, step021vloz, step02datum, AkceMistnostiDel |
| 3 | step03 | Mobiliář — dovakceinventar |
✓ | ✓ | ✓ | Plný | step03Vloz, step03VlozJeden, AkceInventarDel |
| 4 | step04 | Personál — dovakcepersonal |
✓ | ✓ | ✓ | Plný | step04vloz, step04VlozJeden, step04a/bVloz, step04VlozVice, AkcePersonalDel |
| 4 | step04 | Personál hromadně (Multi) | ✓ | — | — | Plný | step04vlozMulti.x — jednotlivě + souhrn ids= (Fáze 5.5) |
| 5 | step05 | Přílohy — dovakceprilohy |
✓ | — | ✓ | Částečný | FilesAkceUpload (vložení), AkceFilesDel (mazání); editace metadat přílohy neauditována |
| 6 / 96 | step06 | Kalkulace / objednávka — skladkartapohyby |
✓ | ✓ | — | Plný | step06Vloz.x — 22× ActiveHistoryWorkers, všechny oblasti v kalkulaci |
| 7 | step07 | Služby — dovakcesluzby |
✓ | ✓ | ✓ | Plný | step07vloz, step07VlozJeden, AkceSluzbyDel |
| 7 | step07 | Služby Multi | ✓ | — | — | Plný | step07vlozMulti.x — Fáze 5.5 |
| 9 / 10 | step08–10, step14 | Technika — dovakcetechnika |
✓ | ✓ | ✓ | Plný | step08Nabidka*, step09Vloz, step10Vloz*, NabidkuAktivuj, step08NabidkaDel |
| 9 / 10 | step15 | Nákladové listy (step15) | ✓ | ✓ | ✓ | Plný | step15HistLib.x, step15Vloz, step15Del — Fáze 5.3 · test aa=6482 |
| 9 / 10 | step14 | Technika po dnech | — | ✓ | — | Plný | step14VlozPoDnech.x — Fáze 5.7 |
| 20 | step20 | Detail akce — dovakcedetail |
✓ | ✓ | — | Plný | step20vloz.x |
| 25 | Colosseum | Vstupenky Colosseum | ✗ | ✗ | ✗ | Chybí | Integrace v step01 — bez samostatného auditu |
| 30 | step30? | Protokol | ✗ | ✗ | ✗ | Pasivní | Bez vloz handleru s PopisXX |
| 40 | step40, step51 | Catering / zboží — dovakcezbozi |
✓ v step06 | ✓ v step06 | ? | Částečný | Kalkulace step06 audituje catering; step40VlozZbozi.x a step51vloz.x bez ActiveHistoryWorkers |
| 50 | step50 | Auta — dovakceauta |
✓ | ✓ | ✓ | Plný | step50HistLib.x + TimeLine — Fáze 5.4 · test aa=6482 |
| 60 | step60, smlouvy | Smlouvy — dovakcesmlouvy |
✓ | ✓ | ✓ | Plný | SmlouvyHistLib — editor CREATE/UPDATE, soft DELETE/obnovení, PAGE_VIEW náhled/tisk |
| 70 | step70 | Dokumenty — dovakcedokumenty |
✓ | — | ✓ | Plný | FilesDokumentUpload, AkceDokumentyDel.x — Fáze 5.8 |
| 75 | step75 | DigiSign / podpis — digisign_podpis |
✓ | ✓ | ✓ | Plný | Odeslání, sync/webhook stavy, příjemci, audit PDF (DigiSignHistLib); EntitaId=zdroj_id |
| 95 | step94, step95 | Energie — dovakcespotreba |
✓ | ✓ | — | Plný | Step94HistLib — step94vloz, step95vloz; step06 také loguje energii v kalkulaci |
| 99 | step99 | Projekt / úkoly | ✗ | ✗ | ✗ | Pasivní | Webcollab úkoly — bez audit handleru |
| — | akcekopiruj | Kopie celé akce | ✓ | — | ✓ | Plný | AkceKopieHistLib.x — Fáze 5.9, ověřeno 6512→6572 |
| — | step80 | Školní pomůcky — dovakceinventar |
✓ | ✓ | — | Plný | Step80HistLib — step80Vloz CREATE/UPDATE; stejná tabulka jako mobiliář, modul step80 |
| — | step43 | Mazání catering nabídky | — | — | ✓ | Plný | step43NabidkaDel.x — Fáze 5.6 |
12.1 step06 — kalkulace audituje všechny oblasti najednou
V step06Vloz.x je nejkompletnější audit (22 explicitních zápisů). Loguje:
- Prostory — oprava (cena, sleva, nákup, hodiny)
- Služby — vložení / oprava
- Inventář (mobiliář) — vložení / oprava
- Personál — vložení / oprava
- Catering — vložení / oprava (+ DPH)
- Energie — oprava (+ jiná energie)
- Jiné služby — vložení / oprava
- Auta — vložení / oprava (sazba za km)
- Poznámka v objednávce (finanční)
Problém: stejná položka může být auditována v step04 a znovu v step06 — duplicitní kroky v historii.
13. Vložení / editace / mazání — co logovat u každé operace
Standard, který by měl platit pro každý handler položky akce:
| Operace | Povinná pole v historyworkers | Stav (HW_Log moduly) | Zbývá / legacy |
|---|---|---|---|
| VLOŽENÍ položky | KodU, Jmeno, KodAkce, TypAkce=CREATE, EntitaTyp, EntitaId, název, termín, cena | Splněno — HW_Log + Popis pro UI | Legacy bez EntitaId |
| EDITACE položky | TypAkce=UPDATE, EntitaId, diff (stará→nová cena, termín, kusy) | Splněno — DataPred/DataPo | Staré řádky jen PopisXX |
| MAZÁNÍ položky | TypAkce=DELETE, EntitaId, snapshot smazané položky | Splněno — DataPred před DELETE | — |
| ZAMÍTNUTO (práva, ZO) | TypAkce=DENIED, Vysledek=denied, důvod | Splněno — červený řádek v UI | RefererPage zatím ne |
| PROHLÍŽENÍ kroku | TypAkce=PAGE_VIEW (volitelně) | Skryto ve view=forensic |
Stále v DB u starých návštěv |
13.1 Příklad: personál (step04) — stav po migraci
| Událost | Soubor | HW_Log | Poznámka |
|---|---|---|---|
| Vložení 1 osoby | step04VlozJeden.x | CREATE | EntitaId, DataPo, Modul=step04 |
| Oprava | step04vloz.x | UPDATE + diff | cena, termíny v DataPred/DataPo |
| Smazání | AkcePersonalDel.x | DELETE | DataPred snapshot před mazáním |
| Hromadné vložení | step04vlozMulti.x | CREATE + souhrn | Jednotlivě + řádek s ids= (5.5) |
| Prohlížení step04 | step04.x | Skryto | Ve forenzním pohledu neviditelné |
13.2 Příklad: prostory — duplicita step02 vs step021 vs step06
step02vloz.x/step021vloz.x— audit při vložení/smazání v kroku prostorstep06Vloz.x— audit při změně ceny prostoru v kalkulaci- V historii akce jsou 2–3 záznamy za jednu business akci — sjednotit přes EntitaId + TypAkce
13.3 Soubory bez auditu — zbývající mezery
- hotovo Opakování/kopie — Fáze 5.1, 5.9
- hotovo step15, step50, Multi, step43 del, step14, mazání dokumentů
- Colosseum, step99 úkoly — mimo rozsah migrace
step01RozsireniVloz.x,AkceSluzbyDel.x, staršístep60vloz.xstep40VlozZbozi.x,step51vloz.x— catering mimo step06 kalkulaci
14. Audit podle uživatele — identifikace a kolize
14.1 Co dnes identifikuje uživatele
| Pole | Zdroj | Spolehlivost | Poznámka |
|---|---|---|---|
| KodU | SESSION("KodU") | Vysoká | Primární klíč uživatele v DB |
| Jmeno | SESSION("Osoba") = fullname | Vysoká | Zobrazuje se v historie.x sloupec „Osoba" |
| IPAdresa | REMOTE_ADDR | Střední | Proxy/NAT — více uživatelů může sdílet IP |
| Odkud | HTTP_REFERER | Nízká | Často prázdné; ne pro forenzní analýzu |
| URL | PATH_INFO handleru | Střední | Ukazuje kde běžel kód, ne kde uživatel klikl |
14.2 Typické kolize „kdo vs. kde"
| Scénář | Co vidíte v historii | Skutečnost | Řešení |
|---|---|---|---|
| Uživatel A otevře step04, nic neuloží | Ve forenzním pohledu: nic (pasivní log potlačen / skryt) | Jen prohlížení | hotovo Fáze 1.3 + view=forensic |
| Uživatel B smaže akci, špatná ZO | KodU=B, URL=/akcedelpotvrd.x, Popis=Nesprávná zodpovědná osoba | B klikl na akce.x, confirm na jiné stránce | Logovat RefererPage + ActionPage; TypAkce=DENIED |
| Technik edituje step10, obchodník prohlíží step06 | Oba mají KodAkce=3753 v historii | Různí uživatelé, různé oblasti — OK, ale těžké filtrovat | Sloupec Modul + filtr podle KodU v historie.x |
| Admin „zz" pracuje v systému | Výchozí: žádný záznam | Konfigurátor menu — záměrně bez auditu | Volitelně Application("HW_LogAdminZz")=True (Fáze 7.3) |
| Dvojitý zápis po uložení | 1 řádek (HW_Log) nebo 2 u legacy step02 CREATE | Inline + StrErrorKonec | hotovo SESSION("HistLogged") flag |
14.3 Požadovaný výstup v historie.x?aa= podle uživatele
Pro analýzu sporů typu „kdo smazal personál v 14:32" potřebujete:
- Filtr uživatele — hotovo dropdown
KodU+ token jména vfq - Filtr typu operace — hotovo
ftyp(CREATE/UPDATE/DELETE/DENIED); výchozí skrytíStranka: - Filtr oblasti — hotovo
fkat(Personál, Prostory…) + aliasy vfq - Filtr období / den — hotovo
Obdobi+rok,dd, měsíce/data vfq - Rychlé vyhledávání — hotovo
person nikol kveten,georg 15.10— viz 6.1 - Sloupec EntitaId — hotovo sloupec Entita v detailu kroků
- Export — hotovo CSV:
AkceHistorieExport.x(max 50 000 řádků, UTF-8, středník) — Fáze 6.3
15. Konkrétní zlepšení pro historie.x?aa= — akce a položky
15.1 Okamžitá vylepšení (bez změny DB)
| # | Úkol | Soubor | Dopad |
|---|---|---|---|
| 1 | SESSION("HistLogged") po inline zápisu | ActiveHistoryWorkers.x, !StrErrorKonec.x | hotovo Fáze 1.1 |
| 2 | Vypnout pasivní log pro /step*.x | ActiveHistoryWorkers.x | hotovo Fáze 1.3 |
| 3 | Prefix [ZAMÍTNUTO] u AkceDel, akcedelpotvrd | !akce/AkceDel.x, akcedelpotvrd.x | hotovo Fáze 1.4 |
| 4 | Doplnit audit kopie akce | step01HistLib, AkceKopieHistLib, OpakujAkceLib | hotovo + ověřeno — 5.1, 5.9 |
| 5 | Doplnit audit DigiSign | step75PodpisOdeslat.x + DigiSignHistLib | hotovo (4.8) |
| 6 | step50 → HW_Log + TimeLine | step50HistLib, step50vloz | hotovo Fáze 5.4 · aa=6482 |
| 7 | Multi handlery step03/04/07 | *vlozMulti.x | hotovo Fáze 5.5 |
| 8 | V AkceHistorieShow výchozí skrýt „Stranka:" | AkceHistorieHistLib.x SQL WHERE | hotovo |
| 9 | Formulář filtrů + rychlé hledání fq | AkceHistorieShow.x, AkceHistorieHistLib.x | hotovo — 6.1 |
15.2 Šablona HW_Log pro nové handlery položek
' Volat po každém úspěšném INSERT/UPDATE/DELETE položky akce:
CALL HW_Log("UPDATE", "step04", "personal", KodAkcePersonal, KodAkce, _
"Opraven personál: " & PersonalZkratka, _
"OD=" & terminOdOld & "→" & terminOd & "; cena=" & cenaOld & "→" & cena, _
"ok")
' Parametry:
' typ = CREATE | UPDATE | DELETE | DENIED
' modul = step01, step04, step06…
' entita = personal | misto | technika | smlouva | priloha…
' entitaId = primární klíč položky v dovakce*
' kodAkce = vazba na akci
' popis = krátký text pro UI
' detail = diff / parametry
' vysledek = ok | denied | error
15.3 Mapování Modul → EntitaTyp (pro nové sloupce)
| Modul (step) | EntitaTyp | Tabulka | ID pole |
|---|---|---|---|
| step01 | akce | dovakce | Kod |
| step02 / step021 | misto | dovakcemista | Kod / KodAkceMisto |
| step03 | inventar | dovakceinventar | Kod |
| step04 | personal | dovakcepersonal | Kod |
| step05 | priloha | dovakceprilohy | Kod |
| step06 | kalkulace | skladkartapohyby | Kod |
| step07 | sluzba | dovakcesluzby | Kod |
| step08–10 | technika | dovakcetechnika | Kod |
| step20 | detail, detail_polozka | dovakcedetail, dovakcedetailvlastni | KodDetail / kod |
| step50 | auto | dovakceauta | Kod |
| step60 | smlouva | dovakcesmlouvy | KodSmlouvy |
| step70 | dokument | dovakcedokumenty | Kod |
| step75 | digisign | digisign_podpis → zdroj v dovakceprilohy / dovakcedokumenty | zdroj_id (EntitaId v HW) |
| step80 | inventar | dovakceinventar | Kod |
| step94, step95 | spotreba | dovakcespotreba | Kod |
15.4 Revize plánu F1 — priorita podle položek akce
- Kritické mezery: 5.1–5.9 hotovo · ověřeno DB: 5.1/5.9 aa=6512, 5.3/5.4 aa=6482 · viz detail Fáze 5
- Duplicity: sjednotit step02/021 vs step06 pro prostory; step04 vs step06 pro personál
- UI historie: hotovo filtry, fq, export CSV, barevné řádky ok/denied/error (Fáze 6)
- Postupná migrace: hotovo Fáze 4–5; zbývá provozní nasazení Fáze 7 na DB