openapi: 3.0.0
info:
  title: Clinic Management System API
  version: 1.0.0
  description: |
    API documentation for the Clinic Management System.
    This API provides endpoints for managing clinics, appointments, patients, doctors, and subscriptions.
  contact:
    name: API Support
    email: support@example.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: /api
    description: API base path

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    CSRF:
      type: apiKey
      in: header
      name: X-CSRF-Token

  schemas:
    Error:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              example: VALIDATION_ERROR
            message:
              type: string
              example: Invalid input data
            details:
              type: string
              example: email: invalid format

    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        firstName:
          type: string
        lastName:
          type: string
        roles:
          type: array
          items:
            type: string
        clinicId:
          type: string
          format: uuid
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    Clinic:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        address:
          type: string
        phone:
          type: string
        email:
          type: string
          format: email
        subscriptionPlanId:
          type: string
          format: uuid
        maxDoctors:
          type: integer
        maxStaff:
          type: integer
        maxPatientsPerMonth:
          type: integer
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    Appointment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        patientId:
          type: string
          format: uuid
        doctorId:
          type: string
          format: uuid
        clinicId:
          type: string
          format: uuid
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum: [pending, confirmed, cancelled, completed, rescheduled, no_show]
        startTime:
          type: string
          format: date-time
        endTime:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    PaginatedResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Appointment'
        total:
          type: integer
        page:
          type: integer
        limit:
          type: integer

    Subscription:
      type: object
      properties:
        id:
          type: string
          format: uuid
        clinicId:
          type: string
          format: uuid
        planId:
          type: string
          format: uuid
        billingPeriod:
          type: string
          enum: [monthly, annual]
        startDate:
          type: string
          format: date-time
        endDate:
          type: string
          format: date-time
        status:
          type: string
          enum: [active, cancelled, expired]
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    SubscriptionUsage:
      type: object
      properties:
        id:
          type: string
          format: uuid
        clinicId:
          type: string
          format: uuid
        currentDoctors:
          type: integer
        currentStaff:
          type: integer
        patientsThisMonth:
          type: integer
        aiConsultsUsed:
          type: integer
        lastResetDate:
          type: string
          format: date-time
        usageHistory:
          type: array
          items:
            $ref: '#/components/schemas/UsageRecord'

    UsageRecord:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        doctorsAdded:
          type: integer
        staffAdded:
          type: integer
        patientsAdded:
          type: integer
        aiConsultsAdded:
          type: integer

security:
  - BearerAuth: []
  - CSRF: []

paths:
  /auth/login:
    post:
      summary: Login user
      tags: [Auth]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                  format: password
      responses:
        '200':
          description: Login successful
          content:
            application/json:
              schema:
                type: object
                properties:
                  accessToken:
                    type: string
                  refreshToken:
                    type: string
        '401':
          description: Invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /auth/refresh:
    post:
      summary: Refresh access token
      tags: [Auth]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [refreshToken]
              properties:
                refreshToken:
                  type: string
      responses:
        '200':
          description: Token refreshed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  accessToken:
                    type: string
                  refreshToken:
                    type: string
        '401':
          description: Invalid refresh token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /appointments:
    get:
      summary: List appointments
      description: Get a list of appointments for a clinic with pagination
      tags: [Appointments]
      parameters:
        - name: clinic_id
          in: query
          required: true
          description: Clinic ID
          schema:
            type: string
            format: uuid
        - name: page
          in: query
          description: Page number
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: Items per page
          schema:
            type: integer
            default: 10
      responses:
        '200':
          description: List of appointments
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedResponse'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    post:
      summary: Create a new appointment
      description: Create a new appointment with the provided details
      tags: [Appointments]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Appointment'
      responses:
        '201':
          description: Created appointment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Appointment'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /appointments/{id}:
    get:
      summary: Get appointment details
      description: Get details of a specific appointment by ID
      tags: [Appointments]
      parameters:
        - name: id
          in: path
          required: true
          description: Appointment ID
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Appointment details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Appointment'
        '404':
          description: Appointment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    put:
      summary: Update appointment
      description: Update an existing appointment
      tags: [Appointments]
      parameters:
        - name: id
          in: path
          required: true
          description: Appointment ID
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Appointment'
      responses:
        '200':
          description: Updated appointment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Appointment'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Appointment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /clinics:
    get:
      summary: Get all clinics
      tags: [Clinics]
      responses:
        '200':
          description: List of clinics
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Clinic'
    post:
      summary: Create a new clinic
      tags: [Clinics]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Clinic'
      responses:
        '201':
          description: Clinic created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clinic'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /clinics/{id}:
    get:
      summary: Get clinic by ID
      tags: [Clinics]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Clinic details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clinic'
        '404':
          description: Clinic not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    put:
      summary: Update clinic
      tags: [Clinics]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Clinic'
      responses:
        '200':
          description: Clinic updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clinic'
        '404':
          description: Clinic not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      summary: Delete clinic
      tags: [Clinics]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Clinic deleted successfully
        '404':
          description: Clinic not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /subscriptions:
    get:
      summary: Get all subscriptions
      tags: [Subscriptions]
      responses:
        '200':
          description: List of subscriptions
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subscription'
    post:
      summary: Create a new subscription
      tags: [Subscriptions]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Subscription'
      responses:
        '201':
          description: Subscription created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /subscriptions/{id}:
    get:
      summary: Get subscription by ID
      tags: [Subscriptions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Subscription details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    put:
      summary: Update subscription
      tags: [Subscriptions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Subscription'
      responses:
        '200':
          description: Subscription updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      summary: Cancel subscription
      tags: [Subscriptions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Subscription cancelled successfully
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /subscriptions/{id}/usage:
    get:
      summary: Get subscription usage
      tags: [Subscriptions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Subscription usage details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionUsage'
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error' 