{
  "openapi": "3.0.3",
  "info": {
    "title": "BEKIND API",
    "version": "1.0.0",
    "description": "BEKIND backend REST API. Spec is generated from Zod contracts — do not edit openapi.json manually."
  },
  "servers": [
    {
      "url": "/",
      "description": "Current host"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "schemas": {
      "RegisterResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/RegisterResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RegisterResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "username": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          }
        },
        "required": ["id", "email", "username", "status"]
      },
      "Error": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "messages": {
            "type": "object",
            "properties": {
              "vi": {
                "type": "string"
              },
              "en": {
                "type": "string"
              }
            },
            "required": ["vi", "en"]
          }
        },
        "required": ["field", "code", "messages"]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RegisterBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "user@example.com"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128,
            "example": "SecurePass123"
          },
          "username": {
            "type": "string",
            "example": "johndoe"
          },
          "first_name": {
            "type": "string",
            "example": "John"
          },
          "last_name": {
            "type": "string",
            "example": "Doe"
          },
          "phone": {
            "type": "string",
            "pattern": "^\\+?[1-9]\\d{9,14}$",
            "example": "+84901234567"
          }
        },
        "required": ["email", "password"]
      },
      "LoginMobileResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MobileLoginData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "MobileLoginData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "user": {
            "$ref": "#/components/schemas/UserPublic"
          },
          "access_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "enum": ["Bearer"]
          }
        },
        "required": ["user", "access_token", "refresh_token", "token_type"]
      },
      "UserPublic": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "username": {
            "type": "string",
            "nullable": true
          },
          "first_name": {
            "type": "string",
            "nullable": true
          },
          "last_name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "avatar_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "last_login_at": {
            "type": "string",
            "nullable": true
          }
        },
        "required": ["id", "email", "username", "first_name", "last_name", "status", "roles", "permissions"]
      },
      "LoginBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "user@example.com"
          },
          "password": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "example": "SecurePass123"
          },
          "device_info": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "example": {
              "device_type": "mobile",
              "os": "iOS 17.0",
              "browser": "Safari",
              "model": "iPhone 15 Pro"
            }
          }
        },
        "required": ["email", "password"]
      },
      "WebLoginResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WebLoginData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "WebLoginData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "user": {
            "$ref": "#/components/schemas/UserPublic"
          },
          "session": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time"
              },
              "refresh_expires_at": {
                "type": "string",
                "format": "date-time"
              },
              "expires_in": {
                "type": "number"
              },
              "refresh_expires_in": {
                "type": "number"
              },
              "token_type": {
                "type": "string",
                "enum": ["Bearer"]
              }
            },
            "required": ["id", "expires_at", "refresh_expires_at", "expires_in", "refresh_expires_in", "token_type"]
          },
          "access_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          }
        },
        "required": ["user", "session"]
      },
      "WebLoginBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "user@example.com"
          },
          "password": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "example": "SecurePass123"
          },
          "device_info": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "example": {
              "device_type": "desktop",
              "os": "Windows 11",
              "browser": "Chrome 120",
              "resolution": "1920x1080"
            }
          }
        },
        "required": ["email", "password"]
      },
      "ZaloLoginResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MobileLoginData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "ZaloLoginBody": {
        "type": "object",
        "properties": {
          "zalo_code": {
            "type": "string",
            "example": "zalo_auth_code_12345"
          },
          "zalo_open_id": {
            "type": "string",
            "example": "123456789"
          },
          "device_info": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "example": {
              "device_type": "zalo_mini_app",
              "os": "iOS",
              "app_version": "1.0.0"
            }
          }
        }
      },
      "SessionListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "nullable": true,
            "properties": {
              "count": {
                "type": "number"
              },
              "rows": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "platform": {
                      "type": "string"
                    },
                    "device_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "device_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "ip_address": {
                      "type": "string",
                      "nullable": true
                    },
                    "user_agent": {
                      "type": "string",
                      "nullable": true
                    },
                    "last_activity_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "platform",
                    "device_id",
                    "device_name",
                    "ip_address",
                    "user_agent",
                    "last_activity_at",
                    "created_at",
                    "expires_at"
                  ]
                }
              },
              "page": {
                "type": "number"
              },
              "pageSize": {
                "type": "number"
              }
            },
            "required": ["count", "rows", "page", "pageSize"]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RevokeSessionResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "nullable": true
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "LogoutAllBody": {
        "type": "object",
        "properties": {
          "confirm_password": {
            "type": "string"
          },
          "confirm_otp": {
            "type": "string"
          }
        }
      },
      "RefreshTokenResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/RefreshTokenData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RefreshTokenData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "session": {
            "type": "object",
            "properties": {
              "expires_at": {
                "type": "string",
                "format": "date-time"
              },
              "refresh_expires_at": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": ["expires_at", "refresh_expires_at"]
          },
          "access_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "enum": ["Bearer"]
          }
        },
        "required": ["session"]
      },
      "RefreshTokenBody": {
        "type": "object",
        "properties": {
          "refresh_token": {
            "type": "string",
            "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
          },
          "device_info": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "example": {
              "device_type": "mobile",
              "os": "iOS 17.0",
              "browser": "Safari"
            }
          }
        }
      },
      "ProfileResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UserPublic"
              },
              {
                "nullable": true
              }
            ]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "SendConfirmOtpResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SendConfirmOtpResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "SendConfirmOtpResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "expiresInSeconds": {
            "type": "number"
          },
          "otp": {
            "type": "string"
          }
        },
        "required": ["expiresInSeconds"]
      },
      "PasswordResetRequestResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PasswordResetRequestResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "PasswordResetRequestResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "sent": {
            "type": "boolean"
          },
          "expiresIn": {
            "type": "number"
          }
        },
        "required": ["sent", "expiresIn"]
      },
      "PasswordResetSubmitResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "nullable": true,
            "properties": {
              "success": {
                "type": "boolean"
              }
            },
            "required": ["success"]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "PasswordResetBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "code": {
            "type": "string",
            "minLength": 6,
            "maxLength": 6
          },
          "new_password": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          }
        },
        "required": ["email", "code", "new_password"],
        "example": {
          "email": "user@example.com",
          "code": "123456",
          "new_password": "SecurePass123"
        }
      },
      "FileListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/FileListData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "FileListData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "count": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          }
        },
        "required": ["count", "rows", "page", "pageSize"]
      },
      "File": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "path": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "mime": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "size": {
            "type": "integer",
            "nullable": true
          },
          "compress_info": {
            "$ref": "#/components/schemas/CompressInfo"
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "is_library": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "created_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "updated_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          }
        },
        "required": [
          "id",
          "path",
          "name",
          "mime",
          "type",
          "size",
          "compress_info",
          "title",
          "description",
          "note",
          "is_library",
          "created_at",
          "updated_at",
          "created_by",
          "updated_by"
        ]
      },
      "CompressInfo": {
        "type": "object",
        "nullable": true,
        "properties": {
          "desktop": {
            "type": "string",
            "nullable": true
          },
          "tablet": {
            "type": "string",
            "nullable": true
          },
          "mobile": {
            "type": "string",
            "nullable": true
          },
          "preload": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "FileResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/File"
              },
              {
                "nullable": true
              }
            ]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "FileUploadBody": {
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "File to upload"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "maxLength": 150,
            "example": "Product Image"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "maxLength": 500,
            "example": "Main product image"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "example": "Compressed version"
          },
          "is_library": {
            "type": "boolean",
            "example": false
          }
        },
        "required": ["file"]
      },
      "FileMutateBody": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "nullable": true,
            "maxLength": 150,
            "example": "Product Image"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "maxLength": 500,
            "example": "Main product image for homepage"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "example": "Compressed version"
          },
          "is_library": {
            "type": "boolean",
            "example": false
          }
        }
      },
      "FileArrayResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/File"
            }
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "QuotaResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/QuotaResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "QuotaResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "used_bytes": {
            "type": "integer"
          },
          "used_files": {
            "type": "integer"
          },
          "limit_bytes": {
            "type": "number",
            "nullable": true
          }
        },
        "required": ["used_bytes", "used_files", "limit_bytes"]
      },
      "PresignResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PresignResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "PresignResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "upload_url": {
            "type": "string"
          },
          "file_key": {
            "type": "string"
          },
          "upload_token": {
            "type": "string"
          },
          "expires_in": {
            "type": "number"
          }
        },
        "required": ["upload_url", "file_key", "upload_token", "expires_in"]
      },
      "PresignRequest": {
        "type": "object",
        "properties": {
          "file_name": {
            "type": "string",
            "example": "document.pdf"
          },
          "file_size": {
            "type": "integer",
            "example": 1048576
          },
          "mime_type": {
            "type": "string",
            "example": "application/pdf"
          }
        },
        "required": ["file_name", "file_size", "mime_type"]
      },
      "ConfirmFileRequest": {
        "type": "object",
        "properties": {
          "file_key": {
            "type": "string",
            "example": "uploads/2024/01/document.pdf"
          },
          "file_name": {
            "type": "string",
            "example": "document.pdf"
          },
          "file_size": {
            "type": "integer",
            "example": 1048576
          },
          "mime_type": {
            "type": "string",
            "example": "application/pdf"
          },
          "upload_token": {
            "type": "string",
            "example": "upload_token_xyz123"
          },
          "title": {
            "type": "string",
            "example": "Document"
          },
          "is_library": {
            "type": "boolean",
            "example": false
          }
        },
        "required": ["file_key", "file_name", "file_size", "mime_type", "upload_token"]
      },
      "PreviewLinkResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PreviewLinkResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "PreviewLinkResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          },
          "fallback_endpoint": {
            "type": "string",
            "nullable": true
          },
          "expires_in": {
            "type": "number",
            "nullable": true
          }
        },
        "required": ["url", "fallback_endpoint", "expires_in"]
      },
      "DownloadLinkResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DownloadLinkResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "DownloadLinkResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          },
          "fallback_endpoint": {
            "type": "string",
            "nullable": true
          },
          "expires_in": {
            "type": "number",
            "nullable": true
          }
        },
        "required": ["url", "fallback_endpoint", "expires_in"]
      },
      "RestoreFileResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "boolean",
            "nullable": true
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "BatchPreviewLinkResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BatchPreviewLinkResult"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "BatchPreviewLinkResult": {
        "type": "array",
        "nullable": true,
        "items": {
          "type": "object",
          "properties": {
            "file_id": {
              "type": "string",
              "format": "uuid"
            },
            "preview_url": {
              "type": "string",
              "nullable": true
            },
            "expires_in": {
              "type": "number",
              "nullable": true
            },
            "error": {
              "type": "string"
            }
          },
          "required": ["file_id", "preview_url", "expires_in"]
        }
      },
      "BatchPreviewLinkRequest": {
        "type": "object",
        "properties": {
          "file_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "maxItems": 100,
            "example": ["550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001"]
          }
        },
        "required": ["file_ids"]
      },
      "NotificationListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/NotificationListData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "NotificationListData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "count": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Notification"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "unread_count": {
            "type": "integer"
          }
        },
        "required": ["count", "rows", "page", "pageSize", "unread_count"]
      },
      "Notification": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "enum": [
              "order_created",
              "payment_success",
              "payment_failed",
              "order_shipped",
              "order_delivered",
              "system_alert",
              "promotion",
              "chat_message",
              "security_alert",
              "account_update"
            ]
          },
          "data": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "nullable": true
            }
          },
          "tenant_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "scheduled_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "priority": {
            "type": "integer",
            "nullable": true
          },
          "created_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "campaign_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "template_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "external_key": {
            "type": "string",
            "nullable": true
          },
          "dedupe_key": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "channel": {
            "type": "string",
            "enum": ["in_app", "push", "email", "sms", "zalo"]
          },
          "read_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "deleted_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "archived_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "title",
          "body",
          "type",
          "data",
          "tenant_id",
          "scheduled_at",
          "priority",
          "created_by",
          "campaign_id",
          "template_id",
          "external_key",
          "dedupe_key",
          "created_at",
          "updated_at",
          "user_id",
          "channel",
          "read_at",
          "deleted_at",
          "archived_at"
        ]
      },
      "NotificationResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Notification"
              },
              {
                "nullable": true
              }
            ]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "NotificationMutateBody": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "example": "Order Shipped"
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "example": "Your order #12345 has been shipped and will arrive in 2-3 business days."
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "minItems": 1
              },
              {
                "nullable": true
              }
            ],
            "example": "550e8400-e29b-41d4-a716-446655440000"
          },
          "type": {
            "type": "string",
            "enum": [
              "order_created",
              "payment_success",
              "payment_failed",
              "order_shipped",
              "order_delivered",
              "system_alert",
              "promotion",
              "chat_message",
              "security_alert",
              "account_update"
            ],
            "default": "system_alert",
            "example": "order_shipped"
          },
          "channel": {
            "type": "string",
            "enum": ["in_app", "push", "email", "sms", "zalo"],
            "default": "in_app",
            "example": "push"
          },
          "platform": {
            "type": "string",
            "nullable": true,
            "enum": ["web", "ios", "android", "zalo_mini_app", null],
            "example": "ios"
          },
          "data": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "nullable": true
            },
            "example": {
              "order_id": "12345",
              "tracking_number": "TN123456789"
            }
          },
          "tenant_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid",
            "example": "550e8400-e29b-41d4-a716-446655440001"
          },
          "scheduled_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "example": "2024-01-15T10:00:00Z"
          },
          "priority": {
            "type": "integer",
            "nullable": true,
            "example": 1
          }
        },
        "required": ["title", "body"]
      },
      "UnreadCountResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/UnreadCountData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "UnreadCountData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "unread_count": {
            "type": "integer"
          },
          "has_unread": {
            "type": "boolean"
          }
        },
        "required": ["unread_count", "has_unread"]
      },
      "NotificationPreference": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "notification_type": {
            "type": "string",
            "enum": [
              "order_created",
              "payment_success",
              "payment_failed",
              "order_shipped",
              "order_delivered",
              "system_alert",
              "promotion",
              "chat_message",
              "security_alert",
              "account_update"
            ]
          },
          "channel": {
            "type": "string",
            "enum": ["in_app", "push", "email", "sms", "zalo"]
          },
          "is_enabled": {
            "type": "boolean",
            "default": true
          },
          "quiet_hours_start": {
            "type": "string",
            "nullable": true
          },
          "quiet_hours_end": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "user_id",
          "notification_type",
          "channel",
          "quiet_hours_start",
          "quiet_hours_end",
          "created_at",
          "updated_at"
        ]
      },
      "NotificationPreferenceUpdate": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "notification_type": {
              "type": "string",
              "enum": [
                "order_created",
                "payment_success",
                "payment_failed",
                "order_shipped",
                "order_delivered",
                "system_alert",
                "promotion",
                "chat_message",
                "security_alert",
                "account_update"
              ]
            },
            "channel": {
              "type": "string",
              "enum": ["in_app", "push", "email", "sms", "zalo"]
            },
            "is_enabled": {
              "type": "boolean"
            },
            "quiet_hours_start": {
              "type": "string"
            },
            "quiet_hours_end": {
              "type": "string"
            }
          },
          "required": ["notification_type", "channel"]
        }
      },
      "NotificationDevice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "platform": {
            "type": "string",
            "enum": ["web", "ios", "android", "zalo_mini_app"]
          },
          "device_id": {
            "type": "string"
          },
          "device_name": {
            "type": "string",
            "nullable": true
          },
          "push_token": {
            "type": "string",
            "nullable": true
          },
          "one_signal_player_id": {
            "type": "string",
            "nullable": true
          },
          "device_info": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "nullable": true
            }
          },
          "is_active": {
            "type": "boolean"
          },
          "last_used_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "user_id",
          "platform",
          "device_id",
          "device_name",
          "push_token",
          "one_signal_player_id",
          "device_info",
          "is_active",
          "last_used_at",
          "created_at",
          "updated_at"
        ]
      },
      "NotificationDeviceRegister": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "enum": ["web", "ios", "android", "zalo_mini_app"],
            "example": "ios"
          },
          "device_id": {
            "type": "string",
            "example": "device_token_abc123"
          },
          "device_name": {
            "type": "string",
            "example": "iPhone 15 Pro"
          },
          "push_token": {
            "type": "string",
            "example": "push_token_xyz789"
          },
          "one_signal_player_id": {
            "type": "string",
            "example": "one_signal_id_123"
          },
          "device_info": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "example": {
              "os": "iOS 17.0",
              "app_version": "1.0.0",
              "model": "iPhone 15 Pro"
            }
          }
        },
        "required": ["platform", "device_id"]
      },
      "UserListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/UserListData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "UserListData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "count": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/User"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          }
        },
        "required": ["count", "rows", "page", "pageSize"]
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "username": {
            "type": "string",
            "nullable": true
          },
          "first_name": {
            "type": "string",
            "nullable": true
          },
          "last_name": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "avatar_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "email",
          "username",
          "first_name",
          "last_name",
          "phone",
          "status",
          "avatar_id",
          "created_at",
          "updated_at"
        ]
      },
      "UserResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/User"
              },
              {
                "nullable": true
              }
            ]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "UserCreateBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "user@example.com"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128,
            "example": "SecurePass123"
          },
          "username": {
            "type": "string",
            "minLength": 3,
            "maxLength": 50,
            "example": "johndoe"
          },
          "first_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "John"
          },
          "last_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "Doe"
          },
          "phone": {
            "type": "string",
            "pattern": "^\\+?[1-9]\\d{9,14}$",
            "example": "+84901234567"
          },
          "role": {
            "type": "string",
            "enum": ["user", "admin", "system_admin"],
            "example": "user"
          }
        },
        "required": ["email", "password"]
      },
      "UserUpdateBody": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string",
            "minLength": 3,
            "maxLength": 50,
            "example": "johndoe_updated"
          },
          "first_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "John"
          },
          "last_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "Smith"
          },
          "phone": {
            "type": "string",
            "pattern": "^\\+?[1-9]\\d{9,14}$",
            "example": "+84901234568"
          },
          "avatar_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid",
            "example": "550e8400-e29b-41d4-a716-446655440000"
          }
        }
      },
      "ResetPasswordResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ResetPasswordResponseData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "ResetPasswordResponseData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "required": ["success"]
      },
      "RoleListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/RoleListData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RoleListData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "count": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Role"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          }
        },
        "required": ["count", "rows", "page", "pageSize"]
      },
      "Role": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "created_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "updated_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          }
        },
        "required": ["id", "name", "description", "created_at", "updated_at", "created_by", "updated_by"]
      },
      "RoleResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Role"
              },
              {
                "nullable": true
              }
            ]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RoleMutateBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "Manager"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "example": "Can manage users and content"
          }
        },
        "required": ["name"]
      },
      "PermissionListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PermissionListData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "PermissionListData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "count": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Permission"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          }
        },
        "required": ["count", "rows", "page", "pageSize"]
      },
      "Permission": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "resource": {
            "type": "string"
          },
          "action": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "created_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "updated_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          }
        },
        "required": ["id", "name", "description", "resource", "action", "created_at", "created_by", "updated_by"]
      },
      "PermissionResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Permission"
              },
              {
                "nullable": true
              }
            ]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "PermissionMutateBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "example": "create_user"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "example": "Create new users"
          },
          "resource": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "users"
          },
          "action": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "create"
          }
        },
        "required": ["name", "resource", "action"]
      },
      "UserRoleListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/UserRoleListData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "UserRoleListData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "count": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserRole"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          }
        },
        "required": ["count", "rows", "page", "pageSize"]
      },
      "UserRole": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "role_id": {
            "type": "string",
            "format": "uuid"
          },
          "assigned_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "assigned_by": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "updated_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": ["id", "user_id", "role_id", "assigned_at", "assigned_by", "updated_at"]
      },
      "UserRoleResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UserRole"
              },
              {
                "nullable": true
              }
            ]
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "UserRoleMutateBody": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid",
            "example": "550e8400-e29b-41d4-a716-446655440000"
          },
          "role_id": {
            "type": "string",
            "format": "uuid",
            "example": "550e8400-e29b-41d4-a716-446655440001"
          }
        },
        "required": ["user_id", "role_id"]
      },
      "RolePermissionListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/RolePermissionListData"
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RolePermissionListData": {
        "type": "object",
        "nullable": true,
        "properties": {
          "count": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RolePermission"
            }
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          }
        },
        "required": ["count", "rows", "page", "pageSize"]
      },
      "RolePermission": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "role_id": {
            "type": "string",
            "format": "uuid"
          },
          "permission_id": {
            "type": "string",
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": ["id", "role_id", "permission_id", "created_at"]
      },
      "RolePermissionArrayResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/RolePermission"
            }
          },
          "trace_id": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "required": ["success", "trace_id", "timestamp", "errors"]
      },
      "RolePermissionBulkAssignBody": {
        "type": "object",
        "properties": {
          "permission_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "example": ["550e8400-e29b-41d4-a716-446655440002", "550e8400-e29b-41d4-a716-446655440003"]
          }
        },
        "required": ["permission_ids"]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/api/v1/auth/register": {
      "post": {
        "operationId": "register",
        "tags": ["Authentication"],
        "summary": "User registration",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Registration successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegisterResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login/mobile": {
      "post": {
        "operationId": "loginMobile",
        "tags": ["Authentication"],
        "summary": "Mobile login (Bearer token)",
        "description": "Authenticate mobile app users. Tokens are returned in the response body.",
        "security": [],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Unique device identifier (required)"
            },
            "required": true,
            "description": "Unique device identifier (required)",
            "name": "X-Device-Id",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "Human-readable device name"
            },
            "required": false,
            "description": "Human-readable device name",
            "name": "X-Device-Name",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful — tokens in body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginMobileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login/web": {
      "post": {
        "operationId": "loginWeb",
        "tags": ["Authentication"],
        "summary": "Web login (HttpOnly Cookie)",
        "description": "Authenticate web users with HttpOnly cookies. Tokens stored in HttpOnly cookies (XSS protection).",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebLoginBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful - tokens in HttpOnly cookies",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebLoginResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "423": {
            "description": "Account locked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login/zalo": {
      "post": {
        "operationId": "loginZalo",
        "tags": ["Authentication"],
        "summary": "Zalo Mini App login (Bearer token)",
        "description": "Authenticate Zalo Mini App users via Zalo auth code or Open ID.",
        "security": [],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Unique device identifier (REQUIRED)"
            },
            "required": true,
            "description": "Unique device identifier (REQUIRED)",
            "name": "X-Device-Id",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "Device name for display"
            },
            "required": false,
            "description": "Device name for display",
            "name": "X-Device-Name",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ZaloLoginBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZaloLoginResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid Zalo code or authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Zalo configuration not set up",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/sessions": {
      "get": {
        "operationId": "listSessions",
        "tags": ["Authentication"],
        "summary": "List active sessions",
        "description": "Get all active sessions for the authenticated user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List of active sessions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/sessions/{id}/revoke": {
      "post": {
        "operationId": "revokeSession",
        "tags": ["Authentication"],
        "summary": "Revoke a specific session",
        "description": "Revoke a specific active session belonging to the authenticated user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Session ID to revoke"
            },
            "required": true,
            "description": "Session ID to revoke",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Session revoked successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeSessionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "operationId": "logout",
        "tags": ["Authentication"],
        "summary": "Logout user",
        "description": "Logout user and invalidate current session",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Logged out successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/logout-all": {
      "post": {
        "operationId": "logoutAll",
        "tags": ["Authentication"],
        "summary": "Logout all devices",
        "description": "Revoke all active sessions for the authenticated user. Requires password confirmation (confirm_password) or OTP (confirm_otp).",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LogoutAllBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "All sessions revoked successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - missing or invalid confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/refresh": {
      "post": {
        "operationId": "refreshToken",
        "tags": ["Authentication"],
        "summary": "Refresh access token",
        "security": [],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshTokenBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token refreshed. In development, new tokens are included in response body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefreshTokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — invalid or expired refresh token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/profile": {
      "get": {
        "operationId": "getProfile",
        "tags": ["Authentication"],
        "summary": "Get authenticated user profile",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Profile retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfileResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/send-confirm-otp": {
      "post": {
        "operationId": "sendConfirmOtp",
        "tags": ["Authentication"],
        "summary": "Request a sensitive-action confirmation OTP",
        "description": "Generates a 6-digit OTP, stores it in Redis (TTL 5 min), and sends it to the authenticated user's email.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OTP generated and sent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendConfirmOtpResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/forgot-password/send-otp": {
      "post": {
        "operationId": "forgotPasswordSendOtp",
        "tags": ["Authentication"],
        "summary": "Request password reset OTP",
        "description": "Send 6-digit OTP code to user email (valid for 10 minutes)",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                },
                "required": ["email"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OTP code sent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasswordResetRequestResponse"
                }
              }
            }
          },
          "404": {
            "description": "Email not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/forgot-password/confirm-reset": {
      "post": {
        "operationId": "forgotPasswordConfirmReset",
        "tags": ["Authentication"],
        "summary": "Reset password",
        "description": "Reset user password after OTP verification",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasswordResetBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasswordResetSubmitResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or expired code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files": {
      "get": {
        "operationId": "getFiles",
        "tags": ["Files"],
        "summary": "Get all files",
        "description": "Admin/system_admin: all files. Regular user: own uploads only.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Files retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "uploadFile",
        "tags": ["Files"],
        "summary": "Upload a file",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FileUploadBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "File uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/{id}": {
      "get": {
        "operationId": "getFileById",
        "tags": ["Files"],
        "summary": "Get file by ID",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "File retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateFile",
        "tags": ["Files"],
        "summary": "Update file metadata (or replace file)",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileMutateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "File updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteFile",
        "tags": ["Files"],
        "summary": "Delete file",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "File deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/upload-multiple": {
      "post": {
        "operationId": "uploadMultipleFiles",
        "tags": ["Files"],
        "summary": "Upload multiple files",
        "description": "Upload up to 10 files at once. Each file undergoes magic-byte, MIME/extension, and virus scan validation.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    }
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 150
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "is_library": {
                    "type": "boolean"
                  }
                },
                "required": ["files"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Files uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileArrayResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/quota": {
      "get": {
        "operationId": "getFileQuota",
        "tags": ["Files"],
        "summary": "Get storage quota",
        "description": "Get storage quota and usage breakdown for the current user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Quota retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/presign": {
      "post": {
        "operationId": "presignFileUpload",
        "tags": ["Files"],
        "summary": "Get presigned upload URL",
        "description": "Get a presigned URL for direct MinIO upload (MinIO only)",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PresignRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Presigned URL generated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresignResponse"
                }
              }
            }
          },
          "400": {
            "description": "Direct upload only supported with MinIO",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/confirm": {
      "post": {
        "operationId": "confirmFileUpload",
        "tags": ["Files"],
        "summary": "Confirm direct upload",
        "description": "Confirm a direct MinIO upload and save metadata",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmFileRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "File confirmed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/File"
                        },
                        {
                          "nullable": true
                        }
                      ]
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/{id}/stream": {
      "get": {
        "operationId": "streamFile",
        "tags": ["Files"],
        "summary": "Stream file or redirect to signed URL",
        "description": "Stream the file directly or redirect to a signed URL for cloud storage",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "File stream or redirect",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "307": {
            "description": "Temporary redirect to signed URL"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/{id}/preview-link": {
      "get": {
        "operationId": "getFilePreviewLink",
        "tags": ["Files"],
        "summary": "Get file preview link",
        "description": "Generate a signed URL for file preview (inline content disposition)",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "nullable": true,
              "default": 3600
            },
            "required": false,
            "name": "expires",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Preview link generated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewLinkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/{id}/download-link": {
      "get": {
        "operationId": "getFileDownloadLink",
        "tags": ["Files"],
        "summary": "Get file download link",
        "description": "Generate a signed URL for file download (attachment content disposition)",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "nullable": true,
              "default": 3600
            },
            "required": false,
            "name": "expires",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Download link generated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadLinkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/{id}/restore": {
      "put": {
        "operationId": "restoreFile",
        "tags": ["Files"],
        "summary": "Restore a soft-deleted file",
        "description": "Restores a soft-deleted file by setting is_deleted = false. The physical file must still exist on disk/storage for it to be usable.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "File restored successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestoreFileResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/files/batch-preview-link": {
      "post": {
        "operationId": "batchPreviewLink",
        "tags": ["Files"],
        "summary": "Batch get preview URLs",
        "description": "Generate preview URLs for up to 100 file IDs in a single request",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchPreviewLinkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preview URLs resolved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchPreviewLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications": {
      "get": {
        "operationId": "getNotifications",
        "tags": ["Notifications"],
        "summary": "Get notifications of current user",
        "description": "Returns paginated notifications for the authenticated user, including unread count.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Notifications retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createNotification",
        "tags": ["Notifications"],
        "summary": "Create and send notification",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationMutateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Notification created and sent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications/{id}": {
      "get": {
        "operationId": "getNotificationById",
        "tags": ["Notifications"],
        "summary": "Get notification by ID",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Notification retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteNotification",
        "tags": ["Notifications"],
        "summary": "Delete notification",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Notification deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications/unread-count": {
      "get": {
        "operationId": "getUnreadNotificationCount",
        "tags": ["Notifications"],
        "summary": "Get unread notification count",
        "description": "Get the number of unread notifications for the current user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Unread count retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnreadCountResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications/subscribe": {
      "get": {
        "operationId": "subscribeToNotifications",
        "tags": ["Notifications"],
        "summary": "Subscribe to notifications via SSE",
        "description": "Subscribe to real-time notifications using Server-Sent Events",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "SSE connection established",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications/preferences": {
      "get": {
        "operationId": "getNotificationPreferences",
        "tags": ["Notifications"],
        "summary": "Get notification preferences",
        "description": "Get notification preferences for the current user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Preferences retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/NotificationPreference"
                      }
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateNotificationPreferences",
        "tags": ["Notifications"],
        "summary": "Update notification preferences",
        "description": "Update notification preferences for the current user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationPreferenceUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preferences updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/NotificationPreference"
                      }
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications/mark-as-read": {
      "put": {
        "operationId": "markNotificationsAsRead",
        "tags": ["Notifications"],
        "summary": "Mark notifications as read",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Marked notifications as read successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications/devices": {
      "get": {
        "operationId": "getNotificationDevices",
        "tags": ["Notifications"],
        "summary": "Get user notification devices",
        "description": "Get list of active notification devices for the current user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Devices retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/NotificationDevice"
                      }
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "registerNotificationDevice",
        "tags": ["Notifications"],
        "summary": "Register notification device",
        "description": "Register a new device for push notifications",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationDeviceRegister"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Device registered successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/NotificationDevice"
                        },
                        {
                          "nullable": true
                        }
                      ]
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/notifications/devices/{id}": {
      "delete": {
        "operationId": "unregisterNotificationDevice",
        "tags": ["Notifications"],
        "summary": "Remove notification device",
        "description": "Deactivate a notification device for the current user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Device unregistered successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/users": {
      "get": {
        "operationId": "getUsers",
        "tags": ["Users"],
        "summary": "Get all users",
        "description": "Retrieve paginated list of users. Admin only.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createUser",
        "tags": ["Users"],
        "summary": "Create a user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/users/{id}": {
      "get": {
        "operationId": "getUserById",
        "tags": ["Users"],
        "summary": "Get user by ID",
        "description": "Users may only access their own record; admins can access any.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateUser",
        "tags": ["Users"],
        "summary": "Update user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteUser",
        "tags": ["Users"],
        "summary": "Delete user",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/users/{id}/reset-password": {
      "put": {
        "operationId": "adminResetUserPassword",
        "tags": ["Users"],
        "summary": "Reset user password to default",
        "description": "Reset user password to default value. Admin only.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Password reset successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResetPasswordResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Default password not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/roles": {
      "get": {
        "operationId": "getRoles",
        "tags": ["Roles"],
        "summary": "Get all roles",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createRole",
        "tags": ["Roles"],
        "summary": "Create a role",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleMutateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/roles/{id}": {
      "get": {
        "operationId": "getRoleById",
        "tags": ["Roles"],
        "summary": "Get role by ID",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateRole",
        "tags": ["Roles"],
        "summary": "Update role",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleMutateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteRole",
        "tags": ["Roles"],
        "summary": "Delete role",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/permissions": {
      "get": {
        "operationId": "getPermissions",
        "tags": ["Permissions"],
        "summary": "Get all permissions",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PermissionListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createPermission",
        "tags": ["Permissions"],
        "summary": "Create a permission",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PermissionMutateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PermissionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/permissions/{id}": {
      "get": {
        "operationId": "getPermissionById",
        "tags": ["Permissions"],
        "summary": "Get permission by ID",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PermissionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deletePermission",
        "tags": ["Permissions"],
        "summary": "Delete permission",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/user-roles": {
      "get": {
        "operationId": "getUserRoles",
        "tags": ["User Roles"],
        "summary": "Get user-role assignments",
        "description": "Retrieve a list of user-role assignments with pagination, filtering and sorting",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRoleListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "assignRoleToUser",
        "tags": ["User Roles"],
        "summary": "Assign a role to a user",
        "description": "Create a new user-role assignment",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserRoleMutateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Role assigned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRoleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/user-roles/{id}": {
      "get": {
        "operationId": "getUserRoleById",
        "tags": ["User Roles"],
        "summary": "Get user-role assignment by ID",
        "description": "Retrieve a single user-role assignment by its ID",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "UserRole retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRoleResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateUserRoleById",
        "tags": ["User Roles"],
        "summary": "Update user-role assignment by ID",
        "description": "Update a user-role assignment",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserRoleMutateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "UserRole updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRoleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteUserRoleById",
        "tags": ["User Roles"],
        "summary": "Delete user-role assignment by ID",
        "description": "Delete a user-role assignment (revoke role from user)",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Role revoked successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "string",
                      "nullable": true
                    },
                    "trace_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "timestamp": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Error"
                      }
                    }
                  },
                  "required": ["success", "trace_id", "timestamp", "errors"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/role-permissions": {
      "get": {
        "operationId": "getRolePermissions",
        "tags": ["Role Permissions"],
        "summary": "Get role-permission assignments",
        "description": "Retrieve a list of role-permission assignments with pagination, filtering and sorting. Admin only.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "filter, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "filters",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sortField, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortField",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "sort order, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "sortOrder",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1,
              "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "page, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10,
              "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax"
            },
            "required": false,
            "description": "pageSize, visit https://www.npmjs.com/package/sequelize-api-paginate for syntax",
            "name": "pageSize",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RolePermissionListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/role-permissions/{role_id}/assign": {
      "post": {
        "operationId": "assignPermissionsToRole",
        "tags": ["Role Permissions"],
        "summary": "Bulk assign permissions to a role",
        "description": "Assign multiple permissions to a role at once",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "role_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RolePermissionBulkAssignBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Permissions assigned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RolePermissionArrayResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateRolePermissions",
        "tags": ["Role Permissions"],
        "summary": "Update role permissions",
        "description": "Replace all permissions of a role with a new set of permissions",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "role_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RolePermissionBulkAssignBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Permissions updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RolePermissionArrayResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  }
}
