openapi: 3.0.3
info:
  title: AImanager API
  version: 1.0.0
  description: OpenAPI specification for AImanager endpoints.
servers:
  - url: /

tags:
  - name: Health
  - name: Models
  - name: Auth
  - name: Chat
  - name: History

paths:
  /health:
    get:
      tags: [Health]
      summary: Health check
      responses:
        '200':
          description: Service status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'

  /models:
    get:
      tags: [Models]
      summary: List available text models
      responses:
        '200':
          description: Model list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ModelInfo'
        '502':
          description: Failed to load models
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/register:
    post:
      tags: [Auth]
      summary: Register a new user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterRequest'
            example:
              username: "alice"
              email: "alice@example.com"
              password: "s3cretP@ssw0rd"
      responses:
        '201':
          description: User created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterResponse'
        '400':
          description: Missing required fields
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Username or email already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many auth requests
          headers:
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/login:
    post:
      tags: [Auth]
      summary: Login with username or email
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            example:
              email: "alice@example.com"
              password: "s3cretP@ssw0rd"
      responses:
        '200':
          description: Login successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
        '400':
          description: Missing identifier or password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many auth requests
          headers:
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/information:
    get:
      tags: [Auth]
      summary: Get current user information
      security:
        - bearerAuth: []
      responses:
        '200':
          description: User profile
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserInfoResponse'
        '401':
          description: Missing/invalid bearer token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: User not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many auth requests
          headers:
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/forgot-password:
    post:
      tags: [Auth]
      summary: Request a password reset token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ForgotPasswordRequest'
            example:
              email: "alice@example.com"
      responses:
        '200':
          description: Reset request accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForgotPasswordResponse'
        '400':
          description: Email missing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many auth requests
          headers:
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/reset-password:
    post:
      tags: [Auth]
      summary: Reset password with a reset token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResetPasswordRequest'
            example:
              token: "b2f5ff47436671b6e533d8dc3614845d"
              new_password: "n3wS3cretP@ss"
      responses:
        '200':
          description: Password reset successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResetPasswordResponse'
        '400':
          description: Invalid token or missing fields
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many auth requests
          headers:
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /chat:
    post:
      tags: [Chat]
      summary: Send a message and get AI response
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatRequest'
            example:
              message: "Hello, what's the weather like today?"
              chat_id: ""
              model: "gpt-4-mini"
      responses:
        '200':
          description: Chat response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatResponse'
        '400':
          description: Invalid message
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Chat not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many chat requests
          headers:
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Unable to create chat
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /history:
    get:
      tags: [History]
      summary: List chat history headers
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Chat list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/HistoryChatItem'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /history/search:
    get:
      tags: [History]
      summary: Search chats by header text
      security:
        - bearerAuth: []
      parameters:
        - in: query
          name: query
          required: false
          schema:
            type: string
          description: Search keyword. Empty value returns an empty array.
      responses:
        '200':
          description: Matching chats
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/HistoryChatItem'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /history/{id}:
    get:
      tags: [History]
      summary: Get full turns for a chat
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
          description: Chat ID
      responses:
        '200':
          description: Chat turns
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/HistoryTurnItem'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Chat not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    HealthResponse:
      type: object
      properties:
        ok:
          type: boolean
      required: [ok]

    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        details:
          nullable: true
      required: [error, details]

    RegisterRequest:
      type: object
      properties:
        username:
          type: string
        email:
          type: string
          format: email
        password:
          type: string
      required: [username, email, password]

    RegisterResponse:
      type: object
      properties:
        id:
          type: string
        username:
          type: string
        email:
          type: string
          format: email
        created_at:
          type: string
          format: date-time
      required: [id, username, email, created_at]

    LoginRequest:
      type: object
      properties:
        username:
          type: string
        email:
          type: string
          format: email
        password:
          type: string
      required: [password]
      anyOf:
        - required: [username]
        - required: [email]

    LoginResponse:
      type: object
      properties:
        token:
          type: string
        token_type:
          type: string
          example: Bearer
        expires_in:
          type: integer
        user:
          type: object
          properties:
            id:
              type: string
            username:
              type: string
            email:
              type: string
              format: email
            last_login:
              type: string
              format: date-time
            created_at:
              type: string
              format: date-time
          required: [id, username, email, last_login, created_at]
      required: [token, token_type, expires_in, user]

    UserInfoResponse:
      type: object
      properties:
        username:
          type: string
        email:
          type: string
          format: email
        last_login:
          type: string
          nullable: true
        created_at:
          type: string
          format: date-time
      required: [username, email, last_login, created_at]

    ForgotPasswordRequest:
      type: object
      properties:
        email:
          type: string
          format: email
      required: [email]

    ForgotPasswordResponse:
      type: object
      properties:
        message:
          type: string
        reset_token:
          type: string
          description: Only returned in non-production environments.
        expires_at:
          type: string
          format: date-time
          description: Only returned in non-production environments.
      required: [message]

    ResetPasswordRequest:
      type: object
      properties:
        token:
          type: string
        password:
          type: string
        new_password:
          type: string
      required: [token]
      anyOf:
        - required: [password]
        - required: [new_password]

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

    ModelInfo:
      type: object
      properties:
        model:
          type: string
        description:
          type: string
      required: [model, description]

    ChatRequest:
      type: object
      properties:
        message:
          type: string
        chat_id:
          type: string
        model:
          type: string
      required: [message]

    ChatResponse:
      type: object
      properties:
        response:
          type: string
        chat_id:
          type: string
        created_at:
          type: string
          format: date-time
      required: [response, chat_id, created_at]

    HistoryChatItem:
      type: object
      properties:
        id:
          type: string
        header:
          type: string
        created_at:
          type: string
          format: date-time
      required: [id, header, created_at]

    HistoryTurnItem:
      type: object
      properties:
        id:
          type: string
        question:
          type: string
        response:
          type: string
        created_at:
          type: string
          format: date-time
      required: [id, question, response, created_at]
