Dependencies: None
RHIDP Stories: RHIDP-15335, RHIDP-15337
Feature: RHDHPLAN-1513 — Epic RHIDP-15331
Implement the ingestion health backend: boost_sync_attempts table with database migration, SyncAttemptsRepository, HealthStatusService with status derivation (healthy/degraded/failing/unknown based on last 3 attempts; unknown = zero sync attempts recorded), GET /api/boost/ingestion-health REST endpoint, and ErrorClassifier utility with actionable diagnostic guidance for auth failures, network errors, schema mismatches, and rate limits. RBAC gating (ai-catalog.admin) for this endpoint is deferred to Issue 26. The admin UI consuming this API is also in Issue 26.
Tasks
From openspec/changes/ingestion-health-dashboard/tasks.md group 1 (RHIDP-15335):
- 1.1 Define
boost_sync_attempts table schema in database migration (connector_id, timestamp, outcome, error_type, error_message, assets_added/updated/removed, duration_ms)
- 1.2 Create database migration file for
boost_sync_attempts table with indexes on (connector_id, timestamp DESC)
- 1.3 Implement
SyncAttemptsRepository class with methods: insertSyncAttempt(), getLatestAttempts(), cleanupOldAttempts()
- 1.4 Add retention policy config schema (
boost.ingestion.healthRetention.maxAttemptsPerConnector, default 100)
- 1.5 Implement scheduled cleanup job for sync attempts (daily, enforces retention)
- 1.6 Add database indexes for efficient health status queries
From openspec/changes/ingestion-health-dashboard/tasks.md group 2 (RHIDP-15335):
- 2.1 Define
ConnectorHealthStatus type in plugins/boost-common/src/types/ingestion-health.ts
- 2.2 Implement
GET /api/boost/ingestion-health route returning array of connector health objects
- 2.3 Implement health status derivation logic in
HealthStatusService.deriveStatus(attempts) (healthy/degraded/failing/unknown based on last 3 attempts; unknown = zero sync attempts recorded)
- 2.4 Add
?includeDisabled=true query parameter support
2.5 Implement RBAC gating via ai-catalog.admin permission check in route handler (using permissions.authorize()) — deferred to Issue 26
- 2.6 Add structured logging for health API requests via Backstage
LoggerService (full audit event emitters deferred to Issue 21 / RHIDP-15277)
- 2.7 Implement empty state handling
- 2.8 Add health API integration tests
From openspec/changes/ingestion-health-dashboard/tasks.md group 3 (RHIDP-15337):
- 3.1 Create
ErrorClassifier utility class
- 3.2 Implement
classify(error, options?) method returning { errorType, errorMessage, diagnosticGuidance }
- 3.3 Add auth failure detection patterns (401/403, "Invalid token", "OAuth expired")
- 3.4 Add network failure detection patterns (ECONNREFUSED, ETIMEDOUT, DNS, TLS)
- 3.5 Add schema mismatch detection patterns (JSON parsing, "Unexpected field", GraphQL)
- 3.6 Add rate limit detection patterns (429, X-RateLimit-Remaining)
- 3.7 Implement connector-specific error matchers
- 3.8 Implement unknown error fallback classification
- 3.9 Add diagnostic guidance text for each error type
- 3.10 Add error classification unit tests
Specifications
openspec/changes/ingestion-health-dashboard/specs/health-status-api/spec.md
openspec/changes/ingestion-health-dashboard/specs/error-classification/spec.md
Dependencies: None
RHIDP Stories: RHIDP-15335, RHIDP-15337
Feature: RHDHPLAN-1513 — Epic RHIDP-15331
Implement the ingestion health backend:
boost_sync_attemptstable with database migration,SyncAttemptsRepository,HealthStatusServicewith status derivation (healthy/degraded/failing/unknown based on last 3 attempts; unknown = zero sync attempts recorded),GET /api/boost/ingestion-healthREST endpoint, andErrorClassifierutility with actionable diagnostic guidance for auth failures, network errors, schema mismatches, and rate limits. RBAC gating (ai-catalog.admin) for this endpoint is deferred to Issue 26. The admin UI consuming this API is also in Issue 26.Tasks
From
openspec/changes/ingestion-health-dashboard/tasks.mdgroup 1 (RHIDP-15335):boost_sync_attemptstable schema in database migration (connector_id, timestamp, outcome, error_type, error_message, assets_added/updated/removed, duration_ms)boost_sync_attemptstable with indexes on (connector_id, timestamp DESC)SyncAttemptsRepositoryclass with methods:insertSyncAttempt(),getLatestAttempts(),cleanupOldAttempts()boost.ingestion.healthRetention.maxAttemptsPerConnector, default 100)From
openspec/changes/ingestion-health-dashboard/tasks.mdgroup 2 (RHIDP-15335):ConnectorHealthStatustype inplugins/boost-common/src/types/ingestion-health.tsGET /api/boost/ingestion-healthroute returning array of connector health objectsHealthStatusService.deriveStatus(attempts)(healthy/degraded/failing/unknown based on last 3 attempts; unknown = zero sync attempts recorded)?includeDisabled=truequery parameter support2.5 Implement RBAC gating via— deferred to Issue 26ai-catalog.adminpermission check in route handler (usingpermissions.authorize())LoggerService(full audit event emitters deferred to Issue 21 / RHIDP-15277)From
openspec/changes/ingestion-health-dashboard/tasks.mdgroup 3 (RHIDP-15337):ErrorClassifierutility classclassify(error, options?)method returning{ errorType, errorMessage, diagnosticGuidance }Specifications
openspec/changes/ingestion-health-dashboard/specs/health-status-api/spec.mdopenspec/changes/ingestion-health-dashboard/specs/error-classification/spec.md