Files
xamxam/todo/03-system-cache.md
Pontoporeia b981223ff4 admin/system: fetch()-based tab switching, no full-page reload
Add system-fragment.php — a thin authenticated endpoint that returns only
the tab-panel HTML (toolbar + meta + log/nginx-config output) for a given
?tab=&n= combination. No page shell, no status section, no DB queries.

system.php changes:
- Tab <a> elements gain data-tab= attributes used by JS to identify the
  target without parsing hrefs.
- Tab panel content wrapped in <div id=sys-tab-panel data-tab= data-n=>
  which JS uses as both the swap target and its own state store.
- JS rewritten: tab clicks and lines-select changes call loadPanel()
  which fetch()es system-fragment.php, swaps innerHTML, updates active
  tab ARIA attributes, and pushes state via history.pushState.
- Browser back/forward handled via popstate listener.
- bindPanelControls() re-wires the lines-select and copy-to-clipboard
  button after every innerHTML swap (event delegation not feasible here
  because log-output is replaced wholesale).
- fetch() failure falls back to window.location.href (full page load).
- Tabs without JS still work: <a href> links go to system.php?tab=…
  as before.

system-fragment.php:
- Requires AdminAuth::isAuthenticated(); returns 403 on failure.
- Validates tab and n params against the same whitelist as system.php.
- All helper functions namespaced with frag_ prefix to avoid redeclaration
  if PHP ever includes both files in the same process.
- Renders identical HTML to the corresponding section in system.php.

system.css:
- #sys-tab-panel gets min-height:8rem and position:relative to prevent
  layout jump during fetch.
- .sys-panel-loading: opacity 0.4 + pointer-events:none + subtle
  diagonal-stripe ::after overlay with shimmer animation.
2026-04-06 15:32:41 +02:00

34 lines
2.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# System Page Caching - Database-Backed Status Cache
## Problem
The admin system page (`/admin/system.php`) runs expensive operations on every load:
- `systemctl` subprocess calls (~4 checks × ~100ms each)
- `curl` HTTP self-check (~200-500ms)
- `disk_total_space()`/`disk_free_space()` (fast but unnecessary per-request)
- Log file `tail` + `filesize` + `filemtime` (I/O bound)
- Nginx config file reading
## Solution: `system_cache` table + background refresh
- [x] **Add `system_cache` table** to schema: `CREATE TABLE system_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at INTEGER NOT NULL)`
- [x] **Add migration** `storage/migrations/007_system_cache.sql`
- [x] **Add `SystemCache` class** (`src/SystemCache.php`) with methods:
- `get(string $key, int $maxAgeSec = 60): ?array`
- `set(string $key, array $data): void`
- `isStale(string $key, int $maxAgeSec = 60): bool`
- [x] **Refactor `system.php` status section**:
1. Check `SystemCache::get('system_status', 120)` — 2-minute TTL
2. If cache hit → render from cache, show “mis en cache il y a X sec” label
3. If cache miss → run checks, store in cache, render
4. Add `?refresh=1` GET param to force-bypass cache
- [x] **Refactor `system.php` log sections** — avoid re-reading on every tab switch; only read the active tabs log
- [x] **Cache disk info** separately with 5-minute TTL: `SystemCache::get('disk_info', 300)`
- [x] **Cache PHP info** separately with 1-hour TTL: `SystemCache::get('php_info', 3600)`
## Notes
- Log caching deliberately omitted: `tail` output is inherently real-time and caching even 30s would show stale data during the moments it matters most (deploys, errors). The existing tab guard already ensures only the active log file is read.
- nginx config could be cached but `file()` on a small static config file is negligible; not worth the added complexity.
- [x] Log tab switching and line-count changes now use `fetch()` via `system-fragment.php`; no full page reload on tab switch.