Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Replace per-project notify host provisioning (7-9 API calls + DNS + async Resend verification) with a shared platform host for all *.threesix.ai projects. Under the new model: - CreateProjectNotify: 3 calls only (account + send key + host grant) - No per-project Resend domain, DNS records, or async verification - All *.threesix.ai projects share `threesix.ai` as the platform host - Custom domains still get a dedicated host via ReprovisionNotifyHost Changes: - domain/notify.go: slim NotifyCredentials (no Host/From/ResendDomainID); add NotifyHostCredentials for reprovision return path - port/notify_provisioner.go: update interface signatures and docs - adapter/notify/provisioner.go: rewrite CreateProjectNotify (3 steps); rewrite DeleteProjectNotify (account-only vs full cleanup) - adapter/notify/provisioner_reprovision.go: return *NotifyHostCredentials - adapter/notify/provisioner_test.go: update tests for new model - service/project_infra_crud.go: store only NOTIFY_API_KEY on provision - domain/credential.go: add CredKeyNotifySharedHost/CredKeyNotifySharedFrom - cmd/rdev-api/config.go: add NotifySharedHost/NotifySharedFrom to InfraConfig - service/component.go: add notifySharedHost/notifySharedFrom + WithNotifyDefaults - service/component_deploy.go: inject shared host defaults when no custom host stored - handlers/notify.go: handle shared-host projects in Reprovision guard; add WithSharedNotifyHost builder - cmd/rdev-api/main.go: wire SharedHost to provisioner, component service, and notify handler Bootstrap: NOTIFY_SHARED_HOST=threesix.ai and NOTIFY_SHARED_FROM=noreply@threesix.ai stored in credential store (host id=1 already provisioned with Resend provider). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
87 lines
2.8 KiB
Go
87 lines
2.8 KiB
Go
// Package domain contains core business entities.
|
|
package domain
|
|
|
|
import "time"
|
|
|
|
// Credential represents a stored secret/credential for infrastructure adapters.
|
|
// Credentials are encrypted at rest and accessed by key name.
|
|
type Credential struct {
|
|
// Key is the unique identifier (e.g., "GITEA_TOKEN", "CLOUDFLARE_API_TOKEN")
|
|
Key string
|
|
|
|
// Value is the credential value (stored encrypted in database)
|
|
Value string
|
|
|
|
// Description explains what this credential is for
|
|
Description string
|
|
|
|
// Category groups related credentials (e.g., "gitea", "cloudflare", "woodpecker")
|
|
Category string
|
|
|
|
// CreatedAt is when the credential was first stored
|
|
CreatedAt time.Time
|
|
|
|
// UpdatedAt is when the credential was last modified
|
|
UpdatedAt time.Time
|
|
|
|
// UpdatedBy tracks who last modified the credential
|
|
UpdatedBy string
|
|
}
|
|
|
|
// CredentialCategories for grouping.
|
|
const (
|
|
CredentialCategoryGitea = "gitea"
|
|
CredentialCategoryCloudflare = "cloudflare"
|
|
CredentialCategoryWoodpecker = "woodpecker"
|
|
CredentialCategoryDatabase = "database"
|
|
CredentialCategoryRegistry = "registry"
|
|
CredentialCategoryWorker = "worker"
|
|
CredentialCategoryStorage = "storage"
|
|
CredentialCategoryAI = "ai"
|
|
CredentialCategoryNotify = "notify"
|
|
CredentialCategoryCache = "cache"
|
|
)
|
|
|
|
// Known credential keys.
|
|
const (
|
|
// Gitea
|
|
CredKeyGiteaToken = "GITEA_TOKEN"
|
|
CredKeyGiteaURL = "GITEA_URL"
|
|
|
|
// Cloudflare
|
|
CredKeyCloudflareAPIToken = "CLOUDFLARE_API_TOKEN"
|
|
CredKeyCloudflareZoneID = "CLOUDFLARE_ZONE_ID"
|
|
|
|
// Woodpecker
|
|
CredKeyWoodpeckerURL = "WOODPECKER_URL"
|
|
CredKeyWoodpeckerAPIToken = "WOODPECKER_API_TOKEN"
|
|
CredKeyWoodpeckerWebhookSecret = "WOODPECKER_WEBHOOK_SECRET"
|
|
|
|
// Registry
|
|
CredKeyRegistryURL = "REGISTRY_URL"
|
|
|
|
// GCS
|
|
CredKeyGCSBucket = "GCS_BUCKET"
|
|
CredKeyGCSServiceAccountJSON = "GCS_SERVICE_ACCOUNT_JSON"
|
|
|
|
// AI Providers
|
|
CredKeyLaozhangAPIKey = "LAOZHANG_API_KEY"
|
|
CredKeyGeminiAPIKey = "GEMINI_API_KEY"
|
|
|
|
// Notify service (email delivery)
|
|
CredKeyNotifyURL = "NOTIFY_URL"
|
|
CredKeyNotifyAdminKey = "NOTIFY_ADMIN_KEY"
|
|
CredKeyNotifyAPIKey = "NOTIFY_API_KEY"
|
|
CredKeyNotifyHost = "NOTIFY_HOST" // per-project: custom domain only
|
|
CredKeyNotifyFrom = "NOTIFY_FROM" // per-project: custom domain only
|
|
CredKeyNotifyResendDomainID = "NOTIFY_RESEND_DOMAIN_ID" // per-project: custom domain only
|
|
CredKeyNotifySharedHost = "NOTIFY_SHARED_HOST" // global: pre-provisioned platform sending host
|
|
CredKeyNotifySharedFrom = "NOTIFY_SHARED_FROM" // global: from-address for the shared host
|
|
|
|
// Resend (email provider for per-project domain provisioning)
|
|
CredKeyResendAPIKey = "RESEND_API_KEY"
|
|
|
|
// Project-scoped auth secret (unique per project, auto-generated on first code component)
|
|
CredKeyJWTSecret = "JWT_SECRET"
|
|
)
|