diff --git a/internal/api/handler/metrics.go b/internal/api/handler/metrics.go
index 8b7040a..ac41008 100644
--- a/internal/api/handler/metrics.go
+++ b/internal/api/handler/metrics.go
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"net/http"
+ "sort"
"time"
"github.com/shankar0123/certctl/internal/api/middleware"
@@ -25,6 +26,31 @@ type CounterSnapshotter interface {
Snapshot() map[string]uint64
}
+// DeploySnapshotEntry is the per-target-type tuple emitted by the
+// deploy package's counter table. Avoids importing the service
+// package's DeploySnapshot directly so the handler stays
+// dependency-light (the interface uses primitives only).
+//
+// Phase 10 of the deploy-hardening I master bundle.
+type DeploySnapshotEntry struct {
+ TargetType string
+ AttemptsSuccess uint64
+ AttemptsFailure uint64
+ ValidateFailures uint64
+ ReloadFailures uint64
+ PostVerifyFails uint64
+ RollbackRestored uint64
+ RollbackAlsoFail uint64
+ IdempotentSkips uint64
+}
+
+// DeployCounterSnapshotter is the surface MetricsHandler consumes
+// for the per-target-type deploy counters. The DeployCounters type
+// in internal/service satisfies this via an adapter.
+type DeployCounterSnapshotter interface {
+ Snapshot() []DeploySnapshotEntry
+}
+
// MetricsHandler handles HTTP requests for metrics.
// Supports both JSON format (GET /api/v1/metrics) and Prometheus exposition format
// (GET /api/v1/metrics/prometheus) for integration with Prometheus, Grafana, Datadog, etc.
@@ -36,6 +62,8 @@ type MetricsHandler struct {
// wires the instances at startup. The naming convention is
// certctl__