openapi: 3.1.0
info:
  title: Api
  version: 0.1.0
  description: Headless W API
servers:
  - url: /api
    description: Base API path
tags:
  - name: health
    description: Health operations
  - name: auth
    description: Authentication
  - name: dashboard
    description: Dashboard summaries
  - name: clients
    description: Client management
  - name: prospects
    description: Prospect pipeline
  - name: projects
    description: Project management
  - name: tasks
    description: Project task management
  - name: users
    description: User management
  - name: activity
    description: Activity log
  - name: settings
    description: Admin settings
  - name: ai
    description: AI assistant features
  - name: ads
    description: Google Ads integration
  - name: whmcs
    description: WHMCS API explorer

paths:
  /healthz:
    get:
      operationId: healthCheck
      tags: [health]
      summary: Health check
      responses:
        "200":
          description: Healthy
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthStatus"

  # AUTH
  /auth/login:
    post:
      operationId: login
      tags: [auth]
      summary: Login with email and password
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LoginRequest"
      responses:
        "200":
          description: Login successful
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthResponse"
        "401":
          description: Invalid credentials
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /auth/logout:
    post:
      operationId: logout
      tags: [auth]
      summary: Logout
      responses:
        "200":
          description: Logged out
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"

  /auth/me:
    get:
      operationId: getMe
      tags: [auth]
      summary: Get current user
      responses:
        "200":
          description: Current user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "401":
          description: Not authenticated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  # DASHBOARD
  /dashboard/summary:
    get:
      operationId: getDashboardSummary
      tags: [dashboard]
      summary: Get dashboard summary metrics
      responses:
        "200":
          description: Dashboard summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashboardSummary"

  /dashboard/my-tasks:
    get:
      operationId: getMyTasks
      tags: [dashboard]
      summary: Get tasks assigned to the current user
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        "200":
          description: My tasks
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ProjectTask"

  /dashboard/recent-activity:
    get:
      operationId: getRecentActivity
      tags: [dashboard]
      summary: Get recent activity feed
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        "200":
          description: Recent activity
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ActivityEntry"

  /dashboard/project-stats:
    get:
      operationId: getProjectStats
      tags: [dashboard]
      summary: Get project status breakdown counts
      responses:
        "200":
          description: Project stats
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProjectStats"

  # CLIENTS
  /clients:
    get:
      operationId: listClients
      tags: [clients]
      summary: List all clients
      parameters:
        - name: search
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        "200":
          description: List of clients
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ClientList"

  /clients/sync:
    post:
      operationId: syncClients
      tags: [clients]
      summary: Sync clients from WHMCS
      responses:
        "200":
          description: Sync result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SyncResult"

  /clients/{id}:
    get:
      operationId: getClient
      tags: [clients]
      summary: Get client details
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Client details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ClientDetail"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  # PROSPECTS
  /prospects:
    get:
      operationId: listProspects
      tags: [prospects]
      summary: List prospects
      parameters:
        - name: search
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        "200":
          description: Prospect list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProspectList"
    post:
      operationId: createProspect
      tags: [prospects]
      summary: Create a prospect
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateProspectRequest"
      responses:
        "201":
          description: Created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Prospect"

  /prospects/{id}:
    get:
      operationId: getProspect
      tags: [prospects]
      summary: Get prospect details
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Prospect
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Prospect"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
    put:
      operationId: updateProspect
      tags: [prospects]
      summary: Update a prospect
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateProspectRequest"
      responses:
        "200":
          description: Updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Prospect"
    delete:
      operationId: deleteProspect
      tags: [prospects]
      summary: Delete a prospect
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Deleted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"

  /prospects/{id}/convert:
    post:
      operationId: convertProspect
      tags: [prospects]
      summary: Convert prospect to WHMCS client
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Converted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"

  /prospects/{id}/notes:
    post:
      operationId: addProspectNote
      tags: [prospects]
      summary: Add note to prospect
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AddNoteRequest"
      responses:
        "201":
          description: Note added
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProspectNote"

  # PROJECTS
  /projects:
    get:
      operationId: listProjects
      tags: [projects]
      summary: List all projects
      parameters:
        - name: search
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
        - name: clientId
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        "200":
          description: Project list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProjectList"

  /projects/sync:
    post:
      operationId: syncProjects
      tags: [projects]
      summary: Sync projects from WHMCS
      responses:
        "200":
          description: Sync result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SyncResult"

  /projects/{id}:
    get:
      operationId: getProject
      tags: [projects]
      summary: Get project details with tasks
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Project detail
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProjectDetail"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /projects/{id}/tasks:
    get:
      operationId: listTasksByProject
      tags: [tasks]
      summary: Get tasks for a project
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: assignedToMe
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: Task list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ProjectTask"

  # USERS
  /users:
    get:
      operationId: listUsers
      tags: [users]
      summary: List all users
      responses:
        "200":
          description: Users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
    post:
      operationId: createUser
      tags: [users]
      summary: Create a user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateUserRequest"
      responses:
        "201":
          description: Created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /users/{id}:
    get:
      operationId: getUser
      tags: [users]
      summary: Get user
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: User
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
    put:
      operationId: updateUser
      tags: [users]
      summary: Update user
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateUserRequest"
      responses:
        "200":
          description: Updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
    delete:
      operationId: deleteUser
      tags: [users]
      summary: Delete user
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Deleted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"

  # ACTIVITY LOG
  /activity:
    get:
      operationId: listActivity
      tags: [activity]
      summary: List activity log entries
      parameters:
        - name: userId
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        "200":
          description: Activity log
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ActivityList"

  # SETTINGS
  /settings:
    get:
      operationId: getSettings
      tags: [settings]
      summary: Get all system settings
      responses:
        "200":
          description: Settings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AppSettings"
    put:
      operationId: updateSettings
      tags: [settings]
      summary: Update system settings
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateSettingsRequest"
      responses:
        "200":
          description: Updated settings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AppSettings"

  /settings/connectivity/{service}:
    post:
      operationId: testConnectivity
      tags: [settings]
      summary: Test connectivity for a service
      parameters:
        - name: service
          in: path
          required: true
          schema:
            type: string
            enum: [whmcs, claude, google_ads]
      responses:
        "200":
          description: Connectivity result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConnectivityResult"

  # AI
  /ai/summarize-project/{id}:
    post:
      operationId: summarizeProject
      tags: [ai]
      summary: Generate AI summary for a project
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AiTextResult"

  /ai/generate-update/{id}:
    post:
      operationId: generateProjectUpdate
      tags: [ai]
      summary: Generate client-friendly project update
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Update text
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AiTextResult"

  /ai/suggest-next-steps/{id}:
    post:
      operationId: suggestNextSteps
      tags: [ai]
      summary: Suggest next steps for a project
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Suggestions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AiTextResult"

  # GOOGLE ADS
  /ads/campaigns:
    get:
      operationId: listAdCampaigns
      tags: [ads]
      summary: List Google Ads campaigns
      responses:
        "200":
          description: Campaigns
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AdCampaign"

  /ads/campaigns/{campaignId}/keywords:
    get:
      operationId: getCampaignKeywords
      tags: [ads]
      summary: Get keywords for a campaign
      parameters:
        - name: campaignId
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Keywords
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AdKeyword"

  # WHMCS API EXPLORER
  /whmcs/available-calls:
    get:
      operationId: getWhmcsAvailableCalls
      tags: [whmcs]
      summary: Get list of available WHMCS API calls
      responses:
        "200":
          description: Available API calls
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WhmcsApiCall"

  /whmcs/execute:
    post:
      operationId: executeWhmcsCall
      tags: [whmcs]
      summary: Execute a WHMCS API call
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WhmcsExecuteRequest"
      responses:
        "200":
          description: API response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WhmcsExecuteResponse"

components:
  schemas:
    HealthStatus:
      type: object
      properties:
        status:
          type: string
      required: [status]

    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
      required: [error]

    MessageResponse:
      type: object
      properties:
        message:
          type: string
      required: [message]

    # AUTH
    LoginRequest:
      type: object
      properties:
        email:
          type: string
        password:
          type: string
      required: [email, password]

    AuthResponse:
      type: object
      properties:
        token:
          type: string
        user:
          $ref: "#/components/schemas/User"
      required: [token, user]

    User:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
        name:
          type: string
        role:
          type: string
          enum: [admin, manager, freelancer]
        avatarUrl:
          type: string
          nullable: true
        createdAt:
          type: string
      required: [id, email, name, role, createdAt]

    CreateUserRequest:
      type: object
      properties:
        email:
          type: string
        name:
          type: string
        role:
          type: string
          enum: [admin, manager, freelancer]
        password:
          type: string
      required: [email, name, role, password]

    UpdateUserRequest:
      type: object
      properties:
        name:
          type: string
        role:
          type: string
          enum: [admin, manager, freelancer]
        password:
          type: string

    # DASHBOARD
    DashboardSummary:
      type: object
      properties:
        totalClients:
          type: integer
        activeProjects:
          type: integer
        openTasks:
          type: integer
        totalProspects:
          type: integer
        tasksAssignedToMe:
          type: integer
        projectsCompletedThisMonth:
          type: integer
      required: [totalClients, activeProjects, openTasks, totalProspects, tasksAssignedToMe, projectsCompletedThisMonth]

    ProjectStats:
      type: object
      properties:
        active:
          type: integer
        completed:
          type: integer
        onHold:
          type: integer
        cancelled:
          type: integer
      required: [active, completed, onHold, cancelled]

    # CLIENTS
    Client:
      type: object
      properties:
        id:
          type: string
        whmcsId:
          type: string
          nullable: true
        name:
          type: string
        email:
          type: string
        company:
          type: string
          nullable: true
        phone:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        status:
          type: string
        currency:
          type: string
          nullable: true
        createdAt:
          type: string
        lastSync:
          type: string
          nullable: true
      required: [id, name, email, status, createdAt]

    ClientDetail:
      allOf:
        - $ref: "#/components/schemas/Client"
        - type: object
          properties:
            address:
              type: string
              nullable: true
            city:
              type: string
              nullable: true
            state:
              type: string
              nullable: true
            postcode:
              type: string
              nullable: true
            notes:
              type: string
              nullable: true
            projects:
              type: array
              items:
                $ref: "#/components/schemas/Project"
            adCampaigns:
              type: array
              items:
                $ref: "#/components/schemas/AdCampaign"

    ClientList:
      type: object
      properties:
        clients:
          type: array
          items:
            $ref: "#/components/schemas/Client"
        total:
          type: integer
      required: [clients, total]

    SyncResult:
      type: object
      properties:
        synced:
          type: integer
        created:
          type: integer
        updated:
          type: integer
        errors:
          type: integer
        message:
          type: string
      required: [synced, created, updated, errors, message]

    # PROSPECTS
    Prospect:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        email:
          type: string
        company:
          type: string
          nullable: true
        phone:
          type: string
          nullable: true
        status:
          type: string
          enum: [new, contacted, qualified, proposal_sent, won, lost]
        source:
          type: string
          nullable: true
        assignedTo:
          type: string
          nullable: true
        assignedUser:
          $ref: "#/components/schemas/User"
          nullable: true
        notes:
          type: array
          items:
            $ref: "#/components/schemas/ProspectNote"
        createdAt:
          type: string
        updatedAt:
          type: string
      required: [id, name, email, status, createdAt, updatedAt]

    ProspectList:
      type: object
      properties:
        prospects:
          type: array
          items:
            $ref: "#/components/schemas/Prospect"
        total:
          type: integer
      required: [prospects, total]

    CreateProspectRequest:
      type: object
      properties:
        name:
          type: string
        email:
          type: string
        company:
          type: string
        phone:
          type: string
        status:
          type: string
          enum: [new, contacted, qualified, proposal_sent, won, lost]
        source:
          type: string
        assignedTo:
          type: string
      required: [name, email]

    UpdateProspectRequest:
      type: object
      properties:
        name:
          type: string
        email:
          type: string
        company:
          type: string
        phone:
          type: string
        status:
          type: string
          enum: [new, contacted, qualified, proposal_sent, won, lost]
        source:
          type: string
        assignedTo:
          type: string

    ProspectNote:
      type: object
      properties:
        id:
          type: string
        content:
          type: string
        createdBy:
          type: string
        authorName:
          type: string
          nullable: true
        createdAt:
          type: string
      required: [id, content, createdBy, createdAt]

    AddNoteRequest:
      type: object
      properties:
        content:
          type: string
      required: [content]

    # PROJECTS
    Project:
      type: object
      properties:
        id:
          type: string
        whmcsId:
          type: string
          nullable: true
        title:
          type: string
        description:
          type: string
          nullable: true
        status:
          type: string
          enum: [pending, in_progress, completed, on_hold, cancelled]
        clientId:
          type: string
          nullable: true
        clientName:
          type: string
          nullable: true
        assignedUsers:
          type: array
          items:
            type: string
        taskCount:
          type: integer
        completedTaskCount:
          type: integer
        dueDate:
          type: string
          nullable: true
        createdAt:
          type: string
        lastSync:
          type: string
          nullable: true
      required: [id, title, status, taskCount, completedTaskCount, createdAt]

    ProjectList:
      type: object
      properties:
        projects:
          type: array
          items:
            $ref: "#/components/schemas/Project"
        total:
          type: integer
      required: [projects, total]

    ProjectDetail:
      allOf:
        - $ref: "#/components/schemas/Project"
        - type: object
          properties:
            tasks:
              type: array
              items:
                $ref: "#/components/schemas/ProjectTask"
            billingInfo:
              type: object
              nullable: true
              properties:
                amount:
                  type: number
                currency:
                  type: string
                type:
                  type: string

    ProjectTask:
      type: object
      properties:
        id:
          type: string
        whmcsId:
          type: string
          nullable: true
        projectId:
          type: string
        title:
          type: string
        description:
          type: string
          nullable: true
        status:
          type: string
          enum: [pending, in_progress, completed, on_hold]
        priority:
          type: string
          enum: [low, medium, high, urgent]
        assignedTo:
          type: string
          nullable: true
        assignedUser:
          $ref: "#/components/schemas/User"
          nullable: true
        projectTitle:
          type: string
          nullable: true
        dueDate:
          type: string
          nullable: true
        createdAt:
          type: string
      required: [id, projectId, title, status, priority, createdAt]

    # ACTIVITY
    ActivityEntry:
      type: object
      properties:
        id:
          type: string
        userId:
          type: string
        userName:
          type: string
        action:
          type: string
        entity:
          type: string
        entityId:
          type: string
          nullable: true
        entityName:
          type: string
          nullable: true
        meta:
          type: object
          nullable: true
        createdAt:
          type: string
      required: [id, userId, userName, action, entity, createdAt]

    ActivityList:
      type: object
      properties:
        entries:
          type: array
          items:
            $ref: "#/components/schemas/ActivityEntry"
        total:
          type: integer
      required: [entries, total]

    # SETTINGS
    AppSettings:
      type: object
      properties:
        whmcsUrl:
          type: string
          nullable: true
        whmcsApiIdentifier:
          type: string
          nullable: true
        whmcsApiSecretConfigured:
          type: boolean
        claudeApiConfigured:
          type: boolean
        googleAdsConfigured:
          type: boolean
        syncInterval:
          type: integer
          description: Sync interval in minutes
        featuresEnabled:
          type: object
          properties:
            aiFeatures:
              type: boolean
            googleAds:
              type: boolean
            prospects:
              type: boolean
          required: [aiFeatures, googleAds, prospects]
      required: [whmcsApiSecretConfigured, claudeApiConfigured, googleAdsConfigured, syncInterval, featuresEnabled]

    UpdateSettingsRequest:
      type: object
      properties:
        whmcsUrl:
          type: string
        whmcsApiIdentifier:
          type: string
        whmcsApiSecret:
          type: string
        claudeApiKey:
          type: string
        googleAdsClientId:
          type: string
        googleAdsClientSecret:
          type: string
        googleAdsDeveloperToken:
          type: string
        syncInterval:
          type: integer
        featuresEnabled:
          type: object
          properties:
            aiFeatures:
              type: boolean
            googleAds:
              type: boolean
            prospects:
              type: boolean

    ConnectivityResult:
      type: object
      properties:
        connected:
          type: boolean
        message:
          type: string
        latencyMs:
          type: integer
          nullable: true
      required: [connected, message]

    # AI
    AiTextResult:
      type: object
      properties:
        text:
          type: string
        model:
          type: string
          nullable: true
      required: [text]

    # GOOGLE ADS
    AdCampaign:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        status:
          type: string
        budget:
          type: number
          nullable: true
        spend:
          type: number
          nullable: true
        impressions:
          type: integer
          nullable: true
        clicks:
          type: integer
          nullable: true
        ctr:
          type: number
          nullable: true
        clientId:
          type: string
          nullable: true
        clientName:
          type: string
          nullable: true
        startDate:
          type: string
          nullable: true
        endDate:
          type: string
          nullable: true
      required: [id, name, status]

    AdKeyword:
      type: object
      properties:
        id:
          type: string
        text:
          type: string
        matchType:
          type: string
        status:
          type: string
        bids:
          type: number
          nullable: true
        impressions:
          type: integer
          nullable: true
        clicks:
          type: integer
          nullable: true
      required: [id, text, matchType, status]

    # WHMCS
    WhmcsApiCall:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        category:
          type: string
        parameters:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              type:
                type: string
              required:
                type: boolean
              description:
                type: string
            required: [name, type, required]
      required: [name, description, category, parameters]

    WhmcsExecuteRequest:
      type: object
      properties:
        action:
          type: string
        params:
          type: object
      required: [action]

    WhmcsExecuteResponse:
      type: object
      properties:
        result:
          type: string
        data:
          type: object
          nullable: true
        error:
          type: string
          nullable: true
      required: [result]
