rdev/internal/domain/diagnostics.go
jordan 210064d490 feat: add diagnostics endpoint and external health monitoring
- Add /diagnostics endpoint for system health overview
- Add external health worker for monitoring Gitea, Woodpecker, Registry
- Add health check methods to Gitea and Woodpecker clients
- Remove hardcoded fallback projects (pantheon, aeries)
- Add diagnostics domain types and service layer
- Add comprehensive tests for diagnostics handler and service
- Fix tests to use registered test project instead of hardcoded one

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 19:10:56 -07:00

111 lines
3.5 KiB
Go

package domain
import "time"
// ProjectDiagnostics provides a unified view of project health for debugging.
// It aggregates data from operations, CI pipelines, and registry health.
type ProjectDiagnostics struct {
// ProjectID is the project being diagnosed.
ProjectID string `json:"project_id"`
// GeneratedAt is when this diagnostic was generated.
GeneratedAt time.Time `json:"generated_at"`
// Summary is a one-line status: "healthy", "degraded", or "unhealthy".
Summary string `json:"summary"`
// Issues is a list of detected problems (empty if healthy).
Issues []DiagnosticIssue `json:"issues,omitempty"`
// RecentOperations are the last N operations for this project.
RecentOperations []OperationSummary `json:"recent_operations,omitempty"`
// CI contains CI/CD pipeline status.
CI *CIDiagnostics `json:"ci,omitempty"`
// Registry contains container registry health.
Registry *RegistryStatus `json:"registry,omitempty"`
}
// DiagnosticIssue represents a detected problem.
type DiagnosticIssue struct {
// Severity: "error", "warning", "info"
Severity string `json:"severity"`
// Source: "operation", "ci", "registry"
Source string `json:"source"`
// Message is a human-readable description.
Message string `json:"message"`
// Details provides additional context (e.g., error output).
Details string `json:"details,omitempty"`
// Timestamp is when the issue occurred.
Timestamp time.Time `json:"timestamp,omitempty"`
}
// OperationSummary is a condensed view of an operation for diagnostics.
type OperationSummary struct {
ID string `json:"id"`
Type OperationType `json:"type"`
Status OperationStatus `json:"status"`
StartedAt time.Time `json:"started_at"`
DurationMs int64 `json:"duration_ms,omitempty"`
Error string `json:"error,omitempty"`
ExternalRef string `json:"external_ref,omitempty"`
}
// CIDiagnostics contains CI pipeline health information.
type CIDiagnostics struct {
// Available indicates if CI is configured for this project.
Available bool `json:"available"`
// RecentPipelines are the last N pipeline executions.
RecentPipelines []CIPipelineSummary `json:"recent_pipelines,omitempty"`
// LastFailure contains details of the most recent failed pipeline.
LastFailure *CIPipelineFailure `json:"last_failure,omitempty"`
}
// CIPipelineSummary is a condensed view of a pipeline for diagnostics.
type CIPipelineSummary struct {
Number int64 `json:"number"`
Status string `json:"status"`
Branch string `json:"branch"`
Commit string `json:"commit"`
StartedAt time.Time `json:"started_at"`
Duration string `json:"duration,omitempty"`
}
// CIPipelineFailure contains details about a failed pipeline.
type CIPipelineFailure struct {
Number int64 `json:"number"`
FailedStep string `json:"failed_step"`
Error string `json:"error,omitempty"`
LogTail string `json:"log_tail,omitempty"`
URL string `json:"url,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
// DiagnosticsSummary constants.
const (
DiagnosticsSummaryHealthy = "healthy"
DiagnosticsSummaryDegraded = "degraded"
DiagnosticsSummaryUnhealthy = "unhealthy"
)
// DiagnosticSeverity constants.
const (
DiagnosticSeverityError = "error"
DiagnosticSeverityWarning = "warning"
DiagnosticSeverityInfo = "info"
)
// DiagnosticSource constants.
const (
DiagnosticSourceOperation = "operation"
DiagnosticSourceCI = "ci"
DiagnosticSourceRegistry = "registry"
)