{ "openapi": "3.0.0", "info": { "title": "Project Image Uploader API", "version": "1.10.2", "description": "Auto-generated OpenAPI spec with correct mount prefixes" }, "servers": [ { "url": "http://localhost:5001", "description": "Development server (dev compose backend)" } ], "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" } } }, "429": { "description": "Too Many Requests" }, "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/groups/{groupId}/reorder": { "put": { "tags": [ "Admin - Groups Moderation" ], "summary": "Reorder images in a group", "description": "Updates the display order of images within a group", "parameters": [ { "name": "groupId", "in": "path", "required": true, "type": "string", "description": "Group ID", "example": "abc123def456" } ], "responses": { "200": { "description": "Images reordered successfully", "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Image order updated successfully" }, "data": { "type": "object", "properties": { "updatedImages": { "type": "number", "example": 5 } } } }, "xml": { "name": "main" } } }, "400": { "description": "Invalid imageIds parameter" }, "403": { "description": "Forbidden" }, "404": { "description": "Group not found" }, "500": { "description": "Internal Server Error" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "imageIds" ], "properties": { "imageIds": { "type": "array", "items": { "type": "integer" }, "example": [ 5, 3, 1, 2, 4 ], "description": "Array of image IDs in new order" } } } } } } } }, "/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" } } } } } } } }