From 2e93df5d699cde5b6592478b4d2fe09a2c27b727 Mon Sep 17 00:00:00 2001 From: hongming-ceo-delegated Date: Fri, 22 May 2026 17:17:28 -0700 Subject: [PATCH] =?UTF-8?q?fix(scheduler):=20#1692=20=E2=80=94=20mount=20S?= =?UTF-8?q?cheduleHandler=20HTTP=20routes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The handler + Temporal cron worker are implemented in workspace-server/internal/handlers/schedules.go + platform/internal/scheduler, but the HTTP routes were never mounted. Every call to /workspaces/:id/schedules returned 404, so: - Canvas "Schedule" tab silently failed to load/save schedules - Agent MCP set_schedule tool returned 404 → agents had no way to self-schedule wake-ups (PM in particular had no platform-side scheduler and was relying on the CTO orchestrator's /loop tick as its only heartbeat) Routes are mounted under WorkspaceAuth so the per-workspace bearer token scopes ownership, matching the IDOR-fix shape in handlers/schedules.go (Update/Delete/RunNow/History rebind to workspaceID before touching the row). Endpoints exposed: GET /workspaces/:id/schedules POST /workspaces/:id/schedules PUT /workspaces/:id/schedules/:scheduleId DELETE /workspaces/:id/schedules/:scheduleId POST /workspaces/:id/schedules/:scheduleId/run GET /workspaces/:id/schedules/:scheduleId/history GET /workspaces/:id/schedules/health Co-Authored-By: Claude Opus 4.7 (1M context) --- workspace-server/internal/router/router.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/workspace-server/internal/router/router.go b/workspace-server/internal/router/router.go index 7ce0c1834..4a63d100f 100644 --- a/workspace-server/internal/router/router.go +++ b/workspace-server/internal/router/router.go @@ -311,6 +311,24 @@ func Setup(hub *ws.Hub, broadcaster *events.Broadcaster, prov *provisioner.Provi wsAuth.PATCH("/agent", ah.Replace) wsAuth.DELETE("/agent", ah.Remove) wsAuth.POST("/agent/move", ah.Move) + + // Schedules (#1692). The handler + Temporal cron worker are + // implemented in workspace-server/internal/handlers/schedules.go + + // platform/internal/scheduler, but the HTTP routes were never + // mounted — every call returned 404 (Canvas "Schedule" tab + agent + // MCP set_schedule both silently failed). Mounting here puts the + // endpoints under WorkspaceAuth so the per-workspace bearer token + // scopes ownership, matching the IDOR-fix shape in handlers/schedules.go + // (Update/Delete/RunNow/History rebind to workspaceID before + // touching the row). + sch := handlers.NewScheduleHandler() + wsAuth.GET("/schedules", sch.List) + wsAuth.POST("/schedules", sch.Create) + wsAuth.PUT("/schedules/:scheduleId", sch.Update) + wsAuth.DELETE("/schedules/:scheduleId", sch.Delete) + wsAuth.POST("/schedules/:scheduleId/run", sch.RunNow) + wsAuth.GET("/schedules/:scheduleId/history", sch.History) + wsAuth.GET("/schedules/health", sch.Health) } // Registry -- 2.52.0