{
  "version": "7.5.101",
  "build": "2026-04-27T13:00:00Z",
  "features_v7.5.101": [
    "SECURITY (public): aukcie.html — showContact() onclick mal contact_name/email/phone ako JS string literál; esc() konvertuje ' na &#39; ale HTML parser ho pred JS dekóduje späť → XSS. Opravené cez data-* atribúty + onclick='showContact(this)'."
  ],
  "features_v7.5.100": [
    "SECURITY (public): inzercia.html, inzerat.html — rovnaká XSS zraniteľnosť: showContact(), openMedia(), copyUrl() mali user-provided data v JS string literáloch v onclick. Opravené cez data-cid/name/email/phone/type/url atribúty."
  ],
  "features_v7.5.99": [
    "fix(admin): editácia draft článkov (fetch '/api/articles/id' bez auth → 404 po PR #467), nahrávanie obrázkov článkov/albumov/fotiek/lôg/dokumentov (fetch '/api/upload' bez Bearer tokenu → 401), updateReservationStatus PUT bez auth → 401. Všetky nahradené api() helperom s automatickým tokenom."
  ],
  "features_v7.5.98": [
    "DOCS: README.md kompletne prepísaný na aktuálny stav (v7.5.97) — moduly, bezpečnostné hardening, architektúra, lib/* utility, stack, deployment, roadmap. Predtým bol stale verzia (v5.1 / v6.21.7 changelog mixed)."
  ],
  "features_v7.5.97": [
    "SECURITY: training-generator.js — escape source label, Number() na phase.duration/ex.duration/totalDuration (AI response hardening proti prompt injection leakage)",
    "SECURITY: error-logs.js — l.severity v CSS style bol raw → safeColor() CSS hex validator, l.id v onclick Number() coercia, all HTTP status Number(), all timestamp escape"
  ],
  "features_v7.5.96": [
    "SECURITY: compliance-alerts.js — esc() na a.severity v data-severity attr a filter button, escape SEVERITY_META.label v filter chips, Number() coercia na summary.total + counts",
    "SECURITY: self-test.js — esc() na overallLabel (fallback na raw overall string), escape timestamp, Number() na summary.passed/warned/failed"
  ],
  "features_v7.5.95": [
    "SECURITY: user-requests.js — esc() na ROLE_LABELS fallback, STATUS_LABELS fallback, u.id v data-edit-id attr, Number() na res.status v error"
  ],
  "features_v7.5.94": [
    "SECURITY admin modules: pricing.js renderPricingRules, populatePricingRuleSelects, renderReport — esc() na r.name, discipline, rider/horse names, id v onclick",
    "SECURITY admin modules: billing.js renderBilling, updateBillingSummary, openMarkPaidModal, openVoidModal, populateBillingSelects — esc() na rider/horse names, reference_code, paid_reference, void_reason, c.id v onclick",
    "SECURITY admin modules: cashdesk.js renderCashdeskTable — esc() na všetky user-zadané polia (rider name, horse name, paid_reference, note)"
  ],
  "features_v7.5.93": [
    "SECURITY: /profil — esc() na ROLE_LABELS fallback (user.role môže byť DB value so zvláštnymi znakmi)",
    "SECURITY: /overenie-emailu — esc() helper pridaný, aplikovaný na title, message, c.href, c.variant, c.label v render() funkcii. Body.error/message z backend API escape-ované (defense-in-depth)"
  ],
  "features_v7.5.92": [
    "SECURITY (public): /preteky — escapeHtml na typeLabel, statusLabel (fallback na raw admin-zadaný competition_type/status pri neznámej hodnote), fmtDateRange output, e.message v error handler",
    "SECURITY (public): /vysledky — escapeHtml na typeLabel, fmtDate output, fmtMoney output, fmtTime output, e.message; Number() coercia na placement a penalties (predtým raw DB value v HTML)"
  ],
  "features_v7.5.91": [
    "SECURITY (public): /rezervacia — renderSpaces, renderTimeSlots, updateSummary mali innerHTML interpolácie bez escape. Admin user ktorý editoval arena/priestor meno/popis alebo slot_type mohol injectnúť JS do verejnej rezervačnej stránky.",
    "esc() helper na space.name, description, slot.start_time/end_time, slot_type",
    "safeColor() validator na space.color (CSS injection — admin-zadaný #hex code)",
    "Number() coercia na space.id, slot.id, total_available, available_spots, price pred interpoláciou do onclick/display"
  ],
  "features_v7.5.90": [
    "UX: Homepage 'Detaily →' (Drezúra, Parkúr) mali href='#' — nikam neviedli. Teraz '#kontakt' s textom 'Záujem →' (viac akcieschopné CTA)",
    "UX: Footer 'JKZM Platform' link z href='#' → '/pre-kluby' (už existujúca landing stránka)",
    "Typografia: '60cm' → '60 cm' s non-breaking space pre správne zalamovanie"
  ],
  "features_v7.5.89": [
    "SECURITY: homepage cenník (/index.html) — esc() na r.name a ostatné interpolované polia pre pricing rules. Admin user ktorý môže editovať cenník (Admin → Cenník) nemohol injectnúť JS do verejnej homepage.",
    "Number() coercia na duration minúty pred interpoláciou"
  ],
  "features_v7.5.88": [
    "SECURITY: Competition modal — escape disciplines/levels option labels a description (hintEl). Pred fixom mohol cachedDisciplines.description + d.label narušiť HTML pri zlom backend response alebo budúcom i18n mechanizme."
  ],
  "features_v7.5.87": [
    "SECURITY: Dashboard widgets criticalAlerts + todayTrainings + upcomingDeadlines — esc() na a.title, a.text, rider/horse name, training status, start_time pred interpoláciou do innerHTML",
    "ALERT_TYPES whitelist na a.type (povoluje iba 'success'|'danger'|'warning'|'info' v CSS class-alert-*; fallback 'info' pri nevalidnom type)"
  ],
  "features_v7.5.86": [
    "SECURITY: SJF sync status widget (renderSjfSyncStatus) — last.status, last.error_message, numeric counts sum/ins/upd/elapsedSec escape-ované/coerced. safeColor() validator na CSS color (CSS injection prevention)."
  ],
  "features_v7.5.85": [
    "SECURITY (KRITICKÉ): showDayDetail — reservation data od public usera (customer_name, phone, email, notes) + arenaName boli interpolované do innerHTML bez escape. Stored XSS vektor — public user v rezervácii mohol zadať JS payload ktorý sa spustil v admin UI pri otvorení detail dňa.",
    "safeTelHref() validátor na r.customer_phone pred vložením do tel: URL — povoluje iba +/číslice/medzery/zátvorky/pomlčky (prevenuje URI injection)",
    "Number() coercia na id, riders_count, reservation count (predtým raw interpolation do onclick argument)"
  ],
  "features_v7.5.84": [
    "SECURITY: renderHorseDetailInfo — 15 admin-zadaných polí escape-ovaných (meno, pas, UELN, mikročip, FEI, SJF, disciplíny, poznámky, atď.) + Number() coercia na výšku/hmotnosť",
    "SECURITY: renderHorseDocs — safeUrl() + esc() na d.file_url (predtým <a href='${d.file_url}'> bez validácie — javascript:URL vektor) + rel='noopener noreferrer'",
    "encodeURIComponent na horse_id v loadHorseDocs fetch URL",
    "'Volacia meno' → 'Volacie meno' (gramatika — 'meno' je stredný rod)"
  ],
  "features_v7.5.83": [
    "SECURITY batch (6 error handlerov): esc() na e.message vo všetkých zostávajúcich error innerHTML šablónach — SJF pairing search, CSV import (riders/horses), photo upload, partner logo upload",
    "CRITICAL: uploadPartnerLogo — safeUrl() + esc() na data.url v img src (pred fixom mohol malicious server vrátiť data:text/html alebo javascript: URL)",
    "uploadMedia — esc() na file.name v status text (filename z disku admin usera mohol obsahovať HTML)",
    "CSV import error: escape aj data.details (SQL chyby od backendu)",
    "'...' → '…' Unicode ellipsis"
  ],
  "features_v7.5.82": [
    "SECURITY: renderResultsList + refreshResultsList — esc() na rider/horse mená, discipline, id (v onchange/onclick), notes v input value, e.message. Pred fixom rider.last_name s ' by XSS-nulo pri rendrovaní.",
    "numVal() helper — coercia numerických hodnôt (placement, score, time, penalties, prize_money) pred interpoláciou do input value",
    "encodeURIComponent na competition_id"
  ],
  "features_v7.5.81": [
    "SECURITY: renderEntriesList + refreshEntriesList — esc() na rider/horse mená, sjf licence numbers, discipline, category, entry id, payment/status labels, validation error message (v title attribute), entry.message",
    "Number() coercia na start_number, entry_fee (namiesto raw string interpolation)",
    "encodeURIComponent na competition_id vo fetch URL"
  ],
  "features_v7.5.80": [
    "SECURITY: openFeedingDetail a loadFeedingItems escape-ujú horse.name, feeding.date, feed_type, quantity, unit, notes, item.id pred interpoláciou do innerHTML/onclick",
    "encodeURIComponent na feeding_id vo fetch URL",
    "Diakritika: 'Kon/Datum/Cas' → 'Kôň/Dátum/Čas' v feedingDetailInfo"
  ],
  "features_v7.5.79": [
    "SECURITY: populateSelects escape-uje horse/rider/trainer/employee name a id pred interpoláciou do <option value>/<option text>. Pred fixom by admin-zadaný horse.name s < znakom narušil select tag."
  ],
  "features_v7.5.78": [
    "SECURITY (XSS): openAlbumPhotos interpolovalo p.url do onclick='viewImage(\"${p.url}\")' — kritický XSS vektor ak URL obsahovala '. Teraz esc() + safeUrl() whitelist.",
    "viewImage/playVideo: pridaná URL validácia pred window.open + 'noopener,noreferrer' — predtým mohol javascript:URL otvoriť nový tab s JS execution",
    "encodeURIComponent na album_id v fetch URLs",
    "isVideo detection: regex místo .includes() — presnejšia detekcia"
  ],
  "features_v7.5.77": [
    "SECURITY (CSS injection fix): loadAlbums interpolovalo a.cover_image do 'background:url(${cover_image})' bez validácie. Ak by admin zadal cover_image so znakmi ); } alebo '/* */' , CSS injection by mohol narušiť layout alebo exfiltrovať data.",
    "Fix: safeCssUrl() whitelist — povoluje iba http(s):// alebo / relatívne URL s bezpečnou sadou znakov. Cover URL teraz s explicitnými úvodzovkami v CSS.",
    "esc() na title, description, a.id"
  ],
  "features_v7.5.76": [
    "SECURITY: loadPartners s safeUrl() pre p.logo_url a p.website + esc() na všetky dáta. Partners grid mohol XSS-núť cez javascript:URI v website.",
    "SECURITY: loadServices s esc() na title, description, icon, badge_text, id"
  ],
  "features_v7.5.75": [
    "SECURITY: XSS + javascript: URI injection fix v loadPages a loadDocuments",
    "loadPages: esc() na title, slug, template, id + ✓/— namiesto emoji character placeholder",
    "loadDocuments: safeUrl() validator — povoluje len http(s):// alebo relatívne URL (prevenuje javascript:/data: URI XSS cez admin-entered d.file_url)",
    "rel='noopener noreferrer' na externý document link",
    "encodeURIComponent na category filter parameter",
    "Number() coercia na download_count"
  ],
  "features_v7.5.74": [
    "SECURITY (XSS + CSS injection): loadArticles interpolovalo neescape-ované hodnoty: a.title, a.author, a.article_categories.name do HTML a — KRITICKÉ — a.article_categories.color do CSS style='background:${color};...'",
    "CSS color injection: ak by admin zadal kategóriu s color='red;}</style><script>alert(1)</script>', XSS by sa spustil. Fix: safeCssColor() validátor — povoluje iba #hex (3-8 chars) alebo rgb()/rgba() formát.",
    "XSS: esc() na title, author, category name, data.error, e.message",
    "Number() coercia na status code a views",
    "Ellipsis '...' → '…' v loading state"
  ],
  "features_v7.5.73": [
    "Defensive XSS: renderUpcomingCompetitionsWidget (dashboard) s esc() — c.name, c.location, c.id escape-ované"
  ],
  "features_v7.5.72": [
    "Defensive XSS: renderReservationsTable + renderReservationsCalendar s esc() — reservations od public usera boli neescape-ované (customer_name, customer_email, arena_name v onclick)",
    "Kritickejšia opravili sa arena.name v onclick='showDayDetail(id, name, date)' — pred sanitizáciou mohol admin, ak sa arena.name obsahovala ' alebo <, spustiť JS injection"
  ],
  "features_v7.5.71": [
    "Defensive XSS: 3 license render funkcie — renderRiderLicenses, renderHorseLicenses, renderTrainerLicenses",
    "Všetky meno/licencie/ID fields escape-ované"
  ],
  "features_v7.5.70": [
    "Defensive XSS: renderMemberships s esc() — rider_name, membership_type escape-ované; onclick m.id → Number() coercia"
  ],
  "features_v7.5.69": [
    "Defensive XSS: renderArenas s esc() + Number() coercia pre arena.id v onclick (prevenuje XSS cez stringy v onclick)",
    "Arena description, name, capacity escape-ované"
  ],
  "features_v7.5.68": [
    "Defensive XSS: renderCompetitions + renderFeeding s esc()",
    "Admin sekcie Preteky a Kŕmenie — user notes, názvy, disciplíny escape-ované"
  ],
  "features_v7.5.67": [
    "Defensive XSS: renderStableLog + renderVisitLog s esc()",
    "Maštaľná kniha a Návštevná kniha — kde sa zapisujú real-world mená, adresy, poznámky — teraz bezpečne escape-ujú všetky fields"
  ],
  "features_v7.5.66": [
    "Defensive XSS: renderVetRecords + renderVaccinations + renderAdminUsers s esc() — finalizuje XSS ochranu admin evidencie",
    "Celkovo 10 render funkcií s esc() ochranou: Messages, Bookings, Tasks, Notifications, Horses, Riders, Trainers, Employees, Payments, VetRecords, Vaccinations, AdminUsers"
  ],
  "features_v7.5.65": [
    "Defensive XSS: 5 ďalších render funkcií (renderHorses, renderRiders, renderTrainers, renderEmployees, renderPayments) s esc() pred všetkými interpoláciami dát.",
    "Motívom: aj keď tieto entity vytvára iba admin (nižšie riziko než public input), obranné escape je bezpečnejší default — prevencia XSS pri náhodnom vložení HTML v poznámke alebo description."
  ],
  "features_v7.5.64": [
    "Defensive XSS: renderTasks a renderNotifications pridané esc() pred interpoláciu t.title/t.description/n.title/n.message (defensive aj keď tasks/notifications vytvára iba admin)",
    "Diakritika: 'Zacat/Dokoncit/Skryt' → 'Začať/Dokončiť/Skryť' v task akciách",
    "delete button glyph 'X' → '×' + aria-label 'Zmazať' (a11y)",
    "'...' → '…' (Unicode ellipsis) v description truncation"
  ],
  "features_v7.5.63": [
    "SECURITY (XSS fix): Admin Správy (renderMessages) a Rezervácie (renderBookings) nepoužívali escape pri user-supplied hodnotách z /api/contact a /api/bookings public endpointov.",
    "Ak by niekto v kontaktnom formulári odoslal meno alebo správu s <script> tagom, admin by pri otvorení sekcie bol XSS-nutý. Každá hodnota teraz escape-nutá cez esc()."
  ],
  "features_v7.5.62": [
    "A11y: 51 modal-close tlačidiel s × glyfom dostane aria-label a title 'Zavrieť' cez JS init — screen reader predtým čítal 'multiplication sign/times' namiesto 'close'",
    "Aplikuje sa automaticky aj na budúce modály (runtime enhancement bez HTML tediousness)"
  ],
  "features_v7.5.61": [
    "Diakritika v titules: 'Novy slot' → 'Nový slot', 'Nova rezervacia' → 'Nová rezervácia', 'Nove upozornenie' → 'Nové upozornenie', 'Novy admin uzivatel' → 'Nový admin používateľ' (2× title + 1× button)",
    "notificationModal close glyph 'x' → '×' (konzistentne)"
  ],
  "features_v7.5.60": [
    "Cleanup: 3 × debug console.log z loadAll() a populateSelects() odstránené (zvyšok developmentu) — čistá browser console v admine"
  ],
  "features_v7.5.59": [
    "SECURITY (defenzívny): /rezervacia chybový alert escape-uje e.message pred vložením do innerHTML — server error messages teoreticky mohli obsahovať HTML",
    "Notifications severityLabels/sourceLabels s diakritikou aj v render (Kritické, Manuálne, Automatické) — predtým len v print export"
  ],
  "features_v7.5.58": [
    "Tasks statusLabels (2×): Otvorena/Rozpracovana/Dokoncena/Zrusena → Otvorená/Rozpracovaná/Dokončená/Zrušená",
    "Tasks priorityLabels: Nizka/Normalna/Vysoka/Urgentna → Nízka/Normálna/Vysoká/Urgentná",
    "Task modal select options s diakritikou",
    "'Vazba na kona' → 'Väzba na koňa' v task modáli"
  ],
  "features_v7.5.57": [
    "9 × toast diakritika: 'Neautorizovane' → 'Neautorizované — prihláste sa znova', 'Kon sa nenasiel' → 'Kôň sa nenašiel', 'Vyplnte typ a mnozstvo' → 'Vyplňte typ a množstvo', 'Polozka pridana' → 'Položka pridaná', 'Vyplnte uzivatelske meno' → 'Vyplňte používateľské meno', 'Heslo je povinne pre noveho pouzivatela', 'Uzivatel ulozeny/zmazany' → 'Používateľ uložený/zmazaný', 'Nemozno zmazat posledneho admina'"
  ],
  "features_v7.5.56": [
    "Calendar toast: 'Ucet nebol vytvoreny - skontrolujte cennik' → 'Účet nebol vytvorený — skontrolujte cenník' + 'Vyberte kona a jazdca' → 'Vyberte koňa a jazdca'"
  ],
  "features_v7.5.55": [
    "Diakritika: 'Ziadne záznamy' → 'Žiadne záznamy' (6 tabuliek), Žiadny/Žiadna/Žiadne položky/očkovania/licencie/úlohy/upozornenia",
    "Aktivny/Neaktivny → Aktívny/Neaktívny v admin users",
    "Vaccination modal: 'Ockovanie' → 'Očkovanie', 'Datum ockovania' → 'Dátum očkovania', 'Typ vakciny' → 'Typ vakcíny', 'Kon' → 'Kôň', 'Nove ockovanie' → 'Nové očkovanie'",
    "Print export templates (7×) kompletne diakritické: JAZDECKÝ KLUB ZELENÁ MÍĽA, Maštaľná kniha, Návštevná kniha, Prehľad úloh/upozornení/očkovaní, Dokumenty; Dátum, Čas, Čip, Dôvod, Organizácia",
    "Severity labels: 'Kriticke' → 'Kritické', 'Manualne' → 'Manuálne', 'Automaticke' → 'Automatické'",
    "'od zaciatku' → 'od začiatku' vo 2 exportoch"
  ],

  "features_v7.5.54": [
    "Diakritika batch: admin tlačidlá Zmazať/Upraviť (6×), modal titles Upraviť koňa/jazdca/záznam/očkovanie/používateľa/úlohu/Nová úloha",
    "Calendar: Pridať slot, Pridať prvý slot, Žiadne sloty v tomto týždni, Zúčastnil sa / Neprišiel / Zrušiť rezerváciu, Hotovosť",
    "TimeLabels: Rano/Vecer → Ráno/Večer v kŕmení",
    "Option: 'Žiadne kone — najprv pridajte…' (predtým Ziadne kone)",
    "Modal title 'Týždeň' + loading text 'Načítavam kalendár…' (predtým Tyzden, Nacitavam)",
    "audit-log actionLabel UPDATE: 'Uprava' → 'Úprava'",
    "Modal close glyph 'x' → '×' v taskModal (konzistentne s ostatnými modálmi)"
  ],

  "features_v7.5.53": [
    "6 delete* funkcií migrovaných na api() helper (deleteStableLog, deleteVisitLog, deleteDoc, deleteDocFromHorse, deleteStableLogFromHorse, deleteTask) — jednotný error handling a žiadne priame fetch volania",
    "deleteTask: pridaný success toast 'Úloha zmazaná' (predtým iba tichý reload)",
    "Diakritika v delete confirmoch/toastoch: 'vymazat tohto kona' → 'vymazať tohto koňa', 'Kon vymazany' → 'Kôň vymazaný', 'zmazat zaznam krmenia' → 'zmazať záznam kŕmenia', 'polozka zmazana' → 'položka zmazaná', atď.",
    "Bezpečnostný polish: rel='noopener noreferrer' na externý link dataprotection.gov.sk (privacy.html)",
    "Typo fix: 'faktúrácia' → 'fakturácia' v /pre-kluby cenník Professional"
  ],
  "features_v7.5.52": [
    "saveArena BUG fix: používal raw fetch bez Authorization header — admin by nevedel ukladať arény v produkcii (401). Teraz používa api() helper + withSaveLock",
    "deleteArena: migrácia na api() helper (bola raw fetch bez auth)",
    "saveDoc: withSaveLock + api() helper (predtým raw fetch s manuálnym Bearer token)",
    "Finalizuje pokryv withSaveLock/api() pattern na všetky save* funkcie v admin index.html"
  ],
  "features_v7.5.51": [
    "saveStableLog + saveVisitLog: withSaveLock + api() helper (predtym raw fetch s manualnym Bearer token)",
    "Success toasty: 'Záznam upravený/uložený', 'Návšteva upravená/uložená'"
  ],
  "features_v7.5.50": [
    "saveTask a saveNotification používajú api() helper + withSaveLock (predtým raw fetch bez feedback toasov)",
    "Success toasty 'Úloha vytvorená/upravená', 'Upozornenie vytvorené'"
  ],
  "features_v7.5.49": [
    "/pre-kluby: odstránená FAQ 'Funguje SJF synchronizácia automaticky?' (user request — zatiaľ vyhodiť)",
    "Aj zo structured data (JSON-LD FAQPage schema) + z viditeľného FAQ accordionu"
  ],
  "features_v7.5.48": [
    "i18n admin: 18 ďalších diakritík — Zrušiť, Uložiť, Pridať, Vyberte koňa, Pridať koňa/jazdca/trénera/zamestnanca (modal titles), Rezervovať",
    "Konzistentnejší slovenský UI"
  ],
  "features_v7.5.47": [
    "Nav: 'Preteky' a 'Výsledky' dočasne skryté z hlavnej navigácie na 15 verejných stránkach (user request 22.4.2026)",
    "Linky nie sú odstránené — iba zakomentované cez '<!-- DISABLED (22.4.2026): ... -->'. Na znovu-zapnutie stačí odstrániť komentár.",
    "Stránky /preteky a /vysledky stále fungujú cez direct URL aj cez sitemap — iba nie sú v menu",
    "TODO: budúce — admin UI pre toggle nav items (architektonická požiadavka, zatiaľ menuálne)"
  ],
  "features_v7.5.46": [
    "USER REPORTED: Knižnica notifikácie — používateľ po odoslaní teraz dostane CONFIRMATION EMAIL 'Ďakujeme, meno!' s potvrdením prijatia správy + klubovými kontaktmi",
    "Admin → Správy: zobrazuje teraz aj 'service' (napr. 'Knižnica — notifikácia o spustení') vedľa mena, telefón ak zadaný, email ako mailto: link",
    "Empty state v Správy má popis: 'Správy prichádzajú cez kontaktný formulár na /kontakt, /rezervacia alebo /kniznica'"
  ],
  "features_v7.5.45": [
    "Security: SJF admin endpointy (sjf-horses, sjf-persons, sjf-clubs) dostali auth guard — predtým bolo možné verejne stiahnuť scraped data (details JSONB pole môže obsahovať kontaktné info)",
    "Admin frontend fetches aktualizované s Authorization header pre SJF endpointy"
  ],
  "features_v7.5.44": [
    "GDPR/Security fix: /api/members-public vracal phone+email jazdcov publicky (bez auth). Endpoint nikto nepoužíva (dead code), ale security díera ostávala. Pridaný verifyToken guard — GDPR compliance"
  ],
  "features_v7.5.43": [
    "Perf: Cache-Control pridané na /api/public/posts a /api/public/posts-slug — CDN cache 60s/300s + stale-while-revalidate 300s/600s",
    "Verejné 'novinky' načítavanie teraz využíva Vercel edge cache — ušetrí DB dotazy pri traffic peaks"
  ],
  "features_v7.5.42": [
    "UX: Admin sidebar zobrazuje version badge (napr. 'v7.5.42') vpravo dole — user vie okamžite aká verzia je nasadená bez klikania na Systém"
  ],
  "features_v7.5.41": [
    "Cleanup: 2 debug console.log v editTraining odstránené (zvyšok z developmentu)"
  ],
  "features_v7.5.40": [
    "UX: 11 natívnych alert() dialógov nahradených showToast — konzistentný UX v admin (predtým browser popup vyzeral ako cudzí prvok v dark admin)",
    "i18n: Vyplňte názov/úlohy, Chyba pri ukladaní, Upozornenia obnovené (diakritika)",
    "Typ toastu správne (error/warning/success) podľa kontextu"
  ],
  "features_v7.5.39": [
    "BUG fix batch: 4 delete* funkcie používali raw fetch bez Authorization (deleteAlbum, deleteMedia, deletePage, deletePartner)",
    "Všetky teraz používajú api() helper — mazanie funguje aj keď endpointy vyžadujú auth",
    "Pridaný success toast po úspešnom delete (predtým len zmizol záznam)"
  ],
  "features_v7.5.38": [
    "saveSettings: rovnaký raw-fetch-bez-auth bug — opravené, použíiva api() helper. Predtým admin nastavenia webu sa nedali uložiť",
    "Odstránený console.log debug spam z saveSettings",
    "Finálne pokrytie: všetky evidence/web-content/settings save funkcie používajú api() s autentifikáciou"
  ],
  "features_v7.5.37": [
    "BUG FIX batch: savePage, saveAlbum, saveWebDocument, saveService — rovnaký raw-fetch-bez-auth bug. Všetky teraz používajú api() helper + withSaveLock",
    "deleteDocument, deleteService tiež opravené (raw fetch bez auth)",
    "Celkové pokrytie: 12 save* funkcií má teraz auth + lock (boli 2 najmä admin evidence + web content)"
  ],
  "features_v7.5.36": [
    "BUG fix: savePartner používal raw fetch bez Authorization header — rovnaký bug ako pre saveArticle (opravené v PR #238). Oba teraz používajú api() helper.",
    "withSaveLock na savePartner"
  ],
  "features_v7.5.35": [
    "withSaveLock: saveVaccination + saveMembership",
    "Diakritika fix v vaccination: 'Ockovanie' → 'Očkovanie', 'datum' → 'dátum', 'vakciny' → 'vakcíny'"
  ],
  "features_v7.5.34": [
    "withSaveLock aplikovaný na savePayment, saveVetRecord, saveFeeding",
    "Bonus diakritika: 'Veterinárny záznam upravený/uložený', 'Záznam kŕmenia uložený'",
    "Kŕmenie (user favorite) — teraz má proper feedback počas ukladania"
  ],
  "features_v7.5.33": [
    "saveTraining: withSaveLock + odstránený console.log debug spam",
    "Diakritika: 'Tréning upravený!/pridaný!' → bez výkričníkov pre konzistentnosť"
  ],
  "features_v7.5.32": [
    "withSaveLock aplikovaný aj na saveTrainer a saveEmployee — finálne pokrytie všetkých evidence save funkcií",
    "Bonus diakritika: 'Tréner upravený/pridaný', 'Zamestnanec upravený/pridaný'",
    "Modal title fix: 'Upravit trenera' → 'Upraviť trénera', 'Upravit zamestnanca' → 'Upraviť zamestnanca'"
  ],
  "features_v7.5.31": [
    "Nový helper withSaveLock(modalId, fn) — reusable double-submit prevention",
    "Aplikovaný na saveCompetition (refactor), saveHorse a saveRider",
    "Saveove tlačidlá sa zamknú + 'Ukladám…' text, po dokončení try/finally odblokuje",
    "Bonus: saveHorse/saveRider success toasty teraz majú diakritiku ('Kôň pridaný', 'Jazdec upravený'), nepoužívajú console.log debug spam"
  ],
  "features_v7.5.30": [
    "UX: saveCompetition double-submit prevention — počas API call sú tlačidlá v modal-footer disabled + 'Ukladám…' text",
    "try/finally zabezpečí že sa tlačidlá vždy odblokujú (aj po chybe)"
  ],
  "features_v7.5.29": [
    "UX: Login form submit tlačidlo počas prihlasovania — 'Prihlasujem…' + disabled (zabráni double-submit a user vidí feedback)",
    "Po úspešnom logine: button zostáva disabled (nahradí sa app UI)",
    "Po chybe: button sa obnoví s pôvodným textom"
  ],
  "features_v7.5.28": [
    "i18n: 'Chyba siete - skontrolujte pripojenie' → '— skontrolujte pripojenie' (em-dash typograficky správne)"
  ],
  "features_v7.5.27": [
    "i18n: ďalších 8 diakritických opráv v calendar.js — Všetci tréneri, bez trénera, Načítavam, Žiadne rezervácie, Vyberte koňa, Slot zmazaný, Rezervácia vytvorená, Účet vytvorený"
  ],
  "features_v7.5.26": [
    "BUG fix: v calendar.js dayNames mali duplicitné 'St' pre stredu aj štvrtok (štvrtok by sa zobrazoval ako 'St') — opravené na ['Po', 'Ut', 'St', 'Št', 'Pi', 'So', 'Ne']",
    "i18n: 15 diakritických opráv v calendar.js, nav.js a toastoch (Nie ste prihlásený, Obnoviť stránku, Načítavam kalendár, Drezúra, Terén, rezervácií, plných, Obľúbené, atď.)",
    "Disciplína labels: Drezura → Drezúra, Teren → Terén, Lonz → Lonž"
  ],
  "features_v7.5.25": [
    "UX: Badge v nav sidebar sa skryje ak je count 0 (predtým visel 'alertBadge: 0' stále, aj keď žiadne upozornenia)",
    "nav.js default badge HTML má display:none — zobrazí sa iba keď setter nastaví reálnu hodnotu",
    "alertBadge setter hide-on-zero logika — konzistentne s userRequestsBadge (ktorý už tak robil)"
  ],
  "features_v7.5.24": [
    "UX: Dynamický browser tab title v admine — mení sa podľa aktívnej sekcie (napr. 'Preteky · Admin JKZM', 'Kone · Admin JKZM')",
    "Pomáha orientácii pri viacerých otvorených admin taboch (rovnako ako Gmail/GitHub)",
    "CSS.escape na section id (safety pre special characters)"
  ],
  "features_v7.5.23": [
    "UX: nav.js search empty state — pri hľadaní bez zhôd zobrazí 'Žiadne zhody pre X. Skús iné kľúčové slovo alebo zmaž filter.' (predtým prázdny sidebar)",
    "HTML escape na searchTerm pre safety"
  ],
  "features_v7.5.22": [
    "UX: Feeding (kŕmenie) empty state — 'Záznamy sa pridávajú po nakŕmení koní — pomáha to sledovať spotrebu krmiva a zdravotné súvislosti' namiesto len 'Žiadne záznamy kŕmenia'"
  ],
  "features_v7.5.21": [
    "UX: vylepšené empty states v billing-charges a pricing-rules — pridaný informatívny popis namiesto strohého 'Žiadne položky'",
    "billing.js: 'Platobné záznamy vznikajú automaticky pri tréningu alebo pridajte manuálne'",
    "pricing.js: 'Pravidlá určujú cenu tréningov podľa disciplíny, dĺžky alebo konkrétnych jazdcov/koní'"
  ],
  "features_v7.5.20": [
    "UX: Empty states v evidencia (Kone/Jazdci/Tréneri) majú teraz call-to-action tlačidlo 'Pridať prvého koňa/jazdca/trénera'",
    "Predtým len text 'Žiadne kone' — teraz aj direct action button, užívateľ vie okamžite čo robiť"
  ],
  "features_v7.5.19": [
    "a11y: 3 dynamické <img> preview v admine dostali alt atribúty (články cover, album cover, upload náhľad) — predtým by screen reader ohlásil iba 'obrázok'",
    "i18n admin: malé opravy typu 'Tip:Klikni' → 'Tip: Klikni' (chýbala medzera v 2 miestach)"
  ],
  "features_v7.5.18": [
    "Preventívny fix: api/vet-records.js POST teraz posiela aj legacy 'date' column okrem moderného 'record_date' — rovnaký pattern ako v PR #220 competitions, pre prípad, že DB má obe kolóny s NOT NULL",
    "safeWriteToTable automaticky strippne legacy 'date' ak DB ho nemá (42703 handler)",
    "Audit iných tabuliek: trainings.date, feeding.date, memberships.start_date — frontend už posiela legacy názvy, OK"
  ],
  "features_v7.5.17": [
    "KRITICKÝ fix ukladania pretekov: DB po v7.5.0 migrácii má OBA stĺpce (competition_date + date_start), a date_start má NOT NULL constraint z pôvodnej schémy",
    "safeWriteToTable remap sa spúšťa iba pri 42703 (column missing), nie pri 23502 (NOT NULL violation) — preto admin stále dostával 500 pri ukladaní",
    "Fix: mirrorDateFields() helper vždy zrkadlí hodnoty medzi competition_date ↔ date_start a end_date ↔ date_end pred insert/update — DB má oba stĺpce satisfied bez ohľadu na schému",
    "User okamžitý efekt: POST /api/competitions s competition_date teraz prejde aj keď DB má NOT NULL na date_start"
  ],
  "features_v7.5.16": [
    "UX: admin showSection() má fallback pre neznáme sekcie — ak URL hash neexistuje (napr. #foo), zobrazí sa Prehľad + toast 'Sekcia nenájdená'",
    "Predtým: unknown hash spôsobil, že všetky sekcie boli skryté → user videl prázdnu stránku",
    "loadSectionFromHash už neni-skipuje unknown hashes (showSection to handleuje)"
  ],
  "features_v7.5.15": [
    "UX: /rezervacia formulár má pridané autocomplete, inputmode, pattern a maxlength atribúty",
    "autocomplete='name/tel/email' — password manageri suggest-ujú uložené hodnoty",
    "inputmode='tel/email' — mobilná klávesnica zobrazí správnu variantu (číslice, @)",
    "pattern na telefón: [+]?[0-9\\s\\-()]{6,20} — HTML5 validácia tvaru + tooltip 'Zadaj telefón v tvare +421 905 123 456'",
    "minlength/maxlength — základná sanitizácia dĺžky vstupov"
  ],
  "features_v7.5.14": [
    "UX: click-to-copy na /o-klube pre dátové karty (IČO 53 536 002, IBAN SK66..., registračné číslo) — užívateľ len klikne a text sa skopíruje, krátky zelený toast potvrdí",
    "Iba .mono karty (strukturované čísla) — ostatné sú normálny text",
    "Keyboard access: tabindex='0' + role='button' + aria-label, Enter/Space tiež kopíruje",
    "Fallback: starší browser bez Clipboard API sa správa ako predtým (žiadna interakcia)"
  ],
  "features_v7.5.13": [
    "SECURITY: logout() vymaže VŠETKY admin localStorage kľúče (predtým len token)",
    "Ovplyvňuje zdieľané PC — ďalší user neuvidí pôvodné preferencie (favorites, open section, calendar filters, last activity timestamp)",
    "Session timeout doLogout() a change-password logout teraz používajú unified logout() funkciu — jediné miesto na údržbu"
  ],
  "features_v7.5.12": [
    "UX: Stat cards na dashboardoch a Kalendári a Notifikáciách defaultne ukazujú '—' (loading state) namiesto '0' — predtým user pred dokončením loadAll() mohol myslieť, že má 0 koní/jazdcov/úloh",
    "title='Načítavam' tooltip pre objasnenie",
    "Po načítaní sa nahradí reálnym číslom"
  ],
  "features_v7.5.11": [
    "Migrované zvyšné 2 native confirm() na showConfirm() v sekcii Výsledky pretekov: 'Vytvoriť výsledok ručne' a 'Vytvoriť výsledky z prihlášok'",
    "Konzistentný UX — všetky confirm v admine teraz cez modal s focus trap a custom OK textom"
  ],
  "features_v7.5.10": [
    "UX: 'Zobraziť/Skryť' tlačidlo pri hesle v admin login forme — common UX pattern, pomáha pri preklepe (môže overiť čo napísal)",
    "Bezpečnosť zachovaná — toggle iba lokálne v DOM, nedeje sa zmena typu inputu pre password manager"
  ],
  "features_v7.5.9": [
    "SECURITY AWARENESS: Po prihlásení do admina sa zobrazí toast 'Posledné prihlásenie: [dátum] z IP [ip]' — pomáha detekovať kompromitáciu účtu (ak user vidí prihlásenie z neznámej IP)",
    "Backend: /api/auth-login pridá do response 'previous_login' field (created_at, ip, user_agent) z login_events tabuľky",
    "Frontend: po úspešnom logine sa zobrazí info toast s 800ms oneskorením"
  ],
  "features_v7.5.8": [
    "UX/Security: Password strength meter v Zmena hesla — vizuálny indikátor (5 úrovní: Veľmi slabé až Veľmi silné) sa updatuje pri písaní",
    "Skóre: dĺžka (8/12/16+), case mixing, číslica, špeciálny znak; mínusové body za opakovanie znakov a sekvencie (123, qwer, ...)",
    "Match indikator pre 'Nové heslo znova' — instant ✓ ak sa zhodujú, ✗ ak nie. Predtým user zistil chybu až pri submite",
    "Encouragement strong passwords bez tvrdej validácie nad rámec server-side requirements"
  ],
  "features_v7.5.7": [
    "SECURITY: Auto-logout admin po 30 minútach nečinnosti — predtým neexistoval idle timeout, otvorený admin tab v kaviarni / na verejnom PC bol stále prihlásený",
    "Po 25 minútach: warning modal s countdown ('Budete odhlásený za 5:00') + tlačidlá 'Pokračovať' / 'Odhlásiť hneď'",
    "Aktivita (klik, klávesa, scroll, mousemove, touchstart) resetuje timer — throttled na 1× za 30s pre výkon",
    "Multi-tab sync: aktivita v inom otvorenom admin tabe posunie timer aj v ostatných tabe-och",
    "Konfigurácia: window.__sessionTimeout pre debug/úpravy (IDLE_MIN, WARN_MIN)"
  ],
  "features_v7.5.6": [
    "Slovenský polish v admin UI: 103 chýbajúcich diakritík opravených (Tlač, Obnoviť, Pridať, Všetky, Neprečítané, Závažnosť, Kritické, Informácie, Manuálne, Kôň, Názov, Správa, Vytvorené, Dátum, Termín, Veterinár, Kategória, Súbor, Číslo, Platnosť, Vakcíny, Šarža, Dokončená, Poznámka, Položku, ...)",
    "Pokrýva tlačidlá, table headers, options, labels, placeholders",
    "Profesionálny vzhľad bez 'cudziackych' textov ako 'Tlac' alebo 'Obnovit'"
  ],
  "features_v7.5.5": [
    "KRITICKÝ SECURITY: 12 endpointov predtým kontrolovalo len prítomnosť 'Bearer ' prefixu v Authorization headeri, bez overenia JWT. Stačilo 'Authorization: Bearer cokolvek' → 200 s dátami",
    "Opravené: notification-rules, notification-rules-id, exports/notifications, exports/audit-logs, exports/documents, exports/stable-log, exports/export-pack, exports/visit-log, exports/tasks, exports/horse-card, exports/horses-licenses, exports/vaccinations",
    "Všetky teraz používajú verifyTokenFromReq() z lib/auth.js — plné JWT overenie"
  ],
  "features_v7.5.4": [
    "SECURITY batch: všetky evidence *-id.js endpointy vyžadujú teraz auth aj na GET",
    "horses-id, riders-id, trainers-id, employees-id, competitions-id — predtým GET bez auth guard vrátil kompletný záznam (passport, SJF licence, poznámky, entry_fee)",
    "KRITICKÝ FIX audit-logs.js a audit-logs-id.js: predtým len kontrolovali prítomnosť 'Bearer ' prefixu, bez overenia JWT — ktokoľvek mohol dostať audit log s 'Authorization: Bearer cokolvek'. Teraz verifyToken() plne overí JWT."
  ],
  "features_v7.5.3": [
    "SECURITY fix: /api/competitions GET teraz vyžaduje auth (predtým verejné — admin polia entry_fee a notes boli exponované)",
    "Verejný prístup: /api/public/competitions vracia iba public-safe polia (skrýva entry_fee)",
    "Druhý endpoint po /api/horses (PR #205) s pridaným auth guard"
  ],
  "features_v7.5.2": [
    "SECURITY fix: /api/horses GET vyžaduje teraz autentifikáciu (predtým bolo verejne dostupné — kľuč údaje koní ako passport_number, sjf_license_number, insurance boli prístupné každému)",
    "Zosúladené s ostatnými evidence endpointmi (riders, trainers, employees už vyžadovali auth)",
    "Verejný prístup na zoznam koní zostáva cez /api/public/horses (ten vracia len nesenzitívne polia)"
  ],
  "features_v7.5.1": [
    "api/bookings-id.js PUT/PATCH: safeWriteToTable (admin úpravy rezervácií)",
    "api/pricing-rules-id.js PATCH: safeWriteToTable (úprava cenníkového pravidla)",
    "Posledné dva high-use *-id endpointy sú teraz schema-drift tolerantné"
  ],
  "features_v7.5.0": [
    "SQL MIGRÁCIA (database-v7.5.0-schema-unification.sql): idempotentné ADD COLUMN IF NOT EXISTS pre všetky evidencia/vet/booking tabuľky — unifikuje schému s modernym frontend contract-om",
    "Nehľadíme na data (iba add nullable columns), bezpečne spustiteľné viackrát",
    "Po aplikácii: horses/riders/trainers/employees/bookings/vet_records/health_records/vaccinations/stable_log/competitions majú všetky stĺpce ktoré frontend posiela",
    "Safe-write pattern v app-layeri zostáva ako 'belt + suspenders' — ale po migrácii už nič nebude stripované"
  ],
  "features_v7.4.24": [
    "Admin Kalendár stat cards (Arén/Rezervácií/Čakajúcich): iniciálky A/R/? v farebných boxoch (predtým prázdne)",
    "Admin Service (Cenník) modal: dead icon picker odstránený — 35 prázdnych 'icon-option' spanov ktoré volali selectIcon('') nerobili nic. Teraz je 'Ikona' pole editovateľné (predtým readonly), s placeholder '★' ako príklad"
  ],
  "features_v7.4.23": [
    "Admin dashboard stat cards (Kone/Jazdci/Tréningy/Upozornení): farebné ikonové boxy dostali iniciálky K/J/T/! (predtým prázdne farebné štvorce)",
    "CSS stat-card .icon: font-weight:700 + letter-spacing:-0.02em pre lepší iniciálka look"
  ],
  "features_v7.4.22": [
    "Admin dashboard quick-actions: prazdne <div class='icon'></div> boxy naplnene '+' znakom (predtym 7 prazdnych 'podlhovastych utvarov' nad textom — user report)",
    "A11y: kazda quick-action ma role='button', tabindex='0' a aria-label pre screen readery (predtym boli divs bez semantiky)",
    "Oprava priamo rieši user feedback: 'Mnohé veci majú iba nejaké podlhovasté útvary a my si máme domyslieť že sú to tlačidlá'"
  ],
  "features_v7.4.21": [
    "api/competition-entries.js POST — safeWriteToTable (prihlášky na preteky tolerantné k schema drifte)",
    "api/stable-log.js POST — maštaľná kniha",
    "api/articles.js POST — novinky/články",
    "api/partners.js POST — partneri (web mode)"
  ],
  "features_v7.4.20": [
    "Financial endpoints safe-write: api/billing-charges.js POST, api/payments.js POST + PUT",
    "Horse health endpoints safe-write: api/health-records.js POST + PUT, api/vet-records.js POST (18+ polí — vysoký drift risk), api/vaccinations.js POST",
    "Pokrytie kompletné pre všetky často-používané evidencia/financie/zdravie admin POST/PUT endpointy"
  ],
  "features_v7.4.19": [
    "api/memberships.js POST + PUT — safeWriteToTable (členské preukazy sa nebudú zadrhávať na schema drifte)",
    "api/pricing-rules.js POST — rovnako (cenníkové pravidlá, ktoré user edituje v Cenník sekcii)",
    "Ďalšie ochrannené endpointy pre high-use admin funkcie"
  ],
  "features_v7.4.18": [
    "api/bookings.js POST — safeWriteToTable pre verejný flow rezervácie. Ak DB nemá niektorý stĺpec (napr. use_club_horse, experience_level, horse_name), rezervácia zákazníka už neskončí 500 — stĺpec sa stripne a rezervácia prejde",
    "Toto je kritický high-value fix — bookings robia reálni zákazníci z /rezervacia, 500 = strata rezervácie"
  ],
  "features_v7.4.17": [
    "api/employees.js POST + PUT, api/employees-id.js PUT — safeWriteToTable (rovnaký pattern ako horses/riders)",
    "api/trainers.js POST + PUT — safeWriteToTable nahrádza bespoke 'fallback na basic fields' handler (teraz sa stripnú len unknown stĺpce, ostatné zostávajú)",
    "Finálny pokryv: všetky evidence POST/PUT sú teraz schema-drift tolerantné"
  ],
  "features_v7.4.16": [
    "api/horses-id.js PUT a PATCH — používajú safeWriteToTable pre editáciu koňa (schema-drift tolerantné, zachované audit logging)",
    "api/riders-id.js PUT — to isté pre editáciu jazdca",
    "Kryje aj druhý vektor 500 chýb: predtým POST bol opravený v PR #193, teraz je chránená aj úprava existujúcich záznamov"
  ],
  "features_v7.4.15": [
    "lib/safe-write.js — nový zdieľaný helper safeWriteToTable() pre schema-drift tolerantný INSERT/UPDATE: extrahuje názov chýbajúceho stĺpca z error message, voliteľne ho premapuje (napr. competition_date → date_start) alebo stripne, a retrie",
    "api/competitions.js — refaktorované na použitie shared helpera (predtým inline safeCompetitionWrite)",
    "api/horses.js POST — schema-drift tolerantné (pri 42703 auto-strip unknown column + retry)",
    "api/riders.js POST — rovnaký fix",
    "11 nových unit testov pre safe-write: remap, strip, retries, error propagation"
  ],
  "features_v7.4.14": [
    "Admin api() helper: ak server pošle 'details' pri error responze, toast ich zobrazi spolu s 'error' — predtým user videl iba generic 'Chyba: Server error', teraz vidí aj konkrétnu DB chybu (duplicitný kľúč, neexistujúca tabuľka, atď)",
    "Párový fix s PR #191 ktorý začal posielať details pre competitions POST/PUT 500s"
  ],
  "features_v7.4.13": [
    "KRITICKÝ FIX: POST/PUT /api/competitions — uloženie nových pretekov končilo 500 errorom ak produkčná DB mala legacy schému (napr. chýbajúci competition_date alebo iný stĺpec, ktorý frontend posiela)",
    "safeCompetitionWrite() helper s schema-drift tolerance — auto-extrahuje názov chýbajúceho stĺpca z error message, stripne ho z payloadu a retrie",
    "Special case remapping: ak chýba 'competition_date', automaticky sa premapuje na legacy 'date_start' (podobne end_date → date_end)",
    "Generic: akýkoľvek 42703 'column does not exist' error sa strip & retry až 12×",
    "Teraz admin môže ukladať preteky aj v produkcii s akoukoľvek schémou DB — neznáme stĺpce sa silently zahodia, známe sa zapíšu"
  ],
  "features_v7.4.12": [
    "/api/public/competition-results — rovnaký schema-drift fix ako PR #188: competition_date → date_start fallback, 200 s warning pri chybe (predtým 500 by rozbilo /vysledky stránku ak DB má legacy schému)",
    "Defenzívne aj pri competition_results tabuľke — ak chýba, vráti prázdne pole namiesto 500"
  ],
  "features_v7.4.11": [
    "Evidencia defenzívne: /api/horses, /api/riders, /api/trainers, /api/employees GET majú teraz ORDER_CANDIDATES fallback (name/last_name → created_at)",
    "Pri schema drift (chýbajúci stĺpec, 42703) endpoint skúsi ďalší kandidát namiesto 500",
    "Ak tabuľka chýba (42P01) alebo iná DB chyba → vráti 200 s prázdnym poľom → evidencia sa nerozbije, admin vidí aspoň prázdny zoznam",
    "Zdieľaná helper funkcia lib/safe-list.js — DRY pre defenzívne SELECT * FROM <table>",
    "SJF Register skrytý z admin nav (ID 'sjf-register' zakomentovaný v nav.js — user požiadavka 21.4.2026), Licencie SJF / FEI zostávajú"
  ],
  "features_v7.4.10": [
    "KRITICKÝ FIX: /api/competitions GET zoraďoval podľa 'start_date' — ak tento stĺpec v prod DB neexistuje, admin dostával prázdne pole a NOVÉ PRETEKY SA NEZOBRAZOVALI (user report)",
    "Fix: multi-column fallback — order by competition_date → date_start → start_date → created_at → bez order (posledná šanca)",
    "Public /api/public/competitions: rovnaký fix — ak competition_date column chýba, fallback na date_start s alias",
    "Namiesto 500 pri DB chybe vrátime 200 s prázdnym pole + warning field (stránka sa nerozbije)",
    "Výsledok: aj v prípade schema drift (rôzne verzie tabuľky) admin uvidí preteky"
  ],
  "features_v7.4.9": [
    "PWA manifest: pridané Preteky + Výsledky shortcuts (homescreen quick access)",
    "PWA manifest: theme_color + background_color zladené s cinematic dizajnom (#050811 dark navy)",
    "Kontakt shortcut odstránený (málo používaný), zostali 4 najdôležitejšie: Preteky, Výsledky, 2%, Rezervácia"
  ],
  "features_v7.4.8": [
    "Konzistentná navigácia: 14 public stránok dostalo 'Preteky' + 'Výsledky' linky v main-nav (predtým len homepage)",
    "'Cenník' presunutý do 'Viac' menu aby sa uvolnilo miesto pre športové linky",
    "Stránky aktualizované: 404, clanky, clanok, cookies, impressum, kniznica, o-klube, obchodne-podmienky, prevadzkovy-poriadok, privacy, rezervacia, spolupraca"
  ],
  "features_v7.4.7": [
    "Modal UX polish — auto-focus na prvý input pri otvorení, ESC zatvorí, focus trap (Tab cyklus zostáva v modále), backdrop click zatvorí",
    "Po zatvorení sa focus vráti na element ktorý modal otvoril (accessibility improvement)",
    "Mobile table scrolling — každá .card-body s <table> dostane overflow-x na <900px viewport, min-width 640px, white-space:nowrap v bunkách",
    "Toast má teraz slide-in animáciu (transform + opacity transition)",
    "CSS cursor:help pre [title] elementy, cursor:pointer pre button[title]"
  ],
  "features_v7.4.6": [
    "31 native confirm() volaní migrovaných na showConfirm() modal — všetky delete/remove/skryt operácie v admin",
    "CSS animations: @keyframes loading-pulse (pulsing dots), skeleton-shimmer (skeleton UI placeholder)",
    "Použitie: <p data-loading>Načítavam</p> alebo class 'loading-state' — animované bodky namiesto statického textu"
  ],
  "features_v7.4.5": [
    "showToast: pridaná ikona (✓/✗/⚠/ℹ) podľa typu + 5s dĺžka pre error toasty (čitateľnejšie)",
    "showToast: nový 'info' typ (modrý)",
    "window.showConfirm(msg, options) — pekný modal dialog namiesto natívneho window.confirm() ktorý v dark admin vyzeral zle",
    "showConfirm vracia Promise<boolean> — await-ovateľné: const ok = await showConfirm('Naozaj zmazať?'); if (ok) {...}",
    "Options: { title, okText, cancelText, danger } — danger dá červené OK tlačidlo",
    "ESC zatvorí, focus na OK, cleanup po resolve"
  ],
  "features_v7.4.4": [
    "api() helper v admine: mutation endpointy teraz zobrazujú toast + throw pri chybe (predtým silent fail)",
    "Sieťové chyby (no fetch) → toast 'Sieťová chyba: ...'",
    "Non-2xx response → toast 'Chyba: <error message>'",
    "GET list endpoints stále fail-safe (vrátia []) pre backward compat",
    "Globálne window.addEventListener('unhandledrejection' + 'error') — zobrazí toast pre nezachytené promise rejections (mnohé tlačidlá mali silent fail)",
    "Audit: všetkých 384 onclick handlerov má definíciu (žiadne 'funkcia nie je definovaná')",
    "Audit: všetkých 32 openModal volaní má <div class=\"modal\"> definovaný",
    "Audit: všetkých 10 showSection volaní má <section class=\"section\"> definovaný"
  ],
  "features_v7.4.3": [
    "Admin: odstránený legacy bookingModal — volal saveBooking() ktorá nebola definovaná (mŕtvy kód)",
    "Rezervácie sa pridávajú cez quickBookingModal (calendar.js) alebo cez slot detail",
    "Audit: overených 384 onclick handlerov — všetky majú definície (v admin/index.html alebo admin/*.js)"
  ],
  "features_v7.4.2": [
    "Admin UI: opravené prázdne tlačidlá (46 výskytov) — predtým sa zobrazovali ako 'podlhovasté útvary' bez textu, teraz majú label podľa title atribútu (Upraviť, Zmazať, Detail, ...)",
    "Filter button pri rezerváciách má teraz správny label 'Filtrovať' (predtým prázdny)",
    "Dashboard, zoznamy jazdcov/koní/pretekov/výsledkov — všetky akčné tlačidlá majú viditeľný text"
  ],
  "features_v7.4.1": [
    "Performance: všetky header logá dostali fetchpriority=high + decoding=async (LCP hint), footer logá loading=lazy (7 súborov)",
    "SEO: SoftwareApplication schema pre JKZM Platform na /pre-kluby — pricing offers, featureList, creator",
    "SEO: FAQPage schema s 8 otázkami na /pre-kluby — Google rich results",
    "SEO: BreadcrumbList schema doplnená na /preteky a /vysledky",
    "Accessibility: skip-link pridaný na 404, overenie-emailu, prihlasenie, profil, registracia",
    "Meta description + noindex pre overenie-emailu a profil (aby neindexovali)",
    "Všetky JSON-LD štrukturálne dáta validované"
  ],
  "features_v7.4.0": [
    "Pre-kluby landing page posilnená: Cenník sekcia (Starter 39€ / Professional 89€ / Enterprise dohodou)",
    "FAQ sekcia pre správcov klubov — 8 otázok (setup, GDPR, migrácia dát, podpora, SJF sync, účtovníctvo, vlastníctvo dát)",
    "Kontaktný formulár s B2B kontextom — meno, klub, email, telefón, veľkosť klubu, správa, GDPR súhlas, honeypot anti-spam",
    "Form submit cez /api/contact endpoint (rate-limited, email notifikácia)",
    "Navigácia zjednodušená: Domov · Funkcie · Cenník · FAQ · Kontakt (odstránené linky na klub, aby B2B user nezabúdal prečo je tam)"
  ],
  "features_v7.3.9": [
    "lib/disciplines/ rozdelené na moduly: skoky.js, drezura.js, vsestrannost.js, voltiz.js, zaprahy.js, vytrvalost.js, reining.js, dostihy.js, fei.js, hobby.js, rider-categories.js + index.js",
    "OPRAVA parkúr výšky podľa SJF 2025: ZM-80, Z-100, ZL-110, L-120, S-130, ST-140, T-150, TT-160 cm (predtým boli zlé!)",
    "DREZÚRA stupne: Z/L/S/ST/T (oficiálne SJF kódy, nie DZ/DL atď)",
    "ZÁPRAHY detailne: jednospreh, dvojspreh, tandem, štvorspreh, pony záprah + stupne Z/L/S/T pre každý",
    "DOSTIHY pridané (DAS Závodisko): rovinové, prekážkové, steeplechase, klusácke — s vzdialenosťami",
    "FEI rozšírené: CSI 1-5* + CSIO/CSIY/CSIJ/CSIP/CSICH/CSIAm/CSIYH, CDI drezúra, CCI, CVI, CAI, CEI, Para, CRI reining",
    "Vekové kategórie jazdcov: 8 kategórií (deti, pony, junior, young_rider, senior, amateur, veteran, open) s popismi a age ranges",
    "Admin modal: optgroupy per sanctioning (SJF/FEI/DAS/Hobby), tooltipy nad option-ami, hint s description disciplíny aj úrovne",
    "API /api/disciplines vracia aj grouped + rider_categories",
    "Spolu 30 disciplín vo všetkých 4 sanctioning bodies"
  ],
  "features_v7.3.8": [
    "Disciplíny a úrovne podľa SJF/FEI pravidiel — lib/disciplines.js + GET /api/disciplines",
    "Parkúr (skoky): ZM/Z/ZL/L/S/ST/T/TT + samostatné kategórie pre JŠ (Jazdecká škola) a Pony",
    "Drezúra: DZ/DL/DS/DST/DT + samostatné JŠ a Pony",
    "Ďalšie disciplíny: všestrannosť (CCN1-5*), voltíž (D/C/B/A), záprah, vytrvalosť, reining, hobby",
    "FEI: parkúr (CSI1-5*+CSIO), drezúra (PSG/Inter/GP), eventing, voltíž, driving, endurance, para",
    "Competition modal: disciplína je teraz select, úroveň sa dynamicky načítava podľa disciplíny",
    "Úpravy existujúceho preteku: discipline musí byť nastavený PRED level aby sa správny zoznam načítal"
  ],
  "features_v7.3.7": [
    "Homepage nav: pridane linky 'Preteky' a 'Výsledky' — členovia a verejnosť ich vidia priamo z homepage",
    "Cenník presunutý do 'Viac' menu (kvoli prioritizácii športového obsahu)"
  ],
  "features_v7.3.6": [
    "Unit testy: lib/licenses.js (18 testov) a lib/sjf-reconcile.js (15 testov) cez vitest",
    "Pokryje edge cases: expires_soon boundary, 'neaktívna' obsahuje 'aktív' substring, cross-year dátumy",
    "Regression safety: ak niekto v budúcnosti upraví license heuristiky, testy zachytia nezámerne zmenu"
  ],
  "features_v7.3.5": [
    "Verejná stránka /vysledky — výsledky uplynulých pretekov (posledných 12 mesiacov)",
    "Nový endpoint /api/public/competition-results — public-safe fields iba (meno jazdca, kôň, placement, skóre, prémia)",
    "Tabuľka per pretek: miesto (gold/silver/bronze pre 1/2/3), jazdec, kôň, disciplína, skóre, čas, tresty, prémia",
    "Typ badge pre SJF/FEI/Hobby + dátum, miesto, organizátor",
    "Navigácia: 'Výsledky' link pridaný do /preteky aj /vysledky",
    "Sitemap: /vysledky pridaná (priority 0.8, weekly)"
  ],
  "features_v7.3.4": [
    "Admin dashboard widget 'Nadchádzajúce preteky' — top 8 pretekov od -7 dní, zoradené podľa dátumu",
    "Badge pre typ pretekov (SJF/FEI/Hobby), dátum label: DNES / o N dní / pred Nd",
    "Rýchle akcie: 👥 Prihlášky, 🏆 Výsledky priamo z dashboardu (bez preklikávania na Preteky)",
    "Sitemap XML: pridaná /preteky stránka (priority 0.85, weekly)"
  ],
  "features_v7.3.3": [
    "Verejná stránka /preteky — nadchádzajúce preteky a súťaže pre členov aj verejnosť",
    "Filtre: Nadchádzajúce / Všetky (30 dní dozadu) / SJF / FEI / Hobby",
    "Karty so všetkými public-safe info: názov, typ, dátum, miesto, organizátor, úroveň, status, poznámky",
    "Prepojenie na iCal feed (/calendar.ics) — prihlásenie do kalendára",
    "Cinematic dizajn zhodný s ostatnými public stránkami (/clanky, /o-klube, ...)",
    "Nav link 'Preteky' pridaný do hlavnej navigácie"
  ],
  "features_v7.3.2": [
    "Výsledky pretekov: nový modal '🏆 Výsledky' v zozname pretekov pre správu competition_results",
    "Inline editácia všetkých polí: umiestnenie, skóre, čas (s), trestné body, prémia (€), poznámky",
    "'⚡ Vytvoriť z prihlášok' — hromadne vytvorí prázdne výsledky pre všetkých confirmed/registered jazdcov (po preteku admin doplní umiestnenie)",
    "'+ Pridať výsledok' — vyberie jazdca+koňa z existujúcich prihlášok",
    "Summary bar: počet výsledkov + suma prémií",
    "Fix api/competition-results-id.js: DB používa 'placement' stĺpec, endpoint akceptuje aj legacy 'place' alias + pridaný 'prize_money'"
  ],
  "features_v7.3.1": [
    "SJF scraper: UA rotation pri 403/429 (Mac→Windows→Linux→Safari) — prekoná prípadný per-UA blacklist",
    "fetchHtml pri HTTP 403/429 spúšťa retry s iným User-Agent (predtým padol ihneď)",
    "Error message v sjf_sync_log je teraz konkrétny: 'SJF blokuje HTTP 403 — použi manuálny CSV', 'Rate limit 429 — počkaj 5-10 min', atď. (predtým generic 'Žiadne záznamy')"
  ],
  "features_v7.3.0": [
    "Manuálne SJF párovanie: nové polia riders.sjf_id a horses.sjf_id (TEXT)",
    "Admin UI: 'Prepojenie so SJF registrom' v rider/horse edit modále + 'Hľadať v SJF' tlačidlo",
    "Pairing search modal s live vyhľadávaním cez /api/sjf-persons?search=X (min 2 znaky, 300ms debounce)",
    "Výsledky ukazujú meno, klub, licenčné číslo a stav licencie — klik priradí sjf_id",
    "Reconcile: sjf_id má najvyššiu prioritu matchingu (pred license_number a birth_date) — 100% presné, nezávisí od mena"
  ],
  "features_v7.2.9": [
    "Reconcile SJF → lokálni: dvojkrokový flow s preview dialógom — najprv dry-run, admin vidí zoznam plánovaných zmien, potom apply",
    "Tabuľky v preview ukazujú meno jazdca/koňa + pole zmien (napr. 'SJF platná do → 2026-12-31')",
    "Matching principy v hint-e: sjf_license_number alebo first+last+birth_date pre riders, life_number alebo name+owner_name pre horses",
    "Tlačidlo Aplikovať sa deaktivuje ak žiadne zmeny (totalChanges=0)",
    "Fix: SQL v7.2.8 reset — DATE cast (predtým chyba 'operator does not exist: date = text')"
  ],
  "features_v7.2.8": [
    "SJF Reconciliation: po importe z CSV / cron syncu automaticky prekopíruje status aktívna/neaktívna zo sjf_persons a sjf_horses do lokálnych riders/horses (nastaví sjf_license_valid_until = koniec roka ak aktívna, včera ak neaktívna)",
    "Analogicky pre FEI — z sjf_persons.details->>'fei_status' → riders.fei_license_valid_until",
    "Matching: jazdci podľa first_name+last_name (+ birth_date ak ambiguous), kone podľa name (+ stable_name)",
    "Nové tlačidlo '🔄 Reconcile SJF → lokálni' v SJF Register widgete pre ad-hoc spustenie",
    "Endpoint /api/admin/sjf-sync/reconcile pre manuálny trigger",
    "Predtým: sjf_persons a riders boli disconnected — aj po úspešnom SJF importe sa badges v UI neaktualizovali"
  ],
  "features_v7.2.7_sql": [
    "database-v7.2.7-sjf-unique-constraints.sql — UNIQUE constraint na sjf_persons.sjf_id + sjf_clubs.sjf_id (fix ON CONFLICT upsert error)"
  ],
  "features_v7.2.6": [
    "Fix: týždenný SJF cron (api/cron/sjf-sync.js) predtým zapisoval iba 8 základných stĺpcov (sjf_id, meno, klub, licencia, status), čím silne ochudobňoval data oproti manuálnemu CSV importu (ktorý zapisuje aj birth_date, region, email, phone, disciplines, details JSONB, license_valid_until, ...)",
    "Dôsledok: každý týždenný cron prepisal rich data z manuálneho importu späť na základ — užívatelia videli 'staré údaje' napriek tomu, že cron bežal",
    "Opravené: robustUpsertRow() zapíše celý record z mapPersonRow/mapHorseRow, s fallback stripovaním neznámych stĺpcov (OPTIONAL_COLS) ako robí robustBatchUpsert v manuálnom importe"
  ],
  "features_v7.2.5": [
    "FEI manuálny CSV import — POST /api/admin/fei-import/import-csv?entity=riders|horses",
    "Upload UI v sekcii Licencie SJF/FEI: file input, entity radio (jazdci/kone), preview povolených stĺpcov v detail expand",
    "Flexibilný parser CSV: auto-detekcia delimiteru (, ; TAB), normalizácia hlavičiek, akceptuje ISO aj DD/MM/YYYY dátumy",
    "Matching riders: first_name+last_name | email · Matching horses: name | stable_name | passport_number",
    "Po importe stats panel: aktualizované (zelené) / nespárované (žlté) + expandable zoznamy pre audit",
    "Auto-refresh riders/horses v pamäti + re-render licenčnej tabuľky"
  ],
  "features_v7.2.4": [
    "Dashboard widget: 'Expirujúce SJF/FEI licencie' — top 10 jazdcov a koní s licenciou expirovanou alebo do 30 dní, priamy link na úpravu",
    "Summary badges hore: N expirovaných + N do 30 dní, zoradené od najhoršieho",
    "Nahradil potrebu manuálne prechádzať zoznam licencií — keď dashboard ukazuje ✓, všetci môžu na preteky; keď ukazuje ✗, vidíš presne kto má problém",
    "Prepojené na Licencie SJF/FEI sekciu cez 'Celá evidencia →' link"
  ],
  "features_v7.2.3": [
    "Admin UI: entriesListModal — kompletný prehľad prihlásených na daný pretek s inline editáciou štartovného čísla, stavu platby a prihlášky",
    "License validation badge pri každom zázname (✓/⚠) s tooltipom popisujúcim problém + ⚡ badge pre záznamy s admin override",
    "Štart listina export — /api/exports/competition-entries?competition_id=X → CSV (Excel-friendly, UTF-8 BOM, ; delimiter, zoradené podľa štart. čísla)",
    "Tlačidlo '👥 Prihlášky' pri každom preteku otvorí zoznam s counts (konfirmovaných / zaplatených / s override)",
    "Summary pod tabuľkou ukazuje priebežné počty — okamžite vidno, koľko štartovného je potvrdené"
  ],
  "features_v7.2.2": [
    "Admin UI: entryModal pre prihlasovanie na preteky — výber jazdca + koňa, inline license preview badges, live validation banner",
    "Pri porušení licenčných požiadaviek sa zobrazí červený banner so zoznamom problémov + admin override checkbox (dôvod sa zapíše do notes)",
    "Server 409 LICENSE_INACTIVE sa elegantne spracuje: banner s chybami + override ponuka namiesto generic toast",
    "Tlačidlo '+ Prihláška' v zozname pretekov otvorí modal s preselectnutými hodnotami z preteku (disciplína, štartovné)",
    "Inline zobrazené SJF/FEI badges pri výbere jazdca/koňa (✓/⚠/✗) — okamžitý náhľad pred odoslaním"
  ],
  "features_v7.2.1": [
    "Admin UI: chýbajúci competitionModal — plnohodnotný formulár pre pridanie/úpravu pretekov (názov, miesto, dátum, typ SJF/FEI/hobby, úroveň, disciplína, štartovné, uzávierka, status, poznámky)",
    "Live hint pri výbere typu pretekov upozorní, aké licencie sa budú vyžadovať (SJF / SJF+FEI / žiadne)",
    "Render pretekov v tabuľke — badges pre typ a status, edit/delete akcie, čítanie kompatibilné s legacy aj v6 schémou (competition_date / date_start)",
    "DB migrácia v7.2.1: idempotentné ADD COLUMN IF NOT EXISTS + normalizácia legacy hodnôt competition_type (national/regional→sjf, international→fei, club→hobby)"
  ],
  "features_v7.2.0": [
    "Validácia SJF/FEI licencií pri prihlásení na preteky — POST /api/competition-entries blokuje neaktívne licencie (409 LICENSE_INACTIVE)",
    "Admin override: force:true pre POST competition-entries v krajných prípadoch (dôvod sa zaznačí do notes entry)",
    "lib/licenses.js — zdieľaná kontrola stavu licencie (active/expires_soon/expired/missing) pre jazdca aj koňa",
    "Admin UI Licencie SJF/FEI — explicitné aktívna/neaktívna badges s legendou a tooltip (dni do expirácie / počet dní po)",
    "API responses GET /api/riders a /api/horses obohatené o license_status (sjf + fei)",
    "Tabuľka Jazdci a Kone v admine — badge riadok so stavom SJF a FEI na prvý pohľad",
    "Kontrola požiadaviek preteku: hobby/klubové preteky licencie nepotrebujú, SJF pretekov vyžaduje SJF, FEI vyžaduje SJF+FEI"
  ],
  "features_v7.1.3": [
    "SJF weekly sync — Vercel cron piatok 07:00 Bratislava (scraper evidencia.sjf.sk)",
    "Admin widget: live polling kazdych 4s kym beh bezi, animovany pulse, progress text",
    "Auto-expire stale running rows (> 10 min → failed) v status endpoint",
    "maxDuration 300s pre /api/cron/sjf-sync (Vercel Pro)",
    "Progresivne updaty v sjf_sync_log po kazdom entity type (clubs→persons→horses)",
    "DB: sjf_sync_log, sjf_horses, rozsirene sjf_clubs/persons (UNIQUE idx na sjf_id)",
    "Structured error logging — /api/errors + error_logs tabulka + client reporter",
    "Admin sekcia 'Chybove logy' s top-groups per fingerprint, resolve workflow",
    "Client error-reporter.js na 15 public pages (consent-aware, dedupe, sendBeacon)",
    "RLS hardening na users, admin_users, sjf_sync_log, error_logs (ENABLE, bez FORCE)",
    "Admin responzivny design pre mobil/tablet — hamburger + overlay, tabulky scrollovatelne",
    "Obchodne podmienky hotfix — nezatvoreny HTML komentar skryval cely obsah",
    "Auth UX polish — password confirm + visibility toggle + phone povinny",
    "Admin cinematic light theme + emoji cleanup"
  ],
  "features_v6.74.0": [
    "📜 História klubu: 25 rokov jazdectva (od 2000 ako JK AXA, od 2021 ako JK Zelená míľa)",
    "Nová timeline sekcia na homepage s 3 míľnikmi (2000 · 2021 · Dnes)",
    "Metriky: pridaný '25 rokov skúseností' (replace '1 aréna')",
    "Hero lead: zmienka o 25 rokoch tradície + predošlom názve JK AXA",
    "Navigácia: pridaný link 'História' na homepage"
  ],
  "features_v6.73.0": [
    "📅 Compliance Alerts — agregované expiračné upozornenia z admin_users, trainers, riders, horses, vaccinations",
    "Severity-triedené: expired (🔴) / urgent ≤14d (🟠) / soon ≤60d (🟡) / watch ≤180d (🔵)",
    "Admin → Compliance → 'Všetky expirácie (180 dní)' widget — filter chips + detail table",
    "API: GET /api/admin/compliance/alerts?window_days=180&severity=urgent",
    "/pre-kluby: nová sekcia 'Legislatívne rámce' (SJF, ŠVPS, BOZP, GDPR, dane, audit)",
    "/pre-kluby: transparency banner 'V aktívnom vývoji'",
    "/pre-kluby: feature card Compliance Alerts + navigácia Legislatíva"
  ],
  "features_v6.72.0": [
    "🎬 Cinematic dizajn rozšírený na VŠETKY public stránky (bol iba na /)",
    "Nový /css/cinematic.css — shared design system, všetky stránky ho importujú",
    "/o-klube kompletne prepísaná na cinematic — 2% info karty, QR, 3-step postup, downloads",
    "/pre-kluby kompletne prepísaná — 10 feature kariet (+ AI Generátor s NEW badge)",
    "/404 kompletne prepísaná — 'Zaskočili sme si mimo dráhy' hero",
    "/clanky, /clanok, /privacy, /cookies — pridaný cinematic.css (bude sa aplikovať nad starým)",
    "/partials/header.html + footer.html — tiež cinematic (pre stránky čo ich používajú cez layout.js)"
  ],
  "features_v6.71.0": [
    "🎬 CINEMATIC REDESIGN homepage — dark navy #050811 + gold + Inter display + Fraunces italic",
    "Hero full-viewport, animovaný gradient mesh background, scroll indicator",
    "Metrics strip: 15 boxov, 2 SJF tréneri, 26 aktívnych členov, 1 aréna",
    "3 služby: Drezúra, Parkúr, Jazdecký krúžok (zjednodušené na reálny rozsah)",
    "Filozofia sekcia — Fraunces italic citácia (luxury feel)",
    "3 piliere — showcase s veľkými číslami",
    "Kontakt sekcia s Google Maps + plnými firemnými údajmi (IČO, IBAN, NCRpo, ...)",
    "SEO: JSON-LD SportsClub, OG + Twitter tagy, canonical, meta keywords",
    "/preview zostáva ako design lab pre ďalšie iterácie"
  ],
  "features_v6.70.1": [
    "🔧 Fix: AI system prompt rozšírený o SJF/FEI technické štandardy",
    "Presné vzdialenosti medzi prekážkami: bounce 3.5-4m, 1-stride 7-7.5m, 2-strides 10-10.5m, ...",
    "Rozstupy kladín: trot 1.2-1.4m, canter 2.7-3m",
    "Drezúrny obdĺžnik 20×40/20×60, písmená A-M-C",
    "Výšky SJF tried: L≤90, E≤105, S≤120, T≤135",
    "AI inštrukcia: ak NEVIE presné číslo, nepíše žiadne (bez halucinácie)",
    "UI: upozornenie 'tréner skontroluj' pri AI výstupe"
  ],
  "features": [
    "🤖 AI Generátor tréningov — admin nástroj ktorý navrhne tréning podľa disciplíny, úrovne, cieľa",
    "8 disciplín: drezúra, parkúr, prijazdovanie, military, reining, vytrvalosť, voltíž, kondícia",
    "Rule-based generator (knižnica ~100 cvičení, žiadne náklady) + AI režim (Claude Haiku)",
    "AI zohľadní vybraného koňa (vek, plemeno, úroveň) + jazdca + posledných 5 tréningov",
    "Štruktúrovaný plán: warmup (20%) → main (65%) → cooldown (15%), každé cvičenie s dĺžkou a popisom",
    "Rate limit 30 AI generovaní / admin / hodina, fallback na rules ak AI zlyhá",
    "Admin → Tréningy → 🤖 AI Generátor (nová sekcia)",
    "Tlačiteľný výstup pre trénerov",
    "/pre-kluby — pridaná feature card pre AI Generátor (NEW badge)"
  ],
  "changelog": {
    "6.70.0": "🤖 AI Generátor tréningov (Claude Haiku + rule-based knižnica cvičení)",
    "6.69.0": "Landing page /pre-kluby — predajný asset pre JKZM Platform softvér",
    "6.68.1": "LGCT paleta + Montserrat rozšírený naprieč všetkými stránkami (6 HTML súborov)",
    "6.68.0": "LGCT-inšpirovaný dizajn: dark navy + gold + Montserrat, minimalist premium",
    "6.67.0": "Revert v6.66 + príprava na LGCT-inšpirovaný dizajn",
    "6.66.1": "[REVERTED] Inline hero color fix",
    "6.66.0": "[REVERTED] Elegantný dizajn — nefungoval podľa očakávania",
    "6.65.0": "Rescue Recent Activity widget — dashboard 'Posledná aktivita' konečne funguje",
    "6.64.6": "Precízny fix public/horses — reálna schéma DB",
    "6.64.5": "Precízny fix public/trainers — reálna schéma DB (status + specializations plural)",
    "6.64.4": "Fix public/trainers + public/horses (schema drift: first_name, last_name v kóde nie v DB)",
    "6.64.3": "Rescue loadWebStatus widgetu — Status verejného webu už ukazuje reálne počty",
    "6.64.2": "Rescue login-history + analytics widgetov (boli v dead app.js), cleanup",
    "6.64.1": "CSP enforce + fix dead booking code JS errorov na homepage",
    "6.64.0": "🛡️ CSP header v Report-Only móde (krok 1/2, potom enforcing)",
    "6.63.0": "Sortovateľné stĺpce v admin tabuľkách (klik na th, auto-detekcia typu, sk-SK locale)",
    "6.62.1": "🚨 HOTFIX: self-test widget do samostatného modulu (app.js sa neloaduje)",
    "6.62.0": "Self-test endpoint + admin widget — preventívny healthcheck pre schema drift",
    "6.61.3": "Schema audit: fix dashboard-stats contacts→contact_messages + SCHEMA-AUDIT.md",
    "6.61.2": "🚨 CRITICAL: auth dopytovalo neexistujúcu tabuľku 'users' namiesto 'admin_users'",
    "6.61.1": "🚨 HOTFIX: admin login-loop — fail-soft 401 handler",
    "6.61.0": "Admin analytics — 4 sparkline charty aktivity za 30 dní (pure SVG)",
    "6.60.0": "Admin inline table filter — client-side filtrovanie (Články, Novinky, Stránky, Dokumenty)",
    "6.59.0": "Dark mode toggle (🌙/☀️) — kompletný dual theme s OS preferenciou",
    "6.58.0": "Copy-to-clipboard pre 2% údaje + print CSS pre /o-klube",
    "6.57.0": "Pro polish — security.txt, humans.txt, vylepšený 404 page",
    "6.56.0": "iCalendar feed súťaží (/calendar.ics) — subscribe v Google/Apple/Outlook",
    "6.55.0": "Admin keyboard shortcuts + help modal (? / g X / n / Esc / Cmd+S)",
    "6.54.0": "Režim údržby (maintenance mode banner) + Systém tab v admin settings",
    "6.53.0": "Login audit trail — login_events tabuľka + dashboard widget s 24h stats",
    "6.52.0": "Admin change password UI + API (anti brute-force, strong password validation)",
    "6.51.0": "SEO rich results — JSON-LD Article/CollectionPage/BreadcrumbList na /clanok a /clanky",
    "6.50.0": "Cleanup orphan imports + 125 endpointov na getSupabase singleton",
    "6.49.0": "Centralizácia verifyToken — 109 endpointov používa lib/auth.js verifyTokenFromReq",
    "6.48.0": "🚨 CRITICAL: auth guard na 30 mutation endpointoch",
    "6.47.0": "Audit security fixes: competitions auth + mass assignment + hardcoded creds",
    "6.46.0": "Design zest — väčšie logo, animovaný hero, gradient buttons/titles",
    "6.45.0": "Article page: reading time estimate + social share buttons",
    "6.44.0": "Dynamický sitemap.xml s article URLs z DB",
    "6.43.0": "Globálny search widget naprieč celou stránkou",
    "6.42.0": "Security headers + /clanky listing page",
    "6.41.0": "Public full-text search — tsvector + search modal",
    "6.40.0": "Zod input validation pre public POST endpointy",
    "6.39.0": "RSS feed + accessibility polish",
    "6.38.0": "Homepage #booking rework — CTA na /rezervacia + email notifikácia",
    "6.37.0": "Udalosti/Súťaže verejná sekcia + ROADMAP dokumentácia",
    "6.36.0": "Performance polish (lazy images, preconnect) + PWA manifest",
    "6.35.0": "Vitest unit testy pre lib/* (35 testov, CI integrated)",
    "6.34.0": "Email notifikácie cez Resend pre nové kontaktné správy",
    "6.33.0": "Recent activity feed na dashboarde + quick action Nový partner",
    "6.32.0": "Admin dashboard polish + anti-spam pre kontakt formulár",
    "6.31.0": "Hotfix admin sekcie + GitHub Actions CI",
    "6.30.1": "Core fix: admin nav click teraz správne načítava dáta sekcie",
    "6.30.0": "Admin Novinky CRUD + fix loadArticles error visibility",
    "6.29.0": "Toggle + edit verejných sekcií Tréneri/Kone (default vypnuté)",
    "6.28.0": "Verejná stránka článku — fix broken /api/articles fetch",
    "6.27.0": "Verejný cenník + deprecated header pre legacy database.sql",
    "6.26.0": "Verejné profily trénerov a koní na homepage",
    "6.25.0": "SEO polish — OG/JSON-LD + share buttons pre 2% kampaň",
    "6.24.1": "Urgent fix: odstránený neoficiálny PDF generátor",
    "6.24.0": "PDF tlačivo 2% dane + CORS migrácia 128 endpointov",
    "6.23.0": "Security hardening — no fallback secret, login rate limit",
    "6.22.0": "Modern redesign + auth-login hardening + lib/ shared utilities"
  }
}
