Documentation
¶
Overview ¶
Package coverage is the fleet coverage read model (#413, epic #405): a tenant-scoped PROJECTION over agents, work orders and the asset model that answers, for each (asset, capability), what the coverage verdict is — with unknown/stale/refused/unauthorized/agent-missing kept as distinct states (domain/fleetcoverage) rather than collapsed into "clean". It owns no table. A summary that does not reconcile with its detail is the exact failure this exists to prevent, so the summary is computed from the same rows and a test asserts they reconcile.
Index ¶
- type AgentLister
- type AgentRow
- type AssetLister
- type CoverageRow
- type OrderBrief
- type Service
- func (s *Service) AgentDetail(ctx context.Context, tenantID, agentID shared.ID) (AgentRow, []OrderBrief, error)
- func (s *Service) Agents(ctx context.Context, tenantID shared.ID, stateFilter fleetcoverage.AgentHealth) ([]AgentRow, error)
- func (s *Service) Coverage(ctx context.Context, tenantID shared.ID) ([]CoverageRow, error)
- func (s *Service) Summary(ctx context.Context, tenantID shared.ID) (Summary, error)
- type Summary
- type WorkOrderLister
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AgentLister ¶
type AgentLister interface {
ListAgents(ctx context.Context, tenantID shared.ID) ([]*fleetagent.Agent, error)
}
Narrow consumer-side read ports; the memory/Postgres stores satisfy these.
type AgentRow ¶
type AgentRow struct {
ID string `json:"id"`
Name string `json:"name"`
Platform string `json:"platform"`
Version string `json:"agent_version"`
Health fleetcoverage.AgentHealth `json:"state"`
LastSeen time.Time `json:"last_seen"`
Capabilities []string `json:"capabilities"`
CurrentWork int `json:"current_work"`
}
AgentRow is one row of the agent-health view.
type AssetLister ¶
type AssetLister interface {
ListAssets(ctx context.Context, tenantID shared.ID) ([]*asset.Asset, error)
}
Narrow consumer-side read ports; the memory/Postgres stores satisfy these.
type CoverageRow ¶
type CoverageRow struct {
AssetID string `json:"asset_id"`
Capability string `json:"capability"`
Verdict fleetcoverage.Verdict `json:"verdict"`
Detail string `json:"detail,omitempty"`
LastRun time.Time `json:"last_run"`
AgentID string `json:"agent_id,omitempty"`
}
CoverageRow is one (asset, capability) coverage verdict.
type OrderBrief ¶
type OrderBrief struct {
ID string `json:"id"`
Capability string `json:"capability"`
AssetID string `json:"asset_id"`
State workorder.State `json:"state"`
UpdatedAt time.Time `json:"updated_at"`
}
OrderBrief is a work order summarised for the agent-detail view.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service computes the coverage read model.
func NewService ¶
func NewService(agents AgentLister, orders WorkOrderLister, assets AssetLister, clock ports.Clock, staleAfter, freshTarget time.Duration) (*Service, error)
NewService validates its dependencies. staleAfter/freshTarget <= 0 disable the respective check.
func (*Service) AgentDetail ¶
func (s *Service) AgentDetail(ctx context.Context, tenantID, agentID shared.ID) (AgentRow, []OrderBrief, error)
AgentDetail returns one agent's health row plus its recent work orders (most recent first). shared.ErrNotFound if the agent does not exist for the tenant.
func (*Service) Agents ¶
func (s *Service) Agents(ctx context.Context, tenantID shared.ID, stateFilter fleetcoverage.AgentHealth) ([]AgentRow, error)
Agents returns the agent-health rows, optionally filtered to a single health state ("" = all).
type Summary ¶
type Summary struct {
AgentsByState map[fleetcoverage.AgentHealth]int `json:"agents_by_state"`
RowsByVerdict map[fleetcoverage.Verdict]int `json:"rows_by_verdict"`
OldestPerCapability map[string]time.Time `json:"oldest_per_capability"`
AssetsWithoutAgent int `json:"assets_without_agent"`
}
Summary is the fleet coverage summary; AssetsByVerdict counts coverage ROWS per verdict and MUST sum to the number of coverage rows (reconciliation).