- Added PUT /api/admin/groups/:groupId/reorder endpoint - Implemented handleReorder in ModerationGroupImagesPage - Uses adminRequest API with proper error handling - Same mobile touch support as ManagementPortalPage
2916 lines
78 KiB
JSON
2916 lines
78 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: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"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |