Skip to content

Spec 022 — Overview success-rate widget (closes phase 4)#67

Merged
Copxer merged 2 commits into
mainfrom
spec/022-overview-success-rate-widget
May 1, 2026
Merged

Spec 022 — Overview success-rate widget (closes phase 4)#67
Copxer merged 2 commits into
mainfrom
spec/022-overview-success-rate-widget

Conversation

@Copxer
Copy link
Copy Markdown
Owner

@Copxer Copxer commented May 1, 2026

Closes #66

Spec: specs/phase-4-deployments-cicd/022-overview-success-rate-widget.md

Last spec of phase 4 — Deployments & CI/CD now ships end-to-end: data layer (020), cross-repo timeline UI with realtime (021), and now the Overview KPI.

Summary

  • GetOverviewDashboardQuery::deploymentsKpi() aggregates workflow_runs over the last 24h (vs prior 24h) with three small helpers (completedRunCount, successfulRunCount, workflowRunSparkline) keeping the main method readable.
  • Returns successful_24h (primary), success_rate_24h (integer percent, null when empty window), change_percent (capped [-100, +999]), 12-day completed-run sparkline, and a 4-state status (muted/success/warning/danger).
  • Window keys on run_completed_at (not run_started_at) so long-running jobs land in the bucket they finished in.
  • MOCK_KPIS['deployments'] removed; class docblock graduates the slice from "still mock" to "real today."
  • Overview.vue secondary prop now renders "{rate}% success" (or "—% success" when null) instead of static "Successful". TypeScript DashboardPayload.deployments extended with success_rate_24h: number | null.

Test plan

  • vendor/bin/pint --test passes.
  • php artisan test — 14 net new passing tests (zero state, 24h window, change-percent + caps, threshold boundaries at 95%/80%, danger band, sparkline daily counts + in-progress exclusion). Full suite 282 passed (was 269). The 41 failures are env-only POST CSRF (419) — pre-existing baseline; CI passes them.
  • npm run build clean.
  • Manual smoke (post-merge): verify the Deployments KpiCard renders "24" + "92% success" + green status on an active account; trigger a failing GH Action and confirm the rate moves; verify a quiet account renders "0" + "—% success" + muted dot.

Self-review notes

Self-review pass via superpowers:code-reviewer; addressed both findings:

  • Boundary tests at the 95% and 80% threshold seams (matters because round() makes 18/19 = 94.7 → 95) plus a -100 cap-floor test (1 → 0 case).
  • Index deferral checkpoint — the spec's "Open questions" line said "EXPLAIN first." Documenting the deferral in the spec work log rather than silently dropping it: at phase-1 row counts (likely <10k runs) the planner will scan and that's fine. Revisit when slow-query logs flag the new aggregate; a composite (status, conclusion, run_completed_at) would be optimal then.

Phase 4 status

# Spec Status
020 Workflow runs storage + sync 🟢
021 Deployment timeline UI (with realtime) 🟢
022 Overview success-rate widget 🟢 (this PR)

Phase complete. Roadmap pointers for what's next:

  • Phase 5 — Website Monitoring (uptime checks, response time, perf widget).
  • Phase 6 — Docker Host Agent MVP.
  • Phase 7 — Alerts Engine.

Plus carryover phase-3 polish: the activity heatmap on Overview is still mock — could be its own small fix/ PR when it earns priority.

Copxer added 2 commits April 30, 2026 18:03
Last spec of phase 4. Replace the mocked Deployments (24h) KpiCard on
/overview with a real query against workflow_runs. Locked decisions:
secondary line shows {rate}% success (B), sparkline stays daily
completed-run counts (A) for cross-card consistency, 95/80/0 status
thresholds with a muted floor for empty windows, and the 24h window
keys on run_completed_at so long-running jobs land in the bucket they
finished in.
Replace the mocked Deployments (24h) KpiCard on /overview with a real
aggregate against the workflow_runs table from spec 020. Last spec of
phase 4.

- GetOverviewDashboardQuery::deploymentsKpi() returns:
  - successful_24h: count of completed-success runs in the last 24h
  - success_rate_24h: integer percent (or null when no completed runs)
  - change_percent: vs prior 24h, capped at [-100, +999]
  - sparkline: 12-day daily count of completed runs
  - status: muted (empty) | success (>=95) | warning (>=80) | danger
- Window keys on run_completed_at so long-running jobs land honestly.
- MOCK_KPIS['deployments'] removed; class docblock moves deployments
  from "still mock" to "real today."
- TS DashboardPayload.deployments adds success_rate_24h: number | null.
- Overview.vue secondary prop renders "{rate}% success" or
  "—% success" when null — keeps the card visually balanced on quiet
  windows instead of pretending to know quality on no data.

Tests: 14 new tests covering zero state, 24h window scoping,
change-percent vs prior 24h, +999 cap, -100 floor, threshold seams at
95% and 80% (matters because round() makes 18/19 = 94.7 → 95), warning
and danger bands, sparkline daily counts, and sparkline excluding
in-progress runs. Existing "mock kpis stay phase-0" test trimmed to
drop the deployments assertion (graduated to real).

Self-review pass via superpowers:code-reviewer; addressed both findings
(boundary tests + cap-floor test added; index-deferral checkpoint
documented in spec work log rather than silently dropped).

run_completed_at index intentionally NOT added — phase-1 row counts
make the planner scan acceptable; revisit at ~5–10k workflow runs.
@Copxer Copxer merged commit c65e152 into main May 1, 2026
1 check passed
@Copxer Copxer deleted the spec/022-overview-success-rate-widget branch May 1, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spec 022 — Overview success-rate widget

1 participant