Add a TTL-based cache for the expensive checks on the admin system page,
eliminating repeated systemctl subprocess calls (~4×~100ms), curl self-pings
(~200-500ms), disk_*_space() and PHP ini reads on every page load.
Changes:
- storage/migrations/007_system_cache.sql: new migration creating the
system_cache table (key TEXT PK, value TEXT, updated_at INTEGER)
- storage/schema.sql: system_cache table added before pages table
- Applied migration to live storage/posterg.db
- src/SystemCache.php: new class with get/set/isStale/ageSeconds/invalidate;
uses SQLite INSERT … ON CONFLICT upsert; no external dependencies
- src/Database.php: added getDatabasePath(): string accessor
- public/admin/system.php:
- Bootstrap SystemCache at request start using the existing DB PDO handle
- system_status: cached with 2-min TTL (systemctl + curl checks)
- php_info: cached with 1-hour TTL (PHP ini values are runtime-constant)
- disk_info: cached with 5-min TTL (total/free/used/pct tuple)
- Logs section: unchanged — always reads live log tail per active tab
- ?refresh=1 GET param invalidates all three cache keys before rendering
- Status panel heading shows cache badge: '⚡ Cache — il y a Xs' (hit)
or '⟳ Actualisé' (miss/fresh), styled via new .sys-cache-badge rules
- public/assets/css/system.css: .sys-cache-badge / --hit / --miss styles
- Add idx_theses_pub_year composite index on theses(is_published, year DESC) to
schema.sql; replaces the need for the query planner to pick between the two
separate idx_theses_published / idx_theses_year indexes and sort with a temp
B-tree. Every public query filters on is_published=1 and orders/filters by year,
so this covering index eliminates the sort pass for those queries.
- Create storage/migrations/006_add_composite_index.sql and apply to both
posterg.db and test.db.
- Fix storage/migrations/005_add_banner.sql: the view recreation in that file
still referenced the pre-migration-001 table/column names (thesis_keywords,
keywords.keyword). Updated to use thesis_tags / tags tg to match the canonical
schema.sql. The live DB was unaffected (migration 001 ran before 005), but the
file was misleading and would fail if ever re-run from scratch.