status

package
v1.2.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: AGPL-3.0 Imports: 23 Imported by: 0

Documentation

Index

Constants

View Source
const (
	StatusOperational   = "operational"
	StatusDegraded      = "degraded"
	StatusPartialOutage = "partial_outage"
	StatusMajorOutage   = "major_outage"
	StatusUnderMaint    = "under_maintenance"
)

Component status values.

View Source
const (
	SeverityMinor    = "minor"
	SeverityMajor    = "major"
	SeverityCritical = "critical"
)

Incident severity levels.

View Source
const (
	IncidentInvestigating = "investigating"
	IncidentResolved      = "resolved"
)

Incident status values.

View Source
const (
	GlobalAllOperational = "All Systems Operational"
	GlobalDegraded       = "Degraded Performance"
	GlobalPartialOutage  = "Partial System Outage"
	GlobalMajorOutage    = "Major System Outage"
	GlobalMaintenance    = "Scheduled Maintenance"
)

Global status messages.

View Source
const (
	TLSMandatory = "mandatory"
	TLSNone      = "none"
)

TLS policy values for SMTP.

View Source
const (
	DefaultTitle                  = "System Status"
	DefaultSubtitle               = ""
	DefaultColorBg                = "#0B0E13"
	DefaultColorSurface           = "#12151C"
	DefaultColorBorder            = "#1F2937"
	DefaultColorText              = "#FFFFFF"
	DefaultColorAccent            = "#22C55E"
	DefaultColorStatusOperational = "#22C55E"
	DefaultColorStatusDegraded    = "#EAB308"
	DefaultColorStatusPartial     = "#F97316"
	DefaultColorStatusMajor       = "#EF4444"
	DefaultLocale                 = "en"
	DefaultDateFormat             = "relative"
)

Variables

View Source
var (
	ErrAssetTooLarge        = errors.New("asset exceeds size cap")
	ErrAssetUnsupportedMIME = errors.New("asset MIME not allowed for this role")
	ErrInvalidScheme        = errors.New("URL scheme not in allowlist (http, https)")
	ErrInvalidHex           = errors.New("color must be #RRGGBB or #RRGGBBAA")
	ErrInvalidLocale        = errors.New("locale not supported")
	ErrInvalidDateFormat    = errors.New("date format must be 'relative' or 'absolute'")
	ErrInvalidTimezone      = errors.New("timezone must be a valid IANA identifier")
	ErrFieldTooLong         = errors.New("field exceeds maximum length")
	ErrNotFound             = errors.New("not found")
)

Functions

func AssetSizeCap added in v1.2.11

func AssetSizeCap(role AssetRole) int64

AssetSizeCap returns the max allowed bytes for the given role.

func ComputeAggregateStatus added in v1.2.11

func ComputeAggregateStatus(states []string) string

ComputeAggregateStatus applies the fractional aggregation rule over a list of monitor states. Empty list → operational (vacuous case). All major_outage → major_outage. Any major_outage + any non-major → partial_outage. No major_outage, any partial_outage → partial_outage (pass-through). No major_outage, no partial_outage, any degraded → degraded. All operational (or empty string treated as operational) → operational.

func ContrastRatio added in v1.2.11

func ContrastRatio(fgHex, bgHex string) (float64, error)

func DetectAssetMIME added in v1.2.11

func DetectAssetMIME(role AssetRole, head []byte) (string, error)

DetectAssetMIME sniffs the MIME type from the first 512 bytes and validates it for the given role.

func RenderAnnouncement added in v1.2.11

func RenderAnnouncement(md string) (string, error)

func RenderFAQAnswer added in v1.2.11

func RenderFAQAnswer(md string) (string, error)

func RenderFooter added in v1.2.11

func RenderFooter(md string) (string, error)

func Severity

func Severity(s string) int

Severity returns a numeric severity for status comparison (higher = worse).

Types

type APIComponentBrief

type APIComponentBrief struct {
	ID     int64  `json:"id"`
	Name   string `json:"name"`
	Status string `json:"status"`
}

APIComponentBrief is a brief component in the JSON API.

type APIIncidentBrief

type APIIncidentBrief struct {
	ID           int64           `json:"id"`
	Title        string          `json:"title"`
	Severity     string          `json:"severity"`
	Status       string          `json:"status"`
	Components   []string        `json:"components"`
	CreatedAt    time.Time       `json:"created_at"`
	LatestUpdate *APIUpdateBrief `json:"latest_update,omitempty"`
}

APIIncidentBrief is a brief incident in the JSON API.

type APIMaintBrief

type APIMaintBrief struct {
	ID         int64     `json:"id"`
	Title      string    `json:"title"`
	StartsAt   time.Time `json:"starts_at"`
	EndsAt     time.Time `json:"ends_at"`
	Components []string  `json:"components"`
}

APIMaintBrief is a brief maintenance window in the JSON API.

type APIUpdateBrief

type APIUpdateBrief struct {
	Status    string    `json:"status"`
	Message   string    `json:"message"`
	CreatedAt time.Time `json:"created_at"`
}

APIUpdateBrief is a brief incident update in the JSON API.

type Announcement added in v1.2.11

type Announcement struct {
	Enabled     bool
	MessageMD   string
	MessageHTML string
	URL         string
}

type Asset added in v1.2.11

type Asset struct {
	Role      AssetRole
	MIME      string
	Bytes     []byte
	ByteSize  int
	AltText   string
	UpdatedAt time.Time
}

type AssetRole added in v1.2.11

type AssetRole string
const (
	AssetRoleFavicon AssetRole = "favicon"
	AssetRoleHero    AssetRole = "hero"
)

type AtomEntry

type AtomEntry struct {
	Title   string   `xml:"title"`
	ID      string   `xml:"id"`
	Link    AtomLink `xml:"link"`
	Updated string   `xml:"updated"`
	Summary string   `xml:"summary"`
}

type AtomFeed

type AtomFeed struct {
	XMLName xml.Name    `xml:"feed"`
	XMLNS   string      `xml:"xmlns,attr"`
	Title   string      `xml:"title"`
	ID      string      `xml:"id"`
	Link    AtomLink    `xml:"link"`
	Updated string      `xml:"updated"`
	Entries []AtomEntry `xml:"entry"`
}
type AtomLink struct {
	Href string `xml:"href,attr"`
	Rel  string `xml:"rel,attr,omitempty"`
	Type string `xml:"type,attr,omitempty"`
}

type Component

type Component struct {
	ID              int64           `json:"id"`
	CompositionMode CompositionMode `json:"composition_mode"`
	Monitors        []MonitorRef    `json:"monitors,omitempty"`
	MatchAllType    string          `json:"match_all_type,omitempty"`
	DisplayName     string          `json:"display_name"`
	DisplayOrder    int             `json:"display_order"`
	Visible         bool            `json:"visible"`
	DerivedStatus   string          `json:"derived_status,omitempty"`
	StatusOverride  *string         `json:"status_override"`
	EffectiveStatus string          `json:"effective_status,omitempty"`
	AutoIncident    bool            `json:"auto_incident"`
	NeedsAttention  bool            `json:"needs_attention,omitempty"`
	CreatedAt       time.Time       `json:"created_at"`
	UpdatedAt       time.Time       `json:"updated_at"`
}

Component is a public-facing representation of a monitored application or service.

type ComponentData

type ComponentData struct {
	ID              int64
	DisplayName     string
	EffectiveStatus string
	StatusLabel     string
	Monitors        []MonitorRef
}

ComponentData holds a component with its effective status for rendering.

type ComponentStore

type ComponentStore interface {
	ListComponents(ctx context.Context) ([]Component, error)
	ListVisibleComponents(ctx context.Context) ([]Component, error)
	GetComponent(ctx context.Context, id int64) (*Component, error)
	ListComponentsByMonitor(ctx context.Context, monitorType string, monitorID int64) ([]Component, error)
	RemoveDanglingMonitorRefs(ctx context.Context, monitorType string, monitorID int64) error
	CreateComponent(ctx context.Context, c *Component) (int64, error)
	UpdateComponent(ctx context.Context, c *Component) error
	DeleteComponent(ctx context.Context, id int64) error
}

ComponentStore defines the persistence interface for status components.

type CompositionMode added in v1.2.11

type CompositionMode string

CompositionMode describes how a status component selects its monitors.

const (
	CompositionExplicit CompositionMode = "explicit"
	CompositionMatchAll CompositionMode = "match-all"
)

type ContrastWarning added in v1.2.11

type ContrastWarning struct {
	Pair            string  `json:"pair"`
	Ratio           float64 `json:"ratio"`
	WCAGAAThreshold float64 `json:"wcag_aa_threshold"`
	Severity        string  `json:"severity"`
}

func EvaluatePalette added in v1.2.11

func EvaluatePalette(p Palette) []ContrastWarning

EvaluatePalette returns warnings for pairs that fail WCAG AA contrast ratios.

type Deps added in v1.1.0

type Deps struct {
	Components        ComponentStore                   // required
	Logger            *slog.Logger                     // required
	Incidents         IncidentStore                    // optional — nil-safe
	Maintenance       MaintenanceStore                 // optional — nil-safe
	MonitorStatus     MonitorStatusProvider            // optional — nil-safe
	MonitorPopulation MonitorPopulationProvider        // optional — nil-safe
	MonitorName       MonitorNameProvider              // optional — nil-safe
	Broadcaster       func(eventType string, data any) // optional — nil-safe
	Subscribers       *SubscriberService               // optional — nil-safe
}

Deps holds all dependencies for the status Service.

type FAQItem added in v1.2.11

type FAQItem struct {
	ID         int64
	Position   int
	Question   string
	AnswerMD   string
	AnswerHTML string
	CreatedAt  time.Time
	UpdatedAt  time.Time
}
type FooterLink struct {
	ID        int64
	Position  int
	Label     string
	URL       string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler serves the public status page API and SSE endpoints.

func NewHandler

func NewHandler(service *Service, sseHandler http.Handler, logger *slog.Logger) *Handler

NewHandler creates a new public status page handler. sseHandler should be an SSEBroker that implements http.Handler for /status/events.

func (*Handler) HandleAtomFeed

func (h *Handler) HandleAtomFeed(w http.ResponseWriter, r *http.Request)

HandleAtomFeed serves the Atom feed of recent incident updates.

func (*Handler) HandleConfirm

func (h *Handler) HandleConfirm(w http.ResponseWriter, r *http.Request)

HandleConfirm processes a subscription confirmation.

func (*Handler) HandleStatusAPI

func (h *Handler) HandleStatusAPI(w http.ResponseWriter, r *http.Request)

HandleStatusAPI serves the JSON status snapshot.

func (*Handler) HandleSubscribe

func (h *Handler) HandleSubscribe(w http.ResponseWriter, r *http.Request)

HandleSubscribe processes a new email subscription request.

func (*Handler) HandleUnsubscribe

func (h *Handler) HandleUnsubscribe(w http.ResponseWriter, r *http.Request)

HandleUnsubscribe processes an unsubscribe request.

func (*Handler) Register

func (h *Handler) Register(mux *http.ServeMux, mw Middleware)

Register registers the status API and SSE routes directly on the given mux.

func (*Handler) SetPersonalizationHandler added in v1.2.11

func (h *Handler) SetPersonalizationHandler(ph *PersonalizationPublicHandler)

SetPersonalizationHandler attaches the personalization public handler.

type Incident

type Incident struct {
	ID                  int64             `json:"id"`
	Title               string            `json:"title"`
	Severity            string            `json:"severity"`
	Status              string            `json:"status"`
	IsMaintenance       bool              `json:"is_maintenance"`
	MaintenanceWindowID *int64            `json:"maintenance_window_id,omitempty"`
	Components          []IncidentCompRef `json:"components,omitempty"`
	Updates             []IncidentUpdate  `json:"updates,omitempty"`
	CreatedAt           time.Time         `json:"created_at"`
	ResolvedAt          *time.Time        `json:"resolved_at"`
	UpdatedAt           time.Time         `json:"updated_at"`
}

Incident represents a public-facing incident.

type IncidentCompRef

type IncidentCompRef struct {
	ID   int64  `json:"id"`
	Name string `json:"name"`
}

IncidentCompRef is a lightweight component reference for incident responses.

type IncidentStore

type IncidentStore interface {
	ListIncidents(ctx context.Context, opts ListIncidentsOpts) ([]Incident, int, error)
	ListActiveIncidents(ctx context.Context) ([]Incident, error)
	ListRecentIncidents(ctx context.Context, days int) ([]Incident, error)
	GetIncident(ctx context.Context, id int64) (*Incident, error)
	GetActiveIncidentByComponent(ctx context.Context, componentID int64) (*Incident, error)
	CreateIncident(ctx context.Context, inc *Incident, componentIDs []int64, initialMessage string) (int64, error)
	UpdateIncident(ctx context.Context, inc *Incident, componentIDs []int64) error
	DeleteIncident(ctx context.Context, id int64) error

	// Incident updates
	ListUpdates(ctx context.Context, incidentID int64) ([]IncidentUpdate, error)
	CreateUpdate(ctx context.Context, u *IncidentUpdate) (int64, error)

	// Cleanup
	DeleteIncidentsOlderThan(ctx context.Context, days int) (int64, error)
}

IncidentStore defines the persistence interface for incidents and updates.

type IncidentUpdate

type IncidentUpdate struct {
	ID         int64     `json:"id"`
	IncidentID int64     `json:"incident_id"`
	Status     string    `json:"status"`
	Message    string    `json:"message"`
	IsAuto     bool      `json:"is_auto"`
	AlertID    *int64    `json:"alert_id,omitempty"`
	CreatedAt  time.Time `json:"created_at"`
}

IncidentUpdate is a timestamped entry in an incident timeline.

type ListIncidentsOpts

type ListIncidentsOpts struct {
	Status   string
	Severity string
	Limit    int
	Offset   int
}

ListIncidentsOpts contains filter parameters for listing incidents.

type MaintenanceScheduler

type MaintenanceScheduler struct {
	// contains filtered or unexported fields
}

MaintenanceScheduler polls for maintenance windows that need activation or deactivation.

func NewMaintenanceScheduler

func NewMaintenanceScheduler(
	maintenance MaintenanceStore,
	components ComponentStore,
	incidents IncidentStore,
	service *Service,
	logger *slog.Logger,
) *MaintenanceScheduler

NewMaintenanceScheduler creates a new scheduler.

func (*MaintenanceScheduler) Start

func (s *MaintenanceScheduler) Start(ctx context.Context)

Start begins the scheduler loop with 60-second polling interval.

type MaintenanceStore

type MaintenanceStore interface {
	ListMaintenance(ctx context.Context, statusFilter string, limit int) ([]MaintenanceWindow, error)
	GetMaintenance(ctx context.Context, id int64) (*MaintenanceWindow, error)
	CreateMaintenance(ctx context.Context, mw *MaintenanceWindow, componentIDs []int64) (int64, error)
	UpdateMaintenance(ctx context.Context, mw *MaintenanceWindow, componentIDs []int64) error
	DeleteMaintenance(ctx context.Context, id int64) error

	// Scheduler queries
	GetPendingActivation(ctx context.Context, now int64) ([]MaintenanceWindow, error)
	GetPendingDeactivation(ctx context.Context, now int64) ([]MaintenanceWindow, error)
	SetActive(ctx context.Context, id int64, active bool, incidentID *int64) error
}

MaintenanceStore defines the persistence interface for maintenance windows.

type MaintenanceWindow

type MaintenanceWindow struct {
	ID          int64             `json:"id"`
	Title       string            `json:"title"`
	Description string            `json:"description"`
	StartsAt    time.Time         `json:"starts_at"`
	EndsAt      time.Time         `json:"ends_at"`
	Active      bool              `json:"active"`
	IncidentID  *int64            `json:"incident_id"`
	Components  []IncidentCompRef `json:"components,omitempty"`
	CreatedAt   time.Time         `json:"created_at"`
	UpdatedAt   time.Time         `json:"updated_at"`
}

MaintenanceWindow represents a scheduled maintenance period.

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware wraps an http.Handler (e.g. rate limiter).

type MonitorNameProvider added in v1.2.11

type MonitorNameProvider func(ctx context.Context, monitorType string, monitorID int64) string

MonitorNameProvider resolves the display name of a specific monitor.

type MonitorPopulationProvider added in v1.2.11

type MonitorPopulationProvider func(ctx context.Context, monitorType string) []MonitorRef

MonitorPopulationProvider returns all monitor refs of a given type (used by match-all components).

type MonitorRef added in v1.2.11

type MonitorRef struct {
	Type   string `json:"type"`
	ID     int64  `json:"id"`
	Name   string `json:"name,omitempty"`
	Status string `json:"status,omitempty"`
}

MonitorRef is a reference to a specific monitor with its type and id. The Name field is populated on reads but ignored on writes.

type MonitorStatusProvider

type MonitorStatusProvider func(ctx context.Context, monitorType string, monitorID int64) string

MonitorStatusProvider resolves the current health status of a specific monitor.

type PageData

type PageData struct {
	GlobalStatus    string
	GlobalMessage   string
	Components      []ComponentData
	ActiveIncidents []Incident
	RecentIncidents []Incident
	Maintenance     []MaintenanceWindow
}

PageData holds all data needed to render the public status page.

type Palette added in v1.2.11

type Palette struct {
	Background          string
	Surface             string
	Border              string
	Text                string
	Accent              string
	StatusOperational   string
	StatusDegraded      string
	StatusPartialOutage string
	StatusMajorOutage   string
}

type PersonalizationPublicHandler added in v1.2.11

type PersonalizationPublicHandler struct {
	// contains filtered or unexported fields
}

func NewPersonalizationPublicHandler added in v1.2.11

func NewPersonalizationPublicHandler(svc *PersonalizationService, logger *slog.Logger) *PersonalizationPublicHandler

func (*PersonalizationPublicHandler) GetVersion added in v1.2.11

func (h *PersonalizationPublicHandler) GetVersion(r *http.Request) int64

GetVersion returns the current personalization settings version (0 on error).

func (*PersonalizationPublicHandler) HandleSettingsJSON added in v1.2.11

func (h *PersonalizationPublicHandler) HandleSettingsJSON(w http.ResponseWriter, r *http.Request)

type PersonalizationService added in v1.2.11

type PersonalizationService struct {
	// contains filtered or unexported fields
}

func NewPersonalizationService added in v1.2.11

func NewPersonalizationService(store PersonalizationStore, logger *slog.Logger) *PersonalizationService

func (*PersonalizationService) CreateFAQItem added in v1.2.11

func (svc *PersonalizationService) CreateFAQItem(ctx context.Context, question, answerMD string) (FAQItem, error)
func (svc *PersonalizationService) CreateFooterLink(ctx context.Context, label, url string) (FooterLink, error)

func (*PersonalizationService) DeleteAsset added in v1.2.11

func (svc *PersonalizationService) DeleteAsset(ctx context.Context, role AssetRole) error

func (*PersonalizationService) DeleteFAQItem added in v1.2.11

func (svc *PersonalizationService) DeleteFAQItem(ctx context.Context, id int64) error
func (svc *PersonalizationService) DeleteFooterLink(ctx context.Context, id int64) error

func (*PersonalizationService) GetAsset added in v1.2.11

func (svc *PersonalizationService) GetAsset(ctx context.Context, role AssetRole) (*Asset, error)

func (*PersonalizationService) GetSettings added in v1.2.11

func (svc *PersonalizationService) GetSettings(ctx context.Context) (Settings, error)

func (*PersonalizationService) ListFAQItems added in v1.2.11

func (svc *PersonalizationService) ListFAQItems(ctx context.Context) ([]FAQItem, error)
func (svc *PersonalizationService) ListFooterLinks(ctx context.Context) ([]FooterLink, error)

func (*PersonalizationService) PutAsset added in v1.2.11

func (svc *PersonalizationService) PutAsset(ctx context.Context, role AssetRole, mime string, data []byte, altText string) error

func (*PersonalizationService) ReorderFAQItems added in v1.2.11

func (svc *PersonalizationService) ReorderFAQItems(ctx context.Context, ids []int64) ([]FAQItem, error)
func (svc *PersonalizationService) ReorderFooterLinks(ctx context.Context, ids []int64) ([]FooterLink, error)

func (*PersonalizationService) UpdateFAQItem added in v1.2.11

func (svc *PersonalizationService) UpdateFAQItem(ctx context.Context, id int64, question, answerMD string) (FAQItem, error)
func (svc *PersonalizationService) UpdateFooterLink(ctx context.Context, id int64, label, url string) (FooterLink, error)

func (*PersonalizationService) UpdateSettings added in v1.2.11

func (svc *PersonalizationService) UpdateSettings(ctx context.Context, in Settings) (Settings, []ContrastWarning, error)

type PersonalizationStore added in v1.2.11

type PersonalizationStore interface {
	GetSettings(ctx context.Context) (Settings, error)
	UpdateSettings(ctx context.Context, s Settings) (Settings, error)
	BumpVersion(ctx context.Context) error

	GetAsset(ctx context.Context, role AssetRole) (*Asset, error)
	PutAsset(ctx context.Context, a Asset) error
	DeleteAsset(ctx context.Context, role AssetRole) error

	ListFooterLinks(ctx context.Context) ([]FooterLink, error)
	CreateFooterLink(ctx context.Context, label, url string) (FooterLink, error)
	UpdateFooterLink(ctx context.Context, id int64, label, url string) (FooterLink, error)
	DeleteFooterLink(ctx context.Context, id int64) error
	ReorderFooterLinks(ctx context.Context, ids []int64) ([]FooterLink, error)

	ListFAQItems(ctx context.Context) ([]FAQItem, error)
	CreateFAQItem(ctx context.Context, question, answerMD, answerHTML string) (FAQItem, error)
	UpdateFAQItem(ctx context.Context, id int64, question, answerMD, answerHTML string) (FAQItem, error)
	DeleteFAQItem(ctx context.Context, id int64) error
	ReorderFAQItems(ctx context.Context, ids []int64) ([]FAQItem, error)
}

type PublicAnnouncement added in v1.2.11

type PublicAnnouncement struct {
	Enabled bool   `json:"enabled"`
	HTML    string `json:"html"`
	URL     string `json:"url"`
}

type PublicAssetItem added in v1.2.11

type PublicAssetItem struct {
	DataURL string `json:"data_url"`
	AltText string `json:"alt_text,omitempty"`
}

type PublicAssetsResp added in v1.2.11

type PublicAssetsResp struct {
	Favicon *PublicAssetItem `json:"favicon,omitempty"`
	Hero    *PublicAssetItem `json:"hero,omitempty"`
}

type PublicColorsResp added in v1.2.11

type PublicColorsResp struct {
	Bg                string `json:"bg"`
	Surface           string `json:"surface"`
	Border            string `json:"border"`
	Text              string `json:"text"`
	Accent            string `json:"accent"`
	StatusOperational string `json:"status_operational"`
	StatusDegraded    string `json:"status_degraded"`
	StatusPartial     string `json:"status_partial"`
	StatusMajor       string `json:"status_major"`
}

type PublicFAQItem added in v1.2.11

type PublicFAQItem struct {
	Question   string `json:"question"`
	AnswerHTML string `json:"answer_html"`
}
type PublicFooterLink struct {
	Label string `json:"label"`
	URL   string `json:"url"`
}

type PublicFooterResp added in v1.2.11

type PublicFooterResp struct {
	HTML      string             `json:"html"`
	Links     []PublicFooterLink `json:"links"`
	PoweredBy PublicPoweredBy    `json:"powered_by"`
}

type PublicPoweredBy added in v1.2.11

type PublicPoweredBy struct {
	Label string `json:"label"`
	URL   string `json:"url"`
}

type PublicSettingsResponse added in v1.2.11

type PublicSettingsResponse struct {
	Version      int64              `json:"version"`
	Title        string             `json:"title"`
	Subtitle     string             `json:"subtitle"`
	Colors       PublicColorsResp   `json:"colors"`
	Assets       PublicAssetsResp   `json:"assets"`
	Announcement PublicAnnouncement `json:"announcement"`
	Footer       PublicFooterResp   `json:"footer"`
	FAQ          []PublicFAQItem    `json:"faq"`
	Locale       string             `json:"locale"`
	Timezone     string             `json:"timezone"`
	DateFormat   string             `json:"date_format"`
}

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service encapsulates public status page business logic.

func NewService

func NewService(d Deps) *Service

NewService creates a new status page service.

func (*Service) BroadcastComponentChange

func (s *Service) BroadcastComponentChange(ctx context.Context, comp *Component)

BroadcastComponentChange notifies public SSE clients of a component status change.

func (*Service) ComputeGlobalStatus

func (s *Service) ComputeGlobalStatus(ctx context.Context) (string, string)

ComputeGlobalStatus derives the global status from all visible components.

func (*Service) DeriveComponentStatus

func (s *Service) DeriveComponentStatus(ctx context.Context, c *Component) string

DeriveComponentStatus computes the effective status for a single component.

func (*Service) GetPageData

func (s *Service) GetPageData(ctx context.Context) (*PageData, error)

GetPageData assembles all data for the public status page.

func (*Service) GetSmtpConfig

func (s *Service) GetSmtpConfig() *SmtpConfig

GetSmtpConfig returns the current SMTP configuration.

func (*Service) HandleAlertEvent

func (s *Service) HandleAlertEvent(ctx context.Context, evt alert.Event)

HandleAlertEvent processes an alert event and creates/updates incidents for auto-incident components.

func (*Service) NotifyMonitorChanged

func (s *Service) NotifyMonitorChanged(ctx context.Context, monitorType string, monitorID int64)

NotifyMonitorChanged checks whether any status components are linked to the given monitor and, if so, broadcasts updated statuses to public SSE clients.

func (*Service) SetBroadcaster

func (s *Service) SetBroadcaster(fn func(eventType string, data any))

SetBroadcaster sets the function used to broadcast SSE events.

func (*Service) SetIncidentStore

func (s *Service) SetIncidentStore(store IncidentStore)

SetIncidentStore sets the incident store used by the feed handler.

func (*Service) SetMaintenanceStore

func (s *Service) SetMaintenanceStore(store MaintenanceStore)

SetMaintenanceStore sets the maintenance store used by GetPageData.

func (*Service) SetMonitorNameProvider added in v1.2.11

func (s *Service) SetMonitorNameProvider(fn MonitorNameProvider)

SetMonitorNameProvider sets the function used to resolve monitor display names.

func (*Service) SetMonitorPopulationProvider added in v1.2.11

func (s *Service) SetMonitorPopulationProvider(fn MonitorPopulationProvider)

SetMonitorPopulationProvider sets the function used to enumerate all monitors of a given type.

func (*Service) SetMonitorStatusProvider

func (s *Service) SetMonitorStatusProvider(fn MonitorStatusProvider)

SetMonitorStatusProvider sets the function used to derive component status from monitors.

func (*Service) SetSmtpConfig

func (s *Service) SetSmtpConfig(cfg *SmtpConfig)

SetSmtpConfig updates the SMTP configuration.

func (*Service) SetSubscriberService

func (s *Service) SetSubscriberService(sub *SubscriberService)

SetSubscriberService sets the subscriber service used for notifications.

type Settings added in v1.2.11

type Settings struct {
	Version        int64
	Title          string
	Subtitle       string
	Colors         Palette
	Announcement   Announcement
	FooterTextMD   string
	FooterTextHTML string
	Locale         string
	Timezone       string
	DateFormat     string
	UpdatedAt      time.Time
}

func DefaultSettings added in v1.2.11

func DefaultSettings() Settings

type SmtpClient

type SmtpClient struct {
	// contains filtered or unexported fields
}

SmtpClient wraps go-mail to send emails.

func NewSmtpClient

func NewSmtpClient(config SmtpConfig) *SmtpClient

NewSmtpClient creates a new SMTP client from the given config.

func (*SmtpClient) Send

func (c *SmtpClient) Send(to, subject, htmlBody string) error

Send sends an HTML email to the given recipient.

func (*SmtpClient) TestConnection

func (c *SmtpClient) TestConnection() error

TestConnection verifies SMTP connectivity by dialing the server.

type SmtpConfig

type SmtpConfig struct {
	Host        string `json:"host"`
	Port        int    `json:"port"`
	Username    string `json:"username"`
	Password    string `json:"password,omitempty"`
	TLSPolicy   string `json:"tls_policy"`
	FromAddress string `json:"from_address"`
	FromName    string `json:"from_name"`
	Configured  bool   `json:"configured"`
}

SmtpConfig holds SMTP server configuration for sending emails.

type StatusAPIResponse

type StatusAPIResponse struct {
	GlobalStatus           string              `json:"global_status"`
	GlobalMessage          string              `json:"global_message"`
	UpdatedAt              time.Time           `json:"updated_at"`
	Components             []APIComponentBrief `json:"components"`
	ActiveIncidents        []APIIncidentBrief  `json:"active_incidents"`
	UpcomingMaint          []APIMaintBrief     `json:"upcoming_maintenance"`
	PersonalizationVersion int64               `json:"personalization_version,omitempty"`
}

StatusAPIResponse is the JSON snapshot of current status.

type StatusSubscriber

type StatusSubscriber struct {
	ID             int64      `json:"id"`
	Email          string     `json:"email"`
	Confirmed      bool       `json:"confirmed"`
	ConfirmToken   *string    `json:"-"`
	ConfirmExpires *time.Time `json:"-"`
	UnsubToken     string     `json:"-"`
	CreatedAt      time.Time  `json:"created_at"`
}

StatusSubscriber is an email subscriber for incident notifications.

type SubscriberService

type SubscriberService struct {
	// contains filtered or unexported fields
}

SubscriberService manages email subscriptions for status updates.

func NewSubscriberService

func NewSubscriberService(store SubscriberStore, smtp *SmtpClient, baseURL string, logger *slog.Logger) *SubscriberService

NewSubscriberService creates a new subscriber service.

func (*SubscriberService) CleanExpired

func (s *SubscriberService) CleanExpired(ctx context.Context) (int64, error)

CleanExpired removes unconfirmed subscribers older than 24 hours.

func (*SubscriberService) Confirm

func (s *SubscriberService) Confirm(ctx context.Context, token string) error

Confirm validates a confirmation token and activates the subscription.

func (*SubscriberService) NotifyAll

func (s *SubscriberService) NotifyAll(ctx context.Context, subject, message string)

NotifyAll sends an incident notification to all confirmed subscribers.

func (*SubscriberService) Start

func (s *SubscriberService) Start(ctx context.Context)

Start runs periodic cleanup of expired unconfirmed subscribers.

func (*SubscriberService) Subscribe

func (s *SubscriberService) Subscribe(ctx context.Context, email string) error

Subscribe creates a new subscriber with double opt-in.

func (*SubscriberService) Unsubscribe

func (s *SubscriberService) Unsubscribe(ctx context.Context, token string) error

Unsubscribe removes a subscriber by their unsubscribe token.

type SubscriberStats

type SubscriberStats struct {
	Total     int `json:"total"`
	Confirmed int `json:"confirmed"`
}

SubscriberStats holds aggregated subscriber information.

type SubscriberStore

type SubscriberStore interface {
	CreateSubscriber(ctx context.Context, s *StatusSubscriber) (int64, error)
	GetSubscriberByToken(ctx context.Context, confirmToken string) (*StatusSubscriber, error)
	GetSubscriberByUnsubToken(ctx context.Context, unsubToken string) (*StatusSubscriber, error)
	ConfirmSubscriber(ctx context.Context, id int64) error
	DeleteSubscriber(ctx context.Context, id int64) error
	ListConfirmedSubscribers(ctx context.Context) ([]StatusSubscriber, error)
	ListSubscribers(ctx context.Context) ([]StatusSubscriber, error)
	GetSubscriberStats(ctx context.Context) (*SubscriberStats, error)
	CleanExpiredUnconfirmed(ctx context.Context) (int64, error)
}

SubscriberStore defines the persistence interface for email subscribers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL