towerops/lib/towerops/integrations.ex
Graham McIntie db40a3e5b7 feat: show human-readable sync status messages for integrations
- Added last_sync_message field to integrations schema
- Gaiia sync: shows item counts on success, friendly error on failure
- Preseem sync: shows AP/device counts on success, friendly error on failure
- Error messages translated from technical errors to user-friendly text
- Message displayed on integration card next to status badge
- Exposed in REST API response
2026-02-14 14:11:02 -06:00

70 lines
1.8 KiB
Elixir

defmodule Towerops.Integrations do
@moduledoc """
Context for managing third-party integrations per organization.
"""
import Ecto.Query
alias Towerops.Integrations.Integration
alias Towerops.Repo
def list_integrations(organization_id) do
Integration
|> where(organization_id: ^organization_id)
|> order_by(:provider)
|> Repo.all()
end
def get_integration(organization_id, provider) do
case Repo.get_by(Integration, organization_id: organization_id, provider: provider) do
nil -> {:error, :not_found}
integration -> {:ok, integration}
end
end
def get_integration!(organization_id, provider) do
Repo.get_by!(Integration, organization_id: organization_id, provider: provider)
end
def create_integration(organization_id, attrs) do
%Integration{}
|> Integration.changeset(Map.put(attrs, :organization_id, organization_id))
|> Repo.insert()
end
def update_integration(%Integration{} = integration, attrs) do
integration
|> Integration.changeset(attrs)
|> Repo.update()
end
def update_sync_status(%Integration{} = integration, status, message \\ nil) do
integration
|> Integration.changeset(%{
last_sync_status: status,
last_synced_at: DateTime.truncate(DateTime.utc_now(), :second),
last_sync_message: message
})
|> Repo.update()
end
def delete_integration(%Integration{} = integration) do
Repo.delete(integration)
end
def change_integration(%Integration{} = integration, attrs \\ %{}) do
Integration.changeset(integration, attrs)
end
def get_integration_by_id(id) do
case Repo.get(Integration, id) do
nil -> {:error, :not_found}
integration -> {:ok, integration}
end
end
def list_enabled_integrations(provider) do
Integration
|> where(provider: ^provider, enabled: true)
|> Repo.all()
end
end