openapi: 3.1.0
info:
  title: Smart Clinic API
  version: 1.0.0
  description: Laravel API contract for the Smart Clinic mobile application. Base
    path is /api/v1.
servers:
- url: /api/v1
  description: Local
- url: https://your-domain.example/api/v1
  description: Production
tags:
- name: Auth
- name: Bootstrap
- name: Discovery
- name: Patients
- name: Appointments
- name: Queue
- name: Billing
- name: Notifications
- name: Admin
paths:
  /auth/login:
    post:
      tags:
      - Auth
      summary: Login and return Sanctum token plus bootstrap context
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
      responses:
        '200':
          description: Logged in
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '422':
          $ref: '#/components/responses/ValidationError'
  /auth/forgot-password:
    post:
      tags:
      - Auth
      summary: Request staff password reset
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - email
              - organization_slug
              properties:
                email:
                  type: string
                  format: email
                organization_slug:
                  type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /auth/reset-password:
    post:
      tags:
      - Auth
      summary: Reset staff password using emailed token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - email
              - organization_slug
              - token
              - password
              - password_confirmation
              properties:
                email:
                  type: string
                  format: email
                organization_slug:
                  type: string
                token:
                  type: string
                password:
                  type: string
                  minLength: 8
                password_confirmation:
                  type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /auth/email/verify/{id}/{hash}:
    get:
      tags:
      - Auth
      summary: Verify staff email using signed URL
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
      - name: hash
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /auth/logout:
    post:
      tags:
      - Auth
      summary: Revoke current access token
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /auth/logout-all:
    post:
      tags:
      - Auth
      summary: Revoke all user access tokens
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /auth/email/verification-notification:
    post:
      tags:
      - Auth
      summary: Send signed staff email verification link
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /me:
    get:
      tags:
      - Bootstrap
      summary: Current user, role, profile, permissions and assignments
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /bootstrap:
    get:
      tags:
      - Bootstrap
      summary: Initial mobile bootstrap data and lightweight counts
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /locations:
    get:
      tags:
      - Discovery
      summary: List locations permitted for current user
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /doctors:
    get:
      tags:
      - Discovery
      summary: List/filter permitted doctors
      security:
      - sanctum: []
      parameters:
      - name: search
        in: query
        required: false
        schema:
          type: string
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /doctors/{doctor}/locations:
    get:
      tags:
      - Discovery
      summary: Doctor practice locations and schedule metadata
      security:
      - sanctum: []
      parameters:
      - name: doctor
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /doctors/{doctor}/availability:
    get:
      tags:
      - Discovery
      summary: Server-calculated available slots
      security:
      - sanctum: []
      parameters:
      - name: doctor
        in: path
        required: true
        schema:
          type: integer
      - name: location_id
        in: query
        required: true
        schema:
          type: integer
      - name: date
        in: query
        required: true
        schema:
          type: string
        description: YYYY-MM-DD
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /patients:
    get:
      tags:
      - Patients
      summary: Search/filter/paginate role-scoped patients
      security:
      - sanctum: []
      parameters:
      - name: search
        in: query
        required: false
        schema:
          type: string
      - name: page
        in: query
        required: false
        schema:
          type: integer
      - name: per_page
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    post:
      tags:
      - Patients
      summary: Create patient
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema: &id001
              $ref: '#/components/schemas/PatientInput'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '403':
          $ref: '#/components/responses/Forbidden'
  /patients/{patient}:
    get:
      tags:
      - Patients
      summary: Patient detail with record-level authorization
      security:
      - sanctum: []
      parameters:
      - name: patient
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    patch:
      tags:
      - Patients
      summary: Edit patient demographics and WhatsApp fields
      security:
      - sanctum: []
      parameters:
      - name: patient
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema: *id001
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /patients/{patient}/appointments:
    get:
      tags:
      - Patients
      summary: Patient visit/appointment history
      security:
      - sanctum: []
      parameters:
      - name: patient
        in: path
        required: true
        schema:
          type: integer
      - name: page
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /patients/{patient}/archive:
    post:
      tags:
      - Patients
      summary: Archive patient instead of destructive delete
      security:
      - sanctum: []
      parameters:
      - name: patient
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /appointments:
    get:
      tags:
      - Appointments
      summary: Role-scoped appointment list
      security:
      - sanctum: []
      parameters:
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      - name: patient_id
        in: query
        required: false
        schema:
          type: integer
      - name: status
        in: query
        required: false
        schema:
          type: string
      - name: date
        in: query
        required: false
        schema:
          type: string
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: page
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    post:
      tags:
      - Appointments
      summary: Book appointment after schedule/conflict validation
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppointmentCreateRequest'
      responses:
        '201':
          description: Created
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '403':
          $ref: '#/components/responses/Forbidden'
  /appointments/{appointment}:
    get:
      tags:
      - Appointments
      summary: Appointment detail
      security:
      - sanctum: []
      parameters:
      - name: appointment
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    patch:
      tags:
      - Appointments
      summary: Update allowed appointment fields
      security:
      - sanctum: []
      parameters:
      - name: appointment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                reason:
                  type:
                  - string
                  - 'null'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /appointments/{appointment}/reschedule:
    post:
      tags:
      - Appointments
      summary: Atomically validate and reschedule appointment
      security:
      - sanctum: []
      parameters:
      - name: appointment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - scheduled_start_at
              properties:
                scheduled_start_at:
                  type: string
                  format: date-time
                location_id:
                  type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /appointments/{appointment}/cancel:
    post:
      tags:
      - Appointments
      summary: Cancel appointment with reason and synchronize queue
      security:
      - sanctum: []
      parameters:
      - name: appointment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - reason
              properties:
                reason:
                  type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /appointments/{appointment}/status:
    post:
      tags:
      - Appointments
      summary: Apply allowed appointment state-machine transition
      security:
      - sanctum: []
      parameters:
      - name: appointment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - status
              properties:
                status:
                  $ref: '#/components/schemas/AppointmentStatus'
                reason:
                  type:
                  - string
                  - 'null'
                admin_correction:
                  type: boolean
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /queue:
    get:
      tags:
      - Queue
      summary: Active queue with serving state
      security:
      - sanctum: []
      parameters:
      - name: doctor_id
        in: query
        required: true
        schema:
          type: integer
      - name: location_id
        in: query
        required: true
        schema:
          type: integer
      - name: queue_date
        in: query
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /queue/check-in:
    post:
      tags:
      - Queue
      summary: Check in appointment and allocate automatic/manual token
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QueueCheckInRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /queue/next-token:
    post:
      tags:
      - Queue
      summary: Check in appointment using next automatic token
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - appointment_id
              properties:
                appointment_id:
                  type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /queue/{entry}/token:
    patch:
      tags:
      - Queue
      summary: Edit active queue token with collision validation
      security:
      - sanctum: []
      parameters:
      - name: entry
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - token_number
              properties:
                token_number:
                  type: integer
                  minimum: 1
                  maximum: 9999
                reason:
                  type:
                  - string
                  - 'null'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /queue/{entry}/status:
    post:
      tags:
      - Queue
      summary: Change queue state and synchronize appointment
      security:
      - sanctum: []
      parameters:
      - name: entry
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - status
              properties:
                status:
                  $ref: '#/components/schemas/QueueStatus'
                reason:
                  type:
                  - string
                  - 'null'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /queue/call-next:
    post:
      tags:
      - Queue
      summary: Serve smallest eligible waiting token after current token
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - doctor_id
              - location_id
              properties:
                doctor_id:
                  type: integer
                location_id:
                  type: integer
                queue_date:
                  type: string
                  format: date
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /transactions:
    get:
      tags:
      - Billing
      summary: Role/permission-scoped financial transaction list
      security:
      - sanctum: []
      parameters:
      - name: appointment_id
        in: query
        required: false
        schema:
          type: integer
      - name: patient_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      - name: status
        in: query
        required: false
        schema:
          type: string
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: page
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /appointments/{appointment}/payments:
    post:
      tags:
      - Billing
      summary: Collect idempotent payment
      security:
      - sanctum: []
      parameters:
      - name: appointment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /appointments/{appointment}/waiver:
    post:
      tags:
      - Billing
      summary: Create authorized fee waiver
      security:
      - sanctum: []
      parameters:
      - name: appointment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - amount
              - reason
              - idempotency_key
              properties:
                amount:
                  type: number
                  minimum: 0.01
                reason:
                  type: string
                idempotency_key:
                  type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /transactions/{transaction}/refund:
    post:
      tags:
      - Billing
      summary: Refund successful payment transaction
      security:
      - sanctum: []
      parameters:
      - name: transaction
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - amount
              - reason
              - idempotency_key
              properties:
                amount:
                  type: number
                  minimum: 0.01
                reason:
                  type: string
                idempotency_key:
                  type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /notifications:
    get:
      tags:
      - Notifications
      summary: List in-app notifications
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /notifications/{notification}/read:
    post:
      tags:
      - Notifications
      summary: Mark in-app notification read
      security:
      - sanctum: []
      parameters:
      - name: notification
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /notification-preferences:
    get:
      tags:
      - Notifications
      summary: Get channel preferences
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    patch:
      tags:
      - Notifications
      summary: Update channel preferences
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                push_enabled:
                  type: boolean
                whatsapp_enabled:
                  type: boolean
                email_enabled:
                  type: boolean
                in_app_enabled:
                  type: boolean
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /devices:
    post:
      tags:
      - Notifications
      summary: Register or update Expo/FCM/APNs device token
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - token
              - platform
              properties:
                device_id:
                  type:
                  - string
                  - 'null'
                token:
                  type: string
                platform:
                  type: string
                  enum:
                  - expo
                  - fcm
                  - apns
                device_name:
                  type:
                  - string
                  - 'null'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /devices/{device}:
    delete:
      tags:
      - Notifications
      summary: Remove/deactivate push device
      security:
      - sanctum: []
      parameters:
      - name: device
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/dashboard:
    get:
      tags:
      - Admin
      summary: Admin KPI dashboard
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/appointments:
    get:
      tags:
      - Admin
      summary: Appointment report
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/queue:
    get:
      tags:
      - Admin
      summary: Daily queue/wait-time report
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/revenue:
    get:
      tags:
      - Admin
      summary: Revenue/collections report
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/patients:
    get:
      tags:
      - Admin
      summary: Patient visit/new-vs-returning report
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/cancellations:
    get:
      tags:
      - Admin
      summary: Cancellation/no-show report
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/assistant-activity:
    get:
      tags:
      - Admin
      summary: Assistant activity report
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/reports/notifications:
    get:
      tags:
      - Admin
      summary: Notification delivery/failure report
      security:
      - sanctum: []
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: doctor_id
        in: query
        required: false
        schema:
          type: integer
      - name: location_id
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/audit-logs:
    get:
      tags:
      - Admin
      summary: Paginated audit history
      security:
      - sanctum: []
      parameters:
      - name: event
        in: query
        required: false
        schema:
          type: string
      - name: actor_user_id
        in: query
        required: false
        schema:
          type: integer
      - name: from
        in: query
        required: false
        schema:
          type: string
      - name: to
        in: query
        required: false
        schema:
          type: string
      - name: page
        in: query
        required: false
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/settings:
    get:
      tags:
      - Admin
      summary: Organization settings
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    patch:
      tags:
      - Admin
      summary: Update organization settings with audit
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/locations:
    get:
      tags:
      - Admin
      summary: List locations
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    post:
      tags:
      - Admin
      summary: Create location
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/locations/{location}:
    patch:
      tags:
      - Admin
      summary: Update location
      security:
      - sanctum: []
      parameters:
      - name: location
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      tags:
      - Admin
      summary: Deactivate/delete location according to domain rules
      security:
      - sanctum: []
      parameters:
      - name: location
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/doctors:
    get:
      tags:
      - Admin
      summary: List doctors
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    post:
      tags:
      - Admin
      summary: Create doctor
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/doctors/{doctor}:
    patch:
      tags:
      - Admin
      summary: Update doctor
      security:
      - sanctum: []
      parameters:
      - name: doctor
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      tags:
      - Admin
      summary: Deactivate/delete doctor according to domain rules
      security:
      - sanctum: []
      parameters:
      - name: doctor
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/assistants:
    get:
      tags:
      - Admin
      summary: List assistants
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    post:
      tags:
      - Admin
      summary: Create assistant
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/assistants/{assistant}:
    patch:
      tags:
      - Admin
      summary: Update assistant
      security:
      - sanctum: []
      parameters:
      - name: assistant
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      tags:
      - Admin
      summary: Deactivate/delete assistant according to domain rules
      security:
      - sanctum: []
      parameters:
      - name: assistant
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/doctor-location-assignments:
    get:
      tags:
      - Admin
      summary: List doctor-location-assignments
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    post:
      tags:
      - Admin
      summary: Create assignment
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/doctor-location-assignments/{assignment}:
    patch:
      tags:
      - Admin
      summary: Update assignment
      security:
      - sanctum: []
      parameters:
      - name: assignment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      tags:
      - Admin
      summary: Deactivate/delete assignment according to domain rules
      security:
      - sanctum: []
      parameters:
      - name: assignment
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/assistant-assignments:
    get:
      tags:
      - Admin
      summary: List assistant-assignments
      security:
      - sanctum: []
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    post:
      tags:
      - Admin
      summary: Create assignment
      security:
      - sanctum: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/assistant-assignments/{assignment}:
    patch:
      tags:
      - Admin
      summary: Update assignment
      security:
      - sanctum: []
      parameters:
      - name: assignment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      tags:
      - Admin
      summary: Deactivate/delete assignment according to domain rules
      security:
      - sanctum: []
      parameters:
      - name: assignment
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/doctor-location-assignments/{assignment}/schedule:
    get:
      tags:
      - Admin
      summary: Read working hours and schedule exceptions
      security:
      - sanctum: []
      parameters:
      - name: assignment
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/doctor-location-assignments/{assignment}/working-hours:
    post:
      tags:
      - Admin
      summary: Create doctor working-hour session
      security:
      - sanctum: []
      parameters:
      - name: assignment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/working-hours/{workingHour}:
    patch:
      tags:
      - Admin
      summary: Update working-hour session
      security:
      - sanctum: []
      parameters:
      - name: workingHour
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      tags:
      - Admin
      summary: Delete working-hour session
      security:
      - sanctum: []
      parameters:
      - name: workingHour
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/doctor-location-assignments/{assignment}/schedule-exceptions:
    post:
      tags:
      - Admin
      summary: Create leave/holiday/blocked/special-hours exception
      security:
      - sanctum: []
      parameters:
      - name: assignment
        in: path
        required: true
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /admin/schedule-exceptions/{exception}:
    patch:
      tags: [Admin]
      summary: Update leave, holiday, blocked time or special-hours exception
      security: [{sanctum: []}]
      responses:
        '200': {description: Updated, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
        '422': {$ref: '#/components/responses/ValidationError'}
    delete:
      tags:
      - Admin
      summary: Delete schedule exception
      security:
      - sanctum: []
      parameters:
      - name: exception
        in: path
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /dashboard:
    get:
      tags: [Bootstrap]
      summary: Role-specific home dashboard data
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
        '401': {$ref: '#/components/responses/Unauthenticated'}
        '403': {$ref: '#/components/responses/Forbidden'}
  /admin/reports/doctor-utilization:
    get:
      tags: [Admin]
      summary: Doctor capacity and utilization report by location/date range
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
  /admin/reports/outstanding-payments:
    get:
      tags: [Admin]
      summary: Outstanding and partial appointment balances
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
  /admin/reports/refunds:
    get:
      tags: [Admin]
      summary: Successful refund transactions by date range
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
  /admin/reports/export:
    get:
      tags: [Admin]
      summary: Export supported operational reports as CSV
      security: [{sanctum: []}]
      parameters:
        - {name: report, in: query, required: true, schema: {type: string, enum: [appointments, revenue, cancellations]}}
      responses:
        '200': {description: CSV report export}
  /admin/roles:
    get:
      tags: [Admin]
      summary: List supported roles and assistant permission flags
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
  /admin/users:
    get:
      tags: [Admin]
      summary: Search and paginate organization users
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
    post:
      tags: [Admin]
      summary: Create admin, doctor, assistant or linked patient user
      security: [{sanctum: []}]
      responses:
        '201': {description: User created, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
        '422': {$ref: '#/components/responses/ValidationError'}
  /admin/users/{user}:
    parameters:
      - {name: user, in: path, required: true, schema: {type: integer}}
    get:
      tags: [Admin]
      summary: Get organization user and profile
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
    patch:
      tags: [Admin]
      summary: Update user, profile status, password or verification state
      security: [{sanctum: []}]
      responses:
        '200': {description: Updated, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
        '422': {$ref: '#/components/responses/ValidationError'}
    delete:
      tags: [Admin]
      summary: Disable user while preserving operational history
      security: [{sanctum: []}]
      responses:
        '200': {description: Disabled, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
  /admin/system/metrics:
    get:
      tags: [Admin]
      summary: Operational database, queue and notification metrics
      security: [{sanctum: []}]
      responses:
        '200': {description: Success, content: {application/json: {schema: {$ref: '#/components/schemas/SuccessEnvelope'}}}}
components:
  securitySchemes:
    sanctum:
      type: http
      scheme: bearer
      bearerFormat: Sanctum
  responses:
    Unauthenticated:
      description: Missing, invalid or revoked token
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Forbidden:
      description: Authenticated but not authorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ValidationError:
      description: Validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Conflict:
      description: Domain conflict such as token collision or unavailable slot
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  schemas:
    SuccessEnvelope:
      type: object
      required:
      - success
      - data
      properties:
        success:
          type: boolean
          const: true
        data: {}
        meta:
          type:
          - object
          - 'null'
        message:
          type:
          - string
          - 'null'
    ErrorEnvelope:
      type: object
      required:
      - success
      - error
      properties:
        success:
          type: boolean
          const: false
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: string
            message:
              type: string
            fields:
              type:
              - object
              - 'null'
            context:
              type:
              - object
              - 'null'
    LoginRequest:
      type: object
      required:
      - email
      - password
      properties:
        email:
          type: string
          format: email
        password:
          type: string
        device_name:
          type:
          - string
          - 'null'
        device_id:
          type:
          - string
          - 'null'
        organization_slug:
          type:
          - string
          - 'null'
    LoginResponse:
      allOf:
      - $ref: '#/components/schemas/SuccessEnvelope'
      - type: object
        properties:
          data:
            type: object
            properties:
              token:
                type: string
              token_type:
                type: string
              expires_at:
                type:
                - string
                - 'null'
                format: date-time
              bootstrap:
                type: object
    PatientInput:
      type: object
      properties:
        name:
          type: string
          maxLength: 150
        phone:
          type: string
        has_whatsapp:
          type: boolean
        whatsapp:
          type:
          - string
          - 'null'
        email:
          type:
          - string
          - 'null'
          format: email
        gender:
          type:
          - string
          - 'null'
        date_of_birth:
          type:
          - string
          - 'null'
          format: date
        city:
          type:
          - string
          - 'null'
        blood_group:
          type:
          - string
          - 'null'
          enum:
          - A+
          - A-
          - B+
          - B-
          - AB+
          - AB-
          - O+
          - O-
          - null
        allergies:
          type:
          - string
          - 'null'
        emergency_contact:
          type:
          - string
          - 'null'
        notes:
          type:
          - string
          - 'null'
        allow_duplicate:
          type: boolean
    AppointmentCreateRequest:
      type: object
      required:
      - patient_id
      - doctor_id
      - location_id
      - scheduled_start_at
      - type
      properties:
        patient_id:
          type: integer
        doctor_id:
          type: integer
        location_id:
          type: integer
        scheduled_start_at:
          type: string
          format: date-time
        type:
          type: string
          examples:
          - new_consultation
          - follow_up
          - routine
          - emergency
        reason:
          type:
          - string
          - 'null'
        discount_amount:
          type: number
          minimum: 0
    AppointmentStatus:
      type: string
      enum:
      - confirmed
      - checked_in
      - waiting
      - with_doctor
      - completed
      - cancelled
      - no_show
    QueueStatus:
      type: string
      enum:
      - checked_in
      - waiting
      - with_doctor
      - completed
      - no_show
      - cancelled
    QueueCheckInRequest:
      type: object
      required:
      - appointment_id
      - token_mode
      properties:
        appointment_id:
          type: integer
        token_mode:
          type: string
          enum:
          - auto
          - manual
        token_number:
          type:
          - integer
          - 'null'
          minimum: 1
          maximum: 9999
    PaymentRequest:
      type: object
      required:
      - amount
      - method
      - idempotency_key
      properties:
        amount:
          type: number
          minimum: 0.01
        method:
          type: string
          enum:
          - cash
          - card
          - bank_transfer
          - online
          - insurance
        reference:
          type:
          - string
          - 'null'
        idempotency_key:
          type: string
        notes:
          type:
          - string
          - 'null'
