|
|
|
@@ -888,7 +888,10 @@ export function generateOpenApiSpec(): object {
|
|
|
|
|
registry.registerPath({ method: "post", path: "/api/v1/admin/invites", summary: "Create an invite", description: "Admin only.", security: adminSecurity, request: { body: { content: { "application/json": { schema: CreateInviteRef } }, required: true } }, responses: { 200: { description: "Created", content: { "application/json": { schema: z.object({ invite: InviteRef }) } } }, 400: { description: "Invalid role or tier", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
registry.registerPath({ method: "delete", path: "/api/v1/admin/invites/{id}", summary: "Revoke an invite", description: "Admin only.", security: adminSecurity, request: { params: idParam }, responses: { 200: { description: "Revoked", content: { "application/json": { schema: z.object({ ok: z.boolean() }) } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Invite not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
|
|
|
|
|
registry.registerPath({ method: "get", path: "/api/v1/admin/reports", summary: "List pending reports (up to 100, newest first)", description: "Admin only.", security: adminSecurity, responses: { 200: { description: "Reports", content: { "application/json": { schema: z.object({ reports: z.array(AdminReportRef) }) } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
registry.registerPath({ method: "get", path: "/api/v1/admin/reports", summary: "List pending reports (up to 100, newest first)", description: "Admin or moderator.", security: adminSecurity, responses: { 200: { description: "Reports", content: { "application/json": { schema: z.object({ reports: z.array(AdminReportRef) }) } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
|
|
|
|
|
const UnpublishRecipeRef = registry.register("UnpublishRecipe", z.object({ action: z.literal("unpublish") }));
|
|
|
|
|
registry.registerPath({ method: "patch", path: "/api/v1/admin/recipes/{id}", summary: "Unpublish a public recipe (moderation takedown)", description: "Admin or moderator. Flips visibility to private — the only transition this endpoint allows.", security: adminSecurity, request: { params: idParam, body: { content: { "application/json": { schema: UnpublishRecipeRef } }, required: true } }, responses: { 200: { description: "Unpublished", content: { "application/json": { schema: z.object({ ok: z.boolean() }) } } }, 400: { description: "Validation error", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
|
|
|
|
|
registry.registerPath({ method: "get", path: "/api/v1/admin/support", summary: "List all support tickets, newest first", description: "Admin only.", security: adminSecurity, responses: { 200: { description: "Tickets", content: { "application/json": { schema: z.array(AdminSupportTicketRef) } } }, 401: { description: "Unauthorized", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
registry.registerPath({ method: "patch", path: "/api/v1/admin/support/{id}", summary: "Update a support ticket's status, or retry opening its Gitea issue", description: "Admin only. A status change to/from \"closed\" also best-effort closes/reopens the linked Gitea issue.", security: adminSecurity, request: { params: idParam, body: { content: { "application/json": { schema: UpdateAdminSupportTicketRef } }, required: true } }, responses: { 200: { description: "Updated", content: { "application/json": { schema: z.object({ ok: z.boolean() }) } } }, 400: { description: "Validation error", content: { "application/json": { schema: ApiErrorRef } } }, 401: { description: "Unauthorized", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
@@ -901,7 +904,7 @@ export function generateOpenApiSpec(): object {
|
|
|
|
|
registry.registerPath({ method: "delete", path: "/api/v1/admin/webhooks/{id}", summary: "Delete a site-wide ops webhook", description: "Admin only.", security: adminSecurity, request: { params: idParam }, responses: { 204: { description: "Deleted" }, 401: { description: "Unauthorized", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
registry.registerPath({ method: "get", path: "/api/v1/admin/webhooks/{id}/deliveries", summary: "List recent delivery attempts for a site-wide ops webhook (most recent 20)", description: "Admin only.", security: adminSecurity, request: { params: idParam }, responses: { 200: { description: "Deliveries, newest first", content: { "application/json": { schema: z.array(AdminWebhookDeliveryRef) } } }, 401: { description: "Unauthorized", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
registry.registerPath({ method: "post", path: "/api/v1/admin/webhooks/{id}/redeliver", summary: "Re-send a past delivery's payload for a site-wide ops webhook", description: "Admin only.", security: adminSecurity, request: { params: idParam, body: { content: { "application/json": { schema: z.object({ deliveryId: z.string().uuid() }) } }, required: true } }, responses: { 200: { description: "Redelivery dispatched", content: { "application/json": { schema: z.object({ ok: z.boolean() }) } } }, 400: { description: "Validation error", content: { "application/json": { schema: ApiErrorRef } } }, 401: { description: "Unauthorized", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Webhook or delivery not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
registry.registerPath({ method: "patch", path: "/api/v1/admin/reports/{id}", summary: "Resolve a report (mark reviewed or dismissed)", description: "Admin only.", security: adminSecurity, request: { params: idParam, body: { content: { "application/json": { schema: ResolveReportBodyRef } }, required: true } }, responses: { 200: { description: "Updated", content: { "application/json": { schema: z.object({ report: ResolvedReportRef }) } } }, 400: { description: "Invalid status", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
registry.registerPath({ method: "patch", path: "/api/v1/admin/reports/{id}", summary: "Resolve a report (mark reviewed or dismissed)", description: "Admin or moderator.", security: adminSecurity, request: { params: idParam, body: { content: { "application/json": { schema: ResolveReportBodyRef } }, required: true } }, responses: { 200: { description: "Updated", content: { "application/json": { schema: z.object({ report: ResolvedReportRef }) } } }, 400: { description: "Invalid status", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } }, 404: { description: "Not found", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
|
|
|
|
|
registry.registerPath({ method: "put", path: "/api/v1/admin/settings", summary: "Update site settings (AI provider keys, VAPID keys, signups toggle)", description: "Admin only. Secret-flagged keys are encrypted at rest and never echoed back by any endpoint; this route only accepts new values, it does not return current ones.", security: adminSecurity, request: { body: { content: { "application/json": { schema: UpdateSiteSettingsRef } }, required: true } }, responses: { 200: { description: "Saved", content: { "application/json": { schema: z.object({ ok: z.boolean() }) } } }, 401: { description: "Unauthorized", content: { "application/json": { schema: ApiErrorRef } } }, 403: { description: "Forbidden", content: { "application/json": { schema: ApiErrorRef } } } } });
|
|
|
|
|
|
|
|
|
|