Documentation
¶
Overview ¶
Package api provides Chronos's HTTP REST API. It is a thin transport layer over the persistence ports: parse the request, call a port, render the response. Per the cognitive-stack vision Chronos surfaces signals; it does not interpret or render prose. The wire shape is just the structured signal — Title/Summary/Suggestion are not part of this API.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type EvidenceDTO ¶
type EvidenceDTO struct {
Series uuid.UUID `json:"series"`
Time time.Time `json:"time"`
Kind string `json:"kind"`
Score float64 `json:"score"`
Metrics map[string]float64 `json:"metrics,omitempty"`
}
EvidenceDTO is one piece of supporting evidence.
type IngestRequest ¶
type IngestRequest struct {
ID uuid.UUID `json:"id,omitempty"`
EntityID uuid.UUID `json:"entity_id"`
ScopeID uuid.UUID `json:"scope_id"`
Timestamp time.Time `json:"timestamp"`
Features []float64 `json:"features"`
Labels []string `json:"labels,omitempty"`
Meta map[string]string `json:"meta,omitempty"`
// Adapter labels the source for retention policy / count queries. If
// empty, signals fall back to "http" so streaming clients are
// distinguishable from pull adapters in the Count column.
Adapter string `json:"adapter,omitempty"`
}
IngestRequest is the wire shape for POST /v1/ingest. It mirrors the vision's TimeSeriesPoint with multi-feature support.
type Middleware ¶
Middleware wraps an http.Handler with cross-cutting behaviour. It is the standard "decorator" signature used by net/http composition.
func BearerAuth ¶
func BearerAuth(token string) Middleware
BearerAuth requires every request to carry an "Authorization: Bearer <token>" header matching the configured token. If token is empty, authentication is disabled and the middleware is a no-op — that matches the documented "no auth out of the box" default. The /health route is always public so liveness probes never need credentials.
Token comparison uses subtle.ConstantTimeCompare to avoid leaking the prefix length via timing.
func Logging ¶
func Logging(logger *slog.Logger, metrics *observability.Metrics) Middleware
Logging emits a structured slog event for every HTTP request once the response has been written, and (when metrics is non-nil) records the observation for /metrics scraping. Fields on the slog event: method, path, status, duration, remote.
func Recover ¶
func Recover(logger *slog.Logger) Middleware
Recover converts panics in downstream handlers into 500 responses and logs the stack trace. Without it, a single buggy handler can crash the whole HTTP server because net/http re-throws the panic.
type SSEBroadcaster ¶
type SSEBroadcaster interface {
Subscribe(scope uuid.UUID, pattern string) (uuid.UUID, <-chan domain.Signal)
Unsubscribe(uuid.UUID)
}
SSEBroadcaster is the structural contract the api layer requires of any streaming source. internal/notify.SSE satisfies it without either package importing the other (notify -> api would otherwise cycle through webhook.go's use of ToSignalDTO).
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server holds dependencies for HTTP handlers.
func NewServer ¶
func NewServer(states ports.EntityStateRepository, signals ports.SignalRepository, metrics *observability.Metrics, logger *slog.Logger) *Server
NewServer wires an HTTP server. Pass slog.Default() for the logger if the caller has no preference. The states repository is required to support the streaming /v1/ingest endpoint; pass nil to disable it (the route still mounts but returns 501). metrics may be nil, in which case /metrics returns an empty document and observations in handlers are no-ops.
func (*Server) RegisterRoutes ¶
RegisterRoutes wires API routes onto a ServeMux. Routes are stable wire contracts; bump /v1 to introduce incompatible changes.
func (*Server) WithSSE ¶
func (s *Server) WithSSE(sse SSEBroadcaster) *Server
WithSSE attaches an SSE broadcaster so the /v1/signals/stream route can register subscribers. Returns the server for chaining. Without this attachment, /v1/signals/stream responds 501 Not Implemented.
type SignalDTO ¶
type SignalDTO struct {
ID uuid.UUID `json:"id"`
ScopeID uuid.UUID `json:"scope_id"`
Series uuid.UUID `json:"series"`
Pattern string `json:"pattern"`
DetectedAt time.Time `json:"detected_at"`
Window TimeWindowDTO `json:"window"`
Strength float64 `json:"strength"`
Confidence float64 `json:"confidence"`
Metrics map[string]float64 `json:"metrics,omitempty"`
Evidence []EvidenceDTO `json:"evidence,omitempty"`
}
SignalDTO is the wire shape for signals returned by the HTTP API. It is decoupled from domain.Signal so internal refactors do not break clients. There is no Title/Summary/Suggestion: per the cognitive- stack vision, Chronos emits signals — not prose. Downstream consumers (Nous) interpret the structured fields.
func ToSignalDTO ¶
ToSignalDTO renders a domain.Signal into its wire form.