# 0027 - 2026-02-26 - Dynamic Backup Buttons & TEKMidian Registration ## Context Changes made from the TEKMidian project session while registering TEKMidian in the ops dashboard. ## Changes ### 1. Dynamic "Create Backup" Buttons (app.js) **Problem:** The "Create Backup" buttons on the Backups page were hardcoded to only `mdf` and `seriousletter`: ```javascript for (const p of ['mdf', 'seriousletter']) { for (const e of ['dev', 'int', 'prod']) { ``` **Fix:** Made buttons dynamic from the `/api/schedule/` endpoint. Now all backup-enabled projects get buttons automatically based on their configured environments: ```javascript for (const s of (cachedSchedules || [])) { if (!s.enabled) continue; const envs = s.backup_environments || s.environments || []; // render button per environment } ``` Also added schedule data fetch in `renderBackups()` alongside the existing backup/offsite fetches: ```javascript const [local, offsite, schedules] = await Promise.all([ api('/api/backups/'), api('/api/backups/offsite').catch(() => []), cachedSchedules ? Promise.resolve(cachedSchedules) : api('/api/schedule/').catch(() => []), ]); ``` ### 2. Empty-State Project Cards (app.js) **Problem:** Projects with backup config but no backups yet didn't appear in the project cards grid (only projects with existing backup files showed up). **Fix:** After the existing project cards loop, added a second loop over `cachedSchedules` to show backup-configured projects that have 0 backups as dashed-border cards: ```javascript for (const s of (cachedSchedules || [])) { if (!s.enabled || projects[s.project]) continue; // render dashed card with "0 backups" and "No backups yet" } ``` ### 3. Cache Busting - Bumped `APP_VERSION` from `v15-20260225` to `v16-20260226` - Updated `index.html`: `app.js?v=15` to `app.js?v=16` ## Files Modified (on server) - `/opt/data/ops-dashboard/static/js/app.js` — dynamic backup buttons, schedule fetch, empty-state cards, version bump - `/opt/data/ops-dashboard/static/index.html` — cache bust `?v=16` ## Notes - Edits require `sudo` — file is owned by uid 501 (macOS user via scp) - No container restart needed — static files are bind-mounted (`./static:/app/static`) - First TEKMidian backup triggered via schedule API (926K tar.gz)