chore: příprava release v1.0.0

- CLAUDE.md: přidány Gitea API credentials a UTF-8 poznámka
- .claude/settings.json: odebrán code-review plugin
- sql/migrate_encrypt_totp_secrets.php: smazán (migrace již proběhla)
- reports/: přidány pracovní reporty z 2026-03-12 a 2026-03-13
- dist: aktualizovány vendor a rate_limits

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-17 14:14:26 +01:00
parent 5550358b15
commit 870d982752
7 changed files with 84 additions and 40 deletions

View File

@@ -1,6 +1,5 @@
{ {
"enabledPlugins": { "enabledPlugins": {
"frontend-design@claude-plugins-official": true, "frontend-design@claude-plugins-official": true
"code-review@claude-plugins-official": true
} }
} }

View File

@@ -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` - **npm:** při instalaci balíčků vždy `--legacy-peer-deps`
- **Git remote:** https://git.boha-automation.cz/boha_admin/app.git - **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 - **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`
--- ---

View File

@@ -1 +1 @@
{"window_start":1773407459,"count":1} {"window_start":1773428518,"count":1}

View File

@@ -3,7 +3,7 @@
'name' => 'boha/website', 'name' => 'boha/website',
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => '4c8a41c1072f825e78f3a6381a0e2c27e90b7382', 'reference' => '913344b8c4b6c649ae10322feea261e9a1b56c01',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@@ -13,7 +13,7 @@
'boha/website' => array( 'boha/website' => array(
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => '4c8a41c1072f825e78f3a6381a0e2c27e90b7382', 'reference' => '913344b8c4b6c649ae10322feea261e9a1b56c01',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),

58
reports/2026-03-12.md Normal file
View File

@@ -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ů)

19
reports/2026-03-13.md Normal file
View File

@@ -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 `<a>` element
- Pridano error handling s `alert.error()`
## Nalezene problemy
- Zadne
## Stav
- ESLint: PASS
- PHPCS: PASS
- Build: PASS
- Git: commitnuto a pushnuto (019a835)

View File

@@ -1,35 +0,0 @@
<?php
/**
* Jednorázová migrace: zašifruje existující TOTP secrets v DB.
*
* Spuštění: php sql/migrate_encrypt_totp_secrets.php
* Vyžaduje TOTP_ENCRYPTION_KEY v .env
*/
declare(strict_types=1);
require_once __DIR__ . '/../api/config.php';
require_once __DIR__ . '/../api/includes/Encryption.php';
$pdo = db();
$stmt = $pdo->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";