{
  "openapi": "3.0.3",
  "info": {
    "title": "CampNow – Admin Campsite Modules",
    "description": "Two admin modules:\n\n**Module 1 – Campsite Owners** (`/admin/campsite-owners`): Admin creates an operator account. Owner receives a temporary password by email. Account stays **disabled** until the admin creates at least one campsite for them.\n\n**Module 2 – Campsites** (`/admin/campsites`): Admin creates campsites and assigns them to an owner via `userId`. On the **first** campsite creation the owner account is automatically **activated**.\n\n### Login flow for campsite owners\n1. Owner tries to login → `403` if no campsite yet (pending setup)\n2. After first campsite created → login succeeds, response includes `requiresPasswordReset: true`\n3. Owner calls `POST /api/auth/change-password` → `isPasswordReset` flips to `true`\n4. Subsequent logins → `requiresPasswordReset: false` → normal session\n\n**Auth:** All endpoints require `Authorization: Bearer <admin-jwt>`",
    "version": "1.0.0"
  },
  "servers": [
    { "url": "{{baseUrl}}", "description": "Environment base URL" }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }
    },
    "schemas": {
      "Location": {
        "type": "object",
        "properties": {
          "latitude":  { "type": "number",  "example": 48.1351 },
          "longitude": { "type": "number",  "example": 11.582 },
          "address":   { "type": "string",  "example": "Musterstraße 1, 80331 München" }
        }
      },
      "Completeness": {
        "type": "object",
        "properties": {
          "isProfileComplete":    { "type": "boolean", "example": false },
          "completionPercentage": { "type": "integer", "example": 33 },
          "missingFields": {
            "type": "array",
            "items": { "type": "string" },
            "example": ["description", "coverImageUrl", "location.latitude"]
          },
          "redirectBehaviour": {
            "type": "string",
            "enum": ["detail-page", "external-website", "hidden"],
            "example": "hidden"
          },
          "websiteLink": { "type": "string", "nullable": true, "example": null }
        }
      },
      "CampsiteOwner": {
        "type": "object",
        "properties": {
          "id":              { "type": "string",  "example": "664f1a2b3c4d5e6f7a8b9c01" },
          "firstName":       { "type": "string",  "example": "Klaus" },
          "lastName":        { "type": "string",  "example": "Müller" },
          "email":           { "type": "string",  "example": "k.mueller@campsite.de" },
          "mobile":          { "type": "string",  "nullable": true, "example": "+49 170 1234567" },
          "isDisabled":      { "type": "boolean", "example": true,  "description": "true = account pending first campsite setup" },
          "isPasswordReset": { "type": "boolean", "example": false, "description": "false = owner must reset temp password on first login" },
          "createdAt":       { "type": "string",  "format": "date-time" },
          "updatedAt":       { "type": "string",  "format": "date-time" }
        }
      },
      "CampsiteOwnerSummary": {
        "type": "object",
        "properties": {
          "id":        { "type": "string", "example": "664f1a2b3c4d5e6f7a8b9c01" },
          "firstName": { "type": "string", "example": "Klaus" },
          "lastName":  { "type": "string", "example": "Müller" },
          "email":     { "type": "string", "example": "k.mueller@campsite.de" },
          "mobile":    { "type": "string", "nullable": true, "example": "+49 170 1234567" },
          "isDisabled": { "type": "boolean", "example": false }
        }
      },
      "Campsite": {
        "type": "object",
        "properties": {
          "id":            { "type": "string",  "example": "664f1a2b3c4d5e6f7a8b9c0d" },
          "userId":        { "type": "string",  "example": "664f1a2b3c4d5e6f7a8b9c01" },
          "owner":         { "$ref": "#/components/schemas/CampsiteOwnerSummary" },
          "name":          { "type": "string",  "nullable": true, "example": "Waldcamp Muster" },
          "email":         { "type": "string",  "nullable": true, "example": "info@waldcamp-muster.de" },
          "description":   { "type": "string",  "nullable": true, "example": "A beautiful forest campsite in Bavaria." },
          "location":      { "$ref": "#/components/schemas/Location" },
          "coverImageUrl": { "type": "string",  "nullable": true, "example": "https://cdn.campnow.com/campsites/upload/cover.jpg" },
          "websiteUrl":    { "type": "string",  "nullable": true, "example": "https://waldcamp-muster.de" },
          "bookingUrl":    { "type": "string",  "nullable": true, "example": "https://waldcamp-muster.de/booking" },
          "membershipDoc": { "type": "string",  "nullable": true, "example": "https://assets.campnow.de/public/media/campsites/documents/1714123456789-membership.pdf" },
          "showOnMap":     { "type": "boolean", "example": true },
          "isActive":      { "type": "boolean", "example": false },
          "completeness":  { "$ref": "#/components/schemas/Completeness" },
          "createdAt":     { "type": "string",  "format": "date-time" },
          "updatedAt":     { "type": "string",  "format": "date-time" }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "total":       { "type": "integer", "example": 42 },
          "totalPages":  { "type": "integer", "example": 5 },
          "currentPage": { "type": "integer", "example": 1 },
          "perPage":     { "type": "integer", "example": 10 },
          "hasNextPage": { "type": "boolean", "example": true },
          "hasPrevPage": { "type": "boolean", "example": false }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "message": { "type": "string",  "example": "Error message" },
          "data":    { "nullable": true,  "example": null },
          "errors":  { "nullable": true,  "example": null }
        }
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "message": { "type": "string",  "example": "Validation Error" },
          "data":    { "nullable": true,  "example": null },
          "errors":  {
            "type": "array",
            "items": { "type": "string" },
            "example": ["First name is required.", "A valid email address is required."]
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid JWT",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": { "success": false, "message": "Unauthorized", "data": null, "errors": null }
          }
        }
      },
      "OwnerNotFound": {
        "description": "Campsite owner not found",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": { "success": false, "message": "Campsite owner not found", "data": null, "errors": null }
          }
        }
      },
      "CampsiteNotFound": {
        "description": "Campsite not found",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": { "success": false, "message": "Campsite not found", "data": null, "errors": null }
          }
        }
      },
      "ServerError": {
        "description": "Internal server error",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": { "success": false, "message": "Server Error", "data": null, "errors": null }
          }
        }
      }
    }
  },
  "security": [{ "bearerAuth": [] }],
  "tags": [
    {
      "name": "Admin – Campsite Owners",
      "description": "Create and manage campsite operator accounts. Owner stays **disabled** until their first campsite is created."
    },
    {
      "name": "Admin – Campsites",
      "description": "Create and manage campsites. Assigning the **first** campsite to an owner auto-activates their account."
    }
  ],
  "paths": {

    "/admin/campsite-owners": {
      "get": {
        "tags": ["Admin – Campsite Owners"],
        "summary": "List all campsite owners",
        "operationId": "adminListCampsiteOwners",
        "parameters": [
          { "name": "page",   "in": "query", "schema": { "type": "integer", "default": 1,  "minimum": 1 } },
          { "name": "limit",  "in": "query", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 } },
          { "name": "search", "in": "query", "description": "Search by first name, last name or email", "schema": { "type": "string" }, "example": "Klaus" }
        ],
        "responses": {
          "200": {
            "description": "Owners retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success":  { "type": "boolean", "example": true },
                    "message":  { "type": "string",  "example": "Campsite owners retrieved successfully" },
                    "data":     { "type": "array", "items": { "$ref": "#/components/schemas/CampsiteOwner" } },
                    "metadata": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                },
                "examples": {
                  "with_results": {
                    "summary": "200 – list with mixed states",
                    "value": {
                      "success": true,
                      "message": "Campsite owners retrieved successfully",
                      "data": [
                        {
                          "id": "664f1a2b3c4d5e6f7a8b9c01",
                          "firstName": "Klaus", "lastName": "Müller",
                          "email": "k.mueller@campsite.de", "mobile": "+49 170 1234567",
                          "isDisabled": false, "isPasswordReset": true,
                          "createdAt": "2025-04-18T08:00:00.000Z", "updatedAt": "2025-04-20T10:00:00.000Z"
                        },
                        {
                          "id": "664f1a2b3c4d5e6f7a8b9c02",
                          "firstName": "Anna", "lastName": "Schmidt",
                          "email": "a.schmidt@campsite.de", "mobile": null,
                          "isDisabled": true, "isPasswordReset": false,
                          "createdAt": "2025-04-20T09:00:00.000Z", "updatedAt": "2025-04-20T09:00:00.000Z"
                        }
                      ],
                      "metadata": { "total": 2, "totalPages": 1, "currentPage": 1, "perPage": 10, "hasNextPage": false, "hasPrevPage": false }
                    }
                  },
                  "empty": {
                    "summary": "200 – empty list",
                    "value": {
                      "success": true, "message": "Campsite owners retrieved successfully",
                      "data": [],
                      "metadata": { "total": 0, "totalPages": 0, "currentPage": 1, "perPage": 10, "hasNextPage": false, "hasPrevPage": false }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "422": {
            "description": "Query validation error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ValidationError" },
                "example": { "success": false, "message": "Validation Error", "data": null, "errors": ["page must be a number"] }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "post": {
        "tags": ["Admin – Campsite Owners"],
        "summary": "Create a campsite owner",
        "operationId": "adminCreateCampsiteOwner",
        "description": "Creates a new campsite operator account.\n- Account is **disabled** (`isDisabled: true`) until first campsite is created\n- A temporary password is generated and sent by email\n- On first login, `requiresPasswordReset: true` is returned",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["firstName", "lastName", "email"],
                "properties": {
                  "firstName": { "type": "string", "example": "Klaus",                 "description": "Required." },
                  "lastName":  { "type": "string", "example": "Müller",               "description": "Required." },
                  "email":     { "type": "string", "example": "k.mueller@campsite.de", "description": "Required. Must be unique." },
                  "mobile":    { "type": "string", "example": "+49 170 1234567",       "description": "Optional." }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Owner created – welcome email sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite owner created successfully. A welcome email has been sent." },
                    "data":    { "$ref": "#/components/schemas/CampsiteOwner" }
                  }
                },
                "example": {
                  "success": true,
                  "message": "Campsite owner created successfully. A welcome email has been sent.",
                  "data": {
                    "id": "664f1a2b3c4d5e6f7a8b9c02",
                    "firstName": "Anna", "lastName": "Schmidt",
                    "email": "a.schmidt@campsite.de", "mobile": null,
                    "isDisabled": true,
                    "isPasswordReset": false,
                    "createdAt": "2025-04-20T09:00:00.000Z",
                    "updatedAt": "2025-04-20T09:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "409": {
            "description": "Email already registered",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "success": false, "message": "An account with this email already exists", "data": null, "errors": null }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ValidationError" },
                "examples": {
                  "missing_fields": {
                    "summary": "422 – missing required fields",
                    "value": { "success": false, "message": "Validation Error", "data": null, "errors": ["First name is required.", "A valid email address is required."] }
                  },
                  "bad_email": {
                    "summary": "422 – invalid email",
                    "value": { "success": false, "message": "Validation Error", "data": null, "errors": ["A valid email address is required."] }
                  }
                }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },

    "/admin/campsite-owners/{id}": {
      "parameters": [
        { "name": "id", "in": "path", "required": true, "description": "Owner MongoDB ObjectId", "schema": { "type": "string", "example": "664f1a2b3c4d5e6f7a8b9c01" } }
      ],
      "get": {
        "tags": ["Admin – Campsite Owners"],
        "summary": "Get owner detail",
        "operationId": "adminGetCampsiteOwner",
        "responses": {
          "200": {
            "description": "Owner retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite owner retrieved successfully" },
                    "data":    { "$ref": "#/components/schemas/CampsiteOwner" }
                  }
                },
                "examples": {
                  "pending_owner": {
                    "summary": "200 – owner pending (no campsite yet)",
                    "value": {
                      "success": true, "message": "Campsite owner retrieved successfully",
                      "data": {
                        "id": "664f1a2b3c4d5e6f7a8b9c02",
                        "firstName": "Anna", "lastName": "Schmidt",
                        "email": "a.schmidt@campsite.de", "mobile": null,
                        "isDisabled": true, "isPasswordReset": false,
                        "createdAt": "2025-04-20T09:00:00.000Z", "updatedAt": "2025-04-20T09:00:00.000Z"
                      }
                    }
                  },
                  "active_owner": {
                    "summary": "200 – active owner (has campsites, password reset)",
                    "value": {
                      "success": true, "message": "Campsite owner retrieved successfully",
                      "data": {
                        "id": "664f1a2b3c4d5e6f7a8b9c01",
                        "firstName": "Klaus", "lastName": "Müller",
                        "email": "k.mueller@campsite.de", "mobile": "+49 170 1234567",
                        "isDisabled": false, "isPasswordReset": true,
                        "createdAt": "2025-04-18T08:00:00.000Z", "updatedAt": "2025-04-20T10:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/OwnerNotFound" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "put": {
        "tags": ["Admin – Campsite Owners"],
        "summary": "Update owner details",
        "operationId": "adminUpdateCampsiteOwner",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "firstName": { "type": "string", "example": "Klaus" },
                  "lastName":  { "type": "string", "example": "Müller-Berg" },
                  "email":     { "type": "string", "example": "k.mueller.berg@campsite.de" },
                  "mobile":    { "type": "string", "example": "+49 171 9876543" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Owner updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite owner updated successfully" },
                    "data":    { "$ref": "#/components/schemas/CampsiteOwner" }
                  }
                },
                "example": {
                  "success": true, "message": "Campsite owner updated successfully",
                  "data": {
                    "id": "664f1a2b3c4d5e6f7a8b9c01",
                    "firstName": "Klaus", "lastName": "Müller-Berg",
                    "email": "k.mueller.berg@campsite.de", "mobile": "+49 171 9876543",
                    "isDisabled": false, "isPasswordReset": true,
                    "createdAt": "2025-04-18T08:00:00.000Z", "updatedAt": "2025-04-20T15:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/OwnerNotFound" },
          "409": {
            "description": "Email already in use by another account",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "success": false, "message": "An account with this email already exists", "data": null, "errors": null }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ValidationError" },
                "example": { "success": false, "message": "Validation Error", "data": null, "errors": ["\"email\" must be a valid email"] }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },

    "/admin/campsite-owners/{id}/status": {
      "parameters": [
        { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "example": "664f1a2b3c4d5e6f7a8b9c01" } }
      ],
      "patch": {
        "tags": ["Admin – Campsite Owners"],
        "summary": "Enable or disable owner account",
        "operationId": "adminToggleCampsiteOwnerStatus",
        "description": "Manually enable (`isDisabled: false`) or disable (`isDisabled: true`) a campsite owner account.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["isDisabled"],
                "properties": {
                  "isDisabled": { "type": "boolean", "example": false, "description": "false = enable, true = disable" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite owner status updated successfully" },
                    "data":    { "$ref": "#/components/schemas/CampsiteOwner" }
                  }
                },
                "examples": {
                  "enabled": {
                    "summary": "200 – owner enabled",
                    "value": {
                      "success": true, "message": "Campsite owner status updated successfully",
                      "data": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "mobile": null, "isDisabled": false, "isPasswordReset": false, "createdAt": "2025-04-20T09:00:00.000Z", "updatedAt": "2025-04-20T12:00:00.000Z" }
                    }
                  },
                  "disabled": {
                    "summary": "200 – owner disabled",
                    "value": {
                      "success": true, "message": "Campsite owner status updated successfully",
                      "data": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "mobile": null, "isDisabled": true, "isPasswordReset": true, "createdAt": "2025-04-20T09:00:00.000Z", "updatedAt": "2025-04-20T12:00:00.000Z" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/OwnerNotFound" },
          "422": {
            "description": "isDisabled missing or not a boolean",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ValidationError" },
                "example": { "success": false, "message": "Validation Error", "data": null, "errors": ["isDisabled is required."] }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },

    "/admin/campsites": {
      "get": {
        "tags": ["Admin – Campsites"],
        "summary": "List all campsites (paginated)",
        "operationId": "adminListCampsites",
        "parameters": [
          { "name": "page",     "in": "query", "schema": { "type": "integer", "default": 1,  "minimum": 1 } },
          { "name": "limit",    "in": "query", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 } },
          { "name": "search",   "in": "query", "description": "Search by campsite name or email", "schema": { "type": "string" }, "example": "Waldcamp" },
          { "name": "isActive", "in": "query", "schema": { "type": "string", "enum": ["true","false"] } },
          { "name": "userId",   "in": "query", "description": "Filter by owner ObjectId", "schema": { "type": "string" }, "example": "664f1a2b3c4d5e6f7a8b9c01" }
        ],
        "responses": {
          "200": {
            "description": "Campsites retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success":  { "type": "boolean", "example": true },
                    "message":  { "type": "string",  "example": "Campsites retrieved successfully" },
                    "data":     { "type": "array", "items": { "$ref": "#/components/schemas/Campsite" } },
                    "metadata": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                },
                "examples": {
                  "with_data": {
                    "summary": "200 – with results",
                    "value": {
                      "success": true, "message": "Campsites retrieved successfully",
                      "data": [
                        {
                          "id": "664f1a2b3c4d5e6f7a8b9c0d",
                          "userId": "664f1a2b3c4d5e6f7a8b9c01",
                          "owner": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "mobile": "+49 170 1234567", "isDisabled": false },
                          "name": "Waldcamp Muster", "email": "info@waldcamp-muster.de",
                          "description": "A beautiful forest campsite in Bavaria.",
                          "location": { "latitude": 48.1351, "longitude": 11.582, "address": "Musterstraße 1, 80331 München" },
                          "coverImageUrl": "https://cdn.campnow.com/campsites/upload/cover.jpg",
                          "websiteUrl": "https://waldcamp-muster.de",
                          "bookingUrl": "https://waldcamp-muster.de/booking",
                          "membershipDoc": null,
                          "showOnMap": true, "isActive": true,
                          "completeness": { "isProfileComplete": true, "completionPercentage": 100, "missingFields": [], "redirectBehaviour": "detail-page", "websiteLink": "https://waldcamp-muster.de" },
                          "createdAt": "2025-04-19T10:00:00.000Z", "updatedAt": "2025-04-20T12:00:00.000Z"
                        }
                      ],
                      "metadata": { "total": 1, "totalPages": 1, "currentPage": 1, "perPage": 10, "hasNextPage": false, "hasPrevPage": false }
                    }
                  },
                  "empty": {
                    "summary": "200 – empty list",
                    "value": {
                      "success": true, "message": "Campsites retrieved successfully", "data": [],
                      "metadata": { "total": 0, "totalPages": 0, "currentPage": 1, "perPage": 10, "hasNextPage": false, "hasPrevPage": false }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "post": {
        "tags": ["Admin – Campsites"],
        "summary": "Create a campsite",
        "operationId": "adminCreateCampsite",
        "description": "Creates a campsite assigned to an existing campsite owner.\n\n**Auto-activation**: if this is the owner's **first** campsite, their account is automatically enabled (`isDisabled → false`).\n\n`membershipDoc` is PDF only, max 5 MB.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["userId"],
                "properties": {
                  "userId":        { "type": "string",  "example": "664f1a2b3c4d5e6f7a8b9c01", "description": "Required. Must be an existing campsite owner ID." },
                  "name":          { "type": "string",  "example": "Waldcamp Muster" },
                  "email":         { "type": "string",  "example": "info@waldcamp-muster.de",  "description": "Campsite contact email (not the owner's personal email)." },
                  "description":   { "type": "string",  "example": "A beautiful forest campsite in Bavaria." },
                  "location[latitude]":  { "type": "number", "example": 48.1351 },
                  "location[longitude]": { "type": "number", "example": 11.582 },
                  "location[address]":   { "type": "string", "example": "Musterstraße 1, 80331 München" },
                  "coverImageUrl": { "type": "string",  "example": "https://cdn.campnow.com/campsites/upload/cover.jpg" },
                  "websiteUrl":    { "type": "string",  "example": "https://waldcamp-muster.de" },
                  "bookingUrl":    { "type": "string",  "example": "https://waldcamp-muster.de/booking" },
                  "membershipDoc": { "type": "string",  "format": "binary", "description": "PDF only, max 5 MB." },
                  "showOnMap":     { "type": "boolean", "example": true },
                  "isActive":      { "type": "boolean", "example": true }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campsite created – owner auto-activated if this is their first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite created successfully" },
                    "data":    { "$ref": "#/components/schemas/Campsite" }
                  }
                },
                "examples": {
                  "first_campsite_auto_activated": {
                    "summary": "201 – first campsite → owner auto-activated",
                    "value": {
                      "success": true, "message": "Campsite created successfully",
                      "data": {
                        "id": "664f1a2b3c4d5e6f7a8b9c0d",
                        "userId": "664f1a2b3c4d5e6f7a8b9c02",
                        "owner": { "id": "664f1a2b3c4d5e6f7a8b9c02", "firstName": "Anna", "lastName": "Schmidt", "email": "a.schmidt@campsite.de", "mobile": null, "isDisabled": false },
                        "name": "Waldcamp Muster", "email": null,
                        "description": null,
                        "location": { "latitude": null, "longitude": null, "address": null },
                        "coverImageUrl": null, "websiteUrl": "https://waldcamp-muster.de", "bookingUrl": null, "membershipDoc": null,
                        "showOnMap": false, "isActive": false,
                        "completeness": { "isProfileComplete": false, "completionPercentage": 17, "missingFields": ["description","coverImageUrl","location.address","location.latitude","location.longitude"], "redirectBehaviour": "external-website", "websiteLink": "https://waldcamp-muster.de" },
                        "createdAt": "2025-04-20T10:00:00.000Z", "updatedAt": "2025-04-20T10:00:00.000Z"
                      }
                    }
                  },
                  "full_campsite": {
                    "summary": "201 – full campsite (complete profile)",
                    "value": {
                      "success": true, "message": "Campsite created successfully",
                      "data": {
                        "id": "664f1a2b3c4d5e6f7a8b9c0e",
                        "userId": "664f1a2b3c4d5e6f7a8b9c01",
                        "owner": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "mobile": "+49 170 1234567", "isDisabled": false },
                        "name": "Waldcamp Muster", "email": "info@waldcamp-muster.de",
                        "description": "A beautiful forest campsite in Bavaria.",
                        "location": { "latitude": 48.1351, "longitude": 11.582, "address": "Musterstraße 1, 80331 München" },
                        "coverImageUrl": "https://cdn.campnow.com/campsites/upload/cover.jpg",
                        "websiteUrl": "https://waldcamp-muster.de", "bookingUrl": "https://waldcamp-muster.de/booking",
                        "membershipDoc": "https://assets.campnow.de/public/media/campsites/documents/1714123456789-membership.pdf",
                        "showOnMap": true, "isActive": true,
                        "completeness": { "isProfileComplete": true, "completionPercentage": 100, "missingFields": [], "redirectBehaviour": "detail-page", "websiteLink": "https://waldcamp-muster.de" },
                        "createdAt": "2025-04-20T10:00:00.000Z", "updatedAt": "2025-04-20T10:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Owner (userId) not found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "success": false, "message": "Campsite owner not found", "data": null, "errors": null }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ValidationError" },
                "examples": {
                  "missing_userid": {
                    "summary": "422 – missing userId",
                    "value": { "success": false, "message": "Validation Error", "data": null, "errors": ["Owner (userId) is required."] }
                  },
                  "bad_url": {
                    "summary": "422 – invalid URL",
                    "value": { "success": false, "message": "Validation Error", "data": null, "errors": ["\"websiteUrl\" must be a valid uri"] }
                  },
                  "bad_pdf": {
                    "summary": "422 – non-PDF uploaded",
                    "value": { "success": false, "message": "Only PDF files are allowed", "data": null, "errors": null }
                  }
                }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },

    "/admin/campsites/{id}": {
      "parameters": [
        { "name": "id", "in": "path", "required": true, "description": "Campsite MongoDB ObjectId", "schema": { "type": "string", "example": "664f1a2b3c4d5e6f7a8b9c0d" } }
      ],
      "get": {
        "tags": ["Admin – Campsites"],
        "summary": "Get campsite detail",
        "operationId": "adminGetCampsite",
        "responses": {
          "200": {
            "description": "Campsite retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite retrieved successfully" },
                    "data":    { "$ref": "#/components/schemas/Campsite" }
                  }
                },
                "examples": {
                  "hidden": {
                    "summary": "200 – incomplete, no website (hidden)",
                    "value": {
                      "success": true, "message": "Campsite retrieved successfully",
                      "data": {
                        "id": "664f1a2b3c4d5e6f7a8b9c0d", "userId": "664f1a2b3c4d5e6f7a8b9c01",
                        "owner": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "mobile": null, "isDisabled": false },
                        "name": "Waldcamp Muster", "email": null, "description": null,
                        "location": { "latitude": null, "longitude": null, "address": null },
                        "coverImageUrl": null, "websiteUrl": null, "bookingUrl": null, "membershipDoc": null,
                        "showOnMap": false, "isActive": false,
                        "completeness": { "isProfileComplete": false, "completionPercentage": 17, "missingFields": ["description","coverImageUrl","location.address","location.latitude","location.longitude"], "redirectBehaviour": "hidden", "websiteLink": null },
                        "createdAt": "2025-04-20T10:00:00.000Z", "updatedAt": "2025-04-20T10:00:00.000Z"
                      }
                    }
                  },
                  "external_website": {
                    "summary": "200 – incomplete but has websiteUrl (external-website)",
                    "value": {
                      "success": true, "message": "Campsite retrieved successfully",
                      "data": {
                        "id": "664f1a2b3c4d5e6f7a8b9c0d", "userId": "664f1a2b3c4d5e6f7a8b9c01",
                        "owner": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "mobile": null, "isDisabled": false },
                        "name": "Waldcamp Muster", "email": "info@waldcamp-muster.de", "description": null,
                        "location": { "latitude": null, "longitude": null, "address": null },
                        "coverImageUrl": null, "websiteUrl": "https://waldcamp-muster.de", "bookingUrl": null, "membershipDoc": null,
                        "showOnMap": true, "isActive": false,
                        "completeness": { "isProfileComplete": false, "completionPercentage": 17, "missingFields": ["description","coverImageUrl","location.address","location.latitude","location.longitude"], "redirectBehaviour": "external-website", "websiteLink": "https://waldcamp-muster.de" },
                        "createdAt": "2025-04-20T10:00:00.000Z", "updatedAt": "2025-04-20T10:00:00.000Z"
                      }
                    }
                  },
                  "complete": {
                    "summary": "200 – complete profile (detail-page)",
                    "value": {
                      "success": true, "message": "Campsite retrieved successfully",
                      "data": {
                        "id": "664f1a2b3c4d5e6f7a8b9c0d", "userId": "664f1a2b3c4d5e6f7a8b9c01",
                        "owner": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "mobile": "+49 170 1234567", "isDisabled": false },
                        "name": "Waldcamp Muster", "email": "info@waldcamp-muster.de",
                        "description": "A beautiful forest campsite in Bavaria.",
                        "location": { "latitude": 48.1351, "longitude": 11.582, "address": "Musterstraße 1, 80331 München" },
                        "coverImageUrl": "https://cdn.campnow.com/campsites/upload/cover.jpg",
                        "websiteUrl": "https://waldcamp-muster.de", "bookingUrl": "https://waldcamp-muster.de/booking",
                        "membershipDoc": "https://assets.campnow.de/public/media/campsites/documents/1714123456789-membership.pdf",
                        "showOnMap": true, "isActive": true,
                        "completeness": { "isProfileComplete": true, "completionPercentage": 100, "missingFields": [], "redirectBehaviour": "detail-page", "websiteLink": "https://waldcamp-muster.de" },
                        "createdAt": "2025-04-19T10:00:00.000Z", "updatedAt": "2025-04-20T12:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/CampsiteNotFound" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "put": {
        "tags": ["Admin – Campsites"],
        "summary": "Update campsite",
        "operationId": "adminUpdateCampsite",
        "description": "Updates any campsite fields. All body fields optional. `membershipDoc` replaces existing PDF if provided.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "userId":               { "type": "string",  "example": "664f1a2b3c4d5e6f7a8b9c01", "description": "Optional. Reassign to a different owner." },
                  "name":                 { "type": "string",  "example": "Waldcamp Muster – Updated" },
                  "email":                { "type": "string",  "example": "contact@waldcamp-muster.de" },
                  "description":          { "type": "string",  "example": "Updated description." },
                  "location[latitude]":   { "type": "number",  "example": 48.1351 },
                  "location[longitude]":  { "type": "number",  "example": 11.582 },
                  "location[address]":    { "type": "string",  "example": "Musterstraße 1, 80331 München" },
                  "coverImageUrl":        { "type": "string",  "example": "https://cdn.campnow.com/updated-cover.jpg" },
                  "websiteUrl":           { "type": "string",  "example": "https://waldcamp-muster.de" },
                  "bookingUrl":           { "type": "string",  "example": "https://waldcamp-muster.de/booking" },
                  "membershipDoc":        { "type": "string",  "format": "binary", "description": "PDF only, max 5 MB. Replaces existing." },
                  "showOnMap":            { "type": "boolean", "example": true },
                  "isActive":             { "type": "boolean", "example": true }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Campsite updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite updated successfully" },
                    "data":    { "$ref": "#/components/schemas/Campsite" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/CampsiteNotFound" },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ValidationError" },
                "examples": {
                  "bad_url": { "summary": "422 – bad URL", "value": { "success": false, "message": "Validation Error", "data": null, "errors": ["\"websiteUrl\" must be a valid uri"] } },
                  "bad_pdf": { "summary": "422 – non-PDF", "value": { "success": false, "message": "Only PDF files are allowed", "data": null, "errors": null } }
                }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "delete": {
        "tags": ["Admin – Campsites"],
        "summary": "Delete campsite (soft delete)",
        "operationId": "adminDeleteCampsite",
        "description": "Soft-deletes the campsite (`isDeleted: true`, `isActive: false`). Requires `confirmed: true` as a guard.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["confirmed"],
                "properties": {
                  "confirmed": { "type": "boolean", "enum": [true], "example": true }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Campsite deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string",  "example": "Campsite deleted successfully" },
                    "data":    { "type": "object",  "properties": { "deletedId": { "type": "string", "example": "664f1a2b3c4d5e6f7a8b9c0d" } } }
                  }
                },
                "example": { "success": true, "message": "Campsite deleted successfully", "data": { "deletedId": "664f1a2b3c4d5e6f7a8b9c0d" } }
              }
            }
          },
          "400": {
            "description": "confirmed not set to true",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "success": false, "message": "Please set confirmed: true to delete this campsite", "data": null, "errors": null }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/CampsiteNotFound" },
          "422": {
            "description": "confirmed field missing or wrong value",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ValidationError" },
                "example": { "success": false, "message": "Validation Error", "data": null, "errors": ["confirmed must be true.", "confirmed is required."] }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },

    "/api/auth/login": {
      "post": {
        "tags": ["Auth – Campsite Owner Login"],
        "summary": "Campsite owner login (same endpoint as all users)",
        "operationId": "campsiteOwnerLogin",
        "description": "Standard login endpoint. For campsite owners:\n- `403` if no campsite created yet (`isDisabled: true`)\n- On success: `requiresPasswordReset: true` until owner changes their temp password",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email","password"],
                "properties": {
                  "email":    { "type": "string",  "example": "k.mueller@campsite.de" },
                  "password": { "type": "string",  "example": "TempPass123X" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful",
            "content": {
              "application/json": {
                "examples": {
                  "needs_password_reset": {
                    "summary": "200 – first login, temp password (redirect to set-password)",
                    "value": {
                      "success": true, "message": "Login successful",
                      "data": {
                        "user": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "userType": "campsiteOwner", "isPasswordReset": false },
                        "tokens": { "accessToken": "<jwt>", "refreshToken": "<jwt>" },
                        "requiresPasswordReset": true
                      }
                    }
                  },
                  "normal_login": {
                    "summary": "200 – normal login after password was set",
                    "value": {
                      "success": true, "message": "Login successful",
                      "data": {
                        "user": { "id": "664f1a2b3c4d5e6f7a8b9c01", "firstName": "Klaus", "lastName": "Müller", "email": "k.mueller@campsite.de", "userType": "campsiteOwner", "isPasswordReset": true },
                        "tokens": { "accessToken": "<jwt>", "refreshToken": "<jwt>" },
                        "requiresPasswordReset": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "example": { "success": false, "message": "Invalid credentials", "data": null, "errors": null }
              }
            }
          },
          "403": {
            "description": "Account not yet active (no campsite created)",
            "content": {
              "application/json": {
                "example": { "success": false, "message": "Your account is not yet active. Please wait for the admin to configure your first campsite.", "data": null, "errors": null }
              }
            }
          }
        }
      }
    }
  }
}
