{
  "openapi": "3.0.0",
  "paths": {
    "/health": {
      "get": {
        "operationId": "HealthController_check",
        "parameters": [],
        "responses": {
          "200": {
            "description": "The Health Check is successful\n\nService healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "info": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": ["status"],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "error": {
                      "type": "object",
                      "example": {},
                      "additionalProperties": {
                        "type": "object",
                        "required": ["status"],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "details": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": ["status"],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The Health Check is not successful\n\nService degraded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "error"
                    },
                    "info": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": ["status"],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "error": {
                      "type": "object",
                      "example": {
                        "redis": {
                          "status": "down",
                          "message": "Could not connect"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": ["status"],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      },
                      "nullable": true
                    },
                    "details": {
                      "type": "object",
                      "example": {
                        "database": {
                          "status": "up"
                        },
                        "redis": {
                          "status": "down",
                          "message": "Could not connect"
                        }
                      },
                      "additionalProperties": {
                        "type": "object",
                        "required": ["status"],
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Health check (database connectivity)",
        "tags": ["Health"]
      }
    },
    "/auth/me": {
      "get": {
        "operationId": "AuthController_getMe",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Current user profile"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get current authenticated user profile",
        "tags": ["Auth"]
      },
      "patch": {
        "operationId": "AuthController_updateMe",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated user profile"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update current user profile",
        "tags": ["Auth"]
      }
    },
    "/auth/me/onboarding-reset": {
      "post": {
        "operationId": "AuthController_resetOnboarding",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Onboarding reset"
          },
          "403": {
            "description": "Not an admin"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Reset onboarding (admin only, for testing)",
        "tags": ["Auth"]
      }
    },
    "/auth/me/email": {
      "post": {
        "operationId": "AuthController_requestEmailChange",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestEmailChangeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verification email sent"
          },
          "409": {
            "description": "Email already in use"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Request email change — sends verification email",
        "tags": ["Auth"]
      }
    },
    "/auth/me/email/verify": {
      "post": {
        "operationId": "AuthController_verifyEmail",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyEmailDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email verified and updated"
          },
          "400": {
            "description": "Invalid or expired token"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Verify email with token from verification link",
        "tags": ["Auth"]
      }
    },
    "/auth/me/onboarding-complete": {
      "post": {
        "operationId": "AuthController_completeOnboarding",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Onboarding marked complete"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Mark onboarding as complete for current user",
        "tags": ["Auth"]
      }
    },
    "/auth/me/battlenet/status": {
      "get": {
        "operationId": "AuthController_getBattleNetStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Token status"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Check if Battle.net token is expired for current user",
        "tags": ["Auth"]
      }
    },
    "/auth/me/avatar": {
      "post": {
        "operationId": "AuthController_uploadAvatar",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated user profile with new avatar URL\n\nBattle.net account disconnected"
          },
          "400": {
            "description": "Invalid file or moderation failed"
          },
          "401": {
            "description": "Not authenticated\n\nNot authenticated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Disconnect Battle.net account for current user",
        "tags": ["Auth"]
      }
    },
    "/auth/me/battlenet/disconnect": {
      "post": {
        "operationId": "AuthController_disconnectBattleNet",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Battle.net account disconnected"
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Disconnect Battle.net account for current user",
        "tags": ["Auth"]
      }
    },
    "/auth/{path}": {
      "get": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_get",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      },
      "post": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_post",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      },
      "put": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_put",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      },
      "delete": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_delete",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      },
      "patch": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_patch",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      },
      "options": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_options",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      },
      "head": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_head",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      },
      "search": {
        "description": "Handles OAuth flows, magic links, session management. Powered by Better Auth.",
        "operationId": "AuthController_handleAuth_search",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Auth response varies by route"
          }
        },
        "summary": "Better Auth OAuth/session handler (all auth routes)",
        "tags": ["Auth"]
      }
    },
    "/organizations": {
      "get": {
        "operationId": "OrganizationController_getAll",
        "parameters": [
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by organization type",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeArchived",
            "required": false,
            "in": "query",
            "description": "Include archived organizations",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of organizations"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all organizations",
        "tags": ["Organizations"]
      },
      "post": {
        "operationId": "OrganizationController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrganizationDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Organization created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a new organization",
        "tags": ["Organizations"]
      }
    },
    "/organizations/templates": {
      "get": {
        "operationId": "OrganizationController_getTemplates",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Available organization templates"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List guild creation templates",
        "tags": ["Organizations"]
      }
    },
    "/organizations/mine": {
      "get": {
        "operationId": "OrganizationController_getMine",
        "parameters": [],
        "responses": {
          "200": {
            "description": "List of guilds with id, name, alias, and current logo URL"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Organizations the current user is an active member of (summary only)",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/discord/in-server": {
      "get": {
        "operationId": "OrganizationController_getDiscordInServerStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Discord server membership for linked account",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inDiscordServer": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not a guild member or Discord not linked"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Whether the linked Discord user is already in the guild Discord server",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/discord/server-invite": {
      "get": {
        "operationId": "OrganizationController_getDiscordServerInviteUrl",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invite URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inviteUrl": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No invite channel configured"
          },
          "403": {
            "description": "Not a member or Discord not linked"
          },
          "409": {
            "description": "Already a member of the Discord server"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get Discord server invite URL (guild members with linked Discord only)",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}": {
      "get": {
        "operationId": "OrganizationController_getOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Organization detail"
          },
          "404": {
            "description": "Organization not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get organization by ID or alias",
        "tags": ["Organizations"]
      },
      "patch": {
        "operationId": "OrganizationController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOrganizationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Organization updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update organization",
        "tags": ["Organizations"]
      },
      "delete": {
        "operationId": "OrganizationController_archive",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Organization archived"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Archive organization (soft delete)",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/settings": {
      "patch": {
        "operationId": "OrganizationController_updateSettings",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Settings updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Merge-update organization settings",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/text-content": {
      "get": {
        "operationId": "OrganizationController_getTextContent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Text content by type"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get organization text content (MOTD, rules, loot rules, etc.)",
        "tags": ["Organizations"]
      },
      "patch": {
        "operationId": "OrganizationController_updateTextContent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Updated text content"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update organization text content (partial)",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/roster": {
      "get": {
        "operationId": "OrganizationController_getRoster",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeLeft",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["rank", "name", "lastLogin"],
              "type": "string"
            }
          },
          {
            "name": "sortOrder",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["asc", "desc"],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated roster members"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get guild roster (WoW guilds only)",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/composition": {
      "get": {
        "operationId": "OrganizationController_getComposition",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "activeSince",
            "required": false,
            "in": "query",
            "description": "Only include members active within this many days (e.g. 30, 90)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Aggregated class, role, and armor type distributions"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get guild composition stats",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/roster/sync/active": {
      "get": {
        "operationId": "OrganizationController_getActiveRosterSync",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Most recent sync session or null"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get most recent roster sync session status",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/roster/sync": {
      "post": {
        "operationId": "OrganizationController_syncRoster",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sync started, returns session ID"
          },
          "400": {
            "description": "Battle.net account not linked or not a guild"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger roster sync from Battle.net",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/sync": {
      "post": {
        "operationId": "OrganizationController_syncGuild",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncGuildDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sync results per requested type"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger one or more guild syncs (roster, crest, etc.)",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/ranks": {
      "get": {
        "operationId": "OrganizationController_getRanks",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Guild ranks"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get guild ranks from Battle.net",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/logo": {
      "get": {
        "operationId": "OrganizationController_getLogo",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Logo URLs and current selection"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get guild logo information",
        "tags": ["Organizations"]
      },
      "post": {
        "operationId": "OrganizationController_uploadLogo",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Logo uploaded, returns URL"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Upload custom guild logo",
        "tags": ["Organizations"]
      },
      "delete": {
        "operationId": "OrganizationController_deleteLogo",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Logo deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete custom guild logo",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/logo/toggle": {
      "patch": {
        "operationId": "OrganizationController_toggleLogo",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Logo preference updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Toggle between custom and synced guild logo",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/attendance-stats": {
      "get": {
        "operationId": "OrganizationController_getAttendanceStatistics",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "required": false,
            "in": "query",
            "description": "ISO date to filter from",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "eventType",
            "required": false,
            "in": "query",
            "description": "Filter by event type (raid, dungeon, etc.)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Attendance stats per member"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get per-member attendance statistics (officers only)",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/attendance-trends": {
      "get": {
        "operationId": "OrganizationController_getAttendanceTrends_endpoint",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "required": false,
            "in": "query",
            "description": "ISO date to filter from (default: 90 days ago)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "eventType",
            "required": false,
            "in": "query",
            "description": "Filter by event type (raid, dungeon, etc.)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "required": false,
            "in": "query",
            "description": "Time bucket: week or month (default: week)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Attendance trend data bucketed by time period"
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "bearer": []
          }
        ],
        "summary": "Get attendance trends over time",
        "tags": ["Organizations"]
      }
    },
    "/organizations/{id}/crafters": {
      "get": {
        "operationId": "OrganizationController_getCrafters",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Recipe or item name to search for",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "professionId",
            "required": false,
            "in": "query",
            "description": "Filter by Blizzard profession ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of guild crafters with matching recipes"
          }
        },
        "security": [
          {
            "session": []
          },
          {
            "bearer": []
          }
        ],
        "summary": "Search guild crafters by recipe name or profession",
        "tags": ["Organizations"]
      }
    },
    "/jobs/sync-rosters": {
      "post": {
        "operationId": "JobsController_triggerRosterSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync initiated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Manually trigger roster sync for all guilds (admin only)",
        "tags": ["Jobs"]
      }
    },
    "/jobs/seed-holidays": {
      "post": {
        "operationId": "JobsController_seedHolidays",
        "parameters": [
          {
            "name": "year",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Holidays seeded"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Seed WoW holiday events for a year (admin only)",
        "tags": ["Jobs"]
      }
    },
    "/characters/search": {
      "get": {
        "operationId": "CharacterController_searchCharacter",
        "parameters": [
          {
            "name": "name",
            "required": true,
            "in": "query",
            "description": "Character name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "realm",
            "required": true,
            "in": "query",
            "description": "Realm slug (e.g. stormrage, area-52)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character preview data"
          },
          "404": {
            "description": "Character not found on Battle.net"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Preview a character by name and realm (no DB write)",
        "tags": ["Characters"]
      }
    },
    "/characters/import": {
      "post": {
        "operationId": "CharacterController_importCharacter",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Character created"
          },
          "404": {
            "description": "Character not found on Battle.net"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Import a character from Battle.net into the database",
        "tags": ["Characters"]
      }
    },
    "/characters": {
      "get": {
        "operationId": "CharacterController_findAll",
        "parameters": [
          {
            "name": "includeInactive",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "guildId",
            "required": false,
            "in": "query",
            "description": "Filter to characters in this guild",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character list"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List current user characters",
        "tags": ["Characters"]
      },
      "post": {
        "operationId": "CharacterController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateManualCharacterDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Character created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a manual character",
        "tags": ["Characters"]
      }
    },
    "/characters/templates": {
      "get": {
        "operationId": "CharacterController_getTemplates",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Character templates"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character creation templates",
        "tags": ["Characters"]
      }
    },
    "/characters/battlenet-preview": {
      "get": {
        "operationId": "CharacterController_previewBattleNetCharacters",
        "parameters": [
          {
            "name": "gameVersion",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Battle.net character list"
          },
          "409": {
            "description": "Battle.net token expired or missing"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Preview characters from Battle.net account, enriched with local DB data",
        "tags": ["Characters"]
      }
    },
    "/characters/sync/active": {
      "get": {
        "operationId": "CharacterController_getActiveSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or null"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active Battle.net sync session for current user",
        "tags": ["Characters"]
      }
    },
    "/characters/sync/{sessionId}/complete": {
      "patch": {
        "operationId": "CharacterController_completeStuckSync",
        "parameters": [
          {
            "name": "sessionId",
            "required": true,
            "in": "path",
            "description": "Sync session UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session marked complete"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Manually complete a stuck sync session (admin/dev)",
        "tags": ["Characters"]
      }
    },
    "/characters/sync/{sessionId}": {
      "get": {
        "operationId": "CharacterController_getSyncStatus",
        "parameters": [
          {
            "name": "sessionId",
            "required": true,
            "in": "path",
            "description": "Sync session UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sync session status"
          },
          "404": {
            "description": "Session not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character sync session status",
        "tags": ["Characters"]
      }
    },
    "/characters/sync": {
      "post": {
        "operationId": "CharacterController_syncFromBattleNet",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync started, returns sessionId"
          },
          "409": {
            "description": "Sync already in progress"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger character sync from Battle.net",
        "tags": ["Characters"]
      }
    },
    "/characters/reputations": {
      "get": {
        "operationId": "CharacterController_getReputationComparison",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "description": "Blizzard locale for expansion/faction names (default: en_US)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expansionId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reputation comparison matrix grouped by expansion"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Compare reputations across all of the current user's characters",
        "tags": ["Characters"]
      }
    },
    "/characters/reputations/search-factions": {
      "get": {
        "operationId": "CharacterController_searchFactions",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "description": "Search query (fuzzy match via pg_trgm)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "description": "Blizzard locale (default: en_US)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching factions with expansion info"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Fuzzy-search reputation factions by name",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}": {
      "get": {
        "operationId": "CharacterController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character detail"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character by ID",
        "tags": ["Characters"]
      },
      "delete": {
        "operationId": "CharacterController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Permanently delete a character",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/render": {
      "get": {
        "operationId": "CharacterController_getCharacterRender",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Render URL"
          },
          "404": {
            "description": "No avatar available to derive render from"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get or generate cached character render image URL",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/encounters": {
      "get": {
        "operationId": "CharacterController_getEncounterProgression",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Encounter progression grouped by expansion"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character encounter progression",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/active-build": {
      "get": {
        "operationId": "CharacterController_getActiveBuild",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Active build info"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get resolved active spec and hero talents from specializations data",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/statistics": {
      "get": {
        "operationId": "CharacterController_getStatistics",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character statistics"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character combat statistics",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/specializations": {
      "get": {
        "operationId": "CharacterController_getSpecializations",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character specializations"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character specializations and talent loadouts",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/reputations": {
      "get": {
        "operationId": "CharacterController_getReputations",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "standing",
            "required": false,
            "in": "query",
            "description": "Filter by standing (e.g. EXALTED)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "description": "Blizzard locale for expansion names (default: en_US)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character reputations grouped by expansion"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character faction reputations grouped by expansion",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/professions": {
      "get": {
        "operationId": "CharacterController_getProfessions",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character professions"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character professions and skill tiers",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/recipes": {
      "get": {
        "operationId": "CharacterController_getRecipes",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character known recipes grouped by profession"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character known profession recipes",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/pvp": {
      "get": {
        "operationId": "CharacterController_getPvpSummary",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character PvP summary"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character PvP summary",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/achievements": {
      "get": {
        "operationId": "CharacterController_getAchievements",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character achievements"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get character achievements summary",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/data-patch": {
      "get": {
        "operationId": "CharacterController_getDataPatch",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Patch version"
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get the GDL patch version for this character's enriched data",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/simc-profile": {
      "get": {
        "operationId": "CharacterController_getSimcProfile",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "talentLoadoutCode",
            "required": false,
            "in": "query",
            "description": "Override talent loadout code (base64 talent string)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "SimC profile text"
          },
          "404": {
            "description": "Character not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Generate SimC profile text for a character",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/enrich": {
      "post": {
        "operationId": "CharacterController_enrichCharacter",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Enrichment job queued"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Enrich a single character from Battle.net (queues job)",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/archive": {
      "patch": {
        "operationId": "CharacterController_archive",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character archived"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Archive a character (soft delete)",
        "tags": ["Characters"]
      }
    },
    "/characters/{id}/restore": {
      "patch": {
        "operationId": "CharacterController_restore",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character restored"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Restore an archived character",
        "tags": ["Characters"]
      }
    },
    "/game-data/expansions": {
      "get": {
        "operationId": "GameDataController_getExpansions",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Expansion list"
          }
        },
        "summary": "List WoW expansions",
        "tags": ["Game Data"]
      }
    },
    "/game-data/instances": {
      "get": {
        "operationId": "GameDataController_getInstances",
        "parameters": [
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["raid", "dungeon"],
              "type": "string"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Instance list"
          }
        },
        "summary": "List WoW instances (raids and dungeons)",
        "tags": ["Game Data"]
      }
    },
    "/game-data/encounters": {
      "get": {
        "operationId": "GameDataController_getEncounters",
        "parameters": [
          {
            "name": "journalInstanceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Encounter list"
          }
        },
        "summary": "List encounters (bosses) for an instance",
        "tags": ["Game Data"]
      }
    },
    "/game-data/encounters/{encounterId}": {
      "get": {
        "operationId": "GameDataController_getEncounterDetail",
        "parameters": [
          {
            "name": "encounterId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Encounter detail"
          }
        },
        "summary": "Get a single encounter by ID",
        "tags": ["Game Data"]
      }
    },
    "/game-data/encounters/{encounterId}/loot": {
      "get": {
        "operationId": "GameDataController_getEncounterLoot",
        "parameters": [
          {
            "name": "encounterId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Encounter loot"
          }
        },
        "summary": "Get loot table for an encounter",
        "tags": ["Game Data"]
      }
    },
    "/game-data/items": {
      "get": {
        "operationId": "GameDataController_getItemDisplayInfo",
        "parameters": [
          {
            "name": "ids",
            "required": true,
            "in": "query",
            "description": "Comma-separated item IDs",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Item display info"
          }
        },
        "summary": "Get display info for items by IDs",
        "tags": ["Game Data"]
      }
    },
    "/game-data/raid-instances": {
      "get": {
        "deprecated": true,
        "operationId": "GameDataController_getRaidInstances",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Raid instances"
          }
        },
        "summary": "List raid instances (deprecated, use /instances?category=raid)",
        "tags": ["Game Data"]
      }
    },
    "/game-data/class-icons": {
      "get": {
        "operationId": "GameDataController_getClassIcons",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Class icon list"
          }
        },
        "summary": "List cached class icons",
        "tags": ["Game Data"]
      }
    },
    "/game-data/spec-icons": {
      "get": {
        "operationId": "GameDataController_getSpecIcons",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Spec icon list"
          }
        },
        "summary": "List cached spec icons",
        "tags": ["Game Data"]
      }
    },
    "/game-data/sync-icons": {
      "post": {
        "operationId": "GameDataController_syncIcons",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sync result"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Sync class/spec icons from Blizzard via GDL (admin only)",
        "tags": ["Game Data"]
      }
    },
    "/game-data/housing/decor": {
      "get": {
        "operationId": "GameDataController_getHousingDecor",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dyeable",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "craftable",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "collected",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["true", "false"],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated decor items"
          }
        },
        "summary": "Paginated housing decor catalog",
        "tags": ["Game Data"]
      }
    },
    "/game-data/housing/decor/{id}": {
      "get": {
        "operationId": "GameDataController_getHousingDecorById",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Decor item"
          },
          "404": {
            "description": "Not found"
          }
        },
        "summary": "Get a single housing decor item",
        "tags": ["Game Data"]
      }
    },
    "/game-data/housing/decor/{id}/crafters": {
      "get": {
        "operationId": "GameDataController_getHousingDecorCrafters",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of platform crafters who can make this decor item"
          }
        },
        "summary": "Get crafters for a housing decor item",
        "tags": ["Game Data"]
      }
    },
    "/game-data/housing/rooms": {
      "get": {
        "operationId": "GameDataController_getHousingRooms",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Room list"
          }
        },
        "summary": "List all housing rooms",
        "tags": ["Game Data"]
      }
    },
    "/game-data/housing/fixtures": {
      "get": {
        "operationId": "GameDataController_getHousingFixtures",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Fixture list"
          }
        },
        "summary": "List all housing fixtures with hooks",
        "tags": ["Game Data"]
      }
    },
    "/game-data/talent-trees/{specId}": {
      "get": {
        "operationId": "GameDataController_getTalentTree",
        "parameters": [
          {
            "name": "specId",
            "required": true,
            "in": "path",
            "description": "Blizzard spec ID",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Talent tree structure"
          },
          "404": {
            "description": "Not found"
          }
        },
        "summary": "Get talent tree structure for a specialization",
        "tags": ["Game Data"]
      }
    },
    "/game-data/talent-trees": {
      "get": {
        "operationId": "GameDataController_listTalentTrees",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Available spec IDs and names"
          }
        },
        "summary": "List all available talent tree specs",
        "tags": ["Game Data"]
      }
    },
    "/game-data/decode-talent-loadout": {
      "post": {
        "operationId": "GameDataController_decodeTalentLoadout",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Decoded talent selections"
          },
          "400": {
            "description": "Invalid or undecodable loadout"
          }
        },
        "summary": "Decode a Blizzard talent loadout code into selected talents",
        "tags": ["Game Data"]
      }
    },
    "/game-data/professions": {
      "get": {
        "operationId": "GameDataController_getProfessions",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profession list"
          }
        },
        "summary": "List all WoW professions",
        "tags": ["Game Data"]
      }
    },
    "/game-data/profession-recipes": {
      "get": {
        "operationId": "GameDataController_getProfessionRecipes",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "professionId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "itemClassId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "itemSubclassId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "tierIds",
            "required": false,
            "in": "query",
            "description": "Comma-separated tier IDs for expansion filtering",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "categoryName",
            "required": false,
            "in": "query",
            "description": "Recipe category_name filter (for categories without item class data)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated recipe catalog"
          }
        },
        "summary": "Paginated profession recipe catalog",
        "tags": ["Game Data"]
      }
    },
    "/game-data/profession-recipes/{id}": {
      "get": {
        "operationId": "GameDataController_getRecipeDetail",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recipe detail with reagents"
          },
          "404": {
            "description": "Recipe not found"
          }
        },
        "summary": "Get recipe detail with reagents",
        "tags": ["Game Data"]
      }
    },
    "/game-data/crafting-expansions": {
      "get": {
        "operationId": "GameDataController_getCraftingExpansions",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Expansion list with tier groups"
          }
        },
        "summary": "List crafting expansions with tier IDs",
        "tags": ["Game Data"]
      }
    },
    "/game-data/craftable-item-categories": {
      "get": {
        "operationId": "GameDataController_getCraftableItemCategories",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tierIds",
            "required": false,
            "in": "query",
            "description": "Comma-separated tier IDs to scope by expansion",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Item class/subclass tree for craftable recipes"
          }
        },
        "summary": "Item category tree for craftable items",
        "tags": ["Game Data"]
      }
    },
    "/game-data/current-patch": {
      "get": {
        "operationId": "GameDataController_getCurrentPatch",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Current patch info"
          }
        },
        "summary": "Get the current game patch",
        "tags": ["Game Data"]
      }
    },
    "/game-data/patches": {
      "get": {
        "operationId": "GameDataController_listPatches",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Patch history"
          }
        },
        "summary": "List all registered game patches",
        "tags": ["Game Data"]
      }
    },
    "/game-data/patches/{version}/hotfixes": {
      "get": {
        "operationId": "GameDataController_getPatchHotfixes",
        "parameters": [
          {
            "name": "version",
            "required": true,
            "in": "path",
            "description": "Game patch version string",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Hotfix entries for this patch"
          }
        },
        "summary": "Get hotfix notes assigned to a patch version",
        "tags": ["Game Data"]
      }
    },
    "/game-data/hotfixes": {
      "get": {
        "operationId": "GameDataController_getRecentHotfixes",
        "parameters": [
          {
            "name": "since",
            "required": true,
            "in": "query",
            "description": "ISO date string",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recent hotfix entries"
          }
        },
        "summary": "Get recent hotfix notes since a date",
        "tags": ["Game Data"]
      }
    },
    "/organizations/{guildId}/memberships": {
      "get": {
        "operationId": "MembershipController_findByGuild",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "sortBy",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["rank", "name", "lastSeen", "lastLogin", "status"],
              "type": "string"
            }
          },
          {
            "name": "sortOrder",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["asc", "desc"],
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Filter by character name or class (case-insensitive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "minLevel",
            "required": false,
            "in": "query",
            "description": "Minimum character level",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated guild roster"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List memberships in a guild (roster)",
        "tags": ["Memberships"]
      },
      "post": {
        "operationId": "MembershipController_create",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMembershipDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Membership created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a guild membership (officers only)",
        "tags": ["Memberships"]
      }
    },
    "/organizations/{guildId}/memberships/{id}": {
      "get": {
        "operationId": "MembershipController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Membership detail"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get membership by ID",
        "tags": ["Memberships"]
      },
      "patch": {
        "operationId": "MembershipController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMembershipDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Membership updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update membership role (officers only)",
        "tags": ["Memberships"]
      },
      "delete": {
        "operationId": "MembershipController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Membership removed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove a membership (kick from guild)",
        "tags": ["Memberships"]
      }
    },
    "/organizations/{guildId}/memberships/{id}/role-history": {
      "get": {
        "operationId": "MembershipController_getRoleHistory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Role history"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get role change history for a membership",
        "tags": ["Memberships"]
      }
    },
    "/organizations/{guildId}/memberships/{id}/notes": {
      "get": {
        "operationId": "MembershipController_getNotes",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Membership notes"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List notes for a membership",
        "tags": ["Memberships"]
      },
      "post": {
        "operationId": "MembershipController_createNote",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMembershipNoteDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Note created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Add a note to a membership",
        "tags": ["Memberships"]
      }
    },
    "/organizations/{guildId}/memberships/{id}/notes/{noteId}": {
      "patch": {
        "operationId": "MembershipController_updateNote",
        "parameters": [
          {
            "name": "noteId",
            "required": true,
            "in": "path",
            "description": "Note UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {}
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMembershipNoteDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Note updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a membership note",
        "tags": ["Memberships"]
      },
      "delete": {
        "operationId": "MembershipController_deleteNote",
        "parameters": [
          {
            "name": "noteId",
            "required": true,
            "in": "path",
            "description": "Note UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Membership UUID",
            "schema": {}
          },
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "Note deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a membership note",
        "tags": ["Memberships"]
      }
    },
    "/organizations/{organizationId}/posts": {
      "get": {
        "operationId": "PostsController_getPosts",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated posts"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List posts for an organization",
        "tags": ["Posts"]
      },
      "post": {
        "operationId": "PostsController_createPost",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePostDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Post created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a new post",
        "tags": ["Posts"]
      }
    },
    "/organizations/{organizationId}/posts/check-slug": {
      "get": {
        "operationId": "PostsController_checkSlug",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "excludePostId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Slug availability result"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Check slug availability",
        "tags": ["Posts"]
      }
    },
    "/organizations/{organizationId}/posts/{postId}": {
      "get": {
        "operationId": "PostsController_getPost",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postId",
            "required": true,
            "in": "path",
            "description": "Post UUID or slug",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Post detail"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get a single post",
        "tags": ["Posts"]
      },
      "patch": {
        "operationId": "PostsController_updatePost",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postId",
            "required": true,
            "in": "path",
            "description": "Post UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePostDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Post updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a post",
        "tags": ["Posts"]
      },
      "delete": {
        "operationId": "PostsController_deletePost",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postId",
            "required": true,
            "in": "path",
            "description": "Post UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Post deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a post",
        "tags": ["Posts"]
      }
    },
    "/organizations/{organizationId}/posts/{postId}/history": {
      "get": {
        "operationId": "PostsController_getPostHistory",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postId",
            "required": true,
            "in": "path",
            "description": "Post UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Post version history"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get all versions of a post",
        "tags": ["Posts"]
      }
    },
    "/organizations/{organizationId}/posts/{postId}/history/{version}/restore": {
      "post": {
        "operationId": "PostsController_restorePostVersion",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postId",
            "required": true,
            "in": "path",
            "description": "Post UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "required": true,
            "in": "path",
            "description": "Version number to restore",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Post restored to version"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Restore a post to a specific version",
        "tags": ["Posts"]
      }
    },
    "/organizations/{organizationId}/posts/{postId}/history/{historyId}": {
      "get": {
        "operationId": "PostsController_getPostHistoryItem",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postId",
            "required": true,
            "in": "path",
            "description": "Post UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "historyId",
            "required": true,
            "in": "path",
            "description": "History entry UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "History snapshot"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get a specific history snapshot by ID",
        "tags": ["Posts"]
      }
    },
    "/organizations/{organizationId}/posts/{postId}/history/{historyId}/diff": {
      "get": {
        "operationId": "PostsController_getPostHistoryDiff",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "postId",
            "required": true,
            "in": "path",
            "description": "Post UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "historyId",
            "required": true,
            "in": "path",
            "description": "History entry UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Content diff"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get diff between a history version and current",
        "tags": ["Posts"]
      }
    },
    "/discord/bot-invite": {
      "get": {
        "operationId": "DiscordController_getBotInvite",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Bot invite URL"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get bot invite URL",
        "tags": ["Discord"]
      }
    },
    "/discord/{guildId}/voice-stream": {
      "get": {
        "operationId": "DiscordController_voiceStream",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Discord server snowflake ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Server-sent events stream"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "SSE stream of voice state changes for a Discord server",
        "tags": ["Discord"]
      }
    },
    "/discord/{guildId}/activity": {
      "get": {
        "operationId": "DiscordController_getChannelActivity",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Discord server snowflake ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "channelIds",
            "required": false,
            "in": "query",
            "description": "Comma-separated channel IDs to filter",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Channel activity"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get recent Discord channel activity and voice presence",
        "tags": ["Discord"]
      }
    },
    "/discord/{guildId}/channels": {
      "get": {
        "operationId": "DiscordController_listChannels",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Discord server snowflake ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Channel list"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List text channels in a Discord server",
        "tags": ["Discord"]
      }
    },
    "/discord/{guildId}/roles": {
      "get": {
        "operationId": "DiscordController_listRoles",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Discord server snowflake ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Role list"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List roles in a Discord server",
        "tags": ["Discord"]
      }
    },
    "/organizations/{guildId}/discord-rank-roles": {
      "get": {
        "operationId": "DiscordRankRoleController_list",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mappings keyed by platform role id"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List platform role → Discord role mappings",
        "tags": ["Discord rank roles"]
      }
    },
    "/organizations/{guildId}/discord-rank-roles/roles/{roleId}": {
      "put": {
        "operationId": "DiscordRankRoleController_putRoleMappings",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "roleId",
            "required": true,
            "in": "path",
            "description": "Platform Role UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDiscordRankRoleMappingsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Replace Discord roles mapped to a platform role",
        "tags": ["Discord rank roles"]
      }
    },
    "/organizations/{guildId}/discord-rank-roles/clear-suppressions": {
      "post": {
        "operationId": "DiscordRankRoleController_clearSuppressions",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClearDiscordRankSuppressionsDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Clear rank-managed Discord role suppressions (re-allow sync adds)",
        "tags": ["Discord rank roles"]
      }
    },
    "/organizations/{guildId}/discord-rank-roles/reconcile": {
      "post": {
        "operationId": "DiscordRankRoleController_reconcile",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Reconcile Discord rank roles for all members in this guild",
        "tags": ["Discord rank roles"]
      }
    },
    "/events/{eventId}/participations": {
      "get": {
        "operationId": "ParticipationController_findByEvent",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Event participations"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List participations for an event",
        "tags": ["Events"]
      }
    },
    "/notifications": {
      "get": {
        "operationId": "NotificationController_findAll",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "unreadOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated notifications"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List notifications for current user",
        "tags": ["Notifications"]
      }
    },
    "/notifications/unread-count": {
      "get": {
        "operationId": "NotificationController_unreadCount",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Unread count"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get unread notification count",
        "tags": ["Notifications"]
      }
    },
    "/notifications/{id}/read": {
      "patch": {
        "operationId": "NotificationController_markAsRead",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Notification UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Notification marked as read"
          },
          "404": {
            "description": "Notification not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Mark a notification as read",
        "tags": ["Notifications"]
      }
    },
    "/notifications/read-all": {
      "patch": {
        "operationId": "NotificationController_markAllAsRead",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "All notifications marked as read"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Mark all notifications as read",
        "tags": ["Notifications"]
      }
    },
    "/notifications/{id}/dismiss": {
      "patch": {
        "operationId": "NotificationController_dismiss",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Notification UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Notification dismissed"
          },
          "404": {
            "description": "Notification not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Dismiss a notification",
        "tags": ["Notifications"]
      }
    },
    "/notifications/dismiss-all": {
      "patch": {
        "operationId": "NotificationController_dismissAllNotifications",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "All notifications dismissed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Dismiss all notifications",
        "tags": ["Notifications"]
      }
    },
    "/notifications/preferences": {
      "get": {
        "operationId": "NotificationController_findPreferences",
        "parameters": [
          {
            "name": "organizationId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User notification preferences"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get notification preferences",
        "tags": ["Notifications"]
      },
      "put": {
        "operationId": "NotificationController_upsertPreferences",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePreferencesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preferences updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update notification preferences",
        "tags": ["Notifications"]
      }
    },
    "/notifications/push/vapid-key": {
      "get": {
        "operationId": "NotificationController_getVapidKey",
        "parameters": [],
        "responses": {
          "200": {
            "description": "VAPID public key"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get VAPID public key for push subscriptions",
        "tags": ["Notifications"]
      }
    },
    "/notifications/push/subscribe": {
      "post": {
        "operationId": "NotificationController_subscribePush",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Subscription registered"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Register a push subscription",
        "tags": ["Notifications"]
      },
      "delete": {
        "operationId": "NotificationController_unsubscribePush",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Subscription removed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove a push subscription",
        "tags": ["Notifications"]
      }
    },
    "/organizations/{guildId}/roles": {
      "get": {
        "operationId": "RoleController_findByGuild",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Guild roles"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List roles in a guild",
        "tags": ["Roles"]
      },
      "post": {
        "operationId": "RoleController_create",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRoleDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Role created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a guild role (officers only)",
        "tags": ["Roles"]
      }
    },
    "/organizations/{guildId}/roles/{roleId}": {
      "get": {
        "operationId": "RoleController_findOne",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "roleId",
            "required": true,
            "in": "path",
            "description": "Role UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Role detail"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get role by ID",
        "tags": ["Roles"]
      },
      "patch": {
        "operationId": "RoleController_update",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "roleId",
            "required": true,
            "in": "path",
            "description": "Role UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRoleDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Role updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a guild role (officers only)",
        "tags": ["Roles"]
      },
      "delete": {
        "operationId": "RoleController_delete",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "roleId",
            "required": true,
            "in": "path",
            "description": "Role UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Role deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a guild role (officers only)",
        "tags": ["Roles"]
      }
    },
    "/organizations/{guildId}/roles/{roleId}/permissions": {
      "patch": {
        "operationId": "RoleController_updatePermissions",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "roleId",
            "required": true,
            "in": "path",
            "description": "Role UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRolePermissionsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Permissions updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update role permissions (officers only)",
        "tags": ["Roles"]
      }
    },
    "/organizations/{guildId}/events": {
      "get": {
        "operationId": "EventController_findByGuild",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "required": false,
            "in": "query",
            "description": "ISO date filter start",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "required": false,
            "in": "query",
            "description": "ISO date filter end",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search events by title",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dedup",
            "required": false,
            "in": "query",
            "description": "Deduplicate global events by title (default true). Set false to show all instances.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort direction by scheduledAt (asc | desc). Default asc.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated events"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List events for a guild",
        "tags": ["Events"]
      },
      "post": {
        "operationId": "EventController_create",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEventDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Event created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create event",
        "tags": ["Events"]
      }
    },
    "/organizations/{guildId}/events/upload-image": {
      "post": {
        "operationId": "EventController_uploadEventImage",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Image uploaded, returns URL"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Upload event image (officers only)",
        "tags": ["Events"]
      }
    },
    "/events/me": {
      "get": {
        "operationId": "EventController_findMyEvents",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "required": false,
            "in": "query",
            "description": "ISO date filter start",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "required": false,
            "in": "query",
            "description": "ISO date filter end",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search events by title",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort direction by scheduledAt (asc | desc). Default asc.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated events across all guilds"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List events across all guilds for the authenticated user",
        "tags": ["Events"]
      }
    },
    "/events/my-invitations": {
      "get": {
        "operationId": "EventController_findMyInvitations",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Pending invitations"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List pending event invitations for current user",
        "tags": ["Events"]
      }
    },
    "/events/{id}": {
      "get": {
        "operationId": "EventController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID or alias slug",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Event detail"
          },
          "404": {
            "description": "Event not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get event by ID or alias",
        "tags": ["Events"]
      },
      "patch": {
        "operationId": "EventController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEventDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update event",
        "tags": ["Events"]
      },
      "delete": {
        "operationId": "EventController_delete",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Event deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete event",
        "tags": ["Events"]
      }
    },
    "/events/{id}/delay": {
      "patch": {
        "operationId": "EventController_delay",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DelayEventDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event delayed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delay event start time",
        "tags": ["Events"]
      }
    },
    "/events/{id}/cancel-series": {
      "post": {
        "operationId": "EventController_cancelSeries",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Any event UUID from the series",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Series cancelled"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Cancel all future events in a recurring series",
        "tags": ["Events"]
      }
    },
    "/events/{id}/delete-series": {
      "delete": {
        "operationId": "EventController_deleteSeries",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Any event UUID from the series",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Series deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete all future events in a recurring series",
        "tags": ["Events"]
      }
    },
    "/events/{id}/update-series-future": {
      "patch": {
        "operationId": "EventController_updateSeriesFuture",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Any event UUID from the series",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEventDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Future events updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update this and all future events in a recurring series",
        "tags": ["Events"]
      }
    },
    "/events/{id}/inviteable-users": {
      "get": {
        "operationId": "EventController_getInviteableUsers",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Inviteable users"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get guild members eligible to be invited to an event",
        "tags": ["Events"]
      }
    },
    "/events/{id}/invite": {
      "post": {
        "operationId": "EventController_invite",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Member invited"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Invite a member to an event (officers only)",
        "tags": ["Events"]
      }
    },
    "/events/{id}/pending-invites/{characterId}": {
      "delete": {
        "operationId": "EventController_removePendingInvite",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "characterId",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pending invite removed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove a pending invite for an unclaimed character",
        "tags": ["Events"]
      }
    },
    "/events/{id}/sync-group": {
      "post": {
        "operationId": "EventController_syncGroup",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sync completed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Re-sync invites from linked group composition",
        "tags": ["Events"]
      }
    },
    "/events/{id}/signup": {
      "post": {
        "operationId": "EventController_signup",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignupDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Signed up"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Sign up for an event",
        "tags": ["Events"]
      },
      "delete": {
        "operationId": "EventController_removeSignup",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signup removed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove own signup from an event",
        "tags": ["Events"]
      },
      "patch": {
        "operationId": "EventController_updateMySignup",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMySignupDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signup updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update own signup (character or role)",
        "tags": ["Events"]
      }
    },
    "/events/{id}/attendance": {
      "post": {
        "operationId": "EventController_recordAttendance",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordAttendanceDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Attendance recorded"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Record attendance for an event (officers only)",
        "tags": ["Events"]
      }
    },
    "/events/{eventId}/participations/{userId}": {
      "patch": {
        "operationId": "EventController_updateParticipationStatus",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateParticipationStatusDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Participation updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a participation status (officers only)",
        "tags": ["Events"]
      }
    },
    "/events/{id}/voice-presence": {
      "get": {
        "operationId": "EventController_getVoicePresence",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Users currently in voice channel"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get Discord voice channel presence for event",
        "tags": ["Events"]
      }
    },
    "/events/{id}/attendance/confirm": {
      "post": {
        "operationId": "EventController_confirmAttendance",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmAttendanceDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Attendance confirmed"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Confirm final attendance roster (officers only)",
        "tags": ["Events"]
      }
    },
    "/media/upload": {
      "post": {
        "operationId": "MediaController_upload",
        "parameters": [
          {
            "name": "folder",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tags",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Asset uploaded and cataloged"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload a media asset",
        "tags": ["Media"]
      }
    },
    "/media": {
      "get": {
        "operationId": "MediaController_list",
        "parameters": [
          {
            "name": "scope",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["mine", "platform", "all"],
              "type": "string"
            }
          },
          {
            "name": "folder",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of assets"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List media assets",
        "tags": ["Media"]
      }
    },
    "/media/folders": {
      "get": {
        "operationId": "MediaController_folders",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Array of folder names"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List distinct folders",
        "tags": ["Media"]
      }
    },
    "/media/{id}": {
      "get": {
        "operationId": "MediaController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Media asset details"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a single media asset",
        "tags": ["Media"]
      },
      "patch": {
        "operationId": "MediaController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMediaAssetDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated asset"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update media asset metadata",
        "tags": ["Media"]
      },
      "delete": {
        "operationId": "MediaController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a media asset",
        "tags": ["Media"]
      }
    },
    "/admin/features": {
      "get": {
        "operationId": "AdminController_getFeatures",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Current feature flags"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get platform feature flags (public)",
        "tags": ["Admin"]
      },
      "patch": {
        "operationId": "AdminController_updateFeatures",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Updated feature flags"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update platform feature flags (admin only)",
        "tags": ["Admin"]
      }
    },
    "/admin/stats": {
      "get": {
        "operationId": "AdminController_getUsageStats",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Platform stats"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get platform usage statistics",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-rosters": {
      "post": {
        "operationId": "AdminController_triggerRosterSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync started for all guilds"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger roster sync for all guilds",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-rosters/active": {
      "get": {
        "operationId": "AdminController_getActiveRosterSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active roster sync sessions or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active admin roster sync sessions",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-guild-crests": {
      "post": {
        "operationId": "AdminController_triggerGuildCrestSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Crest sync triggered for all guilds"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger crest sync for all guilds",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-user-characters/{userId}": {
      "post": {
        "operationId": "AdminController_triggerUserCharacterSync",
        "parameters": [
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "Target user ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sync started, returns sessionId"
          },
          "404": {
            "description": "User or Battle.net link missing"
          },
          "409": {
            "description": "Sync already in progress"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger Battle.net character sync for a specific user (admin)",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-user-characters/{userId}/active": {
      "get": {
        "operationId": "AdminController_getActiveUserCharacterSync",
        "parameters": [
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "Target user ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active character sync session for a specific user (admin)",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-instances": {
      "post": {
        "operationId": "AdminController_triggerInstanceSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger journal instance sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-instances/active": {
      "get": {
        "operationId": "AdminController_getActiveInstanceSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active journal sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-housing": {
      "post": {
        "operationId": "AdminController_triggerHousingSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger housing catalog sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-housing/active": {
      "get": {
        "operationId": "AdminController_getActiveHousingSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active housing sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-journal-loot": {
      "post": {
        "operationId": "AdminController_triggerJournalLootSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger journal loot sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-journal-loot/active": {
      "get": {
        "operationId": "AdminController_getActiveJournalLootSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active journal loot sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/difficulty-ilvl": {
      "get": {
        "operationId": "AdminController_getDifficultyIlvl",
        "parameters": [
          {
            "name": "instanceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Difficulty ilvl data"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get all instance difficulty item levels",
        "tags": ["Admin"]
      },
      "post": {
        "operationId": "AdminController_upsertDifficultyIlvl",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Difficulty ilvl upserted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Upsert instance difficulty item level",
        "tags": ["Admin"]
      }
    },
    "/admin/difficulty-ilvl/bulk": {
      "post": {
        "operationId": "AdminController_bulkUpsertDifficultyIlvl",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Difficulty ilvls upserted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Bulk upsert difficulty item levels for an instance",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-reputation-factions": {
      "post": {
        "operationId": "AdminController_triggerReputationFactionSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Sync reputation faction hierarchy via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-reputation-factions/active": {
      "get": {
        "operationId": "AdminController_getActiveReputationFactionSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active reputation faction sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-talent-trees": {
      "post": {
        "operationId": "AdminController_triggerTalentTreeSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Sync talent tree structures via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-talent-trees/active": {
      "get": {
        "operationId": "AdminController_getActiveTalentTreeSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active talent tree sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-profession-recipes": {
      "post": {
        "operationId": "AdminController_triggerProfessionRecipeSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger profession recipe catalog sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-profession-recipes/active": {
      "get": {
        "operationId": "AdminController_getActiveProfessionRecipeSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active profession recipe sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-items": {
      "post": {
        "description": "Walks Blizzard item search from MAX(wow_items.id) + 1, picking up only items added since the last sync. Cheap, runs frequently.",
        "operationId": "AdminController_triggerItemSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger incremental item catalog sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-items/active": {
      "get": {
        "operationId": "AdminController_getActiveItemSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active incremental item catalog sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-items/full": {
      "post": {
        "description": "Walks the entire Blizzard item catalog from id=0. Use for major patch landings, locale rebuilds, or periodic sanity checks. Long-running and heavy on Blizzard quota.",
        "operationId": "AdminController_triggerItemFullSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Full sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger full item catalog rebuild via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-items/full/active": {
      "get": {
        "operationId": "AdminController_getActiveItemFullSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active full item catalog rebuild session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-item-icons": {
      "post": {
        "operationId": "AdminController_triggerItemIconSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger item icon sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-item-icons/active": {
      "get": {
        "operationId": "AdminController_getActiveItemIconSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active item icon sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-item-classes": {
      "post": {
        "operationId": "AdminController_triggerItemClassSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger item class taxonomy sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-item-classes/active": {
      "get": {
        "operationId": "AdminController_getActiveItemClassSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active item class taxonomy sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-item-enrichment": {
      "post": {
        "operationId": "AdminController_triggerItemEnrichmentSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger item enrichment sync via GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-item-enrichment/active": {
      "get": {
        "operationId": "AdminController_getActiveItemEnrichmentSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active item enrichment sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-crafting-slots": {
      "post": {
        "operationId": "AdminController_triggerCraftingSlotSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync triggered, returns sessionId"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger crafting slots sync via GDL (Wago DB2)",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-crafting-slots/active": {
      "get": {
        "operationId": "AdminController_getActiveCraftingSlotSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active crafting slots sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/cancel-sync/{sessionId}": {
      "post": {
        "operationId": "AdminController_cancelSync",
        "parameters": [
          {
            "name": "sessionId",
            "required": true,
            "in": "path",
            "description": "Sync session UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancellation result"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Cancel an active sync session",
        "tags": ["Admin"]
      }
    },
    "/admin/blizzard-quota": {
      "get": {
        "operationId": "AdminController_getBlizzardQuota",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Current API quota usage and throttle state"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get Blizzard API hourly quota status",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-status": {
      "get": {
        "operationId": "AdminController_getSyncStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active sync status per category"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get all active sync sessions in one call",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-history": {
      "get": {
        "operationId": "AdminController_getSyncHistory",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Max sessions to return (default 50, max 100)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "description": "Filter by category (e.g. roster, character_sync, wow.journal)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sync history"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get unified sync session history from GDL",
        "tags": ["Admin"]
      }
    },
    "/admin/sync-summary": {
      "get": {
        "operationId": "AdminController_getSyncSummary",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sync summary per category"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get sync summary: last completed sync per category with patch info",
        "tags": ["Admin"]
      }
    },
    "/admin/seed-holidays": {
      "post": {
        "operationId": "AdminController_seedHolidays",
        "parameters": [
          {
            "name": "year",
            "required": false,
            "in": "query",
            "description": "Year to seed (defaults to current)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Holidays seeded"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Seed WoW holiday events for a year",
        "tags": ["Admin"]
      }
    },
    "/admin/holidays": {
      "get": {
        "operationId": "AdminController_getHolidays",
        "parameters": [
          {
            "name": "year",
            "required": false,
            "in": "query",
            "description": "Filter by year",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Holiday events"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List global holiday events",
        "tags": ["Admin"]
      },
      "post": {
        "operationId": "AdminController_createHoliday",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAdminHolidayDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Holiday event created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a global holiday event",
        "tags": ["Admin"]
      }
    },
    "/admin/holidays/{eventId}": {
      "get": {
        "operationId": "AdminController_getHoliday",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Holiday event"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get a single global holiday event",
        "tags": ["Admin"]
      }
    },
    "/admin/upload-event-image": {
      "post": {
        "operationId": "AdminController_uploadEventImage",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Image uploaded, returns URL"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Upload event image (admin)",
        "tags": ["Admin"]
      }
    },
    "/admin/register-patch": {
      "post": {
        "operationId": "AdminController_registerPatch",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Patch registered"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Register a new WoW game patch",
        "tags": ["Admin"]
      }
    },
    "/admin/set-current-patch": {
      "patch": {
        "operationId": "AdminController_setCurrentPatch",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Patch activated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Set a patch as the current active patch",
        "tags": ["Admin"]
      }
    },
    "/admin/update-patch": {
      "patch": {
        "operationId": "AdminController_updatePatch",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Patch updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update an existing game patch",
        "tags": ["Admin"]
      }
    },
    "/admin/patches/{version}": {
      "delete": {
        "operationId": "AdminController_deletePatch",
        "parameters": [
          {
            "name": "version",
            "required": true,
            "in": "path",
            "description": "Patch version string",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Patch deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a non-current patch",
        "tags": ["Admin"]
      }
    },
    "/admin/scrape-hotfixes": {
      "post": {
        "operationId": "AdminController_scrapeHotfixes",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Scrape result"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Scrape hotfix notes (optionally saves URL first)",
        "tags": ["Admin"]
      }
    },
    "/admin/hotfix-url": {
      "get": {
        "operationId": "AdminController_getHotfixUrl",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Current hotfix URL"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get the current hotfix page URL",
        "tags": ["Admin"]
      },
      "patch": {
        "operationId": "AdminController_updateHotfixUrl",
        "parameters": [],
        "responses": {
          "200": {
            "description": "URL updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update the hotfix page URL for scraping",
        "tags": ["Admin"]
      }
    },
    "/admin/hotfix-days": {
      "get": {
        "operationId": "AdminController_getHotfixDays",
        "parameters": [],
        "responses": {
          "200": {
            "description": "All hotfix days"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all scraped hotfix days with assignments",
        "tags": ["Admin"]
      }
    },
    "/admin/hotfixes/{hotfixId}/assign": {
      "put": {
        "operationId": "AdminController_assignHotfixToPatches",
        "parameters": [
          {
            "name": "hotfixId",
            "required": true,
            "in": "path",
            "description": "PatchHotfix ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assignments updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Assign a hotfix day to patch versions",
        "tags": ["Admin"]
      }
    },
    "/admin/crafting-quality-tiers": {
      "get": {
        "operationId": "AdminController_getCraftingQualityTiers",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Tiers grouped by season"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all crafting quality tiers grouped by season",
        "tags": ["Admin"]
      },
      "post": {
        "operationId": "AdminController_createCraftingQualityTier",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Tier created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a crafting quality tier",
        "tags": ["Admin"]
      }
    },
    "/admin/crafting-quality-tiers/{tierId}": {
      "put": {
        "operationId": "AdminController_updateCraftingQualityTier",
        "parameters": [
          {
            "name": "tierId",
            "required": true,
            "in": "path",
            "description": "CraftingQualityTier ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tier updated"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a crafting quality tier",
        "tags": ["Admin"]
      },
      "delete": {
        "operationId": "AdminController_deleteCraftingQualityTier",
        "parameters": [
          {
            "name": "tierId",
            "required": true,
            "in": "path",
            "description": "CraftingQualityTier ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tier deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a crafting quality tier",
        "tags": ["Admin"]
      }
    },
    "/admin/slow-queries/top": {
      "get": {
        "operationId": "AdminController_getTopSlowQueries",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Aggregated slow query stats"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Top slow query patterns from pg_stat_statements",
        "tags": ["Admin"]
      }
    },
    "/admin/slow-queries/recent": {
      "get": {
        "operationId": "AdminController_getRecentSlowQueries",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Recent slow query entries"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Recent slow queries from in-memory ring buffers",
        "tags": ["Admin"]
      }
    },
    "/admin/slow-queries/historical": {
      "get": {
        "operationId": "AdminController_getHistoricalSlowQueries",
        "parameters": [
          {
            "name": "windowMinutes",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "database",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "hideColdStart",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Slow query entries"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Historical slow queries from CloudWatch Logs Insights (last N minutes)",
        "tags": ["Admin"]
      }
    },
    "/admin/slow-queries/meta": {
      "get": {
        "operationId": "AdminController_getSlowQueryMeta",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Slow-query meta payload"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Process boot info, pg_stat_statements last-reset times, Performance Insights URLs",
        "tags": ["Admin"]
      }
    },
    "/admin/slow-queries/reset-pg-stats": {
      "post": {
        "operationId": "AdminController_resetPgStats",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Reset summary"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Reset pg_stat_statements across all 3 databases (sanctum, sanctum_catalog, sanctum_characters)",
        "tags": ["Admin"]
      }
    },
    "/admin/slow-queries/reset-buffer": {
      "post": {
        "operationId": "AdminController_resetSlowQueryBuffer",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Buffer cleared"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Clear in-memory slow-query ring buffers across api and gdl-node",
        "tags": ["Admin"]
      }
    },
    "/admin/probe-account-decor": {
      "get": {
        "operationId": "AdminController_probeAccountDecor",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Raw Blizzard response or error"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Probe Blizzard account-wide decor endpoint (/profile/user/wow/collections/decor)",
        "tags": ["Admin"]
      }
    },
    "/admin/reset-all-onboarding": {
      "post": {
        "operationId": "AdminController_resetAllOnboarding",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Count of users reset"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Reset onboarding for all users",
        "tags": ["Admin"]
      }
    },
    "/admin/cleanup-orphan-storage": {
      "post": {
        "description": "Deletes S3 objects under user-content prefixes that are no longer referenced in the DB. Pass ?dryRun=true to preview without deleting.",
        "operationId": "AdminController_cleanupOrphanStorage",
        "parameters": [
          {
            "name": "dryRun",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cleanup summary"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Run orphan storage cleanup",
        "tags": ["Admin"]
      }
    },
    "/admin/users": {
      "get": {
        "operationId": "AdminUsersController_list",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["lastLoginAt", "createdAt", "email", "displayName"]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeDeleted",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["true", "false"]
            }
          },
          {
            "name": "adminsOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["true", "false"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User list"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List users (paginated, searchable, sortable)",
        "tags": ["Admin · Users"]
      }
    },
    "/admin/users/{id}": {
      "get": {
        "operationId": "AdminUsersController_getOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User detail"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get full user detail",
        "tags": ["Admin · Users"]
      },
      "patch": {
        "operationId": "AdminUsersController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAdminUserDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated user"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update user admin-controllable fields (isAdmin, display name, …)",
        "tags": ["Admin · Users"]
      },
      "delete": {
        "operationId": "AdminUsersController_softDelete",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User soft deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Soft delete a user (sets deletedAt, revokes sessions, frees email for reuse). Relations preserved for audit.",
        "tags": ["Admin · Users"]
      }
    },
    "/admin/users/{id}/revoke-sessions": {
      "post": {
        "operationId": "AdminUsersController_revokeSessions",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sessions revoked"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Revoke all sessions for a user",
        "tags": ["Admin · Users"]
      }
    },
    "/admin/users/{id}/sessions/{sessionId}": {
      "delete": {
        "operationId": "AdminUsersController_revokeSession",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sessionId",
            "required": true,
            "in": "path",
            "description": "Session id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session revoked"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Revoke a single session for a user",
        "tags": ["Admin · Users"]
      }
    },
    "/admin/users/{id}/anonymize": {
      "post": {
        "operationId": "AdminUsersController_anonymize",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Anonymized user"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Anonymize user (clears email/image, rewrites display name). Keeps relations for attribution.",
        "tags": ["Admin · Users"]
      }
    },
    "/admin/users/{id}/unlink-account": {
      "post": {
        "operationId": "AdminUsersController_unlinkAccount",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "User UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnlinkAccountDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account unlinked"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Unlink a social account (deletes Account row + clears denormalized provider id on user). Re-link is NOT blocked yet.",
        "tags": ["Admin · Users"]
      }
    },
    "/admin/users/{userId}/notes": {
      "get": {
        "operationId": "AdminUserNotesController_list",
        "parameters": [
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "Target user UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of notes (most recent first)"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List active admin notes for a user",
        "tags": ["Admin · User Notes"]
      },
      "post": {
        "operationId": "AdminUserNotesController_create",
        "parameters": [
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "Target user UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAdminUserNoteDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created note"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create an admin note on a user",
        "tags": ["Admin · User Notes"]
      }
    },
    "/admin/users/{userId}/notes/{noteId}": {
      "patch": {
        "operationId": "AdminUserNotesController_update",
        "parameters": [
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "Target user UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "noteId",
            "required": true,
            "in": "path",
            "description": "Note UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAdminUserNoteDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated note"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update an admin note (author only)",
        "tags": ["Admin · User Notes"]
      },
      "delete": {
        "operationId": "AdminUserNotesController_delete",
        "parameters": [
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "description": "Target user UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "noteId",
            "required": true,
            "in": "path",
            "description": "Note UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Note deleted"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Soft-delete an admin note",
        "tags": ["Admin · User Notes"]
      }
    },
    "/admin/audit": {
      "get": {
        "operationId": "AdminAuditLogController_list",
        "parameters": [
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "name": "actorUserId",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          },
          {
            "name": "targetUserId",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          },
          {
            "name": "action",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit entries"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List audit entries with cursor pagination",
        "tags": ["Admin · Audit"]
      }
    },
    "/organizations/{guildId}/applications": {
      "post": {
        "operationId": "ApplicationController_submit",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitApplicationDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Submit an application to join the guild",
        "tags": ["Applications"]
      },
      "get": {
        "operationId": "ApplicationController_listAll",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": ["pending", "accepted", "rejected", "withdrawn"],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List all applications for this guild (officers only)",
        "tags": ["Applications"]
      }
    },
    "/organizations/{guildId}/applications/mine": {
      "get": {
        "operationId": "ApplicationController_getMyApplication",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get my application for this guild",
        "tags": ["Applications"]
      },
      "delete": {
        "operationId": "ApplicationController_withdrawApplication",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Withdraw my application",
        "tags": ["Applications"]
      }
    },
    "/organizations/{guildId}/applications/{id}/review": {
      "patch": {
        "operationId": "ApplicationController_reviewApplication",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Application UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewApplicationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Accept or reject an application (officers only)",
        "tags": ["Applications"]
      }
    },
    "/organizations/{guildId}/application-form": {
      "get": {
        "operationId": "ApplicationFormController_getForm",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get the application form config for a guild",
        "tags": ["Application Form"]
      },
      "put": {
        "operationId": "ApplicationFormController_updateForm",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateApplicationFormDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Update the application form config (officers only)",
        "tags": ["Application Form"]
      }
    },
    "/housing/collection": {
      "get": {
        "operationId": "HousingController_getCollection",
        "parameters": [
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dyeable",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "craftable",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated decor collection"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get current user decor collection (paginated)",
        "tags": ["Housing"]
      }
    },
    "/housing/collection/summary": {
      "get": {
        "operationId": "HousingController_getCollectionSummary",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Collection summary"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get collection summary stats",
        "tags": ["Housing"]
      }
    },
    "/housing/collection/sync": {
      "post": {
        "operationId": "HousingController_syncCollection",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Decor collection synced"
          },
          "404": {
            "description": "No WoW character found"
          },
          "409": {
            "description": "Battle.net token expired"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Sync decor collection from Battle.net (account-wide)",
        "tags": ["Housing"]
      }
    },
    "/characters/{id}/sim": {
      "post": {
        "operationId": "SimulationController_simCharacter",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "talentLoadoutCode": {
                    "type": "string",
                    "description": "Override talent loadout code (base64 encoded)"
                  },
                  "profileOverride": {
                    "type": "string",
                    "description": "Raw SimC profile text (advanced — replaces auto-generated profile)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sim job created"
          },
          "403": {
            "description": "Not your character"
          },
          "404": {
            "description": "Character not found"
          },
          "409": {
            "description": "Active job already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Queue a SimC simulation for a character",
        "tags": ["Simulations"]
      }
    },
    "/organizations/{organizationId}/sim-group": {
      "post": {
        "operationId": "SimulationController_simGroup",
        "parameters": [
          {
            "name": "organizationId",
            "required": true,
            "in": "path",
            "description": "Organization UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["characterIds"],
                "properties": {
                  "characterIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Character UUIDs to simulate (e.g. raid comp, dungeon group)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Group sim job created"
          },
          "400": {
            "description": "No valid characters provided"
          },
          "403": {
            "description": "Insufficient permissions"
          },
          "404": {
            "description": "Organization not found"
          },
          "409": {
            "description": "Active job already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Queue a SimC simulation for a group of characters",
        "tags": ["Simulations"]
      }
    },
    "/characters/{id}/classify-build": {
      "post": {
        "operationId": "SimulationController_classifyBuild",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["talentLoadoutCode"],
                "properties": {
                  "talentLoadoutCode": {
                    "type": "string",
                    "description": "Talent loadout code to classify"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Classification job created"
          },
          "403": {
            "description": "Not your character"
          },
          "404": {
            "description": "Character not found"
          },
          "409": {
            "description": "Active job already exists"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Classify a talent loadout by running multi-profile SimC sims",
        "tags": ["Simulations"]
      }
    },
    "/characters/{id}/classify-all-builds": {
      "post": {
        "operationId": "SimulationController_classifyAllBuilds",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["talentLoadoutCodes"],
                "properties": {
                  "talentLoadoutCodes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of talent loadout codes to classify"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Classification jobs created"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Classify all talent loadouts by running multi-profile SimC sims for each",
        "tags": ["Simulations"]
      }
    },
    "/sim-jobs/active-classifications": {
      "get": {
        "operationId": "SimulationController_getActiveClassifications",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active classification jobs"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get active classification jobs for the current user",
        "tags": ["Simulations"]
      }
    },
    "/sim-jobs/mine": {
      "get": {
        "operationId": "SimulationController_getMySimJobs",
        "parameters": [],
        "responses": {
          "200": {
            "description": "List of sim jobs"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List your recent sim jobs",
        "tags": ["Simulations"]
      }
    },
    "/sim-jobs/{id}": {
      "get": {
        "operationId": "SimulationController_getSimJob",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "SimJob UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sim job details"
          },
          "403": {
            "description": "Not your job"
          },
          "404": {
            "description": "Job not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a sim job by ID",
        "tags": ["Simulations"]
      }
    },
    "/sim-jobs/{id}/results": {
      "get": {
        "operationId": "SimulationController_getSimResults",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "SimJob UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Per-character sim results"
          },
          "403": {
            "description": "Not your job"
          },
          "404": {
            "description": "Job not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get per-character sim results for a job",
        "tags": ["Simulations"]
      }
    },
    "/characters/{id}/sim-history": {
      "get": {
        "operationId": "SimulationController_getCharacterSimHistory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character sim history"
          },
          "403": {
            "description": "Not your character"
          },
          "404": {
            "description": "Character not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get sim history for a character",
        "tags": ["Simulations"]
      }
    },
    "/characters/{id}/sim-config": {
      "get": {
        "operationId": "SimulationController_getSimConfig",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sim config data"
          },
          "403": {
            "description": "Not your character"
          },
          "404": {
            "description": "Character not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get sim configuration data for a character (gear, loadouts)",
        "tags": ["Simulations"]
      }
    },
    "/characters/{id}/talent-comparison": {
      "get": {
        "operationId": "SimulationController_getTalentComparison",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Character UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Talent comparison data"
          },
          "403": {
            "description": "Not your character"
          },
          "404": {
            "description": "Character not found"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get talent build comparison data for a character",
        "tags": ["Simulations"]
      }
    },
    "/organizations/{guildId}/crafting-requests": {
      "post": {
        "operationId": "CraftingRequestController_create",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCraftingRequestDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a crafting request",
        "tags": ["Crafting Requests"]
      },
      "get": {
        "operationId": "CraftingRequestController_list",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "profession",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List crafting requests for a guild",
        "tags": ["Crafting Requests"]
      }
    },
    "/organizations/{guildId}/crafting-requests/unmatched": {
      "get": {
        "operationId": "CraftingRequestController_listUnmatched",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "unmatchedOnly",
            "required": false,
            "in": "query",
            "description": "If true, return only requests with zero matched crafters",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List open crafting requests annotated with matched crafter counts",
        "tags": ["Crafting Requests"]
      }
    },
    "/organizations/{guildId}/crafting-requests/{id}/claim": {
      "patch": {
        "operationId": "CraftingRequestController_claim",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Crafting request ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClaimCraftingRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Claim a crafting request",
        "tags": ["Crafting Requests"]
      }
    },
    "/organizations/{guildId}/crafting-requests/{id}/unclaim": {
      "patch": {
        "operationId": "CraftingRequestController_unclaim",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Crafting request ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Unclaim a crafting request",
        "tags": ["Crafting Requests"]
      }
    },
    "/organizations/{guildId}/crafting-requests/{id}/fulfill": {
      "patch": {
        "operationId": "CraftingRequestController_fulfill",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Crafting request ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fulfill a crafting request",
        "tags": ["Crafting Requests"]
      }
    },
    "/organizations/{guildId}/crafting-requests/{id}/cancel": {
      "patch": {
        "operationId": "CraftingRequestController_cancel",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Crafting request ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel a crafting request",
        "tags": ["Crafting Requests"]
      }
    },
    "/organizations/{guildId}/crafting-requests/my-eligible": {
      "get": {
        "operationId": "CraftingRequestController_myEligible",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get open crafting requests the current user can fulfill, keyed by request ID",
        "tags": ["Crafting Requests"]
      }
    },
    "/meta-builds": {
      "get": {
        "operationId": "MetaBuildController_getMetaBuilds",
        "parameters": [
          {
            "name": "specId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "contentType",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "encounterId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "instanceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Active meta builds"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get meta builds filtered by spec, encounter, or instance",
        "tags": ["Meta Builds"]
      }
    },
    "/encounters/{id}/meta-builds": {
      "get": {
        "operationId": "MetaBuildController_getMetaBuildsForEncounter",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Encounter ID (Blizzard ID)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "specId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Meta builds for encounter"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get meta builds for a specific encounter",
        "tags": ["Meta Builds"]
      }
    },
    "/instances/{id}/meta-builds": {
      "get": {
        "operationId": "MetaBuildController_getMetaBuildsForInstance",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Instance ID (Blizzard ID)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "specId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Meta builds for instance"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get meta builds for a specific dungeon instance",
        "tags": ["Meta Builds"]
      }
    },
    "/admin/meta-builds": {
      "post": {
        "operationId": "MetaBuildController_createAdminMetaBuild",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Build created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create or update a meta build (admin)",
        "tags": ["Meta Builds"]
      }
    },
    "/admin/meta-builds/{id}": {
      "delete": {
        "operationId": "MetaBuildController_deleteAdminMetaBuild",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "MetaBuild UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Soft-delete a meta build (admin)",
        "tags": ["Meta Builds"]
      }
    },
    "/admin/sync-meta-builds": {
      "post": {
        "operationId": "MetaBuildController_triggerMetaBuildSync",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sync started"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Trigger full WarcraftLogs meta build sync",
        "tags": ["Meta Builds"]
      }
    },
    "/admin/sync-meta-builds/active": {
      "get": {
        "operationId": "MetaBuildController_getActiveMetaBuildSync",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Active session or inactive"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get active meta build sync session",
        "tags": ["Meta Builds"]
      }
    },
    "/organizations/{orgId}/meta-builds": {
      "post": {
        "operationId": "MetaBuildController_createGuildMetaBuild",
        "parameters": [
          {
            "name": "orgId",
            "required": true,
            "in": "path",
            "description": "Organization UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Guild build added"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Add a guild-recommended meta build",
        "tags": ["Meta Builds"]
      }
    },
    "/organizations/{orgId}/meta-builds/{id}": {
      "delete": {
        "operationId": "MetaBuildController_deleteGuildMetaBuild",
        "parameters": [
          {
            "name": "orgId",
            "required": true,
            "in": "path",
            "description": "Organization UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "MetaBuild UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove a guild meta build",
        "tags": ["Meta Builds"]
      }
    },
    "/organizations/{guildId}/group-comps": {
      "post": {
        "operationId": "GroupCompController_create",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGroupCompDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a group composition",
        "tags": ["Group Compositions"]
      },
      "get": {
        "operationId": "GroupCompController_list",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List group compositions for a guild",
        "tags": ["Group Compositions"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}/events/summary": {
      "get": {
        "operationId": "GroupCompController_findLinkedEventsSummary",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Next upcoming and most recent past event linked to this group composition",
        "tags": ["Group Compositions"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}/events": {
      "get": {
        "operationId": "GroupCompController_findLinkedEvents",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List guild events linked to this group composition",
        "tags": ["Group Compositions"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}": {
      "get": {
        "operationId": "GroupCompController_findOne",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a group composition with full details",
        "tags": ["Group Compositions"]
      },
      "patch": {
        "operationId": "GroupCompController_update",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateGroupCompDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a group composition",
        "tags": ["Group Compositions"]
      },
      "delete": {
        "operationId": "GroupCompController_remove",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a group composition",
        "tags": ["Group Compositions"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}/sim": {
      "post": {
        "operationId": "GroupCompController_startSim",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start build optimization for a group composition",
        "tags": ["Group Compositions"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}/sim/active": {
      "get": {
        "operationId": "GroupCompController_getActiveSim",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get active sim batch for a group composition",
        "tags": ["Group Compositions"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}/sim-results": {
      "get": {
        "operationId": "GroupCompController_getSimResults",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization ID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Group composition ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get sim results for a group composition",
        "tags": ["Group Compositions"]
      }
    },
    "/characters/{id}/wcl-rankings": {
      "get": {
        "operationId": "WarcraftLogsController_getCharacterRankings",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoneId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "difficulty",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/characters/{id}/wcl-rankings/sync": {
      "post": {
        "operationId": "WarcraftLogsController_syncCharacterRankings",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoneId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "difficulty",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/organizations/{id}/wcl-reports": {
      "get": {
        "operationId": "WarcraftLogsController_getGuildReports",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoneId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/organizations/{id}/wcl-reports/sync": {
      "post": {
        "operationId": "WarcraftLogsController_syncGuildReports",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/organizations/{id}/wcl-reports/{code}/fights": {
      "get": {
        "operationId": "WarcraftLogsController_getReportFights",
        "parameters": [
          {
            "name": "code",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/organizations/{id}/wcl-reports/{code}/rankings": {
      "get": {
        "operationId": "WarcraftLogsController_getReportRankings",
        "parameters": [
          {
            "name": "code",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "metric",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "encounterId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}/wcl-report-rankings": {
      "get": {
        "operationId": "WarcraftLogsController_getGroupCompReportRankings",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoneId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "difficulty",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "maxReports",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/organizations/{guildId}/group-comps/{id}/wcl-rankings": {
      "get": {
        "operationId": "WarcraftLogsController_getGroupCompWclRankings",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoneId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "difficulty",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/organizations/{id}/wcl-guild-names": {
      "get": {
        "operationId": "WarcraftLogsController_getWclGuildNames",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      },
      "patch": {
        "operationId": "WarcraftLogsController_updateWclGuildNames",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/wcl/zones": {
      "get": {
        "operationId": "WarcraftLogsController_getRaidZones",
        "parameters": [
          {
            "name": "expansion",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/wcl/sync/{scope}/active": {
      "get": {
        "operationId": "WarcraftLogsController_getActiveSyncSession",
        "parameters": [
          {
            "name": "scope",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/events/{eventId}/wcl-reports": {
      "get": {
        "operationId": "WarcraftLogsController_getEventLinkedReports",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      },
      "post": {
        "operationId": "WarcraftLogsController_linkReportToEvent",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/events/{eventId}/wcl-reports/{code}": {
      "delete": {
        "operationId": "WarcraftLogsController_unlinkReportFromEvent",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/wcl/reports/{code}/linked-event": {
      "get": {
        "operationId": "WarcraftLogsController_getReportLinkedEvent",
        "parameters": [
          {
            "name": "code",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["WarcraftLogs"]
      }
    },
    "/help/articles": {
      "get": {
        "operationId": "HelpController_listPublished",
        "parameters": [
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Published articles"
          }
        },
        "summary": "List published help articles",
        "tags": ["Help"]
      }
    },
    "/help/categories": {
      "get": {
        "operationId": "HelpController_listCategories",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Category names"
          }
        },
        "summary": "List help article categories",
        "tags": ["Help"]
      }
    },
    "/help/articles/by-key/{helpKey}": {
      "get": {
        "operationId": "HelpController_findByHelpKey",
        "parameters": [
          {
            "name": "helpKey",
            "required": true,
            "in": "path",
            "description": "Contextual help key",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Article"
          },
          "404": {
            "description": "Not found"
          }
        },
        "summary": "Get help article by contextual key",
        "tags": ["Help"]
      }
    },
    "/help/articles/{slug}": {
      "get": {
        "operationId": "HelpController_findBySlug",
        "parameters": [
          {
            "name": "slug",
            "required": true,
            "in": "path",
            "description": "URL-friendly article slug",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Article"
          },
          "404": {
            "description": "Not found"
          }
        },
        "summary": "Get help article by slug",
        "tags": ["Help"]
      }
    },
    "/admin/help/articles": {
      "get": {
        "operationId": "HelpAdminController_listAll",
        "parameters": [],
        "responses": {
          "200": {
            "description": "All articles"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all help articles (including unpublished)",
        "tags": ["Help (Admin)"]
      },
      "post": {
        "operationId": "HelpAdminController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateHelpArticleDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Article created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a help article",
        "tags": ["Help (Admin)"]
      }
    },
    "/admin/help/articles/{id}": {
      "patch": {
        "operationId": "HelpAdminController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Article UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateHelpArticleDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Article updated"
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a help article",
        "tags": ["Help (Admin)"]
      },
      "delete": {
        "operationId": "HelpAdminController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Article UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Article deleted"
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a help article",
        "tags": ["Help (Admin)"]
      }
    },
    "/admin/help/templates": {
      "get": {
        "operationId": "HelpAdminController_listTemplates",
        "parameters": [],
        "responses": {
          "200": {
            "description": "All templates"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all help article templates",
        "tags": ["Help (Admin)"]
      },
      "post": {
        "operationId": "HelpAdminController_createTemplate",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateHelpTemplateDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a help article template",
        "tags": ["Help (Admin)"]
      }
    },
    "/admin/help/templates/{id}": {
      "get": {
        "operationId": "HelpAdminController_getTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get a single template",
        "tags": ["Help (Admin)"]
      },
      "patch": {
        "operationId": "HelpAdminController_updateTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateHelpTemplateDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a help article template",
        "tags": ["Help (Admin)"]
      },
      "delete": {
        "operationId": "HelpAdminController_removeTemplate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Template UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a help article template",
        "tags": ["Help (Admin)"]
      }
    },
    "/organizations/{guildId}/rulesets": {
      "get": {
        "operationId": "RulesetController_listRulesets",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeArchived",
            "required": false,
            "in": "query",
            "description": "Include archived rulesets",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by ruleset type",
            "schema": {
              "enum": ["loot"],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of rulesets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RulesetResponseDto"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all rulesets for an organization",
        "tags": ["Rulesets"]
      },
      "post": {
        "operationId": "RulesetController_createRuleset",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRulesetDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Ruleset created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RulesetResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a new ruleset",
        "tags": ["Rulesets"]
      }
    },
    "/organizations/{guildId}/rulesets/event-type-defaults": {
      "get": {
        "operationId": "RulesetController_listEventTypeDefaults",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Event type defaults",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EventTypeDefaultResponseDto"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List event type defaults",
        "tags": ["Rulesets"]
      }
    },
    "/organizations/{guildId}/rulesets/event-type-defaults/{eventType}": {
      "patch": {
        "operationId": "RulesetController_setEventTypeDefault",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "eventType",
            "required": true,
            "in": "path",
            "description": "Event type",
            "schema": {
              "enum": ["raid", "dungeon", "social", "pvp", "holiday"],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetEventTypeDefaultDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default set",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventTypeDefaultResponseDto"
                }
              }
            }
          },
          "404": {
            "description": "Ruleset not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Set default ruleset for an event type",
        "tags": ["Rulesets"]
      },
      "delete": {
        "operationId": "RulesetController_clearEventTypeDefault",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "eventType",
            "required": true,
            "in": "path",
            "description": "Event type",
            "schema": {
              "enum": ["raid", "dungeon", "social", "pvp", "holiday"],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Default cleared"
          },
          "404": {
            "description": "No default set"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Clear default ruleset for an event type",
        "tags": ["Rulesets"]
      }
    },
    "/organizations/{guildId}/rulesets/{id}": {
      "get": {
        "operationId": "RulesetController_getRuleset",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Ruleset UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ruleset details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RulesetResponseDto"
                }
              }
            }
          },
          "404": {
            "description": "Ruleset not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get a single ruleset",
        "tags": ["Rulesets"]
      },
      "patch": {
        "operationId": "RulesetController_updateRuleset",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Ruleset UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRulesetDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ruleset updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RulesetResponseDto"
                }
              }
            }
          },
          "404": {
            "description": "Ruleset not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a ruleset",
        "tags": ["Rulesets"]
      },
      "delete": {
        "operationId": "RulesetController_archiveRuleset",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Ruleset UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ruleset archived"
          },
          "404": {
            "description": "Ruleset not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Archive a ruleset",
        "tags": ["Rulesets"]
      }
    },
    "/organizations/{guildId}/rulesets/{id}/variants": {
      "post": {
        "operationId": "RulesetController_createVariant",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Ruleset UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRulesetVariantDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Variant created"
          },
          "404": {
            "description": "Ruleset not found"
          },
          "409": {
            "description": "Variant already exists"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Add a participant category variant to a ruleset",
        "tags": ["Rulesets"]
      }
    },
    "/organizations/{guildId}/rulesets/{id}/variants/{variantId}": {
      "patch": {
        "operationId": "RulesetController_updateVariant",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Ruleset UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "variantId",
            "required": true,
            "in": "path",
            "description": "Variant UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRulesetVariantDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Variant updated"
          },
          "404": {
            "description": "Ruleset or variant not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a ruleset variant",
        "tags": ["Rulesets"]
      },
      "delete": {
        "operationId": "RulesetController_deleteVariant",
        "parameters": [
          {
            "name": "guildId",
            "required": true,
            "in": "path",
            "description": "Organization UUID or alias",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Ruleset UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "variantId",
            "required": true,
            "in": "path",
            "description": "Variant UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Variant deleted"
          },
          "404": {
            "description": "Ruleset or variant not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a ruleset variant",
        "tags": ["Rulesets"]
      }
    },
    "/events/{eventId}/applicable-rules": {
      "get": {
        "operationId": "EventRulesetController_getApplicableRules",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "description": "Event UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Applicable rules",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplicableRulesResponseDto"
                }
              }
            }
          },
          "404": {
            "description": "Event not found"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get applicable loot rules for an event and current user",
        "tags": ["Events"]
      }
    },
    "/upload/content-image": {
      "post": {
        "operationId": "UploadController_uploadContentImage",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Image uploaded, returns URL"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Upload a content image for use in rich text editors",
        "tags": ["Upload"]
      }
    },
    "/content-blocks": {
      "get": {
        "operationId": "ContentBlockReadController_listAll",
        "parameters": [],
        "responses": {
          "200": {
            "description": "All content blocks"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all content blocks",
        "tags": ["Content Blocks"]
      }
    },
    "/admin/content-blocks": {
      "get": {
        "operationId": "ContentBlockAdminController_listAll",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List all content blocks (admin)",
        "tags": ["Content Blocks (Admin)"]
      },
      "post": {
        "operationId": "ContentBlockAdminController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContentBlockDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Block created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Create a content block",
        "tags": ["Content Blocks (Admin)"]
      }
    },
    "/admin/content-blocks/{id}": {
      "get": {
        "operationId": "ContentBlockAdminController_findById",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get a single content block",
        "tags": ["Content Blocks (Admin)"]
      },
      "patch": {
        "operationId": "ContentBlockAdminController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContentBlockDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a content block",
        "tags": ["Content Blocks (Admin)"]
      },
      "delete": {
        "operationId": "ContentBlockAdminController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Delete a content block",
        "tags": ["Content Blocks (Admin)"]
      }
    },
    "/wishlist": {
      "get": {
        "operationId": "WishlistController_list",
        "parameters": [
          {
            "name": "characterId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "instanceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List current user wishlist items",
        "tags": ["Wishlist"]
      },
      "post": {
        "operationId": "WishlistController_add",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddWishlistItemDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Add an item to the wishlist",
        "tags": ["Wishlist"]
      }
    },
    "/wishlist/bulk": {
      "post": {
        "operationId": "WishlistController_bulkAdd",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkAddDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Bulk add items to the wishlist",
        "tags": ["Wishlist"]
      }
    },
    "/wishlist/check": {
      "post": {
        "operationId": "WishlistController_bulkCheck",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCheckDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Check which items are on the wishlist",
        "tags": ["Wishlist"]
      }
    },
    "/wishlist/{id}": {
      "patch": {
        "operationId": "WishlistController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Wishlist item ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWishlistItemDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Update a wishlist item",
        "tags": ["Wishlist"]
      },
      "delete": {
        "operationId": "WishlistController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Wishlist item ID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove a wishlist item by ID",
        "tags": ["Wishlist"]
      }
    },
    "/wishlist/item/{itemId}": {
      "delete": {
        "operationId": "WishlistController_removeByItem",
        "parameters": [
          {
            "name": "itemId",
            "required": true,
            "in": "path",
            "description": "Blizzard item ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "characterId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove a wishlist item by item ID",
        "tags": ["Wishlist"]
      }
    },
    "/wishlist/event/{eventId}": {
      "get": {
        "operationId": "WishlistController_getEventDemand",
        "parameters": [
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "instanceIds",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Get wishlist demand for an event",
        "tags": ["Wishlist"]
      }
    },
    "/friendships/search-users": {
      "get": {
        "operationId": "FriendshipController_search",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Search for users to friend (annotated with relation)",
        "tags": ["Friendships"]
      }
    },
    "/friendships/requests": {
      "post": {
        "operationId": "FriendshipController_sendRequest",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendFriendRequestDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Friend request created"
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Send a friend request",
        "tags": ["Friendships"]
      },
      "get": {
        "operationId": "FriendshipController_listRequests",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "type": "integer"
            }
          },
          {
            "name": "direction",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["incoming", "outgoing"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List pending friend requests",
        "tags": ["Friendships"]
      }
    },
    "/friendships/requests/{id}/accept": {
      "patch": {
        "operationId": "FriendshipController_acceptRequest",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Friendship UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptFriendRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Accept a friend request",
        "tags": ["Friendships"]
      }
    },
    "/friendships/requests/{id}/decline": {
      "patch": {
        "operationId": "FriendshipController_declineRequest",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Friendship UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Decline a friend request",
        "tags": ["Friendships"]
      }
    },
    "/friendships/requests/{id}": {
      "delete": {
        "operationId": "FriendshipController_cancelRequest",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Friendship UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Cancel an outgoing friend request",
        "tags": ["Friendships"]
      }
    },
    "/friendships": {
      "get": {
        "operationId": "FriendshipController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List confirmed friends",
        "tags": ["Friendships"]
      }
    },
    "/friendships/{id}": {
      "delete": {
        "operationId": "FriendshipController_unfriend",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Friendship UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Unfriend",
        "tags": ["Friendships"]
      }
    },
    "/blocks": {
      "post": {
        "operationId": "FriendshipController_blockUser",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BlockUserDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Block a user",
        "tags": ["Friendships"]
      },
      "get": {
        "operationId": "FriendshipController_list_blocks",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "List blocked users",
        "tags": ["Friendships"]
      }
    },
    "/blocks/{id}": {
      "delete": {
        "operationId": "FriendshipController_unblockUser",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Block UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "session": []
          }
        ],
        "summary": "Remove a block",
        "tags": ["Friendships"]
      }
    },
    "/test/auth": {
      "post": {
        "operationId": "TestController_generateTestToken",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateTokenDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/users": {
      "post": {
        "operationId": "TestController_createTestUser",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTestUserDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/guilds": {
      "post": {
        "operationId": "TestController_createTestGuild",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTestGuildDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/events": {
      "post": {
        "operationId": "TestController_createTestEvent",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTestEventDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/participations": {
      "post": {
        "operationId": "TestController_createTestParticipation",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTestParticipationDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/clear-data": {
      "delete": {
        "operationId": "TestController_clearTestData",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/notifications/send": {
      "post": {
        "operationId": "TestController_sendTestNotification",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/notifications/push": {
      "post": {
        "operationId": "TestController_sendTestPush",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    },
    "/test/notifications/full": {
      "post": {
        "operationId": "TestController_sendFullTestNotification",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "tags": ["Test"]
      }
    }
  },
  "info": {
    "title": "Sanctum API",
    "description": "REST API for the Sanctum guild management platform. Manages organizations, events, memberships, characters, and more.",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [
    {
      "url": "http://localhost:3001/api/v1",
      "description": "Local dev"
    }
  ],
  "components": {
    "securitySchemes": {
      "session": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {
      "UpdateMeDto": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string",
            "minLength": 2,
            "maxLength": 32
          },
          "image": {
            "type": "string",
            "maxLength": 2048,
            "nullable": true
          },
          "anonymizePublicEvents": {
            "type": "boolean"
          },
          "publicCrafterProfile": {
            "type": "boolean"
          },
          "preferredLocale": {
            "type": "string",
            "enum": ["en", "de", "es", "fr", "pt", "zh-CN", "pseudo"]
          }
        },
        "additionalProperties": false
      },
      "RequestEmailChangeDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          }
        },
        "required": ["email"],
        "additionalProperties": false
      },
      "VerifyEmailDto": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "minLength": 1
          }
        },
        "required": ["token"],
        "additionalProperties": false
      },
      "CreateOrganizationDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "type": {
            "type": "string",
            "enum": ["guild", "team", "community", "friend_group"]
          },
          "alias": {
            "type": "string",
            "pattern": "^[a-z0-9-]+$"
          },
          "description": {
            "type": "string"
          },
          "avatarUrl": {
            "type": "string"
          },
          "settings": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": ["name", "type"],
        "additionalProperties": false
      },
      "UpdateOrganizationDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "alias": {
            "type": "string",
            "pattern": "^[a-z0-9-]+$"
          },
          "description": {
            "type": "string"
          },
          "avatarUrl": {
            "type": "string"
          },
          "settings": {
            "type": "object",
            "additionalProperties": {}
          },
          "discordServerId": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "SyncGuildDto": {
        "type": "object",
        "properties": {
          "types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["roster", "crest"]
            }
          }
        },
        "additionalProperties": false
      },
      "CreateManualCharacterDto": {
        "type": "object",
        "properties": {
          "template": {
            "type": "string",
            "enum": [
              "wow",
              "wow_classic",
              "wow_tbc",
              "wow_wrath",
              "wow_cata",
              "wow_mop",
              "wow_wod",
              "wow_legion",
              "wow_bfa",
              "wow_sl",
              "wow_dragonflight",
              "wow_classic_era",
              "wow_tbc_era",
              "wow_wrath_era",
              "wow_cata_era",
              "wow_mop_era",
              "wow_wod_era",
              "wow_bfa_era",
              "wow_sl_era",
              "wow_dragonflight_era",
              "ffxiv",
              "gw2",
              "custom"
            ]
          },
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 50
          },
          "realm": {
            "type": "string",
            "minLength": 2,
            "maxLength": 50
          },
          "faction": {
            "type": "string",
            "enum": ["alliance", "horde"]
          },
          "characterClass": {
            "type": "string",
            "minLength": 2,
            "maxLength": 50
          },
          "race": {
            "type": "string",
            "minLength": 2,
            "maxLength": 50
          },
          "level": {
            "type": "integer",
            "minimum": 1,
            "maximum": 999
          },
          "attributes": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": ["name", "characterClass", "race", "level"],
        "additionalProperties": false
      },
      "CreateMembershipDto": {
        "type": "object",
        "properties": {
          "characterId": {
            "type": "string"
          },
          "roleId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["trial", "active", "benched", "removed"]
          }
        },
        "required": ["characterId", "roleId", "status"],
        "additionalProperties": false
      },
      "UpdateMembershipDto": {
        "type": "object",
        "properties": {
          "roleId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["trial", "active", "benched", "removed"]
          }
        },
        "additionalProperties": false
      },
      "CreateMembershipNoteDto": {
        "type": "object",
        "properties": {
          "content": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": ["content"],
        "additionalProperties": false
      },
      "UpdateMembershipNoteDto": {
        "type": "object",
        "properties": {
          "content": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": ["content"],
        "additionalProperties": false
      },
      "CreatePostDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "content": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": ["doc"]
              }
            },
            "required": ["type"],
            "additionalProperties": {}
          },
          "excerpt": {
            "type": "string",
            "maxLength": 500
          },
          "slug": {
            "type": "string",
            "maxLength": 120,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": ["draft", "published"]
          },
          "visibility": {
            "type": "string",
            "enum": ["public", "members", "officers"]
          },
          "draftVisibility": {
            "type": "string",
            "enum": ["creator", "officers", "specific"]
          },
          "draftVisibleTo": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": ["title", "content"],
        "additionalProperties": false
      },
      "UpdatePostDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "content": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": ["doc"]
              }
            },
            "required": ["type"],
            "additionalProperties": {}
          },
          "excerpt": {
            "type": "string",
            "maxLength": 500
          },
          "slug": {
            "type": "string",
            "maxLength": 120,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": ["draft", "published"]
          },
          "visibility": {
            "type": "string",
            "enum": ["public", "members", "officers"]
          },
          "draftVisibility": {
            "type": "string",
            "enum": ["creator", "officers", "specific"]
          },
          "draftVisibleTo": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "UpdateDiscordRankRoleMappingsDto": {
        "type": "object",
        "properties": {
          "discordRoleIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": ["discordRoleIds"],
        "additionalProperties": false
      },
      "ClearDiscordRankSuppressionsDto": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "clearAll": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "UpdatePreferencesDto": {
        "type": "object",
        "properties": {
          "organizationId": {
            "type": "string"
          },
          "preferences": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "event_published",
                    "event_updated",
                    "event_starting_soon",
                    "event_cancelled",
                    "signup_invited",
                    "signup_confirmed",
                    "signup_waitlisted",
                    "signup_benched",
                    "application_submitted",
                    "application_reviewed",
                    "membership_role_changed",
                    "membership_removed",
                    "battlenet_token_expired"
                  ]
                },
                "channel": {
                  "type": "string",
                  "enum": ["in_app", "email", "web_push"]
                },
                "enabled": {
                  "type": "boolean"
                }
              },
              "required": ["type", "channel", "enabled"],
              "additionalProperties": false
            }
          }
        },
        "required": ["preferences"],
        "additionalProperties": false
      },
      "CreateRoleDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "wowRank": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9
          },
          "permissions": {
            "type": "object",
            "properties": {
              "canManageGuild": {
                "type": "boolean"
              },
              "canManageMembers": {
                "type": "boolean"
              },
              "canManageEvents": {
                "type": "boolean"
              },
              "canViewAttendance": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          }
        },
        "required": ["name"],
        "additionalProperties": false
      },
      "UpdateRoleDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "wowRank": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9
          },
          "permissions": {
            "type": "object",
            "properties": {
              "canManageGuild": {
                "type": "boolean"
              },
              "canManageMembers": {
                "type": "boolean"
              },
              "canManageEvents": {
                "type": "boolean"
              },
              "canViewAttendance": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "UpdateRolePermissionsDto": {
        "type": "object",
        "properties": {
          "canManageGuild": {
            "type": "boolean"
          },
          "canManageMembers": {
            "type": "boolean"
          },
          "canManageEvents": {
            "type": "boolean"
          },
          "canViewAttendance": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "CreateEventDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": ["raid", "dungeon", "social", "pvp", "holiday"]
          },
          "scope": {
            "type": "string",
            "enum": ["members", "group"]
          },
          "visibility": {
            "type": "string",
            "enum": ["public", "unlisted", "members", "invite_only"]
          },
          "description": {
            "type": "string"
          },
          "gameKey": {
            "type": "string"
          },
          "scheduledAt": {
            "type": "string"
          },
          "endsAt": {
            "type": "string"
          },
          "durationMinutes": {
            "type": "number"
          },
          "isAllDay": {
            "type": "boolean"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {}
          },
          "discordRoleId": {
            "type": "string"
          },
          "discordChannelId": {
            "type": "string"
          },
          "discordAnnounce": {
            "type": "boolean"
          },
          "discordScheduledEvent": {
            "type": "boolean"
          },
          "discordVoiceChannelId": {
            "type": "string"
          },
          "imageUrl": {
            "type": "string"
          },
          "signupMode": {
            "type": "string",
            "enum": ["enroll", "waitlist", "interest"]
          },
          "slots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "roleKey": {
                  "type": "string"
                },
                "maxCount": {
                  "type": "number"
                }
              },
              "required": ["roleKey", "maxCount"],
              "additionalProperties": false
            }
          },
          "recurrence": {
            "type": "object",
            "properties": {
              "count": {
                "type": "number",
                "minimum": 2,
                "maximum": 52
              },
              "interval": {
                "type": "string",
                "enum": ["weekly", "biweekly"]
              }
            },
            "required": ["count", "interval"],
            "additionalProperties": false
          },
          "activities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "enum": ["raid", "dungeon", "pvp", "social"]
                },
                "activityType": {
                  "type": "string"
                },
                "difficulty": {
                  "type": "string"
                },
                "instanceId": {
                  "type": "string"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": ["category", "sortOrder"],
              "additionalProperties": false
            }
          },
          "groupCompId": {
            "type": "string"
          },
          "requiresCharacter": {
            "type": "boolean"
          },
          "creatorOnly": {
            "type": "boolean"
          },
          "lootRulesetId": {
            "type": "string",
            "nullable": true
          }
        },
        "required": ["title", "type", "scheduledAt"],
        "additionalProperties": false
      },
      "UpdateEventDto": {
        "type": "object",
        "properties": {
          "alias": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": ["raid", "dungeon", "social", "pvp", "holiday"]
          },
          "scope": {
            "type": "string",
            "enum": ["members", "group"]
          },
          "visibility": {
            "type": "string",
            "enum": ["public", "unlisted", "members", "invite_only"]
          },
          "description": {
            "type": "string"
          },
          "gameKey": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["draft", "published", "active", "cancelled", "completed"]
          },
          "scheduledAt": {
            "type": "string"
          },
          "endsAt": {
            "type": "string",
            "nullable": true
          },
          "durationMinutes": {
            "type": "number"
          },
          "isAllDay": {
            "type": "boolean"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {}
          },
          "discordRoleId": {
            "type": "string"
          },
          "discordChannelId": {
            "type": "string"
          },
          "discordAnnounce": {
            "type": "boolean"
          },
          "discordScheduledEvent": {
            "type": "boolean"
          },
          "discordVoiceChannelId": {
            "type": "string",
            "nullable": true
          },
          "imageUrl": {
            "type": "string"
          },
          "signupMode": {
            "type": "string",
            "enum": ["enroll", "waitlist", "interest"]
          },
          "slots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "roleKey": {
                  "type": "string"
                },
                "maxCount": {
                  "type": "number"
                }
              },
              "required": ["roleKey", "maxCount"],
              "additionalProperties": false
            }
          },
          "activities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "enum": ["raid", "dungeon", "pvp", "social"]
                },
                "activityType": {
                  "type": "string"
                },
                "difficulty": {
                  "type": "string"
                },
                "instanceId": {
                  "type": "string"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": ["category", "sortOrder"],
              "additionalProperties": false
            }
          },
          "groupCompId": {
            "type": "string",
            "nullable": true
          },
          "requiresCharacter": {
            "type": "boolean"
          },
          "creatorOnly": {
            "type": "boolean"
          },
          "lootRulesetId": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DelayEventDto": {
        "type": "object",
        "properties": {
          "minutes": {
            "type": "number",
            "minimum": 1,
            "maximum": 240
          },
          "preserveEndTime": {
            "type": "boolean"
          }
        },
        "required": ["minutes"],
        "additionalProperties": false
      },
      "InviteDto": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "characterId": {
            "type": "string"
          },
          "membershipId": {
            "type": "string"
          },
          "roleKey": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "SignupDto": {
        "type": "object",
        "properties": {
          "roleKey": {
            "type": "string"
          },
          "specName": {
            "type": "string"
          },
          "characterId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "anonymize": {
            "type": "boolean"
          },
          "tentative": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "UpdateMySignupDto": {
        "type": "object",
        "properties": {
          "characterId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "roleKey": {
            "type": "string"
          },
          "specName": {
            "type": "string"
          },
          "anonymize": {
            "type": "boolean"
          },
          "tentative": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "RecordAttendanceDto": {
        "type": "object",
        "properties": {
          "participations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "userId": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[A-Za-z0-9_-]+$"
                },
                "attended": {
                  "type": "boolean"
                },
                "notes": {
                  "type": "string"
                }
              },
              "required": ["userId", "attended"],
              "additionalProperties": false
            }
          }
        },
        "required": ["participations"],
        "additionalProperties": false
      },
      "UpdateParticipationStatusDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "confirmed",
              "waitlist",
              "tentative",
              "attended",
              "benched",
              "absent"
            ]
          },
          "characterId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "roleKey": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "ConfirmAttendanceDto": {
        "type": "object",
        "properties": {
          "attendees": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "userId": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[A-Za-z0-9_-]+$"
                },
                "characterId": {
                  "type": "string"
                },
                "guest": {
                  "type": "boolean"
                },
                "benched": {
                  "type": "boolean"
                }
              },
              "required": ["userId"],
              "additionalProperties": false
            }
          },
          "absentees": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          }
        },
        "required": ["attendees"],
        "additionalProperties": false
      },
      "UpdateMediaAssetDto": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string"
          },
          "folder": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "CreateAdminHolidayDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "alias": {
            "type": "string",
            "nullable": true
          },
          "scheduledAt": {
            "type": "string"
          },
          "endsAt": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string"
          },
          "imageUrl": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["draft", "published", "active", "cancelled", "completed"]
          }
        },
        "required": ["title", "scheduledAt"],
        "additionalProperties": false
      },
      "UpdateAdminUserDto": {
        "type": "object",
        "properties": {
          "isAdmin": {
            "type": "boolean"
          },
          "anonymizePublicEvents": {
            "type": "boolean"
          },
          "displayName": {
            "type": "string",
            "maxLength": 64
          }
        },
        "additionalProperties": false
      },
      "UnlinkAccountDto": {
        "type": "object",
        "properties": {
          "providerId": {
            "type": "string",
            "enum": ["discord", "battlenet"]
          }
        },
        "required": ["providerId"],
        "additionalProperties": false
      },
      "CreateAdminUserNoteDto": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          }
        },
        "required": ["content"],
        "additionalProperties": false
      },
      "UpdateAdminUserNoteDto": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          }
        },
        "required": ["content"],
        "additionalProperties": false
      },
      "SubmitApplicationDto": {
        "type": "object",
        "properties": {
          "characterId": {
            "type": "string"
          },
          "referredByMemberId": {
            "type": "string"
          },
          "answers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "questionId": {
                  "type": "string"
                },
                "answer": {
                  "type": "string"
                }
              },
              "required": ["questionId", "answer"],
              "additionalProperties": false
            }
          }
        },
        "required": ["answers"],
        "additionalProperties": false
      },
      "ReviewApplicationDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": ["accepted", "rejected"]
          },
          "notes": {
            "type": "string"
          }
        },
        "required": ["status"],
        "additionalProperties": false
      },
      "UpdateApplicationFormDto": {
        "type": "object",
        "properties": {
          "isEnabled": {
            "type": "boolean"
          },
          "questions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": ["text", "textarea", "select", "boolean", "date"]
                },
                "options": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "required": {
                  "type": "boolean"
                }
              },
              "required": ["id", "label", "type", "required"],
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "CreateCraftingRequestDto": {
        "type": "object",
        "properties": {
          "recipeId": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "recipeName": {
            "type": "string"
          },
          "professionName": {
            "type": "string"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "urgency": {
            "type": "string",
            "enum": ["LOW", "NORMAL", "HIGH"]
          },
          "note": {
            "type": "string"
          },
          "characterId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": ["recipeName"],
        "additionalProperties": false
      },
      "ClaimCraftingRequestDto": {
        "type": "object",
        "properties": {
          "membershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "additionalProperties": false
      },
      "CreateGroupCompDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "visibility": {
            "type": "string",
            "enum": ["personal", "guild"]
          },
          "members": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "characterId": {
                  "type": "string"
                },
                "roleOverride": {
                  "type": "string",
                  "enum": ["tank", "healer", "dps", null],
                  "nullable": true
                },
                "specOverride": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": ["characterId"],
              "additionalProperties": false
            }
          }
        },
        "required": ["name"],
        "additionalProperties": false
      },
      "UpdateGroupCompDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "visibility": {
            "type": "string",
            "enum": ["personal", "guild"]
          },
          "members": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "characterId": {
                  "type": "string"
                },
                "roleOverride": {
                  "type": "string",
                  "enum": ["tank", "healer", "dps", null],
                  "nullable": true
                },
                "specOverride": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": ["characterId"],
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "CreateHelpArticleDto": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "maxLength": 200,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "helpKey": {
            "type": "string",
            "maxLength": 100
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "summary": {
            "type": "string",
            "maxLength": 500
          },
          "content": {
            "type": "object",
            "additionalProperties": {}
          },
          "category": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "published": {
            "type": "boolean"
          },
          "visibility": {
            "type": "string",
            "enum": ["PUBLIC", "ADMIN"]
          }
        },
        "required": ["slug", "title", "content", "category"],
        "additionalProperties": false
      },
      "UpdateHelpArticleDto": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "maxLength": 200,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "helpKey": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "title": {
            "type": "string",
            "maxLength": 300
          },
          "summary": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          },
          "content": {
            "type": "object",
            "additionalProperties": {}
          },
          "category": {
            "type": "string",
            "maxLength": 100
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "published": {
            "type": "boolean"
          },
          "visibility": {
            "type": "string",
            "enum": ["PUBLIC", "ADMIN"]
          }
        },
        "additionalProperties": false
      },
      "CreateHelpTemplateDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "content": {
            "type": "object",
            "additionalProperties": {}
          },
          "category": {
            "type": "string",
            "maxLength": 100
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": ["name", "content"],
        "additionalProperties": false
      },
      "UpdateHelpTemplateDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          },
          "content": {
            "type": "object",
            "additionalProperties": {}
          },
          "category": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "additionalProperties": false
      },
      "RulesetVariantResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "participantCategory": {
            "type": "string",
            "enum": ["member_trial", "member_active", "member_benched", "guest"]
          },
          "descriptionOverride": {
            "type": "object"
          },
          "rulesOverride": {
            "type": "object"
          }
        },
        "required": ["id", "participantCategory"]
      },
      "RulesetResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "organizationId": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": ["loot"]
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "object"
          },
          "rules": {
            "type": "object"
          },
          "isArchived": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "createdBy": {
            "type": "string"
          },
          "updatedBy": {
            "type": "object"
          },
          "variants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RulesetVariantResponseDto"
            }
          }
        },
        "required": [
          "id",
          "organizationId",
          "type",
          "name",
          "isArchived",
          "createdAt",
          "updatedAt",
          "createdBy"
        ]
      },
      "EventTypeDefaultResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "organizationId": {
            "type": "string"
          },
          "eventType": {
            "type": "string",
            "enum": ["raid", "dungeon", "social", "pvp", "holiday"]
          },
          "rulesetId": {
            "type": "string"
          },
          "ruleset": {
            "$ref": "#/components/schemas/RulesetResponseDto"
          }
        },
        "required": ["id", "organizationId", "eventType", "rulesetId"]
      },
      "SetEventTypeDefaultDto": {
        "type": "object",
        "properties": {
          "rulesetId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": ["rulesetId"],
        "additionalProperties": false
      },
      "CreateRulesetDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "description": {
            "type": "object",
            "additionalProperties": {}
          },
          "rules": {
            "type": "object",
            "additionalProperties": {}
          },
          "type": {
            "type": "string",
            "enum": ["loot"]
          }
        },
        "required": ["name"],
        "additionalProperties": false
      },
      "UpdateRulesetDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "object",
            "additionalProperties": {}
          },
          "rules": {
            "type": "object",
            "additionalProperties": {}
          },
          "isArchived": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "CreateRulesetVariantDto": {
        "type": "object",
        "properties": {
          "participantCategory": {
            "type": "string",
            "enum": ["member_trial", "member_active", "member_benched", "guest"]
          },
          "descriptionOverride": {
            "type": "object",
            "additionalProperties": {}
          },
          "rulesOverride": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": ["participantCategory"],
        "additionalProperties": false
      },
      "UpdateRulesetVariantDto": {
        "type": "object",
        "properties": {
          "descriptionOverride": {
            "type": "object",
            "additionalProperties": {}
          },
          "rulesOverride": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "additionalProperties": false
      },
      "ApplicableRulesResponseDto": {
        "type": "object",
        "properties": {
          "ruleset": {
            "$ref": "#/components/schemas/RulesetResponseDto"
          },
          "variant": {
            "$ref": "#/components/schemas/RulesetVariantResponseDto"
          },
          "participantCategory": {
            "type": "string",
            "enum": ["member_trial", "member_active", "member_benched", "guest"]
          },
          "source": {
            "type": "string",
            "description": "How the ruleset was resolved"
          }
        },
        "required": ["participantCategory", "source"]
      },
      "CreateContentBlockDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "content": {},
          "category": {
            "type": "string",
            "maxLength": 100
          },
          "icon": {
            "type": "string",
            "maxLength": 50
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": ["name", "content"],
        "additionalProperties": false
      },
      "UpdateContentBlockDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          },
          "content": {},
          "category": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "icon": {
            "type": "string",
            "maxLength": 50,
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "additionalProperties": false
      },
      "AddWishlistItemDto": {
        "type": "object",
        "properties": {
          "itemId": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "characterId": {
            "type": "string"
          },
          "encounterId": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "instanceId": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "priority": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5
          },
          "notes": {
            "type": "string",
            "maxLength": 500
          }
        },
        "required": ["itemId"],
        "additionalProperties": false
      },
      "BulkAddDto": {
        "type": "object",
        "properties": {
          "items": {
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "itemId": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "characterId": {
                  "type": "string"
                },
                "encounterId": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "instanceId": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "priority": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 5
                },
                "notes": {
                  "type": "string",
                  "maxLength": 500
                }
              },
              "required": ["itemId"],
              "additionalProperties": false
            }
          }
        },
        "required": ["items"],
        "additionalProperties": false
      },
      "BulkCheckDto": {
        "type": "object",
        "properties": {
          "itemIds": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        },
        "required": ["itemIds"],
        "additionalProperties": false
      },
      "UpdateWishlistItemDto": {
        "type": "object",
        "properties": {
          "characterId": {
            "type": "string",
            "nullable": true
          },
          "priority": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5
          },
          "notes": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SendFriendRequestDto": {
        "type": "object",
        "properties": {
          "addresseeId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "asCharacterId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "message": {
            "type": "string",
            "maxLength": 500
          }
        },
        "required": ["addresseeId"],
        "additionalProperties": false
      },
      "AcceptFriendRequestDto": {
        "type": "object",
        "properties": {
          "asCharacterId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "additionalProperties": false
      },
      "BlockUserDto": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "reason": {
            "type": "string",
            "maxLength": 500
          }
        },
        "required": ["userId"],
        "additionalProperties": false
      },
      "GenerateTokenDto": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "username": {
            "type": "string"
          },
          "battleNetId": {
            "type": "string"
          }
        },
        "required": ["userId"],
        "additionalProperties": false
      },
      "CreateTestUserDto": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string"
          },
          "battleNetId": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "CreateTestGuildDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "realm": {
            "type": "string"
          },
          "faction": {
            "type": "string",
            "enum": ["alliance", "horde"]
          },
          "syncSource": {
            "type": "string",
            "enum": ["standalone", "blizzard"]
          },
          "userId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          }
        },
        "additionalProperties": false
      },
      "CreateTestEventDto": {
        "type": "object",
        "properties": {
          "organizationId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "createdById": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": ["raid", "dungeon", "social", "pvp", "holiday"]
          },
          "status": {
            "type": "string",
            "enum": ["draft", "published", "active", "completed", "cancelled"]
          },
          "visibility": {
            "type": "string",
            "enum": ["public", "unlisted", "members", "invite_only"]
          },
          "scheduledAt": {
            "type": "string"
          },
          "requiresCharacter": {
            "type": "boolean"
          }
        },
        "required": ["organizationId", "createdById"],
        "additionalProperties": false
      },
      "CreateTestParticipationDto": {
        "type": "object",
        "properties": {
          "eventId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "userId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "status": {
            "type": "string",
            "enum": [
              "invited",
              "confirmed",
              "waitlist",
              "interested",
              "declined",
              "attended",
              "benched",
              "absent"
            ]
          },
          "roleKey": {
            "type": "string"
          },
          "characterId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": ["eventId", "userId"],
        "additionalProperties": false
      }
    }
  }
}
