openapi: 3.0.3
info:
  title: Chatterbox API
  version: 1.0.0
  description: Production-grade REST & Socket.io real-time chat API specification for Chatterbox. Includes formalized request and response schemas, authentication patterns, error codes, and WebSocket events.

servers:
  - url: https://frontend-task-chatapp.onrender.com/api
    description: Production Live API

security:
  - bearerAuth: []

paths:
  /auth/login:
    post:
      tags:
        - Auth
      summary: Log in or Auto-Register
      description: Single-step authentication. If the phone number exists, returns session credentials. If the phone number is new, automatically provisions a new account.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            example:
              phone: "+19991234567"
              name: "Alice Developer"
      responses:
        '200':
          description: Successfully authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/me:
    get:
      tags:
        - Auth
      summary: Get Current User Profile
      description: Returns user identity matching the Bearer JWT token in Authorization header.
      responses:
        '200':
          description: Current user profile
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '401':
          description: Unauthorized / Invalid Token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /users/search:
    get:
      tags:
        - Users
      summary: Search Users
      description: Searches registered users by name or phone substring. Query parameter `query` or `q` is supported.
      parameters:
        - name: query
          in: query
          description: Search query substring
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Matching users list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /conversations:
    get:
      tags:
        - Conversations
      summary: List Conversations
      description: Fetches all direct and group conversations for the authenticated user, ordered by most recent update.
      responses:
        '200':
          description: List of user conversations
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Conversation'
    post:
      tags:
        - Conversations
      summary: Start Direct Conversation
      description: Creates or retrieves an existing 1-to-1 conversation with the designated user ID.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartConversationRequest'
            example:
              userId: "6a88601ee5d6aac97522899c"
      responses:
        '200':
          description: Existing direct conversation returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'
        '201':
          description: New direct conversation created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'

  /conversations/group:
    post:
      tags:
        - Groups
      summary: Create Group Conversation
      description: Creates a multi-participant group conversation (requires group name and at least 2 other participant IDs).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateGroupRequest'
            example:
              name: "Avengers Core"
              participantIds:
                - "6a886060e5d6aac975228aff"
                - "6a886061e5d6aac975228b05"
      responses:
        '201':
          description: Group conversation created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'
        '400':
          description: Validation error (less than 3 total members or missing name)

  /conversations/{id}:
    patch:
      tags:
        - Groups
      summary: Rename Group Conversation
      description: Renames a group conversation. Must be executed by a group admin.
      parameters:
        - name: id
          in: path
          required: true
          description: Group Conversation ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenameGroupRequest'
            example:
              name: "Avengers Elite"
      responses:
        '200':
          description: Group renamed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'
        '403':
          description: Forbidden (Caller is not an admin)

  /conversations/{id}/admins:
    post:
      tags:
        - Groups
      summary: Promote Member to Admin
      description: Promotes an existing participant to admin status. Requires admin permissions.
      parameters:
        - name: id
          in: path
          required: true
          description: Group Conversation ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PromoteRequest'
            example:
              userId: "6a886060e5d6aac975228aff"
      responses:
        '200':
          description: Member promoted to admin
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'

  /conversations/{id}/participants:
    post:
      tags:
        - Groups
      summary: Add Participants to Group
      description: Adds one or more users to an existing group conversation. Requires admin permissions.
      parameters:
        - name: id
          in: path
          required: true
          description: Group Conversation ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddParticipantsRequest'
            example:
              userIds:
                - "6a886061e5d6aac975228b05"
      responses:
        '200':
          description: Participants added to group
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'

  /conversations/{id}/participants/{userId}:
    delete:
      tags:
        - Groups
      summary: Remove Participant / Leave Group
      description: Removes a participant from a group (if caller is admin) or allows the caller to leave the group.
      parameters:
        - name: id
          in: path
          required: true
          description: Group Conversation ID
          schema:
            type: string
        - name: userId
          in: path
          required: true
          description: User ID to remove
          schema:
            type: string
      responses:
        '200':
          description: Participant removed or left successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Conversation'

  /conversations/{id}/messages:
    get:
      tags:
        - Messages
      summary: Get Message History
      description: Fetches chronological message history for a direct or group conversation.
      parameters:
        - name: id
          in: path
          required: true
          description: Conversation ID
          schema:
            type: string
      responses:
        '200':
          description: Messages history list
          content:
            application/json:
              schema:
                type: object
                properties:
                  messages:
                    type: array
                    items:
                      $ref: '#/components/schemas/Message'
                  hasMore:
                    type: boolean

  /messages:
    post:
      tags:
        - Messages
      summary: Send Message
      description: Dispatches a new text message to a conversation. Reconciles with optimistic dispatch on client and triggers Socket.io broadcast to peers.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMessageRequest'
            example:
              conversationId: "6a886020e5d6aac9752289b2"
              text: "Hello world!"
      responses:
        '200':
          description: Message sent and persisted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        '201':
          description: Message created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'

  /health:
    get:
      tags:
        - System
      summary: Service Health Check
      description: Checks whether the backend server is operational. Hosted at root `/health`.
      security: []
      responses:
        '200':
          description: Service is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "ok"

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

  schemas:
    User:
      type: object
      required:
        - _id
        - name
        - phone
      properties:
        _id:
          type: string
          example: "6a886007e5d6aac9752288cb"
        name:
          type: string
          example: "Alice Developer"
        phone:
          type: string
          example: "+19991234567"
        createdAt:
          type: string
          format: date-time
          example: "2026-08-21T14:26:15.688Z"

    DirectParticipant:
      type: object
      required:
        - _id
        - name
        - phone
      properties:
        _id:
          type: string
          example: "6a88601ee5d6aac97522899c"
        name:
          type: string
          example: "Bob Test"
        phone:
          type: string
          example: "+1888489938"

    ConversationLastMessage:
      type: object
      properties:
        text:
          type: string
          example: "Hello Bob! How are you?"
        sender:
          type: string
          example: "6a88601de5d6aac975228994"
        createdAt:
          type: string
          format: date-time
          example: "2026-08-21T14:26:41.507Z"

    Conversation:
      type: object
      required:
        - _id
        - type
      properties:
        _id:
          type: string
          example: "6a886020e5d6aac9752289b2"
        type:
          type: string
          enum: [direct, group]
          example: "direct"
        name:
          type: string
          example: "Avengers Elite"
        createdBy:
          type: string
          example: "6a886060e5d6aac975228afa"
        admins:
          type: array
          items:
            type: string
        participants:
          type: array
          items:
            $ref: '#/components/schemas/DirectParticipant'
        participant:
          $ref: '#/components/schemas/DirectParticipant'
        lastMessage:
          $ref: '#/components/schemas/ConversationLastMessage'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    Message:
      type: object
      required:
        - _id
        - conversation
        - sender
        - text
        - createdAt
      properties:
        _id:
          type: string
          example: "6a886021e5d6aac9752289be"
        conversation:
          type: string
          example: "6a886020e5d6aac9752289b2"
        sender:
          type: string
          example: "6a88601de5d6aac975228994"
        text:
          type: string
          example: "Hello Bob! How are you?"
        createdAt:
          type: string
          format: date-time
          example: "2026-08-21T14:26:41.507Z"

    LoginRequest:
      type: object
      required:
        - phone
        - name
      properties:
        phone:
          type: string
          example: "+19991234567"
        name:
          type: string
          example: "Alice Developer"

    AuthResponse:
      type: object
      required:
        - token
        - user
      properties:
        token:
          type: string
          example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
        user:
          $ref: '#/components/schemas/User'

    StartConversationRequest:
      type: object
      required:
        - userId
      properties:
        userId:
          type: string
          example: "6a88601ee5d6aac97522899c"

    CreateGroupRequest:
      type: object
      required:
        - name
        - participantIds
      properties:
        name:
          type: string
          example: "Avengers Team"
        participantIds:
          type: array
          items:
            type: string
          example:
            - "6a886060e5d6aac975228aff"
            - "6a886061e5d6aac975228b05"

    RenameGroupRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          example: "Avengers Elite"

    PromoteRequest:
      type: object
      required:
        - userId
      properties:
        userId:
          type: string
          example: "6a886060e5d6aac975228aff"

    AddParticipantsRequest:
      type: object
      required:
        - userIds
      properties:
        userIds:
          type: array
          items:
            type: string
          example:
            - "6a886061e5d6aac975228b05"

    SendMessageRequest:
      type: object
      required:
        - conversationId
        - text
      properties:
        conversationId:
          type: string
          example: "6a886020e5d6aac9752289b2"
        text:
          type: string
          example: "Hello Bob! How are you?"

    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
              example: "Validation failed"
            code:
              type: string
              example: "VALIDATION_ERROR"
            details:
              type: array
              items:
                type: object
