sqlite

package
v0.0.0-...-acbe8ed Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: AGPL-3.0 Imports: 24 Imported by: 0

Documentation

Overview

Package sqlite provides a SQLite implementation of the db.Service interface.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HeartbeatCounterKey

func HeartbeatCounterKey(checkUID string) string

HeartbeatCounterKey builds the state_entries key holding a check's last accepted SP2 replay counter.

Slash-namespaced, per the documented convention for that table's `key` column (see the column comment in 001_v0_1_0.up.sql).

Types

type Config

type Config struct {
	// DataDir is the directory where the database file will be stored
	DataDir string

	// InMemory creates an in-memory database (for testing)
	InMemory bool

	// LogSQL enables SQL query logging using slog
	LogSQL bool

	// RunMode determines the database filename suffix (e.g., "test" -> "solidping-test.db")
	RunMode string

	// Reset deletes the database file before creating (only for test/demo run modes)
	Reset bool

	// GuardMode controls the migration guard's behavior on a checksum
	// mismatch: migrationguard.ModeStrict (default, fails boot) or
	// migrationguard.ModeWarn (logs and continues). The zero value behaves as
	// ModeStrict.
	GuardMode migrationguard.Mode

	// SlowQueryThreshold logs a successful query at WARN once it takes at
	// least this long (see internal/db/sloghook). 0 disables slow-query
	// logging.
	SlowQueryThreshold time.Duration
}

Config holds SQLite configuration.

type Service

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

Service implements db.Service for SQLite.

func New

func New(ctx context.Context, cfg Config) (*Service, error)

New creates a new SQLite service.

func (*Service) AddOrganizationPreviousSlug

func (s *Service) AddOrganizationPreviousSlug(ctx context.Context, orgUID, slug string) error

AddOrganizationPreviousSlug records a slug an organization has just renamed away from. Any live alias already holding that slug is released first: the partial unique index allows a single live alias per slug, and the newest claim is the truthful one.

func (*Service) ApproveMembershipRequest

func (s *Service) ApproveMembershipRequest(
	ctx context.Context,
	request *models.MembershipRequest,
	member *models.OrganizationMember,
) error

ApproveMembershipRequest commits the request status change AND the new membership row in a single transaction.

func (*Service) AttachIncidentToRollupParent

func (s *Service) AttachIncidentToRollupParent(
	ctx context.Context, childIncidentUID, parentIncidentUID string,
) (bool, error)

AttachIncidentToRollupParent attaches a child incident to a hard-parent incident, guarded on the child still being active and NOT already suppressed — see the postgres twin for why the guard is load-bearing. Returns true when this call performed the update.

func (*Service) CancelIncidentNotificationsForIncident

func (s *Service) CancelIncidentNotificationsForIncident(
	ctx context.Context, incidentUID string, canceledAt time.Time,
) (int64, error)

CancelIncidentNotificationsForIncident bulk-cancels all pending audit rows for an incident. Filters on status=pending to avoid clobbering completed rows. Returns the number of rows updated.

func (*Service) CheckAndStoreAgentNonce

func (s *Service) CheckAndStoreAgentNonce(
	ctx context.Context, agentUID, nonce string, now time.Time, retain time.Duration,
) error

CheckAndStoreAgentNonce records (agentUID, nonce) as consumed, returning db.ErrAgentNonceReplayed when the pair was already seen inside the retention window. This is the cluster-wide replay guard for reconnect signatures: the stale rows of this agent are pruned first, then the insert either wins or conflicts with a live row (which is exactly a replay).

func (*Service) ClearOrgDefaultSeverity

func (s *Service) ClearOrgDefaultSeverity(ctx context.Context, orgUID string) error

ClearOrgDefaultSeverity demotes the current default severity in the org, if any. Called right before promoting a different severity so the `severities_org_default_alive_idx` partial unique index stays satisfied during the transition.

func (*Service) ClearUserContactVerified

func (s *Service) ClearUserContactVerified(ctx context.Context, uid string) error

ClearUserContactVerified removes the verified_at stamp from a contact.

func (*Service) Close

func (s *Service) Close() error

Close closes the database connection.

func (*Service) CompactResults

CompactResults implements db.Service — see that interface for the full contract. Fetch → aggregate (Go) → upsert rollup → delete sources all run in one transaction, so any failure rolls the whole thing back and the bucket stays fully raw.

func (*Service) ConfirmSubscriber

func (s *Service) ConfirmSubscriber(ctx context.Context, uid string, confirmedAt time.Time) error

ConfirmSubscriber sets confirmed_at and consumes the confirm token by replacing it with a non-reusable sentinel (the row UID prefixed with "consumed:") so the opaque token can no longer be looked up while preserving the NOT NULL + unique-index constraints. Returns sql.ErrNoRows when the row is already gone.

func (*Service) ConsumeDeviceAuthRequest

func (s *Service) ConsumeDeviceAuthRequest(ctx context.Context, uid string) (bool, error)

ConsumeDeviceAuthRequest hard-deletes a resolved request. The returned boolean is the exactly-once gate: only the caller whose delete affected a row may hand the stashed PAT back to the client.

func (*Service) CountActiveIncidentsByCheckUID

func (s *Service) CountActiveIncidentsByCheckUID(ctx context.Context, checkUID string) (int, error)

func (*Service) CountAdminsByOrg

func (s *Service) CountAdminsByOrg(ctx context.Context, orgUID string) (int, error)

CountAdminsByOrg counts the members who hold at least the admin role. Owners are included deliberately: they outrank admins, so an org whose only privileged member is its owner must not read as "zero admins" to the last-admin guards.

func (*Service) CountCheckGroupsByEscalationPolicy

func (s *Service) CountCheckGroupsByEscalationPolicy(
	ctx context.Context, orgUID string,
) (map[string]int, error)

CountCheckGroupsByEscalationPolicy counts live groups per referenced policy.

func (*Service) CountChecksByEscalationPolicy

func (s *Service) CountChecksByEscalationPolicy(
	ctx context.Context, orgUID string,
) (map[string]int, error)

CountChecksByEscalationPolicy counts live checks per directly-referenced policy.

func (*Service) CountChecksInheritingOrgDefault

func (s *Service) CountChecksInheritingOrgDefault(
	ctx context.Context, orgUID string,
) (int, error)

CountChecksInheritingOrgDefault counts live checks that resolve to no policy of their own — no direct policy, and either no group or a group whose own policy is null. This is the blast radius of the org default.

func (*Service) CountDanglingOrganizationProviders

func (s *Service) CountDanglingOrganizationProviders(ctx context.Context) (int, error)

CountDanglingOrganizationProviders counts live organization_providers rows pointing at an organization that no longer resolves. Soft-deleting an org does not cascade to its links, so such a row keeps winning the partial unique lookup on (provider_type, provider_id) and blocks every later SSO login and app install for that workspace/guild until it is healed.

func (*Service) CountEscalationPolicyStepsByPolicy

func (s *Service) CountEscalationPolicyStepsByPolicy(
	ctx context.Context, policyUIDs []string,
) (map[string]int, error)

CountEscalationPolicyStepsByPolicy returns step counts keyed by policy UID.

func (*Service) CountFailingIncidentMembers

func (s *Service) CountFailingIncidentMembers(ctx context.Context, incidentUID string) (int, error)

CountFailingIncidentMembers returns the number of members with currently_failing = true.

func (*Service) CountIncidentPublicationsForIncident

func (s *Service) CountIncidentPublicationsForIncident(ctx context.Context, incidentUID string) (int, error)

CountIncidentPublicationsForIncident counts live publications referencing an incident. The retention guard reads this before deleting an incident row.

func (*Service) CountMembersForOrg

func (s *Service) CountMembersForOrg(ctx context.Context, orgUID string) (int, error)

CountMembersForOrg counts every organization member, regardless of how they joined (SSO, invitation, email). Used by the entitlements service to enforce MaxUsers at every membership-creation path.

func (*Service) CountOwnersByOrg

func (s *Service) CountOwnersByOrg(ctx context.Context, orgUID string) (int, error)

CountOwnersByOrg counts the org's live owners. Used by the last-owner guard.

func (*Service) CountResultsByPeriodType

func (s *Service) CountResultsByPeriodType(ctx context.Context) (map[string]int64, error)

CountResultsByPeriodType returns the total row count in `results` grouped by period_type (raw/hour/day/month), across every organization. Deliberately table-wide and uncached: this is only ever called by the periodic gauge sampler tied to the aggregation job's own cadence (internal/jobs/jobtypes/job_aggregation.go), never per-request — a table-wide COUNT(*) is exactly what results cannot afford on every page load (spec 2026-08-17-04 §3).

func (*Service) CountSLOs

func (s *Service) CountSLOs(ctx context.Context, orgUID string) (int, error)

CountSLOs counts an organization's live SLOs.

func (*Service) CountStatusPagesWithCustomDomain

func (s *Service) CountStatusPagesWithCustomDomain(ctx context.Context, orgUID string) (int, error)

CountStatusPagesWithCustomDomain counts an org's live pages with a custom domain set.

func (*Service) CreateAgentEnrollmentToken

func (s *Service) CreateAgentEnrollmentToken(ctx context.Context, token *models.AgentEnrollmentToken) error

CreateAgentEnrollmentToken persists a one-shot enrollment token.

func (*Service) CreateChannel

func (s *Service) CreateChannel(ctx context.Context, conn *models.Integration) error

CreateChannel creates a new integration connection.

func (*Service) CreateCheck

func (s *Service) CreateCheck(ctx context.Context, check *models.Check) error

func (*Service) CreateCheckConnection

func (s *Service) CreateCheckConnection(ctx context.Context, conn *models.CheckConnection) error

CreateCheckConnection creates a new check-connection relationship.

func (*Service) CreateCheckDependency

func (s *Service) CreateCheckDependency(ctx context.Context, dep *models.CheckDependency) error

CreateCheckDependency inserts a new edge.

func (*Service) CreateCheckGroup

func (s *Service) CreateCheckGroup(ctx context.Context, group *models.CheckGroup) error

func (*Service) CreateCheckJob

func (s *Service) CreateCheckJob(ctx context.Context, job *models.CheckJob) error

func (*Service) CreateDeviceAuthRequest

func (s *Service) CreateDeviceAuthRequest(ctx context.Context, req *models.DeviceAuthRequest) error

CreateDeviceAuthRequest inserts a new pending device-authorization request. A unique-violation on user_code is surfaced to the caller, which regenerates and retries.

func (*Service) CreateEmailSuppression

func (s *Service) CreateEmailSuppression(ctx context.Context, sup *models.EmailSuppression) error

CreateEmailSuppression inserts a new suppression row.

func (*Service) CreateEscalationPolicy

func (s *Service) CreateEscalationPolicy(ctx context.Context, policy *models.EscalationPolicy) error

CreateEscalationPolicy inserts a new policy header row.

func (*Service) CreateEvent

func (s *Service) CreateEvent(ctx context.Context, event *models.Event) error

func (*Service) CreateFile

func (s *Service) CreateFile(ctx context.Context, file *models.File) error

CreateFile inserts a new file row.

func (*Service) CreateIncident

func (s *Service) CreateIncident(ctx context.Context, incident *models.Incident) error

CreateIncident inserts an incident, claiming its short per-org number first. Mirrors the Postgres implementation (sync-pg-to-sqlite): the retry-on- collision loop is shared so both engines behave identically.

func (*Service) CreateIncidentNotification

func (s *Service) CreateIncidentNotification(ctx context.Context, n *models.IncidentNotification) error

CreateIncidentNotification inserts a new audit row.

func (*Service) CreateIncidentPublication

func (s *Service) CreateIncidentPublication(ctx context.Context, pub *models.IncidentPublication) error

CreateIncidentPublication inserts a publication row. A duplicate (incident_uid, status_page_uid) is rejected by the partial unique index — callers recover by re-reading with FindIncidentPublication rather than minting a second public incident.

func (*Service) CreateJob

func (s *Service) CreateJob(ctx context.Context, job *models.Job) error

func (*Service) CreateMaintenanceWindow

func (s *Service) CreateMaintenanceWindow(ctx context.Context, window *models.MaintenanceWindow) error

CreateMaintenanceWindow inserts a new maintenance window.

func (*Service) CreateMembershipRequest

func (s *Service) CreateMembershipRequest(ctx context.Context, request *models.MembershipRequest) error

CreateMembershipRequest inserts a new pending request.

func (*Service) CreateOAuthClient

func (s *Service) CreateOAuthClient(ctx context.Context, client *models.OAuthClient) error

CreateOAuthClient inserts a new registered OAuth client.

func (*Service) CreateOnCallSchedule

func (s *Service) CreateOnCallSchedule(ctx context.Context, schedule *models.OnCallSchedule) error

CreateOnCallSchedule inserts a new schedule.

func (*Service) CreateOnCallScheduleOverride

func (s *Service) CreateOnCallScheduleOverride(
	ctx context.Context, override *models.OnCallScheduleOverride,
) error

CreateOnCallScheduleOverride inserts a new override row.

func (*Service) CreateOrgEntitlementAudit

func (s *Service) CreateOrgEntitlementAudit(
	ctx context.Context, audit *models.OrgEntitlementAudit,
) error

CreateOrgEntitlementAudit inserts a standalone audit row (no entitlements write). Used by the suppression path, where the record exists precisely because the stored row did not change.

func (*Service) CreateOrganization

func (s *Service) CreateOrganization(ctx context.Context, org *models.Organization) error

CreateOrganization inserts an organization and releases any rename alias still holding its slug.

The release lives here, at the single choke point every creation path goes through (the API, and every connector's zero-member bootstrap), rather than in one caller: a slug held only as an alias is claimable, and once claimed it must never resolve to the renamed organization again — not even later, if the claiming organization is itself deleted (spec 2026-08-08-12).

func (*Service) CreateOrganizationMember

func (s *Service) CreateOrganizationMember(ctx context.Context, member *models.OrganizationMember) error

func (*Service) CreateOrganizationProvider

func (s *Service) CreateOrganizationProvider(ctx context.Context, provider *models.OrganizationProvider) error

func (*Service) CreateReportSchedule

func (s *Service) CreateReportSchedule(ctx context.Context, schedule *models.ReportSchedule) error

CreateReportSchedule inserts a new report schedule.

func (*Service) CreateResult

func (s *Service) CreateResult(ctx context.Context, result *models.Result) error

func (*Service) CreateResults

func (s *Service) CreateResults(ctx context.Context, results []*models.Result) error

CreateResults inserts many raw results in a single statement. See the db.Service declaration for why it exists and why it does not chunk.

func (*Service) CreateSLO

func (s *Service) CreateSLO(ctx context.Context, slo *models.SLO) error

CreateSLO inserts a new service-level objective.

func (*Service) CreateSLOAlertPolicy

func (s *Service) CreateSLOAlertPolicy(ctx context.Context, policy *models.SLOAlertPolicy) error

CreateSLOAlertPolicy inserts a new burn-rate alert policy.

func (*Service) CreateSeverity

func (s *Service) CreateSeverity(ctx context.Context, severity *models.Severity) error

CreateSeverity inserts a new severity row.

func (*Service) CreateStatusPage

func (s *Service) CreateStatusPage(ctx context.Context, page *models.StatusPage) error

CreateStatusPage inserts a new status page.

func (*Service) CreateStatusPageResource

func (s *Service) CreateStatusPageResource(
	ctx context.Context, resource *models.StatusPageResource,
) error

CreateStatusPageResource inserts a new resource.

func (*Service) CreateStatusPageSection

func (s *Service) CreateStatusPageSection(ctx context.Context, section *models.StatusPageSection) error

CreateStatusPageSection inserts a new section.

func (*Service) CreateStatusPageWithDefaultSection

func (s *Service) CreateStatusPageWithDefaultSection(
	ctx context.Context,
	page *models.StatusPage,
	section *models.StatusPageSection,
	resources []*models.StatusPageResource,
) error

CreateStatusPageWithDefaultSection inserts a status page, its default section, and every initial resource in ONE transaction — see db.Service for the atomicity contract.

func (*Service) CreateStatusUpdate

func (s *Service) CreateStatusUpdate(ctx context.Context, update *models.StatusUpdate) error

CreateStatusUpdate inserts a new status update.

func (*Service) CreateSubscriber

func (s *Service) CreateSubscriber(ctx context.Context, sub *models.StatusPageSubscriber) error

CreateSubscriber inserts a new status page subscriber row.

func (*Service) CreateUser

func (s *Service) CreateUser(ctx context.Context, user *models.User) error

func (*Service) CreateUserPasskey

func (s *Service) CreateUserPasskey(ctx context.Context, passkey *models.UserPasskey) error

CreateUserPasskey inserts a new passkey row.

func (*Service) CreateUserProvider

func (s *Service) CreateUserProvider(ctx context.Context, provider *models.UserProvider) error

func (*Service) CreateUserToken

func (s *Service) CreateUserToken(ctx context.Context, token *models.UserToken) error

func (*Service) CreateWorker

func (s *Service) CreateWorker(ctx context.Context, worker *models.Worker) error

func (*Service) DB

func (s *Service) DB() *bun.DB

DB returns the underlying bun.DB instance.

func (*Service) DeleteAgentEnrollmentToken

func (s *Service) DeleteAgentEnrollmentToken(ctx context.Context, orgUID, uid string) error

DeleteAgentEnrollmentToken soft-deletes an enrollment token.

func (*Service) DeleteChannel

func (s *Service) DeleteChannel(ctx context.Context, uid string) error

DeleteChannel soft-deletes an integration connection.

func (*Service) DeleteCheck

func (s *Service) DeleteCheck(ctx context.Context, uid string) error

func (*Service) DeleteCheckConnection

func (s *Service) DeleteCheckConnection(ctx context.Context, checkUID, connectionUID string) error

DeleteCheckConnection deletes a check-connection relationship.

func (*Service) DeleteCheckDependenciesForCheck

func (s *Service) DeleteCheckDependenciesForCheck(ctx context.Context, checkUID string) error

DeleteCheckDependenciesForCheck soft-deletes every active edge where checkUID is either the parent or the child. Called from check deletion so dependency edges don't outlive the check they reference.

func (*Service) DeleteCheckDependency

func (s *Service) DeleteCheckDependency(ctx context.Context, depUID string) error

DeleteCheckDependency soft-deletes the edge.

func (*Service) DeleteCheckGroup

func (s *Service) DeleteCheckGroup(ctx context.Context, uid string) error

func (*Service) DeleteCheckJob

func (s *Service) DeleteCheckJob(ctx context.Context, uid string) error

func (*Service) DeleteEmailSuppression

func (s *Service) DeleteEmailSuppression(ctx context.Context, uid string) error

DeleteEmailSuppression hard-deletes a suppression row by UID — this is the "re-subscribe" action (GET confirmation-page undo, or the dashboard delete). Hard delete rather than soft: there is no audit value in keeping a tombstone, and re-subscribing should be indistinguishable from never having unsubscribed. Callers scope by org first via GetEmailSuppression.

func (*Service) DeleteEscalationPolicy

func (s *Service) DeleteEscalationPolicy(ctx context.Context, policyUID string) error

DeleteEscalationPolicy soft-deletes the policy.

func (*Service) DeleteEventsBefore

func (s *Service) DeleteEventsBefore(ctx context.Context, before time.Time, limit int) (int64, error)

DeleteEventsBefore hard-deletes up to limit events created before the cutoff and reports how many rows went. Batched so a first sweep on a long-lived installation cannot hold one enormous transaction.

func (*Service) DeleteExpiredStateEntries

func (s *Service) DeleteExpiredStateEntries(ctx context.Context) (int64, error)

DeleteExpiredStateEntries removes entries past their expires_at.

func (*Service) DeleteFile

func (s *Service) DeleteFile(ctx context.Context, orgUID, uid string) error

DeleteFile soft-deletes a file by UID, scoped to org.

func (*Service) DeleteFilesByTopicPrefix

func (s *Service) DeleteFilesByTopicPrefix(ctx context.Context, orgUID, prefix string) (int, error)

DeleteFilesByTopicPrefix soft-deletes every live attachment of an org under a topic prefix and returns how many rows changed. A zero count is a normal answer (nothing was attached), never an error — the reaper runs on entities that may well have no attachments at all.

func (*Service) DeleteJob

func (s *Service) DeleteJob(ctx context.Context, uid string) error

func (*Service) DeleteMaintenanceWindow

func (s *Service) DeleteMaintenanceWindow(ctx context.Context, orgUID, uid string) error

DeleteMaintenanceWindow soft-deletes a maintenance window.

func (*Service) DeleteOnCallSchedule

func (s *Service) DeleteOnCallSchedule(ctx context.Context, scheduleUID string) error

DeleteOnCallSchedule soft-deletes the schedule. Roster and overrides are cascade-deleted by FK on hard delete; for soft delete we leave them in place — they'll be cleaned up if the schedule is purged later.

func (*Service) DeleteOnCallScheduleOverride

func (s *Service) DeleteOnCallScheduleOverride(ctx context.Context, overrideUID string) error

DeleteOnCallScheduleOverride hard-deletes the row. Overrides are short-lived; soft-delete adds no value.

func (*Service) DeleteOrgEntitlements

func (s *Service) DeleteOrgEntitlements(
	ctx context.Context, orgUID string, audit *models.OrgEntitlementAudit,
) error

DeleteOrgEntitlements drops an org's entitlements row and records the audit in the same tx.

func (*Service) DeleteOrgParameter

func (s *Service) DeleteOrgParameter(ctx context.Context, orgUID, key string) error

DeleteOrgParameter soft-deletes an org-scoped parameter.

func (*Service) DeleteOrganization

func (s *Service) DeleteOrganization(ctx context.Context, uid string) error

func (*Service) DeleteOrganizationMember

func (s *Service) DeleteOrganizationMember(ctx context.Context, uid string) error

func (*Service) DeleteOrganizationProvider

func (s *Service) DeleteOrganizationProvider(ctx context.Context, uid string) error

func (*Service) DeleteReportSchedule

func (s *Service) DeleteReportSchedule(ctx context.Context, orgUID, uid string) error

DeleteReportSchedule soft-deletes a report schedule.

func (*Service) DeleteResults

func (s *Service) DeleteResults(ctx context.Context, orgUID string, resultUIDs []string) (int64, error)

func (*Service) DeleteSLO

func (s *Service) DeleteSLO(ctx context.Context, orgUID, uid string) error

DeleteSLO soft-deletes an SLO.

func (*Service) DeleteSeverity

func (s *Service) DeleteSeverity(ctx context.Context, uid string) error

DeleteSeverity soft-deletes the row.

func (*Service) DeleteSoftDeletedJobs

func (s *Service) DeleteSoftDeletedJobs(ctx context.Context, before time.Time, limit int) (int64, error)

DeleteSoftDeletedJobs physically deletes up to `limit` jobs soft-deleted before `before`, skipping any still referenced by another job's previous_job_uid so the retry-chain FK never trips (jobs_cleanup stage 2). Mirrors the Postgres implementation (sync-pg-to-sqlite).

func (*Service) DeleteStateEntry

func (s *Service) DeleteStateEntry(ctx context.Context, orgUID *string, key string) (bool, error)

DeleteStateEntry soft-deletes a state entry, returning whether a live row existed to delete (compare-and-set on deleted_at IS NULL): false means the entry was already deleted (or never existed) — a replay of a prior consume.

func (*Service) DeleteStatusPage

func (s *Service) DeleteStatusPage(ctx context.Context, uid string) error

DeleteStatusPage soft-deletes a status page.

func (*Service) DeleteStatusPageResource

func (s *Service) DeleteStatusPageResource(ctx context.Context, uid string) error

DeleteStatusPageResource hard-deletes a resource.

func (*Service) DeleteStatusPageSection

func (s *Service) DeleteStatusPageSection(ctx context.Context, uid string) error

DeleteStatusPageSection soft-deletes a section.

func (*Service) DeleteSystemParameter

func (s *Service) DeleteSystemParameter(ctx context.Context, key string) error

DeleteSystemParameter soft-deletes a system parameter.

func (*Service) DeleteUser

func (s *Service) DeleteUser(ctx context.Context, uid string) error

func (*Service) DeleteUserContact

func (s *Service) DeleteUserContact(ctx context.Context, uid string) error

DeleteUserContact soft-deletes a contact by UID and hard-deletes the notification route that pointed at it.

The route MUST go explicitly. `user_notification_routes.contact_uid` carries an `on delete cascade` FK, but a cascade only fires on a HARD delete, so a soft-deleted contact used to leave its route behind forever: an undeletable ghost row in the dashboard, and per-dispatch warning noise in the escalation job. `user_notification_routes` has no `deleted_at` — hard delete is the design for that table.

Both writes run in one transaction, route first: if it fails midway the contact is still live and simply keeps its route, which is a consistent state. Revive is unaffected — UpsertUserContact clears deleted_at and every caller re-creates the route (CreateContact, EnsureUserNotificationRoute).

func (*Service) DeleteUserIntegrationIdentity

func (s *Service) DeleteUserIntegrationIdentity(
	ctx context.Context, integrationUID, userUID string,
) error

DeleteUserIntegrationIdentity removes a member's identity on an integration. Hard delete: the row carries no history worth keeping and the unique index on (integration_uid, external_id) must be freed immediately so the external id can be reassigned.

func (*Service) DeleteUserPasskey

func (s *Service) DeleteUserPasskey(ctx context.Context, uid string) error

DeleteUserPasskey soft-deletes a passkey.

func (*Service) DeleteUserProvider

func (s *Service) DeleteUserProvider(ctx context.Context, uid string) error

func (*Service) DeleteUserStateEntry

func (s *Service) DeleteUserStateEntry(ctx context.Context, userUID, key string) (bool, error)

DeleteUserStateEntry soft-deletes a user-scoped state entry, returning whether a live row existed to delete.

func (*Service) DeleteUserToken

func (s *Service) DeleteUserToken(ctx context.Context, uid string) (bool, error)

DeleteUserToken soft-deletes a token, returning whether a live row existed to delete (compare-and-set on deleted_at IS NULL): false means the token was already deleted — for rotating OAuth refresh grants that is a replay racing a concurrent redemption.

func (*Service) DeleteUserTokensByOrg

func (s *Service) DeleteUserTokensByOrg(ctx context.Context, orgUID string) (int, error)

DeleteUserTokensByOrg soft-deletes every token scoped to an organization (refresh tokens, PATs, OAuth grants) and returns how many rows it killed. Called when an organization is deleted so no surviving session can keep talking to it. Org-less tokens (organization_uid IS NULL) are untouched.

func (*Service) DeleteWorker

func (s *Service) DeleteWorker(ctx context.Context, uid string) error

func (*Service) EnrollAgent

func (s *Service) EnrollAgent(
	ctx context.Context, tokenHash, name, ed25519Pub, x25519Pub, fingerprint string,
) (*models.Agent, error)

EnrollAgent consumes a valid enrollment token and creates the bound agent row.

Org tokens keep their exact historical semantics: the single-use guard is the conditional UPDATE (`used_at IS NULL`), so under a concurrent double-enroll only one UPDATE affects a row and the loser rolls back with ErrEnrollmentTokenInvalid. System tokens are multi-use: the same UPDATE increments use_count under an `(max_uses IS NULL OR use_count < max_uses)` guard, which is equally race-safe (the loser of a budget-exhausting race sees zero rows) while letting every machine of a fleet enroll with its own keypair.

func (*Service) EnsureDefaultEmailRoute

func (s *Service) EnsureDefaultEmailRoute(
	ctx context.Context, userUID, orgUID, email string,
) error

EnsureDefaultEmailRoute idempotently seeds one email contact + route.

func (*Service) EnsureUserNotificationRoute

func (s *Service) EnsureUserNotificationRoute(ctx context.Context, userUID, orgUID, contactUID string) error

EnsureUserNotificationRoute idempotently creates an enabled route for an existing contact, appended after the user's current routes.

func (*Service) FindActiveBurnIncident

func (s *Service) FindActiveBurnIncident(ctx context.Context, sloUID, policyUID string) (*models.Incident, error)

FindActiveBurnIncident returns the open burn incident for one (SLO, policy).

func (*Service) FindActiveIncidentByCheckUID

func (s *Service) FindActiveIncidentByCheckUID(ctx context.Context, checkUID string) (*models.Incident, error)

func (*Service) FindActiveIncidentsForChecksInWindow

func (s *Service) FindActiveIncidentsForChecksInWindow(
	ctx context.Context, checkUIDs []string, since, until time.Time,
) ([]*models.Incident, error)

FindActiveIncidentsForChecksInWindow returns the active, non-suppressed incidents for the listed checks whose started_at is within [since, until].

func (*Service) FindAnySubscriber

func (s *Service) FindAnySubscriber(
	ctx context.Context, statusPageUID, email string, scope models.SubscriberScope, incidentUID *string,
) (*models.StatusPageSubscriber, error)

FindAnySubscriber returns the most recent subscriber matching the unique tuple, including soft-deleted rows, or sql.ErrNoRows when none exists. Used to soft-undelete on re-subscribe instead of inserting a duplicate.

func (*Service) FindCheckDependencyEdge

func (s *Service) FindCheckDependencyEdge(
	ctx context.Context, parentUID, childUID string,
) (*models.CheckDependency, error)

FindCheckDependencyEdge returns the edge for the (parent, child) pair if it exists.

func (*Service) FindIncidentPublication

func (s *Service) FindIncidentPublication(
	ctx context.Context, incidentUID, statusPageUID string,
) (*models.IncidentPublication, error)

FindIncidentPublication returns the live publication for an (incident, page) pair, or sql.ErrNoRows when there is none.

func (*Service) FindLiveSubscriber

func (s *Service) FindLiveSubscriber(
	ctx context.Context, statusPageUID, email string, scope models.SubscriberScope, incidentUID *string,
) (*models.StatusPageSubscriber, error)

FindLiveSubscriber returns the live (non-deleted) subscriber matching the unique tuple, or nil when none exists. incidentUID may be nil for page scope.

func (*Service) FindRecentlyResolvedIncidentByCheckUID

func (s *Service) FindRecentlyResolvedIncidentByCheckUID(
	ctx context.Context, checkUID string, since time.Time,
) (*models.Incident, error)

func (*Service) GetAgent

func (s *Service) GetAgent(ctx context.Context, uid string) (*models.Agent, error)

GetAgent returns an agent by UID.

func (*Service) GetAgentEnrollmentTokenByHash

func (s *Service) GetAgentEnrollmentTokenByHash(
	ctx context.Context, tokenHash string,
) (*models.AgentEnrollmentToken, error)

GetAgentEnrollmentTokenByHash returns the live token with the given hash. Kind-aware validity: an org token must still be unused (strictly one-shot), while a system token stays valid for as long as its use budget allows (max_uses NULL = unlimited) so a whole fly fleet can enroll on boot.

func (*Service) GetAppSetting

func (s *Service) GetAppSetting(ctx context.Context, key string) (string, error)

GetAppSetting returns the value for the given key. Returns sql.ErrNoRows if the key does not exist.

func (*Service) GetChannel

func (s *Service) GetChannel(ctx context.Context, uid string) (*models.Integration, error)

GetChannel retrieves an integration connection by UID.

func (*Service) GetChannelByProperty

func (s *Service) GetChannelByProperty(
	ctx context.Context, connType, propertyName, propertyValue string,
) (*models.Integration, error)

GetChannelByProperty retrieves a connection by a settings property.

func (*Service) GetChannelByPropertyForOrg

func (s *Service) GetChannelByPropertyForOrg(
	ctx context.Context, orgUID, connType, propertyName, propertyValue string,
) (*models.Integration, error)

GetChannelByPropertyForOrg is the org-scoped variant of GetChannelByProperty — same settings-property lookup, additionally filtered to a single organization so a workspace connected to several orgs resolves to that org's own row.

func (*Service) GetCheck

func (s *Service) GetCheck(ctx context.Context, orgUID, checkUID string) (*models.Check, error)

func (*Service) GetCheckByEmailToken

func (s *Service) GetCheckByEmailToken(ctx context.Context, token string) (*models.Check, error)

GetCheckByEmailToken looks up an email check by its random token. Tokens are 24 random bytes (48 hex chars), so org scoping is unnecessary — collisions are negligible globally.

func (*Service) GetCheckByUidOrSlug

func (s *Service) GetCheckByUidOrSlug(ctx context.Context, orgUID, identifier string) (*models.Check, error)

func (*Service) GetCheckConnection

func (s *Service) GetCheckConnection(
	ctx context.Context, checkUID, connectionUID string,
) (*models.CheckConnection, error)

GetCheckConnection retrieves a specific check-connection with settings.

func (*Service) GetCheckDependency

func (s *Service) GetCheckDependency(
	ctx context.Context, orgUID, depUID string,
) (*models.CheckDependency, error)

GetCheckDependency fetches a single edge by UID, scoped to its organization.

func (*Service) GetCheckGroup

func (s *Service) GetCheckGroup(ctx context.Context, orgUID, uid string) (*models.CheckGroup, error)

func (*Service) GetCheckGroupBySlug

func (s *Service) GetCheckGroupBySlug(ctx context.Context, orgUID, slug string) (*models.CheckGroup, error)

func (*Service) GetCheckGroupByUidOrSlug

func (s *Service) GetCheckGroupByUidOrSlug(
	ctx context.Context, orgUID, identifier string,
) (*models.CheckGroup, error)

func (*Service) GetCheckGroupStatusCounts

func (s *Service) GetCheckGroupStatusCounts(
	ctx context.Context, orgUID string,
) (map[string]map[models.CheckStatus]int, error)

GetCheckGroupStatusCounts returns, per check group, a count of enabled non-deleted member checks by status (spec 2026-08-01-01). One GROUP BY query over checks, dialect-neutral (no ILIKE, no Postgres-only syntax) so the same implementation works against PostgreSQL.

func (*Service) GetCheckGroupsByUIDs

func (s *Service) GetCheckGroupsByUIDs(
	ctx context.Context, orgUID string, groupUIDs []string,
) (map[string]*models.CheckGroup, error)

GetCheckGroupsByUIDs returns the requested check groups keyed by UID, in a single batched query (absent UIDs simply have no entry). Unlike GetChecksByUIDs, groupUIDs is NOT chunked: at most one entry per group incident on the page, itself capped by base.ParsePageLimit (100) — nowhere near either engine's bound-parameter ceiling.

func (*Service) GetCheckJobByUID

func (s *Service) GetCheckJobByUID(ctx context.Context, uid string) (*models.CheckJob, error)

GetCheckJobByUID returns one check job by UID.

func (*Service) GetCheckStatusCounts

func (s *Service) GetCheckStatusCounts(
	ctx context.Context, orgUID string,
) ([]models.CheckStatusCount, error)

GetCheckStatusCounts returns the org-wide (status, enabled) histogram of checks (spec 2026-08-02-06) as a single GROUP BY — never a load-all-and-count, so it stays correct and cheap past the 100-row page clamp of the list endpoint. Dialect-neutral, byte-identical in intent to the PostgreSQL twin.

The predicate deliberately mirrors what the dashboard's checks list shows: non-deleted AND non-internal. Internal checks are hidden by the list endpoint's default `internal=false` filter, so counting them here would make the KPI tiles disagree with the list the user can open. Disabled checks ARE counted (the enabled flag is a grouping dimension, not a filter) because the dashboard's down/hard-down tiles filter on status alone.

func (*Service) GetChecksByUIDs

func (s *Service) GetChecksByUIDs(
	ctx context.Context, orgUID string, checkUIDs []string,
) (map[string]*models.Check, error)

GetChecksByUIDs returns the requested checks keyed by UID, in one or more batched queries (absent UIDs — deleted or unknown — simply have no entry). Mirrors GetLabelsForChecks's shape: used to replace one GetCheck call per row with a small number of IN(...) queries for a whole response page.

func (*Service) GetDefaultStatusPage

func (s *Service) GetDefaultStatusPage(ctx context.Context, orgUID string) (*models.StatusPage, error)

GetDefaultStatusPage retrieves the default status page for an organization.

func (*Service) GetDeviceAuthRequestByDeviceCode

func (s *Service) GetDeviceAuthRequestByDeviceCode(
	ctx context.Context, deviceCode string,
) (*models.DeviceAuthRequest, error)

GetDeviceAuthRequestByDeviceCode looks up a live request by the client's device code.

func (*Service) GetDeviceAuthRequestByUserCode

func (s *Service) GetDeviceAuthRequestByUserCode(
	ctx context.Context, userCode string,
) (*models.DeviceAuthRequest, error)

GetDeviceAuthRequestByUserCode looks up a live request by its canonical (uppercase, dashless) user code.

func (*Service) GetEmailSuppression

func (s *Service) GetEmailSuppression(ctx context.Context, orgUID, uid string) (*models.EmailSuppression, error)

GetEmailSuppression returns a single suppression row scoped to an org. Returns sql.ErrNoRows when it does not exist within the given org — the handler uses this to 404 rather than deleting a row it hasn't confirmed belongs to the caller's org.

func (*Service) GetEscalationPolicy

func (s *Service) GetEscalationPolicy(
	ctx context.Context, orgUID, policyUID string,
) (*models.EscalationPolicy, error)

GetEscalationPolicy fetches a policy by UID. When orgUID is non-empty the lookup is scoped to that organization (the normal CRUD path); an empty orgUID returns the policy regardless of org (used by the escalation runtime which only knows the policy UID).

func (*Service) GetEscalationPolicyStep

func (s *Service) GetEscalationPolicyStep(
	ctx context.Context, stepUID string,
) (*models.EscalationPolicyStep, error)

GetEscalationPolicyStep loads a single step by UID. Used by the escalation runtime when a job fires and only knows its step UID.

func (*Service) GetFile

func (s *Service) GetFile(ctx context.Context, orgUID, uid string) (*models.File, error)

GetFile retrieves a file by UID for an organization, excluding soft-deleted rows.

func (*Service) GetFileAny

func (s *Service) GetFileAny(ctx context.Context, uid string) (*models.File, error)

GetFileAny retrieves a file by UID without org scoping. Used by the public signed-URL handler — the signature already proves authorization.

func (*Service) GetHeartbeatCounter

func (s *Service) GetHeartbeatCounter(ctx context.Context, orgUID, checkUID string) (int64, bool, error)

GetHeartbeatCounter returns the last accepted SP2 counter for a check, and false when the check has never accepted a signed beat.

It deliberately does NOT filter on deleted_at, because it reports what the guard above actually enforces: a soft-deleted row keeps gating the advance, so hiding it here would claim a counter of 0 for a check that is rejecting beats at counter 5. Nor does it filter on expires_at — a counter row never carries one.

func (*Service) GetIncident

func (s *Service) GetIncident(ctx context.Context, orgUID, uid string) (*models.Incident, error)

func (*Service) GetIncidentAny

func (s *Service) GetIncidentAny(ctx context.Context, uid string) (*models.Incident, error)

GetIncidentAny retrieves an incident by UID without org scoping. Used by the attachment topic authorizer, which derives the organization FROM the incident rather than trusting the caller for it.

func (*Service) GetIncidentByNumber

func (s *Service) GetIncidentByNumber(ctx context.Context, orgUID string, number int64) (*models.Incident, error)

GetIncidentByNumber resolves the short `#42` reference within an organization.

func (*Service) GetIncidentMemberCheck

func (s *Service) GetIncidentMemberCheck(
	ctx context.Context, incidentUID, checkUID string,
) (*models.IncidentMemberCheck, error)

GetIncidentMemberCheck returns a single member row, or sql.ErrNoRows.

func (*Service) GetIncidentNotification

func (s *Service) GetIncidentNotification(
	ctx context.Context, orgUID, incidentUID, notifUID string,
) (*models.IncidentNotificationRow, error)

GetIncidentNotification returns a single notification row for an org and incident, with user/connection/incident/check joined inline (mirroring the join used by ListIncidentNotifications). Returns sql.ErrNoRows when the notification does not exist within the given org and incident.

func (*Service) GetIncidentPublication

func (s *Service) GetIncidentPublication(
	ctx context.Context, orgUID, uid string,
) (*models.IncidentPublication, error)

GetIncidentPublication reads one live publication, scoped to the org.

func (*Service) GetJob

func (s *Service) GetJob(ctx context.Context, uid string) (*models.Job, error)

func (*Service) GetLabelsForCheck

func (s *Service) GetLabelsForCheck(ctx context.Context, checkUID string) ([]*models.Label, error)

func (*Service) GetLabelsForChecks

func (s *Service) GetLabelsForChecks(ctx context.Context, checkUIDs []string) (map[string][]*models.Label, error)

func (*Service) GetLastResultForChecks

func (s *Service) GetLastResultForChecks(
	ctx context.Context, orgUID string, checkUIDs []string,
) (map[string]*models.Result, error)

func (*Service) GetLastSignalForChecks

func (s *Service) GetLastSignalForChecks(
	ctx context.Context, orgUID string, checkUIDs []string,
) (map[string]*models.Result, error)

GetLastSignalForChecks returns the newest inbound-signal raw row per requested check. See the db.Service interface doc and lastSignalForChecksQuery for why this is deliberately not the same thing as GetLastResultForChecks.

func (*Service) GetMaintenanceWindow

func (s *Service) GetMaintenanceWindow(
	ctx context.Context, orgUID, uid string,
) (*models.MaintenanceWindow, error)

GetMaintenanceWindow retrieves a maintenance window by UID within an organization.

func (*Service) GetMemberByUserAndOrg

func (s *Service) GetMemberByUserAndOrg(
	ctx context.Context, userUID, orgUID string,
) (*models.OrganizationMember, error)

func (*Service) GetMembershipRequest

func (s *Service) GetMembershipRequest(
	ctx context.Context, uid string,
) (*models.MembershipRequest, error)

GetMembershipRequest fetches a request by UID with relations.

func (*Service) GetMembershipRequestByOrgAndUser

func (s *Service) GetMembershipRequestByOrgAndUser(
	ctx context.Context, orgUID, userUID string,
) (*models.MembershipRequest, error)

GetMembershipRequestByOrgAndUser returns the (org,user) row if any.

func (*Service) GetMonthlyUsage

func (s *Service) GetMonthlyUsage(
	ctx context.Context, orgUID, kind, periodStart string,
) (int, error)

GetMonthlyUsage returns the current counter value, or 0 when no row exists.

func (*Service) GetOAuthClientByClientID

func (s *Service) GetOAuthClientByClientID(ctx context.Context, clientID string) (*models.OAuthClient, error)

GetOAuthClientByClientID looks up a client by its public client_id.

func (*Service) GetOnCallSchedule

func (s *Service) GetOnCallSchedule(
	ctx context.Context, orgUID, scheduleUID string,
) (*models.OnCallSchedule, error)

GetOnCallSchedule fetches a schedule by UID, scoped to its organization when orgUID is non-empty. The resolver passes orgUID="" so it can answer questions like "who is on call for schedule X" without needing the org context — the schedule UID is globally unique.

func (*Service) GetOnCallScheduleByICalSecret

func (s *Service) GetOnCallScheduleByICalSecret(
	ctx context.Context, secret string,
) (*models.OnCallSchedule, error)

GetOnCallScheduleByICalSecret resolves the unauthenticated iCal feed URL to a schedule. Returns sql.ErrNoRows if the secret has been disabled or rotated.

func (*Service) GetOnCallScheduleOverride

func (s *Service) GetOnCallScheduleOverride(
	ctx context.Context, overrideUID string,
) (*models.OnCallScheduleOverride, error)

GetOnCallScheduleOverride fetches by override UID.

func (*Service) GetOrCreateLabel

func (s *Service) GetOrCreateLabel(ctx context.Context, orgUID, key, value string) (*models.Label, error)

func (*Service) GetOrCreateStateEntry

func (s *Service) GetOrCreateStateEntry(
	ctx context.Context, orgUID *string, key string, defaultValue *models.JSONMap, ttl *time.Duration,
) (*models.StateEntry, bool, error)

GetOrCreateStateEntry returns existing entry or creates new one.

func (*Service) GetOrCreateSystemParameter

func (s *Service) GetOrCreateSystemParameter(
	ctx context.Context, key string, value any, secret bool,
) (*models.Parameter, bool, error)

GetOrCreateSystemParameter returns the existing system parameter for key, or atomically creates it holding value. The bool reports whether this caller is the one that created it.

The insert rides the partial unique index parameters_system_key_idx (key WHERE deleted_at IS NULL AND organization_uid IS NULL) with ON CONFLICT DO NOTHING, then re-reads on a lost race — the GetOrCreateStateEntry pattern. A read-then-write would let concurrent pods each persist their own generated value; here every loser adopts the winner's.

func (*Service) GetOrgAvailability24h

func (s *Service) GetOrgAvailability24h(
	ctx context.Context, orgUID string, since, now time.Time,
) (models.AvailabilityCounts, error)

GetOrgAvailability24h returns the org's combined (success, countable-total) tally over [since, now) (spec 2026-08-26-09) — the query behind the dashboard's "24h Availability" KPI, which the old client-side computation could never produce a real number for (the day bucket it queried never exists for "today").

TWO tier-aligned SQL aggregates, mirroring uptimebar's split (uptimebar/window.go) and for the same reason: `results` has exactly two useful indexes and both are PARTIAL (period_type = 'raw' vs. <> 'raw'), so a predicate straddling both tiers forces a full scan. Each half rides its own partial index:

  • `hour` rollup rows already encode CountsAsUp into successful_checks/total_checks (the aggregation job folds warning into "up" when it writes the bucket), so this tier is a plain SUM.
  • `raw` rows are folded with the same predicate as models.RawAvailability (ExcludedFromAvailability excludes lifecycle markers + abandoned; CountsAsUp counts up + warning) — done in SQL, not by loading rows into Go, because an org's trailing 24h of raw data can be the bulk of everything it has.

day/month rollups are deliberately excluded: their period_start granularity (UTC midnight / month start) means a bucket can only start inside a trailing-24h window on the day it is created, and the aggregation job never creates a day row for "today" — it only compacts once the hour-retention window has passed (job_aggregation.go). So day/month rows never carry data for this window; including that tier would only cost a query for nothing.

Raw and hour rows in the window are disjoint by construction — the aggregation job deletes the raw rows it rolls up in the same transaction — so summing both tiers never double-counts.

func (*Service) GetOrgDefaultSeverity

func (s *Service) GetOrgDefaultSeverity(
	ctx context.Context, orgUID string,
) (*models.Severity, error)

GetOrgDefaultSeverity returns the org's current default severity.

func (*Service) GetOrgEntitlements

func (s *Service) GetOrgEntitlements(
	ctx context.Context, orgUID string,
) (*models.OrgEntitlements, error)

GetOrgEntitlements fetches the entitlement row for an org. Returns (nil, nil) when no row exists — the resolver merges defaults instead of erroring.

func (*Service) GetOrgNotification

func (s *Service) GetOrgNotification(
	ctx context.Context, orgUID, notifUID string,
) (*models.IncidentNotificationRow, error)

GetOrgNotification returns a single notification row scoped only by org UID (no incident required). Returns sql.ErrNoRows when not found.

func (*Service) GetOrgParameter

func (s *Service) GetOrgParameter(ctx context.Context, orgUID, key string) (*models.Parameter, error)

GetOrgParameter retrieves an org-scoped parameter by orgUID and key.

func (*Service) GetOrganization

func (s *Service) GetOrganization(ctx context.Context, uid string) (*models.Organization, error)

func (*Service) GetOrganizationByPreviousSlug

func (s *Service) GetOrganizationByPreviousSlug(ctx context.Context, slug string) (*models.Organization, error)

GetOrganizationByPreviousSlug resolves a rename alias to its organization.

It deliberately delegates the second hop to GetOrganization, which filters `deleted_at IS NULL`: a soft-deleted organization must never be reachable through its previous slug (spec 2026-08-08-11 — a deleted org's slug 404s immediately, with no alias, tombstone or redirect).

Callers must try GetOrganizationBySlug FIRST; a live org always wins over an alias.

func (*Service) GetOrganizationBySlug

func (s *Service) GetOrganizationBySlug(ctx context.Context, slug string) (*models.Organization, error)

func (*Service) GetOrganizationMember

func (s *Service) GetOrganizationMember(ctx context.Context, uid string) (*models.OrganizationMember, error)

func (*Service) GetOrganizationProvider

func (s *Service) GetOrganizationProvider(ctx context.Context, uid string) (*models.OrganizationProvider, error)

func (*Service) GetOrganizationProviderByProviderID

func (s *Service) GetOrganizationProviderByProviderID(
	ctx context.Context, providerType models.ProviderType, providerID string,
) (*models.OrganizationProvider, error)

func (*Service) GetReportSchedule

func (s *Service) GetReportSchedule(ctx context.Context, orgUID, uid string) (*models.ReportSchedule, error)

GetReportSchedule retrieves a report schedule by UID within an organization.

func (*Service) GetResult

func (s *Service) GetResult(ctx context.Context, uid string) (*models.Result, error)

func (*Service) GetResultNeighbors

func (s *Service) GetResultNeighbors(
	ctx context.Context, orgUID, checkUID, periodType string, regions []string,
	pivotStart time.Time, pivotUID string,
) (string, string, error)

GetResultNeighbors returns the next-older and next-newer UIDs relative to the pivot, scoped to organization+check+periodType (and optionally regions). See db.Service for the full contract.

func (*Service) GetSLO

func (s *Service) GetSLO(ctx context.Context, orgUID, uid string) (*models.SLO, error)

GetSLO retrieves an SLO by UID within an organization.

func (*Service) GetSLOAlertPolicy

func (s *Service) GetSLOAlertPolicy(ctx context.Context, orgUID, uid string) (*models.SLOAlertPolicy, error)

GetSLOAlertPolicy retrieves one policy by UID within an organization.

func (*Service) GetSLOBySlug

func (s *Service) GetSLOBySlug(ctx context.Context, orgUID, slug string) (*models.SLO, error)

GetSLOBySlug retrieves an SLO by its per-org slug.

func (*Service) GetSeverity

func (s *Service) GetSeverity(
	ctx context.Context, orgUID, identifier string,
) (*models.Severity, error)

GetSeverity fetches a live severity by uid OR slug, scoped to the org.

func (*Service) GetSlackChannelForOrg

func (s *Service) GetSlackChannelForOrg(ctx context.Context, orgUID string) (*models.Integration, error)

GetSlackChannelForOrg returns the first enabled Slack channel for the org.

func (*Service) GetStateEntry

func (s *Service) GetStateEntry(ctx context.Context, orgUID *string, key string) (*models.StateEntry, error)

GetStateEntry retrieves a state entry by organization and key.

func (*Service) GetStatusPage

func (s *Service) GetStatusPage(ctx context.Context, orgUID, uid string) (*models.StatusPage, error)

GetStatusPage retrieves a status page by UID within an organization.

func (*Service) GetStatusPageByCustomDomain

func (s *Service) GetStatusPageByCustomDomain(ctx context.Context, domain string) (*models.StatusPage, error)

GetStatusPageByCustomDomain retrieves the single live status page bound to a custom domain. The custom_domain column is globally unique among live rows, so at most one row matches.

func (*Service) GetStatusPageBySlug

func (s *Service) GetStatusPageBySlug(ctx context.Context, orgUID, slug string) (*models.StatusPage, error)

GetStatusPageBySlug retrieves a status page by slug within an organization.

func (*Service) GetStatusPageByUidOrSlug

func (s *Service) GetStatusPageByUidOrSlug(
	ctx context.Context, orgUID, identifier string,
) (*models.StatusPage, error)

GetStatusPageByUidOrSlug retrieves a status page by UID or slug.

func (*Service) GetStatusPageResource

func (s *Service) GetStatusPageResource(
	ctx context.Context, sectionUID, uid string,
) (*models.StatusPageResource, error)

GetStatusPageResource retrieves a resource by UID within a section.

func (*Service) GetStatusPageSection

func (s *Service) GetStatusPageSection(
	ctx context.Context, pageUID, uid string,
) (*models.StatusPageSection, error)

GetStatusPageSection retrieves a section by UID within a status page.

func (*Service) GetStatusPageSectionBySlug

func (s *Service) GetStatusPageSectionBySlug(
	ctx context.Context, pageUID, slug string,
) (*models.StatusPageSection, error)

GetStatusPageSectionBySlug retrieves a section by slug within a status page.

func (*Service) GetStatusUpdateByUID

func (s *Service) GetStatusUpdateByUID(ctx context.Context, uid string) (*models.StatusUpdate, error)

GetStatusUpdateByUID retrieves a status update by UID.

func (*Service) GetSubscriber

func (s *Service) GetSubscriber(
	ctx context.Context, statusPageUID, uid string,
) (*models.StatusPageSubscriber, error)

GetSubscriber retrieves a non-deleted subscriber by UID, scoped to the page.

func (*Service) GetSubscriberByConfirmToken

func (s *Service) GetSubscriberByConfirmToken(
	ctx context.Context, token string,
) (*models.StatusPageSubscriber, error)

GetSubscriberByConfirmToken retrieves a non-deleted subscriber by confirm token.

func (*Service) GetSubscriberByUnsubToken

func (s *Service) GetSubscriberByUnsubToken(
	ctx context.Context, token string,
) (*models.StatusPageSubscriber, error)

GetSubscriberByUnsubToken retrieves a non-deleted subscriber by unsubscribe token.

func (*Service) GetSystemParameter

func (s *Service) GetSystemParameter(ctx context.Context, key string) (*models.Parameter, error)

GetSystemParameter retrieves a system parameter by key. Returns (nil, nil) if not found - this is intentional to distinguish "not found" from actual errors.

func (*Service) GetUser

func (s *Service) GetUser(ctx context.Context, uid string) (*models.User, error)

func (*Service) GetUserByEmail

func (s *Service) GetUserByEmail(ctx context.Context, email string) (*models.User, error)

func (*Service) GetUserContact

func (s *Service) GetUserContact(ctx context.Context, uid string) (*models.UserContact, error)

GetUserContact returns a single non-deleted contact by UID.

func (*Service) GetUserIntegrationIdentity

func (s *Service) GetUserIntegrationIdentity(
	ctx context.Context, integrationUID, userUID string,
) (*models.UserIntegrationIdentity, error)

GetUserIntegrationIdentity returns one member's identity on an integration, or nil (no error) when the member has none.

func (*Service) GetUserPasskey

func (s *Service) GetUserPasskey(ctx context.Context, uid string) (*models.UserPasskey, error)

GetUserPasskey returns a non-deleted passkey by uid.

func (*Service) GetUserPasskeyByCredentialID

func (s *Service) GetUserPasskeyByCredentialID(
	ctx context.Context, credentialID []byte,
) (*models.UserPasskey, error)

GetUserPasskeyByCredentialID looks a passkey up by its WebAuthn credential ID. Used during the assertion-verification step.

func (*Service) GetUserProvider

func (s *Service) GetUserProvider(ctx context.Context, uid string) (*models.UserProvider, error)

func (*Service) GetUserProviderByProviderID

func (s *Service) GetUserProviderByProviderID(
	ctx context.Context, providerType models.ProviderType, providerID string,
) (*models.UserProvider, error)

func (*Service) GetUserStateEntry

func (s *Service) GetUserStateEntry(ctx context.Context, userUID, key string) (*models.StateEntry, error)

GetUserStateEntry retrieves a user-scoped state entry by user and key.

The org-scoped GetStateEntry above cannot serve this: passing a nil orgUID selects on `organization_uid IS NULL`, which matches every user's row at once. Scoping on user_uid is what makes one user's UI state invisible to another's.

func (*Service) GetUserToken

func (s *Service) GetUserToken(ctx context.Context, uid string) (*models.UserToken, error)

func (*Service) GetUserTokenByToken

func (s *Service) GetUserTokenByToken(ctx context.Context, tokenValue string) (*models.UserToken, error)

func (*Service) GetWorker

func (s *Service) GetWorker(ctx context.Context, uid string) (*models.Worker, error)

func (*Service) GetWorkerBySlug

func (s *Service) GetWorkerBySlug(ctx context.Context, slug string) (*models.Worker, error)

func (*Service) HasRawResultWithMessageID

func (s *Service) HasRawResultWithMessageID(
	ctx context.Context, orgUID, checkUID, messageID string, since time.Time,
) (bool, error)

HasRawResultWithMessageID reports whether a raw result for the check already carries output.messageId == messageID, among rows with period_start >= since. Mirrors the Postgres JSONB query with SQLite's json_extract; see the db.Service doc for why the caller must bound the window (spec 2026-08-22-01).

The leading organization_uid / check_uid / period_start clauses match results_raw_idx exactly. SQLite has no skip-scan to fall back on, so without the org column this would be a full scan of `results` on every inbound email.

func (*Service) IncrementUsageCounter

func (s *Service) IncrementUsageCounter(
	ctx context.Context, orgUID, kind, periodStart string,
) error

IncrementUsageCounter adds one to the (orgUID, kind, periodStart) counter, creating the row when absent. Unconditional by design: it records an event that already happened, so unlike ReserveMonthlyUsage there is no cap to lose the race against.

func (*Service) Initialize

func (s *Service) Initialize(ctx context.Context) error

Initialize sets up the database schema using migrations.

The integrity guard runs twice on purpose: once BEFORE migrating, to verify (and, on a database that predates the guard, to backfill) the checksums of what is already applied, and once after, to record what this boot just applied. Verifying first is what turns a rewritten-after-apply migration into a loud startup failure instead of a database that silently lacks the DDL (spec 2026-08-18-02).

func (*Service) IsEmailSuppressed

func (s *Service) IsEmailSuppressed(ctx context.Context, orgUID, email, checkUID string) (bool, error)

IsEmailSuppressed reports whether (org, email) is currently suppressed for checkUID — either by a check-specific row (check_uid = checkUID) or an org-wide row (check_uid IS NULL). checkUID may be empty for a suppression-scope check that only cares about the org-wide row (e.g. a non-incident context); in that case only the org-wide row is consulted.

func (*Service) ListActiveAgentsByRegion

func (s *Service) ListActiveAgentsByRegion(
	ctx context.Context, orgUID, region string,
) ([]*models.Agent, error)

ListActiveAgentsByRegion returns the active agents bound to a private region.

func (*Service) ListActiveBurnIncidentsForSLOs

func (s *Service) ListActiveBurnIncidentsForSLOs(
	ctx context.Context, orgUID string, sloUIDs []string,
) ([]*models.Incident, error)

ListActiveBurnIncidentsForSLOs returns every open burn incident bound to any of the given SLOs — one query for a whole list page.

func (*Service) ListAgentEnrollmentTokens

func (s *Service) ListAgentEnrollmentTokens(
	ctx context.Context, orgUID string,
) ([]*models.AgentEnrollmentToken, error)

ListAgentEnrollmentTokens lists an org's live (unused, unexpired) tokens, plus recently-used ones (db.UsedEnrollmentTokenListWindow) so the UI can report a consumed token's outcome. View-only: enrollment still requires an unused token.

func (*Service) ListAgents

func (s *Service) ListAgents(ctx context.Context, orgUID string) ([]*models.Agent, error)

ListAgents lists an org's agents (active and revoked, not deleted).

func (*Service) ListAllAgents

func (s *Service) ListAllAgents(ctx context.Context) ([]*models.Agent, error)

ListAllAgents lists every non-deleted agent across all organizations, both org and system kind (active and revoked), for the fleet-wide operator view. Ordered by kind, region, name for a stable, grouped listing.

func (*Service) ListAttachmentsByTopicPrefix

func (s *Service) ListAttachmentsByTopicPrefix(
	ctx context.Context, prefix string, before time.Time, limit int,
) ([]*models.File, error)

ListAttachmentsByTopicPrefix returns live attachment rows across all orgs under a topic prefix, older than `before`, capped at limit. Cross-org because its only caller is the GC sweep.

func (*Service) ListChannels

func (s *Service) ListChannels(
	ctx context.Context, filter *models.ListIntegrationsFilter,
) ([]*models.Integration, error)

ListChannels lists integration connections with optional filtering. An empty filter.OrganizationUID lists across ALL organizations — used by CountInstalledTeams, which needs a global view of Slack connections. Every other caller passes a real org UID, so this is a no-op for them.

func (*Service) ListChannelsByProperty

func (s *Service) ListChannelsByProperty(
	ctx context.Context, connType, propertyName, propertyValue string,
) ([]*models.Integration, error)

ListChannelsByProperty returns every non-deleted connection matching a settings property, across ALL organizations, ordered created_at ASC (oldest first). See db.Service for the callers (uninstall fan-out and the inbound-routing deterministic fallback).

func (*Service) ListChannelsForCheck

func (s *Service) ListChannelsForCheck(
	ctx context.Context, checkUID string,
) ([]*models.Integration, error)

ListChannelsForCheck returns all connections associated with a check.

func (*Service) ListCheckConnectionsWithSettings

func (s *Service) ListCheckConnectionsWithSettings(
	ctx context.Context, checkUID string,
) ([]*models.CheckConnection, error)

ListCheckConnectionsWithSettings returns all check-connections for a check including settings.

func (*Service) ListCheckDependenciesByOrg

func (s *Service) ListCheckDependenciesByOrg(
	ctx context.Context, orgUID string,
) ([]*models.CheckDependency, error)

ListCheckDependenciesByOrg returns every active edge in the org.

func (*Service) ListCheckDependencyChildren

func (s *Service) ListCheckDependencyChildren(
	ctx context.Context, parentCheckUID string,
) ([]*models.CheckDependency, error)

ListCheckDependencyChildren returns the active edges where this check is the parent.

func (*Service) ListCheckDependencyParents

func (s *Service) ListCheckDependencyParents(
	ctx context.Context, childCheckUID string,
) ([]*models.CheckDependency, error)

ListCheckDependencyParents returns the active edges where this check is the child.

func (*Service) ListCheckGroups

func (s *Service) ListCheckGroups(ctx context.Context, orgUID string) ([]*models.CheckGroup, error)

func (*Service) ListCheckJobsByCheckUID

func (s *Service) ListCheckJobsByCheckUID(ctx context.Context, checkUID string) ([]*models.CheckJob, error)

func (*Service) ListCheckJobsByRegion

func (s *Service) ListCheckJobsByRegion(ctx context.Context, region string) ([]*models.CheckJob, error)

ListCheckJobsByRegion returns every check_job carrying the given region slug, across all organizations. See db.Service for the full contract.

func (*Service) ListCheckUIDsByGroup

func (s *Service) ListCheckUIDsByGroup(
	ctx context.Context, orgUID, groupUID string,
) ([]string, error)

ListCheckUIDsByGroup returns the UIDs of the group's enabled, non-deleted member checks — deliberately the same member predicate as GetCheckGroupStatusCounts so a group's rolled-up status and its aggregated availability always describe the same set of checks (spec 2026-08-01-03).

func (*Service) ListChecks

func (s *Service) ListChecks(
	ctx context.Context, orgUID string, filter *models.ListChecksFilter,
) ([]*models.Check, int64, error)

func (*Service) ListChecksByTunnelCheckUID

func (s *Service) ListChecksByTunnelCheckUID(
	ctx context.Context, orgUID, tunnelCheckUID string,
) ([]*models.Check, error)

ListChecksByTunnelCheckUID returns the org's non-deleted checks whose config references the given SSH check as their tunnel. Mirrors the Postgres JSONB query with SQLite's json_extract.

func (*Service) ListChecksReferencingRegion

func (s *Service) ListChecksReferencingRegion(ctx context.Context, region string) ([]*models.Check, error)

ListChecksReferencingRegion returns every non-deleted check that names the region in `checks.regions` OR owns a check_jobs row carrying it, across all organizations. See db.Service for the full contract.

func (*Service) ListChecksWithStaleJobPeriods

func (s *Service) ListChecksWithStaleJobPeriods(ctx context.Context) ([]*models.Check, error)

ListChecksWithStaleJobPeriods returns enabled, non-deleted checks that have at least one check_job whose period no longer matches the check's own period (spec 2026-07-20-05). Byte-for-byte the postgres twin's shape so the startup reconcile behaves identically on both backends; period is the canonical HH:MM:SS text, so a split-period job never text-equals its check's period.

func (*Service) ListChecksWithStaleJobRegions

func (s *Service) ListChecksWithStaleJobRegions(ctx context.Context) ([]*models.Check, error)

ListChecksWithStaleJobRegions returns enabled, non-deleted checks whose check_jobs no longer line up with `checks.regions`. Mirrors the Postgres twin's shape so the startup reconcile behaves identically on both backends. See db.Service for the full contract.

func (*Service) ListConfirmedSubscribers

func (s *Service) ListConfirmedSubscribers(
	ctx context.Context, statusPageUID string, incidentUID *string,
) ([]*models.StatusPageSubscriber, error)

ListConfirmedSubscribers returns confirmed, non-deleted subscribers for the page: all page-scoped subscribers plus incident-scoped subscribers matching incidentUID (when provided).

func (*Service) ListDefaultChannels

func (s *Service) ListDefaultChannels(
	ctx context.Context, orgUID string,
) ([]*models.Integration, error)

ListDefaultChannels returns all default connections for an organization.

func (*Service) ListDistinctLabelKeys

func (s *Service) ListDistinctLabelKeys(
	ctx context.Context, orgUID, query string, limit int,
) ([]models.LabelSuggestion, error)

ListDistinctLabelKeys returns distinct label keys used by checks in the org, sorted by usage count DESC then key ASC. SQLite uses LOWER(...) + LIKE since it has no ILIKE.

func (*Service) ListDistinctLabelValues

func (s *Service) ListDistinctLabelValues(
	ctx context.Context, orgUID, key, query string, limit int,
) ([]models.LabelSuggestion, error)

ListDistinctLabelValues returns distinct values for a given label key in the org, sorted by usage count DESC then value ASC. SQLite variant.

func (*Service) ListEmailSuppressions

func (s *Service) ListEmailSuppressions(ctx context.Context, orgUID string) ([]*models.EmailSuppression, error)

ListEmailSuppressions returns every suppression row for an org, newest first — backs the dashboard suppression list (D4).

func (*Service) ListEnabledReportSchedules

func (s *Service) ListEnabledReportSchedules(ctx context.Context) ([]*models.ReportSchedule, error)

ListEnabledReportSchedules returns every enabled schedule across all orgs.

func (*Service) ListEnabledSLOAlertPolicies

func (s *Service) ListEnabledSLOAlertPolicies(ctx context.Context, limit int) ([]*models.SLOAlertPolicy, error)

ListEnabledSLOAlertPolicies returns the burn evaluator's work queue.

Joined to `slos` so a policy attached to a disabled or soft-deleted SLO is never evaluated: disabling the objective has to stop the paging, or "turn it off" would not mean what an operator expects.

Ordered oldest-evaluated first (NULLs, i.e. never evaluated, first) so a bounded per-sweep limit still gives every policy a turn on a large install instead of starving the tail forever.

func (*Service) ListEscalationPolicies

func (s *Service) ListEscalationPolicies(
	ctx context.Context, orgUID string,
) ([]*models.EscalationPolicy, error)

ListEscalationPolicies returns all policies for an org, ordered by name.

func (*Service) ListEscalationPolicySteps

func (s *Service) ListEscalationPolicySteps(
	ctx context.Context, policyUID string,
) ([]*models.EscalationPolicyStep, error)

ListEscalationPolicySteps returns the steps of a policy ordered by position.

func (*Service) ListEscalationPolicyTargets

func (s *Service) ListEscalationPolicyTargets(
	ctx context.Context, stepUIDs []string,
) ([]*models.EscalationPolicyTarget, error)

ListEscalationPolicyTargets returns the targets attached to any of the given step UIDs. Empty input yields nil.

func (*Service) ListEvents

func (s *Service) ListEvents(ctx context.Context, filter *models.ListEventsFilter) ([]*models.Event, error)

func (*Service) ListExpiredSnoozedIncidents

func (s *Service) ListExpiredSnoozedIncidents(ctx context.Context, now time.Time) ([]*models.Incident, error)

func (*Service) ListFiles

func (s *Service) ListFiles(
	ctx context.Context, orgUID string, filter models.ListFilesFilter,
) ([]*models.File, int64, error)

ListFiles returns files for an organization with optional substring search on name.

func (*Service) ListIncidentMemberChecks

func (s *Service) ListIncidentMemberChecks(
	ctx context.Context, incidentUID string,
) ([]*models.IncidentMemberCheck, error)

ListIncidentMemberChecks returns all member rows for a group incident.

func (*Service) ListIncidentMemberChecksByIncidentUIDs

func (s *Service) ListIncidentMemberChecksByIncidentUIDs(
	ctx context.Context, incidentUIDs []string,
) (map[string][]*models.IncidentMemberCheck, error)

ListIncidentMemberChecksByIncidentUIDs returns member rows for several group incidents at once, grouped by incident UID. A single batched query replaces one ListIncidentMemberChecks call per group incident on a response page. Unlike GetChecksByUIDs, incidentUIDs is NOT chunked: it is at most one entry per incident on the page, and the page itself is capped by base.ParsePageLimit (100) — nowhere near either engine's bound-parameter ceiling.

func (*Service) ListIncidentNotifications

func (s *Service) ListIncidentNotifications(
	ctx context.Context, orgUID string, filter db.ListIncidentNotificationsFilter,
) ([]*models.IncidentNotificationRow, error)

ListIncidentNotifications returns notification rows for an org, optionally filtered by incident, user, connection, status, and a before-cursor. Results are ordered newest first. User and connection names are joined inline.

func (*Service) ListIncidentPublications

func (s *Service) ListIncidentPublications(
	ctx context.Context, filter *models.ListIncidentPublicationsFilter,
) ([]*models.IncidentPublication, error)

ListIncidentPublications returns publications matching the filter, newest first.

func (*Service) ListIncidents

func (s *Service) ListIncidents(
	ctx context.Context, filter *models.ListIncidentsFilter,
) ([]*models.Incident, int64, error)

func (*Service) ListJobs

func (s *Service) ListJobs(ctx context.Context, orgUID *string, limit int) ([]*models.Job, error)

func (*Service) ListLiveWorkers

func (s *Service) ListLiveWorkers(ctx context.Context, since time.Time) ([]*models.Worker, error)

func (*Service) ListMaintenanceWindowChecks

func (s *Service) ListMaintenanceWindowChecks(
	ctx context.Context, windowUID string,
) ([]*models.MaintenanceWindowCheck, error)

ListMaintenanceWindowChecks lists all check associations for a maintenance window.

func (*Service) ListMaintenanceWindows

func (s *Service) ListMaintenanceWindows(
	ctx context.Context, orgUID string, filter models.ListMaintenanceWindowsFilter,
) ([]*models.MaintenanceWindow, error)

ListMaintenanceWindows lists maintenance windows for an organization with optional filtering.

func (*Service) ListMaintenanceWindowsForCheck

func (s *Service) ListMaintenanceWindowsForCheck(
	ctx context.Context, checkUID string,
) ([]*models.MaintenanceWindow, error)

ListMaintenanceWindowsForCheck returns every non-deleted maintenance window linked to the check directly or via its group. It does not filter by start time or evaluate recurrence — callers decide active/inactive via models.IsActiveAt so an in-process TTL cache can re-evaluate the same rows at a later clock (including windows that only become active after the fetch).

func (*Service) ListMaintenanceWindowsForCheckGroup

func (s *Service) ListMaintenanceWindowsForCheckGroup(
	ctx context.Context, groupUID string,
) ([]*models.MaintenanceWindow, error)

ListMaintenanceWindowsForCheckGroup returns every non-deleted maintenance window that puts the group in maintenance: one targeting the group directly, or one targeting any of its enabled, non-deleted member checks (spec 2026-08-01-03). Recurrence is not evaluated here — callers use models.IsActiveAt.

func (*Service) ListMembersByOrg

func (s *Service) ListMembersByOrg(ctx context.Context, orgUID string) ([]*models.OrganizationMember, error)

func (*Service) ListMembersByUser

func (s *Service) ListMembersByUser(ctx context.Context, userUID string) ([]*models.OrganizationMember, error)

func (*Service) ListMembershipRequests

func (s *Service) ListMembershipRequests(
	ctx context.Context, filter models.ListMembershipRequestsFilter,
) ([]*models.MembershipRequest, error)

ListMembershipRequests returns requests matching the filter, ordered by most recently created first.

func (*Service) ListOnCallScheduleOverrides

func (s *Service) ListOnCallScheduleOverrides(
	ctx context.Context, scheduleUID string, from, until *time.Time,
) ([]*models.OnCallScheduleOverride, error)

ListOnCallScheduleOverrides returns overrides for a schedule, optionally bounded by a window.

func (*Service) ListOnCallScheduleUsers

func (s *Service) ListOnCallScheduleUsers(
	ctx context.Context, scheduleUID string,
) ([]*models.OnCallScheduleUser, error)

ListOnCallScheduleUsers returns the roster ordered by position.

func (*Service) ListOnCallSchedules

func (s *Service) ListOnCallSchedules(
	ctx context.Context, orgUID string,
) ([]*models.OnCallSchedule, error)

ListOnCallSchedules returns all schedules for an org, ordered by name.

func (*Service) ListOrgCheckRates

func (s *Service) ListOrgCheckRates(ctx context.Context, orgUID string) ([]models.CheckRate, error)

ListOrgCheckRates returns (uid, enabled, period, regions, type) for all non-deleted, non-internal checks of the given org. Used by the entitlements service to compute usage stats and enforce MaxChecks. No SQL arithmetic — the per-minute rate is summed in Go.

func (*Service) ListOrgEntitlementAudits

func (s *Service) ListOrgEntitlementAudits(
	ctx context.Context, filter models.ListOrgEntitlementAuditsFilter,
) ([]*models.OrgEntitlementAudit, error)

ListOrgEntitlementAudits returns audit rows for an org, newest first.

func (*Service) ListOrgParametersByKey

func (s *Service) ListOrgParametersByKey(ctx context.Context, key string) ([]*models.Parameter, error)

ListOrgParametersByKey returns all org-scoped parameters with a specific key.

func (*Service) ListOrganizationPreviousSlugs

func (s *Service) ListOrganizationPreviousSlugs(
	ctx context.Context, orgUID string,
) ([]*models.OrganizationPreviousSlug, error)

ListOrganizationPreviousSlugs returns an organization's live aliases, newest first.

func (*Service) ListOrganizationProviders

func (s *Service) ListOrganizationProviders(
	ctx context.Context, orgUID string,
) ([]*models.OrganizationProvider, error)

func (*Service) ListOrganizations

func (s *Service) ListOrganizations(ctx context.Context) ([]*models.Organization, error)

func (*Service) ListPublicStatusUpdates

func (s *Service) ListPublicStatusUpdates(
	ctx context.Context, statusPageUID string, historyDays int,
) ([]*db.PublicStatusUpdate, error)

ListPublicStatusUpdates returns recent status updates for a status page within the given history window. Returns an empty slice when the status_updates table does not yet exist.

func (*Service) ListPurgeableRevokedAgents

func (s *Service) ListPurgeableRevokedAgents(ctx context.Context, cutoff time.Time) ([]*models.Agent, error)

ListPurgeableRevokedAgents returns live agents (any kind) whose revocation is older than cutoff — a revoked agent is dead by admin decision, and nobody is waiting for it to come back. The clock is revoked_at, not last_seen_at (revoking a still-connected agent must not reset it, and an agent revoked before it ever connected has no last_seen_at at all). A legacy/inconsistent revoked row with a NULL revoked_at falls back to updated_at so it is still eventually collected instead of becoming permanently immortal.

func (*Service) ListReportSchedules

func (s *Service) ListReportSchedules(ctx context.Context, orgUID string) ([]*models.ReportSchedule, error)

ListReportSchedules lists an organization's report schedules.

func (*Service) ListResults

func (s *Service) ListResults(
	ctx context.Context, filter *models.ListResultsFilter,
) (*models.ListResultsResponse, error)

func (*Service) ListSLOAlertPolicies

func (s *Service) ListSLOAlertPolicies(ctx context.Context, sloUID string) ([]*models.SLOAlertPolicy, error)

ListSLOAlertPolicies lists one SLO's policies, fast before slow so the API and the dashboard always render them in escalating order.

func (*Service) ListSLOs

func (s *Service) ListSLOs(
	ctx context.Context, orgUID string, filter models.ListSLOsFilter,
) ([]*models.SLO, error)

ListSLOs lists an organization's SLOs.

func (*Service) ListSLOsForChecks

func (s *Service) ListSLOsForChecks(
	ctx context.Context, orgUID string, checkUIDs []string,
) ([]*models.SLO, error)

ListSLOsForChecks returns the live SLOs scoped directly to any of the checks.

func (*Service) ListSelectorSectionPageUIDs

func (s *Service) ListSelectorSectionPageUIDs(ctx context.Context, orgUID string) ([]string, error)

ListSelectorSectionPageUIDs returns the UIDs of every live status page in the organization that owns at least one live selector-bearing section — the set the reconciler has to revisit after a check write. Pages with no dynamic section are never loaded, which is what keeps a check create cheap in the overwhelmingly common case of an org that uses none.

func (*Service) ListSeverities

func (s *Service) ListSeverities(
	ctx context.Context, filter *models.ListSeveritiesFilter,
) ([]*models.Severity, error)

ListSeverities returns every live severity in the org.

func (*Service) ListStaleSystemAgents

func (s *Service) ListStaleSystemAgents(ctx context.Context, cutoff time.Time) ([]*models.Agent, error)

ListStaleSystemAgents returns live system agents last seen before cutoff (an agent that never connected is judged on enrolled_at). Org agents are user-managed and deliberately excluded — see the agent_gc job.

func (*Service) ListStateEntries

func (s *Service) ListStateEntries(
	ctx context.Context, orgUID *string, keyPrefix string,
) ([]*models.StateEntry, error)

ListStateEntries returns all entries matching the key prefix.

func (*Service) ListStatusPageResources

func (s *Service) ListStatusPageResources(
	ctx context.Context, sectionUID string,
) ([]*models.StatusPageResource, error)

ListStatusPageResources lists all resources for a section, ordered by position.

func (*Service) ListStatusPageSections

func (s *Service) ListStatusPageSections(
	ctx context.Context, pageUID string,
) ([]*models.StatusPageSection, error)

ListStatusPageSections lists all sections for a status page, ordered by position.

func (*Service) ListStatusPageTargetsForCheck

func (s *Service) ListStatusPageTargetsForCheck(
	ctx context.Context, checkUID string, checkGroupUID *string,
) ([]*db.StatusPageTarget, error)

ListStatusPageTargetsForCheck returns every live status-page resource that displays the check — directly, or through the check's group.

Written as raw SQL rather than through the query builder: this is a three-table join with no bun model behind it — the result set is a projection, not a row of any one table — so the Model-less TableExpr/ColumnExpr/Join form buys nothing but indirection over the join this actually is. `ListPublicStatusUpdates` is written the same way for the same reason. Placeholders are bun's `?`, never Postgres `$1`: bun formats the query itself and only substitutes `?`.

func (*Service) ListStatusPages

func (s *Service) ListStatusPages(ctx context.Context, orgUID string) ([]*models.StatusPage, error)

ListStatusPages lists all status pages for an organization.

func (*Service) ListStatusPagesWithCustomDomain

func (s *Service) ListStatusPagesWithCustomDomain(ctx context.Context) ([]*models.StatusPage, error)

ListStatusPagesWithCustomDomain lists every live status page (all orgs) with a custom domain set — the periodic re-verify job's work list.

func (*Service) ListStatusUpdates

func (s *Service) ListStatusUpdates(
	ctx context.Context, orgUID string, filter models.StatusUpdatesFilter,
) ([]*models.StatusUpdate, error)

ListStatusUpdates returns status updates for an org, filtered and ordered by published_at DESC.

func (*Service) ListSubscribers

func (s *Service) ListSubscribers(
	ctx context.Context, statusPageUID string,
) ([]*models.StatusPageSubscriber, error)

ListSubscribers returns all non-deleted subscribers for a page (admin view).

func (*Service) ListSuppressedChildIncidents

func (s *Service) ListSuppressedChildIncidents(
	ctx context.Context, parentIncidentUID string,
) ([]*models.Incident, error)

ListSuppressedChildIncidents returns active incidents rolled up under the parent.

func (*Service) ListSystemAgentEnrollmentTokens

func (s *Service) ListSystemAgentEnrollmentTokens(
	ctx context.Context,
) ([]*models.AgentEnrollmentToken, error)

ListSystemAgentEnrollmentTokens returns every live platform token. Never exposed on the org-admin API — system tokens are operator material.

func (*Service) ListSystemParameters

func (s *Service) ListSystemParameters(ctx context.Context) ([]*models.Parameter, error)

ListSystemParameters returns all system parameters.

func (*Service) ListUserContactsByTypeValue

func (s *Service) ListUserContactsByTypeValue(
	ctx context.Context, contactType, value string,
) ([]*models.UserContact, error)

ListUserContactsByTypeValue returns every live contact with the given type and value, across all users and organizations.

The ORDER BY is load-bearing, not cosmetic: one Telegram chat can be linked in several organizations, and callers that still have to pick a single row must pick the SAME one on every call. Oldest link first, UID as the tiebreaker. Kept identical in the Postgres mirror.

func (*Service) ListUserContactsWithRoutes

func (s *Service) ListUserContactsWithRoutes(
	ctx context.Context, userUID, orgUID string,
) ([]*models.UserNotificationRoute, error)

ListUserContactsWithRoutes returns the ordered notification routes for a user in an org, with the contact relation eagerly loaded.

func (*Service) ListUserIntegrationIdentities

func (s *Service) ListUserIntegrationIdentities(
	ctx context.Context, integrationUID string,
) ([]*models.UserIntegrationIdentity, error)

ListUserIntegrationIdentities returns every identity row mapped on one integration, ordered by display name so the admin UI and the mention renderer both see a stable order.

func (*Service) ListUserPasskeysByUser

func (s *Service) ListUserPasskeysByUser(
	ctx context.Context, userUID string,
) ([]*models.UserPasskey, error)

ListUserPasskeysByUser returns all non-deleted passkeys for a user.

func (*Service) ListUserProvidersByUser

func (s *Service) ListUserProvidersByUser(ctx context.Context, userUID string) ([]*models.UserProvider, error)

func (*Service) ListUserTokens

func (s *Service) ListUserTokens(ctx context.Context, userUID string) ([]*models.UserToken, error)

func (*Service) ListUserTokensByType

func (s *Service) ListUserTokensByType(
	ctx context.Context, userUID string, tokenType models.TokenType,
) ([]*models.UserToken, error)

func (*Service) ListUsers

func (s *Service) ListUsers(ctx context.Context) ([]*models.User, error)

func (*Service) ListWorkers

func (s *Service) ListWorkers(ctx context.Context) ([]*models.Worker, error)

func (*Service) MarkIncidentNotificationFailedByJob

func (s *Service) MarkIncidentNotificationFailedByJob(
	ctx context.Context, jobUID string, failedAt time.Time, errMsg string, retryable bool,
	details *models.DeliveryDetails,
) error

MarkIncidentNotificationFailedByJob updates the audit row matching job_uid. When retryable is true the row stays at pending so a retry can update it; when false the row transitions to failed.

func (*Service) MarkIncidentNotificationFailedByUID

func (s *Service) MarkIncidentNotificationFailedByUID(
	ctx context.Context, uid string, failedAt time.Time, errMsg string,
) error

MarkIncidentNotificationFailedByUID updates the audit row identified by UID to status=failed. Used by direct-email paths (no job_uid).

func (*Service) MarkIncidentNotificationSentByJob

func (s *Service) MarkIncidentNotificationSentByJob(
	ctx context.Context, jobUID string, sentAt time.Time, messageID string, details *models.DeliveryDetails,
) error

MarkIncidentNotificationSentByJob updates the audit row matching job_uid to status=sent. Used by NotificationJobRun.Run. When details is non-nil the captured delivery artifacts are persisted alongside the status transition.

func (*Service) MarkIncidentNotificationSentByUID

func (s *Service) MarkIncidentNotificationSentByUID(
	ctx context.Context, uid string, sentAt time.Time, messageID string,
) error

MarkIncidentNotificationSentByUID updates the audit row identified by UID to status=sent. Used by direct-email paths (no job_uid).

func (*Service) MarkReportScheduleRun

func (s *Service) MarkReportScheduleRun(
	ctx context.Context, uid string, periodStart, runAt time.Time,
) (bool, error)

MarkReportScheduleRun claims a closed period for a schedule.

The WHERE clause is the whole point: it only matches when the stored last_period_start is NULL or strictly older than the period being claimed, so two replicas that both notice the same closed period race into the same UPDATE and exactly one of them sees a row affected. That is what makes the report job safe under multi-replica claiming without leader election — the same reasoning as SELECT ... FOR UPDATE SKIP LOCKED elsewhere, expressed as an idempotency key instead of a lock.

func (*Service) MarkUserContactVerified

func (s *Service) MarkUserContactVerified(ctx context.Context, uid string, verifiedAt time.Time) error

MarkUserContactVerified stamps verified_at and clears the pending verification columns.

func (*Service) MaxStatusPageResourcePosition

func (s *Service) MaxStatusPageResourcePosition(
	ctx context.Context, sectionUID string,
) (int, error)

MaxStatusPageResourcePosition returns the largest position currently used by any resource in the given section, or 0 if no resources exist. Callers add 1 to append a new resource at the end.

func (*Service) MaxStatusPageSectionPosition

func (s *Service) MaxStatusPageSectionPosition(
	ctx context.Context, pageUID string,
) (int, error)

MaxStatusPageSectionPosition returns the largest position currently used by any non-deleted section in the given status page, or 0 if no sections exist. Callers add 1 to append a new section at the end.

func (*Service) MigrateCheckRegionSlug

func (s *Service) MigrateCheckRegionSlug(
	ctx context.Context, from, target string,
) ([]*models.Check, error)

MigrateCheckRegionSlug rewrites `checks.regions` in ONE transaction, replacing `from` with `to` everywhere it appears. See db.Service for the full contract.

func (*Service) PruneAgentNonces

func (s *Service) PruneAgentNonces(ctx context.Context, cutoff time.Time) (int64, error)

PruneAgentNonces deletes consumed nonces older than cutoff (the agent_gc job sweeps rows left behind by agents that never reconnected).

func (*Service) PurgeAgent

func (s *Service) PurgeAgent(ctx context.Context, uid string) error

PurgeAgent soft-deletes a revoked agent, clearing it from every listing. Scoped to status='revoked' so it can never touch a live agent — an admin purging an already-revoked row through the API, or the agent_gc sweep collecting one past the retention window.

func (*Service) PurgeExpiredDeviceAuthRequests

func (s *Service) PurgeExpiredDeviceAuthRequests(ctx context.Context, before time.Time) (int64, error)

PurgeExpiredDeviceAuthRequests deletes requests that expired before `before`.

func (*Service) ReapAbandonedResults

func (s *Service) ReapAbandonedResults(ctx context.Context) (models.ReapAbandonedResultsOutcome, error)

ReapAbandonedResults finalizes raw results stuck in a lifecycle-marker status well past any plausible execution window for their check. See the db.Service interface doc for the contract; mirrors postgres.Service's implementation one-for-one (sync-pg-to-sqlite convention) — both dialects go through bun's query builder here, so there is no raw-SQL divergence to track.

There is no proactive check_jobs lease sweep to piggyback on here (spec 2026-08-18-03, resolved from the code as instructed): check_jobs leases are only ever reclaimed lazily, inside ClaimJobs's own SELECT, when a worker happens to ask for work in that job's scope — never on a timer against the whole table. More fundamentally, nothing in this codebase ties an open raw result row to a check_jobs lease at all: the one persistent status=created row is CreateCheck's one-time "Check created" marker, written outside any claim/lease flow. So this has to be its own sweep, over `results` directly, keyed off each row's own check's period rather than any check_jobs state.

func (*Service) RecentResultsPerCheck

func (s *Service) RecentResultsPerCheck(
	ctx context.Context, filter *models.RecentResultsPerCheckFilter,
) ([]*models.Result, error)

RecentResultsPerCheck returns the newest rows per check per tier. See the db.Service interface for the contract and recentResultsPerCheckSQL for why the query is shaped the way it is.

func (*Service) RegisterOrUpdateWorker

func (s *Service) RegisterOrUpdateWorker(ctx context.Context, worker *models.Worker) (*models.Worker, error)

func (*Service) ReleaseOrganizationPreviousSlug

func (s *Service) ReleaseOrganizationPreviousSlug(ctx context.Context, slug string) error

ReleaseOrganizationPreviousSlug drops every live alias on a slug, whichever org holds it. Called when a slug is claimed by a real organization (creation or rename) so an alias can never resolve across tenants once reclaimed.

func (*Service) ReleaseOrganizationPreviousSlugsForOrg

func (s *Service) ReleaseOrganizationPreviousSlugsForOrg(ctx context.Context, orgUID string) error

ReleaseOrganizationPreviousSlugsForOrg drops every alias of an organization. Used on org deletion so nothing of the deleted org keeps holding slugs.

func (*Service) RemoveRecipientFromReportSchedules

func (s *Service) RemoveRecipientFromReportSchedules(ctx context.Context, orgUID, email string) (int, error)

RemoveRecipientFromReportSchedules drops an address from every one of the org's report schedules (spec 2026-08-20-01). Done in Go rather than in SQL because the recipients column is a JSON array on Postgres and a JSON string on SQLite, and one loop is easier to keep honest than two dialect-specific JSON mutations.

func (*Service) ReorderRoutes

func (s *Service) ReorderRoutes(ctx context.Context, userUID, orgUID string, routeUIDs []string) error

ReorderRoutes sets the position of each route to its index in routeUIDs.

func (*Service) ReorderStatusPageResources

func (s *Service) ReorderStatusPageResources(
	ctx context.Context, sectionUID string, orderedUIDs []string,
) error

ReorderStatusPageResources rewrites the position of every resource in the section so that orderedUIDs[i] gets position i+1. Done in a single transaction; the caller is responsible for validating that orderedUIDs exactly matches the section's current resource set.

func (*Service) ReorderStatusPageSections

func (s *Service) ReorderStatusPageSections(
	ctx context.Context, statusPageUID string, orderedUIDs []string,
) error

ReorderStatusPageSections rewrites the position of every section in the page so that orderedUIDs[i] gets position i+1. Done in a single transaction; the caller is responsible for validating that orderedUIDs exactly matches the page's current section set.

func (*Service) RepairMigrationChecksums

func (s *Service) RepairMigrationChecksums(ctx context.Context) ([]migrationguard.RepairResult, error)

RepairMigrationChecksums re-records checksums for every applied migration this binary ships — inserting a missing row or updating a drifted one to the current file checksum — without running any migration. Used by the `solidping migrate repair` CLI command; see internal/db/migrationguard.

func (*Service) ReplaceEscalationPolicySteps

func (s *Service) ReplaceEscalationPolicySteps(
	ctx context.Context,
	policyUID string,
	steps []*models.EscalationPolicyStep,
	targetsByStepIdx map[int][]*models.EscalationPolicyTarget,
) error

ReplaceEscalationPolicySteps atomically rewrites the entire step list and the targets attached to each step. Inputs are constructed by the service layer with fresh UIDs.

func (*Service) ReplaceOnCallScheduleUsers

func (s *Service) ReplaceOnCallScheduleUsers(
	ctx context.Context, scheduleUID string, userUIDs []string,
) error

ReplaceOnCallScheduleUsers atomically rewrites the roster for a schedule. Replacing the whole list keeps positions consistent and avoids reorder bugs from partial diffs.

func (*Service) ReserveMonthlyUsage

func (s *Service) ReserveMonthlyUsage(
	ctx context.Context, orgUID, kind, periodStart string, limit int,
) (bool, error)

ReserveMonthlyUsage atomically claims one unit of the monthly counter when the current count is below limit, via a conditional upsert. Returns true when a unit was reserved.

func (*Service) ResolveDeviceAuthRequest

func (s *Service) ResolveDeviceAuthRequest(
	ctx context.Context, uid string, res *models.DeviceAuthResolution,
) (bool, error)

ResolveDeviceAuthRequest moves a live pending request to approved or denied. The status predicate makes it a compare-and-set: a losing concurrent responder gets false rather than overwriting the first decision.

func (*Service) ResubscribeSubscriber

func (s *Service) ResubscribeSubscriber(
	ctx context.Context, uid, confirmToken, unsubscribeToken string,
) error

ResubscribeSubscriber soft-undeletes an existing row and refreshes its tokens and confirmation state so a returning visitor must confirm again.

func (*Service) RetireAgentWorkerRow

func (s *Service) RetireAgentWorkerRow(ctx context.Context, agentUID string) error

RetireAgentWorkerRow soft-deletes the workers row an agent's connection registered, resolved through the deterministic agents.WorkerSlug(uid). The agent_gc job and the supersede-on-enroll path share this one implementation.

func (*Service) RetireSystemAgent

func (s *Service) RetireSystemAgent(ctx context.Context, uid string) error

RetireSystemAgent revokes and soft-deletes one system agent (enroll-on-boot fleets churn rows; a retired machine's row must stop being a seal recipient and stop cluttering the fleet list). Scoped to kind='system' so it can never touch a customer-managed agent.

func (*Service) RevokeAgent

func (s *Service) RevokeAgent(ctx context.Context, orgUID, uid string) error

RevokeAgent marks an agent revoked.

func (*Service) RevokeSystemAgentEnrollmentTokensExcept

func (s *Service) RevokeSystemAgentEnrollmentTokensExcept(
	ctx context.Context, keepHashes []string,
) (int64, error)

RevokeSystemAgentEnrollmentTokensExcept soft-deletes every live system token whose hash is not in keepHashes. Dropping a token from the environment is the revocation path: the next boot removes it. An empty keepHashes revokes all of them.

func (*Service) SaveResultWithStatusTracking

func (s *Service) SaveResultWithStatusTracking(ctx context.Context, result *models.Result) error

func (*Service) SetAppSetting

func (s *Service) SetAppSetting(ctx context.Context, key, value string) error

SetAppSetting creates or updates a key/value pair (upsert).

func (*Service) SetCheckConnections

func (s *Service) SetCheckConnections(ctx context.Context, checkUID string, connectionUIDs []string) error

SetCheckConnections replaces all connections for a check.

func (*Service) SetCheckLabels

func (s *Service) SetCheckLabels(ctx context.Context, checkUID string, labelUIDs []string) error

func (*Service) SetMaintenanceWindowChecks

func (s *Service) SetMaintenanceWindowChecks(
	ctx context.Context, windowUID string, checkUIDs, checkGroupUIDs []string,
) error

SetMaintenanceWindowChecks replaces the check associations for a maintenance window.

func (*Service) SetOrgParameter

func (s *Service) SetOrgParameter(ctx context.Context, orgUID, key string, value any, secret bool) error

SetOrgParameter creates or updates an org-scoped parameter.

func (*Service) SetRouteEnabled

func (s *Service) SetRouteEnabled(ctx context.Context, routeUID string, enabled bool) error

SetRouteEnabled toggles the enabled flag on a route.

func (*Service) SetStateEntry

func (s *Service) SetStateEntry(
	ctx context.Context, orgUID *string, key string, value *models.JSONMap, ttl *time.Duration,
) error

SetStateEntry creates or updates a state entry.

SQLite (and PostgreSQL by default) treats NULL values as distinct in UNIQUE constraints, so an INSERT … ON CONFLICT(organization_uid, key) does not fire when organization_uid is NULL — duplicate global rows would silently accumulate. To keep callers' upsert intent honest we run an explicit UPDATE first when orgUID is nil; if no row matches we fall through to INSERT.

func (*Service) SetStateEntryIfNotExists

func (s *Service) SetStateEntryIfNotExists(
	ctx context.Context, orgUID *string, key string, value *models.JSONMap, ttl *time.Duration,
) (bool, error)

SetStateEntryIfNotExists creates entry only if key doesn't exist.

func (*Service) SetSystemParameter

func (s *Service) SetSystemParameter(ctx context.Context, key string, value any, secret bool) error

SetSystemParameter creates or updates a system parameter.

func (*Service) SetUserContactVerifyState

func (s *Service) SetUserContactVerifyState(
	ctx context.Context, uid string, codeHash *string, expiresAt *time.Time, attempts int,
) error

SetUserContactVerifyState writes the in-flight verification columns (code hash, expiry, attempt count) on a contact. Passing nil codeHash / expiresAt clears the pending code while preserving the attempt count.

func (*Service) SetUserStateEntry

func (s *Service) SetUserStateEntry(
	ctx context.Context, userUID, key string, value *models.JSONMap, ttl *time.Duration,
) error

SetUserStateEntry creates or updates a user-scoped state entry.

The table's only unique constraint is (organization_uid, key), which does not cover user-scoped rows, so ON CONFLICT has nothing to fire on. Mirror the global-entry branch of SetStateEntry: UPDATE first (which also resurrects a soft-deleted row by clearing deleted_at), and INSERT only when no row matched.

func (*Service) SoftDeleteFinishedJobs

func (s *Service) SoftDeleteFinishedJobs(ctx context.Context, before time.Time, limit int) (int64, error)

SoftDeleteFinishedJobs marks up to `limit` terminal jobs done before `before` as soft-deleted (jobs_cleanup stage 1). Mirrors the Postgres implementation (sync-pg-to-sqlite). Select-then-update keeps the batch bounded.

func (*Service) SoftDeleteIncidentPublication

func (s *Service) SoftDeleteIncidentPublication(ctx context.Context, uid string) error

SoftDeleteIncidentPublication unpublishes: the row stays for audit, but it leaves both the public page and the partial unique index, so the same incident can be republished later.

func (*Service) SoftDeleteStatusUpdate

func (s *Service) SoftDeleteStatusUpdate(ctx context.Context, uid string) error

SoftDeleteStatusUpdate sets deleted_at on a status update.

func (*Service) SoftDeleteSubscriber

func (s *Service) SoftDeleteSubscriber(ctx context.Context, uid string) error

SoftDeleteSubscriber sets deleted_at on a subscriber (unsubscribe).

func (*Service) TLSStorageAcquireLock

func (s *Service) TLSStorageAcquireLock(
	ctx context.Context, key, owner string, expiresAt time.Time,
) (bool, error)

TLSStorageAcquireLock atomically claims the named lock for owner until expiresAt. It succeeds when the lock is free OR the current holder's lease has expired (a crashed issuance must not wedge renewals forever); it returns false — not an error — when a live holder still owns it.

func (*Service) TLSStorageDelete

func (s *Service) TLSStorageDelete(ctx context.Context, key string) error

TLSStorageDelete removes the key and, since certmagic keys are path-like, every key nested under it ("<key>/..."). Deleting a missing key is not an error — certmagic only requires that the key be gone afterwards.

func (*Service) TLSStorageExists

func (s *Service) TLSStorageExists(ctx context.Context, key string) (bool, error)

TLSStorageExists reports whether the key exists as a stored value.

func (*Service) TLSStorageList

func (s *Service) TLSStorageList(ctx context.Context, prefix string) ([]models.TLSStorageKeyInfo, error)

TLSStorageList returns metadata (never the value bytes) for the key itself and every key nested under it, sorted by key. An empty prefix lists everything.

func (*Service) TLSStorageLoad

func (s *Service) TLSStorageLoad(ctx context.Context, key string) ([]byte, error)

TLSStorageLoad returns the stored bytes for key, or sql.ErrNoRows (wrapped) when the key does not exist.

func (*Service) TLSStorageRefreshLock

func (s *Service) TLSStorageRefreshLock(
	ctx context.Context, key, owner string, expiresAt time.Time,
) (bool, error)

TLSStorageRefreshLock extends the lease of a lock this owner still holds. Returns false when the lock was lost (taken over or released), so the caller can stop refreshing.

func (*Service) TLSStorageReleaseLock

func (s *Service) TLSStorageReleaseLock(ctx context.Context, key, owner string) error

TLSStorageReleaseLock drops a lock this owner holds. Releasing a lock that is already gone (or was taken over) is a no-op, never an error.

func (*Service) TLSStorageStat

func (s *Service) TLSStorageStat(ctx context.Context, key string) (models.TLSStorageKeyInfo, error)

TLSStorageStat returns metadata for one key, or sql.ErrNoRows (wrapped) when it does not exist.

func (*Service) TLSStorageStore

func (s *Service) TLSStorageStore(ctx context.Context, key string, value []byte) error

TLSStorageStore upserts an asset, refreshing its modification time.

func (*Service) TouchDeviceAuthPoll

func (s *Service) TouchDeviceAuthPoll(ctx context.Context, uid string, at time.Time) error

TouchDeviceAuthPoll stamps the last poll time used for slow_down enforcement.

func (*Service) TryAdvanceHeartbeatCounter

func (s *Service) TryAdvanceHeartbeatCounter(
	ctx context.Context, orgUID, checkUID string, counter int64,
) (bool, error)

TryAdvanceHeartbeatCounter atomically stores counter as the check's last accepted SP2 replay counter, but ONLY when it is strictly greater than the stored value (or no value is stored yet). Returns true when the beat may be accepted.

See advanceHeartbeatCounterQuery for why this is one statement.

func (*Service) UpdateAgentLastSeen

func (s *Service) UpdateAgentLastSeen(ctx context.Context, uid string, at time.Time) error

UpdateAgentLastSeen sets an agent's last_seen_at.

func (*Service) UpdateChannel

func (s *Service) UpdateChannel(
	ctx context.Context, uid string, update *models.IntegrationUpdate,
) error

UpdateChannel updates an integration connection.

func (*Service) UpdateCheck

func (s *Service) UpdateCheck(
	ctx context.Context, uid string, update *models.CheckUpdate,
) error

func (*Service) UpdateCheckConnection

func (s *Service) UpdateCheckConnection(
	ctx context.Context, checkUID, connectionUID string, update *models.CheckConnectionUpdate,
) error

UpdateCheckConnection updates settings for a check-connection.

func (*Service) UpdateCheckDependency

func (s *Service) UpdateCheckDependency(
	ctx context.Context, depUID string, update *models.CheckDependencyUpdate,
) error

UpdateCheckDependency writes the supplied fields. Empty update is a no-op.

func (*Service) UpdateCheckFlapState

func (s *Service) UpdateCheckFlapState(
	ctx context.Context, checkUID string, flapCount int, lastOutageAt time.Time,
) error

UpdateCheckFlapState persists the rolling flap counter and the last-outage timestamp on a check. Written only on the rare incident open/reopen — never on the per-result hot path. See spec 2026-06-30-07.

func (*Service) UpdateCheckGroup

func (s *Service) UpdateCheckGroup(
	ctx context.Context, orgUID, uid string, update *models.CheckGroupUpdate,
) error

func (*Service) UpdateCheckStatusAndClocks

func (s *Service) UpdateCheckStatusAndClocks(
	ctx context.Context,
	checkUID string,
	status models.CheckStatus,
	streak int,
	statusChangedAt *time.Time,
	clocks models.IncidentClockUpdate,
) error

UpdateCheckStatusAndClocks writes the check's status, streak, status_changed_at and both incident clocks in a single atomic UPDATE, replacing the former separate UpdateCheckStatus + UpdateCheckIncidentClocks round-trips. statusChangedAt is written only when non-nil. The clock fields use IncidentClockUpdate's tri-state (nil + !clear leaves the column untouched, nil + clear writes NULL, non-nil writes the value). updated_at is written once.

func (*Service) UpdateEscalationPolicy

func (s *Service) UpdateEscalationPolicy(
	ctx context.Context, policyUID string, update *models.EscalationPolicyUpdate,
) error

UpdateEscalationPolicy writes the supplied fields. Empty update is a no-op.

func (*Service) UpdateEventPayload

func (s *Service) UpdateEventPayload(ctx context.Context, uid string, payload models.JSONMap) error

UpdateEventPayload replaces one event's payload in place.

events is otherwise strictly append-only; the single exception is auth.login_failed folding (spec 2026-08-21-09), where repeats of the same (org, email, IP) inside a short window bump a counter on the row that is already there instead of writing a new row per attempt. Anything else mutating an audit row would be a bug.

func (*Service) UpdateIncident

func (s *Service) UpdateIncident(ctx context.Context, uid string, update *models.IncidentUpdate) error

func (*Service) UpdateIncidentMemberCheck

func (s *Service) UpdateIncidentMemberCheck(
	ctx context.Context, incidentUID, checkUID string, update *models.IncidentMemberUpdate,
) error

UpdateIncidentMemberCheck applies a partial update to a member row.

func (*Service) UpdateIncidentNotificationDeliveryByMessageID

func (s *Service) UpdateIncidentNotificationDeliveryByMessageID(
	ctx context.Context, orgUID, messageID string, details *models.DeliveryDetails,
) error

UpdateIncidentNotificationDeliveryByMessageID sets delivery_details on the notification row whose message_id matches within the org.

func (*Service) UpdateIncidentNotificationDeliveryByMessageIDAnyOrg

func (s *Service) UpdateIncidentNotificationDeliveryByMessageIDAnyOrg(
	ctx context.Context, messageID string, details *models.DeliveryDetails,
) error

UpdateIncidentNotificationDeliveryByMessageIDAnyOrg sets delivery_details on the notification row whose message_id matches, without an org filter. Used by instance-level provider callbacks (Meta's WhatsApp webhook) that carry no organization context; the provider message id is globally unique.

func (*Service) UpdateIncidentPublication

func (s *Service) UpdateIncidentPublication(
	ctx context.Context, uid string, update *models.IncidentPublicationUpdate,
) error

UpdateIncidentPublication applies a tri-state patch. Nothing but the listed columns (plus updated_at) is written, so two concurrent writers touching different fields do not clobber each other's work.

func (*Service) UpdateJob

func (s *Service) UpdateJob(ctx context.Context, uid string, update models.JobUpdate) error

func (*Service) UpdateMaintenanceWindow

func (s *Service) UpdateMaintenanceWindow(
	ctx context.Context, uid string, update models.MaintenanceWindowUpdate,
) error

UpdateMaintenanceWindow updates a maintenance window by UID.

func (*Service) UpdateMembershipRequest

func (s *Service) UpdateMembershipRequest(
	ctx context.Context, request *models.MembershipRequest,
) error

UpdateMembershipRequest persists status / decision changes.

func (*Service) UpdateOnCallSchedule

func (s *Service) UpdateOnCallSchedule(
	ctx context.Context, scheduleUID string, update *models.OnCallScheduleUpdate,
) error

UpdateOnCallSchedule writes the supplied fields. Empty update is a no-op.

func (*Service) UpdateOrganization

func (s *Service) UpdateOrganization(ctx context.Context, uid string, update models.OrganizationUpdate) error

func (*Service) UpdateOrganizationMember

func (s *Service) UpdateOrganizationMember(
	ctx context.Context, uid string, update models.OrganizationMemberUpdate,
) error

func (*Service) UpdateOrganizationProvider

func (s *Service) UpdateOrganizationProvider(
	ctx context.Context, uid string, update models.OrganizationProviderUpdate,
) error

func (*Service) UpdateReportSchedule

func (s *Service) UpdateReportSchedule(
	ctx context.Context, uid string, update models.ReportScheduleUpdate,
) error

UpdateReportSchedule applies a partial update to a report schedule.

func (*Service) UpdateSLO

func (s *Service) UpdateSLO(ctx context.Context, uid string, update models.SLOUpdate) error

UpdateSLO applies a partial update to an SLO.

func (*Service) UpdateSLOAlertPolicy

func (s *Service) UpdateSLOAlertPolicy(
	ctx context.Context, uid string, update *models.SLOAlertPolicyUpdate,
) error

UpdateSLOAlertPolicy applies a partial update. Nil fields are left alone.

func (*Service) UpdateSeverity

func (s *Service) UpdateSeverity(
	ctx context.Context, uid string, update *models.SeverityUpdate,
) error

UpdateSeverity applies a partial update.

func (*Service) UpdateStatusPage

func (s *Service) UpdateStatusPage(ctx context.Context, uid string, update *models.StatusPageUpdate) error

UpdateStatusPage updates a status page by UID.

func (*Service) UpdateStatusPageBranding

func (s *Service) UpdateStatusPageBranding(
	ctx context.Context, uid string, update *models.StatusPageBrandingUpdate,
) error

UpdateStatusPageBranding replaces the `branding` section of settings in one write. Every transition (upload, replace, clear, white-label opt-in) goes through here, and the section is written WHOLE — a nil file UID travels as an explicit JSON null rather than being omitted, which is what guarantees a cleared asset stops being publicly reachable immediately.

The merge happens in SQL, never as a read-modify-write in Go: reading StatusPageSettings, mutating .Branding and writing the struct back would clobber a concurrent `availability` threshold change.

func (*Service) UpdateStatusPageCustomDomain

func (s *Service) UpdateStatusPageCustomDomain(
	ctx context.Context, uid string, update *models.StatusPageCustomDomainUpdate,
) error

UpdateStatusPageCustomDomain overwrites every custom-domain column in one write. All lifecycle transitions (set, clear, verify-now, re-verify) go through here, so nil pointers write SQL NULL verbatim.

func (*Service) UpdateStatusPageResource

func (s *Service) UpdateStatusPageResource(
	ctx context.Context, uid string, update *models.StatusPageResourceUpdate,
) error

UpdateStatusPageResource updates a resource by UID.

func (*Service) UpdateStatusPageSection

func (s *Service) UpdateStatusPageSection(
	ctx context.Context, uid string, update *models.StatusPageSectionUpdate,
) error

UpdateStatusPageSection updates a section by UID.

func (*Service) UpdateStatusUpdate

func (s *Service) UpdateStatusUpdate(ctx context.Context, update *models.StatusUpdate) error

UpdateStatusUpdate updates an existing status update row.

func (*Service) UpdateSubscriberDelivery

func (s *Service) UpdateSubscriberDelivery(
	ctx context.Context, uid string, failureCount int, disabledAt *time.Time,
) error

UpdateSubscriberDelivery records the outcome of a webhook/Slack delivery: the consecutive-failure counter and, when the circuit breaker trips, the disable timestamp. disabledAt nil CLEARS the column, so a re-enable goes through the same call.

func (*Service) UpdateUser

func (s *Service) UpdateUser(ctx context.Context, uid string, update *models.UserUpdate) error

func (*Service) UpdateUserPasskey

func (s *Service) UpdateUserPasskey(
	ctx context.Context, uid string, update models.UserPasskeyUpdate,
) error

UpdateUserPasskey applies a partial update.

func (*Service) UpdateUserToken

func (s *Service) UpdateUserToken(ctx context.Context, uid string, update models.UserTokenUpdate) error

func (*Service) UpdateWorker

func (s *Service) UpdateWorker(ctx context.Context, uid string, update models.WorkerUpdate) error

func (*Service) UpdateWorkerHeartbeat

func (s *Service) UpdateWorkerHeartbeat(
	ctx context.Context, workerUID string, capabilities []string, version string,
) error

func (*Service) UpsertAggregatedResult

func (s *Service) UpsertAggregatedResult(ctx context.Context, result *models.Result) error

UpsertAggregatedResult replaces any existing aggregated row for the same bucket key (organization_uid, check_uid, coalesce(region,”), period_type, period_start) with the given result, in one transaction. This keeps re-aggregation idempotent (exactly one row per bucket) even when region is NULL — where the unique index treats NULLs as distinct. See spec 2026-07-11-16.

func (*Service) UpsertIncidentMemberCheck

func (s *Service) UpsertIncidentMemberCheck(ctx context.Context, member *models.IncidentMemberCheck) error

UpsertIncidentMemberCheck inserts or updates a member row.

func (*Service) UpsertOrgEntitlements

func (s *Service) UpsertOrgEntitlements(
	ctx context.Context, ent *models.OrgEntitlements, audit *models.OrgEntitlementAudit,
) error

UpsertOrgEntitlements writes the entitlement row + audit row in one tx. The caller pre-populates the audit's BeforeSnapshot from a previous GetOrgEntitlements call.

func (*Service) UpsertSystemAgentEnrollmentToken

func (s *Service) UpsertSystemAgentEnrollmentToken(
	ctx context.Context, token *models.AgentEnrollmentToken,
) error

UpsertSystemAgentEnrollmentToken inserts a seeded platform token, or refreshes the existing row with that hash (expiry, region, use budget) and un-deletes it. Idempotent: SP_SYSTEM_AGENT_ENROLLMENT_TOKENS is re-applied on every boot.

func (*Service) UpsertUserContact

func (s *Service) UpsertUserContact(ctx context.Context, c *models.UserContact) error

UpsertUserContact creates or restores a contact, and writes the CANONICAL uid back into c.

The write-back matters on the restore path: a revive conflicts on (user_uid, organization_uid, type, value) and DO UPDATE clears deleted_at on the row that is already there, keeping ITS uid. The freshly-generated uid the caller handed us was never inserted, so anything that then used c.UID to reference the contact (creating its notification route, say) would point at a row that does not exist and fail the foreign key. RETURNING makes c.UID the uid that is actually in the table, insert or restore.

func (*Service) UpsertUserIntegrationIdentity

func (s *Service) UpsertUserIntegrationIdentity(
	ctx context.Context, identity *models.UserIntegrationIdentity,
) error

UpsertUserIntegrationIdentity writes an identity, keyed on (integration_uid, user_uid). A member who moves to a different Slack account keeps one row rather than accumulating stale ones.

Jump to

Keyboard shortcuts

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