PatientIdentifier:
  type: object
  properties:
    IdentifierType:
      type: string
      enum: [KTP, PASS, SSN, SIM, KTAS]
      description: |
        KTP: 16 digit numeric
        PASS: alphanumeric max 9
        SSN: 9 digit numeric
        SIM: 19-20 digit numeric
        KTAS: 11 digit numeric
    Identifier:
      type: string
      maxLength: 255

LinkedPatient:
  type: object
  description: Linked patient reference
  properties:
    InternalPID:
      type: integer
      description: Internal patient ID of the linked patient
    PatientID:
      type: string
      description: Patient ID of the linked patient

Custodian:
  type: object
  description: Patient custodian/guardian
  properties:
    InternalPID:
      type: integer
      description: Internal patient ID of the custodian
    PatientID:
      type: string
      description: Patient ID of the custodian

PatAttEntry:
  type: object
  description: Patient address/attorney entry
  properties:
    Address:
      type: string
      description: Address text

Patient:
  type: object
  required:
    - PatientID
    - Sex
    - NameFirst
    - Birthdate
  properties:
    PatientID:
      type: string
      maxLength: 30
      pattern: '^[A-Za-z0-9]+$'
      description: Internal patient identifier
    AlternatePID:
      type: string
      maxLength: 30
      pattern: '^[A-Za-z0-9]+$'
    Prefix:
      type: string
      maxLength: 10
      enum: [Mr, Mrs, Ms, Dr, Prof]
    Sex:
      type: string
      enum: ['1', '2']
      description: '1: Female, 2: Male'
    NameFirst:
      type: string
      minLength: 1
      maxLength: 60
      pattern: "^[A-Za-z'\\. ]+$"
    NameMiddle:
      type: string
      minLength: 1
      maxLength: 60
    NameMaiden:
      type: string
      minLength: 1
      maxLength: 60
    NameLast:
      type: string
      minLength: 1
      maxLength: 60
    Suffix:
      type: string
      maxLength: 10
    Birthdate:
      type: string
      format: date-time
      description: ISO 8601 UTC datetime
    PlaceOfBirth:
      type: string
      maxLength: 100
    Citizenship:
      type: string
      maxLength: 100
    Street_1:
      type: string
      maxLength: 255
    Street_2:
      type: string
      maxLength: 255
    Street_3:
      type: string
      maxLength: 255
    ZIP:
      type: string
      maxLength: 10
      pattern: '^[0-9]+$'
    Phone:
      type: string
      pattern: "^\\+?[0-9]{8,15}$"
    MobilePhone:
      type: string
      pattern: "^\\+?[0-9]{8,15}$"
    EmailAddress1:
      type: string
      format: email
      maxLength: 100
    EmailAddress2:
      type: string
      format: email
      maxLength: 100
    PatIdt:
      $ref: 'patient.yaml#/PatientIdentifier'
    LinkTo:
      type: array
      description: Array of linked patient references
      items:
        $ref: 'patient.yaml#/LinkedPatient'
    Custodian:
      $ref: 'patient.yaml#/Custodian'
    isDead:
      type: string
      enum: ['0', '1']
      description: '0: No (alive), 1: Yes (deceased)'
    TimeOfDeath:
      type: string
      format: date-time
      description: ISO 8601 UTC datetime of death
    PatCom:
      type: string
      description: Patient comment/notes
    PatAtt:
      type: array
      description: Patient address entries
      items:
        $ref: 'patient.yaml#/PatAttEntry'
    Province:
      type: integer
      description: Province AreaGeoID (foreign key to areageo table)
    ProvinceLabel:
      type: string
      description: Province name (resolved from areageo)
    City:
      type: integer
      description: City AreaGeoID (foreign key to areageo table)
    CityLabel:
      type: string
      description: City name (resolved from areageo)
    Country:
      type: string
      maxLength: 10
      description: Country ISO 3-letter code (e.g., IDN, USA)
    CountryLabel:
      type: string
      description: Country name (resolved from valueset)
    Race:
      type: string
      maxLength: 100
    MaritalStatus:
      type: string
      enum: [A, B, D, M, S, W]
      description: 'A: Annulled, B: Separated, D: Divorced, M: Married, S: Single, W: Widowed'
    Religion:
      type: string
      maxLength: 100
    Ethnic:
      type: string
      maxLength: 100

PatientPatch:
  type: object
  description: |
    Partial patient update payload.
    Omitted fields are left unchanged. Send null explicitly to clear nullable fields.
  properties:
    PatientID:
      type: string
      maxLength: 30
      pattern: '^[A-Za-z0-9]+$'
      description: Internal patient identifier
    AlternatePID:
      type: string
      maxLength: 30
      pattern: '^[A-Za-z0-9]+$'
    Prefix:
      type: string
      maxLength: 10
      enum: [Mr, Mrs, Ms, Dr, Prof]
    Sex:
      type: string
      enum: ['1', '2']
      description: '1: Female, 2: Male'
    NameFirst:
      type: string
      minLength: 1
      maxLength: 60
      pattern: "^[A-Za-z'\\. ]+$"
    NameMiddle:
      type: string
      minLength: 1
      maxLength: 60
    NameMaiden:
      type: string
      minLength: 1
      maxLength: 60
    NameLast:
      type: string
      minLength: 1
      maxLength: 60
    Suffix:
      type: string
      maxLength: 10
    Birthdate:
      type: string
      format: date-time
      description: ISO 8601 UTC datetime
    PlaceOfBirth:
      type: string
      maxLength: 100
    Citizenship:
      type: string
      maxLength: 100
    Street_1:
      type: string
      maxLength: 255
    Street_2:
      type: string
      maxLength: 255
    Street_3:
      type: string
      maxLength: 255
    ZIP:
      type: string
      maxLength: 10
      pattern: '^[0-9]+$'
    Phone:
      type: string
      pattern: "^\\+?[0-9]{8,15}$"
    MobilePhone:
      type: string
      pattern: "^\\+?[0-9]{8,15}$"
    EmailAddress1:
      type: string
      format: email
      maxLength: 100
    EmailAddress2:
      type: string
      format: email
      maxLength: 100
    PatIdt:
      allOf:
        - $ref: 'patient.yaml#/PatientIdentifier'
      nullable: true
    LinkTo:
      type: array
      description: Array of linked patient references
      items:
        $ref: 'patient.yaml#/LinkedPatient'
    Custodian:
      allOf:
        - $ref: 'patient.yaml#/Custodian'
      nullable: true
    isDead:
      type: string
      enum: ['0', '1']
      description: '0: No (alive), 1: Yes (deceased)'
    TimeOfDeath:
      type: string
      format: date-time
      description: ISO 8601 UTC datetime of death
    PatCom:
      type: string
      description: Patient comment/notes
      nullable: true
    PatAtt:
      type: array
      description: Patient address entries
      nullable: true
      items:
        $ref: 'patient.yaml#/PatAttEntry'
    Province:
      type: integer
      description: Province AreaGeoID (foreign key to areageo table)
    City:
      type: integer
      description: City AreaGeoID (foreign key to areageo table)
    Country:
      type: string
      maxLength: 10
      description: Country ISO 3-letter code (e.g., IDN, USA)
    Race:
      type: string
      maxLength: 100
    MaritalStatus:
      type: string
      enum: [A, B, D, M, S, W]
      description: 'A: Annulled, B: Separated, D: Divorced, M: Married, S: Single, W: Widowed'
    Religion:
      type: string
      maxLength: 100
    Ethnic:
      type: string
      maxLength: 100

PatientListResponse:
  type: object
  properties:
    status:
      type: string
      example: success
    data:
      type: array
      items:
        $ref: 'patient.yaml#/Patient'
    pagination:
      type: object
      properties:
        page:
          type: integer
        perPage:
          type: integer
        total:
          type: integer
