openapi: 3.0.3
info:
  title: KiviCare API
  description: REST API for KiviCare healthcare management system
  version: 1.0.0
  contact:
    name: Descomplicar® Crescimento Digital
    url: https://descomplicar.pt

servers:
  - url: /wp-json/kivicare/v1
    description: WordPress REST API base

security:
  - BearerAuth: []

paths:
  # Authentication
  /auth/login:
    post:
      tags: [Authentication]
      summary: User login
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [username, password]
              properties:
                username: {type: string}
                password: {type: string, format: password}
      responses:
        200:
          description: Login successful
          content:
            application/json:
              schema:
                type: object
                properties:
                  token: {type: string}
                  user_id: {type: integer}
                  role: {type: string, enum: [administrator, doctor, patient, receptionist]}
                  expires_at: {type: string, format: date-time}
        401:
          $ref: '#/components/responses/UnauthorizedError'

  # Clinics
  /clinics:
    get:
      tags: [Clinics]
      summary: List clinics
      parameters:
        - name: status
          in: query
          schema: {type: integer, enum: [0, 1]}
      responses:
        200:
          description: Clinics list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Clinic'
    post:
      tags: [Clinics]
      summary: Create clinic
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClinicInput'
      responses:
        201:
          description: Clinic created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clinic'
        400:
          $ref: '#/components/responses/ValidationError'

  /clinics/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema: {type: integer}
    get:
      tags: [Clinics]
      summary: Get clinic by ID
      responses:
        200:
          description: Clinic details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clinic'
        404:
          $ref: '#/components/responses/NotFoundError'
    put:
      tags: [Clinics]
      summary: Update clinic
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClinicInput'
      responses:
        200:
          description: Clinic updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clinic'
    delete:
      tags: [Clinics]
      summary: Delete clinic
      responses:
        204:
          description: Clinic deleted
        409:
          description: Cannot delete clinic with active patients/doctors

  # Patients
  /patients:
    get:
      tags: [Patients]
      summary: List patients
      parameters:
        - name: clinic_id
          in: query
          schema: {type: integer}
        - name: search
          in: query
          schema: {type: string}
      responses:
        200:
          description: Patients list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Patient'
    post:
      tags: [Patients]
      summary: Create patient
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatientInput'
      responses:
        201:
          description: Patient created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Patient'

  /patients/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema: {type: integer}
    get:
      tags: [Patients]
      summary: Get patient by ID
      responses:
        200:
          description: Patient details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Patient'
    put:
      tags: [Patients]
      summary: Update patient
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatientInput'
      responses:
        200:
          description: Patient updated

  /patients/{id}/encounters:
    parameters:
      - name: id
        in: path
        required: true
        schema: {type: integer}
    get:
      tags: [Patients]
      summary: Get patient encounters
      responses:
        200:
          description: Patient encounters
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Encounter'

  # Appointments
  /appointments:
    get:
      tags: [Appointments]
      summary: List appointments
      parameters:
        - name: doctor_id
          in: query
          schema: {type: integer}
        - name: patient_id
          in: query
          schema: {type: integer}
        - name: date
          in: query
          schema: {type: string, format: date}
      responses:
        200:
          description: Appointments list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Appointment'
    post:
      tags: [Appointments]
      summary: Create appointment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppointmentInput'
      responses:
        201:
          description: Appointment created

  /appointments/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema: {type: integer}
    get:
      tags: [Appointments]
      summary: Get appointment by ID
      responses:
        200:
          description: Appointment details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Appointment'
    put:
      tags: [Appointments]
      summary: Update appointment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppointmentInput'
      responses:
        200:
          description: Appointment updated
    delete:
      tags: [Appointments]
      summary: Cancel appointment
      responses:
        200:
          description: Appointment cancelled

  # Encounters
  /encounters:
    get:
      tags: [Encounters]
      summary: List encounters
      parameters:
        - name: patient_id
          in: query
          schema: {type: integer}
        - name: doctor_id
          in: query
          schema: {type: integer}
      responses:
        200:
          description: Encounters list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Encounter'
    post:
      tags: [Encounters]
      summary: Create encounter
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EncounterInput'
      responses:
        201:
          description: Encounter created

  /encounters/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema: {type: integer}
    get:
      tags: [Encounters]
      summary: Get encounter by ID
      responses:
        200:
          description: Encounter details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Encounter'
    put:
      tags: [Encounters]
      summary: Update encounter
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EncounterInput'
      responses:
        200:
          description: Encounter updated

  /encounters/{id}/prescriptions:
    parameters:
      - name: id
        in: path
        required: true
        schema: {type: integer}
    get:
      tags: [Prescriptions]
      summary: Get encounter prescriptions
      responses:
        200:
          description: Prescriptions list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Prescription'
    post:
      tags: [Prescriptions]
      summary: Add prescription to encounter
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PrescriptionInput'
      responses:
        201:
          description: Prescription added

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

  schemas:
    Clinic:
      type: object
      properties:
        id: {type: integer}
        name: {type: string}
        email: {type: string, format: email}
        telephone_no: {type: string}
        address: {type: string}
        city: {type: string}
        state: {type: string}
        country: {type: string}
        postal_code: {type: string}
        status: {type: integer, enum: [0, 1]}
        created_at: {type: string, format: date-time}

    ClinicInput:
      type: object
      required: [name, email, telephone_no]
      properties:
        name: {type: string, maxLength: 191}
        email: {type: string, format: email, maxLength: 191}
        telephone_no: {type: string, maxLength: 191}
        address: {type: string}
        city: {type: string, maxLength: 191}
        state: {type: string, maxLength: 191}
        country: {type: string, maxLength: 191}
        postal_code: {type: string, maxLength: 191}

    Patient:
      type: object
      properties:
        id: {type: integer}
        display_name: {type: string}
        user_email: {type: string, format: email}
        phone: {type: string}
        birth_date: {type: string, format: date}
        gender: {type: string, enum: [M, F, Other]}
        clinic_id: {type: integer}
        registration_date: {type: string, format: date-time}

    PatientInput:
      type: object
      required: [display_name, user_email, clinic_id]
      properties:
        display_name: {type: string, maxLength: 250}
        user_email: {type: string, format: email, maxLength: 100}
        phone: {type: string}
        birth_date: {type: string, format: date}
        gender: {type: string, enum: [M, F, Other]}
        clinic_id: {type: integer}

    Appointment:
      type: object
      properties:
        id: {type: integer}
        appointment_start_date: {type: string, format: date}
        appointment_start_time: {type: string, format: time}
        appointment_end_date: {type: string, format: date}
        appointment_end_time: {type: string, format: time}
        visit_type: {type: string}
        clinic_id: {type: integer}
        doctor_id: {type: integer}
        patient_id: {type: integer}
        description: {type: string}
        status: {type: integer, enum: [0, 1, 2, 3]}
        created_at: {type: string, format: date-time}

    AppointmentInput:
      type: object
      required: [appointment_start_date, appointment_start_time, doctor_id, patient_id, clinic_id]
      properties:
        appointment_start_date: {type: string, format: date}
        appointment_start_time: {type: string, format: time}
        appointment_end_date: {type: string, format: date}
        appointment_end_time: {type: string, format: time}
        visit_type: {type: string}
        doctor_id: {type: integer}
        patient_id: {type: integer}
        clinic_id: {type: integer}
        description: {type: string}

    Encounter:
      type: object
      properties:
        id: {type: integer}
        encounter_date: {type: string, format: date}
        clinic_id: {type: integer}
        doctor_id: {type: integer}
        patient_id: {type: integer}
        appointment_id: {type: integer}
        description: {type: string}
        status: {type: integer, enum: [0, 1]}
        created_at: {type: string, format: date-time}

    EncounterInput:
      type: object
      required: [appointment_id, description]
      properties:
        appointment_id: {type: integer}
        description: {type: string}
        status: {type: integer, enum: [0, 1]}

    Prescription:
      type: object
      properties:
        id: {type: integer}
        encounter_id: {type: integer}
        patient_id: {type: integer}
        name: {type: string}
        frequency: {type: string}
        duration: {type: string}
        instruction: {type: string}
        created_at: {type: string, format: date-time}

    PrescriptionInput:
      type: object
      required: [name, frequency, duration]
      properties:
        name: {type: string}
        frequency: {type: string, maxLength: 199}
        duration: {type: string, maxLength: 199}
        instruction: {type: string}

  responses:
    UnauthorizedError:
      description: Authentication required
      content:
        application/json:
          schema:
            type: object
            properties:
              code: {type: string, example: "rest_forbidden"}
              message: {type: string}
              data: {type: object, properties: {status: {type: integer}}}

    ValidationError:
      description: Validation failed
      content:
        application/json:
          schema:
            type: object
            properties:
              code: {type: string, example: "rest_invalid_param"}
              message: {type: string}
              data: {type: object}

    NotFoundError:
      description: Resource not found
      content:
        application/json:
          schema:
            type: object
            properties:
              code: {type: string, example: "rest_not_found"}
              message: {type: string}
              data: {type: object, properties: {status: {type: integer, example: 404}}}