Feat event bus subscriptions + trigger system (v0.2.2)
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 24s
CI/CD / test-frontend (pull_request) Has been skipped
CI/CD / test-go-pg (pull_request) Successful in 2m30s
CI/CD / test-sqlite (pull_request) Successful in 2m37s
CI/CD / build-and-deploy (pull_request) Successful in 1m30s
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 24s
CI/CD / test-frontend (pull_request) Has been skipped
CI/CD / test-go-pg (pull_request) Successful in 2m30s
CI/CD / test-sqlite (pull_request) Successful in 2m37s
CI/CD / build-and-deploy (pull_request) Successful in 1m30s
Three trigger primitives replacing the old monolithic scheduler: - Event triggers: extensions subscribe to bus patterns via manifest, async handler invocation through sandbox.CallEntryPoint - Webhook triggers: inbound HTTP at /api/v1/hooks/:pkg/:slug with HMAC-SHA256 verification and synchronous Starlark response - Scheduled tasks: user-created cron scripts with restricted sandbox (no raw HTTP, no DB table creation), runs as creator identity New tables: triggers, scheduled_tasks, trigger_logs (postgres + sqlite). New permission: triggers.register. Full admin + user CRUD APIs. SyncManifestTriggers hooked into seed and install flows. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,7 @@ const (
|
||||
ExtPermFormValidate = "forms.validate" // v0.29.3: form validation hooks
|
||||
ExtPermWorkflowAccess = "workflow.access" // v0.30.2: workflow definition + stage data access
|
||||
ExtPermConnectionsRead = "connections.read" // v0.38.1: extension connection resolution
|
||||
ExtPermTriggersRegister = "triggers.register" // v0.2.2: event/webhook trigger registration
|
||||
)
|
||||
|
||||
// ValidExtensionPermissions is the set of recognized permission keys.
|
||||
@@ -46,6 +47,7 @@ var ValidExtensionPermissions = map[string]bool{
|
||||
ExtPermFormValidate: true,
|
||||
ExtPermWorkflowAccess: true,
|
||||
ExtPermConnectionsRead: true,
|
||||
ExtPermTriggersRegister: true,
|
||||
}
|
||||
|
||||
// ── Extension Permission Model ───────────────
|
||||
|
||||
77
server/models/trigger.go
Normal file
77
server/models/trigger.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ── Trigger Type Constants ───────────────────
|
||||
|
||||
const (
|
||||
TriggerTypeWebhook = "webhook"
|
||||
TriggerTypeEvent = "event"
|
||||
)
|
||||
|
||||
// ── Scheduled Task Run-As Constants ──────────
|
||||
|
||||
const (
|
||||
RunAsCreator = "creator"
|
||||
RunAsSystem = "system"
|
||||
)
|
||||
|
||||
// ── Trigger (extension-declared) ─────────────
|
||||
|
||||
// Trigger represents an extension-declared event or webhook trigger.
|
||||
type Trigger struct {
|
||||
ID string `json:"id" db:"id"`
|
||||
PackageID string `json:"package_id" db:"package_id"`
|
||||
Type string `json:"type" db:"type"`
|
||||
Enabled bool `json:"enabled" db:"enabled"`
|
||||
Slug string `json:"slug,omitempty" db:"slug"`
|
||||
Secret string `json:"-" db:"secret"` // never serialized
|
||||
EventPattern string `json:"event_pattern,omitempty" db:"event_pattern"`
|
||||
EntryPoint string `json:"entry_point" db:"entry_point"`
|
||||
Config json.RawMessage `json:"config" db:"config"`
|
||||
FireCount int `json:"fire_count" db:"fire_count"`
|
||||
LastFireAt *time.Time `json:"last_fire_at,omitempty" db:"last_fire_at"`
|
||||
LastError string `json:"last_error,omitempty" db:"last_error"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
||||
|
||||
// ── Scheduled Task (user-created) ────────────
|
||||
|
||||
// ScheduledTask represents a user-created cron-scheduled Starlark script.
|
||||
type ScheduledTask struct {
|
||||
ID string `json:"id" db:"id"`
|
||||
Name string `json:"name" db:"name"`
|
||||
Description string `json:"description" db:"description"`
|
||||
CreatorID string `json:"creator_id" db:"creator_id"`
|
||||
RunAs string `json:"run_as" db:"run_as"`
|
||||
CronExpr string `json:"cron_expr" db:"cron_expr"`
|
||||
NextFireAt *time.Time `json:"next_fire_at,omitempty" db:"next_fire_at"`
|
||||
LastFireAt *time.Time `json:"last_fire_at,omitempty" db:"last_fire_at"`
|
||||
Enabled bool `json:"enabled" db:"enabled"`
|
||||
Script string `json:"script" db:"script"`
|
||||
TemplateID string `json:"template_id,omitempty" db:"template_id"`
|
||||
TemplateParams json.RawMessage `json:"template_params" db:"template_params"`
|
||||
FireCount int `json:"fire_count" db:"fire_count"`
|
||||
LastError string `json:"last_error,omitempty" db:"last_error"`
|
||||
LastDurationMs *int `json:"last_duration_ms,omitempty" db:"last_duration_ms"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
||||
|
||||
// ── Trigger Log (unified) ────────────────────
|
||||
|
||||
// TriggerLog records a single execution of a trigger or scheduled task.
|
||||
type TriggerLog struct {
|
||||
ID string `json:"id" db:"id"`
|
||||
TriggerID string `json:"trigger_id,omitempty" db:"trigger_id"`
|
||||
ScheduledTaskID string `json:"scheduled_task_id,omitempty" db:"scheduled_task_id"`
|
||||
FiredAt string `json:"fired_at" db:"fired_at"`
|
||||
DurationMs *int `json:"duration_ms,omitempty" db:"duration_ms"`
|
||||
Success bool `json:"success" db:"success"`
|
||||
Error string `json:"error,omitempty" db:"error"`
|
||||
Output string `json:"output,omitempty" db:"output"`
|
||||
}
|
||||
Reference in New Issue
Block a user