Project-Image-Uploader/backend/docs/openapi.json

2823 lines
76 KiB
JSON

{
"openapi": "3.0.0",
"info": {
"title": "Project Image Uploader API",
"version": "1.0.0",
"description": "Auto-generated OpenAPI spec with correct mount prefixes"
},
"servers": [
{
"url": "http://localhost:5000",
"description": "Development server"
}
],
"tags": [
{
"name": "Admin Authentication"
},
{
"name": "Upload"
},
{
"name": "Download"
},
{
"name": "Public Groups"
},
{
"name": "Consent Management"
},
{
"name": "Management Portal"
},
{
"name": "Admin - Users"
},
{
"name": "Admin - Deletion Log"
},
{
"name": "Admin - Cleanup"
},
{
"name": "Admin - Monitoring"
},
{
"name": "Admin - Groups Moderation"
},
{
"name": "System Migration"
}
],
"paths": {
"/auth/setup/status": {
"get": {
"tags": [
"Admin Authentication"
],
"summary": "Check onboarding status",
"description": "Returns whether the initial admin setup is still pending and if a session already exists.",
"responses": {
"200": {
"description": "OK"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/auth/setup/initial-admin": {
"post": {
"tags": [
"Admin Authentication"
],
"summary": "Complete initial admin setup",
"description": "Creates the very first admin account and immediately starts a session.",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"username": {
"example": "any"
},
"password": {
"example": "any"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
},
"409": {
"description": "Conflict"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/auth/login": {
"post": {
"tags": [
"Admin Authentication"
],
"summary": "Admin login",
"description": "Starts a server-side admin session and returns a CSRF token.",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"username": {
"example": "any"
},
"password": {
"example": "any"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
},
"409": {
"description": "Conflict"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/auth/logout": {
"post": {
"tags": [
"Admin Authentication"
],
"summary": "Terminate admin session",
"description": "Destroys the current session and clears the sid cookie.",
"responses": {
"204": {
"description": "No Content"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/auth/csrf-token": {
"get": {
"tags": [
"Admin Authentication"
],
"summary": "Fetch CSRF token",
"description": "Returns a CSRF token for the active admin session (session required).",
"responses": {
"200": {
"description": "OK"
},
"403": {
"description": "Forbidden"
}
}
}
},
"/auth/change-password": {
"post": {
"tags": [
"Admin Authentication"
],
"summary": "Change admin password",
"description": "Allows a logged-in admin to rotate their password (CSRF protected).",
"parameters": [
{
"name": "x-csrf-token",
"in": "header",
"type": "string"
},
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"currentPassword": {
"example": "any"
},
"newPassword": {
"example": "any"
}
}
}
}
],
"responses": {
"0": {
"description": ""
},
"4": {
"description": ""
},
"5": {
"description": ""
},
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/upload": {
"post": {
"tags": [
"Upload"
],
"summary": "Upload a single image and create a new group",
"description": "Uploads an image file, generates a preview, and creates a new group in the database",
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"name": "file",
"in": "formData",
"type": "file",
"required": true,
"description": "Image file to upload"
},
{
"name": "groupName",
"in": "formData",
"type": "string",
"description": "Name for the new group",
"example": "Familie Mueller"
},
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"groupName": {
"example": "any"
}
}
}
}
],
"responses": {
"200": {
"description": "File uploaded successfully",
"schema": {
"type": "object",
"properties": {
"filePath": {
"type": "string",
"example": "/upload/abc123.jpg"
},
"fileName": {
"type": "string",
"example": "abc123.jpg"
},
"groupId": {
"type": "string",
"example": "cTV24Yn-a"
},
"groupName": {
"type": "string",
"example": "Familie Mueller"
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "No file uploaded",
"schema": {
"type": "object",
"properties": {
"msg": {
"type": "string",
"example": "No file uploaded"
}
},
"xml": {
"name": "main"
}
}
},
"500": {
"description": "Server error during upload"
}
}
}
},
"/api/download/{id}": {
"get": {
"tags": [
"Download"
],
"summary": "Download original image",
"description": "",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string",
"description": "Filename of the uploaded image"
}
],
"responses": {
"200": {
"description": "Binary image response"
},
"404": {
"description": "File not found"
}
}
}
},
"/api/upload/batch": {
"post": {
"tags": [
"Upload"
],
"summary": "Batch upload multiple images",
"description": "Accepts multiple images + metadata/consents and creates a managed group with management token.",
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"metadata": {
"example": "any"
},
"descriptions": {
"example": "any"
},
"consents": {
"example": "any"
},
"description": {
"example": "any"
}
}
}
}
],
"responses": {
"200": {
"description": "Batch upload successful (returns management token)"
},
"400": {
"description": "Missing files or workshop consent"
},
"500": {
"description": "Unexpected server error"
}
}
}
},
"/api/groups": {
"get": {
"tags": [
"Public Groups"
],
"summary": "Get approved groups with images",
"description": "Returns all approved groups (slideshow feed). Automatically triggers JSON→SQLite migration if required.",
"responses": {
"200": {
"description": "List of approved groups",
"schema": {
"type": "object",
"properties": {
"groups": {
"type": "array",
"items": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "cTV24Yn-a"
},
"title": {
"type": "string",
"example": "Familie Mueller"
}
}
}
},
"totalCount": {
"type": "number",
"example": 73
}
},
"xml": {
"name": "main"
}
}
},
"500": {
"description": "Server error"
}
}
}
},
"/api/groups/{groupId}": {
"get": {
"tags": [
"Public Groups"
],
"summary": "Get approved group by ID",
"description": "",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Public groupId (e.g. cTV24Yn-a)"
}
],
"responses": {
"200": {
"description": "Group payload (images + metadata)"
},
"404": {
"description": "Group not found or not approved"
},
"500": {
"description": "Server error"
}
}
}
},
"/api/social-media/platforms": {
"get": {
"tags": [
"Consent Management"
],
"summary": "List active social media platforms",
"description": "Public endpoint that exposes the available platforms for consent selection on the upload form.",
"responses": {
"200": {
"description": "OK"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/manage/{token}": {
"get": {
"tags": [
"Management Portal"
],
"summary": "Validate token and load group data",
"description": "Validates management token and returns complete group data with images and consents",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string",
"description": "Management token (UUID v4)",
"example": "550e8400-e29b-41d4-a716-446655440000"
}
],
"responses": {
"200": {
"description": "Group data loaded successfully",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"data": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"groupName": {
"type": "string",
"example": "Familie_Mueller"
},
"managementToken": {
"type": "string",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
"images": {
"type": "array",
"example": [],
"items": {}
},
"socialMediaConsents": {
"type": "array",
"example": [],
"items": {}
},
"display_in_workshop": {
"type": "boolean",
"example": true
}
}
}
},
"xml": {
"name": "main"
}
}
},
"404": {
"description": "Invalid token or group deleted"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
},
"delete": {
"tags": [
"Management Portal"
],
"summary": "Delete complete group",
"description": "Deletes entire group with all images, consents and metadata. Creates deletion_log entry. Removes all files (originals + previews).",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string",
"description": "Management token (UUID v4)",
"example": "550e8400-e29b-41d4-a716-446655440000"
}
],
"responses": {
"200": {
"description": "Group deleted",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Group and all associated data deleted successfully"
},
"data": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"imagesDeleted": {
"type": "number",
"example": 12
},
"deletionTimestamp": {
"type": "string",
"example": "2025-11-15T16:30:00Z"
}
}
}
},
"xml": {
"name": "main"
}
}
},
"404": {
"description": "Invalid token or group already deleted"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/manage/{token}/consents": {
"put": {
"tags": [
"Management Portal"
],
"summary": "Revoke or restore consents",
"description": "Updates workshop or social media consents for a group",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string",
"description": "Management token (UUID v4)",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"consentType": {
"type": "string",
"example": "workshop"
},
"action": {
"type": "string",
"example": "revoke"
},
"platformId": {
"type": "number",
"example": 1
}
}
}
}
],
"responses": {
"200": {
"description": "Consent updated successfully",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Workshop consent revoked successfully"
},
"data": {
"type": "object",
"properties": {
"consentType": {
"type": "string",
"example": "workshop"
},
"newValue": {
"type": "boolean",
"example": false
}
}
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Invalid request parameters"
},
"404": {
"description": "Invalid token"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/manage/{token}/images/descriptions": {
"put": {
"tags": [
"Management Portal"
],
"summary": "Batch update image descriptions",
"description": "Updates descriptions for multiple images in a group (max 200 chars each)",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string",
"description": "Management token (UUID v4)",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"descriptions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"imageId": {
"type": "number",
"example": 2
},
"description": {
"type": "string",
"example": "Gruppenfoto"
}
}
}
}
}
}
}
],
"responses": {
"200": {
"description": "Descriptions updated",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "2 image descriptions updated successfully"
},
"updatedCount": {
"type": "number",
"example": 2
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Invalid request or description too long"
},
"404": {
"description": "Invalid token"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/manage/{token}/metadata": {
"put": {
"tags": [
"Management Portal"
],
"summary": "Update group metadata",
"description": "Updates group title, description or name. Sets approved=0 (returns to moderation).",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string",
"description": "Management token (UUID v4)",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"title": {
"type": "string",
"example": "Sommercamp 2025"
},
"description": {
"type": "string",
"example": "Tolle Veranstaltung"
},
"name": {
"type": "string",
"example": "Familie_Mueller"
}
}
}
}
],
"responses": {
"200": {
"description": "Metadata updated",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Metadata updated successfully"
},
"data": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"updatedFields": {
"type": "array",
"example": [
"title",
"description"
],
"items": {
"type": "string"
}
},
"requiresModeration": {
"type": "boolean",
"example": true
}
}
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "No fields provided"
},
"404": {
"description": "Invalid token"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/manage/{token}/images": {
"post": {
"tags": [
"Management Portal"
],
"summary": "Add new images to group",
"description": "Uploads additional images to existing group. Sets approved=0 (requires re-moderation). Max 50 images per group.",
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string",
"description": "Management token (UUID v4)",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
{
"name": "images",
"in": "formData",
"type": "file",
"required": true,
"description": "Image files to upload (JPEG, PNG)"
}
],
"responses": {
"200": {
"description": "Images uploaded",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "3 images added successfully"
},
"data": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"newImagesCount": {
"type": "number",
"example": 3
},
"totalImagesCount": {
"type": "number",
"example": 15
}
}
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "No images or limit exceeded (max 50)"
},
"404": {
"description": "Invalid token"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/manage/{token}/images/{imageId}": {
"delete": {
"tags": [
"Management Portal"
],
"summary": "Delete single image",
"description": "Deletes a specific image from group (files + DB entry). Sets approved=0. Cannot delete last image.",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string",
"description": "Management token (UUID v4)",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
{
"name": "imageId",
"in": "path",
"required": true,
"type": "integer",
"description": "Image ID",
"example": 42
}
],
"responses": {
"200": {
"description": "Image deleted",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Image deleted successfully"
},
"data": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"imageId": {
"type": "number",
"example": 42
},
"remainingImages": {
"type": "number",
"example": 11
}
}
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Cannot delete last image"
},
"404": {
"description": "Invalid token or image not found"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/manage/{token}/reorder": {
"put": {
"description": "",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"imageIds": {
"example": "any"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"404": {
"description": "Not Found"
},
"429": {
"description": "Too Many Requests"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/social-media/platforms": {
"get": {
"tags": [
"Consent Management"
],
"summary": "Get active social media platforms",
"description": "Returns list of all active social media platforms available for consent",
"responses": {
"200": {
"description": "List of platforms",
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"platform_id": {
"type": "number",
"example": 1
},
"platform_name": {
"type": "string",
"example": "instagram"
},
"display_name": {
"type": "string",
"example": "Instagram"
},
"icon_name": {
"type": "string",
"example": "instagram"
},
"is_active": {
"type": "boolean",
"example": true
}
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/groups/{groupId}/consents": {
"post": {
"description": "",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"workshopConsent": {
"example": "any"
},
"socialMediaConsents": {
"example": "any"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error"
}
}
},
"get": {
"tags": [
"Consent Management"
],
"summary": "Get consents for a group",
"description": "Returns all consent data (workshop + social media) for a specific group",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
}
],
"responses": {
"200": {
"description": "Group consents",
"schema": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"workshopConsent": {
"type": "boolean",
"example": true
},
"consentTimestamp": {
"type": "string",
"example": "2025-11-01T10:00:00Z"
},
"socialMediaConsents": {
"type": "array",
"items": {
"type": "object",
"properties": {
"platformId": {
"type": "number",
"example": 1
},
"platformName": {
"type": "string",
"example": "instagram"
},
"displayName": {
"type": "string",
"example": "Instagram"
},
"consented": {
"type": "boolean",
"example": true
},
"revoked": {
"type": "boolean",
"example": false
}
}
}
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Group not found"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/groups/by-consent": {
"get": {
"tags": [
"Consent Management"
],
"summary": "Filter groups by consent status",
"description": "Returns groups filtered by workshop consent or social media platform consents",
"parameters": [
{
"name": "displayInWorkshop",
"in": "query",
"type": "boolean",
"description": "Filter by workshop consent",
"example": true
},
{
"name": "platformId",
"in": "query",
"type": "integer",
"description": "Filter by platform ID",
"example": 1
},
{
"name": "platformConsent",
"in": "query",
"type": "boolean",
"description": "Filter by platform consent status",
"example": true
}
],
"responses": {
"200": {
"description": "Filtered groups",
"schema": {
"type": "object",
"properties": {
"count": {
"type": "number",
"example": 5
},
"filters": {
"type": "object",
"properties": {
"displayInWorkshop": {
"type": "boolean",
"example": true
}
}
},
"groups": {
"type": "array",
"example": [],
"items": {}
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Invalid platformId"
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/consents/export": {
"get": {
"tags": [
"Consent Management"
],
"summary": "Export consent data",
"description": "Exports consent data for legal documentation in JSON or CSV format",
"produces": [
"text/csv"
],
"parameters": [
{
"name": "format",
"in": "query",
"type": "string",
"enum": [
"json",
"csv"
],
"description": "Export format",
"example": "json"
},
{
"name": "year",
"in": "query",
"type": "integer",
"description": "Filter by year",
"example": 2025
},
{
"name": "approved",
"in": "query",
"type": "boolean",
"description": "Filter by approval status",
"example": true
}
],
"responses": {
"200": {
"description": "Export data (CSV format)",
"schema": {
"type": "object",
"properties": {
"exportDate": {
"type": "string",
"example": "2025-11-15T16:30:00Z"
},
"filters": {
"type": "object",
"properties": {
"year": {
"type": "number",
"example": 2025
}
}
},
"count": {
"type": "number",
"example": 12
},
"data": {
"type": "array",
"example": [],
"items": {}
}
},
"xml": {
"name": "main"
}
},
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
"400": {
"description": "Invalid format"
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/users": {
"post": {
"tags": [
"Admin - Users"
],
"summary": "Create a new admin user",
"description": "Adds an additional admin (or auditor) via API",
"responses": {
"201": {
"description": "Admin user created",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "number",
"example": 5
},
"username": {
"type": "string",
"example": "admin2"
},
"role": {
"type": "string",
"example": "admin"
},
"requiresPasswordChange": {
"type": "boolean",
"example": false
}
}
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
},
"409": {
"description": "Conflict"
},
"500": {
"description": "Internal Server Error"
}
},
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"username",
"password"
],
"properties": {
"username": {
"type": "string",
"example": "admin2"
},
"password": {
"type": "string",
"example": "SehrSicher123!"
},
"role": {
"type": "string",
"example": "admin"
},
"requirePasswordChange": {
"type": "boolean",
"example": true
}
}
}
}
}
}
}
},
"/api/admin/deletion-log": {
"get": {
"tags": [
"Admin - Deletion Log"
],
"summary": "Get recent deletion log entries",
"description": "Returns recent deletion log entries with optional limit",
"parameters": [
{
"name": "limit",
"in": "query",
"type": "integer",
"description": "Number of entries to return (1-1000)",
"example": 10
}
],
"responses": {
"200": {
"description": "Deletion log entries",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"deletions": {
"type": "array",
"example": [],
"items": {}
},
"total": {
"type": "number",
"example": 2
},
"limit": {
"type": "number",
"example": 10
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Invalid limit parameter"
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/deletion-log/all": {
"get": {
"tags": [
"Admin - Deletion Log"
],
"summary": "Get all deletion log entries",
"description": "Returns complete deletion log without pagination",
"responses": {
"200": {
"description": "All deletion log entries",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"deletions": {
"type": "array",
"example": [],
"items": {}
},
"total": {
"type": "number",
"example": 50
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/deletion-log/stats": {
"get": {
"tags": [
"Admin - Deletion Log"
],
"summary": "Get deletion statistics",
"description": "Returns aggregated statistics about deleted images",
"responses": {
"200": {
"description": "Deletion statistics",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"totalDeleted": {
"type": "number",
"example": 12
},
"totalImages": {
"type": "number",
"example": 348
},
"totalSize": {
"type": "string",
"example": "19.38 MB"
},
"totalSizeBytes": {
"type": "number",
"example": 20324352
},
"lastCleanup": {
"type": "string",
"example": "2025-11-15T10:30:00Z"
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/cleanup/trigger": {
"post": {
"tags": [
"Admin - Cleanup"
],
"summary": "Manually trigger cleanup of unapproved groups",
"description": "Deletes groups that have not been approved within retention period",
"responses": {
"200": {
"description": "Cleanup completed",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"deletedGroups": {
"type": "number",
"example": 3
},
"message": {
"type": "string",
"example": "3 alte unbestätigte Gruppen gelöscht"
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/cleanup/preview": {
"get": {
"tags": [
"Admin - Cleanup"
],
"summary": "Preview groups that would be deleted",
"description": "Dry-run showing which unapproved groups are eligible for deletion",
"responses": {
"200": {
"description": "Preview of groups to delete",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"groupsToDelete": {
"type": "number",
"example": 2
},
"groups": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "abc123"
},
"groupName": {
"type": "string",
"example": "Familie_Mueller"
},
"uploadDate": {
"type": "string",
"example": "2025-10-01T12:00:00Z"
},
"daysUntilDeletion": {
"type": "number",
"example": -5
},
"imageCount": {
"type": "number",
"example": 8
}
}
}
},
"message": {
"type": "string",
"example": "2 groups would be deleted"
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/rate-limiter/stats": {
"get": {
"tags": [
"Admin - Monitoring"
],
"summary": "Get rate limiter statistics",
"description": "Returns statistics about rate limiting (blocked requests, active limits)",
"responses": {
"200": {
"description": "Rate limiter statistics",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"totalRequests": {
"type": "number",
"example": 1523
},
"blockedRequests": {
"type": "number",
"example": 12
},
"activeClients": {
"type": "number",
"example": 45
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/management-audit": {
"get": {
"tags": [
"Admin - Monitoring"
],
"summary": "Get management audit log entries",
"description": "Returns recent management portal activity logs",
"parameters": [
{
"name": "limit",
"in": "query",
"type": "integer",
"description": "Number of entries to return (1-1000)",
"example": 100
}
],
"responses": {
"200": {
"description": "Audit log entries",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"logs": {
"type": "array",
"example": [],
"items": {}
},
"total": {
"type": "number",
"example": 15
},
"limit": {
"type": "number",
"example": 100
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Invalid limit parameter"
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/management-audit/stats": {
"get": {
"tags": [
"Admin - Monitoring"
],
"summary": "Get management audit log statistics",
"description": "Returns aggregated statistics about management portal activity",
"responses": {
"200": {
"description": "Audit log statistics",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"totalActions": {
"type": "number",
"example": 523
},
"actionsByType": {
"type": "object",
"properties": {
"update": {
"type": "number",
"example": 312
},
"delete": {
"type": "number",
"example": 45
},
"approve": {
"type": "number",
"example": 166
}
}
},
"lastAction": {
"type": "string",
"example": "2025-11-15T14:30:00Z"
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/management-audit/group/{groupId}": {
"get": {
"tags": [
"Admin - Monitoring"
],
"summary": "Get audit log for specific group",
"description": "Returns all management actions performed on a specific group",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
}
],
"responses": {
"200": {
"description": "Audit log for group",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"groupId": {
"type": "string",
"example": "abc123def456"
},
"logs": {
"type": "array",
"example": [],
"items": {}
},
"total": {
"type": "number",
"example": 8
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/groups": {
"get": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Get all groups for moderation",
"description": "Returns all groups including unapproved ones with moderation info and consent data",
"parameters": [
{
"name": "consents",
"in": "query",
"type": "string"
},
{
"name": "workshopOnly",
"in": "query",
"type": "boolean",
"description": "Filter by workshop consent",
"example": false
},
{
"name": "platform",
"in": "query",
"type": "string",
"description": "Filter by social media platform",
"example": "instagram"
}
],
"responses": {
"200": {
"description": "All groups with moderation info",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"groups": {
"type": "array",
"items": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"groupName": {
"type": "string",
"example": "Familie_Mueller"
},
"isApproved": {
"type": "boolean",
"example": false
},
"uploadDate": {
"type": "string",
"example": "2025-11-01T10:00:00Z"
},
"imageCount": {
"type": "number",
"example": 12
},
"socialMediaConsents": {
"type": "array",
"example": [],
"items": {}
}
}
}
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/groups/{groupId}": {
"get": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Get single group for moderation",
"description": "Returns detailed info for a specific group including unapproved ones",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
}
],
"responses": {
"200": {
"description": "Group details with images",
"schema": {
"type": "object",
"properties": {
"groupId": {
"type": "string",
"example": "abc123"
},
"groupName": {
"type": "string",
"example": "Familie_Mueller"
},
"isApproved": {
"type": "boolean",
"example": true
},
"images": {
"type": "array",
"example": [],
"items": {}
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Group not found"
},
"500": {
"description": "Internal Server Error"
}
}
},
"patch": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Update group metadata",
"description": "Updates group metadata fields (year, title, description, name)",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"year": {
"type": "number",
"example": 2025
},
"title": {
"type": "string",
"example": "Sommercamp"
},
"description": {
"type": "string",
"example": "Tolle Veranstaltung"
},
"name": {
"type": "string",
"example": "Familie_Mueller"
}
}
}
}
],
"responses": {
"200": {
"description": "Group updated successfully",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Gruppe aktualisiert"
},
"updatedFields": {
"type": "array",
"example": [
"year",
"title"
],
"items": {
"type": "string"
}
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Group not found"
},
"500": {
"description": "Internal Server Error"
}
}
},
"delete": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Delete a group",
"description": "Deletes a complete group including all images and metadata",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
}
],
"responses": {
"200": {
"description": "Group deleted successfully",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Gruppe erfolgreich gelöscht"
},
"groupId": {
"type": "string",
"example": "abc123def456"
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Group not found"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/groups/{groupId}/approve": {
"patch": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Approve a group",
"description": "Marks a group as approved, making it publicly visible",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
},
{
"name": "body",
"in": "body",
"required": false,
"schema": {
"type": "object",
"properties": {
"approved": {
"type": "boolean",
"example": true
}
}
}
}
],
"responses": {
"200": {
"description": "Group approved successfully",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Gruppe erfolgreich freigegeben"
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Group not found"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/groups/{groupId}/images/{imageId}": {
"delete": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Delete a single image",
"description": "Deletes a specific image from a group",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
},
{
"name": "imageId",
"in": "path",
"required": true,
"type": "integer",
"description": "Image ID",
"example": 42
}
],
"responses": {
"200": {
"description": "Image deleted successfully",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Bild erfolgreich gelöscht"
},
"groupId": {
"type": "string",
"example": "abc123def456"
},
"imageId": {
"type": "number",
"example": 42
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Image not found"
},
"500": {
"description": "Internal Server Error"
}
}
},
"patch": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Update single image description",
"description": "Updates description for a specific image (max 200 characters)",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
},
{
"name": "imageId",
"in": "path",
"required": true,
"type": "integer",
"description": "Image ID",
"example": 42
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"image_description": {
"type": "string",
"example": "Sonnenuntergang am Strand"
}
}
}
}
],
"responses": {
"200": {
"description": "Description updated",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Bildbeschreibung erfolgreich aktualisiert"
},
"groupId": {
"type": "string",
"example": "abc123def456"
},
"imageId": {
"type": "number",
"example": 42
},
"imageDescription": {
"type": "string",
"example": "Sonnenuntergang am Strand"
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Description too long (max 200 chars)"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Image not found"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/groups/{groupId}/images/batch-description": {
"patch": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Batch update image descriptions",
"description": "Updates descriptions for multiple images in a group at once",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Group ID",
"example": "abc123def456"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"descriptions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"imageId": {
"type": "number",
"example": 2
},
"description": {
"type": "string",
"example": "Gruppenfoto beim Lagerfeuer"
}
}
}
}
}
}
}
],
"responses": {
"200": {
"description": "Descriptions updated",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"updatedCount": {
"type": "number",
"example": 2
},
"message": {
"type": "string",
"example": "2 Bildbeschreibungen aktualisiert"
}
},
"xml": {
"name": "main"
}
}
},
"400": {
"description": "Invalid request format"
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/admin/{groupId}/reorder": {
"put": {
"tags": [
"Admin - Groups Moderation"
],
"summary": "Reorder images within a group",
"description": "",
"parameters": [
{
"name": "groupId",
"in": "path",
"required": true,
"type": "string",
"description": "Admin groupId"
},
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"imageIds": {
"example": "any"
}
}
}
}
],
"responses": {
"200": {
"description": "Order updated successfully"
},
"400": {
"description": "Validation error"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Group not found"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/system/migration/status": {
"get": {
"tags": [
"System Migration"
],
"summary": "Get migration status",
"description": "Returns current database migration status and history",
"responses": {
"200": {
"description": "Migration status",
"schema": {
"type": "object",
"properties": {
"migrationComplete": {
"type": "boolean",
"example": true
},
"jsonBackupExists": {
"type": "boolean",
"example": true
},
"sqliteActive": {
"type": "boolean",
"example": true
},
"lastMigration": {
"type": "string",
"example": "2025-11-01T10:00:00Z"
}
},
"xml": {
"name": "main"
}
}
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/system/migration/migrate": {
"post": {
"tags": [
"System Migration"
],
"summary": "Manually trigger migration",
"description": "Triggers manual migration from JSON to SQLite database",
"parameters": [
{
"name": "x-csrf-token",
"in": "header",
"type": "string"
}
],
"responses": {
"200": {
"description": "Migration successful",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Migration completed successfully"
},
"groupsMigrated": {
"type": "number",
"example": 24
},
"imagesMigrated": {
"type": "number",
"example": 348
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Migration failed"
}
}
}
},
"/api/system/migration/rollback": {
"post": {
"tags": [
"System Migration"
],
"summary": "Rollback to JSON",
"description": "Emergency rollback from SQLite to JSON file storage",
"parameters": [
{
"name": "x-csrf-token",
"in": "header",
"type": "string"
}
],
"responses": {
"200": {
"description": "Rollback successful",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Rolled back to JSON successfully"
},
"groupsRestored": {
"type": "number",
"example": 24
}
},
"xml": {
"name": "main"
}
}
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Rollback failed"
}
}
}
},
"/api/system/migration/health": {
"get": {
"tags": [
"System Migration"
],
"summary": "Database health check",
"description": "Checks database connectivity and health status",
"responses": {
"200": {
"description": "Database healthy",
"schema": {
"type": "object",
"properties": {
"database": {
"type": "object",
"properties": {
"healthy": {
"type": "boolean",
"example": true
},
"status": {
"type": "string",
"example": "OK"
}
}
}
},
"xml": {
"name": "main"
}
}
},
"500": {
"description": "Database unhealthy",
"schema": {
"type": "object",
"properties": {
"database": {
"type": "object",
"properties": {
"healthy": {
"type": "boolean",
"example": false
},
"status": {
"type": "string",
"example": "ERROR"
},
"error": {
"type": "string",
"example": "Connection failed"
}
}
}
},
"xml": {
"name": "main"
}
}
}
}
}
}
}
}