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
@@ -10,6 +10,13 @@ import { authorize } from '$lib/server/authorize';
|
||||
import { auditNotification } from '$lib/server/audit';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: List all notification settings (SMTP and Apprise) with SMTP passwords masked
|
||||
* resp-200: array<{id:integer!, type:string!, name:string!, enabled:boolean!, config:{host:string, port:integer, from_email:string, to_emails:array<string>, urls:array<string>, password:string}, eventTypes:array<string>}>
|
||||
* resp-403: Permission denied (requires the notifications:view permission when auth is enabled)
|
||||
* resp-500: Failed to fetch notification settings
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
if (auth.authEnabled && !await auth.can('notifications', 'view')) {
|
||||
@@ -33,6 +40,16 @@ export const GET: RequestHandler = async ({ cookies }) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Create a notification setting (SMTP or Apprise); the response masks any SMTP password
|
||||
* body: {type:string!, name:string!, enabled:boolean, config:{host:string, port:integer, secure:boolean, username:string, password:string, from_email:string, from_name:string, to_emails:array<string>, urls:array<string>}, eventTypes:array<string>, event_types:array<string>}
|
||||
* body-example: {"type":"smtp","name":"Ops Alerts","enabled":true,"config":{"host":"smtp.example.com","port":587,"secure":false,"from_email":"dockhand@example.com","to_emails":["ops@example.com"],"password":"***"},"eventTypes":["container_unhealthy"]}
|
||||
* resp-200: {id:integer!, type:string!, name:string!, enabled:boolean!, config:{}, eventTypes:array<string>}
|
||||
* resp-400: Missing or invalid fields — type/name/config required, type must be smtp or apprise, SMTP needs host/port/from_email/to_emails, Apprise needs at least one URL
|
||||
* resp-403: Permission denied (requires the notifications:create permission)
|
||||
* resp-500: Failed to create notification setting
|
||||
*/
|
||||
export const POST: RequestHandler = async (event) => {
|
||||
const { request, cookies } = event;
|
||||
const auth = await authorize(cookies);
|
||||
|
||||
@@ -12,6 +12,16 @@ import { auditNotification } from '$lib/server/audit';
|
||||
import { computeAuditDiff } from '$lib/utils/diff';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Get a single notification setting by ID, with any SMTP password masked
|
||||
* path: id:integer! Notification setting ID (from GET /api/notifications)
|
||||
* resp-200: {id:integer!, type:string!, name:string!, enabled:boolean!, config:{host:string, port:integer, from_email:string, to_emails:array<string>, urls:array<string>, password:string}, eventTypes:array<string>}
|
||||
* resp-400: Invalid ID (not a number)
|
||||
* resp-403: Permission denied (requires the notifications:view permission)
|
||||
* resp-404: Notification setting not found
|
||||
* resp-500: Failed to fetch notification setting
|
||||
*/
|
||||
export const GET: RequestHandler = async ({ params, cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
if (auth.authEnabled && !await auth.can('notifications', 'view')) {
|
||||
@@ -45,6 +55,18 @@ export const GET: RequestHandler = async ({ params, cookies }) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Update a notification setting; a masked SMTP password ("********") keeps the stored value
|
||||
* path: id:integer! Notification setting ID (from GET /api/notifications)
|
||||
* body: {name:string, enabled:boolean, config:{host:string, port:integer, secure:boolean, username:string, password:string, from_email:string, from_name:string, to_emails:array<string>, urls:array<string>}, eventTypes:array<string>, event_types:array<string>}
|
||||
* body-example: {"name":"Ops Alerts","enabled":false,"config":{"host":"smtp.example.com","port":587,"from_email":"dockhand@example.com","to_emails":["ops@example.com"],"password":"********"},"eventTypes":["container_unhealthy","container_oom"]}
|
||||
* resp-200: {id:integer!, type:string!, name:string!, enabled:boolean!, config:{}, eventTypes:array<string>}
|
||||
* resp-400: Invalid ID, or config validation failed (SMTP needs host/port/from_email/to_emails, Apprise needs at least one URL)
|
||||
* resp-403: Permission denied (requires the notifications:edit permission)
|
||||
* resp-404: Notification setting not found
|
||||
* resp-500: Failed to update notification setting
|
||||
*/
|
||||
export const PUT: RequestHandler = async (event) => {
|
||||
const { params, request, cookies } = event;
|
||||
const auth = await authorize(cookies);
|
||||
@@ -122,6 +144,17 @@ export const PUT: RequestHandler = async (event) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Delete a notification setting by ID
|
||||
* path: id:integer! Notification setting ID (from GET /api/notifications)
|
||||
* resp-200: {success:boolean!}
|
||||
* resp-200-example: {"success":true}
|
||||
* resp-400: Invalid ID (not a number)
|
||||
* resp-403: Permission denied (requires the notifications:delete permission)
|
||||
* resp-404: Notification setting not found
|
||||
* resp-500: Failed to delete notification setting
|
||||
*/
|
||||
export const DELETE: RequestHandler = async (event) => {
|
||||
const { params, cookies } = event;
|
||||
const auth = await authorize(cookies);
|
||||
|
||||
@@ -3,6 +3,16 @@ import { getNotificationSetting } from '$lib/server/db';
|
||||
import { testNotification } from '$lib/server/notifications';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Send a test notification through an already-saved notification setting
|
||||
* path: id:integer! Notification setting ID (from GET /api/notifications)
|
||||
* resp-200: {success:boolean!, message:string, error:string}
|
||||
* resp-200-example: {"success":true,"message":"Test notification sent successfully"}
|
||||
* resp-400: Invalid ID (not a number)
|
||||
* resp-404: Notification setting not found
|
||||
* resp-500: Failed to test notification
|
||||
*/
|
||||
export const POST: RequestHandler = async ({ params }) => {
|
||||
try {
|
||||
const id = parseInt(params.id);
|
||||
|
||||
@@ -4,6 +4,17 @@ import { authorize } from '$lib/server/authorize';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
// Test notification with provided config (without saving)
|
||||
/**
|
||||
* @openapi
|
||||
* summary: Send a test notification using an ad-hoc config supplied in the body (nothing is saved)
|
||||
* body: {type:string!, name:string, config:{host:string, port:integer, secure:boolean, username:string, password:string, from_email:string, from_name:string, to_emails:array<string>, urls:array<string>}}
|
||||
* body-example: {"type":"smtp","name":"Test","config":{"host":"smtp.example.com","port":587,"from_email":"dockhand@example.com","to_emails":["ops@example.com"],"password":"***"}}
|
||||
* resp-200: {success:boolean!, message:string, error:string}
|
||||
* resp-200-example: {"success":true,"message":"Test notification sent successfully"}
|
||||
* resp-400: Missing/invalid fields — type and config required; SMTP needs host/from_email/to_emails; Apprise needs at least one URL
|
||||
* resp-403: Permission denied (requires the settings:edit permission)
|
||||
* resp-500: Failed to test notification
|
||||
*/
|
||||
export const POST: RequestHandler = async ({ request, cookies }) => {
|
||||
const auth = await authorize(cookies);
|
||||
if (auth.authEnabled && !await auth.can('settings', 'edit')) {
|
||||
|
||||
@@ -6,12 +6,15 @@ import { NOTIFICATION_EVENT_TYPES, type NotificationEventType } from '$lib/serve
|
||||
* Test endpoint to trigger notifications for any event type.
|
||||
* This is intended for development/testing purposes only.
|
||||
*
|
||||
* POST /api/notifications/trigger-test
|
||||
* Body: {
|
||||
* eventType: string,
|
||||
* environmentId?: number,
|
||||
* payload: { title: string, message: string, type?: string }
|
||||
* }
|
||||
* @openapi
|
||||
* summary: Trigger a real notification for a given event type (development/testing helper)
|
||||
* description: environmentId from GET /api/environments.
|
||||
* body: {eventType:string!, environmentId:integer, payload:{title:string!, message:string!, type:string}}
|
||||
* body-example: {"eventType":"container_unhealthy","environmentId":1,"payload":{"title":"Container unhealthy","message":"web-1 is unhealthy","type":"warning"}}
|
||||
* resp-200: {success:boolean!, sent:integer, eventType:string!, environmentId:integer}
|
||||
* resp-200-example: {"success":true,"sent":1,"eventType":"container_unhealthy","environmentId":1}
|
||||
* resp-400: eventType required, payload with title and message required, unknown event type, or environmentId missing for a non-system event
|
||||
* resp-500: Unknown error while sending the notification
|
||||
*/
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
try {
|
||||
@@ -83,6 +86,10 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
|
||||
/**
|
||||
* GET endpoint to list all available event types
|
||||
*
|
||||
* @openapi
|
||||
* summary: List all available notification event types, grouped into categories
|
||||
* resp-200: {eventTypes:array<{id:string!, label:string}>, categories:{container:array<string>, autoUpdate:array<string>, gitStack:array<string>, stack:array<string>, security:array<string>, system:array<string>}}
|
||||
*/
|
||||
export const GET: RequestHandler = async () => {
|
||||
return json({
|
||||
|
||||
Reference in new issue
Block a user