OpenAPI spec at /api/docs with a Scalar viewer, opt-in via FEAT_API_DOCS
This commit is contained in:
251 files changed
+32497
-66
No files matched your search
@@ -47,6 +47,12 @@ export interface ScheduleInfo {
|
||||
vulnerabilityCriteria?: VulnerabilityCriteria | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: List all schedules (container/env auto-updates, git syncs, image-prune, backups, repo maintenance, system jobs)
|
||||
* resp-200: {schedules:array<{id:integer!, type:string!, name:string!, entityName:string!, environmentId:integer, enabled:boolean!, cronExpression:string, nextRun:string, isSystem:boolean!}>!}
|
||||
* resp-500: Unexpected error while assembling the schedule list
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
|
||||
|
||||
@@ -20,6 +20,16 @@ import {
|
||||
import { unregisterSchedule } from '$lib/server/scheduler';
|
||||
import { authorize } from '$lib/server/authorize';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Delete (or disable, for policy-driven types) a schedule by type and id
|
||||
* path: type:string! Schedule type (container_update, git_stack_sync, env_update_check, image_prune, backup, repo_prune, repo_check, repo_verify, system_cleanup)
|
||||
* path: id:integer! Schedule id (semantics depend on type — container/git-stack/backup-config id, environment id, or a synthetic repo-policy id) (from GET /api/schedules)
|
||||
* resp-200: {success:boolean!}
|
||||
* resp-400: Invalid schedule id, invalid/unsupported type, or system_cleanup (cannot be removed)
|
||||
* resp-404: Schedule (or backup destination, for repo_* types) not found
|
||||
* resp-500: Unexpected error while deleting the schedule
|
||||
*/
|
||||
export const DELETE: RequestHandler = async ({ params, cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
|
||||
|
||||
@@ -18,6 +18,16 @@ import { authorize } from '$lib/server/authorize';
|
||||
import { getAutoUpdateSettingById, getGitStack } from '$lib/server/db';
|
||||
import { BACKUPS_ENABLED } from '$lib/server/features';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Manually trigger a single run of a schedule (outside its cron), by type and id
|
||||
* path: type:string! Schedule type (container_update, git_stack_sync, system_cleanup, env_update_check, image_prune, backup, repo_prune, repo_check, repo_verify)
|
||||
* path: id:integer! Schedule id (semantics depend on type) (from GET /api/schedules)
|
||||
* resp-200: {success:boolean!, message:string!}
|
||||
* resp-400: Invalid schedule id/type, or the triggered task itself reported failure
|
||||
* resp-404: Schedule, backup config, or backup destination not found (or backup feature disabled)
|
||||
* resp-500: Unexpected error while triggering the schedule
|
||||
*/
|
||||
export const POST: RequestHandler = async ({ params, cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
|
||||
|
||||
@@ -10,6 +10,16 @@ import { registerSchedule, unregisterSchedule } from '$lib/server/scheduler';
|
||||
import { authorize } from '$lib/server/authorize';
|
||||
import { auditBackup, auditBackupDestination } from '$lib/server/audit';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Toggle a schedule's enabled/disabled state (registers/unregisters the croner job accordingly)
|
||||
* path: type:string! Schedule type (container_update, git_stack_sync, env_update_check, image_prune, backup, repo_prune, repo_check, repo_verify, system_cleanup)
|
||||
* path: id:integer! Schedule id (semantics depend on type) (from GET /api/schedules)
|
||||
* resp-200: {success:boolean!, enabled:boolean!}
|
||||
* resp-400: Invalid schedule id, unsupported type, or system_cleanup (cannot be paused)
|
||||
* resp-404: Schedule, backup config, or backup destination not found
|
||||
* resp-500: Unexpected error while toggling the schedule
|
||||
*/
|
||||
export const POST: RequestHandler = async (event) => {
|
||||
const { params, cookies } = event;
|
||||
const auth = await authorize(cookies);
|
||||
|
||||
@@ -24,6 +24,22 @@ import {
|
||||
type ScheduleStatus
|
||||
} from '$lib/server/db';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: List schedule execution history, filterable and paginated
|
||||
* query: scheduleType:string Filter by schedule type (container_update, git_stack_sync, ...)
|
||||
* query: scheduleId:integer Filter by the numeric id of the schedule (from GET /api/schedules)
|
||||
* query: environmentId:integer Filter by environment id ("null" for global/system schedules) (from GET /api/environments)
|
||||
* query: status:string Filter by execution status (queued/running/success/warning/failed/skipped)
|
||||
* query: statuses:string Comma-separated list of statuses (alternative to status)
|
||||
* query: triggeredBy:string Filter by trigger (cron/webhook/manual)
|
||||
* query: fromDate:string ISO date lower bound
|
||||
* query: toDate:string ISO date upper bound
|
||||
* query: limit:integer Page size (default 50)
|
||||
* query: offset:integer Page offset (default 0)
|
||||
* resp-200: {executions:array<{id:integer!, scheduleType:string!, status:string!, startedAt:string!}>!, total:integer!, limit:integer!, offset:integer!}
|
||||
* resp-500: Unexpected error while loading execution history
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ url }) => {
|
||||
try {
|
||||
const scheduleType = url.searchParams.get('scheduleType') as ScheduleType | null;
|
||||
|
||||
@@ -10,6 +10,15 @@ import type { RequestHandler } from './$types';
|
||||
import { getScheduleExecution, deleteScheduleExecution } from '$lib/server/db';
|
||||
import { authorize } from '$lib/server/authorize';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Get a single schedule execution, including its logs
|
||||
* path: id:integer! Execution id (from GET /api/schedules/executions)
|
||||
* resp-200: {id:integer!, scheduleType:string!, status:string!, startedAt:string!, log:string}
|
||||
* resp-400: Invalid execution id
|
||||
* resp-404: Execution not found
|
||||
* resp-500: Unexpected error while loading the execution
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ params }) => {
|
||||
try {
|
||||
const id = parseInt(params.id, 10);
|
||||
@@ -29,6 +38,15 @@ export const GET: RequestHandler = async ({ params }) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Delete a single schedule execution record
|
||||
* path: id:integer! Execution id (from GET /api/schedules/executions)
|
||||
* resp-200: {success:boolean!}
|
||||
* resp-400: Invalid execution id
|
||||
* resp-403: Permission denied (RBAC 'schedules:edit' missing)
|
||||
* resp-500: Unexpected error while deleting the execution
|
||||
*/
|
||||
export const DELETE: RequestHandler = async ({ params, cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
if (auth.authEnabled && !await auth.can('schedules', 'edit')) {
|
||||
|
||||
@@ -16,6 +16,12 @@ import { authorize } from '$lib/server/authorize';
|
||||
const getHideSystemJobsKey = (userId?: number) =>
|
||||
userId ? `user_${userId}_schedules_hide_system_jobs` : 'schedules_hide_system_jobs';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Get the schedules-page display preference (hide system jobs), per-user with a global fallback
|
||||
* resp-200: {hideSystemJobs:boolean!}
|
||||
* resp-500: Unexpected error while loading the setting
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ cookies }) => {
|
||||
try {
|
||||
const auth = await authorize(cookies);
|
||||
@@ -37,6 +43,15 @@ export const GET: RequestHandler = async ({ cookies }) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Update the schedules-page display preference (hide system jobs) for the current user
|
||||
* body: {hideSystemJobs:boolean}
|
||||
* body-example: {"hideSystemJobs":true}
|
||||
* resp-200: {success:boolean!, hideSystemJobs:boolean}
|
||||
* resp-400: hideSystemJobs is not a boolean
|
||||
* resp-500: Unexpected error while saving the setting
|
||||
*/
|
||||
export const PUT: RequestHandler = async ({ request, cookies }) => {
|
||||
try {
|
||||
const auth = await authorize(cookies);
|
||||
|
||||
@@ -336,6 +336,12 @@ async function getSchedulesData(): Promise<ScheduleInfo[]> {
|
||||
return schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Server-Sent Events stream that polls and pushes schedule updates (same shape as GET /api/schedules)
|
||||
* resp-200: text/event-stream response, periodically emitting the current schedule list as SSE "data:" messages
|
||||
* resp-403: Permission denied (RBAC 'schedules:view' missing)
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
if (auth.authEnabled && !await auth.can('schedules', 'view')) {
|
||||
|
||||
@@ -14,6 +14,15 @@ const SYSTEM_SCHEDULE_CLEANUP_ID = 1;
|
||||
const SYSTEM_EVENT_CLEANUP_ID = 2;
|
||||
const SYSTEM_SCANNER_CLEANUP_ID = 4;
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Toggle one of the three built-in system cleanup jobs (schedule/event/scanner cleanup) on or off
|
||||
* path: id:integer! System schedule id (1=schedule cleanup, 2=event cleanup, 4=scanner cleanup) (from GET /api/schedules)
|
||||
* resp-200: {success:boolean!, enabled:boolean!}
|
||||
* resp-400: Invalid or unknown system schedule id
|
||||
* resp-403: Permission denied (RBAC 'settings:edit' missing)
|
||||
* resp-500: Unexpected error while toggling the job
|
||||
*/
|
||||
export const POST: RequestHandler = async ({ params, cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
if (auth.authEnabled && !await auth.can('settings', 'edit')) {
|
||||
|
||||
Reference in new issue
Block a user