Feat v0.6.3 dead code sweep (#38)
All checks were successful
All checks were successful
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #38.
This commit is contained in:
134
server/main.go
134
server/main.go
@@ -36,7 +36,6 @@ import (
|
||||
sqliteStore "switchboard-core/store/sqlite"
|
||||
)
|
||||
|
||||
// v0.33.0: Embedded OpenAPI spec and Swagger UI for /api/docs.
|
||||
//
|
||||
//go:embed static/openapi.yaml
|
||||
var openapiSpec []byte
|
||||
@@ -59,13 +58,10 @@ func main() {
|
||||
// ── Server startup ──────────────────────
|
||||
cfg := config.Load()
|
||||
|
||||
// v0.33.0: Structured logging — must be first so all subsequent
|
||||
// Structured logging — must be first so all subsequent
|
||||
// log output goes through slog.
|
||||
logging.Init(cfg.LogFormat, cfg.LogLevel)
|
||||
|
||||
|
||||
// v0.29.1: Config-file provider types (Ollama, LiteLLM, vLLM, etc.)
|
||||
|
||||
var stores store.Stores
|
||||
uekCache := crypto.NewUEKCache()
|
||||
var keyResolver *crypto.KeyResolver
|
||||
@@ -109,7 +105,6 @@ func main() {
|
||||
stores = postgres.NewStores(database.DB)
|
||||
}
|
||||
|
||||
// v0.33.0: Start Prometheus DB pool collector
|
||||
metrics.StartDBCollector(database.DB, 15*time.Second)
|
||||
|
||||
// Bootstrap admin from env (K8s secret) — upserts on every restart
|
||||
@@ -161,23 +156,18 @@ func main() {
|
||||
sandbox.New(sandbox.DefaultConfig()),
|
||||
stores,
|
||||
)
|
||||
// v0.38.1: connections module — extension connection resolution
|
||||
starlarkRunner.SetConnectionResolver(handlers.NewConnectionResolverAdapter(stores, keyResolver))
|
||||
// v0.29.2: db module — extension namespaced table access
|
||||
starlarkRunner.SetDB(database.DB, database.IsPostgres())
|
||||
// v0.38.0: disk-based script loading + load() support
|
||||
if cfg.StoragePath != "" {
|
||||
starlarkRunner.SetPackagesDir(cfg.StoragePath + "/packages")
|
||||
}
|
||||
// v0.5.0: realtime module — extension publish to WebSocket channels
|
||||
starlarkRunner.SetBus(bus)
|
||||
// v0.38.5: allow extensions to reach private IPs (self-hosted Gitea, etc.)
|
||||
if os.Getenv("EXT_ALLOW_PRIVATE_IPS") == "true" {
|
||||
starlarkRunner.SetAllowPrivateIPs(true)
|
||||
log.Printf(" ⚠️ Extension SSRF protection relaxed: private IPs allowed")
|
||||
}
|
||||
|
||||
// ── Bundled Packages (v0.3.8) ───────────────
|
||||
// ── Bundled Packages ───────────────
|
||||
// Auto-install bundled .pkg archives on first run.
|
||||
// Skipped if SKIP_BUNDLED_PACKAGES=true or packages already exist.
|
||||
if !cfg.SkipBundledPackages && stores.Packages != nil {
|
||||
@@ -188,7 +178,7 @@ func main() {
|
||||
handlers.InstallBundledPackages(cfg.BundledPackagesDir, bundledPkgDir, cfg.BundledPackages, stores, starlarkRunner)
|
||||
}
|
||||
|
||||
// ── Trigger Engine (v0.2.2) ─────────────────
|
||||
// ── Trigger Engine ─────────────────
|
||||
triggerEngine := triggers.New(stores, starlarkRunner, bus)
|
||||
if err := triggerEngine.Start(context.Background()); err != nil {
|
||||
log.Printf(" ⚠️ Trigger engine start: %v", err)
|
||||
@@ -210,7 +200,7 @@ func main() {
|
||||
// ── WebSocket Hub ─────────────────────────
|
||||
hub := events.NewHub(bus, middleware.GetAllowedOrigins(cfg))
|
||||
|
||||
// ── Cluster Registry (v0.6.0) ────────────
|
||||
// ── Cluster Registry ────────────
|
||||
// PG-backed node self-registration + heartbeat. No-op on SQLite.
|
||||
var clusterReg *cluster.Registry
|
||||
if database.IsPostgres() && stores.Cluster != nil {
|
||||
@@ -231,10 +221,10 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// ── WebSocket Ticket Store (v0.32.0: PG-backed for cross-pod) ─────
|
||||
// ── WebSocket Ticket Store ─────
|
||||
ticketAdapter := &events.TicketValidatorAdapter{Store: stores.Tickets}
|
||||
|
||||
// ── Notification Service (v0.20.0) ───────
|
||||
// ── Notification Service ───────
|
||||
var notifSvc *notifications.Service
|
||||
if stores.Notifications != nil {
|
||||
notifSvc = notifications.NewService(stores.Notifications, hub).
|
||||
@@ -277,7 +267,6 @@ func main() {
|
||||
c.JSON(200, info)
|
||||
})
|
||||
|
||||
// v0.32.0: Kubernetes probe endpoints
|
||||
// Liveness: process is alive and serving (no dependency checks).
|
||||
base.GET("/healthz/live", func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{"status": "ok"})
|
||||
@@ -299,10 +288,8 @@ func main() {
|
||||
c.JSON(200, gin.H{"status": "ok"})
|
||||
})
|
||||
|
||||
// v0.33.0: Prometheus metrics endpoint (no auth — Prometheus scrapes directly)
|
||||
base.GET("/metrics", gin.WrapH(promhttp.Handler()))
|
||||
|
||||
// v0.33.0: OpenAPI spec + Swagger UI (no auth — documentation)
|
||||
base.GET("/api/docs", func(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "text/html; charset=utf-8", swaggerHTML)
|
||||
})
|
||||
@@ -311,7 +298,6 @@ func main() {
|
||||
patched := bytes.Replace(openapiSpec, []byte("${VERSION}"), []byte(Version), 1)
|
||||
c.Data(http.StatusOK, "application/yaml", patched)
|
||||
})
|
||||
// v0.6.2: Dynamic OpenAPI spec with extension routes merged in
|
||||
base.GET("/api/docs/openapi.json", func(c *gin.Context) {
|
||||
spec, err := handlers.BuildOpenAPISpec(stores, openapiSpec, Version)
|
||||
if err != nil {
|
||||
@@ -401,7 +387,7 @@ func main() {
|
||||
extH := handlers.NewExtensionHandler(stores)
|
||||
api.GET("/extensions/:id/assets/*path", extH.ServeExtensionAsset)
|
||||
|
||||
// ── Webhook Inbound (v0.2.2) ──────────────
|
||||
// ── Webhook Inbound ──────────────
|
||||
// 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)
|
||||
@@ -409,7 +395,7 @@ func main() {
|
||||
// ── Workflow Engine (shared by public + protected routes) ──
|
||||
wfEngine := workflow.NewEngine(stores, bus, starlarkRunner)
|
||||
|
||||
// ── Public Workflow Entry (v0.3.3) ─────
|
||||
// ── Public Workflow Entry ─────
|
||||
publicWfH := handlers.NewWorkflowPublicHandler(wfEngine, stores)
|
||||
publicWf := api.Group("/public/workflows")
|
||||
publicWf.Use(authLimiter.Limit())
|
||||
@@ -419,7 +405,7 @@ func main() {
|
||||
publicWf.POST("/advance/:token", publicWfH.AdvancePublic)
|
||||
}
|
||||
|
||||
// ── Workflow Scanner (v0.3.3) ──────────
|
||||
// ── Workflow Scanner ──────────
|
||||
wfScanner := workflow.NewScanner(stores, bus)
|
||||
wfScanner.Start()
|
||||
defer wfScanner.Stop()
|
||||
@@ -429,7 +415,7 @@ func main() {
|
||||
protected.Use(middleware.Auth(cfg, stores.Users, userCache))
|
||||
protected.Use(middleware.ValidatePathParams())
|
||||
{
|
||||
// ── WebSocket Ticket (v0.28.8) ───────────
|
||||
// ── WebSocket Ticket ───────────
|
||||
// Issue a single-use ticket for WebSocket auth.
|
||||
// Client fetches this, then connects with ?ticket=<opaque>.
|
||||
protected.POST("/ws/ticket", func(c *gin.Context) {
|
||||
@@ -442,15 +428,15 @@ func main() {
|
||||
c.JSON(http.StatusOK, gin.H{"ticket": ticket})
|
||||
})
|
||||
|
||||
// Presence (v0.23.1)
|
||||
// Presence
|
||||
presence := handlers.NewPresenceHandler(stores)
|
||||
protected.POST("/presence/heartbeat", presence.Heartbeat)
|
||||
protected.GET("/presence", presence.Query)
|
||||
|
||||
// User search (v0.23.2 — DM user picker)
|
||||
// User search
|
||||
protected.GET("/users/search", presence.SearchUsers)
|
||||
|
||||
// Workflows (v0.26.1 — team-owned staged processes)
|
||||
// Workflows
|
||||
wfH := handlers.NewWorkflowHandler(stores)
|
||||
protected.GET("/workflows", wfH.List)
|
||||
protected.POST("/workflows", middleware.RequirePermission(auth.PermWorkflowCreate, stores), wfH.Create)
|
||||
@@ -466,7 +452,7 @@ func main() {
|
||||
protected.POST("/workflows/:id/clone", middleware.RequirePermission(auth.PermWorkflowCreate, stores), wfH.Clone)
|
||||
protected.GET("/workflows/:id/versions/:version", wfH.GetVersion)
|
||||
|
||||
// Workflow instances + assignments (v0.3.2)
|
||||
// Workflow instances + assignments
|
||||
wfInstH := handlers.NewWorkflowInstanceHandler(wfEngine, stores)
|
||||
protected.POST("/workflows/:id/instances", middleware.RequirePermission(auth.PermWorkflowSubmit, stores), wfInstH.Start)
|
||||
protected.GET("/workflows/:id/instances", wfInstH.ListInstances)
|
||||
@@ -481,16 +467,16 @@ func main() {
|
||||
protected.POST("/assignments/:id/cancel", middleware.RequirePermission(auth.PermWorkflowCreate, stores), wfAssignH.Cancel)
|
||||
protected.GET("/assignments/mine", wfAssignH.ListMine)
|
||||
|
||||
// Workflow signoffs (v0.3.4)
|
||||
// Workflow signoffs
|
||||
wfSignoffH := handlers.NewWorkflowSignoffHandler(wfEngine, stores)
|
||||
protected.POST("/instances/:iid/signoffs", wfSignoffH.Submit)
|
||||
protected.GET("/instances/:iid/signoffs", wfSignoffH.List)
|
||||
|
||||
// Surface discovery (v0.25.0, v0.28.7: unified packages)
|
||||
// Surface discovery
|
||||
pkgH := handlers.NewPackageHandler(stores)
|
||||
protected.GET("/surfaces", pkgH.ListEnabledSurfaces)
|
||||
|
||||
// User package management (v0.30.0)
|
||||
// User package management
|
||||
userPkgDir := ""
|
||||
if cfg.StoragePath != "" {
|
||||
userPkgDir = cfg.StoragePath + "/packages"
|
||||
@@ -500,11 +486,11 @@ func main() {
|
||||
protected.POST("/packages/install", userPkgH.InstallPersonalPackage)
|
||||
protected.DELETE("/packages/:id", userPkgH.DeletePersonalPackage)
|
||||
|
||||
// Connection Type Discovery (v0.38.4)
|
||||
// Connection Type Discovery
|
||||
connTypeH := handlers.NewConnectionTypeHandler(stores)
|
||||
protected.GET("/connection-types", connTypeH.ListConnectionTypes)
|
||||
|
||||
// Extension Connections (personal scope — v0.38.1)
|
||||
// Extension Connections (personal scope
|
||||
connH := handlers.NewConnectionHandler(stores, keyResolver)
|
||||
protected.GET("/connections", connH.ListConnections)
|
||||
protected.POST("/connections", connH.CreateConnection)
|
||||
@@ -521,21 +507,21 @@ func main() {
|
||||
protected.GET("/settings", settings.GetSettings)
|
||||
protected.PUT("/settings", settings.UpdateSettings)
|
||||
|
||||
// Documentation (v0.6.1)
|
||||
// Documentation
|
||||
docsDir := findDocsDir()
|
||||
docsH := handlers.NewDocsHandler(docsDir)
|
||||
protected.GET("/docs", docsH.ListDocs)
|
||||
protected.GET("/docs/:name", docsH.GetDoc)
|
||||
|
||||
// Permission bootstrap (v0.37.1) — self-service resolved permissions
|
||||
// Permission bootstrap — self-service resolved permissions
|
||||
permH := handlers.NewProfilePermissionsHandler(stores)
|
||||
protected.GET("/profile/permissions", permH.GetMyPermissions)
|
||||
|
||||
// Boot payload (v0.37.15) — single-call SDK bootstrap
|
||||
// Boot payload — single-call SDK bootstrap
|
||||
bootH := handlers.NewProfileBootstrapHandler(stores)
|
||||
protected.GET("/profile/bootstrap", bootH.GetBootstrap)
|
||||
|
||||
// Notifications (v0.20.0)
|
||||
// Notifications
|
||||
notifH := handlers.NewNotificationHandler(stores, hub)
|
||||
protected.GET("/notifications", notifH.List)
|
||||
protected.GET("/notifications/unread-count", notifH.UnreadCount)
|
||||
@@ -543,12 +529,12 @@ func main() {
|
||||
protected.POST("/notifications/mark-all-read", notifH.MarkAllRead)
|
||||
protected.DELETE("/notifications/:id", notifH.Delete)
|
||||
|
||||
// Notification preferences (v0.20.0 Phase 3)
|
||||
// Notification preferences
|
||||
protected.GET("/notifications/preferences", notifH.ListPreferences)
|
||||
protected.PUT("/notifications/preferences/:type", notifH.SetPreference)
|
||||
protected.DELETE("/notifications/preferences/:type", notifH.DeletePreference)
|
||||
|
||||
// ── Scheduled Tasks — User (v0.2.2) ────
|
||||
// ── Scheduled Tasks — User ────
|
||||
userSchedH := handlers.NewScheduleHandler(stores, triggerEngine)
|
||||
protected.GET("/schedules", userSchedH.ListMySchedules)
|
||||
protected.POST("/schedules", userSchedH.CreateSchedule)
|
||||
@@ -562,7 +548,7 @@ func main() {
|
||||
teams := handlers.NewTeamHandler(stores, keyResolver)
|
||||
protected.GET("/teams/mine", teams.MyTeams)
|
||||
|
||||
// Groups (user: my groups — v0.16.0)
|
||||
// Groups (user: my groups
|
||||
groupH := handlers.NewGroupHandler(stores)
|
||||
protected.GET("/groups/mine", groupH.MyGroups)
|
||||
|
||||
@@ -580,18 +566,18 @@ func main() {
|
||||
// Team groups (team admins manage team-scoped groups)
|
||||
teamScoped.GET("/groups", groupH.ListTeamGroups)
|
||||
|
||||
// Team connections (v0.38.1)
|
||||
// Team connections
|
||||
teamScoped.GET("/connections", teams.ListTeamConnections)
|
||||
teamScoped.POST("/connections", teams.CreateTeamConnection)
|
||||
teamScoped.PUT("/connections/:id", teams.UpdateTeamConnection)
|
||||
teamScoped.DELETE("/connections/:id", teams.DeleteTeamConnection)
|
||||
|
||||
// Team package management (v0.30.0)
|
||||
// Team package management
|
||||
teamPkgH := handlers.NewUserPackageHandler(stores, userPkgDir)
|
||||
teamScoped.POST("/packages/install", teamPkgH.InstallTeamPackage)
|
||||
teamScoped.DELETE("/packages/:id", teamPkgH.DeleteTeamPackage)
|
||||
|
||||
// Team package settings — cascade overrides (v0.2.0)
|
||||
// Team package settings — cascade overrides
|
||||
teamPkgSettingsH := handlers.NewTeamPackageSettingsHandler(stores)
|
||||
teamScoped.GET("/packages/:id/settings", teamPkgSettingsH.GetTeamPackageSettings)
|
||||
teamScoped.PUT("/packages/:id/settings", teamPkgSettingsH.UpdateTeamPackageSettings)
|
||||
@@ -601,7 +587,7 @@ func main() {
|
||||
teamScoped.GET("/audit", teams.ListTeamAuditLog)
|
||||
teamScoped.GET("/audit/actions", teams.ListTeamAuditActions)
|
||||
|
||||
// Team workflows — self-service (v0.31.2)
|
||||
// Team workflows — self-service
|
||||
teamWfH := handlers.NewWorkflowHandler(stores)
|
||||
teamScoped.GET("/workflows", teamWfH.ListTeamWorkflows)
|
||||
teamScoped.POST("/workflows", teamWfH.CreateTeamWorkflow)
|
||||
@@ -619,7 +605,7 @@ func main() {
|
||||
teamScoped.GET("/workflows/available", teamWfH.ListGlobalWorkflows)
|
||||
teamScoped.GET("/workflows/:id/versions/:version", teamWfH.GetTeamWorkflowVersion)
|
||||
|
||||
// Team workflow instances + assignments (v0.3.2)
|
||||
// Team workflow instances + assignments
|
||||
teamWfInstH := handlers.NewWorkflowInstanceHandler(wfEngine, stores)
|
||||
teamScoped.POST("/workflows/:id/instances", teamWfInstH.Start)
|
||||
teamScoped.GET("/workflows/:id/instances", teamWfInstH.ListInstances)
|
||||
@@ -630,7 +616,7 @@ func main() {
|
||||
teamWfAssignH := handlers.NewWorkflowAssignmentHandler(wfEngine, stores)
|
||||
teamScoped.GET("/assignments", teamWfAssignH.ListByTeam)
|
||||
|
||||
// Team workflow signoffs (v0.3.4)
|
||||
// Team workflow signoffs
|
||||
teamWfSignoffH := handlers.NewWorkflowSignoffHandler(wfEngine, stores)
|
||||
teamScoped.POST("/instances/:iid/signoffs", teamWfSignoffH.Submit)
|
||||
teamScoped.GET("/instances/:iid/signoffs", teamWfSignoffH.List)
|
||||
@@ -674,7 +660,7 @@ func main() {
|
||||
// Stats
|
||||
admin.GET("/stats", adm.GetStats)
|
||||
|
||||
// Global Connections (v0.38.1)
|
||||
// Global Connections
|
||||
admin.GET("/connections", adm.ListGlobalConnections)
|
||||
admin.POST("/connections", adm.CreateGlobalConnection)
|
||||
admin.PUT("/connections/:id", adm.UpdateGlobalConnection)
|
||||
@@ -692,7 +678,7 @@ func main() {
|
||||
admin.PUT("/teams/:id/members/:memberId", teamAdm.UpdateMember)
|
||||
admin.DELETE("/teams/:id/members/:memberId", teamAdm.RemoveMember)
|
||||
|
||||
// Admin broadcast (v0.28.6)
|
||||
// Admin broadcast
|
||||
adminNotifH := handlers.NewNotificationHandler(stores, hub)
|
||||
admin.POST("/notifications/broadcast", adminNotifH.Broadcast)
|
||||
|
||||
@@ -700,7 +686,7 @@ func main() {
|
||||
admin.GET("/audit", adm.ListAuditLog)
|
||||
admin.GET("/audit/actions", adm.ListAuditActions)
|
||||
|
||||
// Groups (admin — v0.16.0)
|
||||
// Groups (admin
|
||||
groupAdm := handlers.NewGroupHandler(stores)
|
||||
admin.GET("/groups", groupAdm.ListGroups)
|
||||
admin.POST("/groups", groupAdm.CreateGroup)
|
||||
@@ -711,11 +697,11 @@ func main() {
|
||||
admin.POST("/groups/:id/members", groupAdm.AddMember)
|
||||
admin.DELETE("/groups/:id/members/:userId", groupAdm.RemoveMember)
|
||||
|
||||
// Permissions (v0.24.2)
|
||||
// Permissions
|
||||
admin.GET("/permissions", groupAdm.ListPermissions)
|
||||
admin.GET("/users/:id/permissions", groupAdm.GetUserPermissions)
|
||||
|
||||
// Resource Grants (admin — v0.16.0)
|
||||
// Resource Grants (admin
|
||||
admin.GET("/grants/:type/:id", groupAdm.GetResourceGrant)
|
||||
admin.PUT("/grants/:type/:id", groupAdm.SetResourceGrant)
|
||||
|
||||
@@ -728,7 +714,7 @@ func main() {
|
||||
// Vault
|
||||
admin.GET("/vault/status", adm.VaultStatus)
|
||||
|
||||
// Email / SMTP test (v0.20.0 Phase 3)
|
||||
// Email / SMTP test
|
||||
emailAdm := handlers.NewAdminEmailHandler(stores)
|
||||
admin.POST("/notifications/test-email", emailAdm.TestEmail)
|
||||
|
||||
@@ -739,7 +725,7 @@ func main() {
|
||||
admin.PUT("/extensions/:id", extAdm.AdminUpdateExtension)
|
||||
admin.DELETE("/extensions/:id", extAdm.AdminUninstallExtension)
|
||||
|
||||
// Extension permissions (admin — v0.29.0)
|
||||
// Extension permissions (admin
|
||||
extPermH := handlers.NewExtPermHandler(stores)
|
||||
admin.GET("/extensions/:id/permissions", extPermH.ListPackagePermissions)
|
||||
admin.GET("/extensions/:id/review", extPermH.ReviewPackage)
|
||||
@@ -747,21 +733,21 @@ func main() {
|
||||
admin.POST("/extensions/:id/permissions/:perm/revoke", extPermH.RevokePermission)
|
||||
admin.POST("/extensions/:id/permissions/grant-all", extPermH.GrantAllPermissions)
|
||||
|
||||
// Extension secrets (admin — v0.29.0 CS3)
|
||||
// Extension secrets (admin
|
||||
extSecH := handlers.NewExtSecretsHandler(stores)
|
||||
admin.GET("/extensions/:id/secrets", extSecH.GetSecrets)
|
||||
admin.PUT("/extensions/:id/secrets", extSecH.SetSecrets)
|
||||
admin.DELETE("/extensions/:id/secrets", extSecH.DeleteSecrets)
|
||||
|
||||
// Package lifecycle management (v0.28.7 — replaces surfaces + extensions admin)
|
||||
// Package lifecycle management
|
||||
packagesDir := ""
|
||||
if cfg.StoragePath != "" {
|
||||
packagesDir = cfg.StoragePath + "/packages"
|
||||
}
|
||||
pkgAdm := handlers.NewPackageHandler(stores, packagesDir)
|
||||
pkgAdm.SetSandbox(sandbox.New(sandbox.DefaultConfig())) // v0.30.0: schema migrations
|
||||
pkgAdm.SetSandbox(sandbox.New(sandbox.DefaultConfig()))
|
||||
|
||||
// Package registry — must be registered before /packages/:id (v0.30.0)
|
||||
// Package registry — must be registered before /packages/:id
|
||||
registryH := handlers.NewRegistryHandler(stores, packagesDir, pkgAdm)
|
||||
admin.GET("/packages/registry", registryH.BrowseRegistry)
|
||||
admin.POST("/packages/registry/install", registryH.InstallFromRegistry)
|
||||
@@ -772,20 +758,20 @@ func main() {
|
||||
admin.PUT("/packages/:id/enable", pkgAdm.EnablePackage)
|
||||
admin.PUT("/packages/:id/disable", pkgAdm.DisablePackage)
|
||||
admin.DELETE("/packages/:id", pkgAdm.DeletePackage)
|
||||
admin.GET("/packages/:id/settings", pkgAdm.GetPackageSettings) // v0.30.0
|
||||
admin.PUT("/packages/:id/settings", pkgAdm.UpdatePackageSettings) // v0.30.0
|
||||
admin.GET("/packages/:id/dependencies", pkgAdm.ListDependencies) // v0.38.2
|
||||
admin.GET("/packages/:id/consumers", pkgAdm.ListConsumers) // v0.38.2
|
||||
admin.POST("/packages/:id/test-tool", pkgAdm.TestTool) // v0.38.2
|
||||
admin.POST("/packages/:id/update", pkgAdm.UpdatePackage) // v0.5.4
|
||||
admin.GET("/packages/:id/export", pkgAdm.ExportPackage) // v0.5.4
|
||||
admin.GET("/dependencies", pkgAdm.ListAllDependencies) // v0.38.2
|
||||
admin.GET("/packages/:id/settings", pkgAdm.GetPackageSettings)
|
||||
admin.PUT("/packages/:id/settings", pkgAdm.UpdatePackageSettings)
|
||||
admin.GET("/packages/:id/dependencies", pkgAdm.ListDependencies)
|
||||
admin.GET("/packages/:id/consumers", pkgAdm.ListConsumers)
|
||||
admin.POST("/packages/:id/test-tool", pkgAdm.TestTool)
|
||||
admin.POST("/packages/:id/update", pkgAdm.UpdatePackage)
|
||||
admin.GET("/packages/:id/export", pkgAdm.ExportPackage)
|
||||
admin.GET("/dependencies", pkgAdm.ListAllDependencies)
|
||||
|
||||
// Workflow package export (v0.30.2)
|
||||
// Workflow package export
|
||||
wfPkgH := handlers.NewWorkflowPackageHandler(stores)
|
||||
admin.GET("/workflows/:id/export", wfPkgH.ExportWorkflowPackage)
|
||||
|
||||
// ── Triggers (v0.2.2) ─────────────────
|
||||
// ── Triggers ─────────────────
|
||||
trigH := handlers.NewTriggerHandler(stores, triggerEngine)
|
||||
admin.GET("/triggers", trigH.ListTriggers)
|
||||
admin.GET("/triggers/:id", trigH.GetTrigger)
|
||||
@@ -795,20 +781,20 @@ func main() {
|
||||
admin.GET("/triggers/:id/logs", trigH.ListTriggerLogs)
|
||||
admin.GET("/packages/:id/triggers", trigH.ListPackageTriggers)
|
||||
|
||||
// ── Scheduled Tasks — Admin (v0.2.2) ──
|
||||
// ── Scheduled Tasks — Admin ──
|
||||
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)
|
||||
|
||||
// ── Cluster (v0.6.0) ─────────────────
|
||||
// ── Cluster ─────────────────
|
||||
if stores.Cluster != nil {
|
||||
clusterH := handlers.NewClusterHandler(stores)
|
||||
admin.GET("/cluster", clusterH.ListNodes)
|
||||
}
|
||||
|
||||
// ── Backup/Restore (v0.6.1) ─────────
|
||||
// ── Backup/Restore ─────────
|
||||
backupH := handlers.NewBackupHandler(stores, packagesDir, cfg.StoragePath)
|
||||
admin.POST("/backup", backupH.CreateBackup)
|
||||
admin.GET("/backups", backupH.ListBackups)
|
||||
@@ -828,9 +814,7 @@ func main() {
|
||||
}
|
||||
|
||||
// ── Page Routes ──────────────────────────
|
||||
// v0.27.0: Extension surface static assets (JS, CSS, images).
|
||||
// Served without auth — same rationale as extension assets (script tags can't send headers).
|
||||
// v0.28.7: on-disk path moved to /data/packages/, URL stays /surfaces/:id/ for stability.
|
||||
// In split deployment, nginx serves these from /data/packages/ directly.
|
||||
if cfg.StoragePath != "" {
|
||||
packagesStaticDir := cfg.StoragePath + "/packages"
|
||||
@@ -850,13 +834,12 @@ func main() {
|
||||
pages.SetVersion(Version)
|
||||
pageEngine := pages.New(cfg, stores)
|
||||
|
||||
// Root redirect → configurable default surface (v0.2.1)
|
||||
// Root redirect → configurable default surface
|
||||
base.GET("/", pageEngine.DefaultSurfaceRedirect())
|
||||
|
||||
// Login page — no auth required
|
||||
base.GET("/login", pageEngine.RenderLogin())
|
||||
|
||||
// v0.25.0: Surface routes generated from manifest registry.
|
||||
// Replaces manual per-surface route blocks.
|
||||
pageEngine.RegisterPageRoutes(base, pages.PageRouteMiddleware{
|
||||
Authenticated: middleware.AuthOrRedirect(cfg, stores.Users, userCache),
|
||||
@@ -864,10 +847,9 @@ func main() {
|
||||
middleware.AuthOrRedirect(cfg, stores.Users, userCache),
|
||||
middleware.RequireAdminPage(stores),
|
||||
},
|
||||
Session: middleware.AuthOrRedirect(cfg, stores.Users, userCache), // TODO: session middleware for workflow visitors (v0.2.0)
|
||||
Session: middleware.AuthOrRedirect(cfg, stores.Users, userCache), // TODO: session middleware for workflow visitors
|
||||
})
|
||||
|
||||
// v0.29.1: Extension API routes — Starlark packages serve JSON endpoints.
|
||||
// Mounted at /s/:slug/api/* with JWT auth (returns 401, not redirect).
|
||||
{
|
||||
extAPIH := handlers.NewExtAPIHandler(stores, starlarkRunner)
|
||||
|
||||
Reference in New Issue
Block a user