Fix golangci-lint unused failure — export OpenAPI response types
CI / Canvas Deploy Reminder (pull_request) Blocked by required conditions
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 7s
CI / Python Lint & Test (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 9s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
Harness Replays / detect-changes (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
Lint no tenant GITEA or GITHUB token write / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request) Successful in 9s
qa-review / approved (pull_request) Failing after 3s
security-review / approved (pull_request) Failing after 3s
sop-checklist / review-refire (pull_request) Has been skipped
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m8s
CI / Canvas (Next.js) (pull_request) Successful in 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
E2E Chat / E2E Chat (pull_request) Successful in 5s
Harness Replays / Harness Replays (pull_request) Successful in 3s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m7s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m19s
CI / Platform (Go) (pull_request) Successful in 5m50s
CI / all-required (pull_request) Successful in 14m14s
audit-force-merge / audit (pull_request) Successful in 3s
CI / Canvas Deploy Reminder (pull_request) Blocked by required conditions
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 7s
CI / Python Lint & Test (pull_request) Successful in 4s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
E2E Chat / detect-changes (pull_request) Successful in 9s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 6s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 5s
Harness Replays / detect-changes (pull_request) Successful in 2s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 4s
Lint no tenant GITEA or GITHUB token write / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 3s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request) Successful in 9s
qa-review / approved (pull_request) Failing after 3s
security-review / approved (pull_request) Failing after 3s
sop-checklist / review-refire (pull_request) Has been skipped
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request) Successful in 4s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m8s
CI / Canvas (Next.js) (pull_request) Successful in 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
E2E Chat / E2E Chat (pull_request) Successful in 5s
Harness Replays / Harness Replays (pull_request) Successful in 3s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m7s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2m19s
CI / Platform (Go) (pull_request) Successful in 5m50s
CI / all-required (pull_request) Successful in 14m14s
audit-force-merge / audit (pull_request) Successful in 3s
CI / Platform (Go) flagged `internal/handlers/schedules.go:19:6: type
errorResponse is unused (unused)` because golangci-lint's `unused`
checker doesn't recognise swaggo's `@Success {object} errorResponse`
annotations as references — the types are only used in comments
from Go's perspective.
Fix: export all OpenAPI request/response types. Exported names are
skipped by the unused-checker (package consumers may exist outside
the package, even if absent inside it).
Renamed:
- errorResponse → ErrorResponse
- statusResponse → StatusResponse
- createScheduleResponse → CreateScheduleResponse
- runNowResponse → RunNowResponse
- historyEntry → HistoryEntry
- scheduleResponse → ScheduleResponse
- createScheduleRequest → CreateScheduleRequest
- updateScheduleRequest → UpdateScheduleRequest
- scheduleHealthResponse → ScheduleHealthResponse (test ref updated)
Regenerated docs/openapi/swagger.{yaml,json} with new type names.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,14 +42,14 @@
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/handlers.scheduleResponse"
|
||||
"$ref": "#/definitions/handlers.ScheduleResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.createScheduleRequest"
|
||||
"$ref": "#/definitions/handlers.CreateScheduleRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -93,19 +93,19 @@
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.createScheduleResponse"
|
||||
"$ref": "#/definitions/handlers.CreateScheduleResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,19 +146,19 @@
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.statusResponse"
|
||||
"$ref": "#/definitions/handlers.StatusResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,7 +201,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.updateScheduleRequest"
|
||||
"$ref": "#/definitions/handlers.UpdateScheduleRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -209,25 +209,25 @@
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.scheduleResponse"
|
||||
"$ref": "#/definitions/handlers.ScheduleResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,14 +270,14 @@
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/handlers.historyEntry"
|
||||
"$ref": "#/definitions/handlers.HistoryEntry"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,19 +318,19 @@
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.runNowResponse"
|
||||
"$ref": "#/definitions/handlers.RunNowResponse"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.errorResponse"
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,7 +338,7 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"handlers.createScheduleRequest": {
|
||||
"handlers.CreateScheduleRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"cron_expr",
|
||||
@@ -362,7 +362,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.createScheduleResponse": {
|
||||
"handlers.CreateScheduleResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -376,7 +376,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.errorResponse": {
|
||||
"handlers.ErrorResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"error": {
|
||||
@@ -384,7 +384,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.historyEntry": {
|
||||
"handlers.HistoryEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"duration_ms": {
|
||||
@@ -404,7 +404,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.runNowResponse": {
|
||||
"handlers.RunNowResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"prompt": {
|
||||
@@ -418,7 +418,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.scheduleResponse": {
|
||||
"handlers.ScheduleResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
@@ -469,7 +469,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.statusResponse": {
|
||||
"handlers.StatusResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
@@ -477,7 +477,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlers.updateScheduleRequest": {
|
||||
"handlers.UpdateScheduleRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cron_expr": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
basePath: /
|
||||
definitions:
|
||||
handlers.createScheduleRequest:
|
||||
handlers.CreateScheduleRequest:
|
||||
properties:
|
||||
cron_expr:
|
||||
type: string
|
||||
@@ -16,7 +16,7 @@ definitions:
|
||||
- cron_expr
|
||||
- prompt
|
||||
type: object
|
||||
handlers.createScheduleResponse:
|
||||
handlers.CreateScheduleResponse:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
@@ -25,12 +25,12 @@ definitions:
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
handlers.errorResponse:
|
||||
handlers.ErrorResponse:
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
type: object
|
||||
handlers.historyEntry:
|
||||
handlers.HistoryEntry:
|
||||
properties:
|
||||
duration_ms:
|
||||
type: integer
|
||||
@@ -43,7 +43,7 @@ definitions:
|
||||
timestamp:
|
||||
type: string
|
||||
type: object
|
||||
handlers.runNowResponse:
|
||||
handlers.RunNowResponse:
|
||||
properties:
|
||||
prompt:
|
||||
type: string
|
||||
@@ -52,7 +52,7 @@ definitions:
|
||||
workspace_id:
|
||||
type: string
|
||||
type: object
|
||||
handlers.scheduleResponse:
|
||||
handlers.ScheduleResponse:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
@@ -87,12 +87,12 @@ definitions:
|
||||
workspace_id:
|
||||
type: string
|
||||
type: object
|
||||
handlers.statusResponse:
|
||||
handlers.StatusResponse:
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
handlers.updateScheduleRequest:
|
||||
handlers.UpdateScheduleRequest:
|
||||
properties:
|
||||
cron_expr:
|
||||
type: string
|
||||
@@ -130,12 +130,12 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/handlers.scheduleResponse'
|
||||
$ref: '#/definitions/handlers.ScheduleResponse'
|
||||
type: array
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
OrgSlugAuth: []
|
||||
@@ -156,22 +156,22 @@ paths:
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.createScheduleRequest'
|
||||
$ref: '#/definitions/handlers.CreateScheduleRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Created
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.createScheduleResponse'
|
||||
$ref: '#/definitions/handlers.CreateScheduleResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
OrgSlugAuth: []
|
||||
@@ -197,15 +197,15 @@ paths:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.statusResponse'
|
||||
$ref: '#/definitions/handlers.StatusResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
OrgSlugAuth: []
|
||||
@@ -231,26 +231,26 @@ paths:
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.updateScheduleRequest'
|
||||
$ref: '#/definitions/handlers.UpdateScheduleRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.scheduleResponse'
|
||||
$ref: '#/definitions/handlers.ScheduleResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
OrgSlugAuth: []
|
||||
@@ -277,12 +277,12 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/handlers.historyEntry'
|
||||
$ref: '#/definitions/handlers.HistoryEntry'
|
||||
type: array
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
OrgSlugAuth: []
|
||||
@@ -308,15 +308,15 @@ paths:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.runNowResponse'
|
||||
$ref: '#/definitions/handlers.RunNowResponse'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.errorResponse'
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
OrgSlugAuth: []
|
||||
|
||||
@@ -15,32 +15,32 @@ import (
|
||||
"github.com/Molecule-AI/molecule-monorepo/platform/internal/scheduler"
|
||||
)
|
||||
|
||||
// errorResponse is returned for 4xx/5xx errors. (OpenAPI doc shape — used by swaggo.)
|
||||
type errorResponse struct {
|
||||
// ErrorResponse is returned for 4xx/5xx errors. (OpenAPI doc shape — used by swaggo.)
|
||||
type ErrorResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// statusResponse is returned by mutating endpoints that only echo a status verb.
|
||||
type statusResponse struct {
|
||||
// StatusResponse is returned by mutating endpoints that only echo a status verb.
|
||||
type StatusResponse struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// createScheduleResponse is returned by POST /workspaces/{id}/schedules.
|
||||
type createScheduleResponse struct {
|
||||
// CreateScheduleResponse is returned by POST /workspaces/{id}/schedules.
|
||||
type CreateScheduleResponse struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
NextRunAt time.Time `json:"next_run_at"`
|
||||
}
|
||||
|
||||
// runNowResponse is returned by POST /workspaces/{id}/schedules/{scheduleId}/run.
|
||||
type runNowResponse struct {
|
||||
// RunNowResponse is returned by POST /workspaces/{id}/schedules/{scheduleId}/run.
|
||||
type RunNowResponse struct {
|
||||
Status string `json:"status"`
|
||||
WorkspaceID string `json:"workspace_id"`
|
||||
Prompt string `json:"prompt"`
|
||||
}
|
||||
|
||||
// historyEntry is one row of /workspaces/{id}/schedules/{scheduleId}/history.
|
||||
type historyEntry struct {
|
||||
// HistoryEntry is one row of /workspaces/{id}/schedules/{scheduleId}/history.
|
||||
type HistoryEntry struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
DurationMs *int `json:"duration_ms"`
|
||||
Status *string `json:"status"`
|
||||
@@ -54,7 +54,7 @@ func NewScheduleHandler() *ScheduleHandler {
|
||||
return &ScheduleHandler{}
|
||||
}
|
||||
|
||||
type scheduleResponse struct {
|
||||
type ScheduleResponse struct {
|
||||
ID string `json:"id"`
|
||||
WorkspaceID string `json:"workspace_id"`
|
||||
Name string `json:"name"`
|
||||
@@ -78,8 +78,8 @@ type scheduleResponse struct {
|
||||
// @Tags schedules
|
||||
// @Produce json
|
||||
// @Param id path string true "Workspace ID"
|
||||
// @Success 200 {array} scheduleResponse
|
||||
// @Failure 500 {object} errorResponse
|
||||
// @Success 200 {array} ScheduleResponse
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
// @Router /workspaces/{id}/schedules [get]
|
||||
// @Security BearerAuth && OrgSlugAuth
|
||||
func (h *ScheduleHandler) List(c *gin.Context) {
|
||||
@@ -100,9 +100,9 @@ func (h *ScheduleHandler) List(c *gin.Context) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
schedules := make([]scheduleResponse, 0)
|
||||
schedules := make([]ScheduleResponse, 0)
|
||||
for rows.Next() {
|
||||
var s scheduleResponse
|
||||
var s ScheduleResponse
|
||||
if err := rows.Scan(
|
||||
&s.ID, &s.WorkspaceID, &s.Name, &s.CronExpr, &s.Timezone,
|
||||
&s.Prompt, &s.Enabled, &s.LastRunAt, &s.NextRunAt, &s.RunCount,
|
||||
@@ -120,7 +120,7 @@ func (h *ScheduleHandler) List(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, schedules)
|
||||
}
|
||||
|
||||
type createScheduleRequest struct {
|
||||
type CreateScheduleRequest struct {
|
||||
Name string `json:"name"`
|
||||
CronExpr string `json:"cron_expr" binding:"required"`
|
||||
Timezone string `json:"timezone"`
|
||||
@@ -135,17 +135,17 @@ type createScheduleRequest struct {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Workspace ID"
|
||||
// @Param body body createScheduleRequest true "Schedule fields"
|
||||
// @Success 201 {object} createScheduleResponse
|
||||
// @Failure 400 {object} errorResponse
|
||||
// @Failure 500 {object} errorResponse
|
||||
// @Param body body CreateScheduleRequest true "Schedule fields"
|
||||
// @Success 201 {object} CreateScheduleResponse
|
||||
// @Failure 400 {object} ErrorResponse
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
// @Router /workspaces/{id}/schedules [post]
|
||||
// @Security BearerAuth && OrgSlugAuth
|
||||
func (h *ScheduleHandler) Create(c *gin.Context) {
|
||||
workspaceID := c.Param("id")
|
||||
ctx := c.Request.Context()
|
||||
|
||||
var body createScheduleRequest
|
||||
var body CreateScheduleRequest
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "cron_expr and prompt are required"})
|
||||
return
|
||||
@@ -199,7 +199,7 @@ func (h *ScheduleHandler) Create(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
type updateScheduleRequest struct {
|
||||
type UpdateScheduleRequest struct {
|
||||
Name *string `json:"name"`
|
||||
CronExpr *string `json:"cron_expr"`
|
||||
Timezone *string `json:"timezone"`
|
||||
@@ -216,11 +216,11 @@ type updateScheduleRequest struct {
|
||||
// @Produce json
|
||||
// @Param id path string true "Workspace ID"
|
||||
// @Param scheduleId path string true "Schedule ID"
|
||||
// @Param body body updateScheduleRequest true "Partial schedule fields (only provided keys are updated)"
|
||||
// @Success 200 {object} scheduleResponse
|
||||
// @Failure 400 {object} errorResponse
|
||||
// @Failure 404 {object} errorResponse
|
||||
// @Failure 500 {object} errorResponse
|
||||
// @Param body body UpdateScheduleRequest true "Partial schedule fields (only provided keys are updated)"
|
||||
// @Success 200 {object} ScheduleResponse
|
||||
// @Failure 400 {object} ErrorResponse
|
||||
// @Failure 404 {object} ErrorResponse
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
// @Router /workspaces/{id}/schedules/{scheduleId} [patch]
|
||||
// @Security BearerAuth && OrgSlugAuth
|
||||
func (h *ScheduleHandler) Update(c *gin.Context) {
|
||||
@@ -228,7 +228,7 @@ func (h *ScheduleHandler) Update(c *gin.Context) {
|
||||
workspaceID := c.Param("id") // #113: bind to owning workspace to prevent IDOR
|
||||
ctx := c.Request.Context()
|
||||
|
||||
var body updateScheduleRequest
|
||||
var body UpdateScheduleRequest
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON"})
|
||||
return
|
||||
@@ -304,9 +304,9 @@ func (h *ScheduleHandler) Update(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path string true "Workspace ID"
|
||||
// @Param scheduleId path string true "Schedule ID"
|
||||
// @Success 200 {object} statusResponse
|
||||
// @Failure 404 {object} errorResponse
|
||||
// @Failure 500 {object} errorResponse
|
||||
// @Success 200 {object} StatusResponse
|
||||
// @Failure 404 {object} ErrorResponse
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
// @Router /workspaces/{id}/schedules/{scheduleId} [delete]
|
||||
// @Security BearerAuth && OrgSlugAuth
|
||||
func (h *ScheduleHandler) Delete(c *gin.Context) {
|
||||
@@ -337,9 +337,9 @@ func (h *ScheduleHandler) Delete(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path string true "Workspace ID"
|
||||
// @Param scheduleId path string true "Schedule ID"
|
||||
// @Success 200 {object} runNowResponse
|
||||
// @Failure 404 {object} errorResponse
|
||||
// @Failure 500 {object} errorResponse
|
||||
// @Success 200 {object} RunNowResponse
|
||||
// @Failure 404 {object} ErrorResponse
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
// @Router /workspaces/{id}/schedules/{scheduleId}/run [post]
|
||||
// @Security BearerAuth && OrgSlugAuth
|
||||
func (h *ScheduleHandler) RunNow(c *gin.Context) {
|
||||
@@ -378,8 +378,8 @@ func (h *ScheduleHandler) RunNow(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param id path string true "Workspace ID"
|
||||
// @Param scheduleId path string true "Schedule ID"
|
||||
// @Success 200 {array} historyEntry
|
||||
// @Failure 500 {object} errorResponse
|
||||
// @Success 200 {array} HistoryEntry
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
// @Router /workspaces/{id}/schedules/{scheduleId}/history [get]
|
||||
// @Security BearerAuth && OrgSlugAuth
|
||||
func (h *ScheduleHandler) History(c *gin.Context) {
|
||||
@@ -407,9 +407,9 @@ func (h *ScheduleHandler) History(c *gin.Context) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
entries := make([]historyEntry, 0)
|
||||
entries := make([]HistoryEntry, 0)
|
||||
for rows.Next() {
|
||||
var e historyEntry
|
||||
var e HistoryEntry
|
||||
var reqStr string
|
||||
if err := rows.Scan(&e.Timestamp, &e.DurationMs, &e.Status, &e.ErrorDetail, &reqStr); err != nil {
|
||||
continue
|
||||
@@ -421,11 +421,11 @@ func (h *ScheduleHandler) History(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, entries)
|
||||
}
|
||||
|
||||
// scheduleHealthResponse is the read-only health view of a schedule.
|
||||
// ScheduleHealthResponse is the read-only health view of a schedule.
|
||||
// It deliberately omits prompt and cron_expr so sensitive task content is
|
||||
// never exposed to peer workspaces — only execution-state fields needed to
|
||||
// detect silent cron failures are returned (issue #249).
|
||||
type scheduleHealthResponse struct {
|
||||
type ScheduleHealthResponse struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Enabled bool `json:"enabled"`
|
||||
@@ -494,9 +494,9 @@ func (h *ScheduleHandler) Health(c *gin.Context) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
schedules := make([]scheduleHealthResponse, 0)
|
||||
schedules := make([]ScheduleHealthResponse, 0)
|
||||
for rows.Next() {
|
||||
var s scheduleHealthResponse
|
||||
var s ScheduleHealthResponse
|
||||
if err := rows.Scan(
|
||||
&s.ID, &s.Name, &s.Enabled, &s.LastRunAt, &s.NextRunAt,
|
||||
&s.RunCount, &s.LastStatus, &s.LastError,
|
||||
|
||||
@@ -234,7 +234,7 @@ func TestScheduleHealth_SelfCall_Allowed(t *testing.T) {
|
||||
t.Fatalf("expected 200 for self-call, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var resp []scheduleHealthResponse
|
||||
var resp []ScheduleHealthResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("failed to parse response: %v", err)
|
||||
}
|
||||
@@ -284,7 +284,7 @@ func TestScheduleHealth_CanCommunicatePeer_LegacyNoToken(t *testing.T) {
|
||||
t.Fatalf("expected 200 for peer with no tokens, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var resp []scheduleHealthResponse
|
||||
var resp []ScheduleHealthResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user