115 lines
2.7 KiB
Elixir
115 lines
2.7 KiB
Elixir
defmodule Towerops.StatusPages do
|
|
@moduledoc """
|
|
Context for white-label customer status pages.
|
|
"""
|
|
|
|
import Ecto.Query
|
|
|
|
alias Towerops.Repo
|
|
alias Towerops.StatusPages.StatusIncident
|
|
alias Towerops.StatusPages.StatusPageComponent
|
|
alias Towerops.StatusPages.StatusPageConfig
|
|
|
|
# -- Config --
|
|
|
|
def get_config_by_org(organization_id) do
|
|
StatusPageConfig
|
|
|> where(organization_id: ^organization_id)
|
|
|> Repo.one()
|
|
end
|
|
|
|
def get_config_by_slug(slug) do
|
|
StatusPageConfig
|
|
|> where(slug: ^slug, enabled: true)
|
|
|> preload([:components, :incidents])
|
|
|> Repo.one()
|
|
end
|
|
|
|
def create_config(attrs) do
|
|
%StatusPageConfig{}
|
|
|> StatusPageConfig.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
def update_config(%StatusPageConfig{} = config, attrs) do
|
|
config
|
|
|> StatusPageConfig.changeset(attrs)
|
|
|> Repo.update()
|
|
end
|
|
|
|
# -- Components --
|
|
|
|
def list_components(config_id) do
|
|
StatusPageComponent
|
|
|> where(status_page_config_id: ^config_id)
|
|
|> order_by(asc: :position)
|
|
|> Repo.all()
|
|
end
|
|
|
|
def create_component(attrs) do
|
|
%StatusPageComponent{}
|
|
|> StatusPageComponent.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
def update_component(%StatusPageComponent{} = component, attrs) do
|
|
component
|
|
|> StatusPageComponent.changeset(attrs)
|
|
|> Repo.update()
|
|
end
|
|
|
|
def delete_component(%StatusPageComponent{} = component) do
|
|
Repo.delete(component)
|
|
end
|
|
|
|
# -- Incidents --
|
|
|
|
def list_incidents(config_id, opts \\ []) do
|
|
limit = Keyword.get(opts, :limit, 20)
|
|
|
|
StatusIncident
|
|
|> where(status_page_config_id: ^config_id)
|
|
|> order_by(desc: :started_at)
|
|
|> limit(^limit)
|
|
|> Repo.all()
|
|
end
|
|
|
|
def list_active_incidents(config_id) do
|
|
StatusIncident
|
|
|> where(status_page_config_id: ^config_id)
|
|
|> where([i], i.status != "resolved")
|
|
|> order_by(desc: :started_at)
|
|
|> Repo.all()
|
|
end
|
|
|
|
def create_incident(attrs) do
|
|
%StatusIncident{}
|
|
|> StatusIncident.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
def update_incident(%StatusIncident{} = incident, attrs) do
|
|
incident
|
|
|> StatusIncident.changeset(attrs)
|
|
|> Repo.update()
|
|
end
|
|
|
|
def resolve_incident(%StatusIncident{} = incident) do
|
|
update_incident(incident, %{
|
|
status: "resolved",
|
|
resolved_at: Towerops.Time.now()
|
|
})
|
|
end
|
|
|
|
# -- Overall Status --
|
|
|
|
def overall_status(components) when is_list(components) do
|
|
cond do
|
|
Enum.any?(components, &(&1.status == "major_outage")) -> :major_outage
|
|
Enum.any?(components, &(&1.status == "partial_outage")) -> :partial_outage
|
|
Enum.any?(components, &(&1.status == "degraded")) -> :degraded
|
|
Enum.any?(components, &(&1.status == "maintenance")) -> :maintenance
|
|
true -> :operational
|
|
end
|
|
end
|
|
end
|