Task 94 — Backup & SLO panel
Phase: 7
Initiative: 48
Status: done
Owner: —
Slug: web-backup-slo-panel
Goal
BackupController (task_063) и SloController (task_064) — критичные операционные эндпойнты: ручной backup, восстановление из архива, листинг архивов, SLO-определения и текущий burn rate. Web не использует ни один из них. Нужна страница, которая даёт оператору возможность одной кнопкой сделать backup и видеть здоровье SLO.
Acceptance criteria
Sub-tasks
src/lib/api.ts— добавить Backup + SLO методы:listBackups,createBackup,restoreBackup,verifyBackup,deleteBackup,getSloSummary,getSloDefinition,getSloStatus,getSloReport,ackSloViolation,ackAllSloViolations- DTO под реальный wire-формат:
BackupSummaryDto(id, filename, created_at, size_bytes, encrypted, key_fingerprint, components, files_count),BackupResultDto(BackupId, ArchivePath, SizeBytes, UncompressedBytes, FilesCount, Encrypted, KeyFingerprint, Duration, Warnings),RestoreResultDto(BackupId, Success, FilesRestored, FilesSkipped, Errors, Warnings, Duration),VerifyResultDto(BackupId, Valid, Encrypted, KeyFingerprint, FileHashesValid, FileHashesInvalid, Warnings, Duration),SloSummaryDto(Timestamp, Verticals, TotalVerticals, OkCount, WarningCount, CriticalCount),SloDefinitionDto(Vertical, Description, Version, AvailabilityTarget, ResponseTimeTargetMs, DataLossTargetPerDay, RecoveryTimeTargetMinutes, CostTargetUsd, AlertThresholds, Runbooks),SloStatusDto(Vertical, OverallSeverity, Timestamp, Objectives, RecentViolations, IsAcknowledged, AcknowledgedBy, AcknowledgedAt),SloObjectiveStatusDto,SloViolationRecordDto,SloReportDto,SloComplianceSummaryDto src/components/BackupPanel.astro— таблица архивов (id, createdAt, size, encrypted badge, components pills, filesCount); кнопка «Create backup» (с optional passphrase-input); кнопки «Verify», «Restore» (passphrase-input + confirm), «Delete» per-rowsrc/components/SloPanel.astro— список verticals (severity pills, objectives progress bar target vs current, violations summary, ack-кнопки); детальный view per vertical (definition targets, runbooks preview)- Новая страница
src/pages/ops.astro— обе панели на одном layout - Add navigation entry в
Layout.astro(active?: "ops") src/hercules-web/README.md— обновитьnpm run build— exit 0npx astro check— 0 errors/warnings в новых файлах- Manual smoke: build artefacts проверены; страница /ops рендерится с активной nav-link; bundle’ы
BackupPanel.*.js(7.6KB) иSloPanel.*.js(11.4KB) присутствуют вdist/_astro/
Implementation notes
Round 1 (this tick) — completed
Backup & SLO панель для новой страницы src/pages/ops.astro (Phase 7 task_094).
API (src/lib/api.ts) — добавлены 11 методов и 15 DTO:
Backup:
listBackups()→GET /api/backups→BackupSummaryDto[]createBackup(passphrase?)→POST /api/backups→BackupResultDtorestoreBackup(id, passphrase?, targetDir?)→POST /api/backups/{id}/restore→RestoreResultDtoverifyBackup(id, passphrase?)→GET /api/backups/{id}/verify?passphrase=…→VerifyResultDtodeleteBackup(id)→DELETE /api/backups/{id}→ 204
SLO:
getSloSummary()→GET /api/slos→SloSummaryDtogetSloDefinition(vertical)→GET /api/slos/{vertical}/definition→SloDefinitionDtogetSloStatus(vertical)→GET /api/slos/{vertical}→SloStatusDtogetSloReport(vertical)→GET /api/slos/{vertical}/report→SloReportDtoackSloViolation(vertical, violationId, by?)→POST /api/slos/{vertical}/ack/{violationId}?acknowledgedBy=…ackAllSloViolations(vertical, by?)→POST /api/slos/{vertical}/ack?acknowledgedBy=…
Расхождение DTO со spec’ом:
Спека перечисляла BackupEntryDto (id, createdAt, sizeBytes, kind: full|incremental, label, sha256, encrypted) и SloDefinitionDto (id, name, target, windowDays, errorBudgetMinutes). Реальный wire-формат использует разные поля. kind: full|incremental — backend не имеет incremental-бэкапов (все full). label и sha256 — отсутствуют в BackupSummary (filename + size_bytes + components + files_count). SloDefinition использует vertical/description/availabilityTarget/responseTimeTargetMs/… (per-objective, не per-window errorBudgetMinutes). DTO в api.ts зеркалит реальный wire-формат, чтобы избежать полей-призраков; в комментариях отмечено расхождение.
BackupPanel (src/components/BackupPanel.astro) — новый:
- Header: title, last-updated, auto-refresh чекбокс (15s, opt-in), refresh button.
- «Create backup» форма: optional passphrase input + submit. После успеха —
showOkс backup id / size / files / duration. - Таблица архивов: id (mono, trunc до 14rem filename), createdAt (локально), size (KB/MB/GB), files_count, components pills (config/skills/memory/sqlite/identity, line-through если false), encryption pill (encrypted/plain) + key_fingerprint, action buttons (Verify / Restore / Delete).
- Inline restore-modal: passphrase (опц.), targetDir (опц.), confirm-чекбокс («понимаю, что перезапишет») — submit enabled только при подтверждении. ESC и клик по фону закрывают.
verify→ successshowOkили errorshowErrorс invalid hashes;delete—window.confirm, потомDELETE /api/backups/{id}.- TimeSpan
Durationпарсится из ISO 8601 (/^PT...S$/) и форматируется как ms/s/m.
SloPanel (src/components/SloPanel.astro) — новый:
- Header: title, last-updated, auto-refresh чекбокс (30s, opt-in), refresh.
- Summary grid: 4 карточки (total / ok / warning / critical) с severity-pill.
- Per-vertical card: severity pill, timestamp, ack-by badge; objectives grid (progress bar targetAchievementPct, severity-coloured bar emerald/amber/rose); recent violations (severity + objective + violationId + breachDescription + detected/resolved/ack);
<details>с definition targets (avail/P95/loss/recovery/cost/version); compliance summary (windowDays + availability/P95/overall/dataLossTotal/maxRecovery/totalCost). - «Ack all violations» появляется если есть un-acked; per-row «Ack» у каждой violation.
- Definition + report подгружаются параллельно с
Promise.allper vertical; частичные сбои swallow (status — must-have). - Auto-refresh каждые 30s, opt-in (как у соседних panels).
Страница (src/pages/ops.astro):
<BackupPanel />сверху,<SloPanel />снизу, gap-8.- Использует
<Layout active="ops">.
Layout (src/layouts/Layout.astro):
- Добавлен
"ops"в unionactive; nav-linkOps → /ops(после Observability, перед A2A).
README (src/hercules-web/README.md):
- В «Структура» добавлены
BackupPanel.astro,SloPanel.astro,ops.astro. - В «Backend API» добавлены 10 эндпоинтов (5 backup + 5 slo + ack-all в одной строке).
Round 1 — validation
npm run build→ exit 0, 9 страниц собрано (/,/a2a,/config,/memmesh,/observability,/ops,/profile,/skills,/stats). Bundle’ы:BackupPanel.*.js≈ 7.6 KB,SloPanel.*.js≈ 11.4 KB.npx astro check→ 0 errors, 0 warnings, 0 hints в новых файлах (BackupPanel.astro,SloPanel.astro,ops.astro,lib/api.ts,layouts/Layout.astro). Pre-existing 17 errors вMeshRouterPanel.astro(вне scope task_094; задокументировано в task_088/089).- Проверка
dist/ops/index.html:id="backup-panel"+id="slo-panel"присутствуют; nav-link/opsактивен (bg-white/10 text-white); titleHercules · Operationsкорректный.