Files
manage/openspec/changes/per-instance-hook-scoping/apply-progress.md
T
Developer 8d3c44d87f spec(per-instance-hook-scoping): verify + reconcile tracking
Write apply-progress.md, tick all 17 tasks, add verify-report.md (21/21 PI-101..121
PASS). Gates green: 368 pytest, ruff clean, npm build+lint 0 errors, 165 vitest.
fetchBackupDashboard/useBackupDashboard/get_backup_dashboard confirmed untouched
(design decision 5). No blocking code findings.
2026-07-10 00:05:58 +00:00

46 lines
3.3 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.
# Apply Progress: Per-Instance Hook Scoping
**Change:** `per-instance-hook-scoping`
**Phase:** apply-progress
**Date:** 2026-07-09
**Status:** complete — all 17 tasks done, all gates green, verified (see `verify-report.md`)
## Slice delivered
Single slice (commit `3bc7ce5`, +268/73, 12 files) — small correctness fix, well within the 400-line budget.
### Backend
- `routers/backups.py``get_backup_jobs`, `get_backup_runs`, `get_backup_alerts` gain `service_id: str | None = None`; threaded into store calls. `get_backup_dashboard` **NOT touched** (design decision 5 — widget path, PI-117 risk) (PI-110).
- `services/settings_store.py`:
- `list_backup_jobs(service_id=None)` — direct `WHERE service_id = ?` when truthy.
- `list_backup_runs(..., service_id=None)` + `list_backup_alerts(..., service_id=None)` — subquery `job_id IN (SELECT id FROM backup_jobs WHERE service_id = ?)` per the schema asymmetry (only `backup_jobs` has the column; runs/alerts attributed via FK chain).
- Skip filter on None/empty → backward-compat (PI-111, PI-112).
- Tests (`test_backups.py`, +83 lines): `service_id=None` → all; `service_id="X"` → only X's; cross-instance preservation (seed A+B, scope A, confirm B's excluded).
### Frontend
- `hooks/useObservability.ts``useAlertmanagerAlerts`, `useAlertmanagerStatus`, `usePrometheusStatus` gain optional `serviceId` in `queryKey` (`["observability","alerts", serviceId ?? ""]` etc.). `usePrometheusTargets` + `useMonitoringMachines` **unchanged** (global by design — PI-107) (PI-101..PI-104).
- `hooks/useBackups.ts``useBackupJobs`, `useBackupRuns`, `useBackupAlerts` gain `serviceId` in `queryKey`. `useBackupDashboard` **unchanged** (PI-105, PI-106).
- `api/client.ts` + `api/backups.ts` — 6 fetch fns gain optional `serviceId``?service_id=` via the shared `get(path, params)` helper. `fetchBackupDashboard` **NOT touched** (PI-108, PI-109).
- `pages/service-tabs/AlertsTab.tsx`, `MetricsTab.tsx`, `JobsTab.tsx` — call hooks with `instance.id`; the prior TODO comments about global scoping removed (PI-113..PI-115). The instance switcher on ServicePage naturally re-scopes: `instance.id` changes → `queryKey` changes → React Query refetches.
- Tests: `useBackups.test.ts` (+85) covers queryKey isolation + serviceId threading; `AlertsTab.test.tsx` updated for the instance.id wiring.
## Deviations from tasks.md / design
- None functional. `fetchBackupDashboard` / `useBackupDashboard` / `get_backup_dashboard` deliberately untouched (design decision 5, PI-117 preserved).
## Final gate results
| Gate | Result |
|---|---|
| `backend && PYTHONPATH=src python3 -m pytest -q` | **368 passed** (+6 new), 2 warnings (pre-existing pythonjsonlogger) |
| `backend && PYTHONPATH=src python3 -m ruff check src tests` | **All checks passed** |
| `frontend && npm run build` | **exit 0** (pre-existing chunk-size warning) |
| `frontend && npm run lint` | **0 errors**, 1 pre-existing warning (`WidgetConfigDialog.tsx`, untouched) |
| `frontend && npx vitest run` | **165 passed** (+7 new) |
## Verification
See `verify-report.md` — adversarial fresh-context review: **21/21 PASS**, all gates green. No blocking code findings. Archive blocker is doc-only (this file + ticked tasks clear it). Non-blocking: weak queryKey-isolation assertion in `useBackups.test.ts` (wiring correct in source; test could assert actual cache keys — LOW).