Changes made from the TEKMidian project session while registering TEKMidian in the ops dashboard.
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(() => []),
]);
```
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"
}
```
APP_VERSION from v15-20260225 to v16-20260226index.html: app.js?v=15 to app.js?v=16/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=16sudo — file is owned by uid 501 (macOS user via scp)./static:/app/static)