Feat triggers v0.2.2 (#6)
All checks were successful
CI/CD / detect-changes (push) Successful in 5s
CI/CD / test-frontend (push) Has been skipped
CI/CD / test-go-pg (push) Successful in 2m18s
CI/CD / test-sqlite (push) Successful in 2m37s
CI/CD / build-and-deploy (push) Successful in 1m26s

Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #6.
This commit is contained in:
2026-03-26 22:47:31 +00:00
committed by xcaliber
parent 342f9e3eb4
commit 57ccf19efb
29 changed files with 3237 additions and 3 deletions

View File

@@ -29,6 +29,7 @@ import (
"switchboard-core/pages"
"switchboard-core/storage"
"switchboard-core/store"
"switchboard-core/triggers"
postgres "switchboard-core/store/postgres"
sqliteStore "switchboard-core/store/sqlite"
)
@@ -174,6 +175,13 @@ func main() {
log.Printf(" ⚠️ Extension SSRF protection relaxed: private IPs allowed")
}
// ── Trigger Engine (v0.2.2) ─────────────────
triggerEngine := triggers.New(stores, starlarkRunner, bus)
if err := triggerEngine.Start(context.Background()); err != nil {
log.Printf(" ⚠️ Trigger engine start: %v", err)
}
triggers.SetGlobalEngine(triggerEngine)
defer triggerEngine.Stop()
r := gin.New()
r.Use(middleware.RequestID())
@@ -347,6 +355,11 @@ func main() {
extH := handlers.NewExtensionHandler(stores)
api.GET("/extensions/:id/assets/*path", extH.ServeExtensionAsset)
// ── Webhook Inbound (v0.2.2) ──────────────
// Public routes — HMAC-verified in handler, no auth middleware.
api.POST("/hooks/:package_id/:slug", triggerEngine.HandleWebhook)
api.GET("/hooks/:package_id/:slug", triggerEngine.HandleWebhook)
// ── Protected routes ────────────────────
protected := api.Group("")
protected.Use(middleware.Auth(cfg, stores.Users, userCache))
@@ -445,6 +458,16 @@ func main() {
protected.PUT("/notifications/preferences/:type", notifH.SetPreference)
protected.DELETE("/notifications/preferences/:type", notifH.DeletePreference)
// ── Scheduled Tasks — User (v0.2.2) ────
userSchedH := handlers.NewScheduleHandler(stores, triggerEngine)
protected.GET("/schedules", userSchedH.ListMySchedules)
protected.POST("/schedules", userSchedH.CreateSchedule)
protected.GET("/schedules/:id", userSchedH.GetSchedule)
protected.PUT("/schedules/:id", userSchedH.UpdateSchedule)
protected.DELETE("/schedules/:id", userSchedH.DeleteSchedule)
protected.POST("/schedules/:id/run", userSchedH.RunSchedule)
protected.GET("/schedules/:id/logs", userSchedH.ListScheduleLogs)
// Teams (user: my teams)
teams := handlers.NewTeamHandler(stores, keyResolver)
protected.GET("/teams/mine", teams.MyTeams)
@@ -649,6 +672,23 @@ func main() {
wfPkgH := handlers.NewWorkflowPackageHandler(stores)
admin.GET("/workflows/:id/export", wfPkgH.ExportWorkflowPackage)
// ── Triggers (v0.2.2) ─────────────────
trigH := handlers.NewTriggerHandler(stores, triggerEngine)
admin.GET("/triggers", trigH.ListTriggers)
admin.GET("/triggers/:id", trigH.GetTrigger)
admin.PUT("/triggers/:id/enable", trigH.EnableTrigger)
admin.PUT("/triggers/:id/disable", trigH.DisableTrigger)
admin.DELETE("/triggers/:id", trigH.DeleteTrigger)
admin.GET("/triggers/:id/logs", trigH.ListTriggerLogs)
admin.GET("/packages/:id/triggers", trigH.ListPackageTriggers)
// ── Scheduled Tasks — Admin (v0.2.2) ──
schedH := handlers.NewScheduleHandler(stores, triggerEngine)
admin.GET("/schedules", schedH.AdminListSchedules)
admin.PUT("/schedules/:id/enable", schedH.AdminEnableSchedule)
admin.PUT("/schedules/:id/disable", schedH.AdminDisableSchedule)
admin.DELETE("/schedules/:id", schedH.AdminDeleteSchedule)
// Surface aliases (backward compat — same handlers)
admin.GET("/surfaces", pkgAdm.ListPackages)
admin.GET("/surfaces/:id", pkgAdm.GetPackage)