ISKASA
  • Úvod
  • O systému
  • Moduly
  • Návod
  • FAQ
  • Historie
  • Kontakt

Návod: 18. Audit a historie změn u akce · technicky: 18. Audit historyworkers (technicky) · přehled návodu

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

Stav projektu (červen 2026): Fáze 0–5 migrace handlerů · Fáze 6 UI (filtry, export CSV, barevné řádky) · Fáze 7 integrita (SQL oprávnění, archivace, monitoring INSERT/min). Reference testy: 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.
Obsah
  1. Shrnutí — jsou všechny položky u akcí auditovány dostatečně?
  2. Forenzní audit — co je potřeba a proč
  3. Postup přestavby — krok za krokem
  4. Fáze 5 — detail kroků (5.1 → 5.9)
    1. 5.1 Opakování
    2. 5.2 DigiSign
    3. 5.3 Nákladové listy
    4. 5.4 Auta
    5. 5.5 Multi vložení
    6. 5.6 Mazání catering nabídky
    7. 5.7 Technika po dnech
    8. 5.8 Mazání dokumentů
    9. 5.9 Kopie + kolize
  5. Test opakování aa=6512
  6. Test kopie + kolize aa=6512
  7. Prompty pro implementaci (Cursor)
  8. Přehled architektury
  9. Schéma tabulky
  10. Tři mechanismy zápisu
  11. Výjimky a filtry
  12. Explicitní audit (významné akce)
  13. Pasivní audit (každá stránka)
  14. Filtry a vyhledávání historie.x (Fáze 6)
  15. Integrita a provoz (Fáze 7)
  16. 16. Návod pro uživatele — co historie.x umí
  17. Zobrazení v historie.x
  18. Známé problémy a kolize
  19. Návrh lepšího řešení
  20. Plán implementace
  21. Životní cyklus akce — vložení
  22. Matice všech položek akce
  23. Vložení / editace / mazání podle operace
  24. Audit podle uživatele — identifikace a kolize
  25. Konkrétní zlepšení pro historie.x?aa=

Shrnutí — jsou všechny položky u akcí auditovány dostatečně?

Odpověď: Ano pro forenzní MVP, s výhradami. Hlavní moduly akce (step01–10, step15/50, kopie, DigiSign, smlouvy…) mají strukturovaný zápis přes 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/tisk smlouva01.x) přes SmlouvyHistLib.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 / modulStav audituPoznámka
Kopie / opakování akce (akceopakuj, step01OpakujRun)HW_LogFáze 5.1 — CREATE + DENIED při kolizi prostor; viz test aa=6512
Jednorázová kopie (akcekopiruj, akcekopie_vloz.x)HW_LogFáze 5.9 — CREATE + KOLIZE + DENIED; ověřeno aa=6512 → 6572
DigiSign / podpis (step75)HW_LogOdeslání, sync/webhook stavy, příjemci, auditní stopa PDF — viz 4.8 DigiSign
Nákladové listy (step15)HW_Logstep15HistLib.x, step15Vloz.x, step15Del.x — Fáze 5.3
Auta (step50)HW_Logstep50HistLib.x + TimeLine — Fáze 5.4
Catering step43 — mazání nabídkyHW_Logstep43NabidkaDel.x — Fáze 5.6
Technika po dnech (step14)HW_Logstep14VlozPoDnech.x
Hromadné vložení (*vlozMulti.x step03/04/07)HW_LogJednotlivě + souhrn ids= — Fáze 5.5
Mazání catering nabídky (step43)HW_Logstep43NabidkaDel.x — Fáze 5.6
Colosseum, protokol, step99 úkolyPasivníJen „Stranka:" nebo nic
Mazání dokumentů akce (step70)HW_LogAkceDokumentyDel.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í:

  1. Duplicitní záznamy — u legacy handlerů stále možné; u HW_Log blokuje HistLogged pasivní CESTU C
  2. Pasivní šum — ve výchozím pohledu view=forensic skryt; staré řádky Stranka: zůstávají v DB
  3. Legacy bez EntitaId — staré logy mají text „Opraven personál: XY" bez EntitaId
  4. Legacy bez diff — u starých UPDATE bez DataPred/DataPo
  5. Duplicita step04 vs step06 — stejná položka může mít 2 záznamy (krok + kalkulace)
  6. Referer vs handler — URL stále ukazuje handler, ne dialog kde uživatel klikl

Celkové hodnocení pokrytí

Oblast akceOdhad 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)
Praktický závěr pro ISKASA: Pro běžný provozní přehled i pro většinu forenzních dotazů („kdo smazal personál", „kdo změnil cenu") je audit po Fázi 0–7 použitelný — zejména u akcí s novými záznamy HW_Log. U starých akcí nebo modulů mimo rozsah (Colosseum, step99) spoléhejte na kombinaci historie + kalkulace + příloh. Detailní matice: kapitola 12 · návod k UI: uživatelská sekce.

Nejvyšší priority doplnění

  1. hotovo Kopie akce (opakování) — 5.1
  2. hotovo DigiSign — 5.2 / 4.8
  3. hotovo + ověřeno Nákladové listy — 5.3
  4. hotovo + ověřeno Auta — 5.4
  5. hotovo Multi vložení — 5.5
  6. hotovo Mazání catering nabídky — 5.6
  7. hotovo Technika po dnech — 5.7
  8. hotovo Mazání dokumentů — 5.8
  9. hotovo Kopie + kolize — 5.9
  10. hotovo Hotfix — pasivní Stranka: skryto ve forenzním pohledu; HistLogged proti 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 sporuProč 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žadavekPročStav dnesImplementace
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žadavekProč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.
Legacy vs. HW_Log: Nové zápisy přes 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.

ModulProč je pro forenzní audit kritickýPriorita
Kopie akce (akceopakuj)Originál vs. kopie — kdo vytvořil duplicitní akci a kdyhotovo 5.1 · 6512
Jednorázová kopie + kolize (akcekopiruj)Kdo zkopíroval akci, přes jakou kolizi prostor/sklad, ProstoryOKhotovo 5.9 · 6512→6572
DigiSign step75Právní stopa — odeslání, stavy, příjemci, auditní PDFhotovo (4.8)
Nákladové listy step15Finanční dopad — kdo schválil / smazal nákladhotovo 5.3
Auta step50Náklady akce — HW_Log + TimeLinehotovo 5.4
Multi vložení step03/04/07Hromadná operace — souhrn ids=hotovo 5.5
Mazání dokumentů step70Symetrie k uploadu — kdo smazal smlouvu / PDFhotovo 5.8
Technika step14 (po dnech)Alternativní cesta editace techniky mimo step10hotovo 5.7

4. Integrita a spolehlivost záznamu — co doplnit a proč

PožadavekPročŘ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 UIPročStav
Výchozí filtr bez Stranka:Provozní šum maže signál — forenzní timeline jen DATA_* a DENIEDhotovo view=forensic
Filtr podle KodU„Vše co udělal uživatel (KodU) u této akce" — základ výslechuhotovo select + fq
Filtr TypAkce (CREATE/UPDATE/DELETE/DENIED)Izolovat mazání nebo neúspěšné pokusyhotovo ftyp
Filtr oblasti / Modul / EntitaTypJen personál, jen prostory — bez LIKE na Popishotovo 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áchhotovo fq + krok 6.1
Text v popisu / diffDoplnění nerozpoznaných tokenů nebo volný texthotovo ftxt
Barevné rozlišení VysledekOk = zelená, Denied = červená — okamžitá orientacehotovo badge v detailu
Sloupec EntitaId + odkaz na detail (pokud existuje)Propojení log ↔ datahotovo sloupec Entita
Export CSV / PDFPř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 PopisXXhotovo + fdiff=1

7. Rozdíl: provozní audit vs. forenzní audit

Provozní audit (dnes)Forenzní audit (cíl)
ÚčelPřehled aktivity u akceDůkaz o konkrétní změně a odpovědnosti
FormátVolný 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é operaceDENIED u AkceDel; Vysledek=deniedStejné — konzistentní u migrace
DuplicitySníženo HistLogged; step04/06 duplicita zůstáváRequestId + 1 business záznam na request
ExportCSV (Fáze 6.3) + obrazovkaCSV: DatumCas, KodU, TypAkce, EntitaId, diff, IP
Spolehlivost u soudu / sporuStřední u HW_Log; nízká u legacyVysoká 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:

  1. F0 hotfix — HistLogged proti duplicitám; audit login/logout; [ZAMÍTNUTO] u denied; skrýt Stranka: v historie.x
  2. F1 knihovna — HistoryWorkersLib.x s HW_Log(TypAkce, Modul, EntitaTyp, EntitaId, …)
  3. F2 schéma DB — TypAkce, Vysledek, EntitaTyp, EntitaId, DataPred, DataPo, RequestId, DatumCas + indexy
  4. F3 mezery modulů — akceopakuj, step15, step50, *Multi, mazání dokumentů
  5. F4 diff u UPDATE — step01 termíny, step04/06 ceny — načíst starý stav před UPDATE
  6. F5 UI + export — filtry, CSV, diff sloupec v AkceHistorieShow.x
  7. 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.

Minimální forenzní standard (MVP): U každé změny dat u akce jeden řádek s 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.

Princip: nejdřív zastavit šum a duplicity → pak sjednotit zápis → pak rozšířit schéma → pak migrovat handlery po modulech → nakonec UI a export.
Testovací akce:
  • 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é AkceDelKopie hard delete.

FÁZE 0 — Příprava (1 den)

Krok 0.1 — Testovací akce a baseline

ParametrHodnota
Testovací akce (hlavní)KodAkce = 3753
Testovací akce (opakování)KodAkce = 6512 — kopie 6568–6595, viz § test 6512
URL historiehistorie.x?aa=3753
Baseline před začátkem úprav2 467 záznamů v historyworkers
baseline_max_id1 660 945 (MAX(id) pro KodAkce = 3753)
Datum baseline21. 6. 2026
nove_od_baseline po ručním testu42 (stav před Fází 1, 22. 6. 2026)
  1. Používat výhradně akci aa=3753 — nevytvářet novou testovací akci.
  2. 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
  3. 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
  4. 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;
  5. Ruční scénáře na aa=3753 — po každém kroku zapsat nove_od_baseline (očekávání uvedeno u kroků Fáze 1):
    • Prohlížení step04.x?aa=3753 bez uložení
    • Vložení / oprava personálu (step04vloz)
    • Oprava ceny v kalkulaci (step06)
    • Neúspěšné smazání akce (špatná zodpovědná osoba)
  6. Screenshot historie.x?aa=3753 př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]

Proč: bez pevné baseline (2467 + max id) neověříte, že úpravy duplicity a šum skutečně odstranily — nové zápisy musí jít oddělit od starých.

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í).

Čtení výsledku (stav před úpravami):
  • Š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).
idKodUDatum/časPopis (zkráceno)URL
16609903722.06.2026 6:12:17Stranka: /step04.x/step04.x
16609893722.06.2026 6:12:16Změna v personálu u akce (souhrn s Kod akce, odkaz na akci)/!step04/step04vloz.x
16609883722.06.2026 6:12:16Opraven personál: Security - Technický vchod, OD/DO 12.05.2026/!step04/step04vloz.x
16609873722.06.2026 6:12:10Stranka: /step04.x/step04.x
16609863722.06.2026 6:12:02Stranka: /step04.x/step04.x
16609853722.06.2026 6:11:58Stranka: /step06.x/step06.x
16609843722.06.2026 6:11:39Oprava personál: Úklid - pracovní den, Kusů:2, Cena:5600, Nakup:4160/!step06/step06vloz.x
16609833722.06.2026 6:11:39Oprava personál: Úklid - pracovní den, Kusů:2, Cena:5600, Nakup:2880/!step06/step06vloz.x
16609823722.06.2026 6:11:39Oprava personál: Úklid - pracovní den, Kusů:2, Cena:4900, Nakup:2520/!step06/step06vloz.x
16609813722.06.2026 6:11:39Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920/!step06/step06vloz.x
16609803722.06.2026 6:11:39Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920/!step06/step06vloz.x
16609793722.06.2026 6:11:39Oprava personál: Správce DOV, Kusů:1, Cena:3000, Nakup:3200/!step06/step06vloz.x
16609783722.06.2026 6:11:39Oprava personál: Správce DOV, Kusů:1, Cena:2700, Nakup:2610/!step06/step06vloz.x
16609773722.06.2026 6:11:39Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920/!step06/step06vloz.x
16609763722.06.2026 6:11:38Oprava personál: Správce DOV, Kusů:1, Cena:1800, Nakup:1920/!step06/step06vloz.x
16609753722.06.2026 6:11:38Oprava personál: Security - Technický vchod, Kusů:1, Cena:3960, Nakup:3060/!step06/step06vloz.x
16609743722.06.2026 6:11:38Oprava personál: Security - Technický vchod, Kusů:1, Cena:1100, Nakup:850/!step06/step06vloz.x
16609733722.06.2026 6:11:38Oprava personál: Security - Technický vchod, Kusů:1, Cena:4400, Nakup:3400/!step06/step06vloz.x
16609723722.06.2026 6:11:38Oprava personál: Security - Technický vchod, Kusů:1, Cena:3080, Nakup:2380/!step06/step06vloz.x
16609713722.06.2026 6:11:38Oprava personál: Security - Technický vchod, Kusů:1, Cena:3080, Nakup:2380/!step06/step06vloz.x

Po Fázi 1 porovnávejte stejným dotazem — nové záznamy budou mít id > 1660990 (nebo aktualizujte baseline_max_id před další várkou testů).

Krok 0.2 — Záloha a větev splněno

Stav 22. 6. 2026: záloha tabulky historyworkers, záloha celé aplikace DOVIS a změny schématu tabulky jsou hotové — lze pokračovat Fází 1 (úpravy ASP).
ÚkolStavPozná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ě):

  • DatumCas DATETIME
  • TypAkce, Vysledek (výchozí 'o'), Modul
  • EntitaTyp, EntitaId, DataPred, DataPo, RequestId
  • Indexy: idx_hw_akce_cas, idx_hw_u_cas, idx_hw_typ

Git větev nebyla povinná — nahrazena zálohou celé aplikace. Před Fází 1 ověřit, že ASP kód nové sloupce zatím neplní (zůstanou NULL u legacy zápisů, dokud se neimplementuje Fáze 3.3 / HW_Log). Backfill DatumCas u starých řádků — Krok 3.2 provedeno.

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

Princip: duplicita se ruší jen v rámci jednoho requestu (explicitní zápis + pasivní 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).
  1. Po úspěšném INSERT v ActiveHistoryWorkers.x: SESSION("HistLogged") = True
  2. V !StrErrorKonec.x: pokud SESSION("HistLogged") = True, přeskočit pasivní zápis na konci requestu
  3. Na začátku requestu v !StrUvodConfig.x: SESSION("HistLogged") = False
  4. 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.

Krok 1.1 splněn: u uložení kalkulace (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:.
SkupinaPočetidZávěr
Navigace (proklik)51660991–1660995 Stopa chování — kam + odkud v Popis i sloupci Odkud
Uložení step06 (1× submit)301660996–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):

idKam (Popis)Odkud (DB sloupec)
1660991Stranka: /akce.xstep04.x?aa=3753
1660992Stranka: /akce.x?action=view&aa=3753historie.x?aa=3753
1660993Stranka: /step01.x?aa=3753akce.x?action=view&aa=3753
1660994Stranka: /step04.x?aa=3753step01.x?aa=3753
1660995Stranka: /step06.x?aa=3753step04.x?aa=3753

Čitelná cesta: historie → detail akce → step01 → personál (step04) → kalkulace (step06) → uložení.

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é)
idTyp (zkráceno)URL
1661025Oprava personál: Úklid - pracovní den, Cena:5600/!step06/step06vloz.x
1661024Oprava personál: Úklid - pracovní den, Cena:5600 (jiný nakup)/!step06/step06vloz.x
1661023Oprava personál: Úklid - pracovní den, Cena:4900/!step06/step06vloz.x
1661000Oprava prostor: 1.NP - Compress Hall/!step06/step06vloz.x
1660996Oprava prostor: GONG - Celý objekt (příprava/úklid)/!step06/step06vloz.x
… celkem 30 řádků (1660996–1661025), každá změněná položka kalkulace zvlášť

Poznámky k dalším krokům: hromadný zápis step06 (30 řádků / 1 uložení) je funkčně správný, ale pro forenzní přehled vhodný až souhrnný řádek + diff (Fáze 4). Krok 1.3 (vypnout Stranka: na stepXX) by zničil navigační řetězec výše — nedoporučeno při současných požadavcích.

Krok 1.2 — Odstranit dvojitý zápis z !StrUvod2 implementováno

Soubor: /!StrUvod2.x

Z hlavičky !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).
  1. hotovo Odstraněn řádek #include ActiveHistoryWorkers.x z !StrUvod2.x
  2. Ověření na aa=3753 (id > 1661025) — viz tabulka níže
HandlerCesta zápisuOč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.

Krok 1.2 + 1.1 splněny u uploadu: bez časného zápisu ze !StrUvod2 a bez pasivní duplicity na konci requestu — jen explicitní záznamy.
idPopis (zkráceno)URLOdkudZdroj
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

Dva řádky jsou očekávané (příloha + notifikace zodpovědné osobě), ne duplicita Kroku 1.2. Sloučení do jednoho forenzního záznamu — později (Fáze 4 / úprava ZO handleru).

Krok 1.3 — Potlačit pasivní šum u kroků akce odloženo

Soubor: /ActiveHistoryWorkers.x

Po ověření Kroku 1.1 (id 1660991–1660995) je navigační zápis na 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.
  1. Rozšířit podmínku jako u kontakty/hledej: pokud PATH = /stepXX.x a PopisXX začíná „Stranka:" → neukládat.
  2. 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

Rozsah: prefix [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:

SouborVě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ětev smazat2 bez shody, konec chybaakce.x bez PopisXX
  • AkceDelKopie.x — chybaakcekopiedel.x bez historie (žádné kopie k smazání); úspěšné mazání loguje AkceDel_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;

Očekávání: 1 řádek při pokusu o smazání; Popis začíná [ZAMÍTNUTO]; žádný duplicitní pasivní Stranka: (Krok 1.1).

Výsledek ověření (aa=3753, 22. 6. 2026)

Dotaz výše → 1 záznam (id = 1661049). Nový referenční baseline_max_id = 1661049.

Krok 1.4 splněn: zamítnutý pokus o smazání je v historii jednoznačně oddělen prefixem [ZAMÍTNUTO].
idPopisURLVě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

Další větve (špatná ZO, akcedelpotvrd.x) lze ověřit stejným dotazem s id > 1661049.

Krok 1.5 — Audit přihlášení a odhlášení implementováno

Soubory: /PrihlaseniDokonceni.x, /logoff.x

Zápis do stávající tabulky historyworkers přes ActiveHistoryWorkers.x (stejné sloupce jako u kroků akce). KodAkce = 0 — záznam není vázaný na akci.
UdálostKdePopisXXKodAkce
Ú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;

Očekávání: 1× přihlášení po loginu, 1× odhlášení před ukončením session; bez duplicitního Stranka: (HistLogged).

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.

Krok 1.5 splněn: přihlášení i odhlášení jdou do historyworkers s KodAkce=0; navigační řádky po loginu (např. vynucená změna hesla) zůstávají jako Stranka: … | odkud: — to je žádoucí.
idKodUPopisURLOdkud
166105638Přihlášení uživatele/overeniuzivatele.xsignin.x
166105337Přihlášení uživatele/overeniuzivatele.xsignin.x
166105237Odhlášení uživatele/logoff.xstep05.x?aa=3753
166105138Odhlášení uživatele/logoff.x/ (úvod)

Navigace po přihlášení (stejný test, KodAkce=0):

idKodUPopis (zkráceno)
166105738Stranka: /users/userheslozmena.x | odkud: signin.x
166105537Stranka: /default.x | odkud: userheslozmena.x
166105437Stranka: /users/userheslozmena.x | odkud: signin.x

Scénář: login → vynucená změna hesla → úvodní stránka; stopa chování je čitelná vedle auth záznamů.

Krok 1.6 — Výchozí filtr v historie.x implementováno

Soubory: !akce/AkceHistorieHistLib.x, !akce/AkceHistorieShow.x

Výchozí pohled forenzní skrývá pasivní Stranka: v SQL i ve souhrnech. Navigační stopa zůstává v DB — zobrazí se přes ?view=all nebo odkaz v UI.
ParametrChování
(bez parametru) nebo ?view=forensicVýchozí — bez řádků Stranka:
?view=allKompletní 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ů, bez Stranka: /step04… v detailu
  • historie.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)

  1. hotovo HW_InitRequest() — SESSION("HW_RequestId") ve tvaru KodU-YYYYMMDDHHMMSS-ms (jen pokud ještě není).
  2. hotovo HW_Log(typAkce, modul, entitaTyp, entitaId, kodAkce, popis, detail, vysledek)
  3. hotovo Legacy INSERT (stejné sloupce jako ActiveHistoryWorkers.x) + PopisXX, KodAkceHistorie, SESSION("HistLogged")=True.
  4. hotovo PopisAkce = detail (+ volitelně entitaTyp=id); Popis s prefixem [UPDATE] / [CREATE] / [DELETE] / [ZAMÍTNUTO] (sloupce TypAkce až 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.xhotovo po DB.OPEN → #include /HistoryWorkersLib.x (jednou na request, bez duplicity při dvojím StrUvodConfig)
/!StrUvodConfig.xhotovo 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:

SouborTypAkceVolání
!step04/step04VlozJeden.xCREATEHW_Log("CREATE", "step04", "personal", Kod, KodAkce, …)
!step04/step04vloz.xCREATE / UPDATEstejný vzor — hlavní formulář personálu (test aa=3753)
!akce/AkcePersonalDel.xDELETEHW_Log("DELETE", …) + NazevPersonal před DELETE
akcedelpotvrd.xkrok1 / DENIEDpožadavek bez prefixu; špatná ZO → [ZAMÍTNUTO]
!akce/AkceDel.xDENIED ×3špatné potvrzení, obchodník bez práv, špatná ZO — prefix [ZAMÍTNUTO], vysledek=denied
!akce/AkceDel.xDELETE ×3skrytí akce, skrytí opakující, kompletní smazání — prefix [DELETE]

Ověření (aa=3753, id > baseline):

  • CREATE přes step04VlozJeden (ne step04vlozMulti — 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í duplicity Stranka: (Krok 1.1)
  • Navigační Stranka: řádky zůstávají (pasivní zápis na konci requestu) — to je očekávané

Poznámka: řádky 1661075–1661084 v testu jsou ještě před migrací (bez prefixů).

Ověření na aa=3753 (id > 1661084, 22. 6. 2026):
idVýsledekPoznámka
1661086OK[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–1661097legacyCREATE přes step04vloz.x bez [CREATE] — opraveno migrací step04vloz.x
1661092, 1661099legacyakcedelpotvrd.x krok1 — opraveno (prefix u krok1 zůstává prázdný jako dříve)
1661093, 1661100OK[ZAMÍTNUTO] Obchodník nemá práva (AkceDel)
1661095–1661098očekávánonavigač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

Migrace schématu byla nasazena při přípravě (22. 6. 2026). Níže původní SQL pro referenci / jiné prostředí.

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;

Spuštěno po stabilizaci zápisu (Fáze 2). Řádky vložené mezi 3.2 a 3.3 (např. id 1661085–1661126) doplnit opakovaným UPDATE výše. Po 3.3 nové INSERTy už DatumCas plní automaticky.

Krok 3.3 — Upravit HW_Log a ActiveHistoryWorkers implementováno

  1. hotovo HW_InsertRecord — DatumCas, TypAkce, Vysledek (o/d/e), Modul, EntitaTyp, EntitaId, RequestId
  2. hotovo ActiveHistoryWorkers.x — legacy: DatumCas=NOW(), TypAkce/Modul NULL, Vysledek='o', RequestId ze session
  3. hotovo Prefix v Popis zůstává (kompatibilita UI); filtry mohou používat TypAkce

Ověření po nasazení (aa=3753, id > 1661130, 22. 6. 2026):

idTypAkceModulEntitaVysl.Poznámka
1661135CREATEstep04personal=4983oHW_Log — prefix + sloupce 3.3
1661132DENIEDAkceDelakce=3753dHW_Log — zamítnutí obchodníka
1661131(prázdné)akcedelpotvrdakce=3753okrok1 mazání — bez prefixu (záměrně)
1661133–1661137NULL—0opasivní Stranka: / notifikace ZO — legacy, DatumCas + RequestId OK

Všechny řádky mají DatumCas. RequestId je shodné v rámci jednoho requestu (např. 37-20260622070408-… u CREATE + nav).

-- 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

  1. hotovo !step06/step06HistLib.x — Step06_PredSnap, Step06_PoCena, Step06_PoMisto, Step06_PoCatering, Step06_PoSleva, Step06_PoAuto, Step06_Log
  2. hotovo step06Vloz.x — všech 22 míst: PopisXX + ActiveHistoryWorkers.x → Step06_Log / HW_LogDiff
  3. hotovo U UPDATE: DataPred před DB.Execute, DataPo po změně (ceny, slevy, km…)
  4. hotovo Entity: misto, sluzba, inventar, personal, catering, spotreba, auto, akce

Ověření (aa=3753, uložení kalkulace 22. 6. 2026, id > 1661137):

idTypAkceModulEntitaDiffPoznámka
1661150UPDATEstep06inventar=5127stejnéuložení beze změny ceny
1661151–1661161UPDATEstep06personal=…stejné11× personál, 1 request 07:44:46

baseline_max_id pro další testy: 1661161. Při skutečné změně ceny očekávat DataPred ≠ DataPo u dané entity.

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 kde DataPred ≠ DataPo (forenzní pohled bez „prázdných“ uložení).
  • Volitelně později: IF dataPred = dataPo THEN EXIT SUB v Step06_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

  1. hotovo Detail kroků: sloupce Typ (TypAkce), Modul (sloupec DB + fallback URL), Entita (EntitaTyp=Id).
  2. hotovo Diff porovnává hodnoty po polích (ne pořadí klíčů v řetězci) — falešné „Změna“ u prostor opraveno.
  3. hotovo Layout 5 sloupců — popis v posledním sloupci (bez zalomení pod datum).
  4. hotovo Odkaz Jen skutečné změny (diff) — parametr fdiff=1.
  5. hotovo Fáze 6.1 — kompaktní formulář filtrů + rychlé vyhledávání fq (viz krok 6.1).
  6. 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

  1. hotovo !step01/step01HistLib.x — Step01_PredSnap, Step01_PoAkce, Step01_PoTerminy, Step01_PoFakturace, Step01_PoMistoBalicek, Step01_Log, Step01_LogTerminZmena
  2. 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)
  3. hotovo Fakturace: step01VlozFakturace.x, step01VlozFakturace2.x, step01VlozFakturace3.x — UPDATE fakturace* s diff před/po
  4. hotovo Balíčky: step01VlozBalickyMista.x — Prostory u akce (UPDATE), Vložen prostor (CREATE misto)
  5. hotovo Kolize: step01TestMista.x — varování obsazeného místa (bez diff)

Ověření (aa=3753, uložení akce 22. 6. 2026, id > 1661161):

idTypAkceModulEntitaDiffPoznámka
1661168, 1661172UPDATEstep01akce=3753falešný (cas)uložení beze změny před Step01_NormCas
1661179UPDATEstep01akce=3753stejné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).

baseline_max_id pro další testy: 1661179. Uložení beze změny → DataPred = DataPo; řádek v fdiff=1 se nezobrazí.

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

  1. hotovo !step04/step04HistLib.x — Step04_PredSnap, Step04_PersonalFields, Step04_NormCas, Step04_Log
  2. hotovo step04vloz.x — UPDATE/CREATE s diff (EntitaId = Kod řádku dovakcepersonal)
  3. hotovo step04VlozJeden.x — CREATE (voláno z step04vlozMulti.x)
  4. hotovo step04VlozVice.x — CREATE při rozepsání více kusů
  5. hotovo AkcePersonalDel.x — DELETE s DataPred př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):

idTypAkceEntitaDiffPoznámka
1661183–1661190DELETEpersonal=4947…4983Pred OK8× smazání, DataPred snapshot, DataPo prázdné
1661193, 1661195DELETEpersonal=4686, 4948Pred OKdalší mazání
1661197, 1661199CREATEpersonal=4981, 4982Po OKvložení přes step04, DataPred prázdné, DataPo z DB
1661203UPDATEpersonal=4982stejnéuložení beze změny — DataPred = DataPo

baseline_max_id pro další testy: 1661203.

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

  1. hotovo !step02/step02HistLib.x — Step02_PredSnap, Step02_MistoFields, Step02_NormCas, Step02_Log
  2. hotovo step02vloz.x — CREATE (2 cesty + legacy duplicitní zápis), DELETE
  3. hotovo step021vloz.x — CREATE/DELETE, Modul=step021; DELETE i přes ajaxDel=1
  4. hotovo AkceMistnostiDel.x — DELETE s DataPred, 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):

idTypModulEntitaPoznámka
1661222, 1661269CREATEstep02misto=19469…DataPo z DB
1661225, 1661250DELETEstep02misto=19469DataPred OK (AkceMistnostiDel / idd)
1661260DELETEstep021misto=19257AJAX mazání ze step021 UI
1661263DELETEstep02misto=19469prázdný Pred — opraveno idd lookup

baseline_max_id: 1661269. step02 může logovat 2× CREATE na jeden INSERT (legacy).

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

  1. hotovo !technika/TechnikaHistLib.x — Technika_PredSnap, Technika_AkceRowFields, Technika_NabidkaFields, Technika_Log
  2. hotovo step08NabidkaVloz.x — CREATE/UPDATE nabídka (EntitaTyp=nabidka)
  3. hotovo step08NabidkaDel.x — DELETE nabídka (1× souhrn místo 4× legacy)
  4. hotovo NabidkuAktivuj.x — UPDATE nabídka/akce (aktivace/deaktivace)
  5. hotovo step09Vloz.x — CREATE/UPDATE/DELETE technika, DELETE balíček
  6. hotovo step10Vloz.x, step10VlozNovouTechniku.x — CREATE/UPDATE/DELETE, hromadné DELETE
  7. hotovo step10NabidkaKopiruj.x — Technika_LogKopieNabidka (odkud→kam, Modul=step08 při kam=08), step10NabidkaVyber.x
  8. hotovo step10ZmenaAkce.x, step10ZmenaTerminu.x, step10ZmenaMista2.x — step14 nastavení akce/termínu/místa (Modul=step14)
  9. hotovo step14VlozPoDnech.x — UPDATE rozpis po dnech po jednotlivých dnech (KusuDen,CenaDen,SlevaDen,datum)
  10. hotovo step10Vloz.x při kam=14 loguje jako step14 (jen historie)
  11. hotovo step10VlozPoDnechHromadne.x — hromadné slevy po dnech (step14 při kam=14)
  12. hotovo UI historie — zvýraznění názvu techniky/nabídky v popisu (uact-hist-ent-nazev), název nabídky z DB pro EntitaTyp=nabidka
  13. 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).

baseline_max_id po testu akce 3753 (22.06.2026): 1661607 (předchozí 1661269).

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.

P3 Šum: časté Vybrána nabídka (step10) při každém přepnutí session — zvážit sloučení nebo nižší prioritu ve filtru UI.

P3 Termín bez skutečné změny (DataPred=DataPo) se stále loguje — volitelně přeskočit v step10ZmenaTerminu.x.

Kopie nabídky: detail z nabidka=… do nabidka=… je ve sloupci PopisAkce (ne v DataPred/DataPo).

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

  1. hotovo !step03/step03HistLib.x — Step03_PredSnap, Step03_InventarFields, Step03_Log (Modul=step03, EntitaTyp=inventar)
  2. hotovo !step07/step07HistLib.x — Step07_PredSnap, Step07_SluzbaFields, Step07_Log (Modul=step07, EntitaTyp=sluzba)
  3. hotovo step03Vloz.x, step03VlozJeden.x — CREATE/UPDATE mobiliáře
  4. hotovo AkceInventarDel.x — DELETE mobiliáře
  5. hotovo step07vloz.x, step07VlozJeden.x — CREATE/UPDATE služby
  6. hotovo AkceSluzbyDel.x — DELETE služby
  7. hotovo UI historie — AkceHistNazevEntita pro inventar/sluzba, kategorie Mobiliář/Služby (oprava mapování URL)
  8. hotovo step03vlozMulti.x, step04vlozMulti.x, step07vlozMulti.x — souhrnný log ids= + 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).

baseline_max_id po testu akce 3753 (22.06.2026): 1661660 (předchozí 1661607).

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í.

SouborKde v kóduTypAkceCo 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
  1. hotovo !akce/AkceDelHistLib.x — AkceDel_PredSnap, AkceDel_AkceFields, AkceDel_DetAkce, AkceDel_Log
  2. hotovo akcedelpotvrd.x + !akce/AkceDel.x — pilot Krok 1.4/2.3; DELETE větve doplněny o DataPred/DataPo (Fáze 4.7)
  3. hotovo !akce/AkceDelKopie.x — nahrazen ActiveHistoryWorkers, log i u hard delete kopií
  4. hotovo UI — AkceHistModulPopis pro AkceDel/AkceDelKopie, název akce z nazevakce ve snapshotech
  5. 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,….

baseline_max_id pro test: 1661660 (konec fáze 4.6).

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.

idTypAkceModulVysledekPoznámka
1661696, 1661689DENIEDAkceDeldOK — aa=3753, [ZAMÍTNUTO] Obchodník nemá práva
1661688(prázdné)akcedelpotvrdoOK — aa=3753, krok1 bez [DELETE]
1662397DELETEAkceDelKopieoOK — aa=6512, Kompletní smazání kopií, pocet=28

baseline_max_id po testu 3753: 1661696.

-- 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.

SouborKde v kóduTypAkceEntitaTyp / 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álostKde v kóduTypAkcePopis / 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).

  1. hotovo /FilesHistLib.x — snapshot, Files_Log*, DigiSign helper
  2. hotovo Log až po INSERT do DB (ne před kopírováním — oprava duplicitního/ prázdného EntitaId)
  3. hotovo UI historie — kategorie Přílohy/Dokumenty/DigiSign, název z nazev / audit_filename ve snapshotech
  4. hotovo DigiSignHistLib.x — stavy obálky, API sync (auto/manual/ajax), webhook, API chyby, příjemci, auditní PDF
  5. hotovo Sync handlery: step75PodpisSync.x, step75PodpisSyncAjax.x, DS_PodpisAutoSyncAkceZApi (F5)
  6. hotovo ZO notifikace příloh — volitelná entita hwZoEntitaTyp/Id v KontrolaZodpovedneOsobyZaAkci.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

baseline_max_id pro test: 1661696 (konec fáze 4.7). Ověřeno aa=3753: příjemci id 1661797+, auditní stopa id 1661819.

-- 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.

SouborKde v kóduTypAkceEntitaTyp / 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álostFunkcePopis (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).

  1. hotovo SmlouvyHistLib.x — Smlouvy_PredSnap, Smlouvy_Log*
  2. hotovo Migrace z PopisXX + ActiveHistoryWorkers na HW_LogDiff
  3. hotovo UI historie — kategorie Smlouvy, badge PAGE_VIEW pro náhled/tisk
  4. 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)

Ověřeno aa=3753: PAGE_VIEW náhled smlouvy id 1661766 (EntitaTyp=smlouva, EntitaId=3).

-- 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).

KnihovnaHandlerTypAkceEntitaTyp / 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álostFunkcePopis (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).

  1. hotovo step20HistLib.x, step94HistLib.x, step80HistLib.x
  2. hotovo Migrace z ActiveHistoryWorkers na HW_LogDiff ve všech uvedených handlerech
  3. hotovo AkceHistorieHistLib.x — moduly step20/step80, kategorie detail/spotreba/pomůcky
  4. hotovo + ověřeno step20 (step20newVloz id 1661861), step95 energie (CREATE id 1661850, 1661852; UPDATE diff id 1661857)
  5. hotovo + ověřeno Premier import (step94mereni id souhrn 1662331, řádky 1662311–1662330)
  6. 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).

Rozdíl ruční vs. import: ruční step95 u akce 3753 → id 1662254 (KodAkce=3753, popis Vlozeni energii:). Import → KodAkce=0, popis Import energie (UPDATE): / souhrn Import mereni Premier:.
idTypEntitaTypEntitaIdPopis (zkráceno)
1662331CREATEimport0Import mereni Premier: Únor 2026 — radku=37, aktualizovano=37
1662330UPDATEspotreba573Import energie (UPDATE): … Landek elektřina
1662311UPDATEspotreba481Import energie (UPDATE): ENC Vnější rozvaděč …
1662254CREATEspotreba577Vlozeni 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.

step95 energie: CREATE ukládá plný snapshot do DataPo (idrozvadece, spotřeby, sazby). UPDATE id 1661857 — diff sazby SazbaJednotkova/SazbaNakup 159→199 u EntitaId=567 (U6 - Voda).
idTypAkceModulEntitaTypEntitaIdPopis (zkráceno)Poznámka
1661861UPDATEstep20akce3753 Aktualizace vlastnich detailu akce: konference PULSE 2026 Step20_LogVlastniPrepis — prázdné DataPred/DataPo (souhrn)
1661857UPDATEstep95spotreba567 Oprava energii: 42008383013 - U6 - Voda DataPo — sazba 199, spotřeba 37 m³
1661852CREATEstep95spotreba567 Vlozeni energii: 42008383013 - U6 - Voda nový řádek spotřeby
1661850CREATEstep95spotreba566 Vlozeni energii: 859182413450000167 - Areál - DICR - Elektrická energie 40 kWh, sazba 9,5

Ještě neověřeno na aa=3753: hlavní blok dovakcedetail (EntitaTyp=detail), jednotlivé položky detail_polozka, modul step94, školní pomůcky step80.

-- 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íModulSoubory k úpravěCo logovatOdhad
4.1Kalkulacestep06Vloz.x (22 míst)UPDATE cen — s diff DataPred/DataPohotovo
4.2Základ akcestep01Vloz.x, fakturace, balíčkyCREATE/UPDATE akce, termínyhotovo
4.3Personálstep04vloz*, AkcePersonalDel, step04vlozMultiCREATE/UPDATE/DELETE + EntitaIdhotovo
4.4Prostorystep02vloz, step021vloz, AkceMistnostiDelCREATE/DELETE mistohotovo
4.5Technikastep08–10*, NabidkuAktivuj, step08NabidkaDelCREATE/UPDATE/DELETE technikahotovo
4.6Služby / inventářstep03*, step07*, Akce*DelCREATE/UPDATE/DELETEhotovo
4.7Lifecycle akceAkceDel, akcedelpotvrd, AkceDelKopieDELETE, DENIEDhotovo
4.8Soubory + DigiSignFiles*, Akce*Del, step75Podpis*, DigiSignHistLib, webhook/syncCREATE/DELETE soubory; DigiSign odeslání, stavy, příjemci, audit PDFhotovo
4.9SmlouvySmlouvyHistLib, SmlouvuVloz, SmlouvyDel, smlouva01CREATE/UPDATE/DELETE + PAGE_VIEW; diff obsah_lenhotovo
4.10Detail, energiestep20HistLib, step94HistLib, step80HistLib; step20vloz, step94/95vloz, step80VlozCREATE/UPDATE s diff DataPred/DataPohotovo + ověřeno step20/95 (1661861, 1661850–57); step80 čeká test

Krok 4.x — Vzor migrace jednoho handleru

Pro každý *vloz.x / *Del.x:

  1. Najít místo po úspěšném DB.Execute (sqluloz=1).
  2. Před UPDATE načíst starý stav do proměnných (SELECT … WHERE Kod=).
  3. 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)
  1. Smazat duplicitní include ActiveHistoryWorkers na stejném místě.
  2. 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)

KrokSouborHW_Log voláníStav
5.1step01OpakujRun.x, step01HistLib.xCREATE kopie akce — zdroj_aa v detail; souhrn po dávcehotovo + ověřeno
5.2step75PodpisOdeslat.x, DigiSignHistLib.xOdeslání, stavy obálky/příjemců, webhook, auditní stopa PDFhotovo · viz 4.8
5.3!step15/step15HistLib.x, step15Vloz/Del, !DOC/nakladovy01.xCREATE/DELETE/PAGE_VIEW tisk — ids=…hotovo + ověřeno
5.4!step50/step50HistLib.x, step50vloz.x, !akce/AkceAutaDel.xCREATE/UPDATE/DELETE auto (+ TimeLine zachován)hotovo + ověřeno
5.5step03/04/07 vlozMulti.x, *VlozJeden.xJednotlivé CREATE + souhrnný řádek ids=…hotovo
5.6!step43/step43NabidkaDel.xDELETE catering nabídka — diff NabidkaNazev, soubor, skladhotovo
5.7!step14/step14VlozPoDnech.xUPDATE rozpis po dnech — diff kusu/cena/sleva per denhotovo
5.8!akce/AkceDokumentyDel.x, FilesHistLib.xDELETE dokument — snapshot názvu souboru před smazánímhotovo
5.9!akce/AkceKopieHistLib.x, akcekopie_vloz.x, OpakujAkceLib.xCREATE / KOLIZE / DENIED kopie + kolize prostor/sklad; oprava detekcehotovo + 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)KodAkcePopis (zkráceně)PopisAkce (klíč)
1662340–16623946512Opakování — vytvořena kopie aa=…zdroj_aa=6512 | aa=6568…6595 | termin=…
16623956512Dokončeno opakování akcevytvoreno=28 | nove_aa=6568,…,6595
1662339–16623936568–6595Kopie 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, entita digisign / 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), detail ids=…
  • DELETE — mazání (step15Del.x), diff před smazáním
  • PAGE_VIEW — tisk (!DOC/nakladovy01.x?aa=&nb=), detail nakladovy01.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

Ověřeno aa=6482: CREATE/DELETE/PAGE_VIEW tisk N1036 (id např. 1662592 PAGE_VIEW, DELETE 18 položek).

Krok 5.4 — Auta u akce (step50) hotovo + ověřeno

step50HistLib.x — entita auto, modul step50:

  • CREATE — vložení (step50vloz.x INSERT), detail id=…, diff po uložení
  • UPDATE — úprava rezervace (step50vloz.x UPDATE), detail id=…, diff před/po
  • DELETE — smazání (!akce/AkceAutaDel.x), detail id=…, diff před smazáním; TimeLine del=1 beze 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

Ověřeno aa=6482: CREATE id 1662620, UPDATE 1662624, DELETE 1662627 (EntitaTyp=auto, EntitaId=8, vw caddy 7AV 3052).

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ář:

ModulHandlerKnihovnaEntita
step03step03vlozMulti.x → step03VlozJeden.xstep03HistLib.xinventar (mobiliář)
step04step04vlozMulti.x → step04VlozJeden.xstep04HistLib.xpersonal
step07step07vlozMulti.x → step07VlozJeden.xstep07HistLib.xsluzba
  • Každý nový řádek — samostatný CREATE s diffem (*VlozJeden.x)
  • Po dávce — souhrnný CREATE: Hromadné vložení … (N), detail ids=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_LogDenZmena jen při skutečné změně (porovnání hwPred vs hwPo)
  • Entita technika, modul step14, EntitaId = řádek v dovakcetechnika
  • Popis: {název techniky} — Rozpis po dnech dne DD.MM.RRRR: kusu=… cena=… sleva=…
  • Detail: datum=…, diff polí řádku dovakcetechnikadatum
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=1 pro dokumenty={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).

SituaceTypAkcePopis / detail
Úspěšná kopie bez kolizíCREATENa novém i zdrojovém aa; zdroj_aa=… | aa=… | termin=…
Kopie přes kolizi prostor (ProstoryOK + tlačítko „Vložit“)CREATE + KOLIZEpres_kolizi_prostor=1 + samostatný řádek TypAkce=KOLIZE
Kolize služeb / mobiliáře / personáluDENIED + KOLIZEDetail kolizí všech kategorií
Kolize prostor bez oprávnění / bez tlačítka přes koliziDENIEDText chyby + detail kolizí prostor
Neplatný termín / validace dataDENIEDText validace, bez kolizí
Selhání AkceKopiruj2DENIEDVysledek=error, text chyby SQL
Opakování — termín přeskočen (kolize prostor)DENIEDModul 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:

idModulTypAkcePopis (zkráceně)PopisAkce (klíč)
1662476AkceKopieCREATEKopie akce — vytvořena kopie aa=6572pres_kolizi_prostor=1 | kolize: … akce 6568 …
1662477AkceKopieKOLIZEKolize 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)
PoleParametr URLPopis
ObdobíObdobi + rokMěsíc (101–112) a rok; změna rovnou odešle formulář (onchange)
UživatelKodUSeznam osob z historie akce
OblastfkatPersonál, Služby, Technika… (AkceHistKategorieExpr)
ModulfmodOdvozený popis stránky (AkceHistUrlPopisExpr) — dropdown ve formuláři
TypftypCREATE / UPDATE / DELETE / PAGE_VIEW / DENIED
Stavfvyslok / d (zamítnuto)
Legacyflegacy=1Skrýt záznamy bez TypAkce (checkbox ve formuláři)
Rychlé hledánífqTextové pole — viz níže; tlačítko Vyhledat (fqGo=1)
Zobrazenízobrazitoba / 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, personalOblast → Personál (fkat)
kveten, leden…Obdobi + rok (aktuální rok, pokud není uveden)
2026rok
20.5.2026, 20.5, 20/5dd — jeden den (rok z tokenu nebo aktuální)
nikol, georg…KodU — shoda jména z historie akce
uprava, vlozeni, smazaniftyp
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é dd v 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á parser fq.
  • Oprava VBScript: u data 15.10 se nepřistupuje k parts(2) bez kontroly UBound (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

  1. hotovo Dropdown Modul (fmod) ve formuláři — stejná logika jako odkazy ze souhrnu „Nejnavštěvovanější oblasti" (AkceHistUrlPopisExpr).
  2. hotovo Checkbox Skrýt legacy (flegacy=1) — filtr TypAkce IS NOT NULL; ve forenzním pohledu výchozí zaškrtnuto.
  3. 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

  1. hotovo Sloupce: DatumCas, TypAkce, Modul, EntitaTyp, EntitaId, Vysledek (krok 4.1c).
  2. hotovo Rozbalitelný diff DataPred → DataPo.
  3. hotovo Barva řádku (AkceHistRowCssClass): ok=zelená, denied=červená, error=oranžová — třídy uact-hist-row--ok/denied/error v UserActivityHist.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ů.

  1. hotovo Tlačítko Export CSV u „Kroků celkem" — předá aktuální filtry z URL.
  2. hotovo Sloupce: id;DatumCas;KodU;Jmeno;KodAkce;TypAkce;Modul;ModulPopis;Oblast;EntitaTyp;EntitaId;Vysledek;Popis;PopisAkce;DataPred;DataPo;Url
  3. hotovo Vysledek jako text ok|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).

  1. hotovo Nové entity: smlouva, nakladovy_list.
  2. hotovo Modul mapuje step01–step99, AkceDel, AkceKopie, akce (ZO).
  3. hotovo Rychlé hledání fq doplně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).

Hard delete kopií akce (AkceDelKopie) a archivace vyžadují DELETE — buď výjimka pro údržbový účet, nebo noční job mimo aplikační pool.

Krok 7.2 — Archivace do historyworkers_archive

Soubory: !!MySQL/historyworkers_integrita (DDL), /HistoryWorkersArchive.x, /HistoryWorkersIntegritaLib.x (HW_ArchiveRunBatch).

  1. Výchozí stáří: 7 let (Application("HW_ArchiveYears") nebo parametr ?years=7).
  2. Dry run: /HistoryWorkersArchive.x?years=7 — jen počet k přesunu.
  3. Spuštění: …&run=1 (admin zz nebo t), 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).

TestOč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=6512ověřeno id 1662397, AkceDelKopie, pocet=28
historie.x?aa=3753 forensic viewFiltry KodU/fkat/ftyp/období/fq (Fáze 6.1)
Export CSVhotovo krok 6.3 — AkceHistorieExport.x

3.2 Časový odhad celkem

FázeObsahOdhadKumulativně
0Příprava1 den1 den
1Hotfix bez DB1–2 dny~3 dny
2Knihovna HW_Log + pilot2–3 dny~1 týden
3ALTER TABLE1 den~1,5 týdne
4Migrace handlerů2–3 týdny~1 měsíc
5Kritické mezery1 týden~5 týdnů
6UI + export1 týden~6 týdnů
7Integritaprůběžně—
Implementace dokončena. Fáze 0–7 jsou v kódu nasazeny. Pro produkční provoz ISKASA zbývá spustit SQL skript oprávnění na DB a naplánovat archivaci (HistoryWorkersArchive.x).

3.3 Prompty pro implementaci v Cursoru

Jak to funguje: Vložení textu z návodu samo o sobě nic nezmění — musíte explicitně napsat „Implementuj tento krok" nebo použít prompt níže. Jeden krok = jeden chat / jedna úprava. Celou Fázi 1 lze zadat najednou: „Implementuj Fázi 1 (kroky 1.1–1.6) podle AuditHistoryWorkers.asp".

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

Implementuj Krok 1.1 z AuditHistoryWorkers.asp (Fáze 1): - Po úspěšném INSERT v ActiveHistoryWorkers.x nastav SESSION("HistLogged") = True - V !StrErrorKonec.x přeskoč pasivní zápis, pokud SESSION("HistLogged") = True - Na začátku requestu v !StrUvodConfig.x vynuluj SESSION("HistLogged") = False Minimální diff, bez dalších změn. Ověř logiku u step04vloz + StrKonec.

Krok 1.2 — !StrUvod2 hotovo

Krok 1.2 implementován: ActiveHistoryWorkers odstraněn z !StrUvod2.x. Ověř upload přílohy (FilesAkceUpload) — 1 explicitní řádek, bez Stranka: duplicity.

Krok 1.3 — šum step*.x

Implementuj Krok 1.3: v ActiveHistoryWorkers.x neukládej triviální záznam Stranka: /stepXX.x (analogicky jako u kontakty.x a hledej.x). Jen pasivní prohlížení kroků akce.

Krok 1.4 — [ZAMÍTNUTO] hotovo

Krok 1.4 implementován v AkceDel.x a akcedelpotvrd.x (4 větve). KontrolaZodpovedneOsobyZaAkci.x — úspěšné změny, bez [ZAMÍTNUTO]. Ověř pokus o smazání bez ZO.

Krok 1.5 — login/logout hotovo

Krok 1.5 implementován: PrihlaseniDokonceni.x + logoff.x → historyworkers, PopisXX Přihlášení/Odhlášení uživatele, KodAkce=0.

Krok 1.6 — filtr historie hotovo

Krok 1.6 implementován: view=forensic výchozí, view=all pro Stranka:, AkceHistorieShow.x — přepínací odkazy.

Celá Fáze 1 najednou

Implementuj celou Fázi 1 (kroky 1.1 až 1.6) podle kapitoly 3 v AuditHistoryWorkers.asp. Minimální diff, zachovej stávající konvence ASP. Po implementaci stručně popiš co testovat.

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.

Fáze 4.9 hotovo + ověřeno — SmlouvyHistLib.x, SmlouvuVloz, SmlouvyDel, náhled/tisk !DOC/smlouva01.x (PAGE_VIEW, EntitaTyp=smlouva, id 1661766). Viz krok 4.9.
Fáze 4.10 hotovo + ověřeno (step20, step95) — 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 5 kompletní (6. 2026): všechny kroky 5.1–5.9 implementovány. Ověřeno v DB: 5.1 + 5.9 aa=6512 (opakování, kopie/kolize 6572), 5.3 + 5.4 aa=6482. Detail každého kroku: § Fáze 5.
hotovo DigiSign (5.2): přesměrování na 5.2 a plný popis 4.8 DigiSign.

Fáze 6 — UI historie.x

Fáze 6 hotovo (6.1–6.4) Filtry, badge, barevné řádky, export CSV, kategorie z Modul/EntitaTyp — kroky 6.1–6.4.

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")
Hlavní riziko kolize vyřešeno (Fáze 1.1 + 1.2): Handler s CESTOU B a koncem !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):

SloupecZdrojÚčel
najemceSESSION("najemce")Multi-tenant (volitelně)
KodU, JmenoSESSION("KodU"), SESSION("Osoba")Kdo provedl krok
Den…SekundaNOW()Čas (rozložený na sloupce)
Tyden, DenNazev, MesicNazev, Ctvrtletivýpočet z NOW()Agregace / reporty
URLPATH_INFO (lowercase)Který skript běžel
URLpQUERY_STRINGGET parametry
OdkudHTTP_REFERERPředchozí stránka (nen spolehlivé)
IPAdresaREMOTE_ADDRIP klienta
PopisPopisXX (proměnná stránky)Hlavní text kroku — volný formát HTML
KodAkceKodAkceHistorie → Request("aa") → Request("KodAkce")Vazba na akci
NazevAkceNazevAkceHistorieNázev / zkratka entity
PopisAkcePopisAkceHistorie / HW_Log detailDetailní popis (terminy, diff text…)
KodKontaktuKodKontaktuVazba na kontakt
DatumCasNOW() při INSERTJednotné řazení v čase (Fáze 3)
TypAkceHW_LogCREATE, UPDATE, DELETE, DENIED, AUTH_LOGIN, PAGE_VIEW…
ModulHW_Logstep01, step04, step06, akce…
EntitaTyp, EntitaIdHW_Logpersonal, misto, technika… + ID řádku
VysledekHW_Logok, denied, error
DataPred, DataPoHW_LogDiffDiff key=value před/po UPDATE/DELETE
RequestId!StrUvodConfig.xKorelace 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ínkaChová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.xPřeskočeno
PATH: /historie.x, /users.xPř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 sDebounce 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)

SouborCo se audituje (PopisXX / PopisAkceHistorie)
!step01/step01Vloz.xNová akce, oprava akce, změna termínů (služby, inventář, personál, technika, prostory), stav techniky (1/2/3)
!step01/step01VlozFakturace.xFakturační údaje akce
!step01/step01VlozFakturace2.xFakturační údaje akce (varianta 2)
!step01/step01VlozFakturace3.xFakturační údaje akce (varianta 3)
!step01/step01VlozBalickyMista.xBalíčky míst u akce
!step01/step01TestMista.xKolize obsazeného místa (varování)
!step00/step00Vloz.xÚvodní krok / metadata akce
!!SHOP/!step01/step01Vloz.xShop varianta vložení akce
!akce/AkceInfo.xVložení nové akce (PopisXX — zápis přes StrErrorKonec, ne inline)

5.2 Prostory (step02, step021, step07)

SouborCo se audituje
!step02/step02vloz.xVložení / smazání prostoru, cena, nákup
!step02/step02datum.xZměna data prostoru
!step02/step02vlozPriprava.xPříprava místa
!step021/step021vloz.xVložení / smazání prostoru (nový UI)
!step07/step07vloz.xVložení / oprava služby (prostorový modul)
!step07/step07VlozJeden.xVložení jedné služby
!akce/AkceMistnostiDel.xSmazání prostoru v akci

5.3 Mobiliář / inventář (step03)

SouborCo se audituje
!step03/step03Vloz.xVložení / oprava mobiliáře
!step03/step03VlozJeden.xVložení jedné položky mobiliáře
!akce/AkceInventarDel.xSmazání mobiliáře z akce

5.4 Personál (step04)

SouborCo se audituje
!step04/step04vloz.xVložení / oprava personálu, termíny OD/DO
!step04/step04VlozJeden.xVložení jednoho člena personálu
!step04/step04aVloz.xHromadné vložení personálu (varianta A)
!step04/step04bVloz.xVarianta B personálu
!step04/step04VlozVice.xVíce personálu najednou
!akce/AkcePersonalDel.xSmazání personálu z akce

5.5 Kalkulace / objednávka (step06) — nejvíce zápisů

SouborCo 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)

SouborCo se audituje
!step08/step08NabidkaVloz.xVložení nabídky techniky
!step08/step08NabidkaForm.xFormulář nabídky
!step08/step08NabidkaDel.xSmazání nabídky / techniky
!step09/step09Vloz.xTechnika — vložení / oprava
!step10/step10Vloz.xMažu techniku, oprava kusů, ceny prodej/dodavatel
!step10/step10VlozNovouTechniku.xNová technika (kusu, dny, ceny)
!step10/step10NabidkaKopiruj.xKopie nabídky techniky
!step10/step10NabidkaVyber.xVýběr nabídky
!technika/NabidkuAktivuj.xAktivace nabídky

5.7 Detail, energie, školní pomůcky

SouborCo se auditujeStav
!step20/step20HistLib.xCentrální HW_LogDiff pro detail akce a vlastní položky4.10
!step20/step20vloz.xCREATE/UPDATE dovakcedetail + vlastní položky4.10
!step20/step20newVloz.xHromadný přepis vlastních detailů (EntitaTyp=akce)4.10
!step94/step94HistLib.xCentrální log pro dovakcespotreba4.10
!step94/step94vloz.xEnergie u akce — CREATE/UPDATE (KodAkce=aa)4.10
!step95/step95vloz.xEnergie u akce — CREATE/UPDATE4.10
!step94/step94mereni.xPremier import → dovakcespotreba (KodAkce=0)4.10 + ověřeno
!step95/step95vloz.xEnergie (modul step95) — CREATE/UPDATE4.10
!step80/step80HistLib.xŠkolní pomůcky v dovakceinventar4.10
!step80/step80Vloz.xCREATE/UPDATE školní pomůcky4.10 — k testu
!akce/AkceSluzbyDel.xSmazání služby z akcebez HW_Log

5.8 Mazání a lifecycle akce

SouborCo se audituje
akcedelpotvrd.xPožadavek smazání krok1, chyba zodpovědné osoby
!akce/AkceDel.xSmazání krok1, chyba práv, neoprávněné smazání, skrytí, kompletní smazání
!akce/AkceDelKopie.xSkrytí kopií akce
!akce/AkceDelZavrit.xUzavření / smazání workflow
zodpovedna/KontrolaZodpovedneOsobyZaAkci.xKontrola zodpovědné osoby (PopisXX = ZakladniTextZO)

5.9 Smlouvy a dokumenty

SouborCo se auditujeStav
!smlouvy/SmlouvyHistLib.xCentrální HW_LogDiff pro smlouvy — snapshot obsah_len4.9
!smlouvy/SmlouvuVloz.xCREATE nová / UPDATE editor HTML smlouvy4.9
!smlouvy/SmlouvyDel.xDELETE soft / UPDATE obnovení (smazano)4.9
!DOC/smlouva01.xPAGE_VIEW náhled/tisk; mod=step75 ze step754.9
!step60/step60vloz.xStarší pole OD/DO aut ve smlouvěbez HW_Log
FilesAkceUpload.xVložena příloha k akci4.8
FilesDokumentUpload.xUpload dokumentu4.8
!akce/AkceFilesDel.xSmazán soubor akce4.8
!akce/AkceDokumentyDel.xSmazán dokument akce4.8
nakupy/filedel.xSmazán soubor nákupůlegacy
donio_dokument/DokumentDel.xSmazán dokument Doniolegacy

5.10 Kontakty

SouborCo se audituje
!DOV/KontaktyVloz.xNový / úprava kontaktu (IČO, DIČ, ARES datová schránka) — KodKontaktu
!DOV/KontaktyPoznamkaVloz.xPoznámka kontaktu uložena
!DOV/KontaktyOsobaVloz.xOsoba u kontaktu — vložení / úprava

5.11 Nákupy / Webcollab shop

SouborCo se audituje
webcoll_shopping/ShopVloz.xNákup, koupeno, dokončeno, smazána položka, vrácení, oprava
!!SHOP/!step02/step02vloz.xShop prostory
!!SHOP/!step03/step03vloz.xShop mobiliář

5.12 Infrastruktura (ne business logika)

SouborÚloha
/ActiveHistoryWorkers.xJádro INSERT
/!StrUvod2.xLehká hlavička handlerů (bez auto-zápisu od Kroku 1.2)
/!StrErrorKonec.xAuto-zápis na konci requestu
!hledej/HledejHistoryLib.xDetekce 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.x
  • hledej.x — jen při odeslání formuláře (hledat=1), s debounce 60–120 s
  • Moduly: majetek, nakupy, donio, webcollab, graf, nastenka…
Pro 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

URLIncludeCo 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=3753 přiřadí akci 3753 i bez editace — v historii vypadá jako aktivita na akci.
  • Chyba vs úspěch: sloupec Vysledek a TypAkce=DENIED u 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é

9. Návrh lepšího řešení auditu

V projektu WebSpinani již existuje vzor HistoryWorkersLogAction.x s funkcí WriteHistoryWorkerAction(NazevAkce, PopisAkce) — vhodný základ pro sjednocení.

9.1 Rozdělit typy událostí

TypKdy logovatPříklad
PAGE_VIEWVolitelně, sampling nebo jen „důležité" stránkystep06.x — prohlížení kalkulace
DATA_CREATEVždyNová akce, vložen personál
DATA_UPDATEVždy + diffOprava termínu, změna ceny
DATA_DELETEVždySmazání prostoru
AUTH_LOGINVždyÚspěšné / neúspěšné přihlášení
AUTH_LOGOUTVždyOdhlášení
SEARCHS debounceGlobální hledání
PERMISSION_DENIEDVždyNemá práva smazat, špatná ZO

9.2 Nová knihovna — HistoryWorkersLib.x

' Jednotné API — nahradí globální PopisXX proměnné

Sub HW_Log(typAkce, kodAkce, popis, popisDetail, vysledek)
  ' vysledek: "ok" | "denied" | "error"
  ' Generuje RequestId = SESSION + timestamp + random
  ' INSERT s novými sloupci: TypAkce, Vysledek, RequestId
  ' Volá se JEN jednou za request (Application("HW_Logged_" & RequestId))
End Sub

' Zrušit automatický zápis v !StrErrorKonec pro stránky s HW_Log
' Flag SESSION("HW_SkipPassive") = True po explicitním logu

9.3 Rozšíření schématu (doporučené sloupce)

Nový sloupecTypÚčel
TypAkceVARCHAR(32)Enum — strojově filtrovatelné
VysledekCHAR(1)o/d/e — ok / denied / error
ModulVARCHAR(32)step04, akce, kontakty…
EntitaTypVARCHAR(32)personal, misto, technika…
EntitaIdINTID smazané/upravené položky
DataPredTEXTJSON snapshot před změnou (volitelně)
DataPoTEXTJSON snapshot po změně
RequestIdVARCHAR(40)Deduplikace dvojitých zápisů
DatumCasDATETIMENahradí Den+Mesic+… pro řazení

9.4 Úprava historie.x?aa=

  • Výchozí filtr: jen DATA_* a PERMISSION_DENIED, skrýt PAGE_VIEW
  • Timeline s barevným kódováním: zelená = úspěch, červená = zamítnuto, šedá = prohlížení
  • Sloupec Modul z TypAkce místo LIKE na Popis
  • Propojení chybového kroku s předchozím referer URL + tlačítko „kde klikl"
  • Export CSV pro analýzu sporů

9.5 Okamžitá náprava kolizí (bez migrace DB)

  1. Po každém inline ActiveHistoryWorkers nastavit SESSION("HistLogged") = True
  2. V !StrErrorKonec.x: pokud SESSION("HistLogged"), přeskočit pasivní zápis
  3. V !StrUvod2.x: odstranit include ActiveHistoryWorkers (logovat jen explicitně nebo na konci)
  4. U chybových větví (AkceDel.x, akcedelpotvrd.x): prefix [ZAMÍTNUTO] před RR (implementováno Krok 1.4)
  5. Přihlášení: v PrihlaseniDokonceni.x přidat explicitní zápis „Přihlášení uživatele"

10. Plán implementace (fáze)

FázeÚkolNá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=)

  1. !step06/step06Vloz.x — nejvíce větví a zápisů
  2. !step01/step01Vloz.x — základ akce
  3. !step02/step02vloz.x, !step021/step021vloz.x — prostory
  4. !step04/step04vloz.x — personál
  5. !step10/step10Vloz.x — technika
  6. !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ázeHandlerAudit dnesCo se logujeMezery
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

OperaceHandlerAuditLogovaná poleDoporuč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

KrokHandlerAuditPopis v DB
Požadavek smazání (krok 1)akcedelpotvrd.xAnoPožadavek na smazání krok1 / Nesprávná zodpovědná osoba
Validace práv / ZO!akce/AkceDel.xAnoChyba smazání, neoprávněné smazání, Obchodník nemá práva
Skrytí (soft delete)AkceDel.x, AkceDelKopie.xAnoAkce je zkrytá
Kompletní smazáníAkceDel.xAnoKompletně i s příslušenstvím smazána
Uzavření workflowAkceDelZavrit.xAnoUzavření
U smazání: záznam obsahuje 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)
1step01 / akce.xZáklad akce — dovakce ✓✓✓ (AkceDel) Plný step01Vloz, AkceDel, akcedelpotvrd
2 / 21step02, step021Prostory — dovakcemista ✓✓ (datum, ceny)✓ Plný step02vloz, step021vloz, step02datum, AkceMistnostiDel
3step03Mobiliář — dovakceinventar ✓✓✓ Plný step03Vloz, step03VlozJeden, AkceInventarDel
4step04Personál — dovakcepersonal ✓✓✓ Plný step04vloz, step04VlozJeden, step04a/bVloz, step04VlozVice, AkcePersonalDel
4step04Personál hromadně (Multi) ✓—— Plný step04vlozMulti.x — jednotlivě + souhrn ids= (Fáze 5.5)
5step05Přílohy — dovakceprilohy ✓—✓ Částečný FilesAkceUpload (vložení), AkceFilesDel (mazání); editace metadat přílohy neauditována
6 / 96step06Kalkulace / objednávka — skladkartapohyby ✓✓— Plný step06Vloz.x — 22× ActiveHistoryWorkers, všechny oblasti v kalkulaci
7step07Služby — dovakcesluzby ✓✓✓ Plný step07vloz, step07VlozJeden, AkceSluzbyDel
7step07Služby Multi ✓—— Plný step07vlozMulti.x — Fáze 5.5
9 / 10step08–10, step14Technika — dovakcetechnika ✓✓✓ Plný step08Nabidka*, step09Vloz, step10Vloz*, NabidkuAktivuj, step08NabidkaDel
9 / 10step15Nákladové listy (step15) ✓✓✓ Plný step15HistLib.x, step15Vloz, step15Del — Fáze 5.3 · test aa=6482
9 / 10step14Technika po dnech —✓— Plný step14VlozPoDnech.x — Fáze 5.7
20step20Detail akce — dovakcedetail ✓✓— Plný step20vloz.x
25ColosseumVstupenky Colosseum ✗✗✗ Chybí Integrace v step01 — bez samostatného auditu
30step30?Protokol ✗✗✗ Pasivní Bez vloz handleru s PopisXX
40step40, step51Catering / zboží — dovakcezbozi ✓ v step06✓ v step06? Částečný Kalkulace step06 audituje catering; step40VlozZbozi.x a step51vloz.x bez ActiveHistoryWorkers
50step50Auta — dovakceauta ✓✓✓ Plný step50HistLib.x + TimeLine — Fáze 5.4 · test aa=6482
60step60, smlouvySmlouvy — dovakcesmlouvy ✓✓✓ Plný SmlouvyHistLib — editor CREATE/UPDATE, soft DELETE/obnovení, PAGE_VIEW náhled/tisk
70step70Dokumenty — dovakcedokumenty ✓—✓ Plný FilesDokumentUpload, AkceDokumentyDel.x — Fáze 5.8
75step75DigiSign / podpis — digisign_podpis ✓✓✓ Plný Odeslání, sync/webhook stavy, příjemci, audit PDF (DigiSignHistLib); EntitaId=zdroj_id
95step94, step95Energie — dovakcespotreba ✓✓— Plný Step94HistLib — step94vloz, step95vloz; step06 také loguje energii v kalkulaci
99step99Projekt / úkoly ✗✗✗ Pasivní Webcollab úkoly — bez audit handleru
—akcekopirujKopie 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
—step43Mazá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:

OperacePovinná pole v historyworkersStav (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álostSouborHW_LogPoznámka
Vložení 1 osobystep04VlozJeden.xCREATEEntitaId, DataPo, Modul=step04
Opravastep04vloz.xUPDATE + diffcena, termíny v DataPred/DataPo
SmazáníAkcePersonalDel.xDELETEDataPred snapshot před mazáním
Hromadné vloženístep04vlozMulti.xCREATE + souhrnJednotlivě + řádek s ids= (5.5)
Prohlížení step04step04.xSkrytoVe 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 prostor
  • step06Vloz.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

  1. hotovo Opakování/kopie — Fáze 5.1, 5.9
  2. hotovo step15, step50, Multi, step43 del, step14, mazání dokumentů
  3. Colosseum, step99 úkoly — mimo rozsah migrace
  4. step01RozsireniVloz.x, AkceSluzbyDel.x, starší step60vloz.x
  5. step40VlozZbozi.x, step51vloz.x — catering mimo step06 kalkulaci

14. Audit podle uživatele — identifikace a kolize

14.1 Co dnes identifikuje uživatele

PoleZdrojSpolehlivostPoznámka
KodUSESSION("KodU")VysokáPrimární klíč uživatele v DB
JmenoSESSION("Osoba") = fullnameVysokáZobrazuje se v historie.x sloupec „Osoba"
IPAdresaREMOTE_ADDRStředníProxy/NAT — více uživatelů může sdílet IP
OdkudHTTP_REFERERNízkáČasto prázdné; ne pro forenzní analýzu
URLPATH_INFO handleruStř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 historiiSkuteč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 v fq
  • Filtr typu operace — hotovo ftyp (CREATE/UPDATE/DELETE/DENIED); výchozí skrytí Stranka:
  • Filtr oblasti — hotovo fkat (Personál, Prostory…) + aliasy v fq
  • Filtr období / den — hotovo Obdobi+rok, dd, měsíce/data v fq
  • 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)

#ÚkolSouborDopad
1SESSION("HistLogged") po inline zápisuActiveHistoryWorkers.x, !StrErrorKonec.xhotovo Fáze 1.1
2Vypnout pasivní log pro /step*.xActiveHistoryWorkers.xhotovo Fáze 1.3
3Prefix [ZAMÍTNUTO] u AkceDel, akcedelpotvrd!akce/AkceDel.x, akcedelpotvrd.xhotovo Fáze 1.4
4Doplnit audit kopie akcestep01HistLib, AkceKopieHistLib, OpakujAkceLibhotovo + ověřeno — 5.1, 5.9
5Doplnit audit DigiSignstep75PodpisOdeslat.x + DigiSignHistLibhotovo (4.8)
6step50 → HW_Log + TimeLinestep50HistLib, step50vlozhotovo Fáze 5.4 · aa=6482
7Multi handlery step03/04/07*vlozMulti.xhotovo Fáze 5.5
8V AkceHistorieShow výchozí skrýt „Stranka:"AkceHistorieHistLib.x SQL WHEREhotovo
9Formulář filtrů + rychlé hledání fqAkceHistorieShow.x, AkceHistorieHistLib.xhotovo — 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)EntitaTypTabulkaID pole
step01akcedovakceKod
step02 / step021mistodovakcemistaKod / KodAkceMisto
step03inventardovakceinventarKod
step04personaldovakcepersonalKod
step05prilohadovakceprilohyKod
step06kalkulaceskladkartapohybyKod
step07sluzbadovakcesluzbyKod
step08–10technikadovakcetechnikaKod
step20detail, detail_polozkadovakcedetail, dovakcedetailvlastniKodDetail / kod
step50autodovakceautaKod
step60smlouvadovakcesmlouvyKodSmlouvy
step70dokumentdovakcedokumentyKod
step75digisigndigisign_podpis → zdroj v dovakceprilohy / dovakcedokumentyzdroj_id (EntitaId v HW)
step80inventardovakceinventarKod
step94, step95spotrebadovakcespotrebaKod

15.4 Revize plánu F1 — priorita podle položek akce

  1. 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
  2. Duplicity: sjednotit step02/021 vs step06 pro prostory; step04 vs step06 pro personál
  3. UI historie: hotovo filtry, fq, export CSV, barevné řádky ok/denied/error (Fáze 6)
  4. Postupná migrace: hotovo Fáze 4–5; zbývá provozní nasazení Fáze 7 na DB

16. Návod pro uživatele — co je audit v DOVIS / ISKASA

Audit v DOVIS znamená automatický zápis každé významné operace do tabulky historyworkers. U akce ho prohlížíte v historie.x?aa=číslo_akce. U přihlášení/odhlášení a globálních kroků v menu Historie bez parametru aa.

16.1 Co audit umí dokázat

  • Kdo — jméno a kód uživatele (KodU) v okamžiku operace
  • Kdy — datum a čas s přesností na vteřinu (DatumCas)
  • Co — typ operace (vložení / úprava / smazání / zamítnuto) a oblast akce (personál, prostory, kalkulace…)
  • Která položka — u nových záznamů ID entity (EntitaId) pro propojení s daty v akci
  • Změna hodnot — u úprav sloupce Před / Po (cena, termín, sleva…)
  • Neúspěšné pokusy — např. smazání bez oprávnění (červený řádek, Vysledek=denied)
  • Export — stažení CSV pro archiv nebo předání třetí straně (tlačítko u „Kroků celkem")

16.2 Jak pracovat s historie.x

Co chceteJak na to
Přehled jen skutečných změn (doporučeno)Výchozí pohled Forenzní — skryje prohlížení stránek (Stranka:)
Vše včetně návštěv krokůOdkaz Zobrazit vše (view=all)
Kroky jednoho uživateleFiltr Uživatel (KodU) nebo ve vyhledávání jméno: fq=nikol
Jen mazání nebo zamítnuté pokusyFiltr Typ → DELETE nebo DENIED (ftyp)
Jen personál / prostory / kalkulaceFiltr Kategorie (fkat) nebo Modul (fmod)
Jen řádky se změnou hodnotyOdkaz Jen skutečné změny (diff) (fdiff=1)
Konkrétní den nebo měsícPole Den (dd) nebo ve fq: kveten, 15.10
Kombinace (osoba + období + text)Rychlé vyhledávání fq: např. georg personál 15.10
Skrýt staré řádky bez strukturyCheckbox Skrýt legacy (jen záznamy s TypAkce)
Export do ExceluTlačítko Export CSV — stejné filtry jako na obrazovce (max 50 000 řádků)

16.3 Co audit neumí nebo umí jen částečně

  • Staré akce — záznamy před migrací HW_Log nemají diff ani EntitaId; spoléhejte na text popisu
  • Kde přesně uživatel klikl — URL ukazuje technický handler, ne dialog v prohlížeči
  • Colosseum, step99 úkoly — bez strukturovaného auditu
  • Admin menu (zz) — výchozí bez zápisu (konfigurátor); volitelně zapnutelné administrátorem
  • Stejná položka 2× — změna v kroku personálu i v kalkulaci může vytvořit dva řádky (step04 + step06)
  • Právní důkaz sam o sobě — audit je provozní stopa; interpretaci v sporu posoudí právník / auditor ISKASA

16.4 Kdo audit používá

RoleTypické použití
Provoz / obchod„Co se u akce dělo", kdo naposledy editoval termín nebo cenu
Vedoucí / ZOKdo schválil smazání, kdo měnil kalkulaci, neúspěšné pokusy o smazání
ISKASA / interní auditExport CSV, filtry podle uživatele a období, korelace s přihlášením (KodAkce=0)
IT / správceArchivace starých dat (Fáze 7), monitoring INSERT/min, SQL oprávnění INSERT-only
Testovací akce pro školení: aa=3753 (běžná akce, Fáze 1–4) · aa=6512 (opakování a kopie s kolizí) · aa=6482 (nákladové listy step15, auta step50).
DOVIS / ISKASA · kompletní dokumentace auditu historyworkers · soubor: AuditHistoryWorkers.asp · Fáze 0–7 implementováno · aktualizace: červen 2026 · testy: aa=3753, aa=6512, aa=6482
2018 © 2026 | TOPlist | [51] | ISKASA.cz | ISKASA.eu | DONIO.eu | DOVIO.eu | DENIO.eu | DOVIS.eu | DOVIS.cz | DolníVitkovice.eu | WebCollab.eu | WebCollab.cz | Pichacky.eu | SmenyOnline.eu | PortálSmen.eu | RFID Terminal | Kontakt | Kontakt | Základní návod | Historie | Historie 2026 | FaNET.cz | xFA.cz | FakturaceNET.cz | EaSun.eu
stop war
uživatelský návod|technický návod|akce|založení akce|plánování akcí|základní info|menu kroků|průběh akce|přihlášení|demo|hledej|globální vyhledávání|levé menu|prostory|rezervace prostor|step021|obsazenost|kolize prostor|služby|mobiliář|technika|schvalování techniky|catering|personál|plánování směn|personální evidence|auta|autacal|objednávky|žádanky|objednávka u akce|kalkulace|fakturace|smlouvy|digisign|elektronický podpis|step75|přílohy|bilance|kalendáře|statistiky|kpi|premier|účetnictví|colosseum|vstupenky|denio|kurzy a lektoři|dovio|schvalování dokumentů|webcollab|projekty a úkoly|majetek|inventura|potvrzování položek|technici|nové vkládání|rozšíření služeb|faq|audit akce|historie změn|HW_Log|audit historyworkers|databáze akcí|přehled stránek

Tyto webové stránky používají soubory cookie, abyste zajistili, že získáte to nejlepší na našich webových stránkách. Další informace