store

package
v0.2.0-beta.20 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package store is the embedded SQLite state layer: WAL mode, modernc.org/sqlite (pure Go, no cgo, keeps cross-compiling the control plane binary trivial), forward-only versioned migrations.

Index

Constants

View Source
const (
	AIChatRoleUser      = "user"
	AIChatRoleAssistant = "assistant"
	AIChatRoleTool      = "tool"
)

AI chat role values. "tool" carries a tool_result turn (either an auto-executed read-only call's result, or a confirmed/rejected mutating call's result), never issued directly by the operator.

View Source
const (
	AIChatConfirmationPending  = "pending"
	AIChatConfirmationApproved = "approved"
	AIChatConfirmationRejected = "rejected"
)

AI chat confirmation status values.

View Source
const (
	AIControlModeOff     = "off"
	AIControlModeObserve = "observe"
	AIControlModeOperate = "operate"
	AIControlModeAdmin   = "admin"
)

AI control modes, from least to most permissive.

View Source
const (
	AppEventRestart        = "restart"
	AppEventEnvChange      = "env_change"
	AppEventSecretChange   = "secret_change"
	AppEventConfigChange   = "config_change"
	AppEventScale          = "scale"
	AppEventSuspend        = "suspend"
	AppEventResume         = "resume"
	AppEventFreezeOverride = "freeze_override"
	// AppEventScanGateOverride marks an operator letting a scan-blocked release through.
	AppEventScanGateOverride = "scan_gate_override"
)

App event kinds recorded in app_events. Deploys and rollbacks are not events: the timeline derives them from deploy attempts.

View Source
const (
	AppImportPlanned      = "planned"
	AppImportStaged       = "staged"
	AppImportBuilding     = "building"
	AppImportVerified     = "verified"
	AppImportVerifyFailed = "verify-failed"
	AppImportStageFailed  = "stage-failed"
	AppImportRouted       = "routed"
	AppImportRolledBack   = "rolled-back"
)

App import item states.

View Source
const (
	AppScheduleHistoryFired         = "fired"
	AppScheduleHistorySkippedFreeze = "skipped_freeze"
	AppScheduleHistoryFailed        = "failed"
)

Statuses recorded on an app_schedule_history row.

View Source
const (
	AppliedFieldPort       = "port"
	AppliedFieldCommand    = "command"
	AppliedFieldEntrypoint = "entrypoint"
	AppliedFieldLabels     = "labels"
	AppliedFieldHostPort   = "host_port"
	AppliedFieldBindAddr   = "bind_address"
	// AppliedFieldSecretKeys lists, comma-joined, which env keys were
	// secret-backed; informational, never diffed as a setting.
	AppliedFieldSecretKeys = "secret_keys"
)

Applied field names compared between desired state and a container's creation-time snapshot.

View Source
const (
	BackupStatusRunning   = "running"
	BackupStatusSucceeded = "succeeded"
	BackupStatusFailed    = "failed"
)

Backup attempt statuses migrations/0018_backup_targets.sql's CHECK constraint accepts. "running" is written first (StartBackupHistory) so a backup that crashes the control plane mid-upload leaves a real, visible "running" row behind rather than no record at all; nothing currently sweeps a stuck "running" row back to "failed", a known, honest gap for the eventual scheduler to close alongside its own retry logic, not invented speculatively here.

View Source
const (
	BackupResourceKindDatabase = "database"
	BackupResourceKindVolume   = "volume"
)

Backup resource kinds migrations/0075_service_volume_backups.sql's own CHECK constraint accepts: which of the two things a backup_history row describes. BackupResourceKindDatabase is the zero value's effective meaning for every row written before this constant existed.

View Source
const (
	DrillStatusRunning = "running"
	DrillStatusPassed  = "passed"
	DrillStatusFailed  = "failed"

	DrillTriggerManual    = "manual"
	DrillTriggerScheduled = "scheduled"
)

Drill statuses and triggers.

View Source
const (
	BackupProviderAWS    = "aws"
	BackupProviderR2     = "r2"
	BackupProviderCustom = "custom"
)

Backup target providers migrations/0018_backup_targets.sql's CHECK constraint accepts. "aws" leaves Endpoint empty (the AWS SDK's default per-region resolver already knows the right host); "r2" and "custom" both require an explicit Endpoint, the only structural difference between them being that "r2" exists as its own value so the API and frontend can show a Cloudflare-specific label instead of a bare URL.

View Source
const (
	BackupVerificationStatusRunning = "running"
	BackupVerificationStatusPassed  = "passed"
	BackupVerificationStatusFailed  = "failed"
)

Backup verification statuses migrations/0069_backup_verification.sql's CHECK constraint accepts, mirroring BackupStatusRunning/Succeeded/Failed's own "running" written first, before real work happens" reasoning (backup_history.go): a verification attempt that downloads a large object can take a while, so a row exists from the moment it starts, not only once it finishes. "passed"/"failed" describe whether the backup itself checked out, not whether the verification process ran without error; VerifyBackup (internal/backup) folds both into the same failed status, since either one means an operator cannot trust this backup without more investigation.

View Source
const (
	ComposeRevisionSourceAPI      = "api"
	ComposeRevisionSourceTemplate = "template"
	ComposeRevisionSourceRollback = "rollback"
)

Compose revision sources.

View Source
const (
	EnginePostgres   = "postgres"
	EngineRedis      = "redis"
	EngineMySQL      = "mysql"
	EngineMongoDB    = "mongodb"
	EngineMariaDB    = "mariadb"
	EngineKeyDB      = "keydb"
	EngineDragonfly  = "dragonfly"
	EngineClickHouse = "clickhouse"
)

Supported managed database engines. internal/spec's own engine list (app.yaml declarative support) is tracked separately and not guaranteed to match this one: Dragonfly and ClickHouse are available here but not yet in internal/spec.

View Source
const (
	PublicPortRangeStart = 20000
	PublicPortRangeEnd   = 20999
)

PublicPortRangeStart and PublicPortRangeEnd bound the host ports auto-assigned by SetDatabasePublicAccess when the caller doesn't request a specific one. Chosen clear of every port this control plane already binds itself (cmd/levelrail's defaultHTTPAddr ":8080", defaultAgentAddr ":9443") and of Caddy's 80/443, so an auto-assigned database port can never collide with the control plane's own listeners.

View Source
const (
	DatabaseAccessKindUser = "user"
	DatabaseAccessKindTemp = "temp"

	DatabaseAccessStateActive   = "active"
	DatabaseAccessStateRevoking = "revoking"
	DatabaseAccessStateRevoked  = "revoked"

	// DatabaseNetworkScopePlatform is the default scope.
	DatabaseNetworkScopePlatform = "platform"
)

Database access user kinds and states.

View Source
const (
	DataImportCopying  = "copying"
	DataImportVerified = "verified"
	DataImportFailed   = "failed"
)

Statuses of a DatabaseDataImport.

View Source
const (
	DBUpgradeStatePending   = "pending"
	DBUpgradeStateBackingUp = "backing_up"
	DBUpgradeStateUpgrading = "upgrading"
	DBUpgradeStateVerifying = "verifying"
	DBUpgradeStateSucceeded = "succeeded"
	DBUpgradeStateReverted  = "reverted"
	DBUpgradeStateFailed    = "failed"
)

Database upgrade run states (migrations/0428_db_upgrade_runs.sql).

View Source
const (
	DBUpgradeSourceAuto   = "auto"
	DBUpgradeSourceManual = "manual"
)

Database upgrade run sources.

View Source
const (
	DBAutoUpgradeOff   = "off"
	DBAutoUpgradePatch = "patch"
	DBAutoUpgradeMinor = "minor"
)

Automatic upgrade levels a policy may allow. Majors are never automatic.

View Source
const (
	DeployApprovalActionDeploy  = "deploy"
	DeployApprovalActionPromote = "promote"
	// DeployApprovalActionMoveApp and DeployApprovalActionMoveDatabase gate
	// retagging a resource into or out of a protected environment; Image
	// then carries the target environment id.
	DeployApprovalActionMoveApp      = "move_app_environment"
	DeployApprovalActionMoveDatabase = "move_database_environment"
)

Deploy approval actions: what kind of desired-state change is gated behind the approval, DeployApproval.Action's valid values.

View Source
const (
	DeployApprovalStatusPending  = "pending"
	DeployApprovalStatusApproved = "approved"
	DeployApprovalStatusRejected = "rejected"
	DeployApprovalStatusExpired  = "expired"
)

Deploy approval statuses, DeployApproval.Status's valid values.

View Source
const (
	DeployAttemptStatusRunning   = "running"
	DeployAttemptStatusSucceeded = "succeeded"
	DeployAttemptStatusFailed    = "failed"
	// DeployAttemptStatusHeld is an automatic deploy parked by a freeze
	// window, replayed once the window ends.
	DeployAttemptStatusHeld = "held"
	// DeployAttemptStatusSuperseded is a deploy that never wrote desired
	// state because a newer one already had.
	DeployAttemptStatusSuperseded = "superseded"
	// DeployAttemptStatusQueued is a deploy waiting for another deploy of
	// the same app, a freeze window or build capacity.
	DeployAttemptStatusQueued = "queued"
	// DeployAttemptStatusCanceled is a deploy stopped by an operator before
	// it wrote desired state.
	DeployAttemptStatusCanceled = "canceled"
)

Deploy attempt lifecycle. There is no "pending" state distinct from "running": every trigger handler saves the row and immediately begins work (SaveDesiredService for the plain path, Pipeline.Deploy for the two build-triggering paths) in the same call, so there is no observable gap between "queued" and "started" worth a separate status value.

View Source
const (
	DeployAttemptSourceWebhook      = "webhook"
	DeployAttemptSourceManual       = "manual"
	DeployAttemptSourceImage        = "image"
	DeployAttemptSourceCompose      = "compose"
	DeployAttemptSourcePromote      = "promote"
	DeployAttemptSourceAutoRollback = "auto_rollback"
	// DeployAttemptSourceClone marks the first deploy of an app created
	// by cloning a whole environment (internal/api/environment_clone.go's
	// handleCloneEnvironment): a fresh app, same shape as the plain
	// image-tag path, just recorded under its own source so deploy
	// history can tell "created by cloning environment X" apart from an
	// ordinary manual create.
	DeployAttemptSourceClone = "clone"
	// DeployAttemptSourceSchedule marks a redeploy internal/scheduledeploy.
	// Scheduler fired for a due store.AppSchedule: the latest commit on
	// its configured branch, deployed through the same
	// internal/api.deployFromGitSourceAs path a webhook push uses.
	DeployAttemptSourceSchedule = "schedule"
)

Deploy attempt trigger sources, one per real call site: the unattended git-push webhook (internal/webhook), a manual git-source build triggered from the dashboard (internal/api/deploy_attempts.go's beginBuildDeployAttempt), a plain image-tag create/update/redeploy/ rollback with no build step (internal/api/deploys.go's recordPlainDeployAttempt), a Docker Compose file or service template fanning out into one or more services under one app (internal/api/apps_compose.go's handleDeployCompose), promoting another app's image across environments within the same project (internal/api/promote.go's handlePromoteApp), and an unattended crashloop auto-rollback (internal/alerting.MaybeAutoRollback, gated on DesiredService.AutoRollbackOnCrashloop) driving internal/deploy. TriggerImageDeploy, the same shared path DeployAttemptSourceImage's own manual rollback already goes through.

View Source
const (
	// DigestReasonResolved: the registry answered for the tag at deploy time.
	DigestReasonResolved = "Resolved"
	// DigestReasonPinned: the requested reference already carried a digest.
	DigestReasonPinned = "AlreadyPinned"
	// DigestReasonLocalBuild: the image ID of the image this deploy built.
	DigestReasonLocalBuild = "LocalBuild"
	// DigestReasonPullFailedUsingCached: the registry could not be reached,
	// so the locally cached image for the tag was used instead.
	DigestReasonPullFailedUsingCached = "PullFailedUsingCached"
	// DigestReasonLocalImage: the image exists only locally, with no registry digest.
	DigestReasonLocalImage = "LocalImage"
	// DigestReasonUnresolved: neither the registry nor the local cache knew
	// the tag; the node resolves it when it creates the container.
	DigestReasonUnresolved = "Unresolved"
)

How a deploy attempt's ImageDigest was obtained.

View Source
const (
	RolloutStateServing  = "serving"
	RolloutStateMismatch = "mismatch"
	RolloutStateFailed   = "failed"
)

What the application controller observed for an attempt's image.

View Source
const (
	DeployReasonFrozen     = "Frozen"
	DeployReasonSuperseded = "Superseded"
	DeployReasonStale      = "StaleCommit"
)

Reasons recorded on held and superseded attempts.

View Source
const (
	DeploymentHeld       = "held"
	DeploymentQueued     = "queued"
	DeploymentAwaiting   = "awaiting_approval"
	DeploymentBuilding   = "building"
	DeploymentReady      = "ready"
	DeploymentFailed     = "failed"
	DeploymentCanceled   = "canceled"
	DeploymentRolledBack = "rolled_back"
	DeploymentSuperseded = "superseded"
)

Deployment statuses exposed by the cross-app deployments list, derived from a deploy attempt's stored status by deploymentStatusSQL.

View Source
const (
	DeploymentTriggerGitPush  = "git push"
	DeploymentTriggerManual   = "manual"
	DeploymentTriggerRollback = "rollback"
	DeploymentTriggerAPI      = "api"
	DeploymentTriggerPreview  = "preview"
	DeploymentTriggerSchedule = "schedule"
)

Deployment triggers exposed by the cross-app deployments list.

View Source
const (
	AuditActionFamilyDeviceLogin    = "device_login"
	AuditActionDeviceLoginApproved  = AuditActionFamilyDeviceLogin + ".approved"
	AuditActionDeviceLoginDenied    = AuditActionFamilyDeviceLogin + ".denied"
	AuditActionDeviceLoginExpired   = AuditActionFamilyDeviceLogin + ".expired"
	AuditActionDeviceLoginDismissed = AuditActionFamilyDeviceLogin + ".dismissed"
)

Audit action names for the CLI device login lifecycle. Family is the prefix the audit log filter matches.

View Source
const (
	DeviceLoginStateWaiting  = "waiting"
	DeviceLoginStateExpired  = "expired"
	DeviceLoginStateDenied   = "denied"
	DeviceLoginStateApproved = "approved"
)

Device login states as the dashboard, CLI and MCP name them.

View Source
const (
	AuditActionDNSRecordCreated = "dns_record.created"
	AuditActionDNSRecordUpdated = "dns_record.updated"
	AuditActionDNSRecordDeleted = "dns_record.deleted"
)

Audit action names for DNS records Levelrail writes on an operator's behalf.

View Source
const (
	DomainErrorPageNotFound           = 404
	DomainErrorPageServerError        = 500
	DomainErrorPageBadGateway         = 502
	DomainErrorPageServiceUnavailable = 503
)

Allowed domain_error_page.status_code values (migrations/0105): the common failure statuses an operator would actually want a custom page for, not a fully generic arbitrary-status-code system.

View Source
const (
	DomainRedirectPermanent = 301
	DomainRedirectTemporary = 302
)

Domain redirect status codes (domain_redirect.status_code, migrations/0102). DomainRedirectPermanent is the default, matching Caddy's own default redirect status.

View Source
const (
	DomainTLSCertCertificateEnvKey = "certificate"
	DomainTLSCertPrivateKeyEnvKey  = "private_key"
)

DomainTLSCertCertificateEnvKey and DomainTLSCertPrivateKeyEnvKey are the two fixed envKeys used within that namespace: one secrets-manager service slot per domain, two keys within it, sharing one data-encryption key (internal/secrets.Manager reuses a service's DEK across keys).

View Source
const (
	DomainWAFModeDetect = "detect"
	DomainWAFModeBlock  = "block"
)

Domain WAF modes (domain_waf.waf_mode, migrations/0093). DomainWAFModeDetect is the default: OWASP CRS runs but only logs matches, never rejects a request, matching Coraza's own documented SecRuleEngine DetectionOnly behavior.

View Source
const (
	EmailBackendSMTP   = "smtp"
	EmailBackendSES    = "ses"
	EmailBackendResend = "resend"
)

Email backends store.EmailSettings.Backend accepts. Empty string means "unset": the caller falls back to APP_SMTP_* env vars if set.

View Source
const (
	EnvironmentKindDev        = "dev"
	EnvironmentKindTest       = "test"
	EnvironmentKindUAT        = "uat"
	EnvironmentKindProduction = "production"
	EnvironmentKindPreview    = "preview"
	EnvironmentKindCustom     = "custom"
)

Environment kinds, Environment.Kind's valid values.

View Source
const (
	EnvironmentScopeProject = "project"
	EnvironmentScopeGlobal  = "global"
)

Environment scopes, Environment.Scope's valid values.

View Source
const (
	ExternalHealthReachable   = "reachable"
	ExternalHealthSlow        = "slow"
	ExternalHealthAuthFailed  = "auth_failed"
	ExternalHealthTLSError    = "tls_error"
	ExternalHealthUnreachable = "unreachable"
	ExternalHealthUnknown     = "unknown"
)

Probe outcomes recorded on an ExternalDatabase.

View Source
const (
	HookTypePreDeploy  = "pre_deploy"
	HookTypePostDeploy = "post_deploy"
)

Hook types HookRun.HookType holds, matching internal/reconcile/application's own unexported constants of the same values (that package can't import this one's vocabulary any more than store.DesiredService's own doc comment lets it import spec's, so the two are kept in sync by value, not by a shared import).

View Source
const (
	PrincipalTypeUser  = "user"
	PrincipalTypeToken = "token"
)

PrincipalTypeUser and PrincipalTypeToken are the only two valid PolicyAttachment.PrincipalType values.

View Source
const (
	LoginApprovalPending  = "pending"
	LoginApprovalApproved = "approved"
	LoginApprovalDenied   = "denied"
	LoginApprovalExpired  = "expired"
	LoginApprovalConsumed = "consumed"
	// LoginApprovalSuperseded marks a request retired by a newer one.
	LoginApprovalSuperseded = "superseded"
)

Login approval states.

View Source
const (
	LoginCodePending  = "pending"
	LoginCodeRedeemed = "redeemed"
	LoginCodeLocked   = "locked"
	LoginCodeExpired  = "expired"
)

Login code challenge states.

View Source
const (
	AuditActionFamilyLoginCode   = "login_code"
	AuditActionLoginCodeRequest  = AuditActionFamilyLoginCode + ".requested"
	AuditActionLoginCodeDeliver  = AuditActionFamilyLoginCode + ".delivered"
	AuditActionLoginCodeRedeem   = AuditActionFamilyLoginCode + ".redeemed"
	AuditActionLoginCodeFail     = AuditActionFamilyLoginCode + ".failed"
	AuditActionLoginCodeLockout  = AuditActionFamilyLoginCode + ".locked"
	AuditActionLoginCodeExpire   = AuditActionFamilyLoginCode + ".expired"
	AuditActionFamilyNewDevice   = "new_device"
	AuditActionNewDeviceRequest  = AuditActionFamilyNewDevice + ".requested"
	AuditActionNewDeviceApprove  = AuditActionFamilyNewDevice + ".approved"
	AuditActionNewDeviceDeny     = AuditActionFamilyNewDevice + ".denied"
	AuditActionNewDeviceExpire   = AuditActionFamilyNewDevice + ".expired"
	AuditActionNewDeviceReplace  = AuditActionFamilyNewDevice + ".superseded"
	AuditActionTrustedDeviceDrop = AuditActionFamilyNewDevice + ".trust_revoked"
	AuditActionApproverRevoke    = AuditActionFamilyNewDevice + ".approver_tokens_revoked"
)

Audit action names for sign in with a code and new-device approval.

View Source
const (
	HubItemPending  = "pending"
	HubItemCopying  = "copying"
	HubItemVerified = "verified"
	HubItemFailed   = "failed"
)

Hub item statuses.

View Source
const (
	ResidencyAlways   = "always"
	ResidencyOnDemand = "on_demand"

	ResidencyAwake  = "awake"
	ResidencyAsleep = "asleep"
	ResidencyWaking = "waking"
)

Model residency modes and reconciler-observed states.

View Source
const (
	NetworkShareProtocolNFS  = "nfs"
	NetworkShareProtocolCIFS = "cifs"
)

Network share protocols, matching internal/docker's own NFS/CIFS driver-opts translation.

View Source
const (
	CertKeyOriginServer = "server"
	CertKeyOriginAgent  = "agent"
)

Certificate key origins: who generated the private key behind a node's current certificate.

View Source
const (
	NodeJoinTokenPurposeEnroll   = "enroll"
	NodeJoinTokenPurposeReenroll = "reenroll"
)

Join token purposes.

View Source
const (
	NodeMoveKindApp      = "app"
	NodeMoveKindDatabase = "database"

	NodeMoveStatusRunning    = "running"
	NodeMoveStatusSucceeded  = "succeeded"
	NodeMoveStatusFailed     = "failed"
	NodeMoveStatusRolledBack = "rolled_back"
)

Node move and drain kinds and statuses.

View Source
const (
	NodeProvisionStatusCreating   = "creating"
	NodeProvisionStatusBooting    = "booting"
	NodeProvisionStatusInstalling = "installing"
	NodeProvisionStatusEnrolling  = "enrolling"
	NodeProvisionStatusReady      = "ready"
	NodeProvisionStatusFailed     = "failed"
)

The lifecycle a node_provisions row moves through. Recomputed live against the provider API and the nodes table on every read (internal/api/node_provision.go), not advanced by a background worker.

View Source
const (
	OAuthProviderGoogle    = "google"
	OAuthProviderGitHub    = "github"
	OAuthProviderOIDC      = "oidc"
	OAuthProviderMicrosoft = "microsoft"
)

OAuth provider names the migrations/0035_users.sql and 0052's CHECK constraints accept.

View Source
const (
	HoldPending  = "pending"
	HoldApproved = "approved"
	HoldRejected = "rejected"
)

Run hold states.

View Source
const (
	TriggerStarted = "started"
	TriggerHeld    = "held"
	TriggerSkipped = "skipped"
	TriggerFailed  = "failed"
)

Trigger decisions.

View Source
const (
	PipelineStatusQueued          = "queued"
	PipelineStatusPending         = "pending"
	PipelineStatusRunning         = "running"
	PipelineStatusWaitingApproval = "waiting_approval"
	PipelineStatusSucceeded       = "succeeded"
	PipelineStatusFailed          = "failed"
	PipelineStatusCancelled       = "cancelled"
	PipelineStatusSkipped         = "skipped"
)

Pipeline run and job statuses. Terminal statuses never transition again.

View Source
const (
	PreviewDatabaseIsolationStatusProvisioned    = "provisioned"
	PreviewDatabaseIsolationStatusTeardownFailed = "teardown_failed"
)

Preview database isolation statuses (migrations/0232_preview_database_isolations.sql).

View Source
const (
	PreviewStatusDeploying = "deploying"
	PreviewStatusActive    = "active"
	PreviewStatusFailed    = "failed"
	// PreviewStatusAwaitingApproval marks a fork pull request held back
	// until an operator approves it; nothing is deployed in this state.
	PreviewStatusAwaitingApproval = "awaiting_approval"
	// PreviewStatusLimitReached marks a pull request rejected because the
	// preview cap was full and the app's policy is to reject.
	PreviewStatusLimitReached = "limit_reached"
)

Preview environment statuses (migrations/0064_preview_environments.sql). Deploying is the initial state a webhook-triggered create/update writes before the build even starts; Active means the preview is reachable (with or without its intended domain, see StatusReason); Failed means the deploy itself never produced a running preview.

View Source
const (
	PreviewEphemeralDatabaseStatusProvisioned    = "provisioned"
	PreviewEphemeralDatabaseStatusTeardownFailed = "teardown_failed"
)

Preview ephemeral database statuses (migrations/0092_preview_ephemeral_databases.sql). Provisioned is the only state this row is ever saved in; TeardownFailed is set in place, never SaveDesiredDatabase, so a retry can find exactly which ones are still owed a teardown.

View Source
const (
	PreviewOnLimitEvictOldest = "evict_oldest"
	PreviewOnLimitReject      = "reject"
)

Preview limit policies applied when an app's preview cap is full.

View Source
const (
	PreviewDatabaseStrategyNone   = "none"
	PreviewDatabaseStrategyShared = "shared"
	PreviewDatabaseStrategyFresh  = "fresh"
	PreviewDatabaseStrategySeed   = "seed"
)

Preview database strategies: what database a preview talks to.

View Source
const (
	ProxyIntegrationOff         = "off"
	ProxyIntegrationTraefikFile = "traefik_file"
)

Proxy integration modes (migrations/0417).

View Source
const (
	ProxyLoadedUnknown = "unknown"
	ProxyLoadedYes     = "yes"
	ProxyLoadedNo      = "no"
)

Proxy loaded verdicts for ProxyRouteStatus.ProxyLoaded.

View Source
const (
	AuditActionFamilyProxyRoute = "proxy_route"
	AuditActionProxyRouteWrite  = AuditActionFamilyProxyRoute + ".written"
	AuditActionProxyRouteRemove = AuditActionFamilyProxyRoute + ".removed"
)

Audit actions for files written into an external proxy's config directory.

View Source
const (
	RoleVisibilityAll     = "all"
	RoleVisibilityGranted = "granted"
)

Role visibility: a role either sees every resource its abilities allow, or only resources in the environments granted to each user holding it.

View Source
const (
	Route53DNSAccessKeyIDEnvKey     = "access_key_id"
	Route53DNSSecretAccessKeyEnvKey = "secret_access_key"
)

Route53DNSAccessKeyIDEnvKey and Route53DNSSecretAccessKeyEnvKey are the fixed envKeys used within that namespace.

View Source
const (
	ScheduledTaskStatusSuccess             = "success"
	ScheduledTaskStatusFailed              = "failed"
	ScheduledTaskStatusTimeout             = "timeout"
	ScheduledTaskStatusContainerNotRunning = "container_not_running"
	// ScheduledTaskStatusSkippedConcurrency is recorded when
	// ConcurrencyPolicy is "forbid" and a previous run of the same task
	// was still in flight, so a skipped tick stays visible in run
	// history instead of silently vanishing.
	ScheduledTaskStatusSkippedConcurrency = "skipped_concurrency"
	// ScheduledTaskStatusReplaced is recorded on the run that
	// ConcurrencyPolicy "replace" cancelled to make room for a newer
	// invocation of the same task.
	ScheduledTaskStatusReplaced = "replaced"
	// ScheduledTaskStatusRunning is the in-flight state of a history row.
	ScheduledTaskStatusRunning = "running"
	// ScheduledTaskStatusMissed marks an occurrence the control plane did
	// not run (it was down, and catch-up did not cover it).
	ScheduledTaskStatusMissed = "missed"
	// ScheduledTaskStatusInterrupted marks a run whose control plane
	// restarted mid-flight; it is never re-run, to rule out a double run.
	ScheduledTaskStatusInterrupted = "interrupted"
)

Scheduled task run statuses (migrations/0048_scheduled_tasks.sql's last_run_status column, no CHECK constraint since this is an application-level enum, not something a foreign key or another table joins against). ScheduledTaskStatusContainerNotRunning is distinct from ScheduledTaskStatusFailed so the dashboard can badge "the container isn't up" differently from "the command itself failed", exactly the "clear, visible signal" this feature's own spec asked for rather than folding that case into a generic failure.

View Source
const (
	ScheduledTaskModeExec        = "exec"
	ScheduledTaskModeFresh       = "fresh"
	ScheduledTaskCatchUpSkip     = "skip"
	ScheduledTaskCatchUpRunOnce  = "run_once"
	ScheduledTaskSourceAPI       = "api"
	ScheduledTaskSourceSpec      = "spec"
	ScheduledTaskTriggerSchedule = "schedule"
	ScheduledTaskTriggerManual   = "manual"
	ScheduledTaskTriggerAPI      = "api"
)

Scheduled task execution modes and catch-up policies.

View Source
const (
	ScheduledTaskConcurrencyAllow   = "allow"
	ScheduledTaskConcurrencyForbid  = "forbid"
	ScheduledTaskConcurrencyReplace = "replace"
)

Scheduled task concurrency policies (migrations/ 0101_scheduled_task_concurrency_policy.sql's concurrency_policy column): what internal/scheduledtask.Runner does when a task's next due run finds a previous invocation of itself still executing.

View Source
const (
	AuditActionFamilySecurity        = "security"
	AuditActionSessionRevoke         = AuditActionFamilySecurity + ".session_revoked"
	AuditActionSessionRevokeOthers   = AuditActionFamilySecurity + ".sessions_revoked"
	AuditActionSecurityPolicyUpdate  = AuditActionFamilySecurity + ".policy_updated"
	AuditActionDeviceApprovalToggle  = AuditActionFamilySecurity + ".device_approval_changed"
	AuditActionNewBrowserSignIn      = AuditActionFamilySecurity + ".new_browser_sign_in"
	AuditActionSignInDisowned        = AuditActionFamilySecurity + ".sign_in_disowned"
	AuditActionTokenUnusedNotice     = AuditActionFamilySecurity + ".token_unused_notice"
	AuditActionTokenUnusedDisabled   = AuditActionFamilySecurity + ".token_unused_disabled"
	AuditActionFailedLoginsThreshold = AuditActionFamilySecurity + ".failed_logins"
)

Audit action names for the security center.

View Source
const (
	AutoRollbackSLOBurnOff           = "off"
	AutoRollbackSLOBurnAuto          = "auto"
	AutoRollbackSLOBurnDryRun        = "dry_run"
	AutoRollbackSLOBurnPauseForHuman = "pause_for_human"
)

AutoRollbackSLOBurn* are DesiredService.AutoRollbackOnSLOBurn's valid values.

View Source
const (
	DefaultDeployStrategy = "blue-green"
	DefaultReplicas       = 1
	// DefaultBindAddress mirrors internal/bindaddr.Default (same value,
	// same "define locally" reasoning above): loopback-only, the safe
	// default for a service whose caller never set BindAddress.
	DefaultBindAddress = "private"
)

DefaultDeployStrategy and DefaultReplicas mirror internal/spec's StrategyBlueGreen/DefaultReplicas exactly (same values), kept as this package's own constants rather than importing internal/spec: this package's own doc comment already establishes that DesiredService is deliberately independent of spec.Service, and every other cross- package enum in this file (NodeStatus, and so on) follows the same "define locally, don't import a higher-level package's vocabulary" convention.

View Source
const (
	SSHNodeProvisionStatusConnecting = "connecting"
	SSHNodeProvisionStatusDetecting  = "detecting"
	SSHNodeProvisionStatusInstalling = "installing"
	SSHNodeProvisionStatusEnrolling  = "enrolling"
	SSHNodeProvisionStatusReady      = "ready"
	SSHNodeProvisionStatusFailed     = "failed"
)

The lifecycle an ssh_node_provisions row moves through. Unlike NodeProvisionStatus* (recomputed live against a provider API), Status, DetectedOS, DetectedArch and Log here are pushed by the provisioning goroutine itself as the SSH session progresses (internal/sshprovision), since this control plane has a live connection to the remote host rather than a provider's own status endpoint to poll.

View Source
const (
	TeamRoleOwner     = "owner"
	TeamRoleAdmin     = "admin"
	TeamRoleDeveloper = "developer"
	TeamRoleViewer    = "viewer"
)

Team roles, ordered from most to least privileged.

View Source
const (
	UpgradeNotesPending     = "pending"
	UpgradeNotesFetched     = "fetched"
	UpgradeNotesUnavailable = "unavailable"
)

Notes states of an UpgradeHistoryEntry: the snapshot is filled once.

View Source
const (
	VaultAuthMethodToken   = "token"
	VaultAuthMethodAppRole = "approle"
)

VaultAuthMethodToken and VaultAuthMethodAppRole are VaultSettings.AuthMethod's only valid values.

View Source
const AIProviderAnthropic = "anthropic"

AIProviderAnthropic is the only supported internal/ai provider today. A string enum (not an int) so a future "openai" addition is a new constant and a switch case, not a schema change.

View Source
const AppStreamProtocolTCP = "tcp"

AppStreamProtocolTCP is the only protocol v1 supports. Stored as a string column (migrations/0279) so udp can be added later without a schema change.

View Source
const CanaryServiceSuffix = "--canary"

CanaryServiceSuffix marks the hidden clone service that runs a canary.

View Source
const CloudflareDNSTokenEnvKey = "token"

CloudflareDNSTokenEnvKey is the fixed envKey used within that namespace.

View Source
const CloudflareTunnelTokenEnvKey = "token"

CloudflareTunnelTokenEnvKey is the fixed envKey used within that namespace, mirroring OAuthProviderSecretEnvKey's shape.

View Source
const DBUpgradePlatformDefault = "*"

DBUpgradePlatformDefault is the policy row every database without its own row inherits.

View Source
const DatabaseAccessTimeLayout = "2006-01-02T15:04:05Z"

DatabaseAccessTimeLayout is the fixed-width UTC layout used for every timestamp here, so lexical comparison in SQL is chronological.

View Source
const DefaultModelKeyName = "default"

DefaultModelKeyName is the name of the key every model is created with.

View Source
const DefaultTeamID = "org_default"

DefaultTeamID is the team migration 0442 creates to own everything that existed before teams. Its members are the instance's own users.

View Source
const DeployFreezeScopeGlobal = "global"

DeployFreezeScopeGlobal applies a freeze window to every app.

View Source
const DeployReasonCanceled = "Canceled"

DeployReasonCanceled is recorded on canceled attempts.

View Source
const DeploymentSummaryDays = 14

DeploymentSummaryDays is how many days the sparkline covers.

View Source
const DomainBasicAuthPasswordEnvKey = "password"

DomainBasicAuthPasswordEnvKey is the fixed envKey used within that namespace, mirroring CloudflareTunnelTokenEnvKey's shape.

View Source
const EgressModeAllowlist = "allowlist"

EgressModeAllowlist is the only meaningful ServiceEgressPolicy.Mode value today, matching internal/spec.EgressModeAllowlist exactly (this package deliberately doesn't import internal/spec, the same "define locally, don't import a higher-level package's vocabulary" convention Strategy's own field doc comment already establishes).

View Source
const ExternalDatabasePasswordKey = "password"

ExternalDatabasePasswordKey is the env key of that password.

View Source
const GlobalProjectID = "proj_global"

GlobalProjectID is the reserved project that owns the instance-wide environments (migration 0375). It is never listed as a project and never deletable, since deleting it would cascade away every global environment.

View Source
const LocalNodeGPUKey = "local"

LocalNodeGPUKey is the node_gpus key of the control plane's own host.

View Source
const MajorUpgradeStatusRolledBack = "rolled_back"

MajorUpgradeStatusRolledBack marks an upgrade undone by a rollback; the other statuses reuse the shared BackupStatus* values.

View Source
const MaxDNSTTLSeconds = 86400

MaxDNSTTLSeconds is the highest valid DNSTTLSeconds (one day).

View Source
const MaxPublicHTTPSPort = 65535

MaxPublicHTTPSPort is the highest valid PublicHTTPSPort.

View Source
const MaxWebhookDeliveryPayloadBytes = 64 * 1024

MaxWebhookDeliveryPayloadBytes bounds how much of a webhook delivery's raw payload SaveWebhookDelivery persists: debug data for an operator to inspect and replay, not a permanent audit log, so an unusually large payload is truncated rather than stored in full.

View Source
const NodeProviderTokenEnvKey = "token"

NodeProviderTokenEnvKey is the fixed envKey within that namespace.

View Source
const OAuthProviderSecretEnvKey = "client_secret"

OAuthProviderSecretEnvKey is the fixed envKey used within that namespace.

View Source
const PipelineFilterHeld = "held"

PipelineFilterHeld is PipelineRunFilter.Status's virtual "held" value (a run awaiting a hold decision), not a real stored run status.

View Source
const PipelineTriggerLogKeep = 200

PipelineTriggerLogKeep is how many trigger decisions are kept per app.

View Source
const PullPolicyAlways = "always"

PullPolicyAlways mirrors internal/compose's own PullPolicyAlways exactly (same value), kept as this package's own constant for the same "define locally, don't import a higher-level package's vocabulary" reasoning DefaultDeployStrategy's own doc comment gives.

View Source
const RegistryPasswordEnvKey = "password"

RegistryPasswordEnvKey is the fixed envKey used within that namespace.

View Source
const VaultCredentialEnvKey = "credential"

VaultCredentialEnvKey is the fixed envKey used within that namespace. It holds a Vault token when AuthMethod is VaultAuthMethodToken, or an AppRole secret ID when AuthMethod is VaultAuthMethodAppRole: exactly one credential is ever configured at a time, so one envKey covers both shapes.

View Source
const VolumeQuiescePause = "pause"

VolumeQuiescePause is the quiesce mode that pauses the app container.

Variables

View Source
var (
	// ErrAIChatSessionNotFound means no ai_chat_sessions row exists for
	// the given id.
	ErrAIChatSessionNotFound = errors.New("store: ai chat session not found")
	// ErrAIChatMessageNotFound means no ai_chat_messages row exists for
	// the given id.
	ErrAIChatMessageNotFound = errors.New("store: ai chat message not found")
	// ErrAIChatConfirmationNotFound means no ai_chat_confirmations row
	// exists for the given id.
	ErrAIChatConfirmationNotFound = errors.New("store: ai chat confirmation not found")
)
View Source
var (
	// ErrPolicyNotFound is returned by GetPolicy/DeletePolicy/UpdatePolicy
	// when no row matches.
	ErrPolicyNotFound = errors.New("store: iam policy not found")
	// ErrPolicyNameExists is SavePolicy's failure mode when name is
	// already taken by a different row.
	ErrPolicyNameExists = errors.New("store: iam policy name already exists")
)
View Source
var (
	// ErrPipelineNotFound is returned when a pipeline ID or name matches no row.
	ErrPipelineNotFound = errors.New("store: pipeline not found")
	// ErrPipelineRunNotFound is returned when a run ID matches no row.
	ErrPipelineRunNotFound = errors.New("store: pipeline run not found")
)
View Source
var (
	// ErrRoleNotFound is returned when no role has the given ID.
	ErrRoleNotFound = errors.New("store: role not found")
	// ErrRoleNameTaken is returned when a role name is already in use.
	ErrRoleNameTaken = errors.New("store: a role with that name already exists")
	// ErrRoleBuiltin is returned when a built-in role would be edited or deleted.
	ErrRoleBuiltin = errors.New("store: built-in roles cannot be changed")
	// ErrRoleInUse is returned when a role still has users.
	ErrRoleInUse = errors.New("store: the role is assigned to users")
)
View Source
var (
	ErrStatusComponentNotFound = errors.New("store: status component not found")
	ErrStatusIncidentNotFound  = errors.New("store: status incident not found")
)

Sentinel errors for the status page store.

View Source
var (
	// ErrTeamMemberNotFound is returned when the user is not in the team.
	ErrTeamMemberNotFound = errors.New("store: team member not found")
	// ErrTeamMemberExists is returned when the user is already in the team.
	ErrTeamMemberExists = errors.New("store: user is already a member of the team")
	// ErrLastTeamOwner is returned when a change would leave a team with no owner.
	ErrLastTeamOwner = errors.New("store: a team must keep at least one owner")
	// ErrInvalidTeamRole is returned for a role outside the fixed set.
	ErrInvalidTeamRole = errors.New("store: invalid team role")
)
View Source
var EnvironmentKinds = []string{"dev", "test", "uat", "production", "preview", "custom"}

EnvironmentKinds lists every environment kind an AI control rule can name.

View Source
var ErrAPITokenNotFound = errors.New("store: api token not found")

ErrAPITokenNotFound is returned by GetAPITokenByHash and RevokeAPIToken when no token matches.

View Source
var ErrAppImportSessionNotFound = errors.New("app import session not found")

ErrAppImportSessionNotFound is returned for an unknown app import session id.

View Source
var ErrAppIntegrationAlreadyAttached = errors.New("store: integration already attached to this app")

ErrAppIntegrationAlreadyAttached is returned by SaveAppIntegration when serviceName already has integrationKey attached (the table's own UNIQUE(service_name, integration_key) constraint).

View Source
var ErrAppIntegrationNotFound = errors.New("store: app integration not found")

ErrAppIntegrationNotFound is returned by GetAppIntegration and DeleteAppIntegration when id doesn't match any row.

View Source
var ErrAppNotFound = errors.New("store: app not found")

ErrAppNotFound is returned by GetApp, GetAppByName, and DeleteApp when no row matches.

View Source
var ErrAppScheduleNotFound = errors.New("store: app schedule not found")

ErrAppScheduleNotFound is returned by GetAppSchedule when no schedule is configured for a service.

View Source
var ErrAppStreamNotFound = errors.New("store: app stream not found")

ErrAppStreamNotFound is returned by GetAppStream/DeleteAppStream when id doesn't match any row.

View Source
var ErrAppVolumeMoveNotFound = errors.New("store: app volume move record not found")

ErrAppVolumeMoveNotFound is returned by UpdateAppVolumeMoveSteps, FinishAppVolumeMove, and GetAppVolumeMove when id doesn't match any row.

View Source
var ErrAutomationRunNotFound = errors.New("store: domain automation run not found")

ErrAutomationRunNotFound is returned for an unknown run id.

View Source
var ErrBackupHistoryNotFound = errors.New("store: backup history record not found")

ErrBackupHistoryNotFound is returned by FinishBackupHistory when id doesn't match any row.

View Source
var ErrBackupTargetNotFound = errors.New("store: backup target not found")

ErrBackupTargetNotFound is returned by GetBackupTarget and DeleteBackupTarget when id doesn't match any row.

View Source
var ErrBackupVerificationNotFound = errors.New("store: backup verification not found")

ErrBackupVerificationNotFound is returned by FinishBackupVerification when id doesn't match any row, and by GetLatestBackupVerification when backupHistoryID has never been verified.

View Source
var ErrBaseBackupHistoryNotFound = errors.New("store: base backup history record not found")

ErrBaseBackupHistoryNotFound is returned by FinishBaseBackupHistory and GetBaseBackupHistory when id doesn't match any row.

View Source
var ErrBitbucketAppConnectionNotFound = errors.New("store: bitbucket app connection not found")

ErrBitbucketAppConnectionNotFound is returned by GetBitbucketAppConnection and DeleteBitbucketAppConnection when no bitbucket_app_connections row exists, i.e. the OAuth consumer has never been configured.

View Source
var ErrBranchEnvOverrideNotFound = errors.New("store: branch env override not found")

ErrBranchEnvOverrideNotFound means no row exists for the id a caller asked to delete.

View Source
var ErrBuildCacheSettingNotFound = errors.New("store: build cache setting not found")

ErrBuildCacheSettingNotFound is returned when an app scope has no build cache setting.

View Source
var ErrCertStorageKeyNotFound = errors.New("store: cert storage key not found")

ErrCertStorageKeyNotFound is returned by GetCertStorageValue and StatCertStorageValue when key has no stored value. Named distinctly from ErrServiceNotFound/ErrNodeNotFound, even though the shape is identical, because internal/ingress's certmagic.Storage adapter needs to translate this into fs.ErrNotExist specifically, per certmagic.Storage's own doc comment ("Load, Delete, List, and Stat methods should return fs.ErrNotExist if the key does not exist"); a store-package-wide NotFound sentinel would make that translation ambiguous about which resource type failed.

View Source
var ErrCloneRestoreNotFound = errors.New("store: clone restore record not found")

ErrCloneRestoreNotFound is returned by FinishCloneRestore when id doesn't match any row.

View Source
var ErrComposeRevisionNotFound = errors.New("store: compose revision not found")

ErrComposeRevisionNotFound is returned when an app has no matching revision.

View Source
var ErrCustomTemplateNotFound = errors.New("store: custom template not found")

ErrCustomTemplateNotFound is returned by GetCustomTemplate and DeleteCustomTemplate when id doesn't match any row.

View Source
var ErrCutoverRunActive = errors.New("store: a cutover run is already in progress for this app")

ErrCutoverRunActive means the app already has a run in flight.

View Source
var ErrCutoverRunNotFound = errors.New("store: cutover run not found")

ErrCutoverRunNotFound is returned for an unknown cutover run id.

View Source
var ErrDBUpgradeRunNotFound = errors.New("store: database upgrade run not found")

ErrDBUpgradeRunNotFound is returned when an upgrade run id matches no row.

View Source
var ErrDataImportInProgress = errors.New("a data copy is already running for this database")

ErrDataImportInProgress is returned when a copy is already running.

View Source
var ErrDatabaseAccessUserExists = errors.New("store: database access user already exists")

ErrDatabaseAccessUserExists is returned when a live record already holds the role.

View Source
var ErrDatabaseNotFound = errors.New("store: database not found")

ErrDatabaseNotFound is returned by GetDesiredDatabase when no database has that name.

View Source
var ErrDeployApprovalNotFound = errors.New("store: deploy approval not found")

ErrDeployApprovalNotFound is returned by GetDeployApproval when id doesn't match any row.

View Source
var ErrDeployAttemptNotFound = errors.New("store: deploy attempt not found")

ErrDeployAttemptNotFound is returned by GetDeployAttempt and FinishDeployAttempt when no row has the given ID.

View Source
var ErrEnvironmentNotFound = errors.New("store: environment not found")

ErrEnvironmentNotFound is returned by GetEnvironment and DeleteEnvironment when id doesn't match any row.

View Source
var ErrExportDestinationNameTaken = errors.New("store: export destination name already in use")

ErrExportDestinationNameTaken is returned when a name is already in use.

View Source
var ErrExportDestinationNotFound = errors.New("store: export destination not found")

ErrExportDestinationNotFound is returned when no destination has the given id.

View Source
var ErrExternalDatabaseExists = errors.New("store: external database already exists")

ErrExternalDatabaseExists is returned when the name is already taken.

View Source
var ErrExternalDatabaseNotFound = errors.New("store: external database not found")

ErrExternalDatabaseNotFound is returned when no external database has that name.

View Source
var ErrFeatureFlagNotFound = errors.New("store: feature flag not found")

ErrFeatureFlagNotFound is returned by GetFeatureFlag, GetFeatureFlagByKey, UpdateFeatureFlag, and DeleteFeatureFlag when id/key doesn't match any row.

View Source
var ErrFirewallRuleNotFound = errors.New("store: firewall rule not found")

ErrFirewallRuleNotFound is returned by DeleteFirewallRule when id doesn't match any row.

View Source
var ErrFirstUserExists = errors.New("store: first user already exists")

ErrFirstUserExists is CreateUser's failure mode when u.IsFirstUser is true but a first user already exists (ux_users_single_first_user).

View Source
var ErrGitHubAppConnectionNotFound = errors.New("store: github app connection not found")

ErrGitHubAppConnectionNotFound is returned by GetGitHubAppConnection and UpdateGitHubAppInstallation/DeleteGitHubAppConnection when no github_app_connections row exists, i.e. the App has never been registered through the manifest flow.

View Source
var ErrGitHubAppInstallationNotFound = errors.New("store: github app installation not found")

ErrGitHubAppInstallationNotFound is returned by UpdateGitHubAppInstallationAccountType and DeleteGitHubAppInstallation when no github_app_installations row matches the given id.

View Source
var ErrGitLabAppConnectionNotFound = errors.New("store: gitlab app connection not found")

ErrGitLabAppConnectionNotFound is returned by GetGitLabAppConnection and DeleteGitLabAppConnection when no gitlab_app_connections row exists, i.e. the OAuth Application has never been registered.

View Source
var ErrGitSourceNotFound = errors.New("store: git source not found")

ErrGitSourceNotFound is returned by GetGitSource and DeleteGitSource when no git source is connected for a given service name.

View Source
var ErrGiteaAppConnectionNotFound = errors.New("store: gitea app connection not found")

ErrGiteaAppConnectionNotFound is returned by GetGiteaAppConnection and DeleteGiteaAppConnection when no gitea_app_connections row exists, i.e. the OAuth2 application has never been registered.

View Source
var ErrInvalidDeploymentCursor = errors.New("store: invalid deployment cursor")

ErrInvalidDeploymentCursor is returned for a cursor ListDeployments did not mint.

View Source
var ErrInviteAlreadyAccepted = errors.New("store: invite already accepted")

ErrInviteAlreadyAccepted is RevokeInvite/ClaimInvite's failure mode when the invite was already accepted.

View Source
var ErrInviteAlreadyRevoked = errors.New("store: invite already revoked")

ErrInviteAlreadyRevoked is RevokeInvite/ClaimInvite's failure mode when the invite was already revoked.

View Source
var ErrInviteEmailExists = errors.New("store: a pending invite already exists for this email")

ErrInviteEmailExists is SaveInvite's failure mode when a pending (not yet accepted or revoked) invite already exists for the same email (ux_invites_pending_email).

View Source
var ErrInviteNotFound = errors.New("store: invite not found")

ErrInviteNotFound is returned by GetInviteByHash/GetInviteByID when no row matches.

View Source
var ErrLogArchivePolicyNotFound = errors.New("store: log archive policy not found")

ErrLogArchivePolicyNotFound is returned when no policy exists for an app scope.

View Source
var ErrLoginApprovalNotFound = errors.New("store: login approval not found")

ErrLoginApprovalNotFound is returned for an unknown approval or browser.

View Source
var ErrLoginCodeNotFound = errors.New("store: login code challenge not found")

ErrLoginCodeNotFound is returned when no live challenge matches.

View Source
var ErrMajorUpgradeNotFound = errors.New("store: database major upgrade not found")

ErrMajorUpgradeNotFound is returned when an upgrade id matches no row.

View Source
var ErrMeshPortsExhausted = errors.New("store: no free database mesh port in the configured range")

ErrMeshPortsExhausted is returned when every port in the configured range is taken.

View Source
var ErrMigrationSessionNotFound = errors.New("migration session not found")

ErrMigrationSessionNotFound is returned for an unknown hub session id.

View Source
var ErrModelDomainTaken = errors.New("store: model domain already in use")

ErrModelDomainTaken is returned by SaveModel when another model owns the domain.

View Source
var ErrModelExists = errors.New("store: model already exists")

ErrModelExists is returned by SaveModel when the name is taken.

View Source
var ErrModelKeyExists = errors.New("store: model key name already in use")

ErrModelKeyExists is returned when a live key already has the name.

View Source
var ErrModelKeyNotFound = errors.New("store: model key not found")

ErrModelKeyNotFound is returned when a model has no key with the given id.

View Source
var ErrModelNotFound = errors.New("store: model not found")

ErrModelNotFound is returned when no model has the given name.

View Source
var ErrNetworkShareNotFound = errors.New("store: network share not found")

ErrNetworkShareNotFound is returned by GetNetworkShare, GetNetworkShareByName, UpdateNetworkShare, and DeleteNetworkShare when id/name doesn't match any row.

View Source
var ErrNodeCertConflict = errors.New("store: node certificate changed concurrently")

ErrNodeCertConflict is returned when the node's certificate changed between read and write, a concurrent renewal having won.

View Source
var ErrNodeCertNotAccepted = errors.New("store: certificate not accepted for this node")

ErrNodeCertNotAccepted is returned when the presented certificate is neither the node's current one nor its previous one inside the overlap window.

View Source
var ErrNodeCertRevoked = errors.New("store: node certificate revoked")

ErrNodeCertRevoked is returned when the node's certificate was revoked by an operator.

View Source
var ErrNodeJoinTokenAlreadyUsed = errors.New("store: node join token already used")

ErrNodeJoinTokenAlreadyUsed is MarkNodeJoinTokenUsed's failure mode when the token has already been exchanged once.

View Source
var ErrNodeJoinTokenNotFound = errors.New("store: node join token not found")

ErrNodeJoinTokenNotFound is returned by GetNodeJoinTokenByHash and MarkNodeJoinTokenUsed when no token matches.

View Source
var ErrNodeMoveInProgress = errors.New("store: a move is already in progress for this resource")

ErrNodeMoveInProgress is returned when a resource or node already has a running move or drain.

View Source
var ErrNodeMoveNotFound = errors.New("store: node move not found")

ErrNodeMoveNotFound is returned when a node move or drain ID matches no row.

View Source
var ErrNodeNameTaken = errors.New("store: node name already taken")

ErrNodeNameTaken is returned by SaveNode when name is already used by a different node: node names are operator-facing identifiers (shown in the join command, the node list), so collisions need to surface as a clear error, not a silently overwritten row.

View Source
var ErrNodeNotFound = errors.New("store: node not found")

ErrNodeNotFound is returned by GetNode when no node has that ID.

View Source
var ErrNodeProvisionNotFound = errors.New("store: node provision not found")

ErrNodeProvisionNotFound is returned by GetNodeProvision when id doesn't match any row.

View Source
var ErrOAuthIdentityAlreadyLinked = errors.New("store: oauth identity already linked")

ErrOAuthIdentityAlreadyLinked is SaveOAuthIdentity's failure mode when either unique index (migrations/0035) would be violated.

View Source
var ErrOAuthIdentityNotFound = errors.New("store: oauth identity not found")

ErrOAuthIdentityNotFound is returned by GetOAuthIdentity when no row matches.

View Source
var ErrOrganizationNotFound = errors.New("store: organization not found")

ErrOrganizationNotFound is returned by GetOrganization and DeleteOrganization when id doesn't match any row.

View Source
var ErrPITRRestoreHistoryNotFound = errors.New("store: pitr restore history record not found")

ErrPITRRestoreHistoryNotFound is returned by FinishPITRRestoreHistory when id doesn't match any row.

View Source
var ErrPreviewDatabaseIsolationNotFound = errors.New("store: preview database isolation not found")

ErrPreviewDatabaseIsolationNotFound is returned when no row matches.

View Source
var ErrPreviewEnvironmentNotFound = errors.New("store: preview environment not found")

ErrPreviewEnvironmentNotFound is returned by GetPreviewEnvironment and GetPreviewEnvironmentByAppAndPR when no row matches.

View Source
var ErrPreviewEphemeralDatabaseNotFound = errors.New("store: preview ephemeral database not found")

ErrPreviewEphemeralDatabaseNotFound is returned by GetPreviewEphemeralDatabaseByPreviewAndKey when no row matches.

View Source
var ErrProjectNotFound = errors.New("store: project not found")

ErrProjectNotFound is returned by GetProject and DeleteProject when id doesn't match any row.

View Source
var ErrPublicPortInUse = errors.New("store: public port already in use by another database")

ErrPublicPortInUse is returned by SetDatabasePublicAccess when an explicitly requested port is already assigned to a different database. The unique index migrations/0026 adds on public_port is the hard backstop; this is the friendly error path that avoids ever reaching it in the normal case.

View Source
var ErrPublicPortRangeExhausted = errors.New("store: no free public port available")

ErrPublicPortRangeExhausted is returned by SetDatabasePublicAccess when auto-assignment finds no free port left in [PublicPortRangeStart, PublicPortRangeEnd].

View Source
var ErrPushSubscriptionNotFound = errors.New("store: push subscription not found")

ErrPushSubscriptionNotFound is returned by DeletePushSubscription when no row matches (id, userID).

View Source
var ErrRegistryCredentialNotFound = errors.New("store: registry credential not found")

ErrRegistryCredentialNotFound is returned by GetRegistryCredential and DeleteRegistryCredential when id doesn't match any row.

View Source
var ErrReservedProject = errors.New("store: the global project is reserved")

ErrReservedProject is returned when a caller tries to delete GlobalProjectID.

View Source
var ErrRestoreHistoryNotFound = errors.New("store: restore history record not found")

ErrRestoreHistoryNotFound is returned by FinishRestoreHistory when id doesn't match any row.

View Source
var ErrSSHNodeProvisionNotFound = errors.New("store: ssh node provision not found")

ErrSSHNodeProvisionNotFound is returned by GetSSHNodeProvision when id doesn't match any row.

View Source
var ErrSavedQueryExists = errors.New("store: saved query name already exists")

ErrSavedQueryExists is returned when the caller already has a saved query with that name.

View Source
var ErrSavedQueryNotFound = errors.New("store: saved query not found")

ErrSavedQueryNotFound is returned when a saved query does not exist for the caller.

View Source
var ErrScheduledTaskNotFound = errors.New("store: scheduled task not found")

ErrScheduledTaskNotFound is returned by GetScheduledTask, UpdateScheduledTask, RecordScheduledTaskRun, and DeleteScheduledTask when id doesn't match any row.

View Source
var ErrScheduledTaskRunNotFound = errors.New("store: scheduled task run not found")

ErrScheduledTaskRunNotFound is returned by GetScheduledTaskRun when id matches no run.

View Source
var ErrSchemaNewer = errors.New("database schema is newer than this binary supports")

ErrSchemaNewer is returned when a database's schema version is newer than this binary's newest migration.

View Source
var ErrSecretValueNotFound = errors.New("store: secret value not found")

ErrSecretValueNotFound is returned by GetSecretValue when no value has been set for that (service, key) pair.

View Source
var ErrServiceDEKNotFound = errors.New("store: service DEK not found")

ErrServiceDEKNotFound is returned by GetServiceDEK when no DEK has been generated for a service yet, i.e. no secret value has ever been set for it.

View Source
var ErrServiceNotFound = errors.New("store: service not found")

ErrServiceNotFound is returned by GetDesiredService when no service has that name.

View Source
var ErrServiceVolumeBackupNotFound = errors.New("store: service volume backup schedule not found")

ErrServiceVolumeBackupNotFound is returned by GetServiceVolumeBackupSchedule when no row exists for the given service/volume pair.

View Source
var ErrServiceVolumeNotFound = errors.New("store: service volume not found")

ErrServiceVolumeNotFound is returned by ResolveServiceVolumeDockerName when serviceName has no volume by that logical name.

View Source
var ErrSessionLinkTokenAlreadyUsed = errors.New("store: session link token already used")

ErrSessionLinkTokenAlreadyUsed is returned by ClaimSessionLinkToken when the token was already used by a concurrent request.

View Source
var ErrSessionLinkTokenNotFound = errors.New("store: session link token not found")

ErrSessionLinkTokenNotFound is returned by GetSessionLinkTokenByHash when no row matches.

View Source
var ErrSignInAlertTokenUsed = errors.New("store: sign-in alert token is invalid, used or expired")

ErrSignInAlertTokenUsed covers an unknown, used or expired alert token.

View Source
var ErrTagNameTaken = errors.New("store: tag name already exists")

ErrTagNameTaken is SaveTag's failure mode when name is already used by a different tag (tags.name's own UNIQUE constraint).

View Source
var ErrTagNotFound = errors.New("store: tag not found")

ErrTagNotFound is returned by GetTag, DeleteTag, AttachAppTag, and DetachAppTag when id doesn't match any row.

View Source
var ErrTeamInviteInvalid = errors.New("store: team invite is invalid or expired")

ErrTeamInviteInvalid covers an unknown, expired, revoked or already used invite, deliberately one error so a probe learns nothing about which.

View Source
var ErrTrustedDeviceNotFound = errors.New("store: trusted device not found")

ErrTrustedDeviceNotFound is returned for an unknown, revoked or expired device.

View Source
var ErrUpgradeHistoryNotFound = errors.New("store: upgrade history entry not found")

ErrUpgradeHistoryNotFound is returned when no history row has the id.

View Source
var ErrUserEmailExists = errors.New("store: user email already exists")

ErrUserEmailExists is CreateUser's failure mode when email is already taken by a different row.

View Source
var ErrUserNotFound = errors.New("store: user not found")

ErrUserNotFound is returned by GetUserByID and GetUserByEmail when no row matches.

View Source
var ErrVolumeBackupPolicyNotFound = errors.New("store: volume backup policy not found")

ErrVolumeBackupPolicyNotFound means no policy was ever set for the volume.

View Source
var ErrVolumeCloneRestoreNotFound = errors.New("store: volume clone restore record not found")

ErrVolumeCloneRestoreNotFound is returned by FinishVolumeCloneRestore when id doesn't match any row.

View Source
var ErrWebhookDeliveryNotFound = errors.New("store: webhook delivery not found")

ErrWebhookDeliveryNotFound is returned by GetWebhookDelivery when no row has the given ID.

Functions

func AIAssistantSecretsKey added in v0.2.0

func AIAssistantSecretsKey() string

AIAssistantSecretsKey is the internal/secrets serviceName the BYOK LLM API key is stored under (envKey "api_key"), the same sentinel-service pattern EmailSettingsSecretsKey already establishes for platform-wide, non-app credentials.

func AIInternalTokenSecretsKey added in v0.2.0

func AIInternalTokenSecretsKey() string

AIInternalTokenSecretsKey is the internal/secrets serviceName the control plane's own self-call API token is stored under (envKey "token"): minted once so the embedded AI engine can call this instance's own REST API the same way any external MCP client would. Deliberately a separate serviceName from AIAssistantSecretsKey, not a second envKey under it: clearing the operator's BYOK LLM key (DELETE /api/v1/settings/ai-assistant) must never invalidate this platform-internal credential, since re-enabling the assistant later shouldn't require re-minting a root-scoped token.

func AppEnvHashes added in v0.2.0

func AppEnvHashes(serviceName string, literal, secretValues map[string]string) map[string]string

AppEnvHashes hashes the env an app itself owns: literal values overlaid by resolved secret values (which win, matching the container's own merge).

func AppIntegrationSecretsKey added in v0.2.0

func AppIntegrationSecretsKey(serviceName, integrationKey string) string

AppIntegrationSecretsKey is the internal/secrets serviceName one app's one attached integration's field values are stored under, distinct per (serviceName, integrationKey) pair so detaching one integration (DeleteAll on this namespace) can never touch the app's own secrets or a different attached integration's values, mirroring ProjectEnvSecretsKey's exact "distinct namespace" shape.

func AppliedFields added in v0.2.0

func AppliedFields(svc DesiredService) map[string]string

AppliedFields summarizes the scalar settings baked into a container at creation. Resources and health are applied live, so they are not here.

func AuditLikeLiteral added in v0.2.0

func AuditLikeLiteral(s string) string

AuditLikeLiteral escapes s for use inside an AuditEntryFilter.PathLike pattern.

func BackupTargetSecretsKey

func BackupTargetSecretsKey(targetID string) string

BackupTargetSecretsKey is the internal/secrets serviceName a backup target's access key ID and secret access key are stored under (envKeys "access_key_id" and "secret_access_key"). A function, not a constant format string inlined at each call site, so internal/api and internal/backup can never drift into computing this two different ways.

func BitbucketAppSecretsKey

func BitbucketAppSecretsKey() string

BitbucketAppSecretsKey is the internal/secrets serviceName the OAuth consumer's secret and access_token/refresh_token/token_expires_at are stored under. A fixed constant, not parameterized: there is only ever one Bitbucket connection per control plane, the same reasoning GitHubAppSecretsKey/GitLabAppSecretsKey's own doc comments give.

func BranchEnvOverrideSecretsKey added in v0.2.0

func BranchEnvOverrideSecretsKey(serviceName, branchPattern string) string

BranchEnvOverrideSecretsKey is the internal/secrets serviceName a branch-scoped override's secret-marked value is stored under, mirroring EnvironmentEnvSecretsKey: one DEK per (service, branch pattern) pair, independent of serviceName's own per-app secrets, so deleting a branch override never touches any other stored secret.

func CanaryServiceName added in v0.2.0

func CanaryServiceName(serviceName string) string

CanaryServiceName returns the hidden service name that runs serviceName's canary.

func CloudflareDNSSecretsKey

func CloudflareDNSSecretsKey() string

CloudflareDNSSecretsKey is the internal/secrets serviceName the Cloudflare DNS-01 API token is stored under (envKey CloudflareDNSTokenEnvKey), mirroring CloudflareTunnelSecretsKey's shape but for a distinct credential: a scoped Cloudflare API token (Zone:DNS:Edit), not the cloudflared connector token.

func CloudflareTunnelSecretsKey

func CloudflareTunnelSecretsKey() string

CloudflareTunnelSecretsKey is the internal/secrets serviceName the Cloudflare Tunnel token is stored under (envKey CloudflareTunnelTokenEnvKey), mirroring EmailSettingsSecretsKey's exact shape: one platform-wide credential, not per-app.

func DBUpgradeTerminal added in v0.2.0

func DBUpgradeTerminal(state string) bool

DBUpgradeTerminal reports whether state is a final state.

func DefaultModelKeyID added in v0.2.0

func DefaultModelKeyID(model string) string

DefaultModelKeyID is the id of a model's original key.

func DefaultTeamRole added in v0.2.0

func DefaultTeamRole(abilities []string) string

DefaultTeamRole picks the default team role matching flat abilities.

func DeployFreezeScopeApp added in v0.2.0

func DeployFreezeScopeApp(serviceName string) string

DeployFreezeScopeApp returns the scope string for one app's own windows.

func DeploymentTrigger added in v0.2.0

func DeploymentTrigger(source string, hasRollbackTarget bool, prNumber int) string

DeploymentTrigger classifies a stored source; hasRollbackTarget is whether an image deploy re-deployed an image that already succeeded.

func DeviceLoginAuditPath added in v0.2.0

func DeviceLoginAuditPath(requestID string) string

DeviceLoginAuditPath is the audit path shared by every entry about one request, so a single filter returns its whole history. The id is not a credential.

func DeviceLoginItemKey added in v0.2.0

func DeviceLoginItemKey(requestID, state string) string

DeviceLoginItemKey identifies one state of one request for dismissal: a request that changes state gets a new key, so it reappears.

func DomainBasicAuthSecretsKey

func DomainBasicAuthSecretsKey(domain string) string

DomainBasicAuthSecretsKey is the internal/secrets serviceName a domain's basic-auth password is stored under (envKey DomainBasicAuthPasswordEnvKey), mirroring BackupTargetSecretsKey's "<kind>/<id>" shape, keyed by domain instead of a target ID.

func DomainTLSCertSecretsKey

func DomainTLSCertSecretsKey(domain string) string

DomainTLSCertSecretsKey is the internal/secrets serviceName a domain's BYO TLS certificate and private key are stored under (envKeys DomainTLSCertCertificateEnvKey/DomainTLSCertPrivateKeyEnvKey), mirroring DomainBasicAuthSecretsKey's "<kind>/<domain>" shape.

func EffectiveServiceDomains added in v0.2.0

func EffectiveServiceDomains(base []string, envID string, sets map[string][]string) []string

EffectiveServiceDomains is the host set an app routes while it is tagged with envID: that environment's own set when non-empty, else the app's default set.

func EmailSettingsSecretsKey

func EmailSettingsSecretsKey() string

EmailSettingsSecretsKey is the internal/secrets serviceName the platform-wide email settings' credentials are stored under (envKeys "smtp_password", "ses_secret_access_key", and "resend_api_key").

func EncodeDeploymentCursor added in v0.2.0

func EncodeDeploymentCursor(startedAt time.Time, id string) string

EncodeDeploymentCursor carries the keyset position (started_at, id) of the last row of a page.

func EnvironmentEnvSecretsKey added in v0.2.0

func EnvironmentEnvSecretsKey(environmentID string) string

EnvironmentEnvSecretsKey is the internal/secrets serviceName an environment's secret-marked shared env vars are stored under, mirroring ProjectEnvSecretsKey/OrganizationEnvSecretsKey.

func ExportDestinationSecretsKey added in v0.2.0

func ExportDestinationSecretsKey(id string) string

ExportDestinationSecretsKey is the internal/secrets serviceName a destination's secret blob is stored under (envKey "config").

func ExternalDatabaseSecretsKey added in v0.2.0

func ExternalDatabaseSecretsKey(name string) string

ExternalDatabaseSecretsKey is the internal/secrets service name a record's password lives under.

func FileSHA256 added in v0.2.0

func FileSHA256(path string) (int64, string, error)

FileSHA256 returns the size and hex sha256 of the file at path.

func FormatAuditTime

func FormatAuditTime(t time.Time) string

FormatAuditTime renders t as this package's audit_log.created_at format. Exported so internal/api's requireAbility, the only writer of AuditEntry.CreatedAt, produces values in the exact format ListAuditEntries' own cursor comparison assumes.

func GitHubAppSecretsKey

func GitHubAppSecretsKey() string

GitHubAppSecretsKey is the internal/secrets serviceName the GitHub App's client_secret, webhook_secret, and PEM private key are stored under (envKeys "client_secret", "webhook_secret", "private_key"). Mirrors BackupTargetSecretsKey's exact shape: a function, not a literal repeated at each call site, so internal/api and internal/githubapp can never drift into computing this two different ways.

A fixed constant, not parameterized by an ID like BackupTargetSecretsKey(targetID) is: there is only ever one GitHub App connection per control plane (github_app_connections is a singleton table, id=1 only), unlike backup targets which are one-per-connected-bucket. The "/" makes this string structurally impossible to collide with a real service name: every real desired_services row name is validated as a Docker-container/ DNS-label-safe token (see internal/spec's service name validation) and can never contain a "/", the same reasoning BackupTargetSecretsKey's own doc comment gives for its "backup-target/"+targetID shape.

func GitLabAppSecretsKey

func GitLabAppSecretsKey() string

GitLabAppSecretsKey is the internal/secrets serviceName the OAuth Application's client_secret and access_token/refresh_token/ token_expires_at are stored under. A fixed constant, not parameterized: there is only ever one GitLab connection per control plane, the same reasoning GitHubAppSecretsKey's own doc comment gives.

func GitSourceSecretsKey

func GitSourceSecretsKey(serviceName string) string

GitSourceSecretsKey is the internal/secrets serviceName a git source's deploy token ("deploy_token" envKey) and webhook HMAC secret ("webhook_secret" envKey) are stored under, the same distinct-namespace-from-the-real-service reasoning BackupTargetSecretsKey's own doc comment already establishes: a git source's own credentials must never share a DEK with the app's actual runtime env secrets (service.go's SaveDesiredService/secret_env), which live under the plain service name.

func GiteaAppSecretsKey added in v0.2.0

func GiteaAppSecretsKey() string

GiteaAppSecretsKey is the internal/secrets serviceName the OAuth2 application's client_secret and access_token/refresh_token/ token_expires_at are stored under. A fixed constant, not parameterized: there is only ever one Gitea connection per control plane, the same reasoning GitLabAppSecretsKey's own doc comment gives.

func HashEnvValue added in v0.2.0

func HashEnvValue(serviceName, key, value string) string

HashEnvValue is the short, service-scoped digest of one env value kept in an AppliedConfig. It is truncated so it can detect a change but not be used to recover a value.

func InspectSnapshot added in v0.2.0

func InspectSnapshot(ctx context.Context, path string) (int, error)

InspectSnapshot opens the SQLite file read-only, runs integrity_check, and returns its schema migration version.

func IsCanaryService added in v0.2.0

func IsCanaryService(name string) bool

IsCanaryService reports whether name is a hidden canary clone.

func IsPipelineTerminal added in v0.2.0

func IsPipelineTerminal(status string) bool

IsPipelineTerminal reports whether status is a final state.

func IsSupportedEngine

func IsSupportedEngine(id string) (bool, error)

IsSupportedEngine reports whether id is a real, registered database engine. internal/api's validateDatabaseResource and internal/store.SaveDesiredDatabase's own callers use this instead of each hardcoding its own postgres/redis/mysql comparison chain, so adding a new engine's identity here is one file to edit, not a grep across the codebase for every hardcoded chain.

func LowerTeamRole added in v0.2.0

func LowerTeamRole(a, b string) string

LowerTeamRole returns the less privileged of two roles.

func MaxSchemaVersion added in v0.2.0

func MaxSchemaVersion() (int, error)

MaxSchemaVersion is the newest migration version this binary knows.

func ModelSecretsKey added in v0.2.0

func ModelSecretsKey(name string) string

ModelSecretsKey is the internal/secrets namespace holding a model's optional HuggingFace token.

func NetworkShareSecretsKey added in v0.2.0

func NetworkShareSecretsKey(id string) string

NetworkShareSecretsKey is the internal/secrets serviceName a network share's CIFS password is stored under (envKey "password").

func NewAIChatConfirmationID added in v0.2.0

func NewAIChatConfirmationID() (string, error)

NewAIChatConfirmationID mints a confirmation id.

func NewAIChatMessageID added in v0.2.0

func NewAIChatMessageID() (string, error)

NewAIChatMessageID mints a message id.

func NewAIChatSessionID added in v0.2.0

func NewAIChatSessionID() (string, error)

NewAIChatSessionID mints a session id.

func NewAppEventID added in v0.2.0

func NewAppEventID() (string, error)

NewAppEventID mints an opaque event ID.

func NewAppScheduleHistoryID added in v0.2.0

func NewAppScheduleHistoryID() (string, error)

NewAppScheduleHistoryID mints an opaque history entry ID, the same shape NewAppEventID already establishes.

func NewAuditEntryID

func NewAuditEntryID() (string, error)

NewAuditEntryID generates an opaque, URL-safe audit entry identifier, minted the same way NewDeployAttemptID mints its own (fixed-length crypto/rand bytes, base64 URL encoding, a short prefix).

func NewBranchEnvOverrideID added in v0.2.0

func NewBranchEnvOverrideID() (string, error)

NewBranchEnvOverrideID mints a random branch env override ID, the same crypto/rand-plus-base64 scheme NewPreviewEnvironmentID already establishes.

func NewDatabaseAccessID added in v0.2.0

func NewDatabaseAccessID() (string, error)

NewDatabaseAccessID returns an opaque identifier for an access user record.

func NewDeployApprovalID added in v0.2.0

func NewDeployApprovalID() (string, error)

NewDeployApprovalID generates an opaque, URL-safe deploy approval identifier, minted the same way NewAuditEntryID mints its own.

func NewDeployAttemptID

func NewDeployAttemptID() (string, error)

NewDeployAttemptID generates an opaque, URL-safe deploy-attempt identifier, minted the same way internal/api/tokens.go's randomTokenID mints an API token ID (fixed-length crypto/rand bytes, base64 URL encoding, a short prefix). Exported and placed in this package, unlike randomTokenID which stays private to internal/api: more than one package needs to mint one of these. The plain image-tag and manual build triggers both live in internal/api, but the git webhook receiver (internal/webhook) is a separate package needing the identical scheme, and duplicating the byte-length/encoding choice in two places would risk them silently drifting apart.

func NewDomainAutomationRunID added in v0.2.0

func NewDomainAutomationRunID() (string, error)

NewDomainAutomationRunID returns a fresh run id.

func NewExportDestinationID added in v0.2.0

func NewExportDestinationID() (string, error)

NewExportDestinationID mints a destination id.

func NewInstanceID added in v0.2.0

func NewInstanceID() (string, error)

NewInstanceID generates an opaque, URL-safe control-plane instance identifier, minted the same way NewAuditEntryID mints its own (fixed- length crypto/rand bytes, base64 URL encoding, a short prefix).

func NewPolicyAttachmentID

func NewPolicyAttachmentID() (string, error)

NewPolicyAttachmentID mints a random attachment ID, same scheme as NewPolicyID.

func NewPolicyID

func NewPolicyID() (string, error)

NewPolicyID mints a random policy ID, the same fixed-length crypto/rand-plus-base64 scheme NewDeployAttemptID already establishes.

func NewPreviewDatabaseIsolationID added in v0.2.0

func NewPreviewDatabaseIsolationID() (string, error)

NewPreviewDatabaseIsolationID mints a random tracking row ID, the same scheme NewPreviewEphemeralDatabaseID already establishes.

func NewPreviewEnvironmentID

func NewPreviewEnvironmentID() (string, error)

NewPreviewEnvironmentID mints a random preview environment ID, the same fixed-length crypto/rand-plus-base64 scheme NewDeployAttemptID already establishes for an analogous webhook-minted identifier.

func NewPreviewEphemeralDatabaseID added in v0.2.0

func NewPreviewEphemeralDatabaseID() (string, error)

NewPreviewEphemeralDatabaseID mints a random ephemeral database tracking row ID, the same scheme NewPreviewEnvironmentID already establishes for its own webhook-minted identifier.

func NewPushSubscriptionID added in v0.2.0

func NewPushSubscriptionID() (string, error)

NewPushSubscriptionID mints an opaque push subscription ID, the same shape NewAppEventID already establishes.

func NewStatusID added in v0.2.0

func NewStatusID(prefix string) (string, error)

NewStatusID mints an identifier with the given prefix.

func NewWebhookDeliveryID

func NewWebhookDeliveryID() (string, error)

NewWebhookDeliveryID generates an opaque, URL-safe webhook-delivery identifier, the same mint scheme NewDeployAttemptID already establishes (fixed-length crypto/rand bytes, base64 URL encoding, a short prefix).

func NodeProviderSecretsKey added in v0.2.0

func NodeProviderSecretsKey(provider string) string

NodeProviderSecretsKey is the internal/secrets serviceName a cloud provider's API token is stored under (envKey NodeProviderTokenEnvKey), mirroring RegistryCredentialSecretsKey's "<kind>/<id>" shape, one namespace per provider rather than per provision: the credential is platform-wide, entered once in Settings, reused by every provision call against that provider.

func OAuthProviderSecretsKey

func OAuthProviderSecretsKey(provider string) string

OAuthProviderSecretsKey is the internal/secrets serviceName a provider's client secret is stored under, mirroring BackupTargetSecretsKey's shape.

func OrganizationEnvSecretsKey added in v0.2.0

func OrganizationEnvSecretsKey(orgID string) string

OrganizationEnvSecretsKey is the internal/secrets serviceName an organization's secret-marked shared env vars are stored under, mirroring ProjectEnvSecretsKey one tier up.

func ProjectEnvSecretsKey added in v0.2.0

func ProjectEnvSecretsKey(projectID string) string

ProjectEnvSecretsKey is the internal/secrets serviceName a project's secret-marked shared env vars are stored under, distinct from the plain app-runtime service namespace, the same distinct-namespace-from-the-real-service reasoning GitSourceSecretsKey already establishes.

func RegistryCredentialSecretsKey

func RegistryCredentialSecretsKey(id string) string

RegistryCredentialSecretsKey is the internal/secrets serviceName a registry credential's password is stored under (envKey "password").

func RegistrySettingsSecretsKey

func RegistrySettingsSecretsKey() string

RegistrySettingsSecretsKey is the internal/secrets serviceName the built-in registry's generated password is stored under (envKey RegistryPasswordEnvKey), mirroring CloudflareTunnelSecretsKey's exact shape: one platform-wide credential, not per-app.

func Route53DNSSecretsKey added in v0.2.0

func Route53DNSSecretsKey() string

Route53DNSSecretsKey is the internal/secrets serviceName the Route53 DNS-01 credential pair is stored under, mirroring CloudflareDNSSecretsKey's shape but for an AWS IAM access key pair instead of a single API token.

func SecretEnvNames added in v0.2.0

func SecretEnvNames(refs []SecretEnvRef) []string

SecretEnvNames extracts just the names from refs, the shape a wire type like appResource.SecretEnv ([]string) still uses.

func ServiceVolumeDockerName

func ServiceVolumeDockerName(svc DesiredService, volumeName string) (string, bool)

ServiceVolumeDockerName finds svc's real Docker volume whose logical name (spec.Volume.Name, what an operator wrote in app.yaml) is volumeName, deriving it back from ServiceVolume.Name by stripping the fixed prefix internal/deploy's own volumeName() always applies ("app-"+svc.Name+"-"): ServiceVolume itself only stores the already- resolved Docker volume name (this struct's own doc comment), not the logical one it came from, so this is the one place that direction gets reversed. Exact-prefix stripping, not a generic split, so a logical name that itself contains "-" is never misparsed.

func TeamRoleAbilities added in v0.2.0

func TeamRoleAbilities(role string) []string

TeamRoleAbilities maps a team role onto the flat ability model, so team roles and IAM policies share one evaluation path.

func TeamRoleAtLeast added in v0.2.0

func TeamRoleAtLeast(role, minimum string) bool

TeamRoleAtLeast reports whether role ranks at or above min. Unknown roles rank below everything.

func UserTOTPSecretsKey

func UserTOTPSecretsKey(userID string) string

UserTOTPSecretsKey returns the internal/secrets serviceName a user's TOTP secret is stored under, parameterized by ID the same way BackupTargetSecretsKey(targetID) is: unlike GitHubAppSecretsKey's fixed singleton-row key, every user has their own. The "/" makes this structurally impossible to collide with a real desired_services name, same reasoning BackupTargetSecretsKey's own doc comment gives.

func ValidAIControlMode added in v0.2.0

func ValidAIControlMode(mode string) bool

ValidAIControlMode reports whether mode is one of the four known modes.

func ValidPreviewDatabaseStrategy added in v0.2.0

func ValidPreviewDatabaseStrategy(s string) bool

ValidPreviewDatabaseStrategy reports whether s is a known strategy.

func ValidProxyIntegrationMode added in v0.2.0

func ValidProxyIntegrationMode(mode string) bool

ValidProxyIntegrationMode reports whether mode is a known value.

func ValidTeamRole added in v0.2.0

func ValidTeamRole(role string) bool

ValidTeamRole reports whether role is one of the four team roles.

func ValidatePublicHTTPSPort added in v0.2.0

func ValidatePublicHTTPSPort(p int) error

ValidatePublicHTTPSPort rejects ports outside 0..MaxPublicHTTPSPort.

func VaultSecretsKey added in v0.2.0

func VaultSecretsKey() string

VaultSecretsKey is the internal/secrets serviceName the Vault credential is stored under (envKey VaultCredentialEnvKey), mirroring CloudflareTunnelSecretsKey's exact shape: one platform-wide credential, not per-app.

Types

type AIAssistantSettings added in v0.2.0

type AIAssistantSettings struct {
	Provider string
	Model    string
}

AIAssistantSettings is the single platform-wide AI assistant config row. No key field: that goes through internal/secrets instead.

type AIChatConfirmation added in v0.2.0

type AIChatConfirmation struct {
	ID         string
	SessionID  string
	MessageID  string
	ToolUseID  string
	ToolName   string
	ToolInput  json.RawMessage
	Status     string
	Result     json.RawMessage
	CreatedAt  time.Time
	ResolvedAt *time.Time
}

AIChatConfirmation is one pending-or-resolved mutating tool call, gating execution behind POST /api/v1/ai/sessions/{id}/confirmations/{id}. A tool call never executes until this row's Status leaves "pending".

type AIChatMessage added in v0.2.0

type AIChatMessage struct {
	ID        string
	SessionID string
	Role      string
	Content   string
	ToolUseID string
	ToolCalls []AIChatToolCall
	CreatedAt time.Time
}

AIChatMessage is one turn in a chat session's history: a plain user message, an assistant reply (Content plus, optionally, ToolCalls it proposed), or a tool-role message carrying one tool_result back to the model. ToolUseID is set only on a tool-role message and is never serialized over the API: it exists purely so internal/ai can reconstruct the Anthropic-format request from stored history.

type AIChatSession added in v0.2.0

type AIChatSession struct {
	ID        string
	CreatedAt time.Time
	UpdatedAt time.Time
}

AIChatSession is one chat conversation's identity and timestamps. The message history itself lives in AIChatMessage rows, not embedded here.

type AIChatToolCall added in v0.2.0

type AIChatToolCall struct {
	// ID is the model's own tool_use id, stable across the propose/
	// execute/result cycle for a single tool call.
	ID string `json:"id"`
	// ConfirmationID is set only for a mutating call: the id
	// POST .../confirmations/{id} resolves.
	ConfirmationID string          `json:"confirmation_id,omitempty"`
	Name           string          `json:"name"`
	Arguments      json.RawMessage `json:"arguments"`
	ReadOnly       bool            `json:"read_only"`
	// Status is "auto_executed" (read-only, already ran), "pending"
	// (mutating, awaiting confirmation), "approved", or "rejected".
	Status  string          `json:"status"`
	Result  json.RawMessage `json:"result,omitempty"`
	IsError bool            `json:"is_error,omitempty"`
}

AIChatToolCall is one tool invocation an assistant turn proposed, stored as part of AIChatMessage.ToolCalls and returned verbatim as the wire "tool_calls" array GET /api/v1/ai/sessions/{id} documents.

type AIControlSettings added in v0.2.0

type AIControlSettings struct {
	Mode            string
	AllowedEnvKinds []string
	UpdatedAt       string
	UpdatedBy       string
}

AIControlSettings is the singleton row that governs agent and AI access.

type APIToken

type APIToken struct {
	ID         string
	Name       string
	TokenHash  string
	Abilities  []string
	CreatedAt  time.Time
	LastUsedAt *time.Time
	ExpiresAt  *time.Time
	RevokedAt  *time.Time
	// AgentName and AgentDescription label a token issued to an AI agent;
	// AgentName is empty for an ordinary token.
	AgentName        string
	AgentDescription string
	// OwnerUserID is the user who minted the token; empty for a
	// system-minted token.
	OwnerUserID string
}

APIToken is one non-interactive credential, the backend auth foundation: a CLI, an MCP server, or a third-party integration authenticates with the plaintext token this row's TokenHash is a SHA-256 digest of, scoped to Abilities. The plaintext itself is never stored anywhere, generated once by internal/api and returned to the caller exactly once.

type APITokenScope added in v0.2.0

type APITokenScope struct {
	TokenID   string
	TeamID    string
	ProjectID string
	Role      string
}

APITokenScope limits a token to one team, optionally one project, and a role.

type App

type App struct {
	ID        string
	Name      string
	ProjectID string
	CreatedAt string
	UpdatedAt string
}

App is stage 1 of multi-service apps (migrations/0039_apps.sql): a named owner that zero or more store.DesiredService rows can belong to via their AppID field. ProjectID mirrors DesiredService.ProjectID: empty string means no project, not merely "unset".

type AppEvent added in v0.2.0

type AppEvent struct {
	ID        string
	AppName   string
	Kind      string
	Actor     string
	Title     string
	Detail    string
	Keys      []string
	CreatedAt time.Time
}

AppEvent is one recorded config or lifecycle change. Keys holds env or secret key names only, never values.

type AppEventCursor added in v0.2.0

type AppEventCursor struct {
	At time.Time
	ID string
}

AppEventCursor is the (time, id) position after which ListAppEvents resumes.

type AppImportItem added in v0.2.0

type AppImportItem struct {
	SessionID     string
	SourceID      string
	SourceName    string
	TargetName    string
	Kind          string
	State         string
	Selected      bool
	Reason        string
	EntryJSON     string
	Domains       []string
	Volumes       []AppImportVolume
	AttemptID     string
	CreatedTarget bool
	UpdatedAt     time.Time
}

AppImportItem is one source app or service within a session.

type AppImportMapping added in v0.2.0

type AppImportMapping struct {
	From string `json:"from"`
	To   string `json:"to"`
}

AppImportMapping rewrites one source hostname to a new one in env values.

type AppImportSession added in v0.2.0

type AppImportSession struct {
	ID        string
	Platform  string
	SourceURL string
	Step      string
	Collision string
	Mappings  []AppImportMapping
	CreatedAt time.Time
	UpdatedAt time.Time
}

AppImportSession is one guided app import (migrations/0408_app_import_sessions.sql).

type AppImportVolume added in v0.2.0

type AppImportVolume struct {
	Name string `json:"name"`
	// SourceName is the volume's name on the source host.
	SourceName    string `json:"source_name,omitempty"`
	ContainerPath string `json:"container_path"`
	Copied        bool   `json:"copied"`
	CopiedAt      string `json:"copied_at,omitempty"`
}

AppImportVolume is one persistent volume and whether the operator confirmed its data was copied.

type AppIntegration added in v0.2.0

type AppIntegration struct {
	ID             string
	ServiceName    string
	IntegrationKey string
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

AppIntegration is one row of internal/integrations' curated catalog attached to an app. Field values (DSN, API key) live in service_secrets/service_secret_values under AppIntegrationSecretsKey(ServiceName, IntegrationKey), not here: see migrations/0119_app_integrations.sql's own doc comment.

type AppListFilter added in v0.2.0

type AppListFilter struct {
	Query         string
	ProjectID     string
	Environment   string
	Tags          []string
	Limit, Offset int
}

AppListFilter narrows and pages the app list. Zero values mean no filter; Limit 0 means no paging.

type AppSchedule added in v0.2.0

type AppSchedule struct {
	ServiceName string
	Cron        string
	Branch      string
	Timezone    string
	Enabled     bool
	// NextFireAt is nil until internal/scheduledeploy.Scheduler has armed
	// this schedule at least once; see that package's own doc comment for
	// why this is persisted rather than kept only in memory.
	NextFireAt *time.Time
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

AppSchedule is one app's configured recurring redeploy (migrations/0250_app_schedules.sql): the latest commit on Branch is deployed whenever Cron fires, evaluated in Timezone.

type AppScheduleHistoryEntry added in v0.2.0

type AppScheduleHistoryEntry struct {
	ID           string
	ServiceName  string
	ScheduledFor time.Time
	FiredAt      time.Time
	Status       string
	Reason       string
	CreatedAt    time.Time
}

AppScheduleHistoryEntry is one recorded evaluation of a due schedule: fired, skipped because a freeze window was active, or failed.

type AppSleep added in v0.2.0

type AppSleep struct {
	ServiceName string
	IdleMinutes int
	Sleeping    bool
	// HoldRequests makes a request that wakes the app wait for it (function mode).
	HoldRequests bool
	Since        time.Time
}

AppSleep is one app's sleep-when-idle setting (migrations/0379_app_sleep.sql). IdleMinutes 0 or a missing row means the app never sleeps.

type AppStream added in v0.2.0

type AppStream struct {
	ID            string
	ServiceName   string
	ContainerPort int
	HostPort      int
	Protocol      string
	CreatedAt     string
}

AppStream is one raw TCP port forward (migrations/0279_app_streams.sql): HostPort on this control plane's own host reaches ContainerPort on ServiceName's container, proxied by Caddy's layer4 app (internal/ingress) rather than a second proxy process.

type AppVolumeMove added in v0.2.0

type AppVolumeMove struct {
	ID          string
	ServiceName string
	FromNodeID  string
	ToNodeID    string
	Status      string
	Error       string
	Steps       []AppVolumeMoveStep
	StartedAt   string
	FinishedAt  string
}

AppVolumeMove is one "move this app to another node, taking its volumes with it" attempt: ServiceName's placement moving from FromNodeID to ToNodeID, with Steps recording exactly how far it got. Status mirrors BackupHistory's own running/succeeded/failed lifecycle.

type AppVolumeMoveStep added in v0.2.0

type AppVolumeMoveStep struct {
	Name       string `json:"name"`
	Status     string `json:"status"`
	Error      string `json:"error,omitempty"`
	StartedAt  string `json:"started_at"`
	FinishedAt string `json:"finished_at,omitempty"`
}

AppVolumeMoveStep is one step of a "move with volumes" attempt (stop the app, archive one volume, restore it onto the new node, ...), appended to AppVolumeMove.Steps as each step starts and finishes: this is what makes a half-completed move diagnosable rather than a black box, see internal/api's handleMoveAppWithVolumes for the exact step sequence.

type AppliedConfig added in v0.2.0

type AppliedConfig struct {
	ServiceName string
	Release     string
	EnvHashes   map[string]string
	Fields      map[string]string
	AppliedAt   time.Time
	// HeldUntil is when the held previous release is due for removal, zero
	// when none is held.
	HeldUntil time.Time
}

AppliedConfig is what a service's newest container was created with. EnvHashes maps app-owned env keys (literal and secret-backed) to short hashes of their values; Fields holds scalar settings such as port.

type AppliedDrift added in v0.2.0

type AppliedDrift struct {
	EnvKeys    []string
	ConfigKeys []string
}

AppliedDrift is what differs between desired state and a snapshot.

func DiffApplied added in v0.2.0

func DiffApplied(applied *AppliedConfig, wantEnv, wantFields map[string]string) AppliedDrift

DiffApplied compares the desired app-owned env hashes and fields with a snapshot. Keys are sorted. A key only in desired is added, only in the snapshot is removed, and differing hashes is changed; all report as env keys. Fields that differ report by name.

type AuditEntry

type AuditEntry struct {
	ID         string
	ActorType  string // "session", "token", or "system" (internal/ingress's SQLiteStorage, no request behind it)
	ActorID    string
	ActorName  string
	Ability    string
	Method     string
	Path       string
	StatusCode int
	RemoteAddr string
	CreatedAt  string
	ClientKind string // "cli", "dashboard", "mcp", "api" (migrations/0077, derived from User-Agent), or "system"
	// AgentName is the agent label of the token that made the request, empty
	// for a session or an unlabeled token. AgentClient is the self-reported
	// MCP client name and version.
	AgentName   string
	AgentClient string
	// Action is a stable event name such as AuditActionDeviceLoginApproved,
	// empty for plain request rows. Filters use it, never the path.
	Action string
}

AuditEntry is one recorded request that passed internal/api's requireAbility at more than AbilityRead (migrations/0043): who did what, closing the gap docs/comparison.md's own "no audit log exists anywhere in the codebase" line calls out. CreatedAt is a pre-formatted RFC3339Nano string, not a time.Time, the same "caller controls the wire format" convention BackupHistory's own StartedAt/FinishedAt fields already establish in this package.

type AuditEntryFilter

type AuditEntryFilter struct {
	Path       string
	Method     string
	ClientKind string
	// Search is a case-insensitive substring matched across actor_name,
	// ability, method, path and remote_addr.
	Search string
	// FailedOnly restricts results to status_code >= 400.
	FailedOnly bool
	// AgentName restricts results to entries made by this agent label.
	AgentName string
	// Action matches an event name exactly, or every event of a family
	// when given without a dot ("device_login" matches "device_login.expired").
	Action string
	// PathLike keeps rows whose path matches any of these LIKE patterns
	// (escape literals with AuditLikeLiteral, '%' is the wildcard).
	PathLike []string
	// ActionPrefixes keeps rows whose action starts with any of these.
	ActionPrefixes []string
}

AuditEntryFilter narrows ListAuditEntries to a specific resource's own audit trail, e.g. an app's config-changing requests (Path set to that app's exact path, Method to "PUT"). A zero-value filter applies no narrowing, the same behavior ListAuditEntries always had.

type BackupDrill added in v0.2.0

type BackupDrill struct {
	ID              string
	BackupHistoryID string
	ResourceKind    string
	DatabaseName    string
	ServiceName     string
	VolumeName      string
	TargetID        string
	Trigger         string
	Status          string
	Stage           string
	ObjectOK        bool
	ChecksumOK      bool
	RestoreOK       bool
	ContentOK       bool
	Files           int64
	Bytes           int64
	DurationMS      int64
	Error           string
	StartedAt       string
	FinishedAt      string
}

BackupDrill is one restore drill attempt.

type BackupHistory

type BackupHistory struct {
	ID           string
	DatabaseName string
	// ResourceKind is BackupResourceKindDatabase for every row written
	// before migrations/0075 added this column: that migration's own
	// DEFAULT 'database' makes this the real, correct value for those
	// rows, not a placeholder.
	ResourceKind   string
	ServiceName    string
	VolumeName     string
	TargetID       string
	ObjectKey      string
	SizeBytes      int64
	Status         string
	Error          string
	StartedAt      string
	FinishedAt     string
	ChecksumSHA256 string
	// Codec is "" for a raw legacy object, "zstd" or "zstd+age" for a sealed one.
	Codec          string
	ManifestDigest string
	ManifestFiles  int64
	ManifestBytes  int64
}

BackupHistory is one attempted backup to one backup target, of either a managed database (DatabaseName, ResourceKind BackupResourceKindDatabase) or an app service's named volume (ServiceName/VolumeName, ResourceKind BackupResourceKindVolume): the two identity shapes are mutually exclusive, never both populated on the same row. Error is empty unless Status is BackupStatusFailed. ChecksumSHA256 is empty until FinishBackupHistory records a succeeded attempt's dump checksum (empty for a running or failed attempt, and for any row written before migrations/0069_backup_verification.sql).

type BackupTarget

type BackupTarget struct {
	ID        string
	Name      string
	Provider  string
	Endpoint  string
	Region    string
	Bucket    string
	CreatedAt string
}

BackupTarget is a connected S3-compatible bucket a database backup can be uploaded to. No credential fields: see this table's own migration comment. A caller resolving credentials does so separately through internal/secrets, keyed by BackupTargetSecretsKey(target.ID).

type BackupTargetProtection added in v0.2.0

type BackupTargetProtection struct {
	TargetID   string
	ObjectLock bool
	LockMode   string
	Versioning string
	CanDelete  bool
	ProbeError string
	CheckedAt  string
}

BackupTargetProtection is the last bucket protection probe of a target.

type BackupUsage added in v0.2.0

type BackupUsage struct {
	ResourceKind string
	DatabaseName string
	ServiceName  string
	VolumeName   string
	Count        int64
	Bytes        int64
}

BackupUsage is the stored size of one resource's succeeded backups.

type BackupVerification

type BackupVerification struct {
	ID              string
	BackupHistoryID string
	Status          string
	ChecksumMatch   bool
	SizeMatch       bool
	FormatValid     bool
	DownloadedBytes int64
	Error           string
	CheckedBy       string
	StartedAt       string
	FinishedAt      string
}

BackupVerification is one attempt to confirm a previously succeeded backup_history row's stored object is still intact: re-downloaded, re-hashed, and checked against what was recorded at backup time, without ever attempting a live restore. Error is empty unless Status is BackupVerificationStatusFailed.

type BaseBackupHistory added in v0.2.0

type BaseBackupHistory struct {
	ID           string
	DatabaseName string
	TargetID     string
	ObjectKey    string
	LSN          string
	SizeBytes    int64
	Status       string
	Error        string
	StartedAt    string
	FinishedAt   string
}

BaseBackupHistory is one attempt to take a physical base backup, the point-in-time-restore counterpart of BackupHistory (a logical dump). ObjectKey names a single pg_basebackup --format=tar object, which already embeds backup_label; no second object is needed. LSN is diagnostics-only; nothing in the restore path re-parses it.

type BitbucketAppConnection

type BitbucketAppConnection struct {
	Key       string
	CreatedAt string
}

BitbucketAppConnection is the single-row bitbucket_app_connections table (migrations/0062_bitbucket_app_connection.sql). No secret fields: the consumer's own secret and the OAuth access_token/ refresh_token/token_expires_at live in internal/secrets instead, under BitbucketAppSecretsKey(), the same split GitHubAppConnection and GitLabAppConnection already establish.

type BuildCacheSetting added in v0.2.0

type BuildCacheSetting struct {
	AppName       string
	TargetID      string
	Enabled       bool
	Mode          string
	LastBuildAt   string
	LastResult    string
	LastWarning   string
	LastClearedAt string
	UpdatedAt     string
}

BuildCacheSetting points an app's BuildKit remote cache at a storage destination. AppName is empty for the global default.

type CPDRSettings added in v0.2.0

type CPDRSettings struct {
	InstallID         string
	Enabled           bool
	TargetID          string
	Recipients        []string
	Schedule          string
	RetainDaily       int
	RetainWeekly      int
	RetainMonthly     int
	DrillSchedule     string
	EscrowTargetID    string
	EscrowGeneratedAt time.Time
	EscrowAckedAt     time.Time
	LastBackupAt      time.Time
	LastBackupKey     string
	LastBackupError   string
	LastAttemptAt     time.Time
	LastDrillAt       time.Time
	LastDrillOK       bool
	LastDrillPartial  bool
	LastDrillDetail   string
	LastDrillMs       int64
}

CPDRSettings is the single control plane disaster recovery row. It holds age public recipients only, never a private key.

type CanaryRelease added in v0.2.0

type CanaryRelease struct {
	ServiceName   string
	CanaryService string
	Image         string
	Weight        int
	CreatedAt     time.Time
}

CanaryRelease is an app's in-flight canary (migrations/0378_canary_releases.sql).

type CertStorageKeyInfo

type CertStorageKeyInfo struct {
	Key        string
	ModifiedAt time.Time
	Size       int64
	// IsTerminal is true for an exact stored value ("file"), false when
	// key only exists as a prefix of other stored keys ("directory"),
	// matching certmagic.Storage's own file-system-shaped key semantics.
	IsTerminal bool
}

CertStorageKeyInfo mirrors certmagic.KeyInfo's shape (see internal/ingress.SQLiteStorage.Stat), decoupled from the certmagic import so this package never needs to depend on Caddy/certmagic itself, only internal/ingress does.

type CertStorageValue

type CertStorageValue struct {
	Value      []byte
	ModifiedAt time.Time
}

CertStorageValue is one stored key's value and last-write time.

type CloneRestore

type CloneRestore struct {
	ID                 string
	SourceDatabaseName string
	NewDatabaseName    string
	BackupHistoryID    string
	Status             string
	Error              string
	StartedAt          string
	FinishedAt         string
}

CloneRestore is one attempted "restore as new database": a backup of SourceDatabaseName restored into NewDatabaseName, a database created fresh for this attempt rather than overwriting anything. Status reuses BackupStatusRunning/Succeeded/Failed, the same reasoning RestoreHistory's own doc comment gives for its identical lifecycle.

type CloudflareDNSSettings

type CloudflareDNSSettings struct {
	Enabled bool
}

CloudflareDNSSettings is the single platform-wide row: whether ACME DNS-01 via Cloudflare is enabled for wildcard domains. No token field: that goes through internal/secrets instead.

type CloudflareTunnelSettings

type CloudflareTunnelSettings struct {
	Enabled bool
}

CloudflareTunnelSettings is the single platform-wide row: whether the operator wants the cloudflared container running. No token field: that goes through internal/secrets instead.

type CodeLoginSettings added in v0.2.0

type CodeLoginSettings struct {
	Admins    bool
	Others    bool
	UpdatedAt time.Time
}

CodeLoginSettings says whether sign in with a code is offered to admin (root) accounts and to every other account.

type ComposeRevision added in v0.2.0

type ComposeRevision struct {
	AppID      string
	Revision   int
	Compose    string
	Profiles   []string
	Source     string
	TemplateID string
	CreatedBy  string
	CreatedAt  time.Time
}

ComposeRevision is one compose file a stack was deployed from.

type CustomTemplate added in v0.2.0

type CustomTemplate struct {
	ID          string
	Name        string
	Description string
	Compose     string
	// SourceApp is the app name this was captured from, informational
	// only: not a foreign key, so renaming or deleting that app later
	// never affects a template already saved from it.
	SourceApp string
	// CreatedBy is the principal ID (internal/api's callerPrincipal)
	// that saved this template, empty if that lookup failed at save
	// time.
	CreatedBy string
	CreatedAt string
	UpdatedAt string
}

CustomTemplate is an operator-defined one-click template (migrations/0270_custom_templates.sql), built from a running app's desired state (internal/compose.FromDesiredServices). Compose is a plain compose.yaml body, same shape as catalog.Template.Compose, so it deploys through the built-in catalog's own routes. Never holds a real secret value: see FromDesiredServices.

type CutoverRun added in v0.2.0

type CutoverRun struct {
	ID          string
	SessionID   string
	SourceID    string
	AppName     string
	Mode        string
	State       string
	Method      string
	DNSWrite    bool
	WasRouted   bool
	AcceptWarn  bool
	Awaiting    string
	DomainsJSON string
	StepsJSON   string
	PlanJSON    string
	Error       string
	CreatedAt   time.Time
	UpdatedAt   time.Time
	FinishedAt  time.Time
}

CutoverRun is one stored cutover run. DomainsJSON, StepsJSON and PlanJSON are owned by internal/cutover.

type DB

type DB struct {
	*sql.DB
}

DB wraps a *sql.DB opened against a single SQLite file, WAL mode and foreign keys on, migrated to the latest version before Open returns.

func Open

func Open(ctx context.Context, path string, opts ...OpenOption) (*DB, error)

Open opens (creating if needed) the SQLite database at path, applies pragmas, and runs every pending migration. path is a plain filesystem path, not a DSN; Open builds the DSN itself so callers never need to know the pragma query-string format.

func (*DB) AckCPDREscrow added in v0.2.0

func (db *DB) AckCPDREscrow(ctx context.Context, at time.Time) error

AckCPDREscrow records that the operator confirmed storing the escrow bundle offline.

func (*DB) AcknowledgeUpgrade added in v0.2.0

func (db *DB) AcknowledgeUpgrade(ctx context.Context, id, byType, byID, byName string, now time.Time) (e UpgradeHistoryEntry, changed bool, err error)

AcknowledgeUpgrade records who acknowledged the transition. The first acknowledgement wins; a repeat returns the stored entry unchanged and changed false.

func (*DB) AcquireCertStorageLock

func (db *DB) AcquireCertStorageLock(ctx context.Context, name string, staleAfter time.Duration) (bool, error)

AcquireCertStorageLock attempts to atomically claim the named lock: insert it if free, or steal it if the existing holder's last refresh is older than staleAfter (an abandoned lock from a holder that crashed without calling ReleaseCertStorageLock). Returns false, nil (not an error) if a different, still-fresh holder currently has the lock; the caller is expected to wait and retry, the same shape certmagic.FileStorage.Lock's own polling loop uses.

func (*DB) AddAppEvent added in v0.2.0

func (db *DB) AddAppEvent(ctx context.Context, e AppEvent) error

AddAppEvent records e, minting its ID and timestamp when unset.

func (*DB) AddComposeRevision added in v0.2.0

func (db *DB) AddComposeRevision(ctx context.Context, rev ComposeRevision) (int, error)

AddComposeRevision stores rev as appID's next revision number and returns that number. Revision and CreatedAt on rev are ignored.

func (*DB) AddDatabaseQueryHistory added in v0.2.0

func (db *DB) AddDatabaseQueryHistory(ctx context.Context, h DatabaseQueryHistory, keep int) (DatabaseQueryHistory, error)

AddDatabaseQueryHistory records an execution and trims the caller's history for that database to keep rows.

func (*DB) AddModelUsage added in v0.2.0

func (db *DB) AddModelUsage(ctx context.Context, rows []ModelUsage) error

AddModelUsage adds the deltas to their hourly rows in one transaction.

func (*DB) AddPendingTeardown added in v0.2.0

func (db *DB) AddPendingTeardown(ctx context.Context, name, nodeID string) error

AddPendingTeardown records name as awaiting teardown on nodeID. Idempotent.

func (*DB) AddPipelineTriggerLog added in v0.2.0

func (db *DB) AddPipelineTriggerLog(ctx context.Context, e PipelineTriggerLog) error

AddPipelineTriggerLog appends e and prunes the app's log to the newest PipelineTriggerLogKeep rows.

func (*DB) AddStatusIncidentUpdate added in v0.2.0

func (db *DB) AddStatusIncidentUpdate(ctx context.Context, u StatusIncidentUpdate) error

AddStatusIncidentUpdate appends a timeline entry.

func (*DB) AddStatusSamples added in v0.2.0

func (db *DB) AddStatusSamples(ctx context.Context, componentID, day string, ok, degraded, down int) error

AddStatusSamples adds probe counts to a component's counters for day (YYYY-MM-DD, UTC).

func (*DB) AddTeamMember added in v0.2.0

func (db *DB) AddTeamMember(ctx context.Context, teamID, userID, role string) error

AddTeamMember inserts a membership.

func (*DB) AppendPipelineLogs added in v0.2.0

func (db *DB) AppendPipelineLogs(ctx context.Context, lines []PipelineLogLine) error

AppendPipelineLogs inserts log lines in one transaction.

func (*DB) ArmAppScheduleNextRun added in v0.2.0

func (db *DB) ArmAppScheduleNextRun(ctx context.Context, serviceName string, next time.Time) error

ArmAppScheduleNextRun records the next time serviceName's schedule should fire. A no-op (not an error) once the schedule has been deleted or disabled out from under an in-flight tick.

func (*DB) AttachAppTag added in v0.2.0

func (db *DB) AttachAppTag(ctx context.Context, tagID, appName string) error

AttachAppTag attaches tagID to appName, idempotently: attaching an already-attached tag is a no-op, not a conflict, the same "declarative, not incremental" convention SetAppVaultEnv's own doc comment establishes for a different attach-style write.

func (*DB) AttachPolicy

func (db *DB) AttachPolicy(ctx context.Context, id, policyID, principalType, principalID string) error

AttachPolicy links policyID to one principal. Idempotent: attaching an already-attached (policy, principal) pair is a no-op, not an error, since the caller's intent ("this principal should have this policy") is already satisfied.

func (*DB) CancelDeployAttempt added in v0.2.0

func (db *DB) CancelDeployAttempt(ctx context.Context, id, from, by string, now time.Time) (bool, error)

CancelDeployAttempt moves an attempt from status from to canceled, recording who canceled it. Reports whether it moved.

func (*DB) ClaimDatabaseAccessUser added in v0.2.0

func (db *DB) ClaimDatabaseAccessUser(ctx context.Context, id string, now time.Time, lease time.Duration) (bool, error)

ClaimDatabaseAccessUser atomically moves an active record to revoking. A revoking record is retaken once its claim is older than lease.

func (*DB) ClaimDatabaseDataImport added in v0.2.0

func (db *DB) ClaimDatabaseDataImport(ctx context.Context, name, host string, port int, srcDB string, now time.Time, staleAfter time.Duration) error

ClaimDatabaseDataImport marks name as copying. It fails with ErrDataImportInProgress unless the previous run is finished or older than staleAfter, which covers a control plane that died mid-copy.

func (*DB) ClaimDeviceLoginExpiry added in v0.2.0

func (db *DB) ClaimDeviceLoginExpiry(ctx context.Context, requestID string, at time.Time, entry AuditEntry) (bool, error)

ClaimDeviceLoginExpiry records that a request lapsed and writes its audit entry in one transaction. It reports false when the expiry was already claimed, so the audit entry exists exactly once however often this runs.

func (*DB) ClaimInvite

func (db *DB) ClaimInvite(ctx context.Context, id string) error

ClaimInvite atomically marks the named invite accepted, only if it hasn't already been accepted or revoked: the same "WHERE clause plus rows-affected check is the single race-decision point" shape ClaimPasswordResetToken already establishes.

func (*DB) ClaimLapsedLoginApprovals added in v0.2.0

func (db *DB) ClaimLapsedLoginApprovals(ctx context.Context, now time.Time, limit int) ([]LoginApproval, error)

ClaimLapsedLoginApprovals marks up to limit pending or approved-but-unused approvals past their expiry as expired, returning the ones this call moved.

func (*DB) ClaimLapsedLoginCodes added in v0.2.0

func (db *DB) ClaimLapsedLoginCodes(ctx context.Context, now time.Time, limit int) ([]LoginCodeChallenge, error)

ClaimLapsedLoginCodes marks up to limit pending challenges past their expiry as expired and returns exactly the ones this call moved.

func (*DB) ClaimScheduledTaskRun added in v0.2.0

func (db *DB) ClaimScheduledTaskRun(ctx context.Context, run ScheduledTaskRun) (claimed bool, err error)

ClaimScheduledTaskRun inserts run (with ScheduledFor set) and advances the task's high-water mark to that occurrence in one transaction. claimed is false when another claim for the same occurrence already exists; the mark is still advanced so the scheduler converges. A run in status running also sets running_since; a missed run bumps consecutive_missed.

func (*DB) ClaimSessionLinkToken added in v0.2.0

func (db *DB) ClaimSessionLinkToken(ctx context.Context, id string) error

ClaimSessionLinkToken atomically marks the named token used, only if it hasn't been already: the WHERE clause and rows-affected check make this the single point two concurrent requests holding the same token race on, so at most one can ever establish a session from it. Same shape as ClaimPasswordResetToken.

func (*DB) ClaimTeamInvite added in v0.2.0

func (db *DB) ClaimTeamInvite(ctx context.Context, tokenHash, userID string, now time.Time) (TeamInvite, error)

ClaimTeamInvite marks a usable invite accepted by userID, at most once. The conditional UPDATE is what stops a replay racing a first use.

func (*DB) ClearAIAssistantSettings added in v0.2.0

func (db *DB) ClearAIAssistantSettings(ctx context.Context) error

ClearAIAssistantSettings resets provider/model to empty, the DELETE counterpart to UpdateAIAssistantSettings. Callers also delete the underlying secret separately (internal/secrets.Manager has no per-key delete, only DeleteAll for a whole serviceName), matching how this sentinel service holds exactly one secret value.

func (*DB) ClearDatabaseQueryHistory added in v0.2.0

func (db *DB) ClearDatabaseQueryHistory(ctx context.Context, database, principalType, principalID string) error

ClearDatabaseQueryHistory deletes the caller's history for a database.

func (*DB) ClearMajorUpgradeSnapshot added in v0.2.0

func (db *DB) ClearMajorUpgradeSnapshot(ctx context.Context, id string) error

ClearMajorUpgradeSnapshot forgets the rollback snapshot after it is deleted.

func (*DB) ClearOrphanSighting added in v0.2.0

func (db *DB) ClearOrphanSighting(ctx context.Context, kind, nodeID, name string) error

ClearOrphanSighting forgets a resource once it is gone or no longer orphaned.

func (*DB) ClearUserResetFlag added in v0.2.0

func (db *DB) ClearUserResetFlag(ctx context.Context, userID string, now time.Time) error

ClearUserResetFlag drops the reset flag after a password change or reset.

func (*DB) CompleteDatabaseAccessUser added in v0.2.0

func (db *DB) CompleteDatabaseAccessUser(ctx context.Context, id string, now time.Time) error

CompleteDatabaseAccessUser marks a claimed record revoked.

func (*DB) CompleteUpgradeNotes added in v0.2.0

func (db *DB) CompleteUpgradeNotes(ctx context.Context, id, notes, state string) error

CompleteUpgradeNotes stores the release-notes snapshot once. A row whose snapshot is already settled is left alone, never overwritten.

func (*DB) ConsumeLoginApproval added in v0.2.0

func (db *DB) ConsumeLoginApproval(ctx context.Context, id string, now time.Time) (bool, error)

ConsumeLoginApproval moves an approved approval to consumed, once, so the session it unlocks is issued exactly once. Approval must still be unexpired.

func (*DB) ConsumeSignInAlertToken added in v0.2.0

func (db *DB) ConsumeSignInAlertToken(ctx context.Context, id string, now time.Time) (SignInAlertToken, error)

ConsumeSignInAlertToken marks id used and returns it, exactly once, and only before it expires. Anything else is ErrSignInAlertTokenUsed.

func (*DB) CountAgentTokens added in v0.2.0

func (db *DB) CountAgentTokens(ctx context.Context, internalName, internalAgent string) (int, error)

CountAgentTokens counts live tokens with an agent label, excluding the internal assistant token.

func (*DB) CountLogArchivePoliciesForTarget added in v0.2.0

func (db *DB) CountLogArchivePoliciesForTarget(ctx context.Context, targetID string) (int, error)

CountLogArchivePoliciesForTarget reports how many policies reference a target.

func (*DB) CountPipelineLogs added in v0.2.0

func (db *DB) CountPipelineLogs(ctx context.Context, runID string) (int, error)

CountPipelineLogs returns how many log lines a run has stored.

func (*DB) CountRootUsersExcept added in v0.2.0

func (db *DB) CountRootUsersExcept(ctx context.Context, userID string) (int, error)

CountRootUsersExcept counts users holding the root ability, ignoring one user.

func (*DB) CountRootUsersOutsideRole added in v0.2.0

func (db *DB) CountRootUsersOutsideRole(ctx context.Context, roleID string) (int, error)

CountRootUsersOutsideRole counts root users who do not hold the given role.

func (*DB) CountScheduledTasksForService added in v0.2.0

func (db *DB) CountScheduledTasksForService(ctx context.Context, serviceName string) (int, error)

CountScheduledTasksForService returns how many jobs an app has, for the per-app cap.

func (*DB) CountSecretValuesByPrefix added in v0.2.0

func (db *DB) CountSecretValuesByPrefix(ctx context.Context, prefix []byte) (total, withPrefix int, err error)

CountSecretValuesByPrefix returns how many secret values exist and how many of those ciphertexts start with prefix.

func (*DB) CountStaleSecrets added in v0.2.0

func (db *DB) CountStaleSecrets(ctx context.Context, cutoff time.Time) (int, error)

CountStaleSecrets returns how many secret-backed values, across every tier that carries one (per-app service_secret_values, plus the secret-marked rows of the three shared-env tiers: project_env_vars, organization_env_vars, environment_env_vars), were last set or rotated strictly before cutoff. Used by GET /api/v1/system/doctor's stale_secrets check (internal/api/doctor.go) to surface one aggregate "N secrets need rotation" count instead of an operator having to check every app and every shared-env scope individually.

func (*DB) CountTeamProjects added in v0.2.0

func (db *DB) CountTeamProjects(ctx context.Context, teamID string) (int, error)

CountTeamProjects returns how many projects a team owns.

func (*DB) CountUsers

func (db *DB) CountUsers(ctx context.Context) (int, error)

CountUsers returns how many user rows exist, BootstrapAdmin's "has anyone signed up yet" check.

func (*DB) CreateAIChatSession added in v0.2.0

func (db *DB) CreateAIChatSession(ctx context.Context, id string, now time.Time) (AIChatSession, error)

CreateAIChatSession inserts a new, empty session row.

func (*DB) CreateAppImportSession added in v0.2.0

func (db *DB) CreateAppImportSession(ctx context.Context, s AppImportSession, items []AppImportItem) error

CreateAppImportSession inserts a session and its inventoried items.

func (*DB) CreateCutoverRun added in v0.2.0

func (db *DB) CreateCutoverRun(ctx context.Context, r CutoverRun) error

CreateCutoverRun inserts a run; ErrCutoverRunActive when the app has one in flight.

func (*DB) CreateDBUpgradeRun added in v0.2.0

func (db *DB) CreateDBUpgradeRun(ctx context.Context, r DBUpgradeRun) error

CreateDBUpgradeRun inserts a new run.

func (*DB) CreateExternalDatabase added in v0.2.0

func (db *DB) CreateExternalDatabase(ctx context.Context, d ExternalDatabase) error

CreateExternalDatabase inserts d, failing with ErrExternalDatabaseExists on a name clash.

func (*DB) CreateForgeDeployment added in v0.2.0

func (db *DB) CreateForgeDeployment(ctx context.Context, d ForgeDeployment) error

CreateForgeDeployment inserts d.

func (*DB) CreateLoginApproval added in v0.2.0

func (db *DB) CreateLoginApproval(ctx context.Context, a LoginApproval) error

CreateLoginApproval inserts a pending approval.

func (*DB) CreateLoginCodeChallenge added in v0.2.0

func (db *DB) CreateLoginCodeChallenge(ctx context.Context, c LoginCodeChallenge) error

CreateLoginCodeChallenge inserts a new pending challenge.

func (*DB) CreateMigrationSession added in v0.2.0

func (db *DB) CreateMigrationSession(ctx context.Context, s MigrationSession, items []MigrationItem) error

CreateMigrationSession inserts a session and its inventoried items.

func (*DB) CreateModelKey added in v0.2.0

func (db *DB) CreateModelKey(ctx context.Context, k ModelKey) error

CreateModelKey inserts a key for an existing model.

func (*DB) CreateNodeDrain added in v0.2.0

func (db *DB) CreateNodeDrain(ctx context.Context, d NodeDrain) error

CreateNodeDrain inserts a running drain, failing with ErrNodeMoveInProgress when the node is already draining.

func (*DB) CreateNodeMove added in v0.2.0

func (db *DB) CreateNodeMove(ctx context.Context, m NodeMove) error

CreateNodeMove inserts a running move, failing with ErrNodeMoveInProgress when the resource already has one.

func (*DB) CreatePipelineApproval added in v0.2.0

func (db *DB) CreatePipelineApproval(ctx context.Context, a PipelineApproval) error

CreatePipelineApproval opens a gate; a gate that already exists for the job and step is left untouched so resumption is idempotent.

func (*DB) CreatePipelineJobs added in v0.2.0

func (db *DB) CreatePipelineJobs(ctx context.Context, jobs []PipelineJob) error

CreatePipelineJobs inserts jobs and their steps for a run in one transaction.

func (*DB) CreatePipelineRun added in v0.2.0

func (db *DB) CreatePipelineRun(ctx context.Context, r PipelineRun) (PipelineRun, error)

CreatePipelineRun inserts r as queued and assigns its per-pipeline number.

func (*DB) CreateRole added in v0.2.0

func (db *DB) CreateRole(ctx context.Context, r Role) error

CreateRole inserts a custom role. Callers validate the abilities.

func (*DB) CreateScheduledTaskRun added in v0.2.0

func (db *DB) CreateScheduledTaskRun(ctx context.Context, run ScheduledTaskRun) error

CreateScheduledTaskRun inserts a manual or api run (no occurrence claim).

func (*DB) CreateSignInAlertToken added in v0.2.0

func (db *DB) CreateSignInAlertToken(ctx context.Context, t SignInAlertToken) error

CreateSignInAlertToken inserts an alert link row.

func (*DB) CreateTeamInvite added in v0.2.0

func (db *DB) CreateTeamInvite(ctx context.Context, inv TeamInvite) error

CreateTeamInvite stores a new invite. Only the token hash is kept.

func (*DB) CreateTrustedDevice added in v0.2.0

func (db *DB) CreateTrustedDevice(ctx context.Context, d TrustedDevice) error

CreateTrustedDevice inserts a trusted device.

func (*DB) CreateUser

func (db *DB) CreateUser(ctx context.Context, u User) error

CreateUser inserts a new user row, insert-only, never an upsert. On failure it re-checks by the relevant unique constraint to classify the cause, rather than assuming every failure means the same thing.

func (*DB) DatabaseNamesInEnvironment added in v0.2.0

func (db *DB) DatabaseNamesInEnvironment(ctx context.Context, envID string) (map[string]bool, error)

DatabaseNamesInEnvironment returns the databases tagged with envID, as a set.

func (*DB) DecideDeployApproval added in v0.2.0

func (db *DB) DecideDeployApproval(ctx context.Context, id, newStatus, approvedByType, approvedBy, approvedByName, reason, decidedAt string) (bool, error)

DecideDeployApproval moves a pending approval to a terminal status (approved, rejected, or expired), recording who decided it and when. Only ever succeeds from status = 'pending': a caller racing to decide an already-decided or already-expired row gets ok=false rather than silently overwriting an earlier decision, the same optimistic- concurrency shape a single UPDATE ... WHERE status = 'pending' gives for free without a separate SELECT-then-UPDATE round trip.

func (*DB) DecideLoginApproval added in v0.2.0

func (db *DB) DecideLoginApproval(ctx context.Context, id, userID string, approve bool, decidedBy string, now time.Time) (bool, error)

DecideLoginApproval approves or denies a pending, unexpired approval owned by userID and reports whether this call decided it.

func (*DB) DecidePipelineApproval added in v0.2.0

func (db *DB) DecidePipelineApproval(ctx context.Context, id int64, decision, by, comment string, now time.Time) (bool, error)

DecidePipelineApproval records a decision on a still-pending gate. It returns false when the gate was already decided.

func (*DB) DecidePipelineRunHold added in v0.2.0

func (db *DB) DecidePipelineRunHold(ctx context.Context, id string, approved bool, by string, now time.Time) (bool, error)

DecidePipelineRunHold records an approver's decision on a held run. It reports false when the run is not pending a decision.

func (*DB) DeleteAIChatSession added in v0.2.0

func (db *DB) DeleteAIChatSession(ctx context.Context, id string) error

DeleteAIChatSession removes a session and, via ON DELETE CASCADE (migrations/0108), every message and confirmation row under it. Returns ErrAIChatSessionNotFound if id doesn't exist.

func (*DB) DeleteApp

func (db *DB) DeleteApp(ctx context.Context, id string) error

DeleteApp removes an app row. desired_services.app_id is "REFERENCES apps(id) ON DELETE CASCADE" (migrations/0039_apps.sql), so every service belonging to this app is deleted along with it, unlike DeleteProject's ON DELETE SET NULL: an app owns its services' lifecycle, a project is only a label. Returns ErrAppNotFound if id doesn't exist.

func (*DB) DeleteAppImportSession added in v0.2.0

func (db *DB) DeleteAppImportSession(ctx context.Context, id string) error

DeleteAppImportSession forgets a session. Apps it created are kept.

func (*DB) DeleteAppIntegration added in v0.2.0

func (db *DB) DeleteAppIntegration(ctx context.Context, id string) error

DeleteAppIntegration removes an app integration row. Returns ErrAppIntegrationNotFound if id doesn't exist. Callers are also responsible for clearing the field values stored under AppIntegrationSecretsKey (internal/api's handleDetachAppIntegration does both in one request).

func (*DB) DeleteAppStream added in v0.2.0

func (db *DB) DeleteAppStream(ctx context.Context, id string) error

DeleteAppStream removes an app stream row. It does not itself touch any running container's published ports: the next deploy or restart of the owning service picks up the change, the same "store is desired state, a fresh container creation converges to it" split DeleteFirewallRule's own doc comment describes for ufw. Returns ErrAppStreamNotFound if id doesn't exist.

func (*DB) DeleteAppTimelineData added in v0.2.0

func (db *DB) DeleteAppTimelineData(ctx context.Context, name string) error

DeleteAppTimelineData removes name's events and applied config.

func (*DB) DeleteAuditEntriesOlderThan

func (db *DB) DeleteAuditEntriesOlderThan(ctx context.Context, cutoff time.Time) (int64, error)

DeleteAuditEntriesOlderThan removes every audit_log row created strictly before cutoff, returning the number of rows removed. The retention sweep (internal/api's RunAuditLogSweeper) and the manual purge endpoint both call this with a cutoff derived from the operator-configured retention window, rather than each rolling its own delete query.

func (*DB) DeleteBackupHistory added in v0.2.0

func (db *DB) DeleteBackupHistory(ctx context.Context, id string) error

DeleteBackupHistory removes id's backup_history row outright, whatever its status: the on-demand counterpart of PruneBackupHistory's bulk, retention-driven deletion, for an operator who wants to delete one archived backup right now rather than wait for retention to age it out. Callers are responsible for deleting the row's underlying stored object first (internal/backup.DeleteRunner does this); this only ever touches the store row.

func (*DB) DeleteBackupTarget

func (db *DB) DeleteBackupTarget(ctx context.Context, id string) error

DeleteBackupTarget removes a backup target row. It does not touch internal/secrets: the caller (internal/api's handleDeleteBackupTarget) deletes the credential secret separately, after this succeeds, the same "store row is the success signal, secret cleanup follows it" ordering used everywhere else credentials and store rows are paired. Returns ErrBackupTargetNotFound if id doesn't exist. Foreign key enforcement is on (store.go's "_pragma foreign_keys(ON)"), so deleting a target any backup_history row still references fails with a constraint error rather than silently orphaning history rows or cascading a delete a user didn't ask for; the caller surfaces that as a real error, not a bug to work around here.

func (*DB) DeleteBaseBackupHistory added in v0.2.0

func (db *DB) DeleteBaseBackupHistory(ctx context.Context, id string) error

DeleteBaseBackupHistory removes one base backup row, used after its bucket object has been deleted by base backup retention. Deleting an id that is already gone is not an error.

func (*DB) DeleteBitbucketAppConnection

func (db *DB) DeleteBitbucketAppConnection(ctx context.Context) error

DeleteBitbucketAppConnection removes the single bitbucket_app_connections row. Returns ErrBitbucketAppConnectionNotFound if nothing was connected. Like DeleteGitLabAppConnection, this does not erase the secrets values still held under BitbucketAppSecretsKey(); callers are expected to also call BitbucketAppSecrets.DeleteAll.

func (*DB) DeleteBuildCacheSetting added in v0.2.0

func (db *DB) DeleteBuildCacheSetting(ctx context.Context, appName string) error

DeleteBuildCacheSetting removes the setting for an app scope.

func (*DB) DeleteCanaryRelease added in v0.2.0

func (db *DB) DeleteCanaryRelease(ctx context.Context, serviceName string) error

DeleteCanaryRelease removes serviceName's canary row; a missing row is not an error.

func (*DB) DeleteCertStorageValue

func (db *DB) DeleteCertStorageValue(ctx context.Context, key string) error

DeleteCertStorageValue removes key. certmagic.Storage.Delete's doc comment requires deleting every key prefixed by key too ("directory" semantics), so this also removes any key under key+"/", not only an exact match. Deleting a key that exists as neither is not an error, matching certmagic's own FileStorage.Delete (os.RemoveAll on an already-absent path is a no-op).

func (*DB) DeleteComposeRevisions added in v0.2.0

func (db *DB) DeleteComposeRevisions(ctx context.Context, appID string) error

DeleteComposeRevisions removes every revision of appID.

func (*DB) DeleteCustomTemplate added in v0.2.0

func (db *DB) DeleteCustomTemplate(ctx context.Context, id string) error

DeleteCustomTemplate removes a custom template row. Returns ErrCustomTemplateNotFound if id doesn't exist.

func (*DB) DeleteDBUpgradePolicy added in v0.2.0

func (db *DB) DeleteDBUpgradePolicy(ctx context.Context, name string) error

DeleteDBUpgradePolicy removes a database's own row so it inherits the platform default again. The default row itself is never deleted.

func (*DB) DeleteDatabaseMeshPort added in v0.2.0

func (db *DB) DeleteDatabaseMeshPort(ctx context.Context, name string) error

DeleteDatabaseMeshPort releases a database's mesh port.

func (*DB) DeleteDatabaseSavedQuery added in v0.2.0

func (db *DB) DeleteDatabaseSavedQuery(ctx context.Context, database, principalType, principalID, id string) error

DeleteDatabaseSavedQuery removes one of the caller's saved queries.

func (*DB) DeleteDesiredDatabase

func (db *DB) DeleteDesiredDatabase(ctx context.Context, name string) error

DeleteDesiredDatabase removes a database's desired state, the same "not found" sentinel and "does not stop the running container itself" gap DeleteDesiredService's own doc comment documents, applied to a database instead of a service.

func (*DB) DeleteDesiredService

func (db *DB) DeleteDesiredService(ctx context.Context, name string) error

DeleteDesiredService removes a service's desired state, e.g. because the app was deleted through the HTTP API. It returns ErrServiceNotFound if no such service exists, the same sentinel GetDesiredService uses, so callers handle "not found" one way regardless of which method produced it.

Deleting desired state does not, by itself, stop or remove any container currently running for this service: as of this writing the application controller (internal/reconcile/application) treats a missing desired service as "nothing to do yet" (NoDesiredState), not "tear down what's running". Making delete actually converge to zero containers is a reconciler change, not a store one, and is a known gap left for that package.

func (*DB) DeleteDomainBasicAuth

func (db *DB) DeleteDomainBasicAuth(ctx context.Context, domain string) error

DeleteDomainBasicAuth removes domain's basic-auth row, if any. Idempotent: deleting a domain with none configured is not an error.

func (*DB) DeleteDomainErrorPage added in v0.2.0

func (db *DB) DeleteDomainErrorPage(ctx context.Context, domain string, statusCode int) error

DeleteDomainErrorPage removes domain's mapping for statusCode, if any. Idempotent: deleting one that doesn't exist is not an error.

func (*DB) DeleteDomainErrorPages added in v0.2.0

func (db *DB) DeleteDomainErrorPages(ctx context.Context, domain string) error

DeleteDomainErrorPages removes every custom error page configured for domain. Idempotent: clearing a domain with none configured is not an error.

func (*DB) DeleteDomainMaintenance

func (db *DB) DeleteDomainMaintenance(ctx context.Context, domain string) error

DeleteDomainMaintenance disables maintenance mode for domain, if enabled. Idempotent: clearing a domain with none configured is not an error.

func (*DB) DeleteDomainRedirect added in v0.2.0

func (db *DB) DeleteDomainRedirect(ctx context.Context, domain string) error

DeleteDomainRedirect removes domain's redirect row, if any. Idempotent: deleting a domain with none configured is not an error.

func (*DB) DeleteDomainTLSCert

func (db *DB) DeleteDomainTLSCert(ctx context.Context, domain string) error

DeleteDomainTLSCert removes domain's BYO cert row, if any. Idempotent: deleting a domain with none uploaded is not an error.

func (*DB) DeleteDomainTrafficPolicy added in v0.2.0

func (db *DB) DeleteDomainTrafficPolicy(ctx context.Context, domain, kind string) error

DeleteDomainTrafficPolicy restores the default for kind. Idempotent.

func (*DB) DeleteDomainWAF added in v0.2.0

func (db *DB) DeleteDomainWAF(ctx context.Context, domain string) error

DeleteDomainWAF removes domain's WAF/rate-limit row, if any, resetting it to the default (WAF off, rate limiting off). Idempotent: deleting a domain with none configured is not an error.

func (*DB) DeleteEnvironment

func (db *DB) DeleteEnvironment(ctx context.Context, id string) error

DeleteEnvironment removes an environment row. desired_services. environment_id is ON DELETE SET NULL (migrations/0054), so every service tagged with this environment is left running, untagged again.

func (*DB) DeleteEnvironmentSecretEnvVar added in v0.2.0

func (db *DB) DeleteEnvironmentSecretEnvVar(ctx context.Context, environmentID, key string) error

DeleteEnvironmentSecretEnvVar removes key's secret-marked row for environmentID, mirroring DeleteProjectSecretEnvVar.

func (*DB) DeleteExportDestination added in v0.2.0

func (db *DB) DeleteExportDestination(ctx context.Context, id string) error

DeleteExportDestination removes a destination and, by cascade, its status.

func (*DB) DeleteExposureRestriction added in v0.2.0

func (db *DB) DeleteExposureRestriction(ctx context.Context, port int, protocol string) error

DeleteExposureRestriction removes a restriction; a missing row is not an error.

func (*DB) DeleteExternalDatabase added in v0.2.0

func (db *DB) DeleteExternalDatabase(ctx context.Context, name string) error

DeleteExternalDatabase removes only the local record. The remote database is never contacted.

func (*DB) DeleteFeatureFlag

func (db *DB) DeleteFeatureFlag(ctx context.Context, id string) error

DeleteFeatureFlag removes a feature flag row. Returns ErrFeatureFlagNotFound if id doesn't exist.

func (*DB) DeleteFirewallRule added in v0.2.0

func (db *DB) DeleteFirewallRule(ctx context.Context, id string) error

DeleteFirewallRule removes a firewall rule row. It does not itself touch the host's ufw state: internal/reconcile/firewall's next pass removes the matching rule from ufw once it sees it's no longer desired, the same "store is desired state, the reconciler converges observed state to it" split every other reconciled resource follows. Returns ErrFirewallRuleNotFound if id doesn't exist.

func (*DB) DeleteGitHubAppConnection

func (db *DB) DeleteGitHubAppConnection(ctx context.Context) error

DeleteGitHubAppConnection removes the single github_app_connections row, the "disconnect" action. Returns ErrGitHubAppConnectionNotFound if nothing was connected.

This does not reach out to GitHub to delete or uninstall the App there, and it does not delete the client_secret/webhook_secret/ private_key values internal/secrets still holds under GitHubAppSecretsKey(): the same known, documented gap DeleteBackupTarget's own doc comment already accepts for backup target credentials, since internal/secrets.Manager has no delete operation today. A re-registration (SaveGitHubAppConnection) simply overwrites those secret values with the new App's own.

func (*DB) DeleteGitHubAppInstallation added in v0.2.0

func (db *DB) DeleteGitHubAppInstallation(ctx context.Context, id int64) error

DeleteGitHubAppInstallation removes one connected account/org by its github_app_installations id (not GitHub's installation_id). Callers must check for in-use git sources first: this does no such check itself, matching DeleteGitHubAppConnection's own division of responsibility (the store layer does the write, internal/api owns the business rule).

func (*DB) DeleteGitLabAppConnection

func (db *DB) DeleteGitLabAppConnection(ctx context.Context) error

DeleteGitLabAppConnection removes the single gitlab_app_connections row. Returns ErrGitLabAppConnectionNotFound if nothing was connected. Like DeleteGitHubAppConnection, this does not erase the secrets values (client_secret/access_token/refresh_token) still held under GitLabAppSecretsKey(); callers are expected to also call GitLabAppSecrets.DeleteAll.

func (*DB) DeleteGitSource

func (db *DB) DeleteGitSource(ctx context.Context, serviceName string) error

DeleteGitSource disconnects serviceName's git source, returning ErrGitSourceNotFound if none exists. Known gap, matching DeleteBackupTarget's own honestly-documented one: internal/secrets.Manager has no delete/revoke operation today, so the deploy token and webhook secret this source's connect flow wrote (GitSourceSecretsKey) remain in the secrets store, unreferenced and unreachable through this API but not actually erased at rest.

func (*DB) DeleteGiteaAppConnection added in v0.2.0

func (db *DB) DeleteGiteaAppConnection(ctx context.Context) error

DeleteGiteaAppConnection removes the single gitea_app_connections row. Returns ErrGiteaAppConnectionNotFound if nothing was connected. Like DeleteGitLabAppConnection, this does not erase the secrets values (client_secret/access_token/refresh_token) still held under GiteaAppSecretsKey(); callers are expected to also call GiteaAppSecrets.DeleteAll.

func (*DB) DeleteLogArchivePolicy added in v0.2.0

func (db *DB) DeleteLogArchivePolicy(ctx context.Context, appName string) error

DeleteLogArchivePolicy removes the policy for an app scope.

func (*DB) DeleteManagedDNSRecord added in v0.2.0

func (db *DB) DeleteManagedDNSRecord(ctx context.Context, domain, recordType string) error

DeleteManagedDNSRecord forgets the tracked record for (domain, type).

func (*DB) DeleteMigrationSession added in v0.2.0

func (db *DB) DeleteMigrationSession(ctx context.Context, id string) error

DeleteMigrationSession forgets a session. Databases it created are kept.

func (*DB) DeleteModel added in v0.2.0

func (db *DB) DeleteModel(ctx context.Context, name string) error

DeleteModel removes the row with its keys and usage. Idempotent.

func (*DB) DeleteNetworkShare added in v0.2.0

func (db *DB) DeleteNetworkShare(ctx context.Context, id string) error

DeleteNetworkShare removes a network share row. It does not touch internal/secrets: the caller deletes the password secret separately, after this succeeds, the same ordering DeleteRegistryCredential uses. Returns ErrNetworkShareNotFound if id doesn't exist.

func (*DB) DeleteNode

func (db *DB) DeleteNode(ctx context.Context, id string) error

DeleteNode removes a node by ID. Idempotent, matching DeleteDesiredService's convention: deleting an already-gone node is not an error.

Still no placement guard at this layer: internal/api's handleDeleteNode is what refuses to call this at all while ListDesiredServicesByNode/ListDesiredDatabasesByNode report any placements remaining, the same "guard at the API boundary, keep the store primitive unconditional" shape this package already uses elsewhere (e.g. SaveDesiredService's node_id exception is enforced by which method gets called, not by a check inside one shared method).

func (*DB) DeleteOrganization

func (db *DB) DeleteOrganization(ctx context.Context, id string) error

DeleteOrganization removes an organization row. projects.org_id is ON DELETE SET NULL (migrations/0054), so every project in this organization is left running, simply org-less again.

func (*DB) DeleteOrganizationSecretEnvVar added in v0.2.0

func (db *DB) DeleteOrganizationSecretEnvVar(ctx context.Context, orgID, key string) error

DeleteOrganizationSecretEnvVar removes key's secret-marked row for orgID, mirroring DeleteProjectSecretEnvVar one tier up.

func (*DB) DeletePendingTeardown added in v0.2.0

func (db *DB) DeletePendingTeardown(ctx context.Context, name string) error

DeletePendingTeardown removes the tombstone for name. Idempotent.

func (*DB) DeletePipeline added in v0.2.0

func (db *DB) DeletePipeline(ctx context.Context, id string) error

DeletePipeline removes a pipeline and, by cascade, its runs.

func (*DB) DeletePolicy

func (db *DB) DeletePolicy(ctx context.Context, id string) error

DeletePolicy removes a policy and (via ON DELETE CASCADE) every attachment referencing it. Idempotent: deleting a missing ID is not an error, matching DeleteDesiredService's own convention.

func (*DB) DeletePreviewDatabaseIsolation added in v0.2.0

func (db *DB) DeletePreviewDatabaseIsolation(ctx context.Context, id string) error

DeletePreviewDatabaseIsolation removes a tracking row once its role has actually been dropped; returns ErrPreviewDatabaseIsolationNotFound if id doesn't exist.

func (*DB) DeletePreviewEnvironment

func (db *DB) DeletePreviewEnvironment(ctx context.Context, id string) error

DeletePreviewEnvironment removes a preview environment row once its app/services and domain have actually been torn down; returns ErrPreviewEnvironmentNotFound if id doesn't exist. A partially-failed teardown instead calls UpdatePreviewEnvironment with a Failed status and a StatusReason, keeping the row so the manual teardown action has something to retry.

func (*DB) DeletePreviewEphemeralDatabase added in v0.2.0

func (db *DB) DeletePreviewEphemeralDatabase(ctx context.Context, id string) error

DeletePreviewEphemeralDatabase removes a tracking row once its database has actually been torn down; returns ErrPreviewEphemeralDatabaseNotFound if id doesn't exist.

func (*DB) DeleteProject

func (db *DB) DeleteProject(ctx context.Context, id string) error

DeleteProject removes a project row. Unlike DeleteBackupTarget (which relies on foreign key enforcement to *reject* a delete while backup_history still references the target), desired_services. project_id and desired_databases.project_id are declared "REFERENCES projects(id) ON DELETE SET NULL" (migrations/0022_projects.sql), so this delete always succeeds and every app/database that belonged to this project is left in place, simply project-less again (project_id reverts to NULL), the same real, valid, permanent state an app/database that was never assigned to a project is already in. There is deliberately no cascade here: a project is an organizational label, not a lifecycle owner, so deleting the label must never delete the real resources it labeled. Returns ErrProjectNotFound if id doesn't exist.

func (*DB) DeleteProjectSecretEnvVar added in v0.2.0

func (db *DB) DeleteProjectSecretEnvVar(ctx context.Context, projectID, key string) error

DeleteProjectSecretEnvVar removes key's secret-marked row for projectID. Idempotent: a key with no such row is not an error. The underlying ciphertext in service_secret_values (if any) is left in place, unreachable once this row is gone: the same orphaned-ciphertext tolerance DeleteServiceSecrets' own doc comment already accepts.

func (*DB) DeleteProxyRouteStatus added in v0.2.0

func (db *DB) DeleteProxyRouteStatus(ctx context.Context, domain string) error

DeleteProxyRouteStatus forgets domain's managed route.

func (*DB) DeletePushSubscription added in v0.2.0

func (db *DB) DeletePushSubscription(ctx context.Context, id, userID string) error

DeletePushSubscription removes subscription id, scoped to userID so an account can only ever revoke its own registrations.

func (*DB) DeletePushSubscriptionByID added in v0.2.0

func (db *DB) DeletePushSubscriptionByID(ctx context.Context, id string) error

DeletePushSubscriptionByID removes subscription id regardless of owner: internal/webpush's own send loop prunes a subscription a push service reports permanently gone (404/410), which has no session user to scope the delete to.

func (*DB) DeleteRegistryCredential

func (db *DB) DeleteRegistryCredential(ctx context.Context, id string) error

DeleteRegistryCredential removes a registry credential row. It does not touch internal/secrets: the caller deletes the password secret separately, after this succeeds, the same ordering BackupTarget uses. Returns ErrRegistryCredentialNotFound if id doesn't exist.

func (*DB) DeleteRole added in v0.2.0

func (db *DB) DeleteRole(ctx context.Context, id string) error

DeleteRole removes a custom role that has no users.

func (*DB) DeleteRollbackPin added in v0.2.0

func (db *DB) DeleteRollbackPin(ctx context.Context, serviceName, attemptID string) error

DeleteRollbackPin removes the pin for attemptID.

func (*DB) DeleteScheduledTask

func (db *DB) DeleteScheduledTask(ctx context.Context, id string) error

DeleteScheduledTask removes a scheduled task row. Returns ErrScheduledTaskNotFound if id doesn't exist.

func (*DB) DeleteSecretValue added in v0.2.0

func (db *DB) DeleteSecretValue(ctx context.Context, serviceName, envKey string) (bool, error)

DeleteSecretValue removes one stored secret value, reporting whether a row existed. The service's DEK and other values are untouched.

func (*DB) DeleteServiceBranchEnvOverride added in v0.2.0

func (db *DB) DeleteServiceBranchEnvOverride(ctx context.Context, serviceName, id string) error

DeleteServiceBranchEnvOverride removes one branch-scoped override by id, scoped to serviceName so a caller authorized for one app's own resource (IAM's appResourceFromPath) can never delete another app's override by guessing or reusing its id. Only the row itself is removed: any ciphertext this override's key held under BranchEnvOverrideSecretsKey is left in place, unreachable once the row is gone, the same orphaned-ciphertext tolerance handleDeleteSharedEnvSecret's own doc comment already accepts. Returns ErrBranchEnvOverrideNotFound if id doesn't exist under serviceName.

func (*DB) DeleteServiceLoadBalancer added in v0.2.0

func (db *DB) DeleteServiceLoadBalancer(ctx context.Context, service string) error

DeleteServiceLoadBalancer removes a service's load balancer config.

func (*DB) DeleteServiceSecrets

func (db *DB) DeleteServiceSecrets(ctx context.Context, serviceName string) error

DeleteServiceSecrets removes every value and the wrapped DEK for serviceName, in a transaction. Deleting the DEK itself (not just the value rows) matters: any ciphertext that somehow survives elsewhere (a backup, a replication lag) becomes permanently unrecoverable once its DEK is gone, rather than merely inaccessible through this API. Idempotent: a serviceName with no rows in either table is not an error, matching DeleteDesiredService's own "delete is idempotent" convention.

func (*DB) DeleteStatusComponent added in v0.2.0

func (db *DB) DeleteStatusComponent(ctx context.Context, id string) error

DeleteStatusComponent removes a component and its counters.

func (*DB) DeleteStatusIncident added in v0.2.0

func (db *DB) DeleteStatusIncident(ctx context.Context, id string) error

DeleteStatusIncident removes an incident and its updates.

func (*DB) DeleteTag added in v0.2.0

func (db *DB) DeleteTag(ctx context.Context, id string) error

DeleteTag removes a tag row; app_tags rows referencing it cascade-delete (migrations/0106_tags.sql's own ON DELETE CASCADE), so an app that was tagged with it just loses that one attachment, nothing else. Returns ErrTagNotFound if id doesn't exist.

func (*DB) DeleteTokenHygieneNotice added in v0.2.0

func (db *DB) DeleteTokenHygieneNotice(ctx context.Context, tokenID string) error

DeleteTokenHygieneNotice forgets a notice, for a token used again since.

func (*DB) DeleteUser

func (db *DB) DeleteUser(ctx context.Context, id string) error

DeleteUser removes a user row; the FK cascade (migrations/0035) takes any linked OAuth identities with it. Guards like "not the last user" live in internal/api/users.go, not here.

func (*DB) DeleteWebhookDeliveriesOlderThan added in v0.2.0

func (db *DB) DeleteWebhookDeliveriesOlderThan(ctx context.Context, cutoff time.Time) (int64, error)

DeleteWebhookDeliveriesOlderThan removes every webhook_deliveries row received strictly before cutoff, returning the number of rows removed. Mirrors DeleteAuditEntriesOlderThan (audit.go): without this, a table that only ever grows (every inbound request, verified or not) would be the one history table in this codebase with no retention mechanism at all.

func (*DB) DetachAppTag added in v0.2.0

func (db *DB) DetachAppTag(ctx context.Context, tagID, appName string) error

DetachAppTag removes tagID from appName. Unlike AttachAppTag this is not silently idempotent: detaching a tag that was never attached returns ErrTagNotFound, so a caller's DELETE gets a real 404 instead of a false-positive success, the same distinction ClearAppVaultEnv's own doc comment draws for its own detach endpoint.

func (*DB) DetachPolicy

func (db *DB) DetachPolicy(ctx context.Context, policyID, principalType, principalID string) error

DetachPolicy removes the link between policyID and one principal. Idempotent, matching DeletePolicy's own convention.

func (*DB) DeviceLoginExpiryClaimed added in v0.2.0

func (db *DB) DeviceLoginExpiryClaimed(ctx context.Context, requestID string) (bool, error)

DeviceLoginExpiryClaimed reports whether a request's expiry was recorded.

func (*DB) DismissAttentionItem added in v0.2.0

func (db *DB) DismissAttentionItem(ctx context.Context, userID, itemKey string, at time.Time, entry *AuditEntry) (bool, error)

DismissAttentionItem stores a per-user dismissal and, when entry is non-nil, its audit entry in one transaction. It reports false when the item was already dismissed, writing nothing the second time.

func (*DB) DueDatabaseAccessUsers added in v0.2.0

func (db *DB) DueDatabaseAccessUsers(ctx context.Context, now time.Time) ([]DatabaseAccessUser, error)

DueDatabaseAccessUsers lists temporary credentials whose expiry has passed and that are not yet revoked.

func (*DB) EditServiceDomains added in v0.2.0

func (db *DB) EditServiceDomains(ctx context.Context, name string, edit func(current []string) ([]string, error)) (domains []string, changed bool, err error)

EditServiceDomains rewrites only name's domain list, reading and writing it in one transaction so a concurrent edit to any other setting is never overwritten. edit returns the new list; its error aborts the change. Returns ErrServiceNotFound, or *ErrDomainTaken via errors.As.

func (*DB) EditServiceEnvironmentDomains added in v0.2.0

func (db *DB) EditServiceEnvironmentDomains(ctx context.Context, name, envID string, edit func(current []string) ([]string, error)) (domains []string, changed bool, err error)

EditServiceEnvironmentDomains rewrites only name's domain set for envID in one transaction, claiming the new hostnames (ErrDomainTaken via errors.As). Returns ErrServiceNotFound or ErrEnvironmentNotFound.

func (*DB) EnsureDatabaseMeshPort added in v0.2.0

func (db *DB) EnsureDatabaseMeshPort(ctx context.Context, name string, minPort, maxPort int) (int, error)

EnsureDatabaseMeshPort returns the database's mesh port, allocating the lowest free one in [minPort, maxPort] on first use. Idempotent.

func (*DB) EnvironmentMemberCounts added in v0.2.0

func (db *DB) EnvironmentMemberCounts(ctx context.Context, envID string) (apps, databases int, err error)

EnvironmentMemberCounts returns how many apps and databases are tagged with envID.

func (*DB) EnvironmentOfApp added in v0.2.0

func (db *DB) EnvironmentOfApp(ctx context.Context, appName string) (*EnvironmentRef, error)

EnvironmentOfApp returns the environment tagged on a service, or nil when the service is untagged or does not exist.

func (*DB) EnvironmentOfDatabase added in v0.2.0

func (db *DB) EnvironmentOfDatabase(ctx context.Context, databaseName string) (*EnvironmentRef, error)

EnvironmentOfDatabase returns the environment tagged on a database, or nil.

func (*DB) EnvironmentsOfApps added in v0.2.0

func (db *DB) EnvironmentsOfApps(ctx context.Context) (map[string]*EnvironmentRef, error)

EnvironmentsOfApps maps every tagged service name to its environment in one query.

func (*DB) EnvironmentsOfDatabases added in v0.2.0

func (db *DB) EnvironmentsOfDatabases(ctx context.Context) (map[string]*EnvironmentRef, error)

EnvironmentsOfDatabases maps every tagged database name to its environment in one query.

func (*DB) ExistsCertStorageValue

func (db *DB) ExistsCertStorageValue(ctx context.Context, key string) (bool, error)

ExistsCertStorageValue reports whether key is stored either as an exact value or as a "directory" prefix of other stored keys.

func (*DB) ExpireLoginCode added in v0.2.0

func (db *DB) ExpireLoginCode(ctx context.Context, id string, now time.Time) (bool, error)

ExpireLoginCode retires a pending challenge early, and reports whether this call did it.

func (*DB) ExtendTrustedDevice added in v0.2.0

func (db *DB) ExtendTrustedDevice(ctx context.Context, id string, expiresAt, now time.Time) error

ExtendTrustedDevice records a sign-in and pushes a live device's expiry.

func (*DB) FailDeployAttemptWithReason added in v0.2.0

func (db *DB) FailDeployAttemptWithReason(ctx context.Context, id, reason, message string) (bool, error)

FailDeployAttemptWithReason flips a succeeded attempt to failed after the fact, recording why. Reports whether it changed anything.

func (*DB) FailOrphanedDeployAttempts

func (db *DB) FailOrphanedDeployAttempts(ctx context.Context, finishedAt time.Time) (int, error)

FailOrphanedDeployAttempts marks every still-"running" deploy attempt as failed: called once at control-plane startup, before anything can create a new one, so a "running" row at that moment can only mean the process that owned it is gone (crash, OOM, restart) and it will never get its own FinishDeployAttempt call. Returns the number of rows fixed.

func (*DB) FailStaleLogArchiveRuns added in v0.2.0

func (db *DB) FailStaleLogArchiveRuns(ctx context.Context, at string) error

FailStaleLogArchiveRuns marks runs left 'running' by a previous process as failed.

func (*DB) FinishAppVolumeMove added in v0.2.0

func (db *DB) FinishAppVolumeMove(ctx context.Context, id, status, errMsg, finishedAt string) error

FinishAppVolumeMove updates a running move row to its final status, mirroring FinishVolumeCloneRestore exactly.

func (*DB) FinishBackupDrill added in v0.2.0

func (db *DB) FinishBackupDrill(ctx context.Context, d BackupDrill) error

FinishBackupDrill records a drill's final outcome.

func (*DB) FinishBackupHistory

func (db *DB) FinishBackupHistory(ctx context.Context, id, status string, sizeBytes int64, checksum, errMsg, finishedAt string) error

FinishBackupHistory updates a running backup history row to its final status. sizeBytes, checksum, and errMsg are all ignored (left as-is / not applicable) when status is BackupStatusRunning, which callers should never actually pass here since StartBackupHistory already wrote that state; FinishBackupHistory exists specifically for the succeeded/failed transition. checksum is the dump's SHA-256, hex-encoded, computed by Runner while streaming it to the upload target; empty on a failed attempt, since there is no complete dump to have hashed.

func (*DB) FinishBackupVerification

func (db *DB) FinishBackupVerification(ctx context.Context, id, status string, checksumMatch, sizeMatch, formatValid bool, downloadedBytes int64, errMsg, finishedAt string) error

FinishBackupVerification updates a running verification row to its final status, recording each individual check's own outcome (checksumMatch, sizeMatch, formatValid) alongside the overall status, so a failure can be explained (which check failed), not just reported.

func (*DB) FinishBaseBackupHistory added in v0.2.0

func (db *DB) FinishBaseBackupHistory(ctx context.Context, id, status string, sizeBytes int64, lsn, errMsg, finishedAt string) error

FinishBaseBackupHistory updates a running base backup history row to its final status, recording the size and start LSN a succeeded attempt produced (both zero-value on a failed one, matching FinishBackupHistory's own convention for its checksum parameter).

func (*DB) FinishCloneRestore

func (db *DB) FinishCloneRestore(ctx context.Context, id, status, errMsg, finishedAt string) error

FinishCloneRestore updates a running clone-restore row to its final status, mirroring FinishRestoreHistory exactly.

func (*DB) FinishDatabaseDataImport added in v0.2.0

func (db *DB) FinishDatabaseDataImport(ctx context.Context, name, status, reason string, checked, mismatched int, detail string, now time.Time) error

FinishDatabaseDataImport records the outcome of a claimed copy.

func (*DB) FinishDeployAttempt

func (db *DB) FinishDeployAttempt(ctx context.Context, id, status string, finishedAt time.Time, errMsg string) error

FinishDeployAttempt marks a deploy attempt's terminal outcome: called exactly once per attempt, when the triggering handler's call to internal/deploy.Pipeline.Deploy (or, for the plain image-tag path, SaveDesiredService) returns. errMsg should be empty for a succeeded attempt; status is not validated against a fixed enum here (the three call sites already only ever pass one of the two terminal DeployAttemptStatus* constants), matching UpsertConditions' own "caller controls the vocabulary" convention for status strings elsewhere in this package.

func (*DB) FinishLogArchiveRun added in v0.2.0

func (db *DB) FinishLogArchiveRun(ctx context.Context, r LogArchiveRun) error

FinishLogArchiveRun closes a run row with its totals.

func (*DB) FinishMajorUpgrade added in v0.2.0

func (db *DB) FinishMajorUpgrade(ctx context.Context, id, status, errMsg, finishedAt string) error

FinishMajorUpgrade stores an upgrade's final status.

func (*DB) FinishPITRRestoreHistory added in v0.2.0

func (db *DB) FinishPITRRestoreHistory(ctx context.Context, id, status, errMsg, finishedAt string) error

FinishPITRRestoreHistory updates a running PITR restore history row to its final status.

func (*DB) FinishRestoreHistory

func (db *DB) FinishRestoreHistory(ctx context.Context, id, status, errMsg, finishedAt string) error

FinishRestoreHistory updates a running restore history row to its final status, the restore counterpart of FinishBackupHistory (no sizeBytes parameter: nothing is uploaded on a restore, so there is no equivalent byte count to record).

func (*DB) FinishRunningDeployAttempt added in v0.2.0

func (db *DB) FinishRunningDeployAttempt(ctx context.Context, id, status string, finishedAt time.Time, errMsg string) (bool, error)

FinishRunningDeployAttempt finishes an attempt only while it is still running, so a queue replay never overwrites an outcome the deploy itself already recorded. Reports whether it moved.

func (*DB) FinishScheduledTaskRun added in v0.2.0

func (db *DB) FinishScheduledTaskRun(ctx context.Context, run ScheduledTaskRun) error

FinishScheduledTaskRun writes a run's terminal state and clears the task's running_since when no other run of it is still in flight. A success resets consecutive_missed.

func (*DB) FinishVolumeCloneRestore

func (db *DB) FinishVolumeCloneRestore(ctx context.Context, id, status, errMsg, finishedAt string) error

FinishVolumeCloneRestore updates a running clone-restore row to its final status, mirroring FinishCloneRestore exactly.

func (*DB) FlagUserForReset added in v0.2.0

func (db *DB) FlagUserForReset(ctx context.Context, userID, reason string, now time.Time) error

FlagUserForReset marks userID as needing a password reset.

func (*DB) ForgetBrowser added in v0.2.0

func (db *DB) ForgetBrowser(ctx context.Context, userID, fingerprint string) error

ForgetBrowser drops one known browser, after "this wasn't me".

func (*DB) GetAIAssistantSettings added in v0.2.0

func (db *DB) GetAIAssistantSettings(ctx context.Context) (AIAssistantSettings, error)

GetAIAssistantSettings returns the single ai_assistant_settings row. Always succeeds: the migration itself inserts the row (id = 1).

func (*DB) GetAIChatConfirmation added in v0.2.0

func (db *DB) GetAIChatConfirmation(ctx context.Context, id string) (AIChatConfirmation, error)

GetAIChatConfirmation returns one confirmation by id, or ErrAIChatConfirmationNotFound.

func (*DB) GetAIChatMessage added in v0.2.0

func (db *DB) GetAIChatMessage(ctx context.Context, id string) (AIChatMessage, error)

GetAIChatMessage returns one message by id, or ErrAIChatMessageNotFound.

func (*DB) GetAIChatSession added in v0.2.0

func (db *DB) GetAIChatSession(ctx context.Context, id string) (AIChatSession, error)

GetAIChatSession returns one session by id, or ErrAIChatSessionNotFound.

func (*DB) GetAIControlSettings added in v0.2.0

func (db *DB) GetAIControlSettings(ctx context.Context) (AIControlSettings, error)

GetAIControlSettings loads the singleton row.

func (*DB) GetAPITokenByHash

func (db *DB) GetAPITokenByHash(ctx context.Context, hash string) (*APIToken, error)

GetAPITokenByHash returns the token row matching hash, regardless of whether it's revoked or expired: deciding "is this token currently usable" is the caller's job (internal/api's auth middleware), this is pure lookup, the same separation reconcile_status.go keeps between storage and decision-making.

func (*DB) GetAPITokenByID added in v0.2.0

func (db *DB) GetAPITokenByID(ctx context.Context, id string) (*APIToken, error)

GetAPITokenByID returns the token row with the given id.

func (*DB) GetAPITokenScope added in v0.2.0

func (db *DB) GetAPITokenScope(ctx context.Context, tokenID string) (*APITokenScope, error)

GetAPITokenScope returns a token's scope, or nil when it is unscoped.

func (*DB) GetApp

func (db *DB) GetApp(ctx context.Context, id string) (App, error)

GetApp returns the app with this ID, or ErrAppNotFound.

func (*DB) GetAppByName

func (db *DB) GetAppByName(ctx context.Context, name string) (App, error)

GetAppByName returns the app with this name, or ErrAppNotFound. A separate method from GetApp rather than one "id or name" lookup: id and name are different columns with different uniqueness guarantees (id is the primary key, name has its own UNIQUE constraint), so which one a caller has is always known at the call site, the same way GetProject (by id) and GetDesiredService (by name) are already two distinct methods rather than one overloaded one.

func (*DB) GetAppImportSession added in v0.2.0

func (db *DB) GetAppImportSession(ctx context.Context, id string) (AppImportSession, error)

GetAppImportSession returns one session.

func (*DB) GetAppIntegration added in v0.2.0

func (db *DB) GetAppIntegration(ctx context.Context, id string) (AppIntegration, error)

GetAppIntegration returns the app integration with this ID, or ErrAppIntegrationNotFound.

func (*DB) GetAppIntegrationByKey added in v0.2.0

func (db *DB) GetAppIntegrationByKey(ctx context.Context, serviceName, integrationKey string) (AppIntegration, error)

GetAppIntegrationByKey returns serviceName's attachment of integrationKey, or ErrAppIntegrationNotFound if it isn't attached.

func (*DB) GetAppSchedule added in v0.2.0

func (db *DB) GetAppSchedule(ctx context.Context, serviceName string) (*AppSchedule, error)

GetAppSchedule returns serviceName's configured schedule, or ErrAppScheduleNotFound if none is set.

func (*DB) GetAppSleep added in v0.2.0

func (db *DB) GetAppSleep(ctx context.Context, serviceName string) (AppSleep, error)

GetAppSleep returns serviceName's row, or a disabled zero value when none exists.

func (*DB) GetAppStream added in v0.2.0

func (db *DB) GetAppStream(ctx context.Context, id string) (AppStream, error)

GetAppStream returns the app stream with this ID, or ErrAppStreamNotFound.

func (*DB) GetAppVolumeMove added in v0.2.0

func (db *DB) GetAppVolumeMove(ctx context.Context, id string) (AppVolumeMove, error)

GetAppVolumeMove returns one move attempt by id, its full step history included.

func (*DB) GetAppliedConfig added in v0.2.0

func (db *DB) GetAppliedConfig(ctx context.Context, name string) (*AppliedConfig, error)

GetAppliedConfig returns name's snapshot, or nil when none was recorded (a container created before snapshots existed). A row that only carries a hold has an empty Release.

func (*DB) GetBackupDrill added in v0.2.0

func (db *DB) GetBackupDrill(ctx context.Context, id string) (BackupDrill, error)

GetBackupDrill returns one drill or a wrapped sql.ErrNoRows.

func (*DB) GetBackupHistory

func (db *DB) GetBackupHistory(ctx context.Context, id string) (BackupHistory, error)

GetBackupHistory returns the backup attempt with this ID, or ErrBackupHistoryNotFound. Added for the restore path (internal/backup.RestoreRunner): a restore is always initiated by naming a specific past backup attempt, so unlike the forward backup path (which only ever lists history, never looks up one row by ID), restoring needs to resolve exactly one row, including its Status, TargetID, and ObjectKey, before anything else can happen.

func (*DB) GetBackupTarget

func (db *DB) GetBackupTarget(ctx context.Context, id string) (BackupTarget, error)

GetBackupTarget returns the backup target with this ID, or ErrBackupTargetNotFound.

func (*DB) GetBaseBackupHistory added in v0.2.0

func (db *DB) GetBaseBackupHistory(ctx context.Context, id string) (BaseBackupHistory, error)

GetBaseBackupHistory returns the base backup attempt with this ID, or ErrBaseBackupHistoryNotFound.

func (*DB) GetBitbucketAppConnection

func (db *DB) GetBitbucketAppConnection(ctx context.Context) (BitbucketAppConnection, error)

GetBitbucketAppConnection returns the single bitbucket_app_connections row, or ErrBitbucketAppConnectionNotFound if none exists.

func (*DB) GetBuildCacheSetting added in v0.2.0

func (db *DB) GetBuildCacheSetting(ctx context.Context, appName string) (BuildCacheSetting, error)

GetBuildCacheSetting returns the setting for an app scope (empty means global).

func (*DB) GetCPDRSettings added in v0.2.0

func (db *DB) GetCPDRSettings(ctx context.Context) (CPDRSettings, error)

GetCPDRSettings returns the single settings row, which the migration seeds.

func (*DB) GetCanaryRelease added in v0.2.0

func (db *DB) GetCanaryRelease(ctx context.Context, serviceName string) (CanaryRelease, bool, error)

GetCanaryRelease returns serviceName's canary and whether one exists.

func (*DB) GetCertStorageValue

func (db *DB) GetCertStorageValue(ctx context.Context, key string) (*CertStorageValue, error)

GetCertStorageValue returns the value stored at key, or ErrCertStorageKeyNotFound.

func (*DB) GetCloudflareDNSSettings

func (db *DB) GetCloudflareDNSSettings(ctx context.Context) (CloudflareDNSSettings, error)

GetCloudflareDNSSettings returns the single cloudflare_dns_settings row. Always succeeds: the migration itself inserts the row (id = 1).

func (*DB) GetCloudflareTunnelSettings

func (db *DB) GetCloudflareTunnelSettings(ctx context.Context) (CloudflareTunnelSettings, error)

GetCloudflareTunnelSettings returns the single cloudflare_tunnel_settings row. Always succeeds: the migration itself inserts the row (id = 1).

func (*DB) GetCodeLoginSettings added in v0.2.0

func (db *DB) GetCodeLoginSettings(ctx context.Context) (s CodeLoginSettings, ok bool, err error)

GetCodeLoginSettings returns the saved settings, or ok false when an admin never saved any and the environment defaults apply.

func (*DB) GetComposeRevision added in v0.2.0

func (db *DB) GetComposeRevision(ctx context.Context, appID string, revision int) (ComposeRevision, error)

GetComposeRevision returns one revision; revision 0 means the latest.

func (*DB) GetConditions

func (db *DB) GetConditions(ctx context.Context, controllerName string) ([]reconcile.Condition, error)

GetConditions returns every stored condition for a controller, ordered by condition type, or nil if none have been recorded yet.

func (*DB) GetConditionsForControllers

func (db *DB) GetConditionsForControllers(ctx context.Context, controllerNames []string) (map[string][]reconcile.Condition, error)

GetConditionsForControllers is GetConditions' batched counterpart: one query for every controller in controllerNames, keyed by controller name in the returned map, instead of a GetConditions call per controller. Built for GET /api/v1/apps (internal/api/apps.go's handleListApps), which needs a status summary per app without reintroducing the N+1 AppRow.tsx's own doc comment warns against. A controller with no stored conditions is simply absent from the map, the same "nil means none recorded yet" convention GetConditions already establishes for a single controller.

func (*DB) GetCustomTemplate added in v0.2.0

func (db *DB) GetCustomTemplate(ctx context.Context, id string) (CustomTemplate, error)

GetCustomTemplate returns the custom template with this ID, or ErrCustomTemplateNotFound.

func (*DB) GetCutoverRun added in v0.2.0

func (db *DB) GetCutoverRun(ctx context.Context, id string) (CutoverRun, error)

GetCutoverRun returns one run.

func (*DB) GetDBUpgradePolicy added in v0.2.0

func (db *DB) GetDBUpgradePolicy(ctx context.Context, name string) (p DBUpgradePolicy, found bool, err error)

GetDBUpgradePolicy returns the policy row for name; found is false when none exists.

func (*DB) GetDBUpgradeRun added in v0.2.0

func (db *DB) GetDBUpgradeRun(ctx context.Context, id string) (DBUpgradeRun, error)

GetDBUpgradeRun returns one run or ErrDBUpgradeRunNotFound.

func (*DB) GetDashboardURL added in v0.2.0

func (db *DB) GetDashboardURL(ctx context.Context) (string, error)

GetDashboardURL returns the configured public dashboard URL, or "" when unset.

func (*DB) GetDatabaseAccessSettings added in v0.2.0

func (db *DB) GetDatabaseAccessSettings(ctx context.Context, database string) (DatabaseAccessSettings, error)

GetDatabaseAccessSettings returns a database's settings; a database with none has the platform-wide scope and optional TLS.

func (*DB) GetDatabaseAccessUser added in v0.2.0

func (db *DB) GetDatabaseAccessUser(ctx context.Context, database, role string) (*DatabaseAccessUser, error)

GetDatabaseAccessUser returns the live record for a role, or nil.

func (*DB) GetDatabaseAccessUserByID added in v0.2.0

func (db *DB) GetDatabaseAccessUserByID(ctx context.Context, id string) (*DatabaseAccessUser, error)

GetDatabaseAccessUserByID returns a record by id regardless of state, or nil.

func (*DB) GetDatabaseDataImport added in v0.2.0

func (db *DB) GetDatabaseDataImport(ctx context.Context, name string) (DatabaseDataImport, bool, error)

GetDatabaseDataImport returns name's row and whether one exists.

func (*DB) GetDatabaseMeshPort added in v0.2.0

func (db *DB) GetDatabaseMeshPort(ctx context.Context, name string) (int, error)

GetDatabaseMeshPort returns a database's mesh port, 0 when none is allocated.

func (*DB) GetDeployApproval added in v0.2.0

func (db *DB) GetDeployApproval(ctx context.Context, id string) (DeployApproval, error)

GetDeployApproval returns the deploy approval with this ID, or ErrDeployApprovalNotFound.

func (*DB) GetDeployAttempt

func (db *DB) GetDeployAttempt(ctx context.Context, id string) (*DeployAttempt, error)

GetDeployAttempt returns one deploy attempt by ID, or ErrDeployAttemptNotFound if no such row exists. Used by the SSE log stream handler (internal/api/deploys.go) to decide whether an attempt is still in progress (serve a live tail) or already finished (serve a full persisted replay), see that handler's own doc comment.

func (*DB) GetDeployCursor added in v0.2.0

func (db *DB) GetDeployCursor(ctx context.Context, serviceName string) (DeployCursor, error)

GetDeployCursor returns serviceName's cursor, the zero value if it has none.

func (*DB) GetDeploySafetySettings added in v0.2.0

func (db *DB) GetDeploySafetySettings(ctx context.Context, serviceName string) (DeploySafetySettings, error)

GetDeploySafetySettings returns serviceName's overrides, or a value with every field nil when it has none.

func (*DB) GetDesiredDatabase

func (db *DB) GetDesiredDatabase(ctx context.Context, name string) (*DesiredDatabase, error)

GetDesiredDatabase returns the desired state for name, or ErrDatabaseNotFound if no such database has been saved.

func (*DB) GetDesiredService

func (db *DB) GetDesiredService(ctx context.Context, name string) (*DesiredService, error)

GetDesiredService returns the desired state for name, or ErrServiceNotFound if no such service has been saved.

func (*DB) GetDomainAutomationRaw added in v0.2.0

func (db *DB) GetDomainAutomationRaw(ctx context.Context) (string, error)

GetDomainAutomationRaw returns the stored policy JSON, "" when never set.

func (*DB) GetDomainAutomationRun added in v0.2.0

func (db *DB) GetDomainAutomationRun(ctx context.Context, id string) (DomainAutomationRun, error)

GetDomainAutomationRun returns one run.

func (*DB) GetDomainBasicAuth

func (db *DB) GetDomainBasicAuth(ctx context.Context, domain string) (DomainBasicAuth, bool, error)

GetDomainBasicAuth returns the basic-auth row for domain. found is false when the domain has none configured, the default, valid state for any domain, not an error.

func (*DB) GetDomainMaintenance

func (db *DB) GetDomainMaintenance(ctx context.Context, domain string) (bool, error)

GetDomainMaintenance reports whether domain currently has maintenance mode enabled. false is the default, valid state for any domain, not an error.

func (*DB) GetDomainRedirect added in v0.2.0

func (db *DB) GetDomainRedirect(ctx context.Context, domain string) (DomainRedirect, bool, error)

GetDomainRedirect returns domain's current redirect configuration. found is false when the domain has no row, the default, valid state for any domain, not an error.

func (*DB) GetDomainTLSCert

func (db *DB) GetDomainTLSCert(ctx context.Context, domain string) (DomainTLSCert, bool, error)

GetDomainTLSCert returns the BYO cert row for domain. found is false when the domain has none uploaded, the default, valid state for any domain, not an error.

func (*DB) GetDomainTrafficPolicy added in v0.2.0

func (db *DB) GetDomainTrafficPolicy(ctx context.Context, domain, kind string) (DomainTrafficPolicy, bool, error)

GetDomainTrafficPolicy returns domain's spec for kind; found is false when the domain uses the default behavior.

func (*DB) GetDomainWAF added in v0.2.0

func (db *DB) GetDomainWAF(ctx context.Context, domain string) (DomainWAF, bool, error)

GetDomainWAF returns domain's current WAF/rate-limit configuration. found is false when the domain has no row, the default, valid state for any domain, not an error; the returned DomainWAF is the zero value plus DomainWAFModeDetect in that case, mirroring what a fresh row would look like before an operator changes anything.

func (*DB) GetEmailSettings

func (db *DB) GetEmailSettings(ctx context.Context) (EmailSettings, error)

GetEmailSettings returns the single email_settings row. Always succeeds: the migration itself inserts the row (id = 1).

func (*DB) GetEnvironment

func (db *DB) GetEnvironment(ctx context.Context, id string) (Environment, error)

GetEnvironment returns the environment with this ID, or ErrEnvironmentNotFound.

func (*DB) GetEnvironmentsByIDs added in v0.2.0

func (db *DB) GetEnvironmentsByIDs(ctx context.Context, ids []string) (map[string]Environment, error)

GetEnvironmentsByIDs returns every environment in ids, keyed by ID, in one query (json_each, matching GetConditionsForControllers' pattern) instead of a GetEnvironment call per ID. An ID with no matching row is simply absent from the map. Built for GET /api/v1/apps (internal/api's environmentNames), which previously called GetEnvironment once per distinct environment on the page.

func (*DB) GetExportDestination added in v0.2.0

func (db *DB) GetExportDestination(ctx context.Context, id string) (ExportDestination, error)

GetExportDestination returns one destination.

func (*DB) GetExportStatus added in v0.2.0

func (db *DB) GetExportStatus(ctx context.Context, id string) (ExportStatus, error)

GetExportStatus returns a destination's state, or a zero value when none has been written yet.

func (*DB) GetExternalDatabase added in v0.2.0

func (db *DB) GetExternalDatabase(ctx context.Context, name string) (*ExternalDatabase, error)

GetExternalDatabase returns the record or ErrExternalDatabaseNotFound.

func (*DB) GetFeatureFlag

func (db *DB) GetFeatureFlag(ctx context.Context, id string) (FeatureFlag, error)

GetFeatureFlag returns the feature flag with this ID, or ErrFeatureFlagNotFound.

func (*DB) GetFeatureFlagByKey

func (db *DB) GetFeatureFlagByKey(ctx context.Context, key string) (FeatureFlag, error)

GetFeatureFlagByKey returns the feature flag with this Key, or ErrFeatureFlagNotFound. This is what handleEvaluateFeatureFlag looks up by, since the evaluate endpoint's URL carries no app name (see this table's own migration comment).

func (*DB) GetFirewallRule added in v0.2.0

func (db *DB) GetFirewallRule(ctx context.Context, id string) (FirewallRule, error)

GetFirewallRule returns the firewall rule with this ID, or ErrFirewallRuleNotFound.

func (*DB) GetGitHubAppConnection

func (db *DB) GetGitHubAppConnection(ctx context.Context) (GitHubAppConnection, error)

GetGitHubAppConnection returns the single github_app_connections row, or ErrGitHubAppConnectionNotFound if the App has never been registered.

func (*DB) GetGitLabAppConnection

func (db *DB) GetGitLabAppConnection(ctx context.Context) (GitLabAppConnection, error)

GetGitLabAppConnection returns the single gitlab_app_connections row, or ErrGitLabAppConnectionNotFound if none exists.

func (*DB) GetGitSource

func (db *DB) GetGitSource(ctx context.Context, serviceName string) (*GitSource, error)

GetGitSource returns the git source connected to serviceName, or ErrGitSourceNotFound if none is.

func (*DB) GetGiteaAppConnection added in v0.2.0

func (db *DB) GetGiteaAppConnection(ctx context.Context) (GiteaAppConnection, error)

GetGiteaAppConnection returns the single gitea_app_connections row, or ErrGiteaAppConnectionNotFound if none exists.

func (*DB) GetHookRuns

func (db *DB) GetHookRuns(ctx context.Context, serviceName string) ([]HookRun, error)

GetHookRuns returns every stored hook outcome for serviceName (at most one per hook type), or nil if neither hook has ever run.

func (*DB) GetImageAutoUpdate added in v0.2.0

func (db *DB) GetImageAutoUpdate(ctx context.Context, serviceName string) (ImageAutoUpdate, error)

GetImageAutoUpdate returns serviceName's row, or a disabled zero value when none exists.

func (*DB) GetIngressSettings

func (db *DB) GetIngressSettings(ctx context.Context) (IngressSettings, error)

GetIngressSettings returns the single ingress_settings row. Always succeeds against a migrated database: the migration itself inserts the row (id = 1), so there is no "not found" case for callers to handle, unlike every other Get* accessor in this package.

func (*DB) GetInviteByHash

func (db *DB) GetInviteByHash(ctx context.Context, hash string) (*Invite, error)

GetInviteByHash returns the invite matching hash, regardless of expiry/accepted/revoked state: deciding whether it's currently usable is the caller's job, matching GetPasswordResetTokenByHash's own shape.

func (*DB) GetInviteByID

func (db *DB) GetInviteByID(ctx context.Context, id string) (*Invite, error)

GetInviteByID returns the invite with this ID, or ErrInviteNotFound.

func (*DB) GetLatestBackupVerification

func (db *DB) GetLatestBackupVerification(ctx context.Context, backupHistoryID string) (BackupVerification, error)

GetLatestBackupVerification returns the most recently started verification attempt for backupHistoryID, or ErrBackupVerificationNotFound if it has never been verified. Used by the backup history detail view (and the CLI's own "backups verifications" summary) to show a single current status without listing full history.

func (*DB) GetLatestBaseBackupBefore added in v0.2.0

func (db *DB) GetLatestBaseBackupBefore(ctx context.Context, databaseName string, cutoff time.Time) (h BaseBackupHistory, ok bool, err error)

GetLatestBaseBackupBefore returns databaseName's most recent succeeded base backup with started_at <= cutoff: the one a PITR restore targeting cutoff must replay WAL forward from. ok is false when no succeeded base backup exists at or before cutoff, meaning cutoff is not reachable (either PITR was enabled after cutoff, or every base backup taken since is itself newer than cutoff).

func (*DB) GetLiveLoginCodeByBrowser added in v0.2.0

func (db *DB) GetLiveLoginCodeByBrowser(ctx context.Context, browserHash string, now time.Time) (LoginCodeChallenge, error)

GetLiveLoginCodeByBrowser returns the newest pending, unexpired challenge bound to browserHash.

func (*DB) GetLogArchivePolicy added in v0.2.0

func (db *DB) GetLogArchivePolicy(ctx context.Context, appName string) (LogArchivePolicy, error)

GetLogArchivePolicy returns the policy for an app scope (empty means global).

func (*DB) GetLoginApproval added in v0.2.0

func (db *DB) GetLoginApproval(ctx context.Context, id string) (LoginApproval, error)

GetLoginApproval loads one approval by id.

func (*DB) GetLoginApprovalByBrowser added in v0.2.0

func (db *DB) GetLoginApprovalByBrowser(ctx context.Context, browserHash string) (LoginApproval, error)

GetLoginApprovalByBrowser returns the newest approval bound to browserHash.

func (*DB) GetMajorUpgrade added in v0.2.0

func (db *DB) GetMajorUpgrade(ctx context.Context, id string) (MajorUpgrade, error)

GetMajorUpgrade returns one upgrade attempt.

func (*DB) GetMasterKeyRotatedAt

func (db *DB) GetMasterKeyRotatedAt(ctx context.Context) (rotatedAt time.Time, ok bool, err error)

GetMasterKeyRotatedAt returns the last time RotateServiceDEKs committed successfully, or ok=false if it never has.

func (*DB) GetMigrationSession added in v0.2.0

func (db *DB) GetMigrationSession(ctx context.Context, id string) (MigrationSession, error)

GetMigrationSession returns one session.

func (*DB) GetModel added in v0.2.0

func (db *DB) GetModel(ctx context.Context, name string) (*Model, error)

GetModel returns the model named name, or ErrModelNotFound.

func (*DB) GetModelByDomain added in v0.2.0

func (db *DB) GetModelByDomain(ctx context.Context, domain string) (*Model, error)

GetModelByDomain returns the live (not deleting) model serving domain.

func (*DB) GetModelKey added in v0.2.0

func (db *DB) GetModelKey(ctx context.Context, model, id string) (*ModelKey, error)

GetModelKey returns one key of a model, or ErrModelKeyNotFound.

func (*DB) GetNetworkShare added in v0.2.0

func (db *DB) GetNetworkShare(ctx context.Context, id string) (NetworkShare, error)

GetNetworkShare returns the network share with this ID, or ErrNetworkShareNotFound.

func (*DB) GetNetworkShareByName added in v0.2.0

func (db *DB) GetNetworkShareByName(ctx context.Context, name string) (NetworkShare, error)

GetNetworkShareByName returns the network share with this Name, or ErrNetworkShareNotFound. A volume's network share reference resolves by name, not opaque ID, the same reasoning GetRegistryCredentialByName's own doc comment gives for app.yaml.

func (*DB) GetNode

func (db *DB) GetNode(ctx context.Context, id string) (*Node, error)

GetNode returns the node with this ID, or ErrNodeNotFound.

func (*DB) GetNodeDrain added in v0.2.0

func (db *DB) GetNodeDrain(ctx context.Context, id string) (NodeDrain, error)

GetNodeDrain returns one drain by ID.

func (*DB) GetNodeGPU added in v0.2.0

func (db *DB) GetNodeGPU(ctx context.Context, nodeID string) (NodeGPU, bool, error)

GetNodeGPU returns the node's snapshot; ok is false when none has been reported yet.

func (*DB) GetNodeJoinTokenByHash

func (db *DB) GetNodeJoinTokenByHash(ctx context.Context, hash string) (*NodeJoinToken, error)

GetNodeJoinTokenByHash returns the token row matching hash, used or not, expired or not: deciding whether a token is currently redeemable is the caller's job (internal/api's enrollment handler), matching GetAPITokenByHash's identical "pure lookup, not a decision" separation.

func (*DB) GetNodeLabels added in v0.2.0

func (db *DB) GetNodeLabels(ctx context.Context, nodeID string) (map[string]string, error)

GetNodeLabels returns one node's labels, empty (not nil) when it has none.

func (*DB) GetNodeMove added in v0.2.0

func (db *DB) GetNodeMove(ctx context.Context, id string) (NodeMove, error)

GetNodeMove returns one move by ID.

func (*DB) GetNodeProvision added in v0.2.0

func (db *DB) GetNodeProvision(ctx context.Context, id string) (NodeProvision, error)

GetNodeProvision returns the node provision with this ID, or ErrNodeProvisionNotFound.

func (*DB) GetOAuthIdentity

func (db *DB) GetOAuthIdentity(ctx context.Context, provider, providerUserID string) (*OAuthIdentity, error)

GetOAuthIdentity returns the identity linking (provider, providerUserID) to whichever user holds it, or ErrOAuthIdentityNotFound. This is the OAuth callback's primary lookup: "has this external account signed in here before."

func (*DB) GetOAuthProviderSettings

func (db *DB) GetOAuthProviderSettings(ctx context.Context, provider string) (OAuthProviderSettings, error)

GetOAuthProviderSettings returns the settings row for provider.

func (*DB) GetObservabilitySettings added in v0.2.0

func (db *DB) GetObservabilitySettings(ctx context.Context) (ObservabilitySettings, error)

GetObservabilitySettings returns the single observability_settings row. Always succeeds: the migration itself inserts the row (id = 1).

func (*DB) GetOldestSucceededBaseBackup added in v0.2.0

func (db *DB) GetOldestSucceededBaseBackup(ctx context.Context, databaseName string) (h BaseBackupHistory, ok bool, err error)

GetOldestSucceededBaseBackup returns databaseName's earliest succeeded base backup, the lower bound of its PITR recoverable window: nothing before this moment can be replayed forward to, since no base backup exists to start from. ok is false, not an error, when there is no succeeded base backup yet (PITR just enabled, first base backup still running or never triggered).

func (*DB) GetOnboardingCompleted

func (db *DB) GetOnboardingCompleted(ctx context.Context) (bool, error)

GetOnboardingCompleted returns whether the setup wizard has been completed or dismissed.

func (*DB) GetOnboardingState added in v0.2.0

func (db *DB) GetOnboardingState(ctx context.Context) (OnboardingState, error)

GetOnboardingState returns the setup wizard row seeded by migration 0067.

func (*DB) GetOrCreateInstanceID added in v0.2.0

func (db *DB) GetOrCreateInstanceID(ctx context.Context) (string, error)

GetOrCreateInstanceID returns this control-plane instance's own persistent, random identity, minting and persisting one on first call if none exists yet. Every subsequent call, across restarts, returns the exact same value: this is the identity internal/spec.InstanceLabelKey stamps onto every Docker resource this instance creates, so two separate instances sharing one Docker daemon can tell their own resources apart during cleanup (see InstanceLabelKey's own doc comment).

Race-safe against a concurrent first call (two processes racing to seed the singleton row, or a caller invoking this more than once during startup): INSERT OR IGNORE means at most one insert ever wins, and the final SELECT always reads back whichever one did, so every caller converges on the same ID regardless of who inserted it.

func (*DB) GetOrganization

func (db *DB) GetOrganization(ctx context.Context, id string) (Organization, error)

GetOrganization returns the organization with this ID, or ErrOrganizationNotFound.

func (*DB) GetPITRRestoreHistory added in v0.2.0

func (db *DB) GetPITRRestoreHistory(ctx context.Context, id string) (PITRRestoreHistory, error)

GetPITRRestoreHistory returns the PITR restore attempt with this ID, or ErrPITRRestoreHistoryNotFound.

func (*DB) GetPipeline added in v0.2.0

func (db *DB) GetPipeline(ctx context.Context, id string) (Pipeline, error)

GetPipeline returns the pipeline with this ID, or ErrPipelineNotFound.

func (*DB) GetPipelineByName added in v0.2.0

func (db *DB) GetPipelineByName(ctx context.Context, app, name string) (Pipeline, error)

GetPipelineByName returns an app's pipeline by name, or ErrPipelineNotFound.

func (*DB) GetPipelineRun added in v0.2.0

func (db *DB) GetPipelineRun(ctx context.Context, id string) (PipelineRun, error)

GetPipelineRun returns a run by ID, or ErrPipelineRunNotFound.

func (*DB) GetPipelineSync added in v0.2.0

func (db *DB) GetPipelineSync(ctx context.Context, app string) (PipelineSync, error)

GetPipelineSync returns the sync state for app, or a zero-valued state carrying only the app name when none has been recorded.

func (*DB) GetPlacementSelector added in v0.2.0

func (db *DB) GetPlacementSelector(ctx context.Context, kind, resource string) (map[string]string, error)

GetPlacementSelector returns the selector of one app or database, empty when unset.

func (*DB) GetPolicy

func (db *DB) GetPolicy(ctx context.Context, id string) (*Policy, error)

GetPolicy returns the policy with this ID, or ErrPolicyNotFound.

func (*DB) GetPreviewAppSettings added in v0.2.0

func (db *DB) GetPreviewAppSettings(ctx context.Context, appName string) (PreviewAppSettings, error)

GetPreviewAppSettings returns appName's saved policy, or the defaults when none has been saved.

func (*DB) GetPreviewDatabaseIsolationByPreviewAndKey added in v0.2.0

func (db *DB) GetPreviewDatabaseIsolationByPreviewAndKey(ctx context.Context, previewEnvironmentID, sourceKey string) (*PreviewDatabaseIsolation, error)

GetPreviewDatabaseIsolationByPreviewAndKey returns the isolation tracking row for (previewEnvironmentID, sourceKey), or ErrPreviewDatabaseIsolationNotFound: provisioning's own idempotency check.

func (*DB) GetPreviewEnvironmentByAppAndPR

func (db *DB) GetPreviewEnvironmentByAppAndPR(ctx context.Context, appName string, prNumber int) (*PreviewEnvironment, error)

GetPreviewEnvironmentByAppAndPR returns the preview environment for (appName, prNumber), or ErrPreviewEnvironmentNotFound: the lookup a synchronize or closed pull request webhook event uses to find the preview it already owns, matching the table's own unique index.

func (*DB) GetPreviewEphemeralDatabaseByPreviewAndKey added in v0.2.0

func (db *DB) GetPreviewEphemeralDatabaseByPreviewAndKey(ctx context.Context, previewEnvironmentID, sourceKey string) (*PreviewEphemeralDatabase, error)

GetPreviewEphemeralDatabaseByPreviewAndKey returns the ephemeral database tracking row for (previewEnvironmentID, sourceKey), or ErrPreviewEphemeralDatabaseNotFound: provisioning's own idempotency check, matching the table's own unique index.

func (*DB) GetProject

func (db *DB) GetProject(ctx context.Context, id string) (Project, error)

GetProject returns the project with this ID, or ErrProjectNotFound.

func (*DB) GetProjectOrganizationID added in v0.2.0

func (db *DB) GetProjectOrganizationID(ctx context.Context, projectID string) (string, error)

GetProjectOrganizationID returns projectID's organization ID, or "" if the project has none (or doesn't exist): the same lookup ListOrganizationEnvVarsForProject already needed internally, exposed here for internal/sharedenv.Resolver, which needs the ID itself (to resolve that organization's secret-marked shared env vars) rather than just its plain vars.

func (*DB) GetProxyIntegrationSettings added in v0.2.0

func (db *DB) GetProxyIntegrationSettings(ctx context.Context) (ProxyIntegrationSettings, error)

GetProxyIntegrationSettings returns the seeded singleton row.

func (*DB) GetRegistryCredential

func (db *DB) GetRegistryCredential(ctx context.Context, id string) (RegistryCredential, error)

GetRegistryCredential returns the registry credential with this ID, or ErrRegistryCredentialNotFound.

func (*DB) GetRegistryCredentialByName

func (db *DB) GetRegistryCredentialByName(ctx context.Context, name string) (RegistryCredential, error)

GetRegistryCredentialByName returns the registry credential with this Name, or ErrRegistryCredentialNotFound. app.yaml's build.type: image references a credential by Name (spec.Build.RegistryCredential's own doc comment: an opaque ID would be hostile to hand-author), so a deploy resolves it this way, not by ID.

func (*DB) GetRegistrySettings

func (db *DB) GetRegistrySettings(ctx context.Context) (RegistrySettings, error)

GetRegistrySettings returns the single registry_settings row. Always succeeds against a migrated database: the migration itself inserts the row (id = 1).

func (*DB) GetRole added in v0.2.0

func (db *DB) GetRole(ctx context.Context, id string) (Role, error)

GetRole returns the role with this ID, or ErrRoleNotFound.

func (*DB) GetRollbackPin added in v0.2.0

func (db *DB) GetRollbackPin(ctx context.Context, serviceName, attemptID string) (*RollbackPin, error)

GetRollbackPin returns the pin for attemptID, or nil when it has none.

func (*DB) GetRoute53DNSSettings added in v0.2.0

func (db *DB) GetRoute53DNSSettings(ctx context.Context) (Route53DNSSettings, error)

GetRoute53DNSSettings returns the single route53_dns_settings row. Always succeeds: the migration itself inserts the row (id = 1).

func (*DB) GetSSHNodeProvision added in v0.2.0

func (db *DB) GetSSHNodeProvision(ctx context.Context, id string) (SSHNodeProvision, error)

GetSSHNodeProvision returns the SSH node provision with this ID, or ErrSSHNodeProvisionNotFound.

func (*DB) GetScheduledTask

func (db *DB) GetScheduledTask(ctx context.Context, id string) (ScheduledTask, error)

GetScheduledTask returns the scheduled task with this ID, or ErrScheduledTaskNotFound.

func (*DB) GetScheduledTaskRun added in v0.2.0

func (db *DB) GetScheduledTaskRun(ctx context.Context, id string) (ScheduledTaskRun, error)

GetScheduledTaskRun returns one run including its output.

func (*DB) GetSecretKeyLocked

func (db *DB) GetSecretKeyLocked(ctx context.Context, serviceName, envKey string) (exists, locked bool, err error)

GetSecretKeyLocked reports whether (serviceName, envKey) has a value set and, if so, whether it's locked. exists is false when no value has ever been set for that key; locked is only meaningful when exists is true.

func (*DB) GetSecretValue

func (db *DB) GetSecretValue(ctx context.Context, serviceName, envKey string) ([]byte, error)

GetSecretValue returns the ciphertext for one env var of one service, or ErrSecretValueNotFound if no value has been set.

func (*DB) GetSecurityPolicy added in v0.2.0

func (db *DB) GetSecurityPolicy(ctx context.Context) (p SecurityPolicy, ok bool, err error)

GetSecurityPolicy returns the stored policy; ok is false when none was saved.

func (*DB) GetServiceCancelSuperseded added in v0.2.0

func (db *DB) GetServiceCancelSuperseded(ctx context.Context, name string) (bool, error)

GetServiceCancelSuperseded reports whether name supersedes older queued deploys.

func (*DB) GetServiceDEK

func (db *DB) GetServiceDEK(ctx context.Context, serviceName string) ([]byte, error)

GetServiceDEK returns the wrapped DEK for serviceName, or ErrServiceDEKNotFound if none has been generated yet.

func (*DB) GetServiceLoadBalancer added in v0.2.0

func (db *DB) GetServiceLoadBalancer(ctx context.Context, service string) (string, bool, error)

GetServiceLoadBalancer returns the raw JSON load balancer config for a service, and false when none is configured.

func (*DB) GetServiceVolumeBackupSchedule

func (db *DB) GetServiceVolumeBackupSchedule(ctx context.Context, serviceName, volumeName string) (ServiceVolumeBackupConfig, error)

GetServiceVolumeBackupSchedule returns serviceName/volumeName's backup schedule config, or ErrServiceVolumeBackupNotFound if it was never set.

func (*DB) GetSessionLinkTokenByHash added in v0.2.0

func (db *DB) GetSessionLinkTokenByHash(ctx context.Context, hash string) (*SessionLinkToken, error)

GetSessionLinkTokenByHash returns the session-link-token row matching hash, regardless of expiry or used state: deciding whether the token is currently usable is the caller's job.

func (*DB) GetStatusComponent added in v0.2.0

func (db *DB) GetStatusComponent(ctx context.Context, id string) (StatusComponent, error)

GetStatusComponent returns one component or ErrStatusComponentNotFound.

func (*DB) GetStatusIncident added in v0.2.0

func (db *DB) GetStatusIncident(ctx context.Context, id string) (StatusIncident, error)

GetStatusIncident returns one incident or ErrStatusIncidentNotFound.

func (*DB) GetStatusPageSettings added in v0.2.0

func (db *DB) GetStatusPageSettings(ctx context.Context) (StatusPageSettings, error)

GetStatusPageSettings returns the settings, or disabled defaults when never saved.

func (*DB) GetStorageOptions added in v0.2.0

func (db *DB) GetStorageOptions(ctx context.Context, targetID string) (StorageOptions, bool, error)

GetStorageOptions returns the options for a target. Targets created before this table existed report ok=false and callers derive defaults.

func (*DB) GetTag added in v0.2.0

func (db *DB) GetTag(ctx context.Context, id string) (Tag, error)

GetTag returns the tag with this ID, or ErrTagNotFound.

func (*DB) GetTagByName added in v0.2.0

func (db *DB) GetTagByName(ctx context.Context, name string) (Tag, error)

GetTagByName returns the tag with this name, or ErrTagNotFound.

func (*DB) GetTeamInviteByHash added in v0.2.0

func (db *DB) GetTeamInviteByHash(ctx context.Context, tokenHash string) (TeamInvite, error)

GetTeamInviteByHash returns the invite for a token hash, whatever its state.

func (*DB) GetTrustedDeviceByHash added in v0.2.0

func (db *DB) GetTrustedDeviceByHash(ctx context.Context, tokenHash string, now time.Time) (TrustedDevice, error)

GetTrustedDeviceByHash returns the live (unrevoked, unexpired) device whose cookie hashes to tokenHash.

func (*DB) GetUpdateSettings added in v0.2.0

func (db *DB) GetUpdateSettings(ctx context.Context) (UpdateSettings, error)

GetUpdateSettings returns the single update_settings row. Always succeeds against a migrated database: the migration itself inserts the row (id = 1), the same "no not-found case" guarantee GetIngressSettings already documents for its own singleton row.

func (*DB) GetUserByEmail

func (db *DB) GetUserByEmail(ctx context.Context, email string) (*User, error)

GetUserByEmail returns the user with this email, or ErrUserNotFound. The stored value isn't always a syntactically valid email: a pre-migration bare username migrates in unchanged (migrations/0035).

func (*DB) GetUserByID

func (db *DB) GetUserByID(ctx context.Context, id string) (*User, error)

GetUserByID returns the user with this ID, or ErrUserNotFound.

func (*DB) GetUserSecuritySettings added in v0.2.0

func (db *DB) GetUserSecuritySettings(ctx context.Context, userID string) (UserSecuritySettings, error)

GetUserSecuritySettings returns userID's settings, zero valued when unset.

func (*DB) GetVaultSettings added in v0.2.0

func (db *DB) GetVaultSettings(ctx context.Context) (VaultSettings, error)

GetVaultSettings returns the single vault_settings row. Always succeeds: the migration itself inserts the row (id = 1).

func (*DB) GetVolumeBackupPolicy added in v0.2.0

func (db *DB) GetVolumeBackupPolicy(ctx context.Context, serviceName, volumeName string) (VolumeBackupPolicy, error)

GetVolumeBackupPolicy returns a volume's policy or ErrVolumeBackupPolicyNotFound.

func (*DB) GetWebhookDelivery

func (db *DB) GetWebhookDelivery(ctx context.Context, id string) (*WebhookDelivery, error)

GetWebhookDelivery returns one webhook delivery by ID, or ErrWebhookDeliveryNotFound. Used by the replay handler to load the stored payload and header fields for the exact request it's about to re-run.

func (*DB) HasSecretValue

func (db *DB) HasSecretValue(ctx context.Context, serviceName, envKey string) (bool, error)

HasSecretValue reports whether a value has been set for (serviceName, envKey), without decrypting or even fetching the ciphertext. Used by internal/deploy to fail a deploy loudly when a { secret: true, required: true } env var has no value yet, matching spec.EnvVar.Required's documented meaning, rather than deferring that check to container-create time where a missing secret would only surface as a confusing runtime failure.

func (*DB) HasSecretValueForServices added in v0.2.0

func (db *DB) HasSecretValueForServices(ctx context.Context, serviceNames []string, envKey string) (map[string]bool, error)

HasSecretValueForServices reports, for every name in serviceNames, whether envKey has a value set, in one query (json_each, matching GetConditionsForControllers' pattern) instead of a HasSecretValue call per service. A name with no value is simply absent from the map, mirroring HasSecretValue's own false-on-no-rows meaning. Built for GET /api/v1/databases (internal/api's databaseTLSEnabled), which previously called Exists once per TLS-capable database on the page.

func (*DB) InsertLogArchiveRun added in v0.2.0

func (db *DB) InsertLogArchiveRun(ctx context.Context, r LogArchiveRun) error

InsertLogArchiveRun starts a run row.

func (*DB) InsertUpgradeHistory added in v0.2.0

func (db *DB) InsertUpgradeHistory(ctx context.Context, e UpgradeHistoryEntry) (UpgradeHistoryEntry, bool, error)

InsertUpgradeHistory appends e unless the newest row already records a transition to e.ToVersion, so a crash loop or a double start records one row. The check and insert are one statement. It reports whether a row was written and returns the stored entry (with its new id) when it was.

func (*DB) InterruptRunningScheduledTaskRuns added in v0.2.0

func (db *DB) InterruptRunningScheduledTaskRuns(ctx context.Context, now time.Time) ([]ScheduledTaskRun, error)

InterruptRunningScheduledTaskRuns marks every run still in status running as interrupted. Called once at control-plane start, when no run can legitimately be in flight; the runs are returned so their containers can be cleaned up. Interrupted runs are never retried, which is what rules out a double run after a restart.

func (*DB) IsDomainHidden added in v0.2.0

func (db *DB) IsDomainHidden(ctx context.Context, domain string) (bool, error)

IsDomainHidden reports whether domain asks search engines to stay away.

func (*DB) IsImagePinned added in v0.2.0

func (db *DB) IsImagePinned(ctx context.Context, imageID string) (bool, error)

IsImagePinned reports whether any rollback pin holds imageID.

func (*DB) LabelUnlabeledTokensByName added in v0.2.0

func (db *DB) LabelUnlabeledTokensByName(ctx context.Context, name, agentName string) error

LabelUnlabeledTokensByName sets the agent label on live tokens of that name that have none.

func (*DB) LatestDeployActivity added in v0.2.0

func (db *DB) LatestDeployActivity(ctx context.Context) (map[string]time.Time, error)

LatestDeployActivity returns, per service, the finish time of its newest deploy attempt (its start time while unfinished) in one statement, the batch counterpart of ListDeployAttempts()[0] for list views.

func (*DB) LatestDeployAttemptFor added in v0.2.0

func (db *DB) LatestDeployAttemptFor(ctx context.Context, serviceName, image string) (*DeployAttempt, error)

LatestDeployAttemptFor returns the newest succeeded attempt that deployed (serviceName, image), or nil when there is none.

func (*DB) LatestUpgradeHistory added in v0.2.0

func (db *DB) LatestUpgradeHistory(ctx context.Context) (UpgradeHistoryEntry, bool, error)

LatestUpgradeHistory returns the newest recorded transition, ok false when none exists yet.

func (*DB) ListAIChatMessages added in v0.2.0

func (db *DB) ListAIChatMessages(ctx context.Context, sessionID string) ([]AIChatMessage, error)

ListAIChatMessages returns every message in sessionID, oldest first.

func (*DB) ListAIChatSessions added in v0.2.0

func (db *DB) ListAIChatSessions(ctx context.Context) ([]AIChatSession, error)

ListAIChatSessions returns every session, most recently updated first.

func (*DB) ListAPITokens

func (db *DB) ListAPITokens(ctx context.Context) ([]APIToken, error)

ListAPITokens returns every token, newest first, revoked ones included: the management UI shows revocation status rather than hiding history, matching Dokploy's own token list.

func (*DB) ListActiveDBUpgradeRuns added in v0.2.0

func (db *DB) ListActiveDBUpgradeRuns(ctx context.Context) ([]DBUpgradeRun, error)

ListActiveDBUpgradeRuns returns every run not yet in a final state, oldest first.

func (*DB) ListActiveModelKeys added in v0.2.0

func (db *DB) ListActiveModelKeys(ctx context.Context) ([]ModelKey, error)

ListActiveModelKeys returns the non-revoked keys of every model, for the gateway. Expiry is checked by the caller against the request time.

func (*DB) ListActivePipelineRuns added in v0.2.0

func (db *DB) ListActivePipelineRuns(ctx context.Context) ([]PipelineRun, error)

ListActivePipelineRuns returns every queued or running run, oldest first.

func (*DB) ListAllAppStreams added in v0.2.0

func (db *DB) ListAllAppStreams(ctx context.Context) ([]AppStream, error)

ListAllAppStreams returns every app stream across every service, oldest first. Used by internal/reconcile/ingress to build one Caddy layer4 route per stream every reconcile pass, the same "list everything fresh, never cache" shape every other ingress input already follows.

func (*DB) ListAllBackupHistory added in v0.2.0

func (db *DB) ListAllBackupHistory(ctx context.Context, limit int, before *time.Time) ([]BackupHistory, error)

ListAllBackupHistory returns up to limit backup attempts across every resource, database and volume alike, newest first: the instance-wide counterpart of ListBackupHistory/ListServiceVolumeBackupHistory, for a caller that wants one merged view rather than per-resource lists. before paginates identically to those two (cursor on started_at, no OFFSET query).

func (*DB) ListAllDomainErrorPages added in v0.2.0

func (db *DB) ListAllDomainErrorPages(ctx context.Context) ([]DomainErrorPage, error)

ListAllDomainErrorPages returns every domain_error_page row across every domain, ordered by domain then status code, for the ingress controller to build error-page routes fresh every reconcile pass, the same "never cache, re-derive from current state every call" convention ListDomainRedirects already follows.

func (*DB) ListAllEnvironments added in v0.2.0

func (db *DB) ListAllEnvironments(ctx context.Context) ([]EnvironmentWithCounts, error)

ListAllEnvironments returns every environment, global and per project, with tagged app and database counts, ordered by sort_order then creation.

func (*DB) ListAllServiceEnvironmentDomains added in v0.2.0

func (db *DB) ListAllServiceEnvironmentDomains(ctx context.Context) (map[string]map[string][]string, error)

ListAllServiceEnvironmentDomains returns every app's per-environment domain sets, keyed by app name then environment ID.

func (*DB) ListAppEvents added in v0.2.0

func (db *DB) ListAppEvents(ctx context.Context, name string, before *AppEventCursor, after time.Time, kinds []string, limit int) ([]AppEvent, error)

ListAppEvents returns name's events newest first, strictly older than before when non-nil, restricted to kinds when any are given. after, when non-zero, keeps only events at or after that time.

func (*DB) ListAppImportItems added in v0.2.0

func (db *DB) ListAppImportItems(ctx context.Context, sessionID string) ([]AppImportItem, error)

ListAppImportItems returns a session's items ordered by source name.

func (*DB) ListAppImportSessions added in v0.2.0

func (db *DB) ListAppImportSessions(ctx context.Context) ([]AppImportSession, error)

ListAppImportSessions returns every session, newest first.

func (*DB) ListAppIntegrationsForService added in v0.2.0

func (db *DB) ListAppIntegrationsForService(ctx context.Context, serviceName string) ([]AppIntegration, error)

ListAppIntegrationsForService returns every integration attached to serviceName, oldest first, the same creation-order convention ListScheduledTasksForService already uses.

func (*DB) ListAppNamesByTag added in v0.2.0

func (db *DB) ListAppNamesByTag(ctx context.Context, tagID string) ([]string, error)

ListAppNamesByTag returns the name of every app tagID is attached to, alphabetical, the primitive GET /api/v1/tags/{id}/apps filters by.

func (*DB) ListAppNamesFiltered added in v0.2.0

func (db *DB) ListAppNamesFiltered(ctx context.Context, f AppListFilter) ([]string, error)

ListAppNamesFiltered returns every matching app name, unpaged and without loading service graphs, for summary counts and bulk targeting.

func (*DB) ListAppScheduleHistory added in v0.2.0

func (db *DB) ListAppScheduleHistory(ctx context.Context, serviceName string, limit int) ([]AppScheduleHistoryEntry, error)

ListAppScheduleHistory returns serviceName's most recent schedule evaluations, newest first, capped at limit (defaulted/clamped by the caller).

func (*DB) ListAppSleep added in v0.2.0

func (db *DB) ListAppSleep(ctx context.Context) ([]AppSleep, error)

ListAppSleep returns every app with sleeping enabled.

func (*DB) ListAppStreamsForService added in v0.2.0

func (db *DB) ListAppStreamsForService(ctx context.Context, serviceName string) ([]AppStream, error)

ListAppStreamsForService returns every stream targeting serviceName, oldest first. Used by internal/reconcile/application's container reconciler to decide which extra container ports to publish, and by GET /api/v1/apps/{name}/streams.

func (*DB) ListAppVolumeMoves added in v0.2.0

func (db *DB) ListAppVolumeMoves(ctx context.Context, serviceName string) ([]AppVolumeMove, error)

ListAppVolumeMoves returns every move attempt for serviceName, newest first, mirroring ListVolumeCloneRestores' own shape.

func (*DB) ListApps

func (db *DB) ListApps(ctx context.Context) ([]App, error)

ListApps returns every app, ordered by name, the same "predictable listing order" convention ListDesiredServices already uses.

func (*DB) ListAttachmentsForPolicy

func (db *DB) ListAttachmentsForPolicy(ctx context.Context, policyID string) ([]PolicyAttachment, error)

ListAttachmentsForPolicy returns every principal a policy is attached to, ordered by creation time: the management UI/CLI's "who does this policy apply to" view.

func (*DB) ListAttentionDismissals added in v0.2.0

func (db *DB) ListAttentionDismissals(ctx context.Context, userID string) (map[string]bool, error)

ListAttentionDismissals returns the item keys a user dismissed.

func (*DB) ListAuditEntries

func (db *DB) ListAuditEntries(ctx context.Context, limit int, before *time.Time, filter AuditEntryFilter) ([]AuditEntry, error)

ListAuditEntries returns up to limit audit log rows, newest first. before, when non-nil, restricts the result to entries strictly older than that timestamp, so a caller pages backward through a large table by re-issuing this call with the last returned row's CreatedAt: cursor pagination, not offset pagination, the same reasoning this function's own doc comment in the task spec calls for (an OFFSET query degrades linearly as the table grows; this one doesn't). filter narrows by exact path and/or method match.

func (*DB) ListAuditEntriesAfter added in v0.2.0

func (db *DB) ListAuditEntriesAfter(ctx context.Context, afterAt, afterID string, to *time.Time, limit int) ([]AuditEntry, error)

ListAuditEntriesAfter returns up to limit audit rows strictly after the (afterAt, afterID) cursor, oldest first, optionally bounded above by to. An empty afterAt starts from the oldest row. The (created_at, id) tuple order makes the cursor safe across rows sharing a timestamp.

func (*DB) ListBackupDrills added in v0.2.0

func (db *DB) ListBackupDrills(ctx context.Context, serviceName, volumeName, databaseName string, limit int) ([]BackupDrill, error)

ListBackupDrills returns drills newest first. serviceName, volumeName and databaseName narrow to one resource when non-empty.

func (*DB) ListBackupHistory

func (db *DB) ListBackupHistory(ctx context.Context, databaseName string, limit int, before *time.Time) ([]BackupHistory, error)

ListBackupHistory returns up to limit backup attempts for databaseName, newest first. before, when non-nil, cursor-paginates on start time (mirrors ListAuditEntries) so long-lived backup schedules never need a slow OFFSET query.

func (*DB) ListBackupTargetProtection added in v0.2.0

func (db *DB) ListBackupTargetProtection(ctx context.Context) ([]BackupTargetProtection, error)

ListBackupTargetProtection returns every stored probe.

func (*DB) ListBackupTargets

func (db *DB) ListBackupTargets(ctx context.Context) ([]BackupTarget, error)

ListBackupTargets returns every backup target, oldest first (creation order, the same order a settings page listing them would want).

func (*DB) ListBackupVerifications

func (db *DB) ListBackupVerifications(ctx context.Context, backupHistoryID string, limit int) ([]BackupVerification, error)

ListBackupVerifications returns up to limit verification attempts for backupHistoryID, newest first.

func (*DB) ListBaseBackupHistory added in v0.2.0

func (db *DB) ListBaseBackupHistory(ctx context.Context, databaseName string) ([]BaseBackupHistory, error)

ListBaseBackupHistory returns every base backup attempt for databaseName, newest first: the frontend's "which base backups exist" view and, for a caller that needs every row rather than just the two boundary lookups below, the same full-history shape ListBackupHistory offers for logical dumps.

func (*DB) ListBuildCacheSettings added in v0.2.0

func (db *DB) ListBuildCacheSettings(ctx context.Context) ([]BuildCacheSetting, error)

ListBuildCacheSettings returns every setting, global first.

func (*DB) ListCanaryReleases added in v0.2.0

func (db *DB) ListCanaryReleases(ctx context.Context) ([]CanaryRelease, error)

ListCanaryReleases returns every in-flight canary.

func (*DB) ListCertStorageKeys

func (db *DB) ListCertStorageKeys(ctx context.Context, prefix string, recursive bool) ([]string, error)

ListCertStorageKeys returns every stored key prefixed by prefix/. If recursive is false, only the immediate next path segment after prefix is returned once per distinct value: certmagic's "directory listing" semantics, where a partial key up to the next "/" stands in for every key nested further below it, matching certmagic.FileStorage.List's non-recursive behavior of listing directory entries rather than every file transitively inside them. Returns an empty slice, not an error, when nothing matches; internal/ingress's adapter is the layer that translates "nothing found" into fs.ErrNotExist, per certmagic's contract, so this stays a plain query with no certmagic-specific knowledge.

func (*DB) ListCloneRestores

func (db *DB) ListCloneRestores(ctx context.Context, sourceDatabaseName string) ([]CloneRestore, error)

ListCloneRestores returns every clone-restore attempt sourced from sourceDatabaseName, newest first: the operator triggers this action from the source database's own backups view (RestoreBackupDialog's "restore as new database" counterpart), so that's the view this list serves, the same way ListRestoreHistory serves the in-place restore table on that same page.

func (*DB) ListComposeApps added in v0.2.0

func (db *DB) ListComposeApps(ctx context.Context) ([]string, error)

ListComposeApps returns every app ID with at least one compose revision, sorted.

func (*DB) ListComposeRevisions added in v0.2.0

func (db *DB) ListComposeRevisions(ctx context.Context, appID string, limit int) ([]ComposeRevision, error)

ListComposeRevisions returns appID's revisions, newest first, at most limit (0 means all).

func (*DB) ListCustomTemplates added in v0.2.0

func (db *DB) ListCustomTemplates(ctx context.Context) ([]CustomTemplate, error)

ListCustomTemplates returns every custom template, oldest first (creation order, the same order ListBackupTargets already uses for a settings-style listing).

func (*DB) ListCutoverRuns added in v0.2.0

func (db *DB) ListCutoverRuns(ctx context.Context, app string, limit int) ([]CutoverRun, error)

ListCutoverRuns returns an app's runs, newest first.

func (*DB) ListCutoverRunsByState added in v0.2.0

func (db *DB) ListCutoverRunsByState(ctx context.Context, states ...string) ([]CutoverRun, error)

ListCutoverRunsByState returns every run in one of states, oldest first.

func (*DB) ListDBUpgradePolicies added in v0.2.0

func (db *DB) ListDBUpgradePolicies(ctx context.Context) ([]DBUpgradePolicy, error)

ListDBUpgradePolicies returns every policy row, the platform default included.

func (*DB) ListDBUpgradeRuns added in v0.2.0

func (db *DB) ListDBUpgradeRuns(ctx context.Context, databaseName string, limit int) ([]DBUpgradeRun, error)

ListDBUpgradeRuns returns a database's runs, newest first, at most limit (0 means all).

func (*DB) ListDatabaseAccessUsers added in v0.2.0

func (db *DB) ListDatabaseAccessUsers(ctx context.Context, database, kind string) ([]DatabaseAccessUser, error)

ListDatabaseAccessUsers returns the live users of one kind for a database, oldest first. An empty kind returns every kind.

func (*DB) ListDatabaseDataImports added in v0.2.0

func (db *DB) ListDatabaseDataImports(ctx context.Context) ([]DatabaseDataImport, error)

ListDatabaseDataImports returns every copy row.

func (*DB) ListDatabaseNetworkRuleNotes added in v0.2.0

func (db *DB) ListDatabaseNetworkRuleNotes(ctx context.Context, database string) (map[string]string, error)

ListDatabaseNetworkRuleNotes returns source -> description for a database.

func (*DB) ListDatabaseQueryHistory added in v0.2.0

func (db *DB) ListDatabaseQueryHistory(ctx context.Context, database, principalType, principalID string, limit int) ([]DatabaseQueryHistory, error)

ListDatabaseQueryHistory returns the caller's history for a database, newest first.

func (*DB) ListDatabaseSavedQueries added in v0.2.0

func (db *DB) ListDatabaseSavedQueries(ctx context.Context, database, principalType, principalID string) ([]DatabaseSavedQuery, error)

ListDatabaseSavedQueries returns the caller's saved queries for a database, by name.

func (*DB) ListDeployApprovals added in v0.2.0

func (db *DB) ListDeployApprovals(ctx context.Context, status, serviceName string) ([]DeployApproval, error)

ListDeployApprovals returns deploy approvals, newest first, optionally filtered to one status (DeployApprovalStatus*, empty means "any") and one service name (empty means "any app"): GET /api/v1/deploy-approvals' own query parameters (internal/api/deploy_approvals.go).

func (*DB) ListDeployAttemptCacheWarnings added in v0.2.0

func (db *DB) ListDeployAttemptCacheWarnings(ctx context.Context, serviceName string) (map[string]string, error)

ListDeployAttemptCacheWarnings maps attempt id to its cache warning for a service.

func (*DB) ListDeployAttempts

func (db *DB) ListDeployAttempts(ctx context.Context, serviceName string) ([]DeployAttempt, error)

ListDeployAttempts returns every attempt for serviceName, newest first. A service with no attempts yet returns an empty (nil) slice and a nil error, not an error, the same "absence is not an error" convention GetConditions/QueryLogs already establish. No pagination: per this task's own scope note, an app that accumulates a very large number of attempts over its lifetime will make this list grow unbounded; that's a known, deliberately deferred follow-up, not solved here.

func (*DB) ListDeployFreezeWindows added in v0.2.0

func (db *DB) ListDeployFreezeWindows(ctx context.Context, scopes ...string) ([]DeployFreezeWindow, error)

ListDeployFreezeWindows returns the windows in any of scopes, oldest first.

func (*DB) ListDeploymentBriefs added in v0.2.0

func (db *DB) ListDeploymentBriefs(ctx context.Context, since time.Time, visibleApps []string) ([]DeploymentBrief, error)

ListDeploymentBriefs returns status and timing for every deployment of the visible apps started at or after since.

func (*DB) ListDeployments added in v0.2.0

func (db *DB) ListDeployments(ctx context.Context, f DeploymentFilter) ([]Deployment, string, error)

ListDeployments returns deploy attempts across every existing app, newest first, plus the cursor for the next page ("" when exhausted).

func (*DB) ListDesiredDatabases

func (db *DB) ListDesiredDatabases(ctx context.Context) ([]DesiredDatabase, error)

ListDesiredDatabases returns every saved database, ordered by name.

func (*DB) ListDesiredDatabasesByNode

func (db *DB) ListDesiredDatabasesByNode(ctx context.Context, nodeID string) ([]DesiredDatabase, error)

ListDesiredDatabasesByNode returns every saved database currently placed on nodeID, ordered by name. The database-kind counterpart to ListDesiredServicesByNode, same drain/delete-guard callers.

func (*DB) ListDesiredDatabasesByProject added in v0.2.0

func (db *DB) ListDesiredDatabasesByProject(ctx context.Context, projectID string) ([]DesiredDatabase, error)

ListDesiredDatabasesByProject returns every saved database filed under projectID, ordered by name, the project-kind counterpart to ListDesiredDatabasesByNode. Used by handleStopProject/handleStartProject (internal/api/project_stop_start.go) to find every database in a project without listing every database.

func (*DB) ListDesiredServices

func (db *DB) ListDesiredServices(ctx context.Context) ([]DesiredService, error)

ListDesiredServices returns every saved service, ordered by name.

func (*DB) ListDesiredServicesByEnvironment added in v0.2.0

func (db *DB) ListDesiredServicesByEnvironment(ctx context.Context, environmentID string) ([]DesiredService, error)

ListDesiredServicesByEnvironment returns every saved service tagged with environmentID, ordered by name, the environment-kind counterpart to ListDesiredServicesByProject above. Used by internal/api/environment_clone.go to find what a "clone environment" operation copies, without listing every service and filtering in-memory the way promote.go's own findPromotionCandidates still does for its narrower single-app lookup.

func (*DB) ListDesiredServicesByNode

func (db *DB) ListDesiredServicesByNode(ctx context.Context, nodeID string) ([]DesiredService, error)

ListDesiredServicesByNode returns every saved service currently placed on nodeID, ordered by name. Node drain (internal/api's handleDrainNode) uses this to find what to move off a node before it's removed, and handleDeleteNode uses it as the guard that makes node deletion refuse to run while placements remain. nodeID="" (the local-node sentinel, see DesiredService.NodeID's own doc comment) is a valid argument, matching every other node_id comparison in this package.

func (*DB) ListDesiredServicesByProject added in v0.2.0

func (db *DB) ListDesiredServicesByProject(ctx context.Context, projectID string) ([]DesiredService, error)

ListDesiredServicesByProject returns every saved service filed under projectID, ordered by name, the project-kind counterpart to ListDesiredServicesByNode. Used by handleStopProject/handleStartProject (internal/api/project_stop_start.go) and internal/api's bulk-restart endpoint to find every app in a project without listing every service.

func (*DB) ListDesiredServicesFiltered added in v0.2.0

func (db *DB) ListDesiredServicesFiltered(ctx context.Context, f AppListFilter) ([]DesiredService, int, error)

ListDesiredServicesFiltered returns one page of services matching f, plus the total match count before paging.

func (*DB) ListDomainAutomationRuns added in v0.2.0

func (db *DB) ListDomainAutomationRuns(ctx context.Context, limit int) ([]DomainAutomationRun, error)

ListDomainAutomationRuns returns the newest runs first, limited.

func (*DB) ListDomainBasicAuth

func (db *DB) ListDomainBasicAuth(ctx context.Context) ([]DomainBasicAuth, error)

ListDomainBasicAuth returns every domain_basic_auth row, ordered by domain, for the ingress controller to build basic_auth directives fresh every reconcile pass, the same "never cache, re-derive from current state every call" convention ListServiceDomains already follows.

func (*DB) ListDomainErrorPages added in v0.2.0

func (db *DB) ListDomainErrorPages(ctx context.Context, domain string) ([]DomainErrorPage, error)

ListDomainErrorPages returns every custom error page configured for domain, ordered by status code.

func (*DB) ListDomainMaintenance

func (db *DB) ListDomainMaintenance(ctx context.Context) ([]string, error)

ListDomainMaintenance returns every domain currently in maintenance mode, ordered by domain, for the ingress controller to check fresh every reconcile pass, the same "never cache, re-derive from current state" convention ListDomainBasicAuth already follows.

func (*DB) ListDomainRedirects added in v0.2.0

func (db *DB) ListDomainRedirects(ctx context.Context) ([]DomainRedirect, error)

ListDomainRedirects returns every domain_redirect row, ordered by domain, for the ingress controller to build redirect routes fresh every reconcile pass, the same "never cache, re-derive from current state every call" convention ListDomainBasicAuth already follows.

func (*DB) ListDomainTLSCerts

func (db *DB) ListDomainTLSCerts(ctx context.Context) ([]DomainTLSCert, error)

ListDomainTLSCerts returns every domain_tls_cert row, ordered by domain, for the ingress controller to resolve fresh every reconcile pass, the same "never cache, re-derive from current state every call" convention ListDomainBasicAuth already follows.

func (*DB) ListDomainTrafficPolicies added in v0.2.0

func (db *DB) ListDomainTrafficPolicies(ctx context.Context) ([]DomainTrafficPolicy, error)

ListDomainTrafficPolicies returns every row, read by the ingress reconciler on each pass.

func (*DB) ListDomainTrafficPoliciesFor added in v0.2.0

func (db *DB) ListDomainTrafficPoliciesFor(ctx context.Context, domain string) ([]DomainTrafficPolicy, error)

ListDomainTrafficPoliciesFor returns every kind configured for domain.

func (*DB) ListDomainWAF added in v0.2.0

func (db *DB) ListDomainWAF(ctx context.Context) ([]DomainWAF, error)

ListDomainWAF returns every domain_waf row, ordered by domain, for the ingress controller to build WAF/rate-limit handlers fresh every reconcile pass, the same "never cache, re-derive from current state every call" convention ListDomainBasicAuth already follows.

func (*DB) ListEnabledAppSchedules added in v0.2.0

func (db *DB) ListEnabledAppSchedules(ctx context.Context) ([]AppSchedule, error)

ListEnabledAppSchedules returns every currently enabled app schedule, re-derived fresh on every call: internal/scheduledeploy.Scheduler calls this once per tick, the same "no cached membership" shape internal/scheduledtask.ScheduleStore's own doc comment establishes.

func (*DB) ListEnabledImageAutoUpdates added in v0.2.0

func (db *DB) ListEnabledImageAutoUpdates(ctx context.Context) ([]ImageAutoUpdate, error)

ListEnabledImageAutoUpdates returns every app that opted in.

func (*DB) ListEnabledScheduledTasks

func (db *DB) ListEnabledScheduledTasks(ctx context.Context) ([]ScheduledTask, error)

ListEnabledScheduledTasks returns every scheduled task with Enabled true, across every service: internal/scheduledtask.Scheduler.Tick's own per-tick query (idx_scheduled_tasks_enabled, migrations/ 0048_scheduled_tasks.sql, supports exactly this filter).

func (*DB) ListEnvironmentEnvVars

func (db *DB) ListEnvironmentEnvVars(ctx context.Context, environmentID string) (map[string]string, error)

ListEnvironmentEnvVars returns environmentID's shared env vars as a plain map, empty (not nil) when none are set, mirroring ListOrganizationEnvVars/ListProjectEnvVars.

func (*DB) ListEnvironmentEnvVarsDetailed added in v0.2.0

func (db *DB) ListEnvironmentEnvVarsDetailed(ctx context.Context, environmentID string) ([]SharedEnvVar, error)

ListEnvironmentEnvVarsDetailed returns every shared env var for environmentID, plain and secret-marked alike, mirroring ListProjectEnvVarsDetailed.

func (*DB) ListEnvironmentSecretEnvKeys added in v0.2.0

func (db *DB) ListEnvironmentSecretEnvKeys(ctx context.Context, environmentID string) ([]string, error)

ListEnvironmentSecretEnvKeys returns every secret-marked shared env var key for environmentID, never a value, mirroring ListProjectSecretEnvKeys.

func (*DB) ListEnvironmentsByProject

func (db *DB) ListEnvironmentsByProject(ctx context.Context, projectID string) ([]Environment, error)

ListEnvironmentsByProject returns every environment for one project, oldest first.

func (*DB) ListExportDestinations added in v0.2.0

func (db *DB) ListExportDestinations(ctx context.Context) ([]ExportDestination, error)

ListExportDestinations returns every destination ordered by name.

func (*DB) ListExposureRestrictions added in v0.2.0

func (db *DB) ListExposureRestrictions(ctx context.Context) ([]ExposureRestriction, error)

ListExposureRestrictions returns every restriction, by port.

func (*DB) ListExternalDatabases added in v0.2.0

func (db *DB) ListExternalDatabases(ctx context.Context) ([]ExternalDatabase, error)

ListExternalDatabases returns every record ordered by name.

func (*DB) ListFailedDeploysSince added in v0.2.0

func (db *DB) ListFailedDeploysSince(ctx context.Context, since time.Time) ([]FailedDeploy, error)

ListFailedDeploysSince returns, per existing app, its latest attempt when that attempt failed and started at or after since, newest first.

func (*DB) ListFeatureFlagsForService

func (db *DB) ListFeatureFlagsForService(ctx context.Context, serviceName string) ([]FeatureFlag, error)

ListFeatureFlagsForService returns every feature flag owned by serviceName, oldest first, the same creation-order convention ListScheduledTasksForService already uses.

func (*DB) ListFirewallRules added in v0.2.0

func (db *DB) ListFirewallRules(ctx context.Context) ([]FirewallRule, error)

ListFirewallRules returns every firewall rule, oldest first.

func (*DB) ListForgeDeploymentsByState added in v0.2.0

func (db *DB) ListForgeDeploymentsByState(ctx context.Context, app, environment, state, excludeID string) ([]ForgeDeployment, error)

ListForgeDeploymentsByState returns an app environment's deployments in state, excluding excludeID, newest first.

func (*DB) ListGateEvents added in v0.2.0

func (db *DB) ListGateEvents(ctx context.Context, attemptID string) ([]DeployGateEvent, error)

ListGateEvents returns attemptID's gate timeline in the order it happened.

func (*DB) ListGateEventsSince added in v0.2.0

func (db *DB) ListGateEventsSince(ctx context.Context, phase, status string, since time.Time) ([]DeployGateEvent, error)

ListGateEventsSince returns every event of phase and status at or after since, oldest first.

func (*DB) ListGitHubAppInstallations added in v0.2.0

func (db *DB) ListGitHubAppInstallations(ctx context.Context) ([]GitHubAppInstallation, error)

ListGitHubAppInstallations returns every connected account/org, oldest first (the order accounts were connected in, so "Personal" or the first org an admin ever connected stays first in the picker).

func (*DB) ListGitSources added in v0.2.0

func (db *DB) ListGitSources(ctx context.Context) ([]GitSourceSummary, error)

ListGitSources returns every connected git source's service name, repo URL and branch, for callers that need to map a repo back to the app deploying it (e.g. a "this repo is already in use" check) without fetching each one's full GitSource individually.

func (*DB) ListHeldDeployAttempts added in v0.2.0

func (db *DB) ListHeldDeployAttempts(ctx context.Context) ([]DeployAttempt, error)

ListHeldDeployAttempts returns every held attempt, oldest first.

func (*DB) ListHiddenDomains added in v0.2.0

func (db *DB) ListHiddenDomains(ctx context.Context) ([]string, error)

ListHiddenDomains returns every domain that asks search engines to stay away.

func (*DB) ListLBUpstreamAdminStates added in v0.2.0

func (db *DB) ListLBUpstreamAdminStates(ctx context.Context) (map[string]map[int]string, error)

ListLBUpstreamAdminStates returns every non-active state as service -> replica -> state.

func (*DB) ListLiveLoginCodesForUser added in v0.2.0

func (db *DB) ListLiveLoginCodesForUser(ctx context.Context, userID string, now time.Time) ([]LoginCodeChallenge, error)

ListLiveLoginCodesForUser returns userID's pending, unexpired challenges, newest first.

func (*DB) ListLoadBalancerRows added in v0.2.0

func (db *DB) ListLoadBalancerRows(ctx context.Context) ([]LoadBalancerRow, error)

ListLoadBalancerRows returns every configured balancer joined to its desired service, ordered by service name, in a single query.

func (*DB) ListLogArchivePolicies added in v0.2.0

func (db *DB) ListLogArchivePolicies(ctx context.Context) ([]LogArchivePolicy, error)

ListLogArchivePolicies returns every policy, global first.

func (*DB) ListLogArchiveRuns added in v0.2.0

func (db *DB) ListLogArchiveRuns(ctx context.Context, appName string, all bool, limit int) ([]LogArchiveRun, error)

ListLogArchiveRuns returns the newest runs for an app scope; all=true ignores the scope.

func (*DB) ListMajorUpgradeSnapshots added in v0.2.0

func (db *DB) ListMajorUpgradeSnapshots(ctx context.Context) ([]MajorUpgrade, error)

ListMajorUpgradeSnapshots returns every upgrade that still holds a rollback snapshot volume, across all databases.

func (*DB) ListMajorUpgrades added in v0.2.0

func (db *DB) ListMajorUpgrades(ctx context.Context, databaseName string) ([]MajorUpgrade, error)

ListMajorUpgrades returns a database's upgrade attempts, newest first.

func (*DB) ListManagedDNSRecords added in v0.2.0

func (db *DB) ListManagedDNSRecords(ctx context.Context, domain string) ([]ManagedDNSRecord, error)

ListManagedDNSRecords returns the records tracked for domain.

func (*DB) ListMigrationItems added in v0.2.0

func (db *DB) ListMigrationItems(ctx context.Context, sessionID string) ([]MigrationItem, error)

ListMigrationItems returns a session's databases ordered by source name.

func (*DB) ListMigrationSessions added in v0.2.0

func (db *DB) ListMigrationSessions(ctx context.Context) ([]MigrationSession, error)

ListMigrationSessions returns every session, newest first.

func (*DB) ListModelKeys added in v0.2.0

func (db *DB) ListModelKeys(ctx context.Context, model string) ([]ModelKey, error)

ListModelKeys returns every key of a model, revoked ones included.

func (*DB) ListModelUsage added in v0.2.0

func (db *DB) ListModelUsage(ctx context.Context, model string, from, to time.Time) ([]ModelUsage, error)

ListModelUsage returns the hourly rows of a model whose hour lies in [from, to), oldest first.

func (*DB) ListModels added in v0.2.0

func (db *DB) ListModels(ctx context.Context) ([]Model, error)

ListModels returns every model ordered by name, including those being deleted.

func (*DB) ListModelsInSwapGroup added in v0.2.0

func (db *DB) ListModelsInSwapGroup(ctx context.Context, group string) ([]Model, error)

ListModelsInSwapGroup returns every model sharing group, ordered by name. group must not be empty: the empty group means "no group" and is never looked up as a set.

func (*DB) ListNetworkShares added in v0.2.0

func (db *DB) ListNetworkShares(ctx context.Context) ([]NetworkShare, error)

ListNetworkShares returns every network share, oldest first.

func (*DB) ListNodeAgentVersionChanges added in v0.2.0

func (db *DB) ListNodeAgentVersionChanges(ctx context.Context, limit int) ([]NodeAgentVersionChange, error)

ListNodeAgentVersionChanges returns recent agent version changes across nodes, newest first.

func (*DB) ListNodeDrains added in v0.2.0

func (db *DB) ListNodeDrains(ctx context.Context, nodeID string, limit int) ([]NodeDrain, error)

ListNodeDrains returns drains newest first, for one node or (nodeID "") only the running ones across every node.

func (*DB) ListNodeGPUs added in v0.2.0

func (db *DB) ListNodeGPUs(ctx context.Context) (map[string]NodeGPU, error)

ListNodeGPUs returns every stored snapshot keyed by node ID.

func (*DB) ListNodeLabels added in v0.2.0

func (db *DB) ListNodeLabels(ctx context.Context) (map[string]map[string]string, error)

ListNodeLabels returns every node's labels keyed by node ID.

func (*DB) ListNodeMoves added in v0.2.0

func (db *DB) ListNodeMoves(ctx context.Context, f NodeMoveFilter) ([]NodeMove, error)

ListNodeMoves returns moves newest first.

func (*DB) ListNodeProvisions added in v0.2.0

func (db *DB) ListNodeProvisions(ctx context.Context) ([]NodeProvision, error)

ListNodeProvisions returns every node provision, newest first.

func (*DB) ListNodeStatusEvents added in v0.2.0

func (db *DB) ListNodeStatusEvents(ctx context.Context, nodeID string, limit int) ([]NodeStatusEvent, error)

ListNodeStatusEvents returns a node's most recent status transitions, newest first.

func (*DB) ListNodes

func (db *DB) ListNodes(ctx context.Context) ([]Node, error)

ListNodes returns every node, ordered by name.

func (*DB) ListNodesFiltered added in v0.2.0

func (db *DB) ListNodesFiltered(ctx context.Context, f NodeListFilter) ([]Node, int, error)

ListNodesFiltered returns one page of nodes matching f, ordered by name, plus the total match count before paging. ListNodes stays the simple unpaged primitive every existing caller already uses; this is the new surface for the API/CLI's paginated list, the same "add a filtered sibling rather than change the existing signature" shape apps_list.go's ListDesiredServicesFiltered already uses next to ListApps.

func (*DB) ListOAuthIdentitiesForUser

func (db *DB) ListOAuthIdentitiesForUser(ctx context.Context, userID string) ([]OAuthIdentity, error)

ListOAuthIdentitiesForUser returns every provider a user has linked, oldest first.

func (*DB) ListOAuthProviderSettings

func (db *DB) ListOAuthProviderSettings(ctx context.Context) ([]OAuthProviderSettings, error)

ListOAuthProviderSettings returns every provider row, ordered by provider name: GET /api/v1/settings/oauth's read model.

func (*DB) ListOrganizationEnvVars

func (db *DB) ListOrganizationEnvVars(ctx context.Context, orgID string) (map[string]string, error)

ListOrganizationEnvVars returns orgID's shared env vars as a plain map, empty (not nil) when none are set, mirroring ListProjectEnvVars.

func (*DB) ListOrganizationEnvVarsDetailed added in v0.2.0

func (db *DB) ListOrganizationEnvVarsDetailed(ctx context.Context, orgID string) ([]SharedEnvVar, error)

ListOrganizationEnvVarsDetailed returns every shared env var for orgID, plain and secret-marked alike, mirroring ListProjectEnvVarsDetailed one tier up.

func (*DB) ListOrganizationEnvVarsForProject

func (db *DB) ListOrganizationEnvVarsForProject(ctx context.Context, projectID string) (map[string]string, error)

ListOrganizationEnvVarsForProject returns the shared env vars of projectID's organization, empty when the project has no organization (or doesn't exist): the join internal/reconcile/application.Controller.resolveEnv needs to add the organization tier below its existing project tier without that package having to know projects carry an org_id column at all.

func (*DB) ListOrganizationSecretEnvKeys added in v0.2.0

func (db *DB) ListOrganizationSecretEnvKeys(ctx context.Context, orgID string) ([]string, error)

ListOrganizationSecretEnvKeys returns every secret-marked shared env var key for orgID, never a value, mirroring ListProjectSecretEnvKeys one tier up.

func (*DB) ListOrganizations

func (db *DB) ListOrganizations(ctx context.Context) ([]Organization, error)

ListOrganizations returns every organization, oldest first.

func (*DB) ListOrphanSightings added in v0.2.0

func (db *DB) ListOrphanSightings(ctx context.Context) ([]OrphanSighting, error)

ListOrphanSightings returns every recorded sighting.

func (*DB) ListPITRRestoreHistory added in v0.2.0

func (db *DB) ListPITRRestoreHistory(ctx context.Context, databaseName string) ([]PITRRestoreHistory, error)

ListPITRRestoreHistory returns every PITR restore attempt for databaseName, newest first.

func (*DB) ListPendingAIChatConfirmations added in v0.2.0

func (db *DB) ListPendingAIChatConfirmations(ctx context.Context, messageID string) ([]AIChatConfirmation, error)

ListPendingAIChatConfirmations returns every still-pending confirmation for messageID, so a caller can tell whether an assistant turn that proposed several mutating calls in one response still has any unresolved before it's safe to continue that turn.

func (*DB) ListPendingInvites

func (db *DB) ListPendingInvites(ctx context.Context) ([]Invite, error)

ListPendingInvites returns every invite not yet accepted or revoked, oldest first, including ones past their expires_at: an expired invite still shows up so an operator can see and revoke it, expiry itself is a display-time computation over ExpiresAt, not a filter here.

func (*DB) ListPendingLoginApprovalsForUser added in v0.2.0

func (db *DB) ListPendingLoginApprovalsForUser(ctx context.Context, userID string, now time.Time) ([]LoginApproval, error)

ListPendingLoginApprovalsForUser returns userID's pending, unexpired approvals, newest first.

func (*DB) ListPendingTeardowns added in v0.2.0

func (db *DB) ListPendingTeardowns(ctx context.Context) ([]PendingTeardown, error)

ListPendingTeardowns returns every tombstone, oldest first.

func (*DB) ListPipelineApprovals added in v0.2.0

func (db *DB) ListPipelineApprovals(ctx context.Context, runID string) ([]PipelineApproval, error)

ListPipelineApprovals returns a run's approval gates, oldest first.

func (*DB) ListPipelineJobs added in v0.2.0

func (db *DB) ListPipelineJobs(ctx context.Context, runID string) ([]PipelineJob, error)

ListPipelineJobs returns a run's jobs with steps, in creation order.

func (*DB) ListPipelineLogs added in v0.2.0

func (db *DB) ListPipelineLogs(ctx context.Context, runID, jobKey string, afterID int64, limit int) ([]PipelineLogLine, error)

ListPipelineLogs returns a run's log lines with ID greater than afterID. jobKey, when non-empty, filters to one job. limit <= 0 defaults to 1000.

func (*DB) ListPipelineRunRows added in v0.2.0

func (db *DB) ListPipelineRunRows(ctx context.Context, f PipelineRunFilter) ([]PipelineRunRow, error)

ListPipelineRunRows returns runs across all apps, newest first.

func (*DB) ListPipelineRuns added in v0.2.0

func (db *DB) ListPipelineRuns(ctx context.Context, app, pipelineID string, limit int) ([]PipelineRun, error)

ListPipelineRuns returns an app's runs newest first, optionally limited to one pipeline. limit <= 0 defaults to 50.

func (*DB) ListPipelineRunsInGroup added in v0.2.0

func (db *DB) ListPipelineRunsInGroup(ctx context.Context, group string) ([]PipelineRun, error)

ListPipelineRunsInGroup returns active runs sharing a concurrency group. Runs held for approval are left out so an unapproved fork pull request can never keep a trusted run waiting.

func (*DB) ListPipelineStepLogs added in v0.2.0

func (db *DB) ListPipelineStepLogs(ctx context.Context, runID, jobKey string, step *int, afterID int64, limit int) ([]PipelineLogLine, error)

ListPipelineStepLogs is ListPipelineLogs with an optional step filter applied before the limit, so a late step is not crowded out by earlier ones.

func (*DB) ListPipelineTriggerLog added in v0.2.0

func (db *DB) ListPipelineTriggerLog(ctx context.Context, app string, limit int) ([]PipelineTriggerLog, error)

ListPipelineTriggerLog returns an app's trigger decisions newest first. limit <= 0 defaults to 50.

func (*DB) ListPipelines added in v0.2.0

func (db *DB) ListPipelines(ctx context.Context, app string) ([]Pipeline, error)

ListPipelines returns an app's pipelines by name; an empty app lists all.

func (*DB) ListPolicies

func (db *DB) ListPolicies(ctx context.Context) ([]Policy, error)

ListPolicies returns every policy, ordered by name.

func (*DB) ListPoliciesForPrincipal

func (db *DB) ListPoliciesForPrincipal(ctx context.Context, principalType, principalID string) ([]Policy, error)

ListPoliciesForPrincipal returns every policy attached to one principal (a user or a token), ordered by name: exactly the set internal/api's authorization check evaluates for a given caller.

func (*DB) ListPolicyVersions added in v0.2.0

func (db *DB) ListPolicyVersions(ctx context.Context, policyID string) ([]PolicyVersion, error)

ListPolicyVersions returns a policy's versions, newest first.

func (*DB) ListPreviewAppSettings added in v0.2.0

func (db *DB) ListPreviewAppSettings(ctx context.Context) (map[string]PreviewAppSettings, error)

ListPreviewAppSettings returns every saved policy keyed by app name.

func (*DB) ListPreviewDatabaseIsolationsByPreview added in v0.2.0

func (db *DB) ListPreviewDatabaseIsolationsByPreview(ctx context.Context, previewEnvironmentID string) ([]PreviewDatabaseIsolation, error)

ListPreviewDatabaseIsolationsByPreview returns every isolation tracking row for previewEnvironmentID.

func (*DB) ListPreviewEnvironments added in v0.2.0

func (db *DB) ListPreviewEnvironments(ctx context.Context) ([]PreviewEnvironment, error)

ListPreviewEnvironments returns every preview environment across all apps, oldest created first: the order eviction and the global usage view both need.

func (*DB) ListPreviewEnvironmentsByApp

func (db *DB) ListPreviewEnvironmentsByApp(ctx context.Context, appName string) ([]PreviewEnvironment, error)

ListPreviewEnvironmentsByApp returns every preview environment for appName, newest first: GET /api/v1/apps/{name}/previews's read path.

func (*DB) ListPreviewEphemeralDatabasesByPreview added in v0.2.0

func (db *DB) ListPreviewEphemeralDatabasesByPreview(ctx context.Context, previewEnvironmentID string) ([]PreviewEphemeralDatabase, error)

ListPreviewEphemeralDatabasesByPreview returns every ephemeral database tracking row for previewEnvironmentID, for the API's own status surface and for teardown to find everything it owns.

func (*DB) ListProbeAttempts added in v0.2.0

func (db *DB) ListProbeAttempts(ctx context.Context, deployID string) ([]ProbeAttempt, error)

ListProbeAttempts returns every probe attempt recorded for deployID, in the order they actually happened.

func (*DB) ListProjectEnvVars

func (db *DB) ListProjectEnvVars(ctx context.Context, projectID string) (map[string]string, error)

ListProjectEnvVars returns projectID's shared env vars as a plain map, empty (not nil) when none are set: the one caller that matters, internal/reconcile/application.Controller.resolveEnv, merges this straight into a working map with no nil check needed.

func (*DB) ListProjectEnvVarsDetailed added in v0.2.0

func (db *DB) ListProjectEnvVarsDetailed(ctx context.Context, projectID string) ([]SharedEnvVar, error)

ListProjectEnvVarsDetailed returns every shared env var for projectID, plain and secret-marked alike, secret entries carrying an empty Value (see SharedEnvVar's own doc comment): the shape GET /api/v1/projects/{id}/env/all (project_env.go) needs to render one combined settings-page table instead of stitching two separate list calls together itself.

func (*DB) ListProjectSecretEnvKeys added in v0.2.0

func (db *DB) ListProjectSecretEnvKeys(ctx context.Context, projectID string) ([]string, error)

ListProjectSecretEnvKeys returns every secret-marked shared env var key for projectID, never a value, mirroring ListSecretKeys' own "names only" shape for per-app secrets.

func (*DB) ListProjects

func (db *DB) ListProjects(ctx context.Context) ([]Project, error)

ListProjects returns every project, oldest first, the same creation- order convention ListBackupTargets already uses for the same reason: it's the order a settings-style listing page wants, and there is no other field (like an app/database's name) a caller would obviously want to sort by instead.

func (*DB) ListProxyRouteStatus added in v0.2.0

func (db *DB) ListProxyRouteStatus(ctx context.Context) ([]ProxyRouteStatus, error)

ListProxyRouteStatus returns every tracked managed route, ordered by domain.

func (*DB) ListPushSubscriptions added in v0.2.0

func (db *DB) ListPushSubscriptions(ctx context.Context) ([]PushSubscription, error)

ListPushSubscriptions returns every registered subscription across every user: the "webpush" notification-channel kind's own send fan-out (internal/webpush), which has no per-rule or per-app destination to scope by, unlike every URL-based channel kind.

func (*DB) ListPushSubscriptionsForUser added in v0.2.0

func (db *DB) ListPushSubscriptionsForUser(ctx context.Context, userID string) ([]PushSubscription, error)

ListPushSubscriptionsForUser returns every subscription userID has registered, oldest first: the settings-page listing.

func (*DB) ListQueuedDeployAttempts added in v0.2.0

func (db *DB) ListQueuedDeployAttempts(ctx context.Context) ([]DeployAttempt, error)

ListQueuedDeployAttempts returns every queued attempt, oldest first.

func (*DB) ListRegistryCredentials

func (db *DB) ListRegistryCredentials(ctx context.Context) ([]RegistryCredential, error)

ListRegistryCredentials returns every registry credential, oldest first.

func (*DB) ListRestoreHistory

func (db *DB) ListRestoreHistory(ctx context.Context, databaseName string) ([]RestoreHistory, error)

ListRestoreHistory returns every restore attempt for databaseName, newest first (migrations/0019's own index is built for exactly this query shape, the same as ListBackupHistory's).

func (*DB) ListRoles added in v0.2.0

func (db *DB) ListRoles(ctx context.Context) ([]Role, error)

ListRoles returns built-in roles first, then custom ones by name.

func (*DB) ListRollbackPins added in v0.2.0

func (db *DB) ListRollbackPins(ctx context.Context, serviceName string) ([]RollbackPin, error)

ListRollbackPins returns serviceName's pins, newest first.

func (*DB) ListRunningBackups added in v0.2.0

func (db *DB) ListRunningBackups(ctx context.Context, startedBefore time.Time) ([]BackupHistory, error)

ListRunningBackups returns backup rows still marked running that started before cutoff: attempts the control plane lost track of.

func (*DB) ListRunningDeployAttempts added in v0.2.0

func (db *DB) ListRunningDeployAttempts(ctx context.Context) ([]DeployAttempt, error)

ListRunningDeployAttempts returns every running attempt.

func (*DB) ListRunningMajorUpgrades added in v0.2.0

func (db *DB) ListRunningMajorUpgrades(ctx context.Context) ([]MajorUpgrade, error)

ListRunningMajorUpgrades returns upgrades still marked running, which after a control plane restart are the ones it interrupted.

func (*DB) ListSSHNodeProvisions added in v0.2.0

func (db *DB) ListSSHNodeProvisions(ctx context.Context) ([]SSHNodeProvision, error)

ListSSHNodeProvisions returns every SSH node provision, newest first.

func (*DB) ListScheduledDatabases

func (db *DB) ListScheduledDatabases(ctx context.Context) ([]DesiredDatabase, error)

ListScheduledDatabases returns every database with both a non-empty backup_schedule and a resolved backup_target_id, ordered by name. The two are deliberately required together, not backup_schedule alone: a schedule whose backup_targets row was since deleted (migrations/0023's own ON DELETE SET NULL) can never actually run, and requiring both here means internal/backup.Scheduler.Tick never has to special-case that half-configured state itself, on every tick, for the lifetime of the process. Re-derived fresh on every call, the same "never cache, re-derive every pass" principle dynamicSource (cmd/levelrail/main.go) already applies to which databases exist at all.

func (*DB) ListScheduledServiceVolumes

func (db *DB) ListScheduledServiceVolumes(ctx context.Context) ([]ServiceVolumeBackupConfig, error)

ListScheduledServiceVolumes returns every service volume with both a non-empty backup_schedule and a resolved backup_target_id, ordered by service_name then volume_name, the volume counterpart of ListScheduledDatabases (database.go): see that method's own doc comment for why both are required together rather than schedule alone.

func (*DB) ListScheduledTaskRuns added in v0.2.0

func (db *DB) ListScheduledTaskRuns(ctx context.Context, f ScheduledTaskRunFilter) ([]ScheduledTaskRun, error)

ListScheduledTaskRuns returns runs newest first without their output (GetScheduledTaskRun carries it), so a history table stays light.

func (*DB) ListScheduledTasksForService

func (db *DB) ListScheduledTasksForService(ctx context.Context, serviceName string) ([]ScheduledTask, error)

ListScheduledTasksForService returns every scheduled task for serviceName, oldest first, the same creation-order convention ListBackupTargets already uses.

func (*DB) ListSecretCiphertexts added in v0.2.0

func (db *DB) ListSecretCiphertexts(ctx context.Context, afterService, afterKey string, limit int) ([]SecretCiphertext, error)

ListSecretCiphertexts returns up to limit rows ordered by (service_name, env_key), strictly after (afterService, afterKey), for keyset pagination that stays stable while rows are rewritten.

func (*DB) ListSecretKeys

func (db *DB) ListSecretKeys(ctx context.Context, serviceName string) ([]SecretKeyInfo, error)

ListSecretKeys returns every secret key set for serviceName, ordered by key, each with its locked state and last-set timestamp. Never touches ciphertext: the caller (internal/api's GET /apps/{name}/secrets) can safely return this straight to a browser.

func (*DB) ListSelfUpgradeAttempts added in v0.2.0

func (db *DB) ListSelfUpgradeAttempts(ctx context.Context, limit int) ([]SelfUpgradeAttempt, error)

ListSelfUpgradeAttempts returns the newest attempts first.

func (*DB) ListServiceBranchEnvOverrides added in v0.2.0

func (db *DB) ListServiceBranchEnvOverrides(ctx context.Context, serviceName string) ([]ServiceBranchEnvOverride, error)

ListServiceBranchEnvOverrides returns every branch-scoped override declared for serviceName, across every branch pattern, ordered by branch pattern then key for a stable listing.

func (*DB) ListServiceDomains

func (db *DB) ListServiceDomains(ctx context.Context) ([]ServiceDomain, error)

ListServiceDomains returns every row in service_domains, ordered by domain. This is the same table domainOwner (domains.go) already queries for uniqueness enforcement, exposed here as a plain listing for GET /api/v1/domains rather than a single-domain lookup.

func (*DB) ListServiceEnvironmentDomains added in v0.2.0

func (db *DB) ListServiceEnvironmentDomains(ctx context.Context, name string) (map[string][]string, error)

ListServiceEnvironmentDomains returns name's per-environment domain sets, keyed by environment ID.

func (*DB) ListServiceLoadBalancers added in v0.2.0

func (db *DB) ListServiceLoadBalancers(ctx context.Context) (map[string]string, error)

ListServiceLoadBalancers returns every service's raw JSON config by name.

func (*DB) ListServiceVolumeBackupHistory

func (db *DB) ListServiceVolumeBackupHistory(ctx context.Context, serviceName, volumeName string, limit int, before *time.Time) ([]BackupHistory, error)

ListServiceVolumeBackupHistory returns up to limit backup attempts for serviceName's volumeName, newest first, the volume counterpart of ListBackupHistory. resource_kind is filtered explicitly (not merely implied by service_name/volume_name being non-empty) so this can never accidentally match a database row, however this schema evolves later.

func (*DB) ListServiceVolumeRestoreHistory

func (db *DB) ListServiceVolumeRestoreHistory(ctx context.Context, serviceName, volumeName string) ([]RestoreHistory, error)

ListServiceVolumeRestoreHistory returns every restore attempt for serviceName's volumeName, newest first, the volume counterpart of ListRestoreHistory.

func (*DB) ListServicesByApp

func (db *DB) ListServicesByApp(ctx context.Context, appID string) ([]DesiredService, error)

ListServicesByApp returns every service belonging to appID, ordered by name. This is the read side of stage 1 multi-service apps: an app's member services, for a group-status rollup or a detail view.

func (*DB) ListStalePreviewEnvironments

func (db *DB) ListStalePreviewEnvironments(ctx context.Context, cutoff time.Time) ([]PreviewEnvironment, error)

ListStalePreviewEnvironments returns every preview environment last updated before cutoff, oldest first: the TTL sweep's fallback path for a pull-request-closed webhook that never arrived (see internal/store/webhook_delivery.go's own reasoning for why that happens). String comparison against a UTC RFC3339Nano cutoff, the same convention ListWebhookDeliveries's own before-cursor already uses.

func (*DB) ListStaticSites

func (db *DB) ListStaticSites(ctx context.Context) ([]StaticSite, error)

ListStaticSites returns every saved static site, ordered by name. The ingress controller (internal/reconcile/ingress) calls this on every reconcile pass, the same "read fresh, never cached" treatment ListDesiredServices already gets.

func (*DB) ListStatusComponents added in v0.2.0

func (db *DB) ListStatusComponents(ctx context.Context) ([]StatusComponent, error)

ListStatusComponents returns components in display order.

func (*DB) ListStatusDaily added in v0.2.0

func (db *DB) ListStatusDaily(ctx context.Context, sinceDay string) ([]StatusDaily, error)

ListStatusDaily returns counters for every component from sinceDay (inclusive), oldest first.

func (*DB) ListStatusIncidentUpdates added in v0.2.0

func (db *DB) ListStatusIncidentUpdates(ctx context.Context) ([]StatusIncidentUpdate, error)

ListStatusIncidentUpdates returns every update, oldest first.

func (*DB) ListStatusIncidents added in v0.2.0

func (db *DB) ListStatusIncidents(ctx context.Context, limit int) ([]StatusIncident, error)

ListStatusIncidents returns incidents newest first, capped at limit.

func (*DB) ListStorageOptions added in v0.2.0

func (db *DB) ListStorageOptions(ctx context.Context) (map[string]StorageOptions, error)

ListStorageOptions returns every options row keyed by target ID.

func (*DB) ListSucceededBackups added in v0.2.0

func (db *DB) ListSucceededBackups(ctx context.Context) ([]BackupHistory, error)

ListSucceededBackups returns every succeeded backup newest first, for the per-resource health rollup.

func (*DB) ListSucceededVolumeBackups added in v0.2.0

func (db *DB) ListSucceededVolumeBackups(ctx context.Context, serviceName, volumeName string) ([]BackupHistory, error)

ListSucceededVolumeBackups returns every succeeded backup of one volume, newest first, with no paging: retention needs the whole set.

func (*DB) ListTags added in v0.2.0

func (db *DB) ListTags(ctx context.Context) ([]Tag, error)

ListTags returns every tag, alphabetical by name so a filter control's own option list doesn't need to sort it again client-side.

func (*DB) ListTagsForApp added in v0.2.0

func (db *DB) ListTagsForApp(ctx context.Context, appName string) ([]Tag, error)

ListTagsForApp returns every tag attached to appName, alphabetical by name, the same ordering ListTags uses.

func (*DB) ListTagsForApps added in v0.2.0

func (db *DB) ListTagsForApps(ctx context.Context, appNames []string) (map[string][]Tag, error)

ListTagsForApps batch-loads every tag attached to any app in appNames, keyed by app name, so GET /api/v1/apps can render tag chips on every row from one query instead of one ListTagsForApp call per app (the same N+1 GET .../deploys gap appListResource's own doc comment describes for status, avoided here the same way). An app with no tags simply has no key in the returned map.

func (*DB) ListTeamEvents added in v0.2.0

func (db *DB) ListTeamEvents(ctx context.Context, teamID string, limit int) ([]TeamEvent, error)

ListTeamEvents returns a team's newest events, at most limit.

func (*DB) ListTeamInvites added in v0.2.0

func (db *DB) ListTeamInvites(ctx context.Context, teamID string) ([]TeamInvite, error)

ListTeamInvites returns a team's invites, newest first.

func (*DB) ListTeamMembers added in v0.2.0

func (db *DB) ListTeamMembers(ctx context.Context, teamID string) ([]TeamMember, error)

ListTeamMembers returns a team's members, owners first.

func (*DB) ListTokenHygieneNotices added in v0.2.0

func (db *DB) ListTokenHygieneNotices(ctx context.Context) ([]TokenHygieneNotice, error)

ListTokenHygieneNotices returns every recorded notice, oldest first.

func (*DB) ListTrustedDevices added in v0.2.0

func (db *DB) ListTrustedDevices(ctx context.Context, userID string, now time.Time) ([]TrustedDevice, error)

ListTrustedDevices returns userID's live trusted devices, newest first.

func (*DB) ListUnacknowledgedUpgrades added in v0.2.0

func (db *DB) ListUnacknowledgedUpgrades(ctx context.Context) ([]UpgradeHistoryEntry, error)

ListUnacknowledgedUpgrades returns transitions nobody has acknowledged, newest first. This is the query the attention center consumes.

func (*DB) ListUpgradeHistory added in v0.2.0

func (db *DB) ListUpgradeHistory(ctx context.Context, limit int) ([]UpgradeHistoryEntry, error)

ListUpgradeHistory returns transitions newest first, at most limit rows.

func (*DB) ListUserEnvironmentGrants added in v0.2.0

func (db *DB) ListUserEnvironmentGrants(ctx context.Context, userID string) ([]string, error)

ListUserEnvironmentGrants returns the environment IDs granted to a user.

func (*DB) ListUserSecuritySettings added in v0.2.0

func (db *DB) ListUserSecuritySettings(ctx context.Context) ([]UserSecuritySettings, error)

ListUserSecuritySettings returns every account that has a stored row.

func (*DB) ListUsers

func (db *DB) ListUsers(ctx context.Context) ([]User, error)

ListUsers returns every user, oldest first.

func (*DB) ListVolumeCloneRestores

func (db *DB) ListVolumeCloneRestores(ctx context.Context, sourceServiceName, sourceVolumeName string) ([]VolumeCloneRestore, error)

ListVolumeCloneRestores returns every clone-restore attempt sourced from sourceServiceName/sourceVolumeName, newest first, mirroring ListCloneRestores exactly.

func (*DB) ListWebhookDeliveries

func (db *DB) ListWebhookDeliveries(ctx context.Context, serviceName string, limit int, before *time.Time) ([]WebhookDelivery, error)

ListWebhookDeliveries returns up to limit deliveries for serviceName, newest first. before, when non-nil, cursor-paginates on receipt time, mirroring ListBackupHistory/ListAuditEntries: a webhook receiver sees steady traffic over an app's lifetime, so this must never degrade into a slow OFFSET query as history grows.

func (*DB) LockLoginCode added in v0.2.0

func (db *DB) LockLoginCode(ctx context.Context, id string, now time.Time) (bool, error)

LockLoginCode kills a pending challenge after its last failed attempt and reports whether this call did it.

func (*DB) LockLoginCodesForUser added in v0.2.0

func (db *DB) LockLoginCodesForUser(ctx context.Context, userID string, now time.Time) ([]string, error)

LockLoginCodesForUser locks every pending challenge of userID and returns the ids it moved, so a credential reset leaves no code redeemable.

func (*DB) MarkDatabaseAccessUserRevoked added in v0.2.0

func (db *DB) MarkDatabaseAccessUserRevoked(ctx context.Context, database, role string, now time.Time) error

MarkDatabaseAccessUserRevoked retires a live record for a role.

func (*DB) MarkDomainAutomationRunUndone added in v0.2.0

func (db *DB) MarkDomainAutomationRunUndone(ctx context.Context, id string, at time.Time) error

MarkDomainAutomationRunUndone stamps a run as undone.

func (*DB) MarkMigrationItemTargetCreated added in v0.2.0

func (db *DB) MarkMigrationItemTargetCreated(ctx context.Context, sessionID, sourceDB, version string) error

MarkMigrationItemTargetCreated records that the hub created the managed database.

func (*DB) MarkModelDeleting added in v0.2.0

func (db *DB) MarkModelDeleting(ctx context.Context, name string) error

MarkModelDeleting tombstones the model for the controller to tear down.

func (*DB) MarkNodeJoinTokenUsed

func (db *DB) MarkNodeJoinTokenUsed(ctx context.Context, id string) error

MarkNodeJoinTokenUsed atomically marks id as exchanged, failing with ErrNodeJoinTokenAlreadyUsed if it already was: the conditional `WHERE used_at IS NULL` is what makes this safe under concurrent exchange attempts on the same token, the database deciding which caller wins rather than a check-then-act race in application code.

func (*DB) MarkOnboardingCompleted

func (db *DB) MarkOnboardingCompleted(ctx context.Context) error

MarkOnboardingCompleted sets onboarding_state.completed to true; it is never unset.

func (*DB) MarkProxyRouteFailed added in v0.2.0

func (db *DB) MarkProxyRouteFailed(ctx context.Context, domain, target, lastError string) error

MarkProxyRouteFailed records that domain's route could not be written.

func (*DB) MarkProxyRouteWritten added in v0.2.0

func (db *DB) MarkProxyRouteWritten(ctx context.Context, domain, target, fileName string, at time.Time, changed bool) error

MarkProxyRouteWritten records that domain's file now holds the current route. changed clears the last verification so the route is probed again.

func (*DB) MarkRolloutFailureReason added in v0.2.0

func (db *DB) MarkRolloutFailureReason(ctx context.Context, serviceName, image, reason string) error

MarkRolloutFailureReason stamps reason onto the newest succeeded or failed attempt that deployed (serviceName, image).

func (*DB) MarkTokenHygieneDisabled added in v0.2.0

func (db *DB) MarkTokenHygieneDisabled(ctx context.Context, tokenID string, now time.Time) error

MarkTokenHygieneDisabled records that the sweep revoked the token.

func (*DB) MigrationsCurrent added in v0.2.0

func (db *DB) MigrationsCurrent(ctx context.Context) error

MigrationsCurrent returns an error unless every embedded migration has been applied to this database.

func (*DB) MoveEnvironmentMembers added in v0.2.0

func (db *DB) MoveEnvironmentMembers(ctx context.Context, fromID, toID string) error

MoveEnvironmentMembers retags every app and database in fromID to toID in one transaction.

func (*DB) NextDeploySequence added in v0.2.0

func (db *DB) NextDeploySequence(ctx context.Context, serviceName string) (int64, error)

NextDeploySequence hands out serviceName's next trigger sequence, starting at 1. Sequences only grow, so a later trigger always sorts after an earlier one.

func (*DB) OwnerOfApp added in v0.2.0

func (db *DB) OwnerOfApp(ctx context.Context, name string) (*ResourceOwner, error)

OwnerOfApp returns the app's team and project, or nil when it does not exist.

func (*DB) OwnerOfDatabase added in v0.2.0

func (db *DB) OwnerOfDatabase(ctx context.Context, name string) (*ResourceOwner, error)

OwnerOfDatabase returns the database's team and project, or nil.

func (*DB) OwnersOfApps added in v0.2.0

func (db *DB) OwnersOfApps(ctx context.Context) (map[string]*ResourceOwner, error)

OwnersOfApps maps every app to its owner in one query.

func (*DB) OwnersOfDatabases added in v0.2.0

func (db *DB) OwnersOfDatabases(ctx context.Context) (map[string]*ResourceOwner, error)

OwnersOfDatabases maps every database to its owner in one query.

func (*DB) PipelineAppCounts added in v0.2.0

func (db *DB) PipelineAppCounts(ctx context.Context, since time.Time) ([]PipelineAppCounts, error)

PipelineAppCounts tallies runs per app: active runs and pending decisions regardless of age, finished runs since the given time.

func (*DB) ProjectTeams added in v0.2.0

func (db *DB) ProjectTeams(ctx context.Context) (map[string]string, error)

ProjectTeams maps every project to its owning team.

func (*DB) PruneAttentionState added in v0.2.0

func (db *DB) PruneAttentionState(ctx context.Context, cutoff time.Time) error

PruneAttentionState removes dismissals and expiry markers older than cutoff. Audit entries are never touched.

func (*DB) PruneBackupHistory

func (db *DB) PruneBackupHistory(ctx context.Context, databaseName string, keep int, olderThan time.Time) ([]PrunedBackup, error)

PruneBackupHistory deletes every succeeded backup_history row for databaseName that violates either retention limit: beyond the newest keep (ordered by started_at), or older than olderThan, and returns the TargetID/ObjectKey of every row removed. Only BackupStatusSucceeded rows are ever eligible: a running or failed attempt carries diagnostic value a retention limit was never meant to bound (an operator who sets retain: 7 wants "7 successful backups," not "7 attempts of any kind"), so those are left untouched regardless of how old they are.

keep <= 0 disables the count limit; a zero-value olderThan (the usual Go zero value, IsZero()) disables the age limit. Both disabled deletes nothing and returns (nil, nil) without issuing a query: this mirrors store.DesiredDatabase.BackupRetain/BackupRetainDays's own "0 means no limit for that dimension" meaning at the one call site that matters, internal/backup.Scheduler, rather than making every caller remember to guard the zero case itself.

Runs as a SELECT of the rows about to be removed followed by a DELETE in the same transaction, rather than a single DELETE ... RETURNING: this codebase's SQLite driver (modernc.org/sqlite) is not used with RETURNING anywhere else, so this avoids relying on unproven support. The transaction ensures the two statements observe the identical row set even though db.SetMaxOpenConns(1) (store.go) already serializes writes against this *sql.DB.

func (*DB) PruneKnownBrowsers added in v0.2.0

func (db *DB) PruneKnownBrowsers(ctx context.Context, cutoff time.Time) error

PruneKnownBrowsers forgets browsers not seen since cutoff.

func (*DB) PruneLoginCodes added in v0.2.0

func (db *DB) PruneLoginCodes(ctx context.Context, cutoff time.Time) error

PruneLoginCodes deletes resolved challenges and approvals older than cutoff.

func (*DB) PruneModelUsage added in v0.2.0

func (db *DB) PruneModelUsage(ctx context.Context, before time.Time) (int64, error)

PruneModelUsage deletes hourly rows older than before and reports how many.

func (*DB) PrunePipelineRuns added in v0.2.0

func (db *DB) PrunePipelineRuns(ctx context.Context, keep int) (int64, error)

PrunePipelineRuns deletes finished runs beyond the newest keep per pipeline and returns how many were removed.

func (*DB) PruneScheduledTaskRuns added in v0.2.0

func (db *DB) PruneScheduledTaskRuns(ctx context.Context, taskID string, keep int, outputCutoff time.Time) error

PruneScheduledTaskRuns keeps the newest keep runs of a task and blanks the output of runs started before outputCutoff (zero skips the output pass).

func (*DB) PruneServiceVolumeBackupHistory

func (db *DB) PruneServiceVolumeBackupHistory(ctx context.Context, serviceName, volumeName string, keep int, olderThan time.Time) ([]PrunedBackup, error)

PruneServiceVolumeBackupHistory is PruneBackupHistory's volume counterpart: identical retention logic (see that method's own doc comment for the count/age semantics), scoped to serviceName/volumeName and resource_kind = 'volume' instead of a single database_name.

func (*DB) PruneSignInAlertTokens added in v0.2.0

func (db *DB) PruneSignInAlertTokens(ctx context.Context, cutoff time.Time) error

PruneSignInAlertTokens deletes alert tokens that expired before cutoff.

func (*DB) PruneStatusDaily added in v0.2.0

func (db *DB) PruneStatusDaily(ctx context.Context, beforeDay string) error

PruneStatusDaily drops counters older than beforeDay.

func (*DB) PruneTrustedDevices added in v0.2.0

func (db *DB) PruneTrustedDevices(ctx context.Context, cutoff time.Time) error

PruneTrustedDevices deletes devices that expired or were revoked before cutoff.

func (*DB) RecordAppScheduleHistory added in v0.2.0

func (db *DB) RecordAppScheduleHistory(ctx context.Context, e AppScheduleHistoryEntry) error

RecordAppScheduleHistory inserts e, minting its ID and timestamps when unset.

func (*DB) RecordBuildCacheCleared added in v0.2.0

func (db *DB) RecordBuildCacheCleared(ctx context.Context, scope, at string) error

RecordBuildCacheCleared stamps a cache clear on an app scope.

func (*DB) RecordBuildCacheResult added in v0.2.0

func (db *DB) RecordBuildCacheResult(ctx context.Context, scope, at, result, warning string) error

RecordBuildCacheResult stores the outcome of the latest build that used the cache configured at scope (the row an app resolved to). A missing row is not an error.

func (*DB) RecordCPDRBackup added in v0.2.0

func (db *DB) RecordCPDRBackup(ctx context.Context, at time.Time, key, runErr string) error

RecordCPDRBackup records the outcome of one off-box backup attempt.

func (*DB) RecordCPDRDrill added in v0.2.0

func (db *DB) RecordCPDRDrill(ctx context.Context, at time.Time, ok, partial bool, detail string, ms int64) error

RecordCPDRDrill records the outcome of one restore drill.

func (*DB) RecordCPDREscrow added in v0.2.0

func (db *DB) RecordCPDREscrow(ctx context.Context, at time.Time) error

RecordCPDREscrow stamps escrow generation and clears any earlier acknowledgement.

func (*DB) RecordDatabaseAccessUser added in v0.2.0

func (db *DB) RecordDatabaseAccessUser(ctx context.Context, u DatabaseAccessUser) error

RecordDatabaseAccessUser inserts a live access user.

func (*DB) RecordGateEvent added in v0.2.0

func (db *DB) RecordGateEvent(ctx context.Context, e DeployGateEvent) error

RecordGateEvent stores e. With no DeployAttemptID it attaches to the newest succeeded or failed attempt that deployed (ServiceName, Image), and inserts nothing when there is none.

func (*DB) RecordImageAutoUpdateCheck added in v0.2.0

func (db *DB) RecordImageAutoUpdateCheck(ctx context.Context, serviceName, result string, at time.Time) error

RecordImageAutoUpdateCheck stores the outcome of the latest check.

func (*DB) RecordLogArchivePolicyRun added in v0.2.0

func (db *DB) RecordLogArchivePolicyRun(ctx context.Context, id, at string, watermarkNs int64, runErr string) error

RecordLogArchivePolicyRun stores the outcome of a scheduled run. The watermark only moves forward, so a failed window is retried.

func (*DB) RecordOrphanSighting added in v0.2.0

func (db *DB) RecordOrphanSighting(ctx context.Context, kind, nodeID, name string, at time.Time) error

RecordOrphanSighting stores the first sighting of a resource and keeps the original timestamp on every later call.

func (*DB) RecordPendingTeardownFailure added in v0.2.0

func (db *DB) RecordPendingTeardownFailure(ctx context.Context, name, cause string) error

RecordPendingTeardownFailure bumps the attempt count and stores cause.

func (*DB) RecordProbeAttempt added in v0.2.0

func (db *DB) RecordProbeAttempt(ctx context.Context, a ProbeAttempt) error

RecordProbeAttempt persists one probe attempt against the newest succeeded deploy_attempts row for (a.ServiceName, a.Image), the same resolution RecordRollout/RecordRolloutFailure already use since waitReady has no deploy_attempt_id of its own to pass in. Best-effort by design, matching RecordRollout's own no-match tolerance: a service/image pair that currently matches no such row inserts nothing rather than erroring.

func (*DB) RecordRollout added in v0.2.0

func (db *DB) RecordRollout(ctx context.Context, serviceName, image, state, runningImageID string) error

RecordRollout stamps what is actually running onto the newest succeeded attempt that deployed image. It is a no-op when nothing changed, so the reconciler can call it on every pass without write amplification.

func (*DB) RecordRolloutFailure added in v0.2.0

func (db *DB) RecordRolloutFailure(ctx context.Context, serviceName, image, reason string) error

RecordRolloutFailure flips the newest succeeded attempt that deployed image to failed: its container never passed readiness, so the "succeeded" recorded optimistically at trigger time no longer holds.

func (*DB) RecordScheduledTaskRun

func (db *DB) RecordScheduledTaskRun(ctx context.Context, id string, ranAt time.Time, status, output string) error

RecordScheduledTaskRun writes the outcome of one run (scheduled or manual "run now") back onto a task's own row: the same in-place "latest attempt" shape this table's own migration comment explains, not an append-only history. consecutive_failures resets to 0 on a success, stays unchanged on a skipped_concurrency or replaced outcome (neither one is a failure of the command itself, just a concurrency- policy side effect), and increments otherwise, computed in SQL rather than read-then-write so a concurrent run can't race it. Returns ErrScheduledTaskNotFound if id doesn't exist, e.g. the task was deleted between being picked up by a tick and this call.

func (*DB) RecordTeamEvent added in v0.2.0

func (db *DB) RecordTeamEvent(ctx context.Context, e TeamEvent) error

RecordTeamEvent appends to a team's audit trail.

func (*DB) RedeemLoginCode added in v0.2.0

func (db *DB) RedeemLoginCode(ctx context.Context, id string, now time.Time) (bool, error)

RedeemLoginCode moves a pending, unexpired challenge to redeemed. It reports false when another request already resolved it, so a code is usable exactly once.

func (*DB) ReenrollNodeCert added in v0.2.0

func (db *DB) ReenrollNodeCert(ctx context.Context, id string, c NodeCert, now time.Time) error

ReenrollNodeCert installs a certificate issued through a re-enrollment token: the previous certificate is dropped and any revocation cleared, since minting the token was the operator's authorization.

func (*DB) ReleaseCertStorageLock

func (db *DB) ReleaseCertStorageLock(ctx context.Context, name string) error

ReleaseCertStorageLock removes name's lock. Idempotent: releasing an already-released or never-held lock is not an error, matching DeleteNode's convention for the same reason (Unlock is often called from a defer alongside error paths that may have already cleaned up).

func (*DB) ReleaseDatabaseAccessUser added in v0.2.0

func (db *DB) ReleaseDatabaseAccessUser(ctx context.Context, id string) error

ReleaseDatabaseAccessUser returns a claimed record to active for the next pass.

func (*DB) RememberBrowser added in v0.2.0

func (db *DB) RememberBrowser(ctx context.Context, userID, fingerprint string, now time.Time) (isNew, hadAny bool, err error)

RememberBrowser records that userID signed in from fingerprint. It reports whether the browser was new and whether the account had any known browser.

func (*DB) RemoveTeamMember added in v0.2.0

func (db *DB) RemoveTeamMember(ctx context.Context, teamID, userID string) error

RemoveTeamMember deletes a membership, refusing to remove the last owner.

func (*DB) RenameOrganization added in v0.2.0

func (db *DB) RenameOrganization(ctx context.Context, id, name string) error

RenameOrganization changes a team's display name.

func (*DB) ReplaceDatabaseNetworkRuleNotes added in v0.2.0

func (db *DB) ReplaceDatabaseNetworkRuleNotes(ctx context.Context, database string, notes map[string]string) error

ReplaceDatabaseNetworkRuleNotes swaps a database's notes for notes.

func (*DB) ReplaceDeployFreezeWindows added in v0.2.0

func (db *DB) ReplaceDeployFreezeWindows(ctx context.Context, scope string, windows []DeployFreezeWindow) ([]DeployFreezeWindow, error)

ReplaceDeployFreezeWindows makes windows the complete set for scope. IDs are minted here; an empty windows clears the scope.

func (*DB) ReplaceLoginApproval added in v0.2.0

func (db *DB) ReplaceLoginApproval(ctx context.Context, a LoginApproval) ([]LoginApproval, error)

ReplaceLoginApproval supersedes a.UserID's open approvals and inserts a as the new pending one in one transaction, so at most one ever waits.

func (*DB) ReplaceSecretCiphertext added in v0.2.0

func (db *DB) ReplaceSecretCiphertext(ctx context.Context, serviceName, envKey string, old, replacement []byte) (bool, error)

ReplaceSecretCiphertext rewrites one value's ciphertext only if it still equals old, reporting whether it did. updated_at is left alone: re-encrypting the same value is not a rotation of it.

func (*DB) ReplaceServedHosts added in v0.2.0

func (db *DB) ReplaceServedHosts(ctx context.Context, hosts []string) error

ReplaceServedHosts records the hostnames the ingress layer now serves.

func (*DB) RequestPipelineRunCancel added in v0.2.0

func (db *DB) RequestPipelineRunCancel(ctx context.Context, id string) error

RequestPipelineRunCancel flags a non-terminal run for cancellation; the executor observes the flag on its next pass.

func (*DB) ReserveLoginCodeAttempt added in v0.2.0

func (db *DB) ReserveLoginCodeAttempt(ctx context.Context, id string, maxAttempts int) (attempt int, ok bool, err error)

ReserveLoginCodeAttempt spends one of a pending challenge's attempts before the code is compared, so parallel guesses can never exceed maxAttempts. It reports the attempt number, or ok false when the challenge is spent or gone.

func (*DB) ResolveAIChatConfirmation added in v0.2.0

func (db *DB) ResolveAIChatConfirmation(ctx context.Context, id, status string, result json.RawMessage, resolvedAt time.Time) error

ResolveAIChatConfirmation transitions a pending confirmation to approved or rejected, recording its execution result (nil for a rejection). Returns ErrAIChatConfirmationNotFound if id doesn't exist; resolving an already-resolved confirmation is idempotent at the SQL layer (the WHERE clause below doesn't gate on current status), the caller (internal/ai) is what enforces "only once" by checking Status before calling this.

func (*DB) ResolveServiceVolumeDockerName

func (db *DB) ResolveServiceVolumeDockerName(ctx context.Context, serviceName, volumeName string) (string, error)

ResolveServiceVolumeDockerName looks up serviceName and resolves volumeName to its real Docker volume name, the single DB-round-trip convenience ServiceVolumeDockerName's own callers that don't already have a DesiredService in hand need (internal/backup.Scheduler's own per-tick volume evaluation).

func (*DB) RestartModel added in v0.2.0

func (db *DB) RestartModel(ctx context.Context, name string) error

RestartModel bumps the restart nonce so the controller recreates the container.

func (*DB) RestartService

func (db *DB) RestartService(ctx context.Context, name string) error

RestartService is the only way restart_nonce ever changes: SaveDesiredService's own doc comment (and this field's own doc comment on DesiredService) explains why it's deliberately excluded from that method's full-record-replace semantics, the same reasoning UpdateServiceNode already establishes for NodeID.

The generated value is opaque and only ever compared for equality by internal/reconcile/application.ContainerName, never interpreted, so a short random hex string is enough; it does not need to be cryptographically unpredictable the way a session token or API key does, only different from whatever was there before.

func (*DB) RevokeAPIToken

func (db *DB) RevokeAPIToken(ctx context.Context, id string) error

RevokeAPIToken sets revoked_at on the named token. Idempotent: revoking an already-revoked token succeeds without error, matching DeleteDesiredService's "not found" sentinel shape for the one real failure case (no such token at all).

func (*DB) RevokeAgentTokens added in v0.2.0

func (db *DB) RevokeAgentTokens(ctx context.Context, internalName, internalAgent string) (int, error)

RevokeAgentTokens revokes every live token with an agent label, except the internal token the in-app assistant holds, and returns how many it revoked.

func (*DB) RevokeAllTrustedDevices added in v0.2.0

func (db *DB) RevokeAllTrustedDevices(ctx context.Context, userID string, now time.Time) (int, error)

RevokeAllTrustedDevices revokes every live device of userID and reports how many it revoked.

func (*DB) RevokeInvite

func (db *DB) RevokeInvite(ctx context.Context, id string) error

RevokeInvite marks the named invite revoked, only if it hasn't already been accepted or revoked. Returns ErrInviteNotFound, ErrInviteAlreadyAccepted, or ErrInviteAlreadyRevoked to say exactly why nothing changed, rather than a single ambiguous failure.

func (*DB) RevokeModelKey added in v0.2.0

func (db *DB) RevokeModelKey(ctx context.Context, model, id string, now time.Time) error

RevokeModelKey stops a key from authenticating immediately. Idempotent.

func (*DB) RevokeNodeCert added in v0.2.0

func (db *DB) RevokeNodeCert(ctx context.Context, id string, now time.Time) error

RevokeNodeCert marks the node's certificate revoked. Session and renewal refuse it from then on; only a re-enrollment token brings the node back.

func (*DB) RevokeTeamInvite added in v0.2.0

func (db *DB) RevokeTeamInvite(ctx context.Context, teamID, id string, now time.Time) error

RevokeTeamInvite revokes a pending invite of this team.

func (*DB) RevokeTrustedDevice added in v0.2.0

func (db *DB) RevokeTrustedDevice(ctx context.Context, userID, id string, now time.Time) (bool, error)

RevokeTrustedDevice revokes one of userID's devices and reports whether a live device was revoked. Another user's device id reads as not found.

func (*DB) RoleUserCounts added in v0.2.0

func (db *DB) RoleUserCounts(ctx context.Context) (map[string]int, error)

RoleUserCounts maps role ID to how many users hold it.

func (*DB) RotateModelAPIKey added in v0.2.0

func (db *DB) RotateModelAPIKey(ctx context.Context, name, hash, prefix string) error

RotateModelAPIKey replaces the model's default key at once, keeping the legacy hash and prefix on the model row in step.

func (*DB) RotateModelKey added in v0.2.0

func (db *DB) RotateModelKey(ctx context.Context, model, oldID string, next ModelKey, graceUntil *time.Time, now time.Time) error

RotateModelKey inserts next and retires the key oldID: it is revoked at once when graceUntil is nil, otherwise it keeps working until then.

func (*DB) RotateNodeCert added in v0.2.0

func (db *DB) RotateNodeCert(ctx context.Context, id, presentedFingerprint string, c NodeCert, grace time.Duration, now time.Time) error

RotateNodeCert records a renewal authenticated by presentedFingerprint. The presented certificate becomes the previous one, accepted until now+grace; a retry presenting the already-previous certificate keeps its original window rather than extending it.

func (*DB) RotateServiceDEKs

func (db *DB) RotateServiceDEKs(ctx context.Context, rewrap func(serviceName string, wrapped []byte) ([]byte, error)) error

RotateServiceDEKs reads every row in service_secrets, calls rewrap once per row, writes back whatever it returns, and records the rotation timestamp, all in one transaction: if rewrap returns an error for any row, nothing is written, matching DeleteServiceSecrets's own defer-rollback pattern. Callers (internal/secrets.RotateStoredDEKs) supply rewrap to do the actual unwrap-under-old-key/wrap-under-new-key work; this file only ever sees opaque bytes.

func (*DB) SaveAIChatConfirmation added in v0.2.0

func (db *DB) SaveAIChatConfirmation(ctx context.Context, c AIChatConfirmation) error

SaveAIChatConfirmation inserts a new, pending confirmation row.

func (*DB) SaveAIChatMessage added in v0.2.0

func (db *DB) SaveAIChatMessage(ctx context.Context, m AIChatMessage) error

SaveAIChatMessage inserts a new message row and bumps its session's updated_at in the same transaction.

func (*DB) SaveAPIToken

func (db *DB) SaveAPIToken(ctx context.Context, t APIToken) error

SaveAPIToken inserts a new token row. Tokens are never updated in place after creation except for LastUsedAt (TouchAPITokenLastUsed) and RevokedAt (RevokeAPIToken): a token's name and abilities are fixed at mint time, matching every competitor's own token model researched for this feature (rotation means minting a new token and revoking the old, not editing an existing one).

func (*DB) SaveApp

func (db *DB) SaveApp(ctx context.Context, a App) error

SaveApp creates or fully replaces an app row, keyed by ID. Matches SaveDesiredService's full-record-replace semantics, not SaveProject's insert-only ones: like a service, an app has an UpdatedAt an ordinary edit is expected to move forward.

func (*DB) SaveAppImportItem added in v0.2.0

func (db *DB) SaveAppImportItem(ctx context.Context, it AppImportItem, now time.Time) error

SaveAppImportItem inserts or replaces one item.

func (*DB) SaveAppIntegration added in v0.2.0

func (db *DB) SaveAppIntegration(ctx context.Context, ai AppIntegration) error

SaveAppIntegration inserts a new app integration row. ID is minted by the caller (internal/api), the same "generate before the INSERT" pattern SaveScheduledTask uses. Returns ErrAppIntegrationAlreadyAttached if serviceName already has integrationKey attached.

func (*DB) SaveAppStream added in v0.2.0

func (db *DB) SaveAppStream(ctx context.Context, s AppStream) error

SaveAppStream inserts a new app stream row. IDs are minted by the caller before this call, the same "generate before the INSERT" pattern FirewallRule uses.

func (*DB) SaveAppliedConfig added in v0.2.0

func (db *DB) SaveAppliedConfig(ctx context.Context, c AppliedConfig) error

SaveAppliedConfig replaces name's applied config snapshot.

func (*DB) SaveAuditEntry

func (db *DB) SaveAuditEntry(ctx context.Context, e AuditEntry) error

SaveAuditEntry inserts a new audit log row. Insert-only, like SaveDeployAttempt: an audit log has no update or delete path through the app, an entry ID is minted fresh by every caller, and a duplicate ID would only ever indicate a caller bug, left to fail on the primary key constraint rather than silently overwriting history.

func (*DB) SaveBackupTarget

func (db *DB) SaveBackupTarget(ctx context.Context, t BackupTarget) error

SaveBackupTarget inserts a new backup target row. IDs are minted by the caller (internal/api, the same "generate before the INSERT" pattern api_token/node join tokens already use) so the caller can store credentials under the same ID before or after this call without a round trip to discover what ID got assigned.

func (*DB) SaveBitbucketAppConnection

func (db *DB) SaveBitbucketAppConnection(ctx context.Context, c BitbucketAppConnection) error

SaveBitbucketAppConnection inserts or replaces the single bitbucket_app_connections row (id=1).

func (*DB) SaveCertStorageValue

func (db *DB) SaveCertStorageValue(ctx context.Context, key string, value []byte) error

SaveCertStorageValue writes value at key, creating or overwriting. Backs certmagic.Storage's Store method (internal/ingress): Caddy's TLS automation calls this to persist ACME account keys, issued certificates, and OCSP staples.

func (*DB) SaveCodeLoginSettings added in v0.2.0

func (db *DB) SaveCodeLoginSettings(ctx context.Context, s CodeLoginSettings) error

SaveCodeLoginSettings stores the settings row.

func (*DB) SaveCustomTemplate added in v0.2.0

func (db *DB) SaveCustomTemplate(ctx context.Context, t CustomTemplate) error

SaveCustomTemplate inserts a new custom template row. IDs are minted by the caller (internal/api, the same "generate before the INSERT" pattern SaveBackupTarget's own doc comment establishes), prefixed so they can never collide with a internal/catalog slug (see internal/api/service_templates.go's resolveTemplate).

func (*DB) SaveCutoverRun added in v0.2.0

func (db *DB) SaveCutoverRun(ctx context.Context, r CutoverRun) error

SaveCutoverRun replaces a run's mutable fields.

func (*DB) SaveDBUpgradePolicy added in v0.2.0

func (db *DB) SaveDBUpgradePolicy(ctx context.Context, p DBUpgradePolicy) error

SaveDBUpgradePolicy creates or replaces a policy row.

func (*DB) SaveDatabaseAccessSettings added in v0.2.0

func (db *DB) SaveDatabaseAccessSettings(ctx context.Context, s DatabaseAccessSettings) error

SaveDatabaseAccessSettings inserts or replaces a database's settings.

func (*DB) SaveDatabaseQuery added in v0.2.0

func (db *DB) SaveDatabaseQuery(ctx context.Context, q DatabaseSavedQuery) (DatabaseSavedQuery, error)

SaveDatabaseQuery creates a saved query, or ErrSavedQueryExists when the name is taken.

func (*DB) SaveDeployApproval added in v0.2.0

func (db *DB) SaveDeployApproval(ctx context.Context, a DeployApproval) error

SaveDeployApproval inserts a new deploy_approvals row, insert-only: a decision is recorded with the dedicated Approve/RejectDeployApproval methods below, never by re-inserting.

func (*DB) SaveDeployAttempt

func (db *DB) SaveDeployAttempt(ctx context.Context, a DeployAttempt) error

SaveDeployAttempt inserts a new deploy attempt row. Unlike SaveDesiredService, this is insert-only, never an upsert: an attempt ID is minted fresh by every trigger call (NewDeployAttemptID), so a second SaveDeployAttempt for the same ID would only ever indicate a caller bug, not a legitimate retry, and is left to fail on the primary key constraint rather than silently overwriting history.

func (*DB) SaveDeploySafetySettings added in v0.2.0

func (db *DB) SaveDeploySafetySettings(ctx context.Context, s DeploySafetySettings) error

SaveDeploySafetySettings replaces s.ServiceName's overrides.

func (*DB) SaveDesiredDatabase

func (db *DB) SaveDesiredDatabase(ctx context.Context, d DesiredDatabase) error

SaveDesiredDatabase creates or fully replaces the desired state for a named database, the same whole-record-replacement semantics as SaveDesiredService, including the identical NodeID exception SaveDesiredService's own doc comment explains.

func (*DB) SaveDesiredService

func (db *DB) SaveDesiredService(ctx context.Context, svc DesiredService) error

SaveDesiredService creates or fully replaces the desired state for a named service. There's no partial update: a service's desired state is always written as a whole record, matching how it'll actually be produced (a deploy pipeline resolving a complete DesiredService from one app.yaml service block, not assembling one field at a time).

One deliberate exception: NodeID is never written by this method, only ever by UpdateServiceNode below. internal/deploy.Pipeline calls this on every ordinary redeploy without ever setting NodeID (it has no opinion on placement), and svc.NodeID passed in here is always silently ignored, not just on an update but even on the very first INSERT: a new service starts on the local node ("") until an operator explicitly places it elsewhere via UpdateServiceNode, and a redeploy of an already-placed service must never un-assign it from wherever that placement decision put it.

The whole write, including reconciling svc.Domains against the service_domains table (0011), happens in one transaction: either the service's desired state and its domain claims both land, or neither does. Returns *ErrDomainTaken (via errors.As) if any domain in svc.Domains is already claimed by a different service; the caller's entire desired-state write is rejected in that case, not partially applied with some domains silently dropped.

func (*DB) SaveDesiredServiceOrdered added in v0.2.0

func (db *DB) SaveDesiredServiceOrdered(ctx context.Context, svc DesiredService, order DeployOrder, check DeployOrderCheck) error

SaveDesiredServiceOrdered is SaveDesiredService guarded by check, in one transaction: check sees the cursor as of this write, and on success the cursor advances to order. Manual orders keep the last automatic commit so a later stale webhook is still judged against real commit history.

func (*DB) SaveDomainAutomationRun added in v0.2.0

func (db *DB) SaveDomainAutomationRun(ctx context.Context, r DomainAutomationRun) error

SaveDomainAutomationRun records a run.

func (*DB) SaveEnvironment

func (db *DB) SaveEnvironment(ctx context.Context, e Environment) error

SaveEnvironment inserts a new environment row, insert-only.

func (*DB) SaveExportDestination added in v0.2.0

func (db *DB) SaveExportDestination(ctx context.Context, d ExportDestination) error

SaveExportDestination inserts a destination.

func (*DB) SaveExportStatus added in v0.2.0

func (db *DB) SaveExportStatus(ctx context.Context, s ExportStatus) error

SaveExportStatus upserts the delivery state of a destination.

func (*DB) SaveExposureRestriction added in v0.2.0

func (db *DB) SaveExposureRestriction(ctx context.Context, r ExposureRestriction) error

SaveExposureRestriction inserts or replaces the restriction for a port.

func (*DB) SaveFeatureFlag

func (db *DB) SaveFeatureFlag(ctx context.Context, f FeatureFlag) error

SaveFeatureFlag inserts a new feature flag row. ID is minted by the caller (internal/api), the same "generate before the INSERT" pattern SaveScheduledTask's own doc comment establishes.

func (*DB) SaveFirewallRule added in v0.2.0

func (db *DB) SaveFirewallRule(ctx context.Context, r FirewallRule) error

SaveFirewallRule inserts a new firewall rule row. IDs are minted by the caller before this call, the same "generate before the INSERT" pattern RegistryCredential uses.

func (*DB) SaveGitHubAppConnection

func (db *DB) SaveGitHubAppConnection(ctx context.Context, c GitHubAppConnection) error

SaveGitHubAppConnection inserts or replaces the single github_app_connections row (id=1). Called once, right after a successful manifest code exchange (internal/api's handleGitHubAppCallback): InstallationID and AccountLogin are always nil at this point, since installation happens in a separate, later redirect. INSERT OR REPLACE rather than a plain INSERT: a second registration (after a prior connection was removed via DeleteGitHubAppConnection) must succeed without a caller having to know whether a row already exists.

func (*DB) SaveGitLabAppConnection

func (db *DB) SaveGitLabAppConnection(ctx context.Context, c GitLabAppConnection) error

SaveGitLabAppConnection inserts or replaces the single gitlab_app_connections row (id=1).

func (*DB) SaveGitSource

func (db *DB) SaveGitSource(ctx context.Context, g GitSource) error

SaveGitSource creates a service's git source, or fully replaces it if one already exists: unlike SaveBackupTarget/SaveProject (insert-only, no legitimate "same id, different contents" case), PUT /api/v1/apps/{name}/git-source (internal/api) is a real connect-or-edit-the-connection endpoint, so this is an upsert, the same shape SaveSecretValue already uses for rotating a secret's value. created_at is left untouched by the ON CONFLICT branch, so it reflects when the source was first connected even across later edits.

func (*DB) SaveGiteaAppConnection added in v0.2.0

func (db *DB) SaveGiteaAppConnection(ctx context.Context, c GiteaAppConnection) error

SaveGiteaAppConnection inserts or replaces the single gitea_app_connections row (id=1).

func (*DB) SaveInvite

func (db *DB) SaveInvite(ctx context.Context, inv Invite) error

SaveInvite inserts a new invite row.

func (*DB) SaveManagedDNSRecord added in v0.2.0

func (db *DB) SaveManagedDNSRecord(ctx context.Context, r ManagedDNSRecord) error

SaveManagedDNSRecord inserts or replaces the record tracked for (domain, record type).

func (*DB) SaveModel added in v0.2.0

func (db *DB) SaveModel(ctx context.Context, m Model) error

SaveModel inserts a new model row and its default API key.

func (*DB) SaveNetworkShare added in v0.2.0

func (db *DB) SaveNetworkShare(ctx context.Context, s NetworkShare) error

SaveNetworkShare inserts a new network share row. IDs are minted by the caller before this call, the same "generate before the INSERT" pattern RegistryCredential uses.

func (*DB) SaveNode

func (db *DB) SaveNode(ctx context.Context, n Node) error

SaveNode inserts a new node row. Unlike SaveDesiredService, this is insert-only: a node's identity (ID, name) is fixed at enrollment time, there is no "replace this node's full record" operation, matching how SaveAPIToken (0007) never updates a token in place either. Status transitions go through UpdateNodeStatus, heartbeats through TouchNodeLastSeen, both narrower and safer than a caller re-supplying a whole Node struct on every heartbeat.

On an INSERT failure, this re-checks whether name is already taken (via nodeNameExists) to distinguish ErrNodeNameTaken from a genuine, unrelated database error, rather than parsing the driver's own error type: the same "let the constraint decide, then classify by re-checking" shape store.CreateUser's own doc comment already establishes for a different unique-constraint conflict.

func (*DB) SaveNodeDrain added in v0.2.0

func (db *DB) SaveNodeDrain(ctx context.Context, d NodeDrain) error

SaveNodeDrain persists a drain's mutable fields.

func (*DB) SaveNodeJoinToken

func (db *DB) SaveNodeJoinToken(ctx context.Context, t NodeJoinToken) error

SaveNodeJoinToken inserts a new join token row.

func (*DB) SaveNodeMove added in v0.2.0

func (db *DB) SaveNodeMove(ctx context.Context, m NodeMove) error

SaveNodeMove persists every mutable field of an existing move.

func (*DB) SaveNodeProvision added in v0.2.0

func (db *DB) SaveNodeProvision(ctx context.Context, p NodeProvision) error

SaveNodeProvision inserts a new node provision row. IDs are minted by the caller before this call, the same "generate before the INSERT" pattern BackupTarget/RegistryCredential use.

func (*DB) SaveOAuthIdentity

func (db *DB) SaveOAuthIdentity(ctx context.Context, i OAuthIdentity) error

SaveOAuthIdentity inserts a new linked identity, insert-only, never an upsert.

func (*DB) SaveOrganization

func (db *DB) SaveOrganization(ctx context.Context, o Organization) error

SaveOrganization inserts a new organization row, insert-only like SaveProject.

func (*DB) SavePipeline added in v0.2.0

func (db *DB) SavePipeline(ctx context.Context, p Pipeline) (Pipeline, error)

SavePipeline inserts p, or replaces the YAML, enabled flag, and sync bookkeeping of the existing pipeline with the same app and name. The stored row is returned.

func (*DB) SavePipelineSync added in v0.2.0

func (db *DB) SavePipelineSync(ctx context.Context, s PipelineSync) error

SavePipelineSync upserts the sync state for s.AppName.

func (*DB) SavePolicy

func (db *DB) SavePolicy(ctx context.Context, p Policy) error

SavePolicy creates a new policy. Policies are never updated in place except via UpdatePolicy (name/description/document); unlike SaveAPIToken this genuinely is meant to change over the policy's life, since a policy document is the whole point of editing one, unlike a token's fixed-at-mint-time abilities. On failure it re-checks by name to classify the cause, the same pattern CreateUser uses for its own unique constraint.

func (*DB) SavePolicyVersion added in v0.2.0

func (db *DB) SavePolicyVersion(ctx context.Context, policyID, name, description, document, actor string) error

SavePolicyVersion records the policy's current document as the next version.

func (*DB) SavePreviewAppSettings added in v0.2.0

func (db *DB) SavePreviewAppSettings(ctx context.Context, s PreviewAppSettings) error

SavePreviewAppSettings upserts an app's policy.

func (*DB) SavePreviewDatabaseIsolation added in v0.2.0

func (db *DB) SavePreviewDatabaseIsolation(ctx context.Context, p PreviewDatabaseIsolation) error

SavePreviewDatabaseIsolation inserts a new tracking row.

func (*DB) SavePreviewEnvironment

func (db *DB) SavePreviewEnvironment(ctx context.Context, p PreviewEnvironment) error

SavePreviewEnvironment inserts a new preview environment row. Insert-only: a fresh (app_name, pr_number) pair always mints a new ID, see UpdatePreviewEnvironment for the redeploy-on-synchronize path.

func (*DB) SavePreviewEphemeralDatabase added in v0.2.0

func (db *DB) SavePreviewEphemeralDatabase(ctx context.Context, p PreviewEphemeralDatabase) error

SavePreviewEphemeralDatabase inserts a new tracking row. Insert-only: callers look the row up first (GetPreviewEphemeralDatabaseByPreviewAndKey) and only call this on a genuine miss, the same idempotent-creation shape deployPreviewEnvironment already uses for preview_environments itself, so a PR synchronize event that re-runs provisioning never mints a second row for the same (preview, source key) pair.

func (*DB) SaveProject

func (db *DB) SaveProject(ctx context.Context, p Project) error

SaveProject inserts a new project row. IDs are minted by the caller (internal/api's randomProjectID), the same "generate before the INSERT" pattern SaveBackupTarget already establishes, and this is insert-only, never an upsert: a project's name is a pure label with no addressing role (migrations/0022_projects.sql's own comment on why it isn't UNIQUE), so there is no legitimate "same id, replace contents" case the way SaveDesiredService's full-replace semantics exist for.

func (*DB) SaveProxyRouteVerification added in v0.2.0

func (db *DB) SaveProxyRouteVerification(ctx context.Context, s ProxyRouteStatus) error

SaveProxyRouteVerification stores a probe outcome for an already tracked domain. A domain removed meanwhile is left untracked.

func (*DB) SavePushSubscription added in v0.2.0

func (db *DB) SavePushSubscription(ctx context.Context, s PushSubscription) error

SavePushSubscription inserts a new subscription, or replaces the existing row for the same endpoint: a browser re-subscribing (a permission reset, a cleared service worker) must overwrite its own stale keys rather than accumulate a dead duplicate alongside them.

func (*DB) SaveRegistryCredential

func (db *DB) SaveRegistryCredential(ctx context.Context, c RegistryCredential) error

SaveRegistryCredential inserts a new registry credential row. IDs are minted by the caller before this call, the same "generate before the INSERT" pattern BackupTarget uses.

func (*DB) SaveRollbackPin added in v0.2.0

func (db *DB) SaveRollbackPin(ctx context.Context, p RollbackPin) error

SaveRollbackPin records p, replacing any earlier pin for the same attempt.

func (*DB) SaveSSHNodeProvision added in v0.2.0

func (db *DB) SaveSSHNodeProvision(ctx context.Context, p SSHNodeProvision) error

SaveSSHNodeProvision inserts a new SSH node provision row. IDs are minted by the caller before this call, the same "generate before the INSERT" pattern NodeProvision uses.

func (*DB) SaveScheduledTask

func (db *DB) SaveScheduledTask(ctx context.Context, t ScheduledTask) error

SaveScheduledTask inserts a new scheduled task row. ID is minted by the caller (internal/api, the same "generate before the INSERT" pattern SaveBackupTarget's own doc comment establishes), and the last-run fields start empty: a freshly created task has never run.

func (*DB) SaveSecretValue

func (db *DB) SaveSecretValue(ctx context.Context, serviceName, envKey string, ciphertext []byte) error

SaveSecretValue creates or replaces the ciphertext for one env var of one service. Unlike SaveServiceDEK this is a real upsert: updating a secret's value (rotating it) is the normal case, updating its DEK is not.

func (*DB) SaveSecurityPolicy added in v0.2.0

func (db *DB) SaveSecurityPolicy(ctx context.Context, p SecurityPolicy) error

SaveSecurityPolicy replaces the stored policy row.

func (*DB) SaveServiceDEK

func (db *DB) SaveServiceDEK(ctx context.Context, serviceName string, wrappedDEK []byte) error

SaveServiceDEK creates a service's wrapped DEK. Called once per service, the first time a secret value is set for it: internal/secrets. Manager checks GetServiceDEK first and only calls this on ErrServiceDEKNotFound, so this intentionally has no upsert path. A service's DEK, once generated, is never replaced: replacing it would silently orphan every value already encrypted under the old one.

func (*DB) SaveSessionLinkToken added in v0.2.0

func (db *DB) SaveSessionLinkToken(ctx context.Context, t SessionLinkToken) error

SaveSessionLinkToken inserts a new session-link-token row.

func (*DB) SaveStaticSite

func (db *DB) SaveStaticSite(ctx context.Context, site StaticSite) error

SaveStaticSite creates or fully replaces a static site's desired state, the same "whole record, one write" shape SaveDesiredService uses for container services: internal/deploy.Pipeline always produces a complete StaticSite from one app.yaml service block, never a partial update.

The whole write, including reconciling site.Domains against static_site_domains, happens in one transaction: either the site's state and its domain claims both land, or neither does. Returns *ErrDomainTaken (via errors.As) if any domain in site.Domains is already claimed by a different static site or by a container service (domainOwner checks both service_domains and static_site_domains); the caller's entire write is rejected in that case, matching SaveDesiredService's own domain-conflict behavior.

func (*DB) SaveStatusComponent added in v0.2.0

func (db *DB) SaveStatusComponent(ctx context.Context, c StatusComponent) error

SaveStatusComponent creates or replaces a component.

func (*DB) SaveStatusIncident added in v0.2.0

func (db *DB) SaveStatusIncident(ctx context.Context, i StatusIncident) error

SaveStatusIncident creates or replaces an incident.

func (*DB) SaveStatusPageSettings added in v0.2.0

func (db *DB) SaveStatusPageSettings(ctx context.Context, s StatusPageSettings) error

SaveStatusPageSettings replaces the settings row.

func (*DB) SaveStorageOptions added in v0.2.0

func (db *DB) SaveStorageOptions(ctx context.Context, o StorageOptions) error

SaveStorageOptions upserts the options row for a backup target.

func (*DB) SaveTag added in v0.2.0

func (db *DB) SaveTag(ctx context.Context, t Tag) error

SaveTag inserts a new tag row. ID is minted by the caller (internal/api), the same "generate before the INSERT" pattern SaveFeatureFlag's own doc comment establishes. On a name conflict it re-checks by name to classify the failure, the same pattern CreateUser's own doc comment establishes for a different unique constraint.

func (*DB) SaveTokenHygieneNotice added in v0.2.0

func (db *DB) SaveTokenHygieneNotice(ctx context.Context, n TokenHygieneNotice) error

SaveTokenHygieneNotice records a notice; an existing one keeps its time.

func (*DB) SaveWebhookDelivery

func (db *DB) SaveWebhookDelivery(ctx context.Context, d WebhookDelivery) error

SaveWebhookDelivery inserts a new webhook delivery row, truncating d.Payload to MaxWebhookDeliveryPayloadBytes if larger (setting PayloadTruncated on the stored row regardless of what the caller passed in): this is the one place that cap is enforced, so no caller can accidentally bypass it.

func (*DB) ServedHosts added in v0.2.0

func (db *DB) ServedHosts(ctx context.Context) (hosts []string, known bool, err error)

ServedHosts returns the last recorded hostnames. known is false until the ingress layer has applied a config at least once.

func (*DB) SetAPITokenScope added in v0.2.0

func (db *DB) SetAPITokenScope(ctx context.Context, s APITokenScope) error

SetAPITokenScope records a token's team scope.

func (*DB) SetAppSchedule added in v0.2.0

func (db *DB) SetAppSchedule(ctx context.Context, serviceName, cronExpr, branch, timezone string, enabled bool) error

SetAppSchedule upserts serviceName's schedule. next_fire_at always resets to NULL: cron/branch/timezone may have just changed, so any previously armed time was computed against config that no longer applies. The scheduler re-arms it, unfired, on its next tick, the same "a freshly armed schedule never fires on sight" rule it applies to a schedule it is seeing for the first time.

func (*DB) SetAppSleepHold added in v0.2.0

func (db *DB) SetAppSleepHold(ctx context.Context, serviceName string, hold bool, now time.Time) error

SetAppSleepHold turns function mode on or off for an app that has a sleep setting.

func (*DB) SetAppSleepIdle added in v0.2.0

func (db *DB) SetAppSleepIdle(ctx context.Context, serviceName string, minutes int, now time.Time) error

SetAppSleepIdle enables (minutes > 0) or disables (0) sleeping and resets the idle baseline.

func (*DB) SetAppSleeping added in v0.2.0

func (db *DB) SetAppSleeping(ctx context.Context, serviceName string, sleeping bool, now time.Time) error

SetAppSleeping records that serviceName went to sleep or woke, and resets the idle baseline.

func (*DB) SetBackupSealInfo added in v0.2.0

func (db *DB) SetBackupSealInfo(ctx context.Context, id, codec, manifestDigest string, files, bytes int64) error

SetBackupSealInfo records how a succeeded backup object was encoded and its content manifest.

func (*DB) SetBackupTargetProtection added in v0.2.0

func (db *DB) SetBackupTargetProtection(ctx context.Context, p BackupTargetProtection) error

SetBackupTargetProtection upserts a probe result.

func (*DB) SetCPDRInstallID added in v0.2.0

func (db *DB) SetCPDRInstallID(ctx context.Context, id string) error

SetCPDRInstallID stores the install id once; an existing id is kept.

func (*DB) SetCanaryRelease added in v0.2.0

func (db *DB) SetCanaryRelease(ctx context.Context, c CanaryRelease) error

SetCanaryRelease creates or replaces serviceName's canary row.

func (*DB) SetDashboardURL added in v0.2.0

func (db *DB) SetDashboardURL(ctx context.Context, u string) error

SetDashboardURL stores the public dashboard URL; "" clears it.

func (*DB) SetDatabaseBackupSchedule

func (db *DB) SetDatabaseBackupSchedule(ctx context.Context, name, targetID, schedule string, retain, retainDays int) error

SetDatabaseBackupSchedule is DesiredDatabase's counterpart to UpdateDatabaseNode/UpdateDatabaseProject: a scheduled backup's config is set through its own endpoint and its own method, the same separation-from-ordinary-desired-state-saves those two already establish, rather than folding it into SaveDesiredDatabase's own whole-record replace. Passing targetID="" and schedule="" (the DELETE /api/v1/databases/{name}/backup-schedule path, retain also forced to 0 by the caller in that case) clears scheduled backups for name entirely: internal/backup.Scheduler's own ListScheduledDatabases query treats an empty schedule exactly like it was never configured, so this is a real "unset," not a sentinel every future caller has to remember to special-case.

func (*DB) SetDatabaseEnvironment added in v0.2.0

func (db *DB) SetDatabaseEnvironment(ctx context.Context, databaseName, envID string) error

SetDatabaseEnvironment assigns or clears (envID == "") a database's environment, returning ErrDatabaseNotFound for an unknown name.

func (*DB) SetDatabasePITR added in v0.2.0

func (db *DB) SetDatabasePITR(ctx context.Context, name string, enabled bool, enabledAt string) error

SetDatabasePITR turns point-in-time restore on or off for name. enabledAt is the caller-supplied "now" (UTC, RFC3339) to record as PITREnabledAt when enabled is true; ignored (and the stored value left untouched) when enabled is false, so disabling and re-enabling later doesn't lose the original enable time a caller might still want for display. internal/reconcile/database reads PITREnabled on every reconcile pass to decide whether to run this database's container with WAL archiving on; internal/api's PITR handlers call this, never SaveDesiredDatabase, the same one-writer-per-special-field convention NodeID/BackupSchedule/Suspended above already establish.

func (*DB) SetDatabasePublicAccess

func (db *DB) SetDatabasePublicAccess(ctx context.Context, name string, enabled bool, requestedPort int, requestedBindAddress string) (int, error)

SetDatabasePublicAccess is DesiredDatabase's counterpart to SetDatabaseBackupSchedule: its own endpoint (PUT/DELETE /api/v1/databases/{name}/public-access), its own store method, same separation-from-ordinary-update reasoning. Disabling (enabled=false) always clears public_port and public_bind_address back to NULL regardless of requestedPort/requestedBindAddress. Enabling with requestedPort 0 auto-assigns the lowest free port in [PublicPortRangeStart, PublicPortRangeEnd]; a non-zero requestedPort is used as-is if no other database already claims it. requestedBindAddress empty resolves to DefaultBindAddress ("private"), the same "resolve and always persist a concrete value" treatment SaveDesiredService gives BindAddress. Returns the port actually assigned (0 when disabling).

Runs inside a transaction so "is this port free" and "claim it" are atomic: db.SetMaxOpenConns(1) (store.go) already serializes every write against this same *sql.DB, so this is a correctness backstop against nothing racing it today, not a fix for an observed bug, the same reasoning claimServiceDomains (service.go) already applies to domain claims.

func (*DB) SetDeployAttemptCacheWarning added in v0.2.0

func (db *DB) SetDeployAttemptCacheWarning(ctx context.Context, id, warning string) error

SetDeployAttemptCacheWarning records why a build ran without its remote cache.

func (*DB) SetDeployAttemptCommit added in v0.2.0

func (db *DB) SetDeployAttemptCommit(ctx context.Context, id, image, commitSHA string) error

SetDeployAttemptCommit re-points a still-running attempt at the commit its checkout resolved to, for a trigger given a branch or tag rather than a hash. Image must be the tag actually built, since a rollback deploys this row's image by name.

func (*DB) SetDeployAttemptDigest added in v0.2.0

func (db *DB) SetDeployAttemptDigest(ctx context.Context, id, digest, reason string) error

SetDeployAttemptDigest records the content identity an attempt resolved to.

func (*DB) SetDeployAttemptReason added in v0.2.0

func (db *DB) SetDeployAttemptReason(ctx context.Context, id, reason string) error

SetDeployAttemptReason records why an attempt was held, superseded or allowed through a freeze.

func (*DB) SetDomainAutomationRaw added in v0.2.0

func (db *DB) SetDomainAutomationRaw(ctx context.Context, raw string) error

SetDomainAutomationRaw stores the policy JSON.

func (*DB) SetDomainBasicAuth

func (db *DB) SetDomainBasicAuth(ctx context.Context, domain, username string) error

SetDomainBasicAuth upserts the username claimed for domain. Callers (internal/api) are expected to write the matching password through internal/secrets in the same request; this method only ever tracks the username, never a credential.

func (*DB) SetDomainErrorPage added in v0.2.0

func (db *DB) SetDomainErrorPage(ctx context.Context, domain string, statusCode int, body string) error

SetDomainErrorPage upserts one status-code-to-body mapping for domain. statusCode and body must already be validated by the caller (internal/api); this method performs no validation of its own, the same division of responsibility store.SetDomainRedirect draws.

func (*DB) SetDomainHidden added in v0.2.0

func (db *DB) SetDomainHidden(ctx context.Context, domain string, hidden bool) error

SetDomainHidden hides or unhides domain from search engines. Idempotent.

func (*DB) SetDomainMaintenance

func (db *DB) SetDomainMaintenance(ctx context.Context, domain string) error

SetDomainMaintenance enables maintenance mode for domain. Idempotent: setting it on a domain that already has it enabled is not an error.

func (*DB) SetDomainRedirect added in v0.2.0

func (db *DB) SetDomainRedirect(ctx context.Context, domain, targetURL string, statusCode int) error

SetDomainRedirect upserts domain's redirect configuration. targetURL and statusCode must already be validated by the caller (internal/api); this method performs no validation of its own, the same division of responsibility store.SetDomainWAF already draws with its own caller.

func (*DB) SetDomainTLSCert

func (db *DB) SetDomainTLSCert(ctx context.Context, domain string, uploadedAt, expiresAt time.Time) error

SetDomainTLSCert upserts the uploaded/expiry timestamps for domain's BYO certificate. Callers (internal/api) are expected to write the matching certificate and key through internal/secrets in the same request; this method only ever tracks metadata, never key material.

func (*DB) SetDomainTrafficPolicy added in v0.2.0

func (db *DB) SetDomainTrafficPolicy(ctx context.Context, domain, kind string, spec []byte) error

SetDomainTrafficPolicy upserts domain's spec for kind.

func (*DB) SetDomainWAF added in v0.2.0

func (db *DB) SetDomainWAF(ctx context.Context, domain string, wafEnabled bool, mode string, rateLimitRPS, rateLimitBurst int) error

SetDomainWAF upserts domain's WAF/rate-limit configuration. mode must already be validated by the caller (internal/api); this method performs no validation of its own, the same division of responsibility store.SetDomainBasicAuth already draws with its own caller.

func (*DB) SetEnvironmentEnvVars

func (db *DB) SetEnvironmentEnvVars(ctx context.Context, environmentID string, vars map[string]string) error

SetEnvironmentEnvVars full-replaces environmentID's shared env vars with vars, the same "replace, don't diff" semantics SetOrganizationEnvVars/SetProjectEnvVars already establish.

func (*DB) SetEnvironmentProtected

func (db *DB) SetEnvironmentProtected(ctx context.Context, id string, protected bool) error

SetEnvironmentProtected updates one environment's protected flag. Returns ErrEnvironmentNotFound if id doesn't match any row.

func (*DB) SetEnvironmentSecretEnvVar added in v0.2.0

func (db *DB) SetEnvironmentSecretEnvVar(ctx context.Context, environmentID, key string) error

SetEnvironmentSecretEnvVar marks key as a secret-backed shared env var for environmentID, mirroring SetProjectSecretEnvVar.

func (*DB) SetExternalDatabaseHealth added in v0.2.0

func (db *DB) SetExternalDatabaseHealth(ctx context.Context, name, status, reason string, latencyMs int, checkedAt time.Time) error

SetExternalDatabaseHealth records the latest probe outcome.

func (*DB) SetForgeDeploymentState added in v0.2.0

func (db *DB) SetForgeDeploymentState(ctx context.Context, id, state, warning string, at time.Time) error

SetForgeDeploymentState updates a deployment's state and warning.

func (*DB) SetGitSourceBuild added in v0.2.0

func (db *DB) SetGitSourceBuild(ctx context.Context, serviceName, buildType, buildPath, baseDirectory string) error

SetGitSourceBuild replaces only a connected source's build settings, so a build-settings edit never rewrites its token, services or trigger mode.

func (*DB) SetGitSourceDeploySettings added in v0.2.0

func (db *DB) SetGitSourceDeploySettings(ctx context.Context, serviceName string, paths, pathsIgnore []string, reportStatus bool) error

SetGitSourceDeploySettings replaces a connected source's deploy path filters and status reporting flag; it returns ErrGitSourceNotFound if no source is connected for serviceName.

func (*DB) SetGitSourcePostPRComments

func (db *DB) SetGitSourcePostPRComments(ctx context.Context, serviceName string, enabled bool) error

SetGitSourcePostPRComments toggles a connected git source's GitHub PR comment/commit status opt-in (GitSource.PostPRComments's own doc comment); returns ErrGitSourceNotFound if no source is connected for serviceName. Mirrors SetGitSourcePreviewEnabled exactly, its own sibling opt-in toggle.

func (*DB) SetGitSourcePreviewEnabled

func (db *DB) SetGitSourcePreviewEnabled(ctx context.Context, serviceName string, enabled bool) error

SetGitSourcePreviewEnabled toggles a connected git source's preview environments opt-in; returns ErrGitSourceNotFound if no source is connected for serviceName. A separate setter rather than a SaveGitSource field, the same "an ordinary edit must never silently move it" shape UpdateServiceSuspended already establishes for DesiredService.Suspended.

func (*DB) SetImageAutoUpdate added in v0.2.0

func (db *DB) SetImageAutoUpdate(ctx context.Context, serviceName string, enabled bool) error

SetImageAutoUpdate enables or disables auto-update for serviceName.

func (*DB) SetImageAutoUpdateWebhookHash added in v0.2.0

func (db *DB) SetImageAutoUpdateWebhookHash(ctx context.Context, serviceName, hash string) error

SetImageAutoUpdateWebhookHash stores the hash of serviceName's registry webhook token; empty clears it.

func (*DB) SetLBUpstreamAdminState added in v0.2.0

func (db *DB) SetLBUpstreamAdminState(ctx context.Context, service string, replica int, state string) error

SetLBUpstreamAdminState stores the admin state for one replica. The state "active" removes the row; the service must exist.

func (*DB) SetMigrationItemPlan added in v0.2.0

func (db *DB) SetMigrationItemPlan(ctx context.Context, sessionID, sourceDB, targetName, targetVersion string, selected bool) error

SetMigrationItemPlan stores the operator's selection, name and version.

func (*DB) SetMigrationItemStatus added in v0.2.0

func (db *DB) SetMigrationItemStatus(ctx context.Context, sessionID, sourceDB, status, reason string, checked, mismatched int, detail string, now time.Time) error

SetMigrationItemStatus records progress or the outcome of one item's copy.

func (*DB) SetMigrationStep added in v0.2.0

func (db *DB) SetMigrationStep(ctx context.Context, id, step string, now time.Time) error

SetMigrationStep records the furthest step a session reached.

func (*DB) SetModelEndpoint added in v0.2.0

func (db *DB) SetModelEndpoint(ctx context.Context, name, dial string) error

SetModelEndpoint records the address the gateway proxies to. Empty clears it.

func (*DB) SetModelHFTokenSet added in v0.2.0

func (db *DB) SetModelHFTokenSet(ctx context.Context, name string, set bool) error

SetModelHFTokenSet records whether a HuggingFace token secret exists.

func (*DB) SetModelResidency added in v0.2.0

func (db *DB) SetModelResidency(ctx context.Context, name, residency string, idleTTLSeconds int, now time.Time) error

SetModelResidency sets the residency mode and idle TTL. Switching to on-demand counts as activity so the model does not sleep at once; switching to always clears any asleep state so the reconciler starts it.

func (*DB) SetModelResidencyState added in v0.2.0

func (db *DB) SetModelResidencyState(ctx context.Context, name, state string) error

SetModelResidencyState records the reconciler-observed residency state.

func (*DB) SetModelSwapGroup added in v0.2.0

func (db *DB) SetModelSwapGroup(ctx context.Context, name, group string) error

SetModelSwapGroup sets the swap group name; empty clears it.

func (*DB) SetNodeGPU added in v0.2.0

func (db *DB) SetNodeGPU(ctx context.Context, nodeID string, info gpu.Info) error

SetNodeGPU upserts a node's GPU snapshot.

func (*DB) SetNodeLabels added in v0.2.0

func (db *DB) SetNodeLabels(ctx context.Context, nodeID string, labels map[string]string) error

SetNodeLabels replaces a node's whole label set.

func (*DB) SetNodeSchedulable

func (db *DB) SetNodeSchedulable(ctx context.Context, id string, schedulable bool) error

SetNodeSchedulable cordons (schedulable=false) or uncordons (schedulable=true) a node. Returns ErrNodeNotFound if no such node exists, the same "distinguish real failure from a no-op" rigor UpdateNodeStatus applies to its own conditional UPDATE. Does not touch Status and does not evacuate anything already running there: cordon on its own only affects new placements (internal/api's handleSetAppNode and handleDrainNode both check Schedulable before accepting a target node), see this package's own Node.Schedulable doc comment for why that's a separate column from Status in the first place.

func (*DB) SetOnboardingProgress added in v0.2.0

func (db *DB) SetOnboardingProgress(ctx context.Context, currentStep string, steps map[string]string) error

SetOnboardingProgress stores the wizard's current step and per-step status.

func (*DB) SetOrganizationEnvVars

func (db *DB) SetOrganizationEnvVars(ctx context.Context, orgID string, vars map[string]string) error

SetOrganizationEnvVars full-replaces orgID's shared env vars with vars, the same "replace, don't diff" semantics SetProjectEnvVars already establishes one tier down.

func (*DB) SetOrganizationSecretEnvVar added in v0.2.0

func (db *DB) SetOrganizationSecretEnvVar(ctx context.Context, orgID, key string) error

SetOrganizationSecretEnvVar marks key as a secret-backed shared env var for orgID, mirroring SetProjectSecretEnvVar one tier up.

func (*DB) SetPipelineEnabled added in v0.2.0

func (db *DB) SetPipelineEnabled(ctx context.Context, id string, enabled bool, now time.Time) error

SetPipelineEnabled flips a pipeline's enabled flag.

func (*DB) SetPipelineJobOutputs added in v0.2.0

func (db *DB) SetPipelineJobOutputs(ctx context.Context, id, outputsJSON string) error

SetPipelineJobOutputs stores a job's JSON-encoded outputs.

func (*DB) SetPipelineJobStatus added in v0.2.0

func (db *DB) SetPipelineJobStatus(ctx context.Context, id, status, reason, nodeID string, attempt int, started, finished *time.Time) error

SetPipelineJobStatus updates a job's status, reason, node, and attempt. started and finished are recorded when non-nil.

func (*DB) SetPipelineRunReport added in v0.2.0

func (db *DB) SetPipelineRunReport(ctx context.Context, id, provider, state, url, warning string) error

SetPipelineRunReport records the outcome of the latest status post for a run. A blank provider, state or url keeps the value already stored; the warning is always replaced so a later success clears an earlier failure.

func (*DB) SetPipelineRunStatus added in v0.2.0

func (db *DB) SetPipelineRunStatus(ctx context.Context, id, status, reason string, started, finished *time.Time) error

SetPipelineRunStatus moves a run to status with a reason. started and finished, when non-nil, are recorded; existing values are kept otherwise.

func (*DB) SetPipelineStepStatus added in v0.2.0

func (db *DB) SetPipelineStepStatus(ctx context.Context, jobID string, idx int, status, reason string, exitCode *int, attempt int, started, finished *time.Time) error

SetPipelineStepStatus updates one step's status, reason, exit code, and attempt. started and finished are recorded when non-nil.

func (*DB) SetPlacementSelector added in v0.2.0

func (db *DB) SetPlacementSelector(ctx context.Context, kind, resource string, selector map[string]string) error

SetPlacementSelector replaces the selector of one app or database.

func (*DB) SetPreviewEnvironmentCommentID added in v0.2.0

func (db *DB) SetPreviewEnvironmentCommentID(ctx context.Context, id string, commentID int64) error

SetPreviewEnvironmentCommentID records the provider comment ID of a preview's status comment without touching any other column.

func (*DB) SetPreviewEnvironmentExtendedUntil added in v0.2.0

func (db *DB) SetPreviewEnvironmentExtendedUntil(ctx context.Context, id, until string) error

SetPreviewEnvironmentExtendedUntil records an operator-granted expiry for a preview without touching any other column.

func (*DB) SetPreviousReleaseHeldUntil added in v0.2.0

func (db *DB) SetPreviousReleaseHeldUntil(ctx context.Context, name string, until time.Time) error

SetPreviousReleaseHeldUntil records when name's held previous release is due for removal; the zero time clears it.

func (*DB) SetProjectEnvVars

func (db *DB) SetProjectEnvVars(ctx context.Context, projectID string, vars map[string]string) error

SetProjectEnvVars full-replaces projectID's shared env vars with vars: every key not present in vars is removed, every key in vars is written, in one transaction, the same "replace, don't diff" shape SaveDesiredService's own claimServiceDomains uses for a service's domain set. There is no partial-update path; a caller wanting to add one key reads the current set first (ListProjectEnvVars) and sends the whole merged map back.

func (*DB) SetProjectOrganization

func (db *DB) SetProjectOrganization(ctx context.Context, projectID, orgID string) error

SetProjectOrganization assigns or clears (orgID == "") a project's organization. Returns ErrProjectNotFound if the project doesn't exist.

func (*DB) SetProjectSecretEnvVar added in v0.2.0

func (db *DB) SetProjectSecretEnvVar(ctx context.Context, projectID, key string) error

SetProjectSecretEnvVar marks key as a secret-backed shared env var for projectID, upserting a placeholder row (is_secret = 1, value = ”). The plaintext itself is never passed here: callers encrypt it separately via internal/secrets.Manager.SetValue under ProjectEnvSecretsKey(projectID), the same split SaveServiceDEK/ SaveSecretValue already keep from this table's own row. Unlike SetProjectEnvVars this is a single-key upsert, not a full replace, so it can never clobber the project's other vars, secret or not.

func (*DB) SetRequireNewDeviceApproval added in v0.2.0

func (db *DB) SetRequireNewDeviceApproval(ctx context.Context, userID string, on bool, now time.Time) error

SetRequireNewDeviceApproval stores userID's own approval switch.

func (*DB) SetSecretLocked

func (db *DB) SetSecretLocked(ctx context.Context, serviceName, envKey string, locked bool) error

SetSecretLocked sets (serviceName, envKey)'s locked flag, either direction: unlike Coolify's permanent lock, this is meant to be reversible. Returns ErrSecretValueNotFound if no value has been set for that key yet, matching GetSecretValue's own not-found sentinel: locking is a property of a value that already exists, not something pre-settable before one does.

func (*DB) SetServiceAutoRollbackOnCrashloop added in v0.2.0

func (db *DB) SetServiceAutoRollbackOnCrashloop(ctx context.Context, name string, enabled bool) error

SetServiceAutoRollbackOnCrashloop is the only way auto_rollback_on_crashloop ever changes, the same "own single-purpose setter, excluded from SaveDesiredService" reasoning UpdateServiceNode/ UpdateServiceProject/UpdateServiceStorageTarget/UpdateServiceSuspended already establish.

func (*DB) SetServiceAutoRollbackOnSLOBurn added in v0.2.0

func (db *DB) SetServiceAutoRollbackOnSLOBurn(ctx context.Context, name, mode string) error

SetServiceAutoRollbackOnSLOBurn is the only way auto_rollback_on_slo_burn ever changes, the same "own single-purpose setter, excluded from SaveDesiredService" reasoning SetServiceAutoRollbackOnCrashloop already establishes. mode must be one of the AutoRollbackSLOBurn* constants; the caller (handleSetAutoRollbackSLOBurn) validates that before calling this.

func (*DB) SetServiceBadgeEnabled added in v0.2.0

func (db *DB) SetServiceBadgeEnabled(ctx context.Context, name string, enabled bool) error

SetServiceBadgeEnabled is the only way badge_enabled ever changes, the same "own single-purpose setter, excluded from SaveDesiredService" reasoning SetServiceExecEnabled already establishes.

func (*DB) SetServiceBranchEnvOverride added in v0.2.0

func (db *DB) SetServiceBranchEnvOverride(ctx context.Context, serviceName, branchPattern, key, value string, secret bool) (string, error)

SetServiceBranchEnvOverride upserts one branch-scoped env var override for serviceName, keyed on (serviceName, branchPattern, key). value is ignored (stored as "") when secret is true: the caller (internal/api) is responsible for encrypting the real value via internal/secrets.Manager under BranchEnvOverrideSecretsKey before or after this call, the same split SetEnvironmentSecretEnvVar and handleSetSharedEnvSecret already establish between "mark secret" and "store ciphertext." Returns the row's id, minting a new one only on first insert; an existing row keeps its own id across updates.

func (*DB) SetServiceCancelSuperseded added in v0.2.0

func (db *DB) SetServiceCancelSuperseded(ctx context.Context, name string, enabled bool) error

SetServiceCancelSuperseded is the only way cancel_superseded changes, following the single-purpose setter convention of the other per-app flags.

func (*DB) SetServiceDatabaseEnvVar added in v0.2.0

func (db *DB) SetServiceDatabaseEnvVar(ctx context.Context, name, envVar string, ref *DatabaseEnvRef) error

SetServiceDatabaseEnvVar adds or replaces (ref non-nil) or removes (ref nil) exactly one entry in name's DatabaseEnv map, the narrow single-key mutation POST/DELETE /api/v1/apps/{name}/connections needs for an app to declare more than one database connection without app.yaml. Same read-modify-write-in-one-transaction shape as SetServiceVaultEnvVar just above, since DatabaseEnv is a JSON blob (like VaultEnv), not one column per key; DatabaseAttachment remains its own single-slot field with its own setter (UpdateServiceDatabaseAttachment), untouched by this method.

func (*DB) SetServiceEnvironment

func (db *DB) SetServiceEnvironment(ctx context.Context, serviceName, envID string) error

SetServiceEnvironment assigns or clears (envID == "") a service's environment. Returns ErrServiceNotFound if the service doesn't exist.

func (*DB) SetServiceExecEnabled added in v0.2.0

func (db *DB) SetServiceExecEnabled(ctx context.Context, name string, enabled bool) error

SetServiceExecEnabled is the only way exec_enabled ever changes, the same "own single-purpose setter, excluded from SaveDesiredService" reasoning SetServiceAutoRollbackOnCrashloop and UpdateServiceNode/UpdateServiceProject/UpdateServiceStorageTarget/ UpdateServiceSuspended already establish.

func (*DB) SetServiceLoadBalancer added in v0.2.0

func (db *DB) SetServiceLoadBalancer(ctx context.Context, service, configJSON string) error

SetServiceLoadBalancer upserts the JSON config; the service must exist.

func (*DB) SetServicePreviewEnvOverride added in v0.2.0

func (db *DB) SetServicePreviewEnvOverride(ctx context.Context, name, envVar string, value *string) error

SetServicePreviewEnvOverride sets or clears one preview-specific env var override on name's own desired state (migrations/0098), the only way preview_env_overrides ever changes: SaveDesiredService's own doc comment explains why this is deliberately excluded from that method's full-record-replace semantics, the same reasoning SetServiceVaultEnvVar already establishes for vault_env. value nil clears the override.

func (*DB) SetServiceSecretEnvDeclared added in v0.2.0

func (db *DB) SetServiceSecretEnvDeclared(ctx context.Context, name, key string, declared bool) (bool, error)

SetServiceSecretEnvDeclared adds (declared) or removes key from name's secret-backed env names without touching any other column, and reports whether the set changed. An existing entry keeps its Required flag.

func (*DB) SetServiceVaultEnvVar added in v0.2.0

func (db *DB) SetServiceVaultEnvVar(ctx context.Context, name, envVar string, ref *VaultEnvRef) error

SetServiceVaultEnvVar adds or replaces (ref non-nil) or removes (ref nil) exactly one entry in name's VaultEnv map, the narrow single-key mutation PUT/DELETE /api/v1/apps/{name}/vault-env/{key} needs. Unlike SaveDesiredService's own full-record-replace semantics, this never touches any other field: VaultEnv is a JSON blob (like SecretEnv, DatabaseEnv), not one column per key, so adding or removing a single entry needs a read-modify-write, done here inside one transaction so a concurrent call for a different key on the same service can never silently lose the other's write.

func (*DB) SetServiceVolumeBackupSchedule

func (db *DB) SetServiceVolumeBackupSchedule(ctx context.Context, serviceName, volumeName, targetID, schedule string, retain, retainDays int, sqlitePath string) error

SetServiceVolumeBackupSchedule upserts serviceName/volumeName's backup schedule config, the volume counterpart of SetDatabaseBackupSchedule (database.go). Passing targetID="" and schedule="" clears it back to "not scheduled", the same "" sentinel SetDatabaseBackupSchedule already establishes: internal/backup.Scheduler's own ListScheduledServiceVolumes query treats an empty schedule exactly like the row was never written.

func (*DB) SetTeamMemberRole added in v0.2.0

func (db *DB) SetTeamMemberRole(ctx context.Context, teamID, userID, role string) error

SetTeamMemberRole changes a member's role, refusing to demote the last owner.

func (*DB) SetUserEnvironmentGrants added in v0.2.0

func (db *DB) SetUserEnvironmentGrants(ctx context.Context, userID string, environmentIDs []string) error

SetUserEnvironmentGrants replaces a user's grants atomically.

func (*DB) SetUserRole added in v0.2.0

func (db *DB) SetUserRole(ctx context.Context, userID, roleID string) error

SetUserRole assigns a role and copies its abilities onto the user in one transaction, so the abilities the gate enforces never drift from the role.

func (*DB) SetVolumeBackupPolicy added in v0.2.0

func (db *DB) SetVolumeBackupPolicy(ctx context.Context, p VolumeBackupPolicy) error

SetVolumeBackupPolicy upserts a volume's policy.

func (*DB) SleepModel added in v0.2.0

func (db *DB) SleepModel(ctx context.Context, name string) error

SleepModel marks a model idle at once by clearing its activity.

func (*DB) SnapshotTo added in v0.2.0

func (db *DB) SnapshotTo(ctx context.Context, dest string) (size int64, sum string, err error)

SnapshotTo writes a consistent copy of the live database to dest using VACUUM INTO, verifies it with integrity_check, and returns its size and sha256. dest must not exist; it only appears once the copy is verified.

func (*DB) StartAppVolumeMove added in v0.2.0

func (db *DB) StartAppVolumeMove(ctx context.Context, m AppVolumeMove) error

StartAppVolumeMove records a move attempt beginning, status BackupStatusRunning with an empty step list, mirroring StartVolumeCloneRestore's own shape.

func (*DB) StartBackupDrill added in v0.2.0

func (db *DB) StartBackupDrill(ctx context.Context, d BackupDrill) error

StartBackupDrill writes a running drill row.

func (*DB) StartBackupHistory

func (db *DB) StartBackupHistory(ctx context.Context, h BackupHistory) error

StartBackupHistory records a backup attempt beginning, status BackupStatusRunning, before the dump or upload has done any real work: see this file's own status-constants comment for why "running" is written eagerly rather than only recording success/failure after the fact. h.ResourceKind defaults to BackupResourceKindDatabase when empty, so every existing caller (database backups, which never set it) keeps writing the identical row shape it always has.

func (*DB) StartBackupVerification

func (db *DB) StartBackupVerification(ctx context.Context, v BackupVerification) error

StartBackupVerification records a verification attempt beginning, status BackupVerificationStatusRunning, the same "write running first" reasoning this file's own status-constants comment gives.

func (*DB) StartBaseBackupHistory added in v0.2.0

func (db *DB) StartBaseBackupHistory(ctx context.Context, h BaseBackupHistory) error

StartBaseBackupHistory records a base backup attempt beginning, status BackupStatusRunning, the same "write running before any real work happens" discipline StartBackupHistory's own doc comment explains for logical dumps.

func (*DB) StartCloneRestore

func (db *DB) StartCloneRestore(ctx context.Context, h CloneRestore) error

StartCloneRestore records a clone-restore attempt beginning, status BackupStatusRunning, before the new database has even become reachable: the same "write running eagerly" reasoning StartRestoreHistory's own doc comment gives.

func (*DB) StartMajorUpgrade added in v0.2.0

func (db *DB) StartMajorUpgrade(ctx context.Context, u MajorUpgrade) error

StartMajorUpgrade records an upgrade attempt as running.

func (*DB) StartPITRRestoreHistory added in v0.2.0

func (db *DB) StartPITRRestoreHistory(ctx context.Context, h PITRRestoreHistory) error

StartPITRRestoreHistory records a PITR restore attempt beginning, status BackupStatusRunning, the same "write running before any real work happens" discipline StartRestoreHistory's own doc comment explains.

func (*DB) StartQueuedDeployAttempt added in v0.2.0

func (db *DB) StartQueuedDeployAttempt(ctx context.Context, id string, now time.Time) (bool, error)

StartQueuedDeployAttempt moves a queued attempt to running and stamps its real start time. Reports whether it moved, so two drainers never both start it.

func (*DB) StartRestoreHistory

func (db *DB) StartRestoreHistory(ctx context.Context, h RestoreHistory) error

StartRestoreHistory records a restore attempt beginning, status BackupStatusRunning, before the download or restore has done any real work: the same "write running eagerly so a mid-attempt crash leaves a real row behind" reasoning StartBackupHistory's own doc comment gives. h.ResourceKind defaults to BackupResourceKindDatabase when empty, mirroring StartBackupHistory's own identical default.

func (*DB) StartVolumeCloneRestore

func (db *DB) StartVolumeCloneRestore(ctx context.Context, h VolumeCloneRestore) error

StartVolumeCloneRestore records a clone-restore attempt beginning, status BackupStatusRunning, mirroring StartCloneRestore exactly.

func (*DB) StatCertStorageValue

func (db *DB) StatCertStorageValue(ctx context.Context, key string) (*CertStorageKeyInfo, error)

StatCertStorageValue returns key's metadata, or ErrCertStorageKeyNotFound if key is stored neither as an exact value nor as a directory prefix of other keys.

func (*DB) SumBackupUsage added in v0.2.0

func (db *DB) SumBackupUsage(ctx context.Context) ([]BackupUsage, error)

SumBackupUsage totals succeeded backup bytes per database or app volume.

func (*DB) SupersedeLoginApprovals added in v0.2.0

func (db *DB) SupersedeLoginApprovals(ctx context.Context, userID string, now time.Time) ([]LoginApproval, error)

SupersedeLoginApprovals retires every pending or approved-but-unused approval of userID, so none can still collect a session, and returns the ones this call moved.

func (*DB) SupersedeQueuedDeployAttempt added in v0.2.0

func (db *DB) SupersedeQueuedDeployAttempt(ctx context.Context, id, by string, now time.Time) (bool, error)

SupersedeQueuedDeployAttempt marks a still-queued attempt as replaced by a newer one. Reports whether it moved; a started attempt is never touched.

func (*DB) SyncNodeCertDetails added in v0.2.0

func (db *DB) SyncNodeCertDetails(ctx context.Context, id, fingerprint, serial string, notAfter time.Time) error

SyncNodeCertDetails records the real expiry and serial of the node's current certificate, replacing the estimate migration 0135 backfilled. A no-op when fingerprint is not the current certificate.

func (*DB) SyncRoleAbilities added in v0.2.0

func (db *DB) SyncRoleAbilities(ctx context.Context, roleID string) error

SyncRoleAbilities rewrites the abilities of every user holding the role to the role's current set.

func (*DB) SyncSpecScheduledTasks added in v0.2.0

func (db *DB) SyncSpecScheduledTasks(ctx context.Context, serviceName string, jobs []ScheduledTask, now time.Time, newID func() (string, error)) error

SyncSpecScheduledTasks makes the spec-sourced jobs of a service match jobs (keyed by Name): new ones are inserted, existing ones updated in place (keeping ID and history), and spec-sourced jobs no longer listed are deleted. Jobs created through the API are never touched.

func (*DB) TeamMemberRole added in v0.2.0

func (db *DB) TeamMemberRole(ctx context.Context, teamID, userID string) (string, error)

TeamMemberRole returns the user's role in the team, or ErrTeamMemberNotFound.

func (*DB) TeamOfEnvironment added in v0.2.0

func (db *DB) TeamOfEnvironment(ctx context.Context, environmentID string) (ResourceOwner, error)

TeamOfEnvironment returns the team and project owning an environment.

func (*DB) TeamOfProject added in v0.2.0

func (db *DB) TeamOfProject(ctx context.Context, projectID string) (string, error)

TeamOfProject returns the team owning a project, or ErrProjectNotFound.

func (*DB) TouchAPITokenLastUsed

func (db *DB) TouchAPITokenLastUsed(ctx context.Context, id string) error

TouchAPITokenLastUsed updates last_used_at to now. Best-effort by design: internal/api calls this on every successful bearer-token lookup for observability, but a failure here must never block the request it's authenticating, so callers log and continue rather than fail the request on error.

func (*DB) TouchCertStorageLock

func (db *DB) TouchCertStorageLock(ctx context.Context, name string) error

TouchCertStorageLock refreshes name's lock's updated_at to now, so a live holder's lock never looks stale to a competitor calling AcquireCertStorageLock. Best-effort by design, matching TouchNodeLastSeen and TouchAPITokenLastUsed: a missed refresh is not itself fatal to the holder's in-progress operation, only a risk that a competitor could (rarely) steal the lock early if staleAfter is also exceeded, which is an accepted, documented trade-off of the whole staleness-based design (see 0010's migration comment).

func (*DB) TouchModel added in v0.2.0

func (db *DB) TouchModel(ctx context.Context, name string, at time.Time) error

TouchModel records gateway activity (or a wake request) without touching updated_at, which tracks configuration changes.

func (*DB) TouchModelKeys added in v0.2.0

func (db *DB) TouchModelKeys(ctx context.Context, used map[string]time.Time) error

TouchModelKeys records last-use times, keeping the later of the stored and given value.

func (*DB) TouchNodeLastSeen

func (db *DB) TouchNodeLastSeen(ctx context.Context, id string) error

TouchNodeLastSeen updates last_seen_at to now, best-effort by design matching TouchAPITokenLastUsed: a heartbeat recording failure must never block whatever triggered it. Called once at session start (Server.Session) and repeatedly on a fixed interval for as long as that session's stream stays open (Server.heartbeatLoop): a single call at connect time can't distinguish "still connected" from "connected an hour ago, then the process hung," which is exactly the case internal/reconcile/nodehealth needs to detect.

func (*DB) TouchTrustedDevice added in v0.2.0

func (db *DB) TouchTrustedDevice(ctx context.Context, id string, now time.Time) error

TouchTrustedDevice records a sign-in from a trusted device.

func (*DB) TransferTeamOwnership added in v0.2.0

func (db *DB) TransferTeamOwnership(ctx context.Context, teamID, from, to string) error

TransferTeamOwnership makes to an owner and from an admin, atomically.

func (*DB) TransitionDeployAttempt added in v0.2.0

func (db *DB) TransitionDeployAttempt(ctx context.Context, id, from, to, reason string) (bool, error)

TransitionDeployAttempt moves an attempt from one status to another only if it is still in from, so two releasers can never both act on it. A terminal to status also stamps finished_at. Reports whether it moved.

func (*DB) UpdateAIAssistantSettings added in v0.2.0

func (db *DB) UpdateAIAssistantSettings(ctx context.Context, s AIAssistantSettings) error

UpdateAIAssistantSettings replaces the single ai_assistant_settings row in full, the same whole-record convention UpdateEmailSettings uses.

func (*DB) UpdateAIChatMessageToolCalls added in v0.2.0

func (db *DB) UpdateAIChatMessageToolCalls(ctx context.Context, messageID string, toolCalls []AIChatToolCall) error

UpdateAIChatMessageToolCalls replaces an existing message's tool_calls column in place, used once a pending confirmation resolves (the assistant message row that proposed it is updated with the outcome, see internal/ai's applyConfirmationResult).

func (*DB) UpdateAIControlSettings added in v0.2.0

func (db *DB) UpdateAIControlSettings(ctx context.Context, mode string, kinds []string, updatedBy string) error

UpdateAIControlSettings replaces the mode and allowed environment kinds.

func (*DB) UpdateAppImportSession added in v0.2.0

func (db *DB) UpdateAppImportSession(ctx context.Context, s AppImportSession, now time.Time) error

UpdateAppImportSession stores the step, collision mode and mappings.

func (*DB) UpdateAppVolumeMoveSteps added in v0.2.0

func (db *DB) UpdateAppVolumeMoveSteps(ctx context.Context, id string, steps []AppVolumeMoveStep) error

UpdateAppVolumeMoveSteps overwrites a running move's step list: called after every step starts and again after it finishes, so a caller polling GetAppVolumeMove mid-flight sees real progress, not just a final result.

func (*DB) UpdateBackupTarget

func (db *DB) UpdateBackupTarget(ctx context.Context, id, name, provider, endpoint, region, bucket string) error

UpdateBackupTarget replaces name/provider/endpoint/region/bucket for an existing row, the same full-replace contract UpdateScheduledTask uses. Credentials are not this function's concern: a caller rotating them writes to internal/secrets separately, under the same BackupTargetSecretsKey(id) this row's ID has always used. Returns ErrBackupTargetNotFound if id doesn't exist.

func (*DB) UpdateCPDRConfig added in v0.2.0

func (db *DB) UpdateCPDRConfig(ctx context.Context, s CPDRSettings, now time.Time) error

UpdateCPDRConfig replaces the operator-controlled fields only, so a settings save can never overwrite a concurrent run's recorded outcome.

func (*DB) UpdateCloudflareDNSSettings

func (db *DB) UpdateCloudflareDNSSettings(ctx context.Context, s CloudflareDNSSettings) error

UpdateCloudflareDNSSettings replaces the single row's Enabled flag.

func (*DB) UpdateCloudflareTunnelSettings

func (db *DB) UpdateCloudflareTunnelSettings(ctx context.Context, s CloudflareTunnelSettings) error

UpdateCloudflareTunnelSettings replaces the single row's Enabled flag, the same whole-record convention UpdateEmailSettings uses.

func (*DB) UpdateDBUpgradeRun added in v0.2.0

func (db *DB) UpdateDBUpgradeRun(ctx context.Context, r DBUpgradeRun) error

UpdateDBUpgradeRun rewrites every mutable field of a run.

func (*DB) UpdateDatabaseNode

func (db *DB) UpdateDatabaseNode(ctx context.Context, name, nodeID string) error

UpdateDatabaseNode is DesiredDatabase's counterpart to UpdateServiceNode.

func (*DB) UpdateDatabaseProject

func (db *DB) UpdateDatabaseProject(ctx context.Context, name, projectID string) error

UpdateDatabaseProject is DesiredDatabase's counterpart to UpdateServiceProject: see that method's own doc comment for why an empty projectID is written as SQL NULL, not the empty string node_id uses.

func (*DB) UpdateDatabaseSuspended added in v0.2.0

func (db *DB) UpdateDatabaseSuspended(ctx context.Context, name string, suspended bool) error

UpdateDatabaseSuspended is DesiredDatabase.Suspended's only writer, the database counterpart to UpdateServiceSuspended. Unlike that method, resuming does not need to clear anything else: a database has no EnvDirty-equivalent latch, since nothing about its desired state can change while suspended (there is no env editor for a database the way there is for an app).

func (*DB) UpdateEmailSettings

func (db *DB) UpdateEmailSettings(ctx context.Context, s EmailSettings) error

UpdateEmailSettings replaces the single email_settings row in full, the same whole-record convention UpdateIngressSettings uses.

func (*DB) UpdateEnvironment added in v0.2.0

func (db *DB) UpdateEnvironment(ctx context.Context, id string, patch EnvironmentPatch) error

UpdateEnvironment applies patch to one environment, returning ErrEnvironmentNotFound when id matches no row.

func (*DB) UpdateExportDestination added in v0.2.0

func (db *DB) UpdateExportDestination(ctx context.Context, d ExportDestination) error

UpdateExportDestination replaces every mutable field of a destination.

func (*DB) UpdateExternalDatabase added in v0.2.0

func (db *DB) UpdateExternalDatabase(ctx context.Context, d ExternalDatabase) error

UpdateExternalDatabase replaces the connection fields of an existing record.

func (*DB) UpdateFeatureFlag

func (db *DB) UpdateFeatureFlag(ctx context.Context, id, name, description string, enabled bool, rolloutPercentage int, updatedAt time.Time) error

UpdateFeatureFlag replaces name/description/enabled/rollout_percentage for an existing row: a full-replace contract, the same shape UpdateScheduledTask uses. It never touches Key or ServiceName (an existing flag cannot be reassigned to a different key or app; delete and recreate instead). Returns ErrFeatureFlagNotFound if id doesn't exist.

func (*DB) UpdateGitHubAppInstallation

func (db *DB) UpdateGitHubAppInstallation(ctx context.Context, installationID int64, accountLogin string) error

UpdateGitHubAppInstallation records the installation_id and account login GitHub's post-install redirect (GET /api/v1/github-app/installed) reports. Returns ErrGitHubAppConnectionNotFound if the App itself was never registered: an installation can't exist without an App to install.

func (*DB) UpdateIngressSettings

func (db *DB) UpdateIngressSettings(ctx context.Context, s IngressSettings) error

UpdateIngressSettings replaces the single ingress_settings row in full, the same "no partial update, the whole record is always written as a whole" convention SaveDesiredService already establishes for desired_services: a settings form always submits its complete current state, there's no legitimate "patch just one field" caller for a four-column singleton row. internal/api's PUT /api/v1/settings/ingress is expected to have already validated s (acme_email required and well-formed whenever s.ACMEEnabled is true) before calling this; this method itself performs no validation, matching the "store trusts its caller to have validated business rules, and only enforces what the schema itself can" division of responsibility SaveDesiredService's own domain-uniqueness enforcement is the exception to, not the rule.

func (*DB) UpdateMajorUpgradePhase added in v0.2.0

func (db *DB) UpdateMajorUpgradePhase(ctx context.Context, id, phase, snapshotVolume string) error

UpdateMajorUpgradePhase records the phase an upgrade reached and, once one exists, its rollback snapshot volume (empty keeps the stored value).

func (*DB) UpdateNetworkShare added in v0.2.0

func (db *DB) UpdateNetworkShare(ctx context.Context, id, name, protocol, host, remotePath, mountOptions, username string) error

UpdateNetworkShare replaces name/protocol/host/remote_path/mount_options/username for an existing row, the same full-replace contract UpdateRegistryCredential uses for its own sibling resource. Rotating a CIFS password is a separate write to internal/secrets under this row's existing NetworkShareSecretsKey, not this function's concern. Returns ErrNetworkShareNotFound if id doesn't exist.

func (*DB) UpdateNodeAgentInfo added in v0.2.0

func (db *DB) UpdateNodeAgentInfo(ctx context.Context, id string, info NodeAgentInfo, now time.Time) error

UpdateNodeAgentInfo stores what the node's agent reported about itself.

func (*DB) UpdateNodeMesh

func (db *DB) UpdateNodeMesh(ctx context.Context, id, publicKey, address string) error

UpdateNodeMesh records a node's WireGuard identity and assigned mesh address (migrations/0014_node_mesh.sql).

Its own narrow updater rather than a field on SaveNode, matching UpdateNodeStatus and TouchNodeLastSeen: SaveNode is insert-only because a node's identity is fixed at enrollment, and mesh state changes on an entirely different schedule (every time the mesh coordinator learns something new about a node) than enrollment does.

Returns ErrNodeNotFound if no such node exists, so a coordinator distributing to a node that was deleted mid-pass finds out rather than silently writing nothing.

func (*DB) UpdateNodeProvisionStatus added in v0.2.0

func (db *DB) UpdateNodeProvisionStatus(ctx context.Context, id, status, providerServerID, ipAddress, nodeID, failureReason string, updatedAt time.Time) error

UpdateNodeProvisionStatus replaces status, providerServerID, ipAddress, nodeID and failureReason for an existing row: the fields internal/api's live status recomputation (and CreateServer's own initial result) can learn between one write and the next. An empty providerServerID leaves the stored value unchanged, since most callers are only updating status/ip/node/failure after the server already has one. Returns ErrNodeProvisionNotFound if id doesn't exist.

func (*DB) UpdateNodeRegion added in v0.2.0

func (db *DB) UpdateNodeRegion(ctx context.Context, id, region string) error

UpdateNodeRegion sets a node's operator-facing location label. Its own narrow updater rather than a SaveNode field, matching UpdateNodeWorkloads: SaveNode is insert-only and this changes on its own schedule. Returns ErrNodeNotFound if no such node exists, same rigor as UpdateNodeWorkloads.

func (*DB) UpdateNodeStatus

func (db *DB) UpdateNodeStatus(ctx context.Context, id string, status NodeStatus) error

UpdateNodeStatus sets a node's status and, when it actually changed, records the transition in node_status_events. Returns ErrNodeNotFound if no such node exists.

func (*DB) UpdateNodeWorkloads

func (db *DB) UpdateNodeWorkloads(ctx context.Context, id string, acceptsApp, acceptsBuild bool) error

UpdateNodeWorkloads sets a node's workload capability flags. Returns ErrNodeNotFound if no such node exists, the same "distinguish real failure from a no-op" rigor UpdateNodeStatus already applies to its own conditional UPDATE.

func (*DB) UpdateOAuthProviderSettings

func (db *DB) UpdateOAuthProviderSettings(ctx context.Context, s OAuthProviderSettings) error

UpdateOAuthProviderSettings replaces one provider's settings row in full. It never touches a credential; storing the client secret is the caller's job via internal/secrets.

func (*DB) UpdateObservabilitySettings added in v0.2.0

func (db *DB) UpdateObservabilitySettings(ctx context.Context, s ObservabilitySettings) error

UpdateObservabilitySettings replaces the single row's URL, the same whole-record convention UpdateCloudflareTunnelSettings uses.

func (*DB) UpdatePolicy

func (db *DB) UpdatePolicy(ctx context.Context, id, name, description, document string) error

UpdatePolicy replaces an existing policy's name/description/document, bumping updated_at. Returns ErrPolicyNotFound if id doesn't exist, ErrPolicyNameExists if name collides with a different row.

func (*DB) UpdatePreviewDatabaseIsolationStatus added in v0.2.0

func (db *DB) UpdatePreviewDatabaseIsolationStatus(ctx context.Context, id, status, statusReason, updatedAt string) error

UpdatePreviewDatabaseIsolationStatus sets id's status/status_reason in place. Returns ErrPreviewDatabaseIsolationNotFound if id doesn't exist.

func (*DB) UpdatePreviewEnvironment

func (db *DB) UpdatePreviewEnvironment(ctx context.Context, p PreviewEnvironment) error

UpdatePreviewEnvironment replaces an existing preview environment row in full, keyed by ID: a synchronize push (new commits on the same PR) or a status transition (deploying -> active/failed) both rewrite the whole record, the same "no partial update" convention UpdateIngressSettings already establishes for a similarly small record.

func (*DB) UpdatePreviewEphemeralDatabaseStatus added in v0.2.0

func (db *DB) UpdatePreviewEphemeralDatabaseStatus(ctx context.Context, id, status, statusReason, updatedAt string) error

UpdatePreviewEphemeralDatabaseStatus sets id's status/status_reason in place, the same "record why, keep the row for a retry" shape finishPreviewFailed already establishes for preview_environments itself. Returns ErrPreviewEphemeralDatabaseNotFound if id doesn't exist.

func (*DB) UpdateProxyIntegrationSettings added in v0.2.0

func (db *DB) UpdateProxyIntegrationSettings(ctx context.Context, s ProxyIntegrationSettings) error

UpdateProxyIntegrationSettings replaces the singleton row in full.

func (*DB) UpdateRegistryCredential

func (db *DB) UpdateRegistryCredential(ctx context.Context, id, name, registryHost, username string, expiresAt *time.Time) error

UpdateRegistryCredential replaces name/registry_host/username/expiresAt for an existing row, the same full-replace contract UpdateBackupTarget uses for its own sibling resource. Rotating the password is a separate write to internal/secrets under this row's existing RegistryCredentialSecretsKey, not this function's concern. Returns ErrRegistryCredentialNotFound if id doesn't exist.

func (*DB) UpdateRegistrySettings

func (db *DB) UpdateRegistrySettings(ctx context.Context, s RegistrySettings) error

UpdateRegistrySettings replaces the single registry_settings row in full, the same whole-record convention UpdateCloudflareTunnelSettings already establishes.

func (*DB) UpdateRole added in v0.2.0

func (db *DB) UpdateRole(ctx context.Context, r Role) error

UpdateRole rewrites a custom role. A built-in role returns ErrRoleBuiltin.

func (*DB) UpdateRoleAndSync added in v0.2.0

func (db *DB) UpdateRoleAndSync(ctx context.Context, r Role) error

UpdateRoleAndSync rewrites a custom role and the abilities of every user holding it in one transaction, so a downgraded role can never leave its users with the old, higher abilities.

func (*DB) UpdateRoute53DNSSettings added in v0.2.0

func (db *DB) UpdateRoute53DNSSettings(ctx context.Context, s Route53DNSSettings) error

UpdateRoute53DNSSettings replaces the single row's fields.

func (*DB) UpdateSSHNodeProvisionProgress added in v0.2.0

func (db *DB) UpdateSSHNodeProvisionProgress(ctx context.Context, id, status, detectedOS, detectedArch, log, nodeID, failureReason string, updatedAt time.Time) error

UpdateSSHNodeProvisionProgress replaces status, detectedOS, detectedArch, log, nodeID and failureReason for an existing row: every field the provisioning goroutine (as the install proceeds) or a GET's live enrollment check (once it finds the matching node) can learn between one write and the next. Returns ErrSSHNodeProvisionNotFound if id doesn't exist.

func (*DB) UpdateScheduledTask

func (db *DB) UpdateScheduledTask(ctx context.Context, id string, command []string, schedule string, enabled bool, concurrencyPolicy string, updatedAt time.Time) error

UpdateScheduledTask updates a task's own editable fields (Command, Schedule, Enabled, ConcurrencyPolicy): it never touches ServiceName (an existing task cannot be reassigned to a different app; delete and recreate instead) or the last-run fields (RecordScheduledTaskRun's job, not this method's). An empty concurrencyPolicy defaults to ScheduledTaskConcurrencyAllow, the same as SaveScheduledTask. Returns ErrScheduledTaskNotFound if id doesn't exist.

func (*DB) UpdateScheduledTaskConfig added in v0.2.0

func (db *DB) UpdateScheduledTaskConfig(ctx context.Context, t ScheduledTask, now time.Time) error

UpdateScheduledTaskConfig replaces every operator-editable field of a task. The schedule is re-armed (high-water mark cleared) when the cron expression or timezone changes, or the task goes from disabled to enabled, so editing a job never backfills occurrences it was not live for.

func (*DB) UpdateServiceApp

func (db *DB) UpdateServiceApp(ctx context.Context, name, appID string) error

UpdateServiceApp assigns svc to app appID, the only way desired_services.app_id ever changes outside migrations/0039_apps.sql's own backfill: SaveDesiredService's own doc comment explains why this is deliberately excluded from that method's full-record-replace semantics, the same reasoning UpdateServiceNode/UpdateServiceProject already establish for NodeID/ProjectID.

func (*DB) UpdateServiceDatabaseAttachment

func (db *DB) UpdateServiceDatabaseAttachment(ctx context.Context, name string, att *DatabaseAttachment) error

UpdateServiceDatabaseAttachment is DesiredService.DatabaseAttachment's only writer, the same separation-from-ordinary-update reasoning UpdateServiceStorageTarget already establishes for StorageTargetID. att nil clears the attachment (all three columns back to ”).

func (*DB) UpdateServiceEgressPolicy added in v0.2.0

func (db *DB) UpdateServiceEgressPolicy(ctx context.Context, name string, policy *ServiceEgressPolicy) error

UpdateServiceEgressPolicy replaces svc's egress allowlist as a whole (policy nil clears it), without SaveDesiredService's full-record replace.

func (*DB) UpdateServiceHealth added in v0.2.0

func (db *DB) UpdateServiceHealth(ctx context.Context, name string, health *ServiceHealth) error

UpdateServiceHealth replaces svc's readiness/liveness config as a whole (health nil clears it), without SaveDesiredService's full-record replace.

func (*DB) UpdateServiceLogDrain

func (db *DB) UpdateServiceLogDrain(ctx context.Context, name string, drain *LogDrain) error

UpdateServiceLogDrain sets or clears svc's log drain, the only way log_drain ever changes: SaveDesiredService's own doc comment explains why this is deliberately excluded from that method's full-record- replace semantics, the same reasoning UpdateServiceStorageTarget already establishes for storage_target_id. drain nil clears it.

func (*DB) UpdateServiceNode

func (db *DB) UpdateServiceNode(ctx context.Context, name, nodeID string) error

UpdateServiceNode reassigns svc to run on nodeID ("" for this control plane's own local node, per the placement migration's comment), the only way node_id ever changes: SaveDesiredService's own doc comment explains why it's deliberately excluded from that method's full-record-replace semantics.

func (*DB) UpdateServiceProject

func (db *DB) UpdateServiceProject(ctx context.Context, name, projectID string) error

UpdateServiceProject reassigns svc to project projectID ("" for "no project", the same real-and-permanent sentinel DesiredService. ProjectID's own doc comment describes), the only way project_id ever changes: SaveDesiredService's own doc comment explains why it's deliberately excluded from that method's full-record-replace semantics, the same reasoning UpdateServiceNode already establishes for NodeID. An empty projectID is written as SQL NULL, not the empty string node_id uses, because unlike node_id (NOT NULL DEFAULT ”), this column is genuinely nullable (migrations/0022_projects.sql's own comment on why).

func (*DB) UpdateServiceStorageTarget

func (db *DB) UpdateServiceStorageTarget(ctx context.Context, name, storageTargetID string) error

UpdateServiceStorageTarget reassigns svc's object-storage credential source to storageTargetID ("" for "no storage attached"), the only way storage_target_id ever changes: SaveDesiredService's own doc comment explains why it's deliberately excluded from that method's full-record-replace semantics, the same reasoning UpdateServiceNode/ UpdateServiceProject already establish for their own single-purpose updates. An empty storageTargetID is written as SQL NULL, not the empty string node_id uses, the same reasoning UpdateServiceProject's own doc comment gives: this column is genuinely nullable, mirroring backup_target_id's own convention on desired_databases (migrations/0023_scheduled_backups.sql) rather than node_id's.

Deliberately does not validate storageTargetID against backup_targets itself: that check belongs to the caller (internal/api's handleSetAppStorage), the same "own endpoint validates, this method just writes" boundary UpdateServiceProject leaves to handleSetAppProject's own validateProjectID call.

func (*DB) UpdateServiceSuspended

func (db *DB) UpdateServiceSuspended(ctx context.Context, name string, suspended bool) error

UpdateServiceSuspended is the only way suspended ever changes, the same "own single-purpose setter, excluded from SaveDesiredService" reasoning UpdateServiceNode/UpdateServiceProject/ UpdateServiceStorageTarget already establish. Setting it true does not by itself stop any container: internal/reconcile/application's controller is what converges to zero containers once it observes Suspended on its next reconcile, the same level-triggered separation DeleteDesiredService's own doc comment describes for delete.

func (*DB) UpdateServiceVolumes added in v0.2.0

func (db *DB) UpdateServiceVolumes(ctx context.Context, name string, volumes []ServiceVolume) error

UpdateServiceVolumes replaces svc's named-volume list as a whole, without SaveDesiredService's full-record replace: the dedicated dual-write path Volumes lacked until now, mirroring UpdateServiceEgressPolicy (app.yaml's volumes: block also sets this, via the ordinary SaveDesiredService replace). A nil slice persists as "[]", matching SaveDesiredService's own nil-to-empty handling, so a service with no volumes always reads back an empty slice, never nil.

func (*DB) UpdateUpdateSettings added in v0.2.0

func (db *DB) UpdateUpdateSettings(ctx context.Context, s UpdateSettings) error

UpdateUpdateSettings replaces the single update_settings row in full, the same "whole record always written as a whole" convention UpdateIngressSettings already establishes for its own singleton row. Validation (channel is one of the recognized values) is the caller's responsibility, matching UpdateIngressSettings's own division of labor between store and API layer.

func (*DB) UpdateUserAbilities

func (db *DB) UpdateUserAbilities(ctx context.Context, id string, abilities []string) error

UpdateUserAbilities replaces a user's Abilities wholesale, the same "fixed at mint time except this one field" shape api_tokens uses for LastUsedAt/RevokedAt. Validation (validateAbilities) is the caller's job (internal/api), not this layer's. It also clears the user's role, since hand-edited abilities no longer match any stored role. Returns ErrUserNotFound if id doesn't exist.

func (*DB) UpdateUserLastLogin

func (db *DB) UpdateUserLastLogin(ctx context.Context, id string, when time.Time) error

UpdateUserLastLogin stamps last_login_at, called once per successful sign-in (password or OAuth). Returns ErrUserNotFound if id doesn't exist.

func (*DB) UpdateUserPasswordHash

func (db *DB) UpdateUserPasswordHash(ctx context.Context, id string, hash *string) error

UpdateUserPasswordHash sets (or, given a nil hash, clears) a user's password. Returns ErrUserNotFound if id doesn't exist.

func (*DB) UpdateVaultSettings added in v0.2.0

func (db *DB) UpdateVaultSettings(ctx context.Context, s VaultSettings) error

UpdateVaultSettings replaces the single row, the same whole-record convention UpdateCloudflareTunnelSettings uses.

func (*DB) UpsertBuildCacheSetting added in v0.2.0

func (db *DB) UpsertBuildCacheSetting(ctx context.Context, s BuildCacheSetting) error

UpsertBuildCacheSetting creates or updates the setting for s.AppName, keeping build history fields.

func (*DB) UpsertConditions

func (db *DB) UpsertConditions(ctx context.Context, controllerName string, conditions []reconcile.Condition) error

UpsertConditions persists every condition from a controller's most recent Reconcile result. Every reconcile must emit a status condition that gets stored and shown in the UI; this is that storage. reconcile.Engine itself only ever held results in memory, lost on restart.

func (*DB) UpsertGitHubAppInstallation added in v0.2.0

func (db *DB) UpsertGitHubAppInstallation(ctx context.Context, installationID int64, accountLogin, accountType string) error

UpsertGitHubAppInstallation records an installation by installation_id: a first-time id inserts a new row, a repeat id (re-authorizing, or GitHub's installation_repositories webhook firing again) updates account_login/account_type in place rather than creating a duplicate. This single upsert is what makes "connect the first org" and "add another org" the same code path in handleGitHubAppInstalled.

func (*DB) UpsertHookRun

func (db *DB) UpsertHookRun(ctx context.Context, run HookRun) error

UpsertHookRun replaces the stored outcome for (run.ServiceName, run.HookType): only the most recent run per hook type is kept, see migrations/0083_service_hook_runs.sql's own comment for why a full history isn't.

func (*DB) UpsertLogArchivePolicy added in v0.2.0

func (db *DB) UpsertLogArchivePolicy(ctx context.Context, p LogArchivePolicy) error

UpsertLogArchivePolicy creates the policy for p.AppName or updates its destination, cadence and retention while keeping the watermark.

func (*DB) UpsertSelfUpgradeAttempt added in v0.2.0

func (db *DB) UpsertSelfUpgradeAttempt(ctx context.Context, a SelfUpgradeAttempt) error

UpsertSelfUpgradeAttempt stores a, replacing an earlier copy of the same id, so importing a journal twice is harmless.

func (*DB) UserRoleID added in v0.2.0

func (db *DB) UserRoleID(ctx context.Context, userID string) (string, error)

UserRoleID returns the role assigned to a user, or "" when none is.

func (*DB) UserTeamRoles added in v0.2.0

func (db *DB) UserTeamRoles(ctx context.Context, userID string) (map[string]string, error)

UserTeamRoles maps each team the user belongs to onto their role there.

func (*DB) UserVisibility added in v0.2.0

func (db *DB) UserVisibility(ctx context.Context, userID string) (Visibility, error)

UserVisibility is restricted when the user's role has granted visibility. A user with no role, or a role that sees everything, is unrestricted.

func (*DB) VaultConfigured added in v0.2.0

func (db *DB) VaultConfigured(ctx context.Context) (bool, error)

VaultConfigured reports whether an operator has enabled Vault integration (VaultSettings.Enabled), the narrow check internal/deploy.VaultConfigChecker needs at deploy validation time without exposing the whole settings row.

type DBUpgradePolicy added in v0.2.0

type DBUpgradePolicy struct {
	DatabaseName    string
	AutoUpgrade     string
	WindowCron      string
	WindowDuration  time.Duration
	WindowTimezone  string
	BackupBefore    bool
	VerifyAfter     bool
	RevertOnFailure bool
	Notify          []string
	UpdatedBy       string
	UpdatedAt       string
}

DBUpgradePolicy is a database's (or the platform default's) automatic upgrade policy.

type DBUpgradeRun added in v0.2.0

type DBUpgradeRun struct {
	ID              string
	DatabaseName    string
	Engine          string
	FromVersion     string
	ToVersion       string
	Kind            string
	Source          string
	State           string
	Phase           string
	VerifyAfter     bool
	RevertOnFailure bool
	Notify          []string
	BackupID        string
	VerificationID  string
	FromImageDigest string
	SnapshotVolume  string
	RevertPath      string
	Reason          string
	RequestedBy     string
	// Timings maps each state and phase entered to its RFC3339 start time.
	Timings        map[string]string
	CreatedAt      string
	PhaseStartedAt string
	FinishedAt     string
}

DBUpgradeRun is one upgrade attempt of a managed database.

type DatabaseAccessSettings added in v0.2.0

type DatabaseAccessSettings struct {
	Database   string
	Scope      string
	RequireTLS bool
	UpdatedAt  string
}

DatabaseAccessSettings is a database's network scope and TLS policy.

type DatabaseAccessUser added in v0.2.0

type DatabaseAccessUser struct {
	ID        string
	Database  string
	Role      string
	Kind      string
	Preset    string
	CreatedBy string
	CreatedAt string
	ExpiresAt string
	State     string
	RevokedAt string
}

DatabaseAccessUser tracks a role this platform created in a managed database. It never holds a password.

type DatabaseAttachment

type DatabaseAttachment struct {
	DatabaseName string
	EnvVar       string
	Field        string
}

DatabaseAttachment is which managed database (desired_databases.name) an app resolves one connection env var from, set through PUT/DELETE /api/v1/apps/{name}/database rather than app.yaml: the UI/CLI-facing equivalent of DatabaseEnv above, for an app that was created directly (build.type: image via the API) rather than deployed from a spec file. Exactly one per app, mirroring StorageTargetID's single-attachment shape rather than DatabaseEnv's open-ended map.

type DatabaseDataImport added in v0.2.0

type DatabaseDataImport struct {
	DatabaseName string
	Status       string
	Reason       string
	SourceHost   string
	SourcePort   int
	SourceDB     string
	Checked      int
	Mismatched   int
	Detail       string
	StartedAt    time.Time
	FinishedAt   time.Time
}

DatabaseDataImport is the latest copy of live data into one managed database (migrations/0381_database_data_imports.sql). Detail is the verification JSON.

type DatabaseEngineInfo

type DatabaseEngineInfo struct {
	ID             string `yaml:"id"`
	Label          string `yaml:"label"`
	DefaultVersion string `yaml:"default_version"`
}

DatabaseEngineInfo is one row of database_engines.yaml: identity and display metadata for a managed database engine this control plane can create. See that file's own doc comment for what does and doesn't belong here (display data only, not the real per-engine reconcile behavior, which stays Go code).

func SupportedDatabaseEngines

func SupportedDatabaseEngines() ([]DatabaseEngineInfo, error)

SupportedDatabaseEngines returns every database engine this control plane can create, parsed from the embedded registry once and cached: the registry never changes at runtime, so there's no reason to re-parse it per call, the same reasoning internal/spec's own compiledAppSchema already applies to its embedded JSON Schema.

type DatabaseEnvRef

type DatabaseEnvRef struct {
	Database string `json:"database"`
	Field    string `json:"field"`
}

DatabaseEnvRef is one env var's parsed { from: "<database>.<field>" } reference (internal/spec.EnvVar.From), stored on DesiredService. DatabaseEnv. Database is a desired_databases.name; Field is one of "url", "host", "port", "username", "password", "database", resolved by the application controller (resolveDatabaseEnv) immediately before container creation, the same "declaration only, resolved later" split SecretEnv already makes for { secret: true }.

type DatabaseQueryHistory added in v0.2.0

type DatabaseQueryHistory struct {
	ID            string
	DatabaseName  string
	PrincipalType string
	PrincipalID   string
	Mode          string
	SQL           string
	Fingerprint   string
	OK            bool
	Error         string
	DurationMs    int64
	RowCount      int
	CreatedAt     time.Time
}

DatabaseQueryHistory is one console execution (migrations/0389).

type DatabaseSavedQuery added in v0.2.0

type DatabaseSavedQuery struct {
	ID            string
	DatabaseName  string
	PrincipalType string
	PrincipalID   string
	Name          string
	SQL           string
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

DatabaseSavedQuery is a named statement owned by one principal (migrations/0390).

type DeployApproval added in v0.2.0

type DeployApproval struct {
	ID string
	// ServiceName is the app whose desired image actually changes once
	// approved.
	ServiceName string
	// SourceServiceName is the app a promote action's image comes from;
	// empty for a plain deploy action.
	SourceServiceName string
	EnvironmentID     string
	// Action is one of the DeployApprovalAction* constants.
	Action string
	// Image is the target image tag ServiceName's desired state will be
	// pointed at once this is approved.
	Image string
	// Status is one of the DeployApprovalStatus* constants.
	Status string

	RequestedByType string
	RequestedBy     string
	RequestedByName string

	// ApprovedByType/ApprovedBy/ApprovedByName are empty until Status
	// leaves pending; "ApprovedBy" is this row's decider whether the
	// outcome was approve or reject, matching the "who decided" framing
	// audit_log's own ActorID already uses regardless of whether the
	// decision was an allow or a deny.
	ApprovedByType string
	ApprovedBy     string
	ApprovedByName string
	// Reason is an optional operator-supplied note, only ever set on
	// reject.
	Reason string

	CreatedAt string
	ExpiresAt string
	// DecidedAt is empty while Status is pending.
	DecidedAt string

	// FreezeOverride is the requester's freeze override note, empty when
	// the request did not override a freeze.
	FreezeOverride string
	// Pull requires a fresh registry resolution when the deploy applies.
	Pull bool
	// IncludeEnv applies a promotion's added and removed env keys too.
	IncludeEnv bool
	// PromoteEnv is the JSON env diff snapshotted when the promotion was requested.
	PromoteEnv string
}

DeployApproval is one pending-or-decided two-person approval gate on a deploy/promote into a protected environment (migrations/0116): the real workflow behind Environment.Protected, replacing the old same-actor confirm-flag gate (environments.go's environmentNeedsConfirmation, internal/api). RequestedBy/ApprovedBy use the same PrincipalTypeUser/PrincipalTypeToken vocabulary iam_policy.go already established, so "the same actor can't approve their own request" compares on the identical (type, id) pair requireAbilityDecided resolves for every other ability check.

type DeployAttempt

type DeployAttempt struct {
	// ID is an opaque, mint-time-random identifier from
	// NewDeployAttemptID, not a database-assigned sequence: see that
	// function's own doc comment for why.
	ID          string
	ServiceName string
	// Image is the tag this attempt deploys (or is trying to build and
	// deploy). For the plain image-tag path this is exactly the
	// caller-supplied tag; for the two build-triggering paths it is
	// computed the same way internal/deploy's own deployDockerfile
	// computes it (ImageRepo + ":" + CommitSHA), known before the build
	// even starts, so a failed build's attempt row still shows what tag
	// it was trying to produce.
	Image string
	// CommitSHA is the git commit this attempt built from, empty for the
	// plain image-tag trigger path (DeployAttemptSourceImage), which has
	// no associated commit.
	CommitSHA string
	// Source is one of the DeployAttemptSource* constants.
	Source string
	// Status is one of the DeployAttemptStatus* constants.
	Status    string
	StartedAt time.Time
	// FinishedAt is nil until FinishDeployAttempt is called.
	FinishedAt *time.Time
	// Error is the attempt's failure detail, set only when Status is
	// DeployAttemptStatusFailed. Unlike an HTTP error response (see
	// internal/api/builds.go's handleTriggerBuild doc comment on why
	// that response body stays non-leaky), this is stored for an
	// authenticated operator's own later inspection via
	// GET /api/v1/apps/{name}/deploy-attempts, the same trust boundary
	// GetConditions' Message field already crosses for reconcile
	// failures.
	Error string

	// Snapshot is this attempt's service configuration at trigger time
	// (migrations/0086), built by NewDeployAttemptSnapshot from the
	// DesiredService the trigger handler already has in hand. Zero value
	// for every attempt recorded before that migration.
	Snapshot DeployAttemptSnapshot

	// DetectedFramework is the human-readable framework name (migrations/
	// 0119) the create-app-from-git wizard's pre-flight detection
	// reported, e.g. "Node.js". Empty for any attempt that skipped that
	// step (the CLI, a git-push webhook, or an attempt recorded before
	// this column existed).
	DetectedFramework string

	// ImageDigest is the content identity this attempt resolved to: a
	// registry digest for a pulled image, or the local image ID of a build.
	ImageDigest string
	// DigestReason says how ImageDigest was obtained, one of the
	// DigestReason* constants.
	DigestReason string
	// RolloutState is what the application controller last observed for
	// this attempt's image: one of the RolloutState* constants, empty until
	// the controller has looked.
	RolloutState   string
	RunningImageID string
	// Sequence is the per-service trigger order (NextDeploySequence).
	Sequence int64
	// Reason explains a held or superseded attempt (Frozen, Superseded, Stale).
	Reason string
	// HeldRequest is the JSON a held or queued attempt needs to be replayed.
	HeldRequest string
	// QueuedAt is when the attempt entered the queue, nil if it never queued.
	QueuedAt *time.Time
	// SupersededBy is the newer attempt that replaced a queued one.
	SupersededBy string
	// CanceledBy is who canceled the attempt.
	CanceledBy string

	// Branch, CommitMessage and Author come from the push payload
	// (migrations/0149), empty when the trigger carried none.
	Branch        string
	CommitMessage string
	Author        string
}

DeployAttempt is one row-per-attempt entry in the deploy_attempts table: real deploy history, closing the gap left by reconcile_status/UpsertConditions only ever keeping the latest condition per (controller, type) pair. Minted by all three real trigger paths (the plain image-tag deploy, the manual git-source build, and the unattended git-push webhook), one row per call.

type DeployAttemptEnvKey

type DeployAttemptEnvKey struct {
	Key   string               `json:"key"`
	Kind  DeployAttemptEnvKind `json:"kind"`
	Value string               `json:"value,omitempty"`
}

DeployAttemptEnvKey is one env var key captured in a DeployAttemptSnapshot. Value is only ever populated for Kind DeployAttemptEnvKindLiteral: a secret- or database-backed key never carries a value here, matching how DesiredService.SecretEnv itself holds names only (see that field's own doc comment).

type DeployAttemptEnvKind

type DeployAttemptEnvKind string

DeployAttemptEnvKind classifies one env var key captured in a DeployAttemptSnapshot: whether its value is safe to snapshot at all.

const (
	// DeployAttemptEnvKindLiteral is an ordinary env var
	// (DesiredService.Env): its Value is snapshotted and diffable.
	DeployAttemptEnvKindLiteral DeployAttemptEnvKind = "literal"
	// DeployAttemptEnvKindSecret is a { secret: true } env var
	// (DesiredService.SecretEnv): only its key is ever snapshotted, never
	// a value or anything derived from one.
	DeployAttemptEnvKindSecret DeployAttemptEnvKind = "secret"
	// DeployAttemptEnvKindDatabase is a { from: ... } env var
	// (DesiredService.DatabaseEnv): resolved from a managed database's
	// live connection details at container-create time, so there is no
	// stable value to snapshot even though it isn't secret-backed.
	DeployAttemptEnvKindDatabase DeployAttemptEnvKind = "database"
	// DeployAttemptEnvKindVault is a { vault: ... } env var
	// (DesiredService.VaultEnv): resolved live from an external Vault
	// instance at container-create time, the same "no stable value to
	// snapshot" reasoning DeployAttemptEnvKindDatabase already gives.
	DeployAttemptEnvKindVault DeployAttemptEnvKind = "vault"
)

type DeployAttemptSnapshot

type DeployAttemptSnapshot struct {
	Env      []DeployAttemptEnvKey `json:"env,omitempty"`
	Port     int                   `json:"port,omitempty"`
	HostPort *int                  `json:"host_port,omitempty"`
	// BindAddress mirrors DesiredService.BindAddress
	// (migrations/0103_service_bind_address.sql).
	BindAddress string            `json:"bind_address,omitempty"`
	Domains     []string          `json:"domains,omitempty"`
	Resources   *ServiceResources `json:"resources,omitempty"`
	// Health, Replicas, Strategy, Volumes, and Labels mirror
	// DesiredService's own fields of the same name, closing the
	// remaining gap this migration's own comment named.
	Health   *ServiceHealth    `json:"health,omitempty"`
	Replicas int               `json:"replicas,omitempty"`
	Strategy string            `json:"strategy,omitempty"`
	Volumes  []ServiceVolume   `json:"volumes,omitempty"`
	Labels   map[string]string `json:"labels,omitempty"`
}

DeployAttemptSnapshot is the subset of DesiredService captured per deploy attempt (migrations/0086), closing the gap docs/roadmap.md's deploy-comparison entry describes: before this, only Image/CommitSHA/Source/Status/timestamps were ever recorded per attempt.

func NewDeployAttemptSnapshot

func NewDeployAttemptSnapshot(svc DesiredService) DeployAttemptSnapshot

NewDeployAttemptSnapshot builds svc's config snapshot at the moment a deploy attempt is triggered. Env keys are sorted for a stable JSON encoding, so two snapshots of an unchanged config marshal identically.

type DeployCursor added in v0.2.0

type DeployCursor struct {
	AppliedSequence int64
	CommitSHA       string
	Before          string
	CommitAt        time.Time
}

DeployCursor is the ordering state of the last deploy that actually wrote a service's desired state.

type DeployFreezeWindow added in v0.2.0

type DeployFreezeWindow struct {
	ID        string
	Scope     string
	Cron      string
	Duration  time.Duration
	Timezone  string
	Reason    string
	CreatedAt time.Time
}

DeployFreezeWindow is a recurring window, starting at each Cron match in Timezone and lasting Duration, during which automatic deploys are held.

type DeployGateEvent added in v0.2.0

type DeployGateEvent struct {
	ID              int64
	DeployAttemptID string
	ServiceName     string
	// Image resolves DeployAttemptID when it is empty; it is not stored.
	Image     string
	Phase     string
	Status    string
	Reason    string
	Message   string
	Container string
	At        time.Time
}

DeployGateEvent is one step on a release's way to traffic or through its post-deploy watch.

type DeployOrder added in v0.2.0

type DeployOrder struct {
	Sequence int64
	// Automatic marks a webhook, schedule or pipeline deploy. Manual deploys
	// and explicit rollbacks are never rejected as stale.
	Automatic bool
	CommitSHA string
	// Before is the commit the push moved the branch from.
	Before   string
	CommitAt time.Time
}

DeployOrder is where one deploy sits in its service's history: the trigger-time Sequence plus, for a git push, the commit ordering the provider reported.

type DeployOrderCheck added in v0.2.0

type DeployOrderCheck func(cursor DeployCursor, order DeployOrder) error

DeployOrderCheck decides whether order may still write desired state given cursor; a non-nil error aborts the write.

type DeploySafetySettings added in v0.2.0

type DeploySafetySettings struct {
	ServiceName      string
	SuccessThreshold *int
	StableWindow     *time.Duration
	DrainTimeout     *time.Duration
	WatchWindow      *time.Duration
	WatchMaxRestarts *int
	WatchErrorRate   *float64
	WatchMinRequests *int
	AutoRollback     *bool
	UpdatedAt        time.Time
}

DeploySafetySettings is one app's readiness gate and post-deploy watch overrides (migrations/0460_deploy_safety.sql). A nil field inherits the platform default.

type Deployment added in v0.2.0

type Deployment struct {
	Attempt      DeployAttempt
	Status       string
	Trigger      string
	Environment  string
	RollbackOf   string
	SupersededBy string
	RolledBackBy string
	PRNumber     int
	IsLive       bool
}

Deployment is one deploy attempt joined with its derived status, environment and rollback links.

type DeploymentBrief added in v0.2.0

type DeploymentBrief struct {
	Status       string
	RolloutState string
	IsLive       bool
	StartedAt    time.Time
	FinishedAt   *time.Time
}

DeploymentBrief is the slim row deployment summaries are computed from.

type DeploymentDay added in v0.2.0

type DeploymentDay struct {
	Date   string `json:"date"`
	Total  int    `json:"total"`
	Failed int    `json:"failed"`
}

DeploymentDay is one bucket of the per-day sparkline.

type DeploymentFilter added in v0.2.0

type DeploymentFilter struct {
	Statuses    []string
	ID          string
	App         string
	Branch      string
	Triggers    []string
	Environment string
	Since       time.Time
	Until       time.Time
	Query       string
	// Live keeps only the release currently serving its app.
	Live bool
	// PR keeps only previews of this pull request number.
	PR int
	// VisibleApps, when non-nil, restricts results to these app names.
	VisibleApps []string
	Cursor      string
	Limit       int
}

DeploymentFilter narrows ListDeployments. Zero values mean no filter.

type DeploymentSummary added in v0.2.0

type DeploymentSummary struct {
	Counts          map[string]int
	InProgress      int
	NeedsAttention  int
	FailureRate24h  *float64
	MedianMS        *int64
	P95MS           *int64
	PerDay          []DeploymentDay
	FinishedInRange int
}

DeploymentSummary aggregates deployments for the summary endpoint.

func BuildDeploymentSummary added in v0.2.0

func BuildDeploymentSummary(briefs []DeploymentBrief, now time.Time, window time.Duration) DeploymentSummary

BuildDeploymentSummary computes counts inside window, the 24h failure rate, duration percentiles and the per-day series ending at now (UTC).

type DesiredDatabase

type DesiredDatabase struct {
	Name    string
	Engine  string
	Version string
	// NodeID: see DesiredService.NodeID's own doc comment, identical
	// meaning and identical "SaveDesiredDatabase never writes it, only
	// UpdateDatabaseNode does" exception below.
	NodeID string
	// ProjectID: see DesiredService.ProjectID's own doc comment,
	// identical meaning and identical "SaveDesiredDatabase never writes
	// it, only UpdateDatabaseProject does" exception below.
	ProjectID string
	// BackupTargetID, BackupSchedule, BackupRetain: wave-2 roadmap item 6,
	// scheduled backups (migrations/0023_scheduled_backups.sql). Same
	// "SaveDesiredDatabase never writes it, only SetDatabaseBackupSchedule
	// does" exception NodeID/ProjectID already establish above, applied
	// to the three columns internal/backup.Scheduler reads every tick.
	// BackupTargetID is "" when no backup_targets row is configured
	// (SQL NULL, mirroring ProjectID's own empty-string-means-NULL
	// convention); BackupSchedule is "" when no cron schedule is set
	// (SQL ”, mirroring NodeID's own empty-string-is-the-real-value
	// convention, see the migration's own doc comment for why the two
	// columns deliberately use different null-ness conventions);
	// BackupRetain is 0, meaning "keep every successful backup, prune
	// nothing."
	BackupTargetID string
	BackupSchedule string
	BackupRetain   int
	// BackupRetainDays is a second, independent retention dimension
	// (migrations/0059_backup_retain_days.sql): 0 means no age limit,
	// mirroring BackupRetain's own zero-means-unlimited convention.
	BackupRetainDays int
	// PubliclyAccessible, PublicPort: whether this database's container
	// port is bound to a host port so an operator's own database GUI
	// tool can connect to it directly, not just from inside the Docker
	// network (migrations/0026_database_public_access.sql). Same
	// "SaveDesiredDatabase never writes it, only
	// SetDatabasePublicAccess does" exception NodeID/ProjectID/
	// BackupSchedule already establish. PublicPort is 0 when
	// PubliclyAccessible is false (SQL NULL).
	PubliclyAccessible bool
	PublicPort         int
	// PublicBindAddress picks which network interface PublicPort binds to
	// (migrations/0104_database_public_bind_address.sql): "private",
	// "public", or a literal IP, see internal/bindaddr.Resolve. Same
	// SetDatabasePublicAccess-only-writer exception as PublicPort; "" when
	// PubliclyAccessible is false (SQL NULL).
	PublicBindAddress string

	// Resources caps this database's memory and CPU, the same
	// *ServiceResources type and JSON-column storage
	// DesiredService.Resources already establishes (migrations/
	// 0028_desired_databases_resources.sql mirrors 0002's reasoning).
	// Unlike NodeID/ProjectID/the backup fields above, this is ordinary
	// desired state: SaveDesiredDatabase writes it on every save, the
	// same "whole record, not a special exception" treatment
	// DesiredService.Resources gets from SaveDesiredService.
	Resources *ServiceResources

	// Suspended: see DesiredService.Suspended's own doc comment, identical
	// meaning and identical "SaveDesiredDatabase never writes it, only
	// UpdateDatabaseSuspended does" exception NodeID/ProjectID already
	// establish above (migrations/0094_database_suspended.sql).
	Suspended bool

	// PITREnabled/PITREnabledAt (migrations/0115_database_pitr.sql):
	// whether this database's reconciler should run it with WAL
	// archiving on, and when that was turned on. Same
	// SaveDesiredDatabase-never-writes-it exception as NodeID/
	// BackupSchedule/Suspended above; only SetDatabasePITR writes these
	// two. PITREnabledAt is "" whenever PITREnabled is false.
	PITREnabled   bool
	PITREnabledAt string
}

DesiredDatabase is what a future database controller reconciles a managed database container against. No credentials field: see the comment in migrations/0003_desired_databases.sql for why.

type DesiredService

type DesiredService struct {
	Name  string
	Image string
	// ImageID is the local content ID a build produced for ImageIDRef.
	// Only trusted while ImageIDRef still equals Image (LocalImageID).
	ImageID    string
	ImageIDRef string
	Port       int
	// HostPort pins the host-side port Docker binds Port to
	// (internal/docker.PortBinding.HostPort), migrations/0056's own
	// operator-facing counterpart to Port itself. nil means "let Docker
	// assign one" (today's only behavior, and the ordinary case), the
	// same "an ordinary desired-state field, written on every
	// SaveDesiredService call" treatment Port itself already gets, not
	// a dedicated setter: an app.yaml redeploy or an API update is meant
	// to be able to change or clear a pin the same way it already
	// changes Port.
	HostPort *int
	// BindAddress picks which network interface Port (and HostPort, if
	// pinned) binds to on the host (migrations/0103_service_bind_address.sql):
	// "private", "public", or a literal IP, see internal/bindaddr.Resolve.
	// Unlike HostPort, this is never empty after SaveDesiredService: an
	// unset value resolves to DefaultBindAddress there, the same
	// resolve-and-always-persist-concrete treatment Strategy/Replicas
	// already get.
	BindAddress string
	Domains     []string
	Env         map[string]string
	// Command overrides the image's own default CMD
	// (internal/docker.ContainerSpec.Command), nil/empty meaning the
	// image's own default. Populated from a compose service's command:
	// (internal/compose.Service.Command); app.yaml has no equivalent
	// field yet.
	Command []string
	// Entrypoint overrides the image's own default ENTRYPOINT
	// (internal/docker.ContainerSpec.Entrypoint), same nil/empty and
	// compose-only sourcing as Command above, from
	// internal/compose.Service.Entrypoint.
	Entrypoint []string
	// DependsOn names sibling services (by their own bare service key,
	// e.g. "db", not the full "<app>-db" DesiredService.Name) this
	// service's containers wait on: internal/reconcile/application.
	// Controller resolves each name against this service's own AppID
	// before creating a container, matching real Docker Compose's
	// default depends_on: semantic (service_started), see
	// internal/spec.Service.DependsOn's own doc comment. Populated from
	// app.yaml's dependsOn: or a compose file's depends_on: (both
	// internal/compose.Service.DependsOn and the compose-expand path).
	DependsOn []string
	// DependsOnHealthy is the subset of DependsOn that waits for the
	// dependency's Ready condition (compose condition: service_healthy).
	DependsOnHealthy []string
	// PullPolicy is PullPolicyAlways to force a fresh image pull at
	// deploy time even when the tag already exists locally
	// (internal/docker.ContainerSpec.ForcePull), or empty for today's
	// existing pull-if-absent behavior. Compose-only sourcing, same as
	// Command/Entrypoint above, from internal/compose.Service.PullPolicy
	// (migrations/0098_service_pull_policy.sql).
	PullPolicy string
	// EnvDirty is true when Env was saved through the update endpoint
	// since the container was last recreated (migrations/0066): env is
	// baked in at create time, so the change isn't live yet. Written by
	// SaveDesiredService like Env itself, unlike RestartNonce/Suspended,
	// so an ordinary fresh-state redeploy clears it for free; callers
	// that bypass SaveDesiredService (RestartService,
	// UpdateServiceSuspended(false)) clear it explicitly instead.
	EnvDirty bool
	// RegistryCredentialID is which store.RegistryCredential
	// (migrations/0046_registry_credentials.sql) to authenticate with
	// when pulling Image, resolved by internal/docker at container-
	// create time; empty string means an unauthenticated (public) pull.
	// A normal deploy-time field, unlike NodeID/ProjectID/
	// StorageTargetID below: SaveDesiredService writes it on every
	// call, the same as Image itself, since it comes from the same
	// app.yaml build.type: image block.
	RegistryCredentialID string
	// SecretEnv lists env vars whose values live in secret storage
	// (internal/secrets), resolved and decrypted by the
	// application controller immediately before container creation.
	// Never holds a value itself, only the key name plus whether it was
	// declared { required: true } (see SecretEnvRef's own doc comment):
	// a name is not a secret, only the value is.
	SecretEnv []SecretEnvRef

	// DatabaseEnv names env vars whose values resolve from a managed
	// database's own connection details (internal/spec's { from:
	// "<database>.<field>" } env var syntax), resolved by the application
	// controller immediately before container creation, the same
	// "ordinary desired state, written on every save" treatment SecretEnv
	// gets: derived fresh from app.yaml on every deploy.
	DatabaseEnv map[string]DatabaseEnvRef

	// VaultEnv names env vars whose values resolve from an external
	// HashiCorp Vault instance (internal/spec's { vault: { path, key } }
	// env var syntax), resolved by the application controller
	// immediately before container creation the same way DatabaseEnv is:
	// derived fresh from app.yaml on every deploy, never persisted with
	// a value.
	VaultEnv map[string]VaultEnvRef

	Resources *ServiceResources
	Health    *ServiceHealth
	// Hooks are this service's pre/post-deploy commands
	// (internal/spec.Service.Hooks), nil meaning neither is configured.
	// A normal deploy-time field, resolved and stored as a whole on every
	// SaveDesiredService call, the same shape Resources/Health already
	// follow.
	Hooks *ServiceHooks

	// Egress is this service's outbound network allowlist
	// (internal/spec.Service.Egress), nil meaning unrestricted egress,
	// today's behavior. A normal deploy-time field written on every
	// SaveDesiredService call, same shape Resources/Health/Hooks already
	// follow: an app.yaml redeploy that drops the egress: block clears it
	// here too, the same declarative "this call replaces the whole
	// record" contract every other field in this group already has.
	// UpdateServiceEgressPolicy additionally lets PUT/DELETE
	// /api/v1/apps/{name}/egress-policy set this outside a redeploy,
	// mirroring VaultEnv's own dual write path (SetServiceVaultEnvVar).
	Egress *ServiceEgressPolicy

	// Volumes are named Docker volumes this service's container mounts
	// (migrations/0041_service_volumes.sql), previously a
	// database-controller-only capability. Empty for the ordinary case
	// (a stateless app), same "declarative, resolved before storing"
	// shape as Resources/Health above.
	Volumes []ServiceVolume

	// BindMounts are real host directories this service's container
	// mounts directly (migrations/0088_service_bind_mounts.sql), see
	// ServiceBindMount's own doc comment for how this differs from
	// Volumes and how it's gated. Empty for the ordinary case, same
	// "declarative, resolved before storing" shape Volumes itself
	// follows.
	BindMounts []ServiceBindMount

	// Labels are arbitrary operator-supplied Docker labels applied to the
	// service's container at create time (internal/spec.Service.Labels'
	// storage home, migrations/0027_service_labels.sql). Already
	// validated by the time a DesiredService exists: internal/spec.
	// ValidateLabels runs at every input boundary (app.yaml parsing,
	// the HTTP API's validateAppResource), so this package and
	// internal/docker both trust it's collision-free with this
	// platform's own reserved label namespace by the time it gets here,
	// the same "resolve/validate once, store the resolved form" shape
	// Resources/Health already follow.
	Labels map[string]string

	// NodeID is which node (internal/store's own nodes table)
	// this service should run on. Empty string is the explicit
	// "this control plane's own local node" value (the placement
	// migration comment explains why that's not NULL or a foreign key),
	// the only value that existed before this field did, so an existing
	// single-node deployment's services keep running exactly where they
	// already were on upgrade.
	NodeID string

	// Strategy and Replicas are always the *resolved* (never empty/zero)
	// values: internal/spec.Service.EffectiveStrategy()/
	// EffectiveReplicas() already define what "unset in app.yaml" means,
	// and this package stores that already-resolved decision rather than
	// re-deriving it on every read, the same "resolve once, store the
	// resolved form" shape Resources/Health already follow (app.yaml's
	// human units are converted before a DesiredService exists at all).
	// SaveDesiredService independently defends against an empty
	// Strategy/zero Replicas from any caller, so this field is never
	// ambiguous regardless of who constructs the struct.
	Strategy string
	Replicas int

	// RestartNonce is opaque and only ever compared for equality, never
	// interpreted: internal/reconcile/application.ContainerName folds it
	// into the container name hash (only when non-empty, so a service
	// that has never been restarted keeps the exact container name it
	// always has). Changing it is therefore indistinguishable, from the
	// reconciler's level-triggered point of view, from an image change:
	// the existing blue-green/recreate cutover logic already handles it
	// correctly with no new branch. Like NodeID, this is deliberately
	// excluded from SaveDesiredService's full-record-replace semantics;
	// only RestartService writes it, see that method's own doc comment.
	RestartNonce string

	// ProjectID is which store.Project (migrations/0022_projects.sql)
	// this service is organizationally grouped under; empty string is
	// "no project", a real, permanent, equally-valid state, not merely
	// "unset" (see that migration's own comment on why the column is
	// genuinely nullable rather than reusing NodeID's NOT NULL DEFAULT
	// ” convention). Like NodeID and RestartNonce, SaveDesiredService
	// never writes this field, on either an INSERT or an UPDATE: only
	// UpdateServiceProject does, see that method's own doc comment for
	// why, and internal/api/apps.go's handleCreateApp for how a create-
	// time project choice still reaches it without this method's
	// full-replace semantics being allowed to silently move an
	// already-placed service between projects.
	ProjectID string

	// EnvironmentID is which store.Environment (migrations/0054) this
	// service is tagged with; empty is "no environment", set only via
	// SetServiceEnvironment, same non-full-replace shape as ProjectID.
	EnvironmentID string

	// StorageTargetID is which store.BackupTarget (migrations/0018_backup_targets.sql)
	// this app's own object-storage credentials resolve from
	// (migrations/0030_service_storage_target.sql): the same bucket
	// connection an operator may already use for a database's scheduled
	// backups, reused rather than duplicated as a second "storage
	// target" concept. Empty string is "no storage attached", a real,
	// permanent, equally-valid state, not merely "unset" (SQL NULL,
	// mirroring ProjectID's own empty-string-means-NULL convention just
	// above, for the identical reasoning: unlike NodeID, there is no
	// meaningful non-empty default this could fall back to). Like
	// NodeID/ProjectID/RestartNonce, SaveDesiredService never writes this
	// field, on either an INSERT or an UPDATE: only
	// UpdateServiceStorageTarget does, see that method's own doc comment
	// for why. internal/reconcile/application's controller resolves the
	// target's Endpoint/Region/Bucket plus its credentials (internal/secrets,
	// store.BackupTargetSecretsKey) into env vars at container-create
	// time when this is non-empty.
	StorageTargetID string

	// DatabaseAttachment is which managed database this app resolves one
	// connection env var from (migrations/0050_service_database_env.sql),
	// set via PUT/DELETE /api/v1/apps/{name}/database rather than
	// app.yaml: see DatabaseAttachment's own doc comment for how it
	// relates to DatabaseEnv above. nil means "no attachment", a real,
	// permanent state, not merely "unset". Like NodeID/ProjectID/
	// StorageTargetID, SaveDesiredService never writes this field: only
	// UpdateServiceDatabaseAttachment does.
	DatabaseAttachment *DatabaseAttachment

	// Suspended is an operator-requested stop, distinct from delete: the
	// desired service row, image, env, and domains are untouched, only
	// the reconciler's converge target changes to zero running
	// containers (internal/reconcile/application.Controller.Reconcile).
	// Like NodeID/ProjectID/RestartNonce/StorageTargetID,
	// SaveDesiredService never writes this field: only
	// UpdateServiceSuspended does.
	Suspended bool

	// AppID is which store.App (migrations/0039_apps.sql) this service
	// belongs to; empty string means none. SaveDesiredService only
	// writes it on first INSERT, never on an ON CONFLICT update, the
	// same "an ordinary edit must never silently move it" invariant
	// NodeID/ProjectID/StorageTargetID/Suspended already have (via
	// their own dedicated Update* setters); a service's AppID is fixed
	// at creation.
	AppID string

	// IsTrial marks a service deployed via the one-click template
	// "Deploy now" path (migrations/0264_service_is_trial.sql) as an
	// obviously-temporary trial instance. Like AppID, SaveDesiredService
	// writes it only on first INSERT, never on an ON CONFLICT update: a
	// redeploy must never flip an existing service's trial status either
	// way.
	IsTrial bool

	// LogDrain is this service's external log-forwarding config
	// (migrations/0047_service_log_drain.sql), nil meaning none
	// configured. Like NodeID/ProjectID/StorageTargetID/Suspended,
	// SaveDesiredService never writes this field: only
	// UpdateServiceLogDrain does.
	LogDrain *LogDrain

	// PreviewEnvOverrides names, for a subset of this service's own env
	// vars, a preview-specific value that replaces the parent's own value
	// only when a preview environment is created from it
	// (migrations/0098_service_preview_env_overrides.sql,
	// internal/api/preview_environments.go's deployPreviewSingle); never
	// applied to this service's own deploy. Like LogDrain,
	// SaveDesiredService never writes this field: only
	// SetServicePreviewEnvOverride does.
	PreviewEnvOverrides map[string]string

	// AutoRollbackOnCrashloop opts this app into automatic rollback
	// (migrations/0106_service_auto_rollback_on_crashloop.sql): once a
	// KindCrashloop alert rule fires for this app, internal/alerting
	// points Image back at the most recent successful deploy's image
	// instead of only notifying. Off by default, like PreviewEnabled.
	// Like LogDrain/PreviewEnvOverrides, SaveDesiredService never writes
	// this field: only SetServiceAutoRollbackOnCrashloop does.
	AutoRollbackOnCrashloop bool

	// AutoRollbackOnSLOBurn opts this app into automatic rollback on a
	// KindSLOBurn alert rule (migrations/0251), one of the
	// AutoRollbackSLOBurn* constants below. "" behaves like
	// AutoRollbackSLOBurnOff, the same off-by-default shape
	// AutoRollbackOnCrashloop already establishes, but as a mode rather
	// than a bool: auto mirrors AutoRollbackOnCrashloop's own immediate
	// rollback, dry_run only records what would have happened, and
	// pause_for_human opens a pending DeployApproval for a human to
	// decide instead of deploying directly. Like AutoRollbackOnCrashloop,
	// SaveDesiredService never writes this field: only
	// SetServiceAutoRollbackOnSLOBurn does.
	AutoRollbackOnSLOBurn string

	// ExecEnabled gates POST /apps/{name}/exec and GET
	// /apps/{name}/terminal (migrations/0112_service_exec_enabled.sql,
	// internal/api/exec.go and terminal.go): both check this in addition
	// to the existing AbilityRoot IAM check, so an operator can lock a
	// specific app's shell access even for a token that otherwise has
	// full IAM abilities. Default true, unlike AutoRollbackOnCrashloop:
	// exec is available today with no equivalent gate, so this preserves
	// existing behavior for every app until someone explicitly disables
	// it. Like LogDrain/PreviewEnvOverrides/AutoRollbackOnCrashloop,
	// SaveDesiredService never writes this field: only
	// SetServiceExecEnabled does.
	ExecEnabled bool

	// BadgeEnabled opts this app into the public, unauthenticated
	// GET /api/v1/apps/{name}/badge.svg deploy-status badge
	// (migrations/0278_service_badge_enabled.sql). Default false, unlike
	// ExecEnabled: a badge exposes deploy status to anyone with the URL,
	// so it must be an explicit per-app choice. Like ExecEnabled,
	// SaveDesiredService never writes this field: only
	// SetServiceBadgeEnabled does.
	BadgeEnabled bool
}

DesiredService is what the application controller reconciles running containers against: an already-resolved image plus what it needs to run. See the migration comment in migrations/0002_desired_services.sql for why this is a distinct type from internal/spec.Service rather than reusing it directly.

func (DesiredService) LocalImageID added in v0.2.0

func (s DesiredService) LocalImageID() string

LocalImageID is ImageID when it still belongs to the current Image.

type DomainAutomationRun added in v0.2.0

type DomainAutomationRun struct {
	ID        string
	AppName   string
	Domain    string
	Result    string
	Steps     string
	Undo      string
	CreatedAt time.Time
	UndoneAt  *time.Time
}

DomainAutomationRun is one recorded go-live run. Steps and Undo are JSON owned by internal/api.

type DomainBasicAuth

type DomainBasicAuth struct {
	Domain   string
	Username string
}

DomainBasicAuth is one row of the domain_basic_auth table (migrations/0052_domain_basic_auth.sql): a username claimed for a domain already present in service_domains. No password field: that goes through internal/secrets instead, the same split CloudflareTunnelSettings uses for its own token.

type DomainErrorPage added in v0.2.0

type DomainErrorPage struct {
	Domain     string
	StatusCode int
	Body       string
}

DomainErrorPage is one row of the domain_error_page table: a status-code-to-HTML-body mapping for a domain already present in service_domains.

type DomainRedirect added in v0.2.0

type DomainRedirect struct {
	Domain     string
	TargetURL  string
	StatusCode int
}

DomainRedirect is one row of the domain_redirect table: an opt-in redirect for a domain already present in service_domains, to an arbitrary absolute target URL.

type DomainRewrite added in v0.2.0

type DomainRewrite struct {
	Prefix  string `json:"prefix,omitempty"`
	Find    string `json:"find,omitempty"`
	Replace string `json:"replace,omitempty"`
}

DomainRewrite rewrites hostnames when a domain set is copied to another environment. Prefix is prepended; otherwise a hostname equal to or under Find has that suffix replaced by Replace. Non-matching hosts are unchanged.

func (DomainRewrite) Apply added in v0.2.0

func (r DomainRewrite) Apply(host string) string

Apply returns host after the rewrite.

func (DomainRewrite) ApplyAll added in v0.2.0

func (r DomainRewrite) ApplyAll(hosts []string) []string

ApplyAll rewrites every host, dropping duplicates and blanks.

func (DomainRewrite) Empty added in v0.2.0

func (r DomainRewrite) Empty() bool

Empty reports whether the rewrite changes nothing.

type DomainTLSCert

type DomainTLSCert struct {
	Domain     string
	UploadedAt time.Time
	ExpiresAt  time.Time
}

DomainTLSCert is one row of the domain_tls_cert table (migrations/0084_domain_tls_cert.sql): a domain already present in service_domains has an operator-supplied certificate uploaded. Neither the certificate nor its private key lives here: both go through internal/secrets under DomainTLSCertSecretsKey(domain), the same split DomainBasicAuth uses for its own password. ExpiresAt is stored in the clear (a certificate's NotAfter is not sensitive) so GET can report it without ever decrypting anything.

type DomainTrafficPolicy added in v0.2.0

type DomainTrafficPolicy struct {
	Domain    string
	Kind      string
	Spec      []byte
	UpdatedAt string
}

DomainTrafficPolicy is one row of domain_traffic_policies (migrations/0421): the JSON spec of one traffic control kind for one domain. The caller (internal/api) validates Spec with internal/trafficpolicy before saving.

type DomainWAF added in v0.2.0

type DomainWAF struct {
	Domain         string
	WAFEnabled     bool
	WAFMode        string
	RateLimitRPS   int
	RateLimitBurst int
}

DomainWAF is one row of the domain_waf table: opt-in WAF and rate limiting for a domain already present in service_domains. RateLimitRPS of 0 means rate limiting is off, independent of WAFEnabled.

type EmailSettings

type EmailSettings struct {
	// Backend is "", EmailBackendSMTP, EmailBackendSES, or EmailBackendResend.
	Backend        string
	SMTPHost       string
	SMTPPort       int
	SMTPUsername   string
	SMTPFrom       string
	SESRegion      string
	SESAccessKeyID string
	SESFrom        string
	ResendFrom     string
}

EmailSettings is the single platform-wide email-sending configuration row. No credential fields: those go through internal/secrets instead.

type Environment

type Environment struct {
	ID        string
	ProjectID string
	Name      string
	Protected bool
	CreatedAt string
	// Kind, Scope and SortOrder come from migrations/0375: Kind is one of
	// the EnvironmentKind* constants, Scope is project or global.
	Kind      string
	Scope     string
	SortOrder int
}

Environment labels a service (e.g. "staging", "production") within one project (migrations/0054). Unlike Project/Organization, environments are owned by their project: deleting the project cascades.

Protected (migrations/0070) requires confirm: true on a deploy, rollback, or promotion targeting an app tagged with this environment (internal/api's deploys.go and promote.go).

type EnvironmentPatch added in v0.2.0

type EnvironmentPatch struct {
	Name      *string
	Kind      *string
	SortOrder *int
	Protected *bool
}

EnvironmentPatch carries the editable fields of an environment, nil meaning unchanged.

type EnvironmentRef added in v0.2.0

type EnvironmentRef struct {
	ID        string
	Name      string
	Kind      string
	Scope     string
	ProjectID string
	Protected bool
}

EnvironmentRef is the environment a service or database is tagged with, enough for the authorization gate to evaluate environment and kind rules.

type EnvironmentWithCounts added in v0.2.0

type EnvironmentWithCounts struct {
	Environment
	AppCount      int
	DatabaseCount int
}

EnvironmentWithCounts is an environment plus how many apps and databases are tagged with it.

type ErrDomainTaken

type ErrDomainTaken struct {
	Domain string
	Owner  string
}

ErrDomainTaken is returned by SaveDesiredService when one of svc's Domains is already claimed by a different service. Enforced here, not only by internal/spec's Validate() (which only ever sees one app.yaml at a time and so cannot see a domain already claimed by an earlier, separate deploy), because internal/reconcile/ingress's controller builds one Caddy route per domain from every desired service in a single reconcile pass: two services claiming the same host would silently produce two routes matching the same Host header, with whichever sorted last winning inside Caddy's own matcher evaluation and silently shadowing the other. See that controller's package doc comment and migrations/0011_service_domains.sql.

func (*ErrDomainTaken) Error

func (e *ErrDomainTaken) Error() string

type ExportDestination added in v0.2.0

type ExportDestination struct {
	ID        string
	Name      string
	Kind      ExportKind
	Endpoint  string
	Enabled   bool
	Apps      []string
	MinLevel  string
	Options   ExportOptions
	CreatedAt string
	UpdatedAt string
}

ExportDestination is one outbound export configuration.

type ExportKind added in v0.2.0

type ExportKind string

ExportKind selects which signal an export destination carries and which wire protocol it speaks.

const (
	ExportKindLogsHTTP     ExportKind = "logs_http"
	ExportKindLogsSyslog   ExportKind = "logs_syslog"
	ExportKindLogsLoki     ExportKind = "logs_loki"
	ExportKindAuditWebhook ExportKind = "audit_webhook"
	ExportKindAuditS3      ExportKind = "audit_s3"
	ExportKindMetricsOTLP  ExportKind = "metrics_otlp"
)

The destination kinds internal/dataexport can build a sender for.

type ExportOptions added in v0.2.0

type ExportOptions struct {
	// StorageTargetID names the storage destination an audit_s3 export writes to.
	StorageTargetID string `json:"storage_target_id,omitempty"`
	// Prefix is the object key prefix for audit_s3.
	Prefix string `json:"prefix,omitempty"`
	// Labels are static Loki stream labels.
	Labels map[string]string `json:"labels,omitempty"`
	// IntervalSeconds is the OTLP push interval.
	IntervalSeconds int `json:"interval_seconds,omitempty"`
	// Backfill makes an audit export start from the oldest row instead of now.
	Backfill bool `json:"backfill,omitempty"`
	// HeaderNames lists the secret header names so they can be shown without
	// resolving the secret.
	HeaderNames []string `json:"header_names,omitempty"`
	// HasHMACKey reports that a signing key is stored.
	HasHMACKey bool `json:"has_hmac_key,omitempty"`
}

ExportOptions holds the non-secret, kind-specific settings.

type ExportStatus added in v0.2.0

type ExportStatus struct {
	DestinationID string
	LastSuccessAt string
	LastError     string
	LastErrorAt   string
	SentTotal     int64
	DroppedTotal  int64
	FailuresTotal int64
	QueueDepth    int64
	CircuitOpen   bool
	CursorAt      string
	CursorID      string
}

ExportStatus is the persisted delivery state of one destination.

type ExposureRestriction added in v0.2.0

type ExposureRestriction struct {
	Port      int
	Protocol  string
	Allow     []string
	CreatedBy string
	CreatedAt string
}

ExposureRestriction is a desired DOCKER-USER allow-list for one published port of the control plane's own host.

type ExternalDatabase added in v0.2.0

type ExternalDatabase struct {
	Name            string
	Engine          string
	Host            string
	Port            int
	Username        string
	DatabaseName    string
	TLSMode         string
	Network         string
	NodeID          string
	ProjectID       string
	SourceContainer string
	HealthStatus    string
	HealthReason    string
	HealthLatencyMs int
	HealthCheckedAt string
	CreatedAt       string
	UpdatedAt       string
}

ExternalDatabase is a database this platform connects to but does not run. The password is stored only through internal/secrets, never on this row.

type FailedDeploy added in v0.2.0

type FailedDeploy struct {
	Attempt       DeployAttempt
	LastGoodImage string
}

FailedDeploy is an app whose most recent deploy attempt failed. LastGoodImage is the image of its newest succeeded attempt, empty if none.

type FeatureFlag

type FeatureFlag struct {
	ID                string
	Key               string
	Name              string
	Description       string
	ServiceName       string
	Enabled           bool
	RolloutPercentage int
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

FeatureFlag is a boolean (plus an optional gradual rollout percentage) an app's own code reads live at runtime, never baked into a container at create time. See migrations/0065_feature_flags.sql for why Key is globally unique rather than scoped to ServiceName.

type FirewallRule added in v0.2.0

type FirewallRule struct {
	ID string
	// NodeID is ” for the control plane's own local node, the only
	// value the reconciler currently acts on (see migration 0262's own
	// doc comment).
	NodeID     string
	Port       int
	Protocol   string
	SourceCIDR string
	Action     FirewallRuleAction
	Label      string
	CreatedAt  string
}

FirewallRule is one declarative host firewall rule internal/reconcile/firewall converges onto ufw.

type FirewallRuleAction added in v0.2.0

type FirewallRuleAction string

FirewallRuleAction is the ufw action a FirewallRule applies.

const (
	FirewallRuleActionAllow FirewallRuleAction = "allow"
	FirewallRuleActionDeny  FirewallRuleAction = "deny"
)

The two FirewallRuleAction values a rule can hold.

type ForgeDeployment added in v0.2.0

type ForgeDeployment struct {
	ID          string
	AppName     string
	Environment string
	Provider    string
	ExternalID  int64
	CommitSHA   string
	State       string
	Warning     string
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

ForgeDeployment records a deployment created on a git forge (GitHub Deployments) for an app deploy, so a later deploy can mark it inactive.

type GitHubAppConnection

type GitHubAppConnection struct {
	AppID    int64
	ClientID string
	// Slug is the App's github.com/apps/<slug> URL segment (migrations/0282).
	// Nil for a connection created before that migration, until the next
	// successful installation check backfills it (GitHub's installation
	// API response doesn't carry it, so a plain nil stays nil until the
	// operator re-registers or an "add org" attempt has somewhere to
	// resolve it from; see handleListGitHubAppInstallations's own doc
	// comment for the current gap).
	Slug *string
	// InstanceURL is the GitHub instance this App is registered
	// against: "https://github.com" for every connection until GitHub
	// Enterprise Server support (migrations/0061), a real GHES base URL
	// after. Never empty: the migration backfills the column, and
	// SaveGitHubAppConnection requires a caller to pass one.
	InstanceURL string
	CreatedAt   string
	// InstallationID and AccountLogin are nil until the App has been
	// installed on a GitHub account/org (the redirect
	// GET /api/v1/github-app/installed records). Pointers, not a
	// zero-value sentinel, since 0 is not a distinguishable "unset" value
	// for an installation ID.
	InstallationID *int64
	AccountLogin   *string
}

GitHubAppConnection is the single-row github_app_connections table (migrations/0034_github_app_connection.sql). No secret fields: see that migration's own comment for why client_secret/webhook_secret/the PEM private key live in internal/secrets instead, under GitHubAppSecretsKey().

type GitHubAppInstallation added in v0.2.0

type GitHubAppInstallation struct {
	ID             int64
	InstallationID int64
	AccountLogin   string
	// AccountType is "user" or "organization" (migrations/0282's CHECK
	// constraint), lowercased to match githubapp.InstallationInfo.
	AccountType string
	ConnectedAt string
}

GitHubAppInstallation is one row of github_app_installations (migrations/0282), one GitHub account or org the platform's single GitHub App has been installed into. Unlike GitHubAppConnection (the App's own one-time registration), this table is one-to-many: an admin can connect any number of accounts/orgs.

type GitLabAppConnection

type GitLabAppConnection struct {
	InstanceURL string
	ClientID    string
	CreatedAt   string
}

GitLabAppConnection is the single-row gitlab_app_connections table (migrations/0044_gitlab_app_connection.sql). No credential fields: client_secret and the OAuth access_token/refresh_token live in internal/secrets instead, under GitLabAppSecretsKey().

type GitSource

type GitSource struct {
	ServiceName string
	RepoURL     string
	Branch      string
	BuildType   string
	// BuildPath is the Dockerfile (or static output directory), relative to
	// the repository root.
	BuildPath string
	// BaseDirectory is the build context, relative to the repository root.
	// Empty means the repository root.
	BaseDirectory string
	// AdditionalServices lets one push fan out to sibling services under
	// the same store.App (apps_group.go): keyed by the sibling
	// DesiredService's own name, each entry carries just enough to call
	// specServiceFromDesired for it (migrations/0057_git_source_additional_services.sql).
	// A monorepo's other services rarely share this app's exact build
	// config, so this is a map, not a single shared BuildType/BuildPath.
	//
	// Mutually exclusive with Services (internal/api's
	// validateAdditionalServices enforces this at write time): an app
	// that has grown a real Services map fans out through that instead,
	// see Services's own doc comment.
	AdditionalServices map[string]GitSourceBuild
	// Services is an app.yaml-style services: map, persisted so a push
	// can re-run the same fan-out deploy.Pipeline.DeploySpec (internal/
	// api/apps_multi.go's handleDeploySpec) already performs for a
	// manual/API-triggered multi-service deploy, without an operator
	// re-submitting it by hand on every commit
	// (migrations/0063_git_source_services_spec.sql). Empty/nil for
	// every git source created before this field existed, and for any
	// git source that only ever used AdditionalServices: a webhook keeps
	// walking AdditionalServices exactly as before when this is empty,
	// see handleGitPushWebhook's own doc comment.
	Services map[string]spec.Service
	// Databases is an app.yaml-style databases: map, persisted the same
	// way and for the same reason Services is (migrations/
	// 0091_git_source_databases_spec.sql): a pull request webhook needs
	// to see which databases the app declares, in particular which ones
	// set ephemeralInPreviews, without re-fetching and parsing app.yaml
	// on every push. Independent of Services/AdditionalServices: a
	// single-service preview (no Services map at all) can still declare
	// databases.
	Databases map[string]spec.Database
	// TriggerMode picks which pushes actually deploy
	// (migrations/0106_git_source_trigger_mode.sql): spec.TriggerModePush
	// (the default, empty-string-safe zero value predating this field)
	// deploys on every push to Branch; spec.TriggerModeRelease deploys
	// only on a tag ref push or a GitHub "release" event, see
	// internal/api/git_webhook.go's gating logic.
	TriggerMode string
	// PreviewEnabled opts an app into preview environments per pull
	// request (migrations/0064_preview_environments.sql): off by
	// default, like every other opt-in feature toggle in this codebase.
	// Set only via SetGitSourcePreviewEnabled, the same "SaveGitSource
	// never writes it" shape AppID/ProjectID's own doc comments already
	// establish for a value that must never move silently on an
	// unrelated connect-form edit.
	PreviewEnabled bool
	// PostPRComments opts an app's preview environments into posting a
	// GitHub PR comment (the live preview URL, or a teardown notice) and
	// a commit status (pending/success/failure) on the pull request's
	// head commit (migrations/0081_git_source_pr_status.sql). Off by
	// default; only meaningful once PreviewEnabled is also on, but kept
	// as its own field rather than folded into PreviewEnabled: an
	// operator may want previews without the GitHub-visible noise, or
	// vice versa want the notifications wired up before flipping previews
	// on. Set only via SetGitSourcePostPRComments, the same
	// "SaveGitSource never writes it" shape PreviewEnabled's own doc
	// comment already establishes.
	PostPRComments bool
	// DeployPaths and DeployPathsIgnore filter which pushes deploy by the
	// files they changed (doublestar globs). Empty means every push
	// deploys. ReportStatus posts deploy and preview state back to the
	// forge; it defaults on. All three are set only via
	// SetGitSourceDeploySettings.
	DeployPaths       []string
	DeployPathsIgnore []string
	ReportStatus      bool
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

GitSource is one app's connected git repository (migrations/0029_service_git_sources.sql): what internal/webhook.Config held as static, single-app, server-only configuration, now persisted per app so a control plane can auto-deploy more than one app from a git push. RepoURL/Branch/BuildType/BuildPath are everything internal/api needs to rebuild a spec.Service the same way handleTriggerBuild's specServiceFromDesired already does for a manual build trigger; the deploy token (private repo auth) and webhook HMAC secret are deliberately not fields here, see GitSourceSecretsKey's own doc comment for where they actually live.

func (GitSource) SpecBuild added in v0.2.0

func (g GitSource) SpecBuild() (spec.Build, error)

SpecBuild is the spec.Build a push or preview deploy of this source runs: the one place BaseDirectory and BuildPath become a context plus a path relative to it.

type GitSourceBuild

type GitSourceBuild struct {
	BuildType string `json:"build_type"`
	BuildPath string `json:"build_path,omitempty"`
}

GitSourceBuild is one additional service's own build config within GitSource.AdditionalServices, mirroring this same struct's BuildType/BuildPath fields but scoped to a single sibling.

type GitSourceSummary added in v0.2.0

type GitSourceSummary struct {
	ServiceName string
	RepoURL     string
	Branch      string
}

GitSourceSummary is the trimmed-down row ListGitSources returns: just enough for a caller to map a repo back to the app deploying it, without paying for every JSON column GetGitSource scans.

type GiteaAppConnection added in v0.2.0

type GiteaAppConnection struct {
	InstanceURL string
	ClientID    string
	CreatedAt   string
}

GiteaAppConnection is the single-row gitea_app_connections table (migrations/0114_gitea_app_connection.sql). No credential fields: client_secret and the OAuth access_token/refresh_token live in internal/secrets instead, under GiteaAppSecretsKey(), the same split GitLabAppConnection's own doc comment establishes.

type HookRun

type HookRun struct {
	ServiceName string
	HookType    string
	Command     string
	ExitCode    int
	Success     bool
	Output      string
	RanAt       time.Time
}

HookRun is one outcome of running a service's pre/post-deploy hook command (internal/spec.Hooks, store.ServiceHooks), persisted by UpsertHookRun so GET /api/v1/apps/{name}/hook-runs can show what actually happened without a live log viewer having been open at the time.

type ImageAutoUpdate added in v0.2.0

type ImageAutoUpdate struct {
	ServiceName   string
	Enabled       bool
	LastCheckedAt *time.Time
	LastResult    string
	// WebhookHash is the hash of the registry webhook token, empty when none is set.
	WebhookHash string
}

ImageAutoUpdate is one app's opt-in to redeploy when its image tag moves (migrations/0377_image_auto_updates.sql). A missing row means disabled.

type IngressSettings

type IngressSettings struct {
	// PrimaryDomain is the control plane dashboard's own hostname, if an
	// operator has set one. Empty string means "not set", the same
	// "absence is real, permanent state" convention
	// DesiredService.ProjectID's own doc comment already establishes for
	// a nullable text column.
	PrimaryDomain string
	// ACMEEnabled switches every currently-routed host from Caddy's
	// offline internal issuer to real ACME. False (the default a fresh
	// migration seeds) is byte-identical to this codebase's behavior
	// before this table existed: see internal/ingress/routes.go's
	// BuildRoutesConfig for where this flag actually changes anything.
	ACMEEnabled bool
	// ACMEEmail is the ACME account contact address. Required by
	// internal/api's PUT /api/v1/settings/ingress validation whenever
	// ACMEEnabled is true; may be empty while ACMEEnabled is false.
	ACMEEmail string
	// ACMEDirectoryURL overrides the ACME CA's directory endpoint. Empty
	// means internal/ingress.NewACMEIssuer leaves Caddy's own compiled-in
	// default in place (Let's Encrypt's real production directory). See
	// this migration's own comment for why an operator would point this
	// at Let's Encrypt's staging directory instead.
	ACMEDirectoryURL string
	// HSTSEnabled sends Strict-Transport-Security for the dashboard's own
	// responses (migrations/0254_ingress_settings_hsts.sql). False (the
	// default) matches api.Router.hstsEnabled's existing default: see
	// that field's doc comment for why this stays opt-in. The
	// APP_ENABLE_HSTS env var still works and takes precedence when set,
	// so existing deployments that already export it keep behaving
	// exactly as before (see cmd/levelrail/main.go's hstsEnabled).
	HSTSEnabled bool
	// FallbackDomainsDisabled turns off the automatic
	// <app>.<dashed-ip>.sslip.io hostname apps without a domain get
	// (migrations/0290). Default false: the hostname is on.
	FallbackDomainsDisabled bool
	// PublicHTTPSPort is the port clients use to reach this ingress when a
	// proxy fronts it (migrations/0416). 0 means the ingress listen port.
	PublicHTTPSPort int
	// TLSTerminatedUpstream marks a proxy in front as the TLS owner: no ACME
	// here and links use the public port (migrations/0416).
	TLSTerminatedUpstream bool
	// AppsBaseDomain is the suffix apps created without a domain get as
	// <app>.<base> (migrations/0418). Empty means not set.
	AppsBaseDomain string
	// DNSCNAMETarget makes automatic records CNAMEs to this host instead of
	// A/AAAA to the detected public IP. DNSTTLSeconds 0 is the provider's auto.
	DNSCNAMETarget string
	DNSTTLSeconds  int
	// DNSProxied turns Cloudflare's proxy on for records Levelrail creates.
	DNSProxied bool
}

IngressSettings is the platform-wide ingress configuration row (migrations/0024_ingress_settings.sql): whether to obtain real ACME certificates instead of Caddy's offline internal issuer, and an optional primary domain for the control plane's own dashboard. There is always exactly one of these (id = 1), never zero and never more than one, so GetIngressSettings never returns a not-found error the way GetProject/GetDesiredService do: the row is seeded by the migration itself.

func (IngressSettings) EffectiveACMEEnabled added in v0.2.0

func (s IngressSettings) EffectiveACMEEnabled() bool

EffectiveACMEEnabled is false whenever TLS is terminated upstream, so a stored acme_enabled is kept but never acted on.

func (IngressSettings) PublicLinkPort added in v0.2.0

func (s IngressSettings) PublicLinkPort() int

PublicLinkPort is the explicit port generated links must carry: the configured public port, 443 when TLS is upstream without one, else 0 (the caller's own default applies).

type Invite

type Invite struct {
	ID         string
	Email      string
	Role       string
	Abilities  []string
	TokenHash  string
	CreatedBy  string
	CreatedAt  time.Time
	ExpiresAt  time.Time
	AcceptedAt *time.Time
	RevokedAt  *time.Time
}

Invite is one outstanding team invite (migrations/0086). TokenHash is the only form of the invite token ever persisted, same convention as PasswordResetToken.TokenHash. Role is the curated preset name (internal/api/roles.go) the invite was created with, empty when Abilities was hand-picked instead; accepting the invite always applies Abilities, the already-resolved set either way.

type LoadBalancerRow added in v0.2.0

type LoadBalancerRow struct {
	Service   string
	Config    string
	UpdatedAt string
}

LoadBalancerRow is one configured balancer joined to its app.

type LogArchivePolicy added in v0.2.0

type LogArchivePolicy struct {
	ID              string
	AppName         string
	TargetID        string
	Enabled         bool
	IntervalSeconds int64
	RetentionDays   int
	WatermarkNs     int64
	LastRunAt       string
	LastSuccessAt   string
	LastError       string
	CreatedAt       string
}

LogArchivePolicy schedules node-local logs to a storage destination. AppName is empty for the global policy covering every app.

type LogArchiveRun added in v0.2.0

type LogArchiveRun struct {
	ID         string
	PolicyID   string
	AppName    string
	TargetID   string
	Kind       string
	FromNs     int64
	ToNs       int64
	Status     string
	Objects    int
	Lines      int64
	Bytes      int64
	Error      string
	StartedAt  string
	FinishedAt string
}

LogArchiveRun is one archive attempt.

type LogDrain

type LogDrain struct {
	Type    LogDrainType `json:"type"`
	Target  string       `json:"target"`
	Enabled bool         `json:"enabled"`
}

LogDrain is one service's external log-forwarding configuration (migrations/0047_service_log_drain.sql), the Coolify-parity per-app log_drain field: forward this service's container log stream to Target alongside the existing node-local store, in addition to it, never instead of it. Enabled lets an operator keep Target configured but pause forwarding without losing the value.

type LogDrainType

type LogDrainType string

LogDrainType selects which external sink protocol a service's log drain uses.

const (
	LogDrainHTTP   LogDrainType = "http"
	LogDrainSyslog LogDrainType = "syslog"
)

The two sink protocols internal/telemetry's forwarder knows how to build (internal/telemetry/drain.go).

type LoginApproval added in v0.2.0

type LoginApproval struct {
	ID          string
	UserID      string
	BrowserHash string
	RequesterIP string
	UserAgent   string
	Status      string
	DecidedBy   string
	CreatedAt   time.Time
	ExpiresAt   time.Time
}

LoginApproval is a password sign-in from an unrecognized browser, paused until one of the account's existing sessions approves or denies it.

type LoginCodeChallenge added in v0.2.0

type LoginCodeChallenge struct {
	ID          string
	UserID      string
	BrowserHash string
	CodeHash    string
	Salt        string
	RequesterIP string
	UserAgent   string
	Status      string
	Attempts    int
	CreatedAt   time.Time
	ExpiresAt   time.Time
}

LoginCodeChallenge is one "sign in with a code" request. CodeHash and Salt are the only form of the code ever persisted.

type MajorUpgrade added in v0.2.0

type MajorUpgrade struct {
	ID             string
	DatabaseName   string
	FromVersion    string
	ToVersion      string
	Status         string
	Phase          string
	SnapshotVolume string
	Error          string
	StartedAt      string
	FinishedAt     string
}

MajorUpgrade is one guarded major version upgrade attempt of a database.

type ManagedDNSRecord added in v0.2.0

type ManagedDNSRecord struct {
	Domain     string
	Provider   string
	Zone       string
	Name       string
	RecordType string
	Value      string
	AppName    string
	CreatedAt  time.Time
}

ManagedDNSRecord is a DNS record Levelrail created for a domain, so only records it owns are ever removed (migrations/0418).

type MigrationItem added in v0.2.0

type MigrationItem struct {
	SessionID     string
	SourceDB      string
	SizeBytes     int64
	Tables        int
	Extensions    []string
	TargetName    string
	TargetVersion string
	Selected      bool
	Status        string
	Reason        string
	CreatedTarget bool
	Checked       int
	Mismatched    int
	Detail        string
	StartedAt     time.Time
	FinishedAt    time.Time
}

MigrationItem is one source database within a session.

type MigrationSession added in v0.2.0

type MigrationSession struct {
	ID     string
	Engine string
	Host   string
	Port   int
	User   string
	TLS    bool
	NodeID string
	// HelperNetwork and SourceContainer are set when the source is a local
	// container the helper reaches over that container's own network.
	HelperNetwork   string
	SourceContainer string
	ServerVersion   string
	ServerMajor     int
	FreeBytes       int64
	Step            string
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

MigrationSession is one source server being migrated (migrations/0395_migration_hub.sql).

type Model added in v0.2.0

type Model struct {
	Name          string
	Engine        string
	ModelRef      string
	NodeID        string
	GPUCount      int
	GPUDeviceIDs  []string
	ContextLength int
	Quantization  string
	Domain        string
	APIKeyHash    string
	APIKeyPrefix  string
	HFTokenSet    bool
	EndpointDial  string
	RestartNonce  int
	Deleting      bool
	CreatedAt     time.Time
	UpdatedAt     time.Time

	// Residency is ResidencyAlways or ResidencyOnDemand. IdleTTLSeconds 0
	// means the platform default. LastActiveAt is the last gateway request
	// or wake; zero means never. ResidencyState is written by the reconciler.
	Residency      string
	IdleTTLSeconds int
	LastActiveAt   time.Time
	ResidencyState string

	// SwapGroup is empty (no group) or a name shared by other models on
	// the same node/GPU: at most one model in a non-empty group may be
	// resident at once, waking one stops the group's current resident
	// sibling first.
	SwapGroup string
}

Model is one AI model resource served from a GPU node. NodeID "" is the local node. GPUCount -1 means every GPU on the node; GPUDeviceIDs win over GPUCount when set.

type ModelKey added in v0.2.0

type ModelKey struct {
	ID          string
	ModelName   string
	Name        string
	KeyHash     string
	KeyPrefix   string
	RPM         int
	TPM         int
	MaxParallel int
	AllowPaths  []string
	AllowModels []string
	ReplacedBy  string
	CreatedAt   time.Time
	ExpiresAt   *time.Time
	RevokedAt   *time.Time
	LastUsedAt  *time.Time
	TPD         int
	CreatedBy   string
}

ModelKey is one named virtual API key of a model. Only the hash of the key is stored. A limit of 0 means unlimited; empty allow lists mean any.

type ModelUsage added in v0.2.0

type ModelUsage struct {
	ModelName     string
	KeyID         string
	HourStart     time.Time
	Requests      int64
	Status2xx     int64
	Status4xx     int64
	Status5xx     int64
	RateLimited   int64
	UsageRequests int64
	InputTokens   int64
	OutputTokens  int64
	BytesOut      int64
	DurationMsSum int64
	TTFTMsSum     int64
	TTFTCount     int64
}

ModelUsage is the gateway usage of one model and key in one hour. Token counts only cover requests whose response carried a usage object (UsageRequests); the rest add to Requests alone.

type NetworkShare added in v0.2.0

type NetworkShare struct {
	ID           string
	Name         string
	Protocol     string
	Host         string
	RemotePath   string
	MountOptions string
	Username     string
	CreatedAt    string
}

NetworkShare is an external NFS or CIFS/SMB export this control plane can mount as a Docker local-driver volume. No password field: a CIFS share's credential goes through internal/secrets, keyed by NetworkShareSecretsKey(id), the same split RegistryCredential uses for its own password. Username is CIFS-only; empty for an NFS share, which authenticates by source IP/export rules instead.

type Node

type Node struct {
	ID              string
	Name            string
	Address         string
	Status          NodeStatus
	CertFingerprint string
	JoinedAt        *time.Time
	LastSeenAt      *time.Time

	// Schedulable is cordon's backing state (migration
	// 0013): false means "unschedulable for new placements, but not
	// evacuated," an operator-initiated state independent of Status.
	// New nodes are always schedulable (SaveNode never trusts this
	// field, matching SaveDesiredService's own "not every field of the
	// input struct is honored, some have a dedicated mutation method"
	// convention); the only way to change it is SetNodeSchedulable.
	Schedulable bool

	// AcceptsAppWorkloads and AcceptsBuildWorkloads are the
	// node capability flags (migrations/0010_node_workloads.sql): which
	// kinds of work this node is willing to run, independent of each
	// other. A node can be either, both, or neither. See the migration's
	// own doc comment for the default values new and pre-existing nodes
	// get.
	AcceptsAppWorkloads   bool
	AcceptsBuildWorkloads bool

	// MeshPublicKey and MeshAddress are the WireGuard mesh
	// state (migrations/0014_node_mesh.sql). Both empty means this node
	// has not joined the mesh yet, which is a normal transient state for
	// a node that enrolled but has not brought a device up.
	//
	// Deliberately plain strings rather than internal/network's Key and
	// netip.Addr: this package stores rows, and having it import
	// internal/network to parse and validate them would put the mesh's
	// own rules (a key is 32 bytes, an address is inside the mesh CIDR)
	// in two places. internal/network.ValidateInventory is the one place
	// those rules live; the reconciler that reads these converts and
	// validates on the way in.
	MeshPublicKey string
	MeshAddress   string

	// Certificate lifecycle state (migration 0135, ADR 021).
	CertNotAfter        *time.Time
	CertSerial          string
	CertRenewedAt       *time.Time
	CertGeneration      int
	CertKeyOrigin       string
	PrevCertFingerprint string
	PrevCertValidUntil  *time.Time
	CertRevokedAt       *time.Time

	// Agent self-report (migration 0136); empty until an agent that sends
	// it connects.
	AgentVersion    string
	AgentCommit     string
	AgentOS         string
	AgentArch       string
	AgentReportedAt *time.Time

	// Region is an optional, free-text operator-facing location label
	// (migration 0252, e.g. "hetzner-fsn1", "home-lab"): display and
	// grouping metadata for the network topology view only, never a
	// routing or access-control input. "" means unset. Like
	// AcceptsAppWorkloads, SaveNode never writes this; only
	// UpdateNodeRegion does.
	Region string

	CreatedAt time.Time
	UpdatedAt time.Time
}

Node is one managed machine in the fleet. A row is created by the join-token enrollment flow, not by this package's own CRUD surface: SaveNode exists as a real, directly testable primitive for that future enrollment code to call, but nothing in internal/api wires an operator-facing "create a node" HTTP route to it yet, deliberately, per this migration's own doc comment.

func (Node) AcceptsCert added in v0.2.0

func (n Node) AcceptsCert(fingerprint string, now time.Time) bool

AcceptsCert reports whether fingerprint may authenticate as n at now: the current certificate, or the previous one inside its overlap window, and never while revoked.

type NodeAgentInfo added in v0.2.0

type NodeAgentInfo struct {
	Version string
	Commit  string
	OS      string
	Arch    string
}

NodeAgentInfo is what an agent reports about its own build and platform.

type NodeAgentVersionChange added in v0.2.0

type NodeAgentVersionChange struct {
	ID          string
	NodeID      string
	NodeName    string
	FromVersion string
	ToVersion   string
	ObservedAt  time.Time
}

NodeAgentVersionChange is one observed change of a node's agent version (migrations/0401). FromVersion is empty for the first report.

type NodeCert added in v0.2.0

type NodeCert struct {
	Fingerprint string
	Serial      string
	NotAfter    time.Time
	KeyOrigin   string
}

NodeCert is a newly issued certificate's identifying data.

type NodeDrain added in v0.2.0

type NodeDrain struct {
	ID           string
	NodeID       string
	TargetNodeID string
	Status       string
	Error        string
	Blocked      []NodeDrainBlocked
	StartedAt    string
	UpdatedAt    string
	FinishedAt   string
}

NodeDrain is one persisted drain of a node.

type NodeDrainBlocked added in v0.2.0

type NodeDrainBlocked struct {
	Kind   string `json:"kind"`
	Name   string `json:"name"`
	Reason string `json:"reason"`
}

NodeDrainBlocked is a resource a drain could not move, with the reason.

type NodeGPU added in v0.2.0

type NodeGPU struct {
	NodeID    string
	Info      gpu.Info
	UpdatedAt time.Time
}

NodeGPU is a node's stored GPU snapshot.

type NodeJoinToken

type NodeJoinToken struct {
	ID        string
	TokenHash string
	CreatedAt time.Time
	ExpiresAt time.Time
	// UsedAt is nil until the token is exchanged for a node enrollment.
	// Single-use is enforced by MarkNodeJoinTokenUsed's
	// atomic conditional UPDATE, not by application code checking this
	// field first: two concurrent exchange attempts racing on the same
	// token must not both succeed, the identical concurrency hazard
	// store.CreateUser's own doc comment documents for first-run
	// registration.
	UsedAt *time.Time
	// Purpose is NodeJoinTokenPurposeEnroll (new node) or
	// NodeJoinTokenPurposeReenroll (new certificate for NodeID).
	Purpose string
	NodeID  string
}

NodeJoinToken is a one-time credential (ADR 003: "the control plane issues a one-time join token, agent exchanges it for a client certificate") an operator pastes into a new node's enrollment command. Only the hash is ever stored here, the same shape APIToken/api_tokens (0007) already established: the plaintext is generated once by internal/api, shown to the operator once, and never recoverable from this table again.

type NodeListFilter added in v0.2.0

type NodeListFilter struct {
	Query         string
	Limit, Offset int
}

NodeListFilter narrows and pages the node list, mirroring AppListFilter (apps_list.go). Zero values mean no filter; Limit 0 means no paging.

type NodeMove added in v0.2.0

type NodeMove struct {
	ID             string
	Kind           string
	Resource       string
	FromNodeID     string
	ToNodeID       string
	Stateful       bool
	Volumes        []string
	Phase          string
	Status         string
	Error          string
	Attempts       int
	Steps          []NodeMoveStep
	DrainID        string
	PlacedAt       string
	VerifyDeadline string
	StartedAt      string
	UpdatedAt      string
	FinishedAt     string
}

NodeMove is one persisted move of an app or database between nodes.

type NodeMoveFilter added in v0.2.0

type NodeMoveFilter struct {
	Kind     string
	Resource string
	DrainID  string
	Status   string
	Limit    int
}

NodeMoveFilter narrows ListNodeMoves; empty fields match everything.

type NodeMoveStep added in v0.2.0

type NodeMoveStep struct {
	Phase   string `json:"phase"`
	Outcome string `json:"outcome"`
	Message string `json:"message,omitempty"`
	At      string `json:"at"`
}

NodeMoveStep is one recorded phase transition of a node move.

type NodeProvision added in v0.2.0

type NodeProvision struct {
	ID               string
	Provider         string
	Region           string
	Size             string
	Name             string
	Role             string
	Status           string
	ProviderServerID string
	IPAddress        string
	// NodeID is set once the enrolled node is found by Name.
	NodeID        string
	FailureReason string
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

NodeProvision tracks one cloud VM created on an operator's behalf, through to the join-token enrollment it's expected to complete. Correlated to the real store.Node it produces by Name: the cloud-init script sets APP_NODE_NAME to this row's own Name, so the enrolled node's Name is how a later read finds it (nodes.name is already UNIQUE, migrations/0008_nodes.sql).

type NodeStatus

type NodeStatus string

NodeStatus is a node's current lifecycle state.

const (
	NodeStatusPending NodeStatus = "pending"
	NodeStatusOnline  NodeStatus = "online"
	NodeStatusOffline NodeStatus = "offline"
	// NodeStatusCordoned is currently unused: cordon's real
	// backing state is the Schedulable field / schedulable column
	// (migration 0010), a separate axis from Status, exactly matching
	// this constant's own original doc comment promise that a cordoned
	// node "can still be online." Left defined rather than removed,
	// since nothing ever set it and removing an exported
	// constant is a needless breaking change for zero benefit.
	NodeStatusCordoned NodeStatus = "cordoned"
)

The four states a node can be in. Pending is the state a newly enrolled node starts in (join token exchanged, no heartbeat received yet); Online/Offline track heartbeat presence; Cordoned means "unschedulable for new placements, but not evacuated", a distinct axis from Online/Offline, not a replacement for it: a cordoned node can still be online.

type NodeStatusEvent added in v0.2.0

type NodeStatusEvent struct {
	ID         int64
	NodeID     string
	FromStatus NodeStatus
	ToStatus   NodeStatus
	CreatedAt  time.Time
}

NodeStatusEvent is one recorded node status transition.

type OAuthIdentity

type OAuthIdentity struct {
	ID             string
	UserID         string
	Provider       string
	ProviderUserID string
	CreatedAt      time.Time
}

OAuthIdentity is one linked external account. Uniqueness (at most one per provider per user, never linked to two users) is enforced by migrations/0035's own indexes, not application code.

type OAuthProviderSettings

type OAuthProviderSettings struct {
	Provider           string
	Enabled            bool
	ClientID           string
	AllowedEmailDomain string
	IssuerURL          string
	DisplayName        string
}

OAuthProviderSettings is one row of oauth_provider_settings. IssuerURL and DisplayName are only meaningful for the oidc provider.

type ObservabilitySettings added in v0.2.0

type ObservabilitySettings struct {
	ExternalDashboardURL string
}

ObservabilitySettings is the single platform-wide row: the external Grafana (or other dashboard) URL an operator links out to from the metrics charts. Empty means unset: no link is shown.

type OnboardingState added in v0.2.0

type OnboardingState struct {
	Completed   bool
	CurrentStep string
	// Steps maps a wizard step id to "completed" or "skipped".
	Steps map[string]string
}

OnboardingState is the single platform-wide setup wizard row.

type OpenOption added in v0.2.0

type OpenOption func(*openConfig)

OpenOption customizes Open.

func WithPreMigrateHook added in v0.2.0

func WithPreMigrateHook(h PreMigrateHook) OpenOption

WithPreMigrateHook registers a hook that runs only when an existing database has migrations pending (never for a brand new one).

type Organization

type Organization struct {
	ID        string
	Name      string
	CreatedAt string
}

Organization groups projects (migrations/0054, mirroring Project's own opaque-id, no-auth-attached shape). Deleting an organization leaves its projects in place, org-less again (ON DELETE SET NULL).

type OrphanSighting added in v0.2.0

type OrphanSighting struct {
	Kind        string
	NodeID      string
	Name        string
	FirstSeenAt time.Time
}

OrphanSighting records when a leftover resource was first seen.

type PITRRestoreHistory added in v0.2.0

type PITRRestoreHistory struct {
	ID                  string
	DatabaseName        string
	BaseBackupHistoryID string
	TargetTimestamp     string
	Status              string
	Error               string
	StartedAt           string
	FinishedAt          string
}

PITRRestoreHistory is one attempted point-in-time restore of one database, restore_history's PITR counterpart (see migrations/0115_database_pitr.sql's own comment for why this is a separate table rather than new columns on restore_history).

type PendingTeardown added in v0.2.0

type PendingTeardown struct {
	Name          string
	NodeID        string
	CreatedAt     time.Time
	Attempts      int
	LastError     string
	LastAttemptAt *time.Time
}

PendingTeardown is a deleted app whose containers are not yet confirmed gone.

type Pipeline added in v0.2.0

type Pipeline struct {
	ID        string
	AppName   string
	Name      string
	Source    string
	YAML      string
	Enabled   bool
	CreatedAt time.Time
	UpdatedAt time.Time
	// SourceSHA is the commit a repo-sourced pipeline was synced from.
	SourceSHA string
	// SyncedHash is the SHA-256 of the YAML as synced; a different hash of
	// the current YAML means the definition was edited afterwards.
	SyncedHash string
}

Pipeline is one saved pipeline definition scoped to an app.

type PipelineAppCounts added in v0.2.0

type PipelineAppCounts struct {
	AppName         string
	Running         int
	Succeeded24h    int
	Failed24h       int
	Cancelled24h    int
	WaitingApproval int
	Held            int
}

PipelineAppCounts is one app's run tally for the overview summary.

type PipelineApproval added in v0.2.0

type PipelineApproval struct {
	ID              int64
	RunID           string
	JobID           string
	StepIndex       int
	Message         string
	RequiredAbility string
	Decision        string
	DecidedBy       string
	Comment         string
	ExpiresAt       *time.Time
	CreatedAt       time.Time
	DecidedAt       *time.Time
}

PipelineApproval is one manual approval gate.

type PipelineJob added in v0.2.0

type PipelineJob struct {
	ID          string
	RunID       string
	Key         string
	DisplayName string
	Stage       string
	NeedsJSON   string
	MatrixJSON  string
	NodeID      string
	OutputsJSON string
	Status      string
	Reason      string
	Attempt     int
	StartedAt   *time.Time
	FinishedAt  *time.Time
	Steps       []PipelineStep
}

PipelineJob is one expanded job of a run. NeedsJSON and MatrixJSON are JSON-encoded (a string list and a string map).

type PipelineLogLine added in v0.2.0

type PipelineLogLine struct {
	ID        int64
	RunID     string
	JobKey    string
	StepIndex int
	Stream    string
	Line      string
	CreatedAt time.Time
}

PipelineLogLine is one captured output line.

type PipelineRun added in v0.2.0

type PipelineRun struct {
	ID               string
	PipelineID       string
	AppName          string
	Number           int
	TriggerKind      string
	TriggerActor     string
	Ref              string
	CommitSHA        string
	InputsJSON       string
	Definition       string
	ConcurrencyGroup string
	CancelInProgress bool
	Status           string
	Reason           string
	CancelRequested  bool
	CreatedAt        time.Time
	StartedAt        *time.Time
	FinishedAt       *time.Time
	// HoldState is "" for a normal run, or pending/approved/rejected for a
	// run created held for approval. A pending run starts no job.
	HoldState  string
	HoldReason string
	HoldBy     string
	HoldAt     *time.Time
	// ReportProvider, ReportState and ReportURL record the last commit
	// status posted to the git forge (empty when none was). ReportWarning
	// holds why posting failed; a failure never fails the run.
	ReportProvider string
	ReportState    string
	ReportURL      string
	ReportWarning  string
}

PipelineRun is one execution of a pipeline. Definition is the YAML snapshot the run started with.

type PipelineRunFilter added in v0.2.0

type PipelineRunFilter struct {
	Status   string
	App      string
	Pipeline string
	Trigger  string
	// BeforeCreated and BeforeID form the keyset cursor: only rows strictly
	// older than this position are returned.
	BeforeCreated time.Time
	BeforeID      string
	Limit         int
}

PipelineRunFilter narrows ListPipelineRunRows. Status accepts a run status or the virtual value "held" (a run awaiting a hold decision); "running" matches queued and running runs.

type PipelineRunRow added in v0.2.0

type PipelineRunRow struct {
	ID                string
	PipelineID        string
	PipelineName      string
	AppName           string
	Number            int
	TriggerKind       string
	Ref               string
	CommitSHA         string
	Status            string
	Reason            string
	CreatedAt         time.Time
	StartedAt         *time.Time
	FinishedAt        *time.Time
	HoldState         string
	PendingApprovalID int64
	ApprovalAbility   string
}

PipelineRunRow is one run in the cross-app overview. It carries no logs, steps, or definition snapshot.

type PipelineStep added in v0.2.0

type PipelineStep struct {
	JobID      string
	Index      int
	Name       string
	Kind       string
	Status     string
	Reason     string
	ExitCode   *int
	Attempt    int
	StartedAt  *time.Time
	FinishedAt *time.Time
}

PipelineStep is one step row of a job.

type PipelineSync added in v0.2.0

type PipelineSync struct {
	AppName     string
	RepoIsTruth bool
	LastSHA     string
	LastSyncAt  time.Time
	LastError   string
}

PipelineSync is an app's repository sync settings and last outcome. The zero value (no row) means repo_is_truth off and never synced.

type PipelineTriggerLog added in v0.2.0

type PipelineTriggerLog struct {
	ID        int64
	AppName   string
	Pipeline  string
	Event     string
	Ref       string
	SHA       string
	Decision  string
	Reason    string
	RunID     string
	CreatedAt time.Time
}

PipelineTriggerLog records why a git event did or did not start a run.

type Policy

type Policy struct {
	ID          string
	Name        string
	Description string
	Document    string // raw JSON; internal/api's iam package parses/validates it
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

Policy is one IAM-style policy document (iam.go's Document type holds the actual Allow/Deny statements): additive on top of a principal's flat Abilities list, either narrowing a broad ability down to specific resources (a Deny statement) or granting an ability scoped to specific resources without granting it globally (an Allow statement).

type PolicyAttachment

type PolicyAttachment struct {
	ID            string
	PolicyID      string
	PrincipalType string
	PrincipalID   string
	CreatedAt     time.Time
}

PolicyAttachment links one Policy to one principal (a user or an API token). PrincipalType is "user" or "token", matching audit_log's own actor_type discriminator convention rather than a real foreign key, since a principal isn't a single referenceable table.

type PolicyVersion added in v0.2.0

type PolicyVersion struct {
	ID          string
	PolicyID    string
	Version     int
	Name        string
	Description string
	Document    string
	Actor       string
	CreatedAt   time.Time
}

PolicyVersion is one saved document of a policy.

type PreMigrateHook added in v0.2.0

type PreMigrateHook func(ctx context.Context, db *DB, from, to int)

PreMigrateHook runs before pending migrations are applied to an existing database, with the current and target schema versions.

type PreviewAppSettings added in v0.2.0

type PreviewAppSettings struct {
	AppName           string
	OnLimit           string
	AllowForkPreviews bool
	TTLHours          int
	UpdatedAt         string
	// MaxPreviews overrides the platform per-app cap when above zero.
	MaxPreviews int
	// MemoryLimit and CPULimit override the platform preview resource
	// defaults when set.
	MemoryLimit string
	CPULimit    float64
	// IdleSleepMinutes overrides the platform idle sleep default when above
	// zero.
	IdleSleepMinutes int
	// DatabaseStrategy is one of the PreviewDatabaseStrategy* values.
	DatabaseStrategy string
	// SeedDatabase names the database whose latest backup seeds a preview
	// under the seed strategy.
	SeedDatabase string
	// AllowForkSecrets lets an approved or allowed fork preview receive the
	// app's secret environment variables; off by default.
	AllowForkSecrets bool
	// GateBasicAuth puts HTTP basic auth (GateUsername) in front of every
	// preview domain of the app.
	GateBasicAuth bool
	GateUsername  string
	// AllowIndexing lets search engines index preview URLs; off by default.
	AllowIndexing bool
}

PreviewAppSettings is one app's preview policy: what happens at the concurrency cap, whether fork pull requests may deploy, and an optional per-app TTL in hours (0 means the control plane default).

func DefaultPreviewAppSettings added in v0.2.0

func DefaultPreviewAppSettings(appName string) PreviewAppSettings

DefaultPreviewAppSettings is the policy an app has before anyone saves one.

type PreviewDatabaseIsolation added in v0.2.0

type PreviewDatabaseIsolation struct {
	ID                   string
	PreviewEnvironmentID string
	DatabaseName         string
	SourceKey            string
	RoleName             string
	SecretEnvKey         string
	Status               string
	StatusReason         string
	CreatedAt            string
	UpdatedAt            string
}

PreviewDatabaseIsolation links a PreviewEnvironment to an isolated role or ACL user (a Postgres role, or a Redis ACL user) provisioned on an existing (not preview-owned) DesiredDatabase: one row per (PreviewEnvironmentID, SourceKey). DatabaseName is the existing desired_databases.name the role/user was created on; this table owns nothing about that database's own lifecycle, only the credential's.

type PreviewEnvironment

type PreviewEnvironment struct {
	ID           string
	AppName      string
	PRNumber     int
	PreviewAppID string
	// EnvironmentID is the shared Preview-tier store.Environment this
	// preview is tagged with, empty when tagging failed or hasn't run
	// yet; see internal/api's ensurePreviewEnvironmentTier.
	EnvironmentID string
	Branch        string
	HeadSHA       string
	// Domain is empty when no base domain is configured, or when a
	// domain collision forced this preview to deploy without one (see
	// StatusReason for that case).
	Domain string
	Status string
	// StatusReason explains a non-obvious Status, e.g. a domain
	// collision that left the preview Active but domain-less, or a
	// build failure's own error message when Status is Failed. Empty for
	// the ordinary success case.
	StatusReason string
	CreatedAt    string
	UpdatedAt    string
	// CommentID is the provider ID of the single status comment kept on the
	// pull request, 0 until one has been posted.
	CommentID int64
	// IsFork records that the pull request's head repository differs from
	// its base repository; HeadRepo is that head repository's full name.
	IsFork   bool
	HeadRepo string
	// ExtendedUntil is an operator-granted expiry (RFC3339Nano UTC) that
	// outlives the TTL; empty when never extended.
	ExtendedUntil string
}

PreviewEnvironment is one pull request's preview deployment (migrations/0064_preview_environments.sql): a store.App/DesiredService named PreviewAppID, deployed from Branch at HeadSHA, optionally tagged with EnvironmentID and reachable at Domain.

func (PreviewEnvironment) Occupies added in v0.2.0

func (p PreviewEnvironment) Occupies() bool

Occupies reports whether a preview in this status holds a concurrency slot. A failed preview runs nothing, so it does not.

type PreviewEphemeralDatabase added in v0.2.0

type PreviewEphemeralDatabase struct {
	ID                   string
	PreviewEnvironmentID string
	DatabaseName         string
	SourceKey            string
	Engine               string
	Version              string
	Status               string
	StatusReason         string
	CreatedAt            string
	UpdatedAt            string
}

PreviewEphemeralDatabase links a PreviewEnvironment to one database.Controller-managed DesiredDatabase provisioned just for it: one row per (PreviewEnvironmentID, SourceKey), SourceKey being the app.yaml databases: key (spec.Database.EphemeralInPreviews) this instance stands in for. DatabaseName is a desired_databases.name this row's own container reconciles against through the exact same dynamicSource/database.Controller path every other managed database uses; this table adds no reconciliation logic of its own, only the linkage a preview's teardown needs to find and remove it.

type ProbeAttempt added in v0.2.0

type ProbeAttempt struct {
	ID              int64
	DeployAttemptID string
	ServiceName     string
	Image           string
	Target          string
	Success         bool
	StatusCode      int
	ExitCode        int
	Error           string
	LatencyMS       int64
	ProbedAt        time.Time
}

ProbeAttempt is one individual readiness-probe attempt made during a deploy's cutover (migrations/0284_probe_attempts.sql), reported by internal/probe.WithOnAttempt via internal/reconcile/application's waitReady. ServiceName and Image are used only by RecordProbeAttempt, to resolve DeployAttemptID the same way RecordRollout/ RecordRolloutFailure already do (deploy_attempt_safety.go); the table itself stores neither, so ListProbeAttempts always leaves both empty.

type Project

type Project struct {
	ID        string
	Name      string
	CreatedAt string
	OrgID     string
}

Project is a lightweight, non-auth organizational grouping (see migrations/0022_projects.sql's own comment for the "why" and its explicit boundary against the deferred teams/RBAC work): a name an app or database can optionally be filed under, nothing more. There is no owner, no member list, no permission of any kind attached to a project; the single admin user sees every project exactly the way it already sees every app and database.

type ProxyIntegrationSettings added in v0.2.0

type ProxyIntegrationSettings struct {
	Mode            string
	DynamicDir      string
	EntrypointHTTP  string
	EntrypointHTTPS string
	CertResolver    string
	UpstreamHost    string
}

ProxyIntegrationSettings is the single proxy_integration_settings row.

func (ProxyIntegrationSettings) Enabled added in v0.2.0

func (s ProxyIntegrationSettings) Enabled() bool

Enabled reports whether managed routes are on.

type ProxyRouteStatus added in v0.2.0

type ProxyRouteStatus struct {
	Domain       string
	Target       string
	FileName     string
	Written      bool
	WrittenAt    time.Time
	ProxyLoaded  string
	Reachable    bool
	StatusCode   int
	CertIssuer   string
	CertNotAfter time.Time
	CertTrusted  bool
	LastError    string
	VerifiedAt   time.Time
}

ProxyRouteStatus is one domain's managed route: what was written and the outcome of the last end to end probe.

type PrunedBackup

type PrunedBackup struct {
	TargetID  string
	ObjectKey string
}

PrunedBackup is one backup_history row PruneBackupHistory removed: its TargetID and ObjectKey, enough for a caller (internal/backup. Scheduler) to also delete the object those pointed to in the target bucket. PruneBackupHistory itself only removes the store row.

type PushSubscription added in v0.2.0

type PushSubscription struct {
	ID         string
	UserID     string
	Endpoint   string
	P256dh     string
	Auth       string
	UserAgent  string
	CreatedAt  time.Time
	LastUsedAt *time.Time
}

PushSubscription is one browser's Web Push registration (migrations/0271), scoped to the account that registered it. Endpoint is globally unique (a push service mints one per subscribe call), so re-subscribing the same browser upserts rather than duplicating a row.

type RegistryCredential

type RegistryCredential struct {
	ID           string
	Name         string
	RegistryHost string
	Username     string
	CreatedAt    string
	// ExpiresAt is operator-provided, never inferred: this platform has
	// no way to read an expiry out of an opaque credential string. Nil
	// means no expiry was set.
	ExpiresAt *time.Time
}

RegistryCredential is a username for pulling a private container image from RegistryHost. No password field: a caller resolving it does so separately through internal/secrets, keyed by RegistryCredentialSecretsKey(credential.ID), the same split BackupTarget already uses.

type RegistrySettings

type RegistrySettings struct {
	Enabled bool
	// Host is the domain the embedded Caddy ingress routes to the
	// registry container, e.g. a WireGuard mesh-resolvable name for
	// multi-node reachability, or any hostname on a single node. Empty
	// means "not set yet": Enabled with an empty Host reconciles the
	// container but never routes it, the same "known, incomplete
	// configuration" shape IngressSettings.PrimaryDomain's absence
	// already has for the dashboard route.
	Host string
	// Username is the registry login name, generated once alongside the
	// password when the registry is first enabled.
	Username  string
	CreatedAt string
}

RegistrySettings is the single platform-wide row: whether the operator wants Levelrail's built-in container registry running, the hostname it should be reachable at, and the generated login username. No password field: that goes through internal/secrets instead.

type ResourceOwner added in v0.2.0

type ResourceOwner struct {
	TeamID    string
	ProjectID string
}

ResourceOwner is the team and project an app or database belongs to. A resource with no project belongs to the default team.

type RestoreHistory

type RestoreHistory struct {
	ID              string
	DatabaseName    string
	ResourceKind    string
	ServiceName     string
	VolumeName      string
	BackupHistoryID string
	Status          string
	Error           string
	StartedAt       string
	FinishedAt      string
}

RestoreHistory is one attempted restore of one database, or one app service's named volume, from one backup_history row. ResourceKind/ ServiceName/VolumeName mirror BackupHistory's own identity fields exactly (backup_history.go), the same mutually-exclusive shape. Status reuses BackupStatusRunning/Succeeded/Failed (backup_history.go) rather than a second, identically-valued set of constants: a restore attempt moves through the exact same running-then-succeeded-or-failed lifecycle a backup attempt does, and migrations/0019_restore_history.sql's own CHECK constraint accepts the identical three strings, so two names for the same three values would only invite them drifting apart. Error is empty unless Status is BackupStatusFailed.

type Role added in v0.2.0

type Role struct {
	ID          string
	Name        string
	Description string
	Abilities   []string
	Visibility  string
	Builtin     bool
	CreatedAt   string
}

Role is a named, stored bundle of abilities (migration 0374).

type RollbackPin added in v0.2.0

type RollbackPin struct {
	ServiceName     string
	DeployAttemptID string
	Image           string
	ImageID         string
	// PinRef is the extra tag that keeps ImageID from ever becoming dangling.
	PinRef    string
	CreatedAt time.Time
}

RollbackPin is an image kept tagged as a rollback target for one succeeded deploy attempt (migrations/0461_rollback_pins.sql).

type Route53DNSSettings added in v0.2.0

type Route53DNSSettings struct {
	Enabled      bool
	Region       string
	HostedZoneID string
}

Route53DNSSettings is the single platform-wide row: whether ACME DNS-01 via Route53 is enabled for wildcard domains, plus the two non-secret fields libdns/route53 accepts. Region and HostedZoneID are both optional; empty lets the library resolve them itself. The access key pair goes through internal/secrets instead, the same split CloudflareDNSSettings uses for its own token.

type SSHNodeProvision added in v0.2.0

type SSHNodeProvision struct {
	ID            string
	Name          string
	Role          string
	Status        string
	DetectedOS    string
	DetectedArch  string
	NodeID        string
	FailureReason string
	// Log is the accumulated, human-readable progress of the SSH install
	// (internal/sshprovision.Event.Message lines), replaced wholesale on
	// each update rather than appended in SQL: the provisioning goroutine
	// is the sole writer for a given row's lifetime, so there is no
	// concurrent-append race to guard against.
	Log       string
	CreatedAt time.Time
	UpdatedAt time.Time
}

SSHNodeProvision tracks one SSH-driven agent install on a machine the operator already has, through to the join-token enrollment it's expected to complete. Correlated to the real store.Node it produces by Name, the same convention NodeProvision uses.

type ScheduledTask

type ScheduledTask struct {
	ID          string
	ServiceName string
	Command     []string
	Schedule    string
	Enabled     bool
	// ConcurrencyPolicy governs what happens when this task's next due
	// run finds a previous invocation still executing (internal/
	// scheduledtask.Runner): allow, forbid, or replace. Always one of
	// those three once loaded from the store; SaveScheduledTask and
	// UpdateScheduledTask both default an empty value to allow.
	ConcurrencyPolicy string

	// LastRunAt is nil until this task has run at least once (scheduled
	// or manual "run now"), the same "zero value means never happened
	// yet" convention APIToken's own LastUsedAt already establishes for
	// state that starts out unset.
	LastRunAt     *time.Time
	LastRunStatus string
	// LastRunOutput is already bounded by the runner before it reaches
	// this field (see this table's own migration comment); this struct
	// never re-truncates it.
	LastRunOutput string
	// ConsecutiveFailures counts runs in a row that were not
	// ScheduledTaskStatusSuccess, reset to 0 by RecordScheduledTaskRun on
	// a success. What a kind=scheduled_task_failure alert rule
	// (internal/alerting) polls, so repeated failure is visible without
	// this table keeping a full run history.
	ConsecutiveFailures int

	// Name is the job's operator-facing identifier, unique per app when
	// set (what app.yaml's jobs: entries are keyed by).
	Name string
	// Mode is ScheduledTaskModeExec or ScheduledTaskModeFresh.
	Mode string
	// Timezone is an IANA zone the cron expression is evaluated in.
	Timezone string
	// TimeoutSeconds, MaxRetries and RetryBackoffSeconds use 0 as "the
	// control plane default" (env-configured), never as a literal zero.
	TimeoutSeconds      int
	MaxRetries          int
	RetryBackoffSeconds int
	// CatchUp is ScheduledTaskCatchUpSkip or ScheduledTaskCatchUpRunOnce,
	// what to do when the control plane was down across occurrences.
	CatchUp                string
	CatchUpLookbackSeconds int
	// CPULimitMillis and MemoryLimitMB bound a fresh-mode container, 0
	// meaning the app's own limits.
	CPULimitMillis int
	MemoryLimitMB  int
	// WarnAfterSeconds raises the running-too-long alert once a run has
	// been in flight that long, 0 meaning never.
	WarnAfterSeconds int
	// Source is ScheduledTaskSourceAPI or ScheduledTaskSourceSpec: a
	// spec-sourced job is owned by the app.yaml that declared it.
	Source string

	// LastScheduledFor is the cron occurrence the scheduler last handled
	// (ran, skipped, or recorded as missed): the level-triggered
	// high-water mark that makes a restart neither double-run nor
	// silently skip. ArmedAt is when the schedule last became live.
	LastScheduledFor *time.Time
	ArmedAt          *time.Time
	// RunningSince is non-nil while a run is in flight, what the
	// running-too-long alert polls. ConsecutiveMissed counts occurrences
	// the control plane failed to run in a row.
	RunningSince      *time.Time
	ConsecutiveMissed int

	CreatedAt time.Time
	UpdatedAt time.Time
}

ScheduledTask is one cron-scheduled command an operator runs inside a service's currently running container. See migrations/ 0048_scheduled_tasks.sql for the full field-by-field reasoning.

type ScheduledTaskRun added in v0.2.0

type ScheduledTaskRun struct {
	ID          string
	TaskID      string
	ServiceName string
	Trigger     string
	Status      string
	// ScheduledFor is the cron occurrence this run was claimed for, nil
	// for a manual or api run.
	ScheduledFor *time.Time
	StartedAt    time.Time
	FinishedAt   *time.Time
	ExitCode     *int
	DurationMS   int64
	Attempts     int
	NodeID       string
	Mode         string
	ContainerID  string
	Message      string
	Output       string
}

ScheduledTaskRun is one persisted job run (migrations/0467).

type ScheduledTaskRunFilter added in v0.2.0

type ScheduledTaskRunFilter struct {
	ServiceName string
	TaskID      string
	Status      string
	Limit       int
}

ScheduledTaskRunFilter narrows ListScheduledTaskRuns.

type SchemaState added in v0.2.0

type SchemaState struct {
	// Schema is the highest applied migration version.
	Schema int
	// LastVersion is the control plane version recorded most recently in the
	// upgrade history, empty when there is none.
	LastVersion string
}

SchemaState is what a database file says about itself, read without migrating or modifying it.

func ReadSchemaState added in v0.2.0

func ReadSchemaState(ctx context.Context, path string) (SchemaState, error)

ReadSchemaState reports a database file's schema version and last running release read-only, safe against a database newer than this binary.

type SecretCiphertext added in v0.2.0

type SecretCiphertext struct {
	ServiceName string
	EnvKey      string
	Ciphertext  []byte
}

SecretCiphertext is one stored secret value row, ciphertext only.

type SecretEnvRef added in v0.2.0

type SecretEnvRef struct {
	Name     string `json:"name"`
	Required bool   `json:"required,omitempty"`
}

SecretEnvRef is one env var's { secret: true } declaration (internal/spec.EnvVar), stored on DesiredService.SecretEnv. Name is the secret storage key (internal/secrets), resolved and decrypted by the application controller immediately before container creation, the same "declaration only, resolved later" split DatabaseEnvRef/VaultEnvRef already make. Required mirrors app.yaml's own { required: true } flag: carrying it through here is what lets a build-triggered deploy (internal/api/builds.go's specServiceFromDesired, feeding internal/deploy.Pipeline's validateEnv) reject a still-unset required secret the same way a fresh app.yaml parse already does on the webhook path, instead of silently deploying without it.

func SecretEnvRefsFromNames added in v0.2.0

func SecretEnvRefsFromNames(names []string) []SecretEnvRef

SecretEnvRefsFromNames builds []SecretEnvRef for names with Required false for each: the shape a caller that only ever tracks secret-backed env var names by name needs (e.g. the direct app API and Docker Compose imports, neither of which has an app.yaml { required: true } flag to carry over).

type SecretKeyInfo

type SecretKeyInfo struct {
	Key       string
	Locked    bool
	UpdatedAt time.Time
}

SecretKeyInfo is one secret key known for a service, with its locked state and when its value was last set (created or rotated), never the value itself. UpdatedAt is service_secret_values.updated_at (bumped by every SaveSecretValue upsert, so a rotation moves it the same as an initial set), used by GET /apps/{name}/secrets to let a UI surface a secret's age and flag it stale past Router.effectiveSecretRotationWarnAge.

type SecurityPolicy added in v0.2.0

type SecurityPolicy struct {
	ApprovalScope        *string
	MaxTokenLifetimeDays *int
	WarnUnusedDays       *int
	DisableUnusedDays    *int
	UpdatedAt            time.Time
}

SecurityPolicy is the stored platform security policy. A nil field was never saved, so its APP_* env default applies.

type SelfUpgradeAttempt added in v0.2.0

type SelfUpgradeAttempt struct {
	ID          string
	FromVersion string
	ToVersion   string
	FromSchema  int
	ToSchema    int
	Initiator   string
	Outcome     string
	FailedStep  string
	Error       string
	BackupName  string
	AckedJSON   string
	StepsJSON   string
	StartedAt   string
	FinishedAt  string
}

SelfUpgradeAttempt is one recorded host-run self-upgrade (migrations/0456). StepsJSON and AckedJSON are opaque to the store.

type ServiceBindMount added in v0.2.0

type ServiceBindMount struct {
	HostPath      string `json:"host_path"`
	ContainerPath string `json:"container_path"`
	ReadOnly      bool   `json:"read_only,omitempty"`
}

ServiceBindMount is one host directory an application service's container mounts directly, distinct from ServiceVolume (a Docker- managed named volume): HostPath is a real path on whichever node the service runs on, not a Docker volume name. internal/compose is the only producer today (compose.go's own doc comment on volumes:'s bind-mount short form); internal/api gates persisting any non-empty BindMounts to AbilityRoot callers, the same tier POST /apps/{name}/exec sits behind, since a bind mount is a real host-filesystem access capability. Kept as its own type rather than an optional HostPath field on ServiceVolume so a bind mount and a named volume are never ambiguous in code or storage.

type ServiceBranchEnvOverride added in v0.2.0

type ServiceBranchEnvOverride struct {
	ID            string
	ServiceName   string
	BranchPattern string
	Key           string
	// Value is always "" when Secret is true, matching SharedEnvVar's
	// own "never carry a secret's plaintext on this struct" rule.
	Value     string
	Secret    bool
	UpdatedAt time.Time
}

ServiceBranchEnvOverride is one branch-scoped env var override row (migrations/0119): serviceName's env var key resolves to Value (or, if Secret, a decrypted value under BranchEnvOverrideSecretsKey) whenever a preview built from BranchPattern is deployed, in place of whatever serviceName's own Env/SecretEnv/VaultEnv holds for that key.

type ServiceDomain

type ServiceDomain struct {
	Domain      string
	ServiceName string
}

ServiceDomain is one row of the service_domains table (migrations/0012_service_domains.sql): a domain currently claimed by a named service. Read-only projection for GET /api/v1/domains (internal/api), the centralized cross-app domain list; this is not a new tracking mechanism, service_domains is already kept in sync by SaveDesiredService on every write (see that method's own doc comment).

type ServiceEgressAllow added in v0.2.0

type ServiceEgressAllow struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

ServiceEgressAllow is one host+port pair a service's outbound traffic may reach when its ServiceEgressPolicy.Mode is EgressModeAllowlist.

type ServiceEgressPolicy added in v0.2.0

type ServiceEgressPolicy struct {
	Mode  string               `json:"mode"`
	Allow []ServiceEgressAllow `json:"allow,omitempty"`
}

ServiceEgressPolicy holds a service's outbound network allowlist (internal/spec.Egress's storage home, migrations/0112_service_egress_policy.sql). nil means egress is unrestricted, today's behavior for every service before this field existed and the permanent default for any service that never opts in: see internal/spec.Egress's own doc comment for why this is opt-in rather than deny-by-default.

type ServiceGPU added in v0.2.0

type ServiceGPU struct {
	Count     int      `json:"count,omitempty"`
	DeviceIDs []string `json:"device_ids,omitempty"`
}

ServiceGPU is a service's GPU request: Count -1 means every GPU, DeviceIDs (indexes or UUIDs) take precedence over Count.

type ServiceHealth

type ServiceHealth struct {
	Readiness *ServiceProbe `json:"readiness,omitempty"`
	Liveness  *ServiceProbe `json:"liveness,omitempty"`
	// ReadyTimeout overrides internal/reconcile/application's own
	// defaultReadyBudget (60s) for this service alone, zero meaning
	// "use the default". See internal/spec.Health.ReadyTimeout, its
	// app.yaml source.
	ReadyTimeout time.Duration `json:"ready_timeout,omitempty"`
}

ServiceHealth holds a service's probe configuration.

type ServiceHooks

type ServiceHooks struct {
	PreDeploy  string `json:"pre_deploy,omitempty"`
	PostDeploy string `json:"post_deploy,omitempty"`
}

ServiceHooks holds a service's pre/post-deploy hook commands (internal/spec.Hooks' storage home, migrations/0082_service_hooks.sql). See internal/reconcile/application.Controller's own doc comment for when each one runs and what a failure does.

type ServiceProbe

type ServiceProbe struct {
	Path            string        `json:"path"`
	Scheme          string        `json:"scheme,omitempty"`
	Host            string        `json:"host,omitempty"`
	TLSSkipVerify   bool          `json:"tls_skip_verify,omitempty"`
	FollowRedirects *bool         `json:"follow_redirects,omitempty"`
	ExpectedStatus  string        `json:"expected_status,omitempty"`
	Exec            []string      `json:"exec,omitempty"`
	Interval        time.Duration `json:"interval,omitempty"`
	Timeout         time.Duration `json:"timeout,omitempty"`
	Failures        int           `json:"failures,omitempty"`
}

ServiceProbe is one readiness or liveness check.

func (ServiceProbe) NeedsPort added in v0.2.0

func (p ServiceProbe) NeedsPort() bool

NeedsPort reports whether p can only run against a published port.

func (ServiceProbe) ProbeConfig added in v0.2.0

func (p ServiceProbe) ProbeConfig() probe.Config

ProbeConfig converts p into the shape internal/probe runs.

type ServiceResources

type ServiceResources struct {
	MemoryBytes int64 `json:"memory_bytes,omitempty"`
	NanoCPUs    int64 `json:"nano_cpus,omitempty"`
	// SwapMemoryBytes is Docker's own MemorySwap: total memory plus swap
	// combined, only meaningful alongside MemoryBytes.
	SwapMemoryBytes int64 `json:"swap_memory_bytes,omitempty"`
	// CPUSetCPUs pins the container to specific host CPUs, Docker's own
	// cpuset-cpus format (e.g. "0-3" or "0,2").
	CPUSetCPUs string `json:"cpuset_cpus,omitempty"`
	// GPU requests NVIDIA GPUs. nil means none.
	GPU *ServiceGPU `json:"gpu,omitempty"`
}

ServiceResources caps a service's memory and CPU, in the same units internal/docker.Resources already uses (bytes, nano-CPUs), not app.yaml's human-friendly "512Mi"/0.5-cores strings. Translating those is the deploy pipeline's job, not this package's; by the time a DesiredService exists, its units are already resolved.

type ServiceVolume

type ServiceVolume struct {
	Name          string `json:"name"`
	ContainerPath string `json:"container_path"`
}

ServiceVolume is one named Docker volume an application service's container mounts, the same shape internal/docker.VolumeMount already has for the database controller's own (single, fixed-path) volume. Name is this platform's own volume name (already scoped/prefixed, see internal/reconcile/application's own volume-naming helper), not whatever a compose file's own top-level volumes: key called it.

type ServiceVolumeBackupConfig

type ServiceVolumeBackupConfig struct {
	ServiceName      string
	VolumeName       string
	BackupTargetID   string
	BackupSchedule   string
	BackupRetain     int
	BackupRetainDays int
	// SqlitePath: see migrations/0259.
	SqlitePath string
}

ServiceVolumeBackupConfig is one service volume's scheduled-backup config: migrations/0075_service_volume_backups.sql's own row, the volume counterpart of DesiredDatabase's BackupTargetID/BackupSchedule/ BackupRetain/BackupRetainDays fields. ServiceName/VolumeName identify the volume the same way internal/api's resolveServiceVolume does: VolumeName is the volume's logical name (spec.Volume.Name), not the resolved Docker volume name internal/deploy's volumeName() computes.

type SessionLinkToken added in v0.2.0

type SessionLinkToken struct {
	ID            string
	PrincipalType string
	PrincipalID   string
	Abilities     []string
	DisplayName   string
	TokenHash     string
	CreatedAt     time.Time
	ExpiresAt     time.Time
	UsedAt        *time.Time
}

SessionLinkToken is one outstanding session-link mint: a short-lived, single-use token that establishes a session for whoever minted it, without a password. TokenHash is the only form of the token ever persisted. Abilities and DisplayName are a snapshot taken at mint time, since a PrincipalTypeToken principal has no live user record this could be re-resolved from at consume time, unlike a session's own user row.

type SharedEnvVar added in v0.2.0

type SharedEnvVar struct {
	Key       string
	Value     string
	Secret    bool
	UpdatedAt time.Time
}

SharedEnvVar is one shared env var at the project, organization, or environment tier. Value is always empty when Secret is true: a secret-marked entry's plaintext never lives in project_env_vars/ organization_env_vars/environment_env_vars, only its key does; the plaintext lives in service_secrets/service_secret_values instead, the same envelope-encryption tables every other platform-wide credential (Vault, registry, git source) already uses, under ProjectEnvSecretsKey/OrganizationEnvSecretsKey/EnvironmentEnvSecretsKey. UpdatedAt is the row's own updated_at (bumped on every SetX.../ SetXSecretEnvVar write, so a plain override and a secret rotation alike move it), used by GET .../env/all to let a UI show a secret-marked entry's age and flag it stale, the same purpose SecretKeyInfo.UpdatedAt serves for per-app secrets.

type SignInAlertToken added in v0.2.0

type SignInAlertToken struct {
	ID              string
	UserID          string
	SessionID       string
	TrustedDeviceID string
	IP              string
	Label           string
	CreatedAt       time.Time
	ExpiresAt       time.Time
}

SignInAlertToken backs one "this wasn't me" link from a new-browser alert.

type StaticSite

type StaticSite struct {
	Name    string
	Domains []string
	// RootDir is the local filesystem directory internal/deploy copied
	// this site's built static files into (under the control plane's
	// data directory, never the ephemeral git checkout dir itself, which
	// a caller like internal/webhook removes as soon as the deploy call
	// returns). The ingress controller passes this straight to Caddy's
	// file_server handler as its root.
	RootDir string
}

StaticSite is what internal/reconcile/ingress's controller reads to point Caddy's file_server handler directly at a directory on disk, no container involved. See migrations/0015_static_sites.sql for why this is a separate table from DesiredService rather than a variant of it: build.type: static (served directly by the embedded Caddy) has no image, no port, and no running container to converge to, so it never belongs in desired_services at all.

type StatusComponent added in v0.2.0

type StatusComponent struct {
	ID          string
	Kind        string
	Target      string
	DisplayName string
	Position    int
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

StatusComponent is one operator-chosen thing shown on the status page. Target is internal; only DisplayName is ever published.

type StatusDaily added in v0.2.0

type StatusDaily struct {
	ComponentID string
	Day         string
	OK          int
	Degraded    int
	Down        int
}

StatusDaily is one component's probe counters for one UTC day.

type StatusIncident added in v0.2.0

type StatusIncident struct {
	ID           string
	Kind         string
	Title        string
	Status       string
	Impact       string
	ComponentIDs []string
	StartsAt     time.Time
	EndsAt       *time.Time
	ResolvedAt   *time.Time
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

StatusIncident is an operator-authored incident or maintenance announcement.

type StatusIncidentUpdate added in v0.2.0

type StatusIncidentUpdate struct {
	ID         string
	IncidentID string
	Status     string
	Body       string
	CreatedAt  time.Time
}

StatusIncidentUpdate is one timeline entry on an incident.

type StatusPageSettings added in v0.2.0

type StatusPageSettings struct {
	Enabled      bool
	Title        string
	Description  string
	CustomDomain string
	UpdatedAt    time.Time
}

StatusPageSettings is the single settings row for the public status page.

type StorageOptions added in v0.2.0

type StorageOptions struct {
	TargetID  string
	Preset    string
	PathStyle bool
	AccountID string
}

StorageOptions are the per-destination settings layered on a BackupTarget.

type Tag added in v0.2.0

type Tag struct {
	ID        string
	Name      string
	CreatedAt time.Time
}

Tag is an arbitrary, operator-defined label an app can be attached to for organization and filtering, independent of the project/ environment hierarchy (migrations/0106_tags.sql).

type TeamEvent added in v0.2.0

type TeamEvent struct {
	ID        string
	TeamID    string
	ActorID   string
	ActorName string
	Action    string
	Subject   string
	Detail    string
	CreatedAt time.Time
}

TeamEvent is one membership change in a team's own audit trail.

type TeamInvite added in v0.2.0

type TeamInvite struct {
	ID         string
	TeamID     string
	Email      string
	Role       string
	TokenHash  string
	CreatedBy  string
	CreatedAt  time.Time
	ExpiresAt  time.Time
	AcceptedAt *time.Time
	AcceptedBy string
	RevokedAt  *time.Time
}

TeamInvite is a pending, accepted or revoked invitation into a team.

type TeamMember added in v0.2.0

type TeamMember struct {
	TeamID      string
	UserID      string
	Email       string
	DisplayName string
	Role        string
	CreatedAt   string
}

TeamMember is one user's membership of a team.

type TokenHygieneNotice added in v0.2.0

type TokenHygieneNotice struct {
	TokenID    string
	OwnerID    string
	TokenName  string
	NoticedAt  time.Time
	DisabledAt time.Time
}

TokenHygieneNotice records that an unused token was warned about, and when it was disabled if the grace period ran out.

type TrustedDevice added in v0.2.0

type TrustedDevice struct {
	ID         string
	UserID     string
	TokenHash  string
	Label      string
	IP         string
	CreatedAt  time.Time
	LastUsedAt time.Time
	ExpiresAt  time.Time
}

TrustedDevice is one browser a user approved for password sign-in. TokenHash is the SHA-256 of its cookie; the cookie value is never stored.

type UpdateSettings added in v0.2.0

type UpdateSettings struct {
	// Channel is one of "stable", "beta", or "edge" (kit/upgrade's
	// Channel constants). Defaults to "stable": GET /api/v1/updates
	// compares against GitHub's latest non-prerelease release, unchanged
	// from this table's own pre-existing behavior.
	Channel string
	// AutoUpdateEnabled gates internal/updatecheck.Scheduler's periodic
	// check. False by default: no background GitHub polling happens
	// until an operator opts in.
	AutoUpdateEnabled bool
}

UpdateSettings is the platform-wide self-update configuration row (migrations/0258_update_settings.sql): which release channel to compare the running build against, and whether internal/updatecheck.Scheduler should run its periodic check at all. There is always exactly one of these (id = 1), seeded by the migration, so GetUpdateSettings never returns a not-found error.

type UpgradeHistoryEntry added in v0.2.0

type UpgradeHistoryEntry struct {
	ID           string
	Kind         string
	FromVersion  string
	ToVersion    string
	Channel      string
	SchemaBefore int
	SchemaAfter  int
	OccurredAt   time.Time
	Initiator    string
	Method       string
	BackupName   string
	Health       string
	Notes        string
	NotesState   string
	AckedByType  string
	AckedByID    string
	AckedByName  string
	AckedAt      *time.Time
}

UpgradeHistoryEntry is one recorded control plane version transition (migrations/0400). Rows are append-only apart from the notes snapshot, filled once, and the acknowledgement.

func (UpgradeHistoryEntry) Acknowledged added in v0.2.0

func (e UpgradeHistoryEntry) Acknowledged() bool

Acknowledged reports whether an operator has acknowledged the transition.

type User

type User struct {
	ID           string
	Email        string
	DisplayName  string
	PasswordHash *string
	Abilities    []string
	IsFirstUser  bool
	CreatedAt    time.Time
	LastLoginAt  *time.Time
	// TeamID and TeamRole pick the team a new user joins; empty means the
	// default team with a role matching Abilities.
	TeamID   string
	TeamRole string
}

User is a real, individually-identified account (migrations/0035_users.sql). PasswordHash is nil for an OAuth-only user. IsFirstUser is display-only. Second factors live in the auth library. Abilities (migrations/0045_user_abilities.sql) is the same shape and validation (internal/api's validateAbilities) as APIToken.Abilities: a session now carries real, checkable scoping instead of every session being treated as implicitly root.

type UserSecuritySettings added in v0.2.0

type UserSecuritySettings struct {
	UserID                   string
	RequireNewDeviceApproval bool
	ResetFlaggedAt           time.Time
	ResetFlagReason          string
}

UserSecuritySettings are one account's own security switches.

type VaultEnvRef added in v0.2.0

type VaultEnvRef struct {
	Path string `json:"path"`
	Key  string `json:"key"`
}

VaultEnvRef is one env var's parsed { vault: { path, key } } reference (internal/spec.EnvVar.Vault), stored on DesiredService.VaultEnv. Path is a KV v2 secret path in the operator's own Vault instance (see VaultSettings); Key is the field name inside that secret's data. Resolved fresh from a live Vault read by the application controller immediately before container creation, the same "declaration only, resolved later" split DatabaseEnvRef already makes.

type VaultSettings added in v0.2.0

type VaultSettings struct {
	Enabled    bool
	Address    string
	AuthMethod string
	Namespace  string
	RoleID     string
	MountPath  string
}

VaultSettings is the single platform-wide row: how to reach an external HashiCorp Vault instance for Vault-sourced app secrets (internal/spec.EnvVar.Vault). RoleID is only meaningful alongside VaultAuthMethodAppRole; the credential itself (token or AppRole secret ID) goes through internal/secrets instead, keyed by VaultSecretsKey/VaultCredentialEnvKey.

type Visibility added in v0.2.0

type Visibility struct {
	Restricted     bool
	EnvironmentIDs map[string]bool
}

Visibility says what a user may see: everything their abilities allow, or only the listed environments.

func (Visibility) Allows added in v0.2.0

func (v Visibility) Allows(environmentID string) bool

Allows reports whether a resource in this environment is visible. A resource with no environment is visible only to unrestricted users.

type VolumeBackupPolicy added in v0.2.0

type VolumeBackupPolicy struct {
	ServiceName   string
	VolumeName    string
	RetainDaily   int
	RetainWeekly  int
	RetainMonthly int
	PreHook       string
	PostHook      string
	Quiesce       string
	UpdatedAt     string
}

VolumeBackupPolicy is a volume's grandfather-father-son retention counts and consistency hooks. A zero value means no extra policy.

func (VolumeBackupPolicy) HasRetention added in v0.2.0

func (p VolumeBackupPolicy) HasRetention() bool

HasRetention reports whether any grandfather-father-son count is set.

type VolumeCloneRestore

type VolumeCloneRestore struct {
	ID                string
	SourceServiceName string
	SourceVolumeName  string
	NewVolumeName     string
	BackupHistoryID   string
	Status            string
	Error             string
	StartedAt         string
	FinishedAt        string
}

VolumeCloneRestore is one attempted "restore as new volume": a backup of SourceServiceName's SourceVolumeName restored into NewVolumeName, a brand-new Docker volume created fresh for this attempt rather than overwriting anything. The app service volume counterpart of CloneRestore, with the same status lifecycle.

type WebhookDelivery

type WebhookDelivery struct {
	// ID is an opaque, mint-time-random identifier from
	// NewWebhookDeliveryID, the same shape NewDeployAttemptID already
	// establishes.
	ID          string
	ServiceName string
	// Provider and EventType are detected from request headers alone
	// (detectWebhookProviderAndEvent), debug metadata only: nothing in
	// this package's own processing branches on them.
	Provider  string
	EventType string
	// HeaderFields carries the small set of provider event-discriminator
	// headers (X-GitHub-Event, X-Gitlab-Event, X-Event-Key) needed to
	// replay this delivery through the identical processing branch it
	// originally took. Deliberately not the full header set: no
	// signature or token header value is ever stored here, only the
	// three name-of-event headers, none of which are secrets.
	HeaderFields   map[string]string
	SignatureValid bool
	// Matched reports whether ServiceName resolved to a connected git
	// source at receipt time, the "app not found" visibility this table
	// exists for in the first place.
	Matched          bool
	StatusCode       int
	Payload          []byte
	PayloadTruncated bool
	// Error is the same non-leaky status message the webhook response
	// itself returned (e.g. "invalid signature", "deploy failed"), never
	// a secret or the payload's own contents.
	Error string
	// Note is the outcome message of a delivery that was accepted but did
	// not (or not yet) deploy, e.g. an ignored branch or a path filter
	// skip. Empty when the delivery returned an error.
	Note       string
	ReceivedAt time.Time
}

WebhookDelivery is one recorded inbound git-provider webhook request (internal/api/git_webhook.go's handleGitPushWebhook): what arrived, whether it verified, what it resolved to, and what this control plane did about it. Exists so an operator can see why a delivery failed (bad signature, no git source connected, a downstream deploy error) without re-triggering a real push, and can replay a stored payload through the exact same processing path once whatever was wrong is fixed.

Source Files

Jump to

Keyboard shortcuts

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