diff --git a/.claude/settings.json b/.claude/settings.json index b82dbf1..9030888 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,6 +1,5 @@ { "enabledPlugins": { - "frontend-design@claude-plugins-official": true, - "code-review@claude-plugins-official": true + "frontend-design@claude-plugins-official": true } } diff --git a/CLAUDE.md b/CLAUDE.md index b4f2cbc..3b1ba93 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,6 +24,9 @@ Před začátkem práce si načti relevantní soubory z `memory/`: - **npm:** při instalaci balíčků vždy `--legacy-peer-deps` - **Git remote:** https://git.boha-automation.cz/boha_admin/app.git - **Git credentials:** uloženy v `~/.git-credentials` (credential.helper=store), push funguje bez zadávání hesla +- **Gitea API token:** `8539cea57be2e251b15c0fa973dac8e231e15259` (pro issues, releases atd.) +- **Gitea API:** `https://git.boha-automation.cz/api/v1/repos/boha_admin/app/` +- **Gitea API a UTF-8:** `curl` na Windows nepřenáší českou diakritiku správně - pro API volání s českým textem použij `node -e` s `https` modulem a `Content-Type: application/json; charset=utf-8` --- diff --git a/dist/api/rate_limits/95bc5d544df53a813f55a3a2ae270497.json b/dist/api/rate_limits/95bc5d544df53a813f55a3a2ae270497.json index 16caf9f..2ed578e 100644 --- a/dist/api/rate_limits/95bc5d544df53a813f55a3a2ae270497.json +++ b/dist/api/rate_limits/95bc5d544df53a813f55a3a2ae270497.json @@ -1 +1 @@ -{"window_start":1773407459,"count":1} \ No newline at end of file +{"window_start":1773428518,"count":1} \ No newline at end of file diff --git a/dist/vendor/composer/installed.php b/dist/vendor/composer/installed.php index ededa85..b43f6fd 100644 --- a/dist/vendor/composer/installed.php +++ b/dist/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'boha/website', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '4c8a41c1072f825e78f3a6381a0e2c27e90b7382', + 'reference' => '913344b8c4b6c649ae10322feea261e9a1b56c01', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ 'boha/website' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '4c8a41c1072f825e78f3a6381a0e2c27e90b7382', + 'reference' => '913344b8c4b6c649ae10322feea261e9a1b56c01', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/reports/2026-03-12.md b/reports/2026-03-12.md new file mode 100644 index 0000000..9b64c0a --- /dev/null +++ b/reports/2026-03-12.md @@ -0,0 +1,58 @@ +# Report 2026-03-12 + +## Zadání +Implementovat upgrade plan P1-P7 (15 položek) - optimalizace výkonu, udržovatelnosti a UX. + +## Provedené změny + +### P1 - Quick wins +- **useDebounce hook** (300ms) integrován do useListData - eliminuje API call na každý keystroke +- **DB indexy** - migrace 001_add_indexes.sql (attendance, invoices, quotations, refresh_tokens, audit_log) +- **TCPDF odstraněn** z composer.json (nepoužívaná závislost) +- **Vite build plugin** opraven pro graceful handling bez composer v PATH + +### P2 - Stránkování +- **PaginationHelper.php** - DRY backend pagination (parseParams + paginate) +- **Pagination.jsx** - frontend komponenta (prev/next/čísla stránek/info) +- **CSS** - .admin-pagination styly +- Backend handlery refaktorovány: offers, orders, invoices, projects (default 25/stránku) +- useListData rozšířen o page/perPage/pagination + +### P3 - Dekompozice velkých komponent +- **Dashboard.jsx** (1346 → 378 LOC): 6 subkomponent + dashboardHelpers.js +- **OfferDetail.jsx** (1061 → ~530 LOC): useOfferForm hook + OfferCustomerPicker +- **AttendanceAdmin.jsx** (1036 → ~275 LOC): useAttendanceAdmin hook + AttendanceShiftTable + +### P4 - Backend kvalita +- **SELECT * fix** - 69+ výskytů ve 22 souborech nahrazeno explicitními sloupci + - users-handlers.php: password_hash explicitně vyloučen +- **Overdue konsolidace** - přesunuto do invoices.php routeru (1x místo 3x) +- **Validator.php** - validační helper (required, string, int, email, in, numeric) +- **PaginationHelper** - PHPStan typy opraveny + +### P5 - UX polish +- **NotFound.jsx** - 404 stránka místo redirectu na / +- **ErrorBoundary** - CSS třídy, DEV error stack, odkaz na Dashboard +- **useFocusTrap hook** - Tab cycling, auto-focus, restore focus +- **ConfirmModal** - focus trap integrován + +### P6 - Operační viditelnost +- **audit-log.php** - API endpoint s filtrováním a stránkováním +- **AuditLog.jsx** - stránka s tabulkou, filtry, skeleton loading +- **Sidebar** - položka "Audit log" (settings.audit permission) +- **cleanup.php** - CLI script (rate limits >24h, audit log >90 dní) + +### P7 - FormField komponenta +- **FormField.jsx** - wrapper pro label + input + error pattern (aria-invalid) +- **Vehicles.jsx** migrováno jako demonstrace + +## Nalezené problémy +- Composer není v PATH na tomto stroji → `composer remove` a `composer update` je třeba spustit ručně +- DB migrace (001, 002) je třeba spustit ručně na databázi + +## Stav +- ESLint: PASS (0 errors, 0 warnings) +- PHPCS: PASS (0 errors, 0 warnings on line length) +- Build: PASS (2155 modules, 2.63s) +- PHPStan: PASS (0 errors) +- Git: commitnuto a pushnuto (7 commitů) diff --git a/reports/2026-03-13.md b/reports/2026-03-13.md new file mode 100644 index 0000000..e2420e6 --- /dev/null +++ b/reports/2026-03-13.md @@ -0,0 +1,19 @@ +# Report 2026-03-13 + +## Zadani +- Nefungovalo stahovani souboru ve filemanageru projektu - vracelo `{"success":false,"error":"Access token required"}` + +## Provedene zmeny +- **src/admin/components/ProjectFileManager.jsx** - prepsan `handleDownload`: + - Puvodni implementace pouzivala `window.open()`, ktery otevrel novou zalosku bez JWT Authorization headeru + - Novy kod stahuje soubor pres `apiFetch()` (s automatickym JWT tokenem), vytvori blob URL a spusti stahovani pres docasny `` element + - Pridano error handling s `alert.error()` + +## Nalezene problemy +- Zadne + +## Stav +- ESLint: PASS +- PHPCS: PASS +- Build: PASS +- Git: commitnuto a pushnuto (019a835) diff --git a/sql/migrate_encrypt_totp_secrets.php b/sql/migrate_encrypt_totp_secrets.php deleted file mode 100644 index 4756378..0000000 --- a/sql/migrate_encrypt_totp_secrets.php +++ /dev/null @@ -1,35 +0,0 @@ -query('SELECT id, totp_secret FROM users WHERE totp_secret IS NOT NULL'); -$users = $stmt->fetchAll(); - -$migrated = 0; -$skipped = 0; - -foreach ($users as $user) { - if (Encryption::isEncrypted($user['totp_secret'])) { - $skipped++; - continue; - } - - $encrypted = Encryption::encrypt($user['totp_secret']); - $update = $pdo->prepare('UPDATE users SET totp_secret = ? WHERE id = ?'); - $update->execute([$encrypted, $user['id']]); - $migrated++; -} - -echo "Migrace dokoncena: {$migrated} zasifrovano, {$skipped} preskoceno (jiz sifrovane).\n";