- Add ListPipelines/GetPipeline to CIProvider port with Woodpecker adapter
- Add DNS alias endpoints: GET/POST/DELETE /projects/{id}/domains
- Implement worker executor daemon, build executor, and git operations
- Add build service, worker service, and build audit tracking
- Add worker registry with PostgreSQL adapter and migration
- Add multi-provider code agent interface (Claude Code + OpenCode)
- Add create-and-build combo endpoint
- Update landing-page cookbook to reflect all gaps closed
- Fix tech debt: unified validation, auth scopes, error wrapping, slog patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
156 lines
5.1 KiB
Go
156 lines
5.1 KiB
Go
package domain
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// WebhookID is a strongly-typed identifier for webhooks.
|
|
type WebhookID string
|
|
|
|
// String returns the webhook ID as a string.
|
|
func (id WebhookID) String() string {
|
|
return string(id)
|
|
}
|
|
|
|
// WebhookEventType represents the type of event that triggers a webhook.
|
|
type WebhookEventType string
|
|
|
|
// Available webhook event types.
|
|
const (
|
|
WebhookEventCommandStarted WebhookEventType = "command.started"
|
|
WebhookEventCommandCompleted WebhookEventType = "command.completed"
|
|
WebhookEventCommandFailed WebhookEventType = "command.failed"
|
|
WebhookEventPodReady WebhookEventType = "pod.ready"
|
|
WebhookEventPodFailed WebhookEventType = "pod.failed"
|
|
)
|
|
|
|
// AllWebhookEventTypes lists all valid webhook event types.
|
|
var AllWebhookEventTypes = []WebhookEventType{
|
|
WebhookEventCommandStarted,
|
|
WebhookEventCommandCompleted,
|
|
WebhookEventCommandFailed,
|
|
WebhookEventPodReady,
|
|
WebhookEventPodFailed,
|
|
}
|
|
|
|
// IsValid checks if a webhook event type is valid.
|
|
func (t WebhookEventType) IsValid() bool {
|
|
for _, valid := range AllWebhookEventTypes {
|
|
if t == valid {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// String returns the event type as a string.
|
|
func (t WebhookEventType) String() string {
|
|
return string(t)
|
|
}
|
|
|
|
// Webhook represents a webhook subscription for a project.
|
|
type Webhook struct {
|
|
ID WebhookID `json:"id"`
|
|
ProjectID string `json:"project_id"`
|
|
URL string `json:"url"`
|
|
Secret string `json:"-"` // Never expose secret in JSON responses
|
|
Events []WebhookEventType `json:"events"`
|
|
Enabled bool `json:"enabled"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// HasSecret returns true if the webhook has a signing secret configured.
|
|
func (w *Webhook) HasSecret() bool {
|
|
return w.Secret != ""
|
|
}
|
|
|
|
// SubscribesToEvent checks if the webhook subscribes to the given event type.
|
|
func (w *Webhook) SubscribesToEvent(eventType WebhookEventType) bool {
|
|
for _, e := range w.Events {
|
|
if e == eventType {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// WebhookDeliveryID is a strongly-typed identifier for webhook deliveries.
|
|
type WebhookDeliveryID string
|
|
|
|
// String returns the delivery ID as a string.
|
|
func (id WebhookDeliveryID) String() string {
|
|
return string(id)
|
|
}
|
|
|
|
// WebhookDelivery represents a single webhook delivery attempt.
|
|
type WebhookDelivery struct {
|
|
ID WebhookDeliveryID `json:"id"`
|
|
WebhookID WebhookID `json:"webhook_id"`
|
|
EventType WebhookEventType `json:"event_type"`
|
|
Payload string `json:"payload"` // JSON payload that was sent
|
|
ResponseStatus int `json:"response_status,omitempty"`
|
|
ResponseBody string `json:"response_body,omitempty"`
|
|
DeliveredAt time.Time `json:"delivered_at"`
|
|
Success bool `json:"success"`
|
|
RetryCount int `json:"retry_count"`
|
|
ErrorMessage string `json:"error_message,omitempty"`
|
|
}
|
|
|
|
// WebhookEvent represents an event to be dispatched to webhooks.
|
|
type WebhookEvent struct {
|
|
Type WebhookEventType `json:"type"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
ProjectID string `json:"project_id"`
|
|
Data any `json:"data"`
|
|
}
|
|
|
|
// WebhookPayload is the structure sent to webhook endpoints.
|
|
type WebhookPayload struct {
|
|
ID string `json:"id"` // Unique delivery ID
|
|
Event WebhookEventType `json:"event"` // Event type
|
|
Timestamp time.Time `json:"timestamp"` // When the event occurred
|
|
ProjectID string `json:"project_id"` // Project this event relates to
|
|
Data any `json:"data"` // Event-specific data
|
|
}
|
|
|
|
// CommandEventData is the data structure for command-related webhook events.
|
|
type CommandEventData struct {
|
|
CommandID string `json:"command_id"`
|
|
CommandType CommandType `json:"command_type"`
|
|
ProjectID string `json:"project_id"`
|
|
StartedAt time.Time `json:"started_at,omitempty"`
|
|
CompletedAt time.Time `json:"completed_at,omitempty"`
|
|
ExitCode int `json:"exit_code,omitempty"`
|
|
DurationMs int64 `json:"duration_ms,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
// PodEventData is the data structure for pod-related webhook events.
|
|
type PodEventData struct {
|
|
PodName string `json:"pod_name"`
|
|
ProjectID string `json:"project_id"`
|
|
Status string `json:"status"`
|
|
Reason string `json:"reason,omitempty"`
|
|
Message string `json:"message,omitempty"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
}
|
|
|
|
// WebhookFilters contains filter options for listing webhook deliveries.
|
|
type WebhookDeliveryFilters struct {
|
|
EventType *WebhookEventType // Filter by event type
|
|
Success *bool // Filter by success status
|
|
Limit int // Max results (default 100)
|
|
Offset int // For pagination
|
|
}
|
|
|
|
// DefaultWebhookDeliveryFilters returns sensible defaults.
|
|
func DefaultWebhookDeliveryFilters() *WebhookDeliveryFilters {
|
|
return &WebhookDeliveryFilters{
|
|
Limit: 100,
|
|
Offset: 0,
|
|
}
|
|
}
|
|
|
|
// Webhook-related errors are defined in errors.go for centralized error definitions.
|