openapi: 3.0.3
info:
  title: Medical Appointment System API
  description: |
    API REST para el sistema de agendamiento de citas médicas.

    ## Características
    - Creación de citas médicas para múltiples países (PE, CL)
    - Consulta de citas por asegurado
    - Consulta de citas individuales
    - Health check endpoint

    ## Arquitectura
    - Serverless Framework en AWS
    - DynamoDB para almacenamiento
    - SNS/SQS para procesamiento asíncrono
    - EventBridge para eventos de negocio
  version: 1.0.0
  contact:
    name: Sistema de Agendamiento Médico
    email: support@medical-appointments.com

servers:
  - url: https://nlhic74tlk.execute-api.us-east-1.amazonaws.com
    description: Producción AWS
  - url: http://localhost:3000
    description: Desarrollo local (serverless offline)

tags:
  - name: Appointments
    description: Operaciones relacionadas con citas médicas
  - name: Health
    description: Endpoints de monitoreo y salud del sistema

paths:
  /health:
    get:
      tags:
        - Health
      summary: Health check
      description: Verifica el estado de salud del sistema
      operationId: healthCheck
      responses:
        '200':
          description: Sistema funcionando correctamente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
              example:
                status: ok
                service: medical-appointment-system
                version: 1.0.0
                timestamp: '2024-03-15T10:30:00.000Z'

  /appointments:
    post:
      tags:
        - Appointments
      summary: Crear nueva cita médica
      description: |
        Crea una nueva cita médica y la procesa de manera asíncrona.

        El proceso incluye:
        1. Validación de datos
        2. Creación del registro en DynamoDB
        3. Publicación en SNS Topic
        4. Enrutamiento a cola SQS según país
        5. Procesamiento asíncrono en RDS del país
      operationId: createAppointment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAppointmentInput'
            examples:
              peru:
                summary: Cita en Perú
                value:
                  insuredId: INS-PE-12345
                  countryISO: PE
                  service: Consulta General
                  scheduleId: 1001
              chile:
                summary: Cita en Chile
                value:
                  insuredId: INS-CL-67890
                  countryISO: CL
                  service: Emergencia
                  scheduleId: 2001
      responses:
        '202':
          description: Cita aceptada para procesamiento asíncrono
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AppointmentResponse'
              example:
                appointmentId: APT-2024-001
                insuredId: INS-PE-12345
                scheduleId: 1001
                countryISO: PE
                service: Consulta General
                status: pending
                createdAt: '2024-03-15T10:30:00.000Z'
                updatedAt: '2024-03-15T10:30:00.000Z'
        '400':
          description: Datos de entrada inválidos
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: ValidationError
                message: El campo 'countryISO' debe ser 'PE' o 'CL'
                statusCode: 400
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /insured/{insuredId}/appointments:
    get:
      tags:
        - Appointments
      summary: Obtener todas las citas de un asegurado
      description: Retorna todas las citas médicas asociadas a un ID de asegurado
      operationId: getAppointmentsByInsured
      parameters:
        - name: insuredId
          in: path
          required: true
          description: ID único del asegurado
          schema:
            type: string
            example: INS-PE-12345
      responses:
        '200':
          description: Lista de citas del asegurado
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Appointment'
              example:
                - appointmentId: APT-2024-001
                  insuredId: INS-PE-12345
                  scheduleId: 1001
                  countryISO: PE
                  service: Consulta General
                  status: completed
                  createdAt: '2024-03-10T10:00:00.000Z'
                  updatedAt: '2024-03-10T11:30:00.000Z'
                - appointmentId: APT-2024-002
                  insuredId: INS-PE-12345
                  scheduleId: 1002
                  countryISO: PE
                  service: Control
                  status: pending
                  createdAt: '2024-03-15T10:30:00.000Z'
                  updatedAt: '2024-03-15T10:30:00.000Z'
        '400':
          description: ID de asegurado inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Asegurado no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /appointments/{appointmentId}:
    get:
      tags:
        - Appointments
      summary: Obtener cita por ID
      description: Retorna los detalles de una cita médica específica
      operationId: getAppointmentById
      parameters:
        - name: appointmentId
          in: path
          required: true
          description: ID único de la cita
          schema:
            type: string
            example: APT-2024-001
      responses:
        '200':
          description: Detalles de la cita
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Appointment'
              example:
                appointmentId: APT-2024-001
                insuredId: INS-PE-12345
                scheduleId: 1001
                countryISO: PE
                service: Consulta General
                status: completed
                createdAt: '2024-03-10T10:00:00.000Z'
                updatedAt: '2024-03-10T11:30:00.000Z'
        '400':
          description: ID de cita inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Cita no encontrada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: NotFoundError
                message: Cita con ID 'APT-2024-999' no encontrada
                statusCode: 404
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  schemas:
    CreateAppointmentInput:
      type: object
      required:
        - insuredId
        - countryISO
        - service
        - scheduleId
      properties:
        insuredId:
          type: string
          description: ID único del asegurado
          example: INS-PE-12345
        countryISO:
          type: string
          enum:
            - PE
            - CL
          description: Código ISO del país (PE = Perú, CL = Chile)
          example: PE
        service:
          type: string
          description: Tipo de servicio médico solicitado
          example: Consulta General
        scheduleId:
          type: integer
          format: int32
          description: ID del horario/espacio disponible seleccionado
          example: 1001
          minimum: 1

    Appointment:
      type: object
      properties:
        appointmentId:
          type: string
          description: ID único de la cita generado por el sistema
          example: APT-2024-001
        insuredId:
          type: string
          description: ID único del asegurado
          example: INS-PE-12345
        scheduleId:
          type: integer
          format: int32
          description: ID del horario/espacio
          example: 1001
        countryISO:
          type: string
          enum:
            - PE
            - CL
          description: Código ISO del país
          example: PE
        service:
          type: string
          description: Tipo de servicio médico
          example: Consulta General
        status:
          type: string
          enum:
            - pending
            - completed
          description: Estado del procesamiento de la cita
          example: pending
        createdAt:
          type: string
          format: date-time
          description: Fecha y hora de creación
          example: '2024-03-15T10:30:00.000Z'
        updatedAt:
          type: string
          format: date-time
          description: Fecha y hora de última actualización
          example: '2024-03-15T10:30:00.000Z'

    AppointmentResponse:
      allOf:
        - $ref: '#/components/schemas/Appointment'
      description: Respuesta al crear una cita

    HealthResponse:
      type: object
      properties:
        status:
          type: string
          example: ok
          description: Estado del servicio
        service:
          type: string
          example: medical-appointment-system
          description: Nombre del servicio
        version:
          type: string
          example: 1.0.0
          description: Versión del servicio
        timestamp:
          type: string
          format: date-time
          example: '2024-03-15T10:30:00.000Z'
          description: Timestamp de la respuesta

    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Tipo de error
          example: ValidationError
        message:
          type: string
          description: Mensaje descriptivo del error
          example: El campo 'countryISO' es requerido
        statusCode:
          type: integer
          description: Código de estado HTTP
          example: 400
        details:
          type: object
          description: Detalles adicionales del error (opcional)
          additionalProperties: true
