{
  "openapi": "3.1.0",
  "info": {
    "title": "Medivana Public API",
    "version": "1.1.0",
    "summary": "API publik Medivana untuk integrasi sistem klinik (FR-INT-03).",
    "description": "API publik `api.medivana.cloud` untuk paket Klinik Pro, Enterprise, atau add-on \"API dan webhook\" (modul `api`).\nSpesifikasi ini hanya memuat operasi yang benar-benar bisa dipanggil klien API: tes\n`internal/server/routeaudit/openapi_test.go` gagal bila ada path yang tidak ada di router, bila scope yang\ndideklarasikan berbeda dari peta scope → izin RBAC (`internal/publicapi/scopes.go`), atau bila ada rute yang\nterbuka untuk scope namun belum didokumentasikan.\n\n## Alur singkat\n1. Admin klinik membuat **klien API** di aplikasi (Pengaturan → API dan webhook, izin `api_client.manage`) dan\n   memilih scope, cabang, serta batas laju. `client_secret` hanya ditampilkan sekali.\n2. Tukar kredensial ke `POST /oauth/token` (OAuth 2.0 client credentials, RFC 6749 §4.4) → `access_token` opaque\n   berawalan `mdn_at_`, berlaku 3600 detik. Minta token baru sebelum kedaluwarsa; tidak ada refresh token.\n3. Panggil endpoint dengan `Authorization: Bearer <access_token>`. Principal berjenis `api_client`; scope dipetakan\n   ke izin RBAC sehingga endpoint menegakkan aturan yang sama seperti untuk pengguna aplikasi. Setiap akses dicatat\n   di audit log klinik dengan `actor_kind = api_client`.\n4. Langgan webhook (`POST /webhooks`) untuk menerima event domain bertanda tangan HMAC-SHA256.\n\nMengubah klien (scope, cabang), merotasi secret, atau mencabut klien langsung membatalkan semua token aktifnya.\n\n## Scope → izin RBAC\n| Scope | Izin RBAC | Membuka |\n| --- | --- | --- |\n| `patients:read` | `patient.read` | cari/detail pasien, consent, riwayat gabung, lookup SATUSEHAT/BPJS |\n| `patients:write` | `patient.read`, `patient.write` | daftar/ubah pasien, daftar kunjungan, dokumen pasien |\n| `encounters:read` | `encounter.read` | kunjungan, RME, hasil penunjang, surat, spesialis, telekonsultasi |\n| `appointments:read` | `appointment.read` | booking, jadwal praktik, slot |\n| `appointments:write` | `appointment.read`, `appointment.manage` | buat/ubah/batal booking, check-in, kelola jadwal |\n| `invoices:read` | `invoice.read` | tagihan, pembayaran, master tarif (baca saja) |\n| `webhooks:manage` | `webhook.manage` | langganan webhook |\n\nSetiap operasi menuliskan scope yang cukup (`security`) dan izin RBAC yang diperiksa router\n(`x-medivana-permissions`). Operasi tanpa scope (`oauth2: []`) bisa dipanggil token apa pun.\n\n## Cabang (`X-Branch-ID`)\nKlien API berlaku untuk semua cabang atau daftar cabang tertentu. Kirim `X-Branch-ID: <uuid cabang>` untuk memilih\ncabang aktif; nilai di luar cabang klien diabaikan. Klien yang hanya punya satu cabang otomatis memakai cabang itu.\nOperasi tulis per cabang (ditandai parameter `X-Branch-ID` wajib) menolak permintaan tanpa cabang aktif dengan\n`400 bad-request`. Daftar kunjungan, booking, tagihan, dan worklist penunjang difilter ke cabang aktif.\n\n## Galat\nSemua galat berformat RFC 9457 `application/problem+json`. Gunakan `code` (dan `errors[].field`) untuk logika\nklien; `title`, `detail`, dan `errors[].message` diterjemahkan sesuai `Accept-Language`.\n\n| HTTP | `code` | Arti |\n| --- | --- | --- |\n| 400 | `bad-request` | Format permintaan/parameter salah, atau cabang aktif belum dipilih |\n| 401 | `unauthorized` | Token tidak ada, salah, kedaluwarsa, dicabut, atau modul API tidak aktif lagi |\n| 402 | `module-locked` | Modul yang melayani endpoint tidak ada di paket klinik |\n| 403 | `forbidden` | Scope token tidak memberi izin untuk aksi ini |\n| 403 | `confidential-record` | Rekam medis ditandai rahasia (klien API tidak pernah punya izin rekam rahasia) |\n| 403 | `read-only` | Langganan klinik dalam mode baca-saja; hanya GET yang dilayani |\n| 404 | `not-found` | Data tidak ada, milik organisasi lain, atau di luar cakupan |\n| 409 | `conflict` | Konflik data (duplikat, status tidak mengizinkan aksi) |\n| 412 | `stale` | `If-Match` tidak cocok dengan versi terbaru |\n| 422 | `validation` | Validasi gagal; rincian di `errors[]` |\n| 429 | `rate-limited` | Batas laju terlampaui |\n| 500 | `internal` | Galat server; aman dicoba ulang dengan backoff |\n| 502 | `satusehat-unavailable`, `bpjs-unavailable` | Layanan pemerintah tidak menjawab (endpoint lookup) |\n\nEndpoint OAuth memakai format galat RFC 6749 (`{\"error\": \"invalid_client\"}`), bukan problem+json.\n\n## Paginasi\nDaftar mengembalikan `{\"items\": [...]}`. Daftar yang berhalaman menambahkan `next_cursor`; kirim nilainya sebagai\n`?cursor=` untuk halaman berikutnya sampai `next_cursor` tidak ada. Ukuran halaman diatur `limit` (default dan\nmaksimum tertulis per operasi). Cursor bersifat opaque; jangan disusun sendiri.\n\n## Konkurensi dan pengulangan\nDetail yang bisa diubah membawa `ETag: \"<version>\"`. Kirim `If-Match: \"<version>\"` saat `PATCH` agar perubahan\nditolak (`412 stale`) bila data sudah diubah pihak lain. Operasi tulis yang terbuka untuk klien API tidak\nmemakai header `Idempotency-Key` (header itu hanya untuk transaksi keuangan kasir yang tidak tersedia bagi klien API);\npengulangan aman karena duplikat ditolak `409` (NIK pasien yang sama, slot booking yang sama, kunjungan aktif di\npoli yang sama), lalu klien dapat membaca data yang sudah ada.\n\n## Batas laju\n- Per klien: `rate_limit_per_min` (default 120, diatur admin klinik) dalam jendela tetap satu menit untuk semua\n  permintaan bertoken → `429 rate-limited`.\n- `POST /oauth/token` dan `POST /oauth/revoke`: 60 permintaan per menit per alamat IP → `429` dengan `Retry-After`.\nGunakan ulang token selama masa berlakunya; jangan meminta token baru untuk setiap permintaan.\n\n## Versi dan kompatibilitas\nVersi mayor ada di path (`/api/v1`). Perubahan aditif (field respons baru, nilai enum baru, event webhook baru,\nendpoint baru) dirilis tanpa menaikkan versi mayor, jadi klien wajib mengabaikan field yang tidak dikenal.\n`info.version` spesifikasi ini naik setiap kali isi kontrak berubah.\n\n## Format data\nWaktu RFC 3339 (zona Asia/Jakarta); tanggal `YYYY-MM-DD`; uang angka desimal rupiah; ID UUID. Bahasa respons\nmengikuti `Accept-Language` (`id` default, `en`); label tampilan (`*_label`) ikut diterjemahkan, nilai enum tidak.\nRespons membawa `Content-Language` dan `X-Request-ID` (sertakan saat menghubungi dukungan).\n\n## Webhook\nLihat bagian `webhooks`: payload `{id, type, created_at, org_id, branch_id?, data}` dengan header\n`X-Medivana-Signature: t=<unix>,v1=<hex>` di mana `v1 = HEX(HMAC-SHA256(secret, \"<t>.\" + body mentah))`.\nVerifikasi: (1) ambil `t` dan semua `v1`; (2) tolak bila `|now − t| > 300 detik`; (3) hitung HMAC atas body\nmentah (sebelum di-parse); (4) bandingkan konstan-waktu dengan salah satu `v1`; (5) deduplikasi memakai `id`\n(`X-Medivana-Event-ID`). Balas 2xx dalam 10 detik lalu proses secara asinkron. Non-2xx atau timeout dicoba ulang\n1, 5, 15, 60 menit lalu tiap 6 jam selama 3 hari (status `failed`, lalu `dead`); `410 Gone` menonaktifkan\nlangganan. Pengiriman bisa diulang manual (`POST /webhooks/deliveries/{id}/redeliver`).\n",
    "contact": {
      "name": "Tim Medivana",
      "url": "https://medivana.cloud/kontak"
    }
  },
  "servers": [
    {
      "url": "https://api.medivana.cloud/api/v1",
      "description": "Produksi"
    },
    {
      "url": "https://demo.medivana.cloud/api/v1",
      "description": "Demo (data sintetis)"
    }
  ],
  "security": [
    {
      "oauth2": []
    }
  ],
  "tags": [
    {
      "name": "OAuth2",
      "description": "Penerbitan dan pencabutan access token (client credentials). Tanpa token; autentikasi klien."
    },
    {
      "name": "Konteks",
      "description": "Identitas token, organisasi, cabang, unit layanan, dan tenaga kesehatan untuk mengisi referensi ID."
    },
    {
      "name": "Terminologi",
      "description": "Kamus kode global ICD-10, ICD-9-CM, LOINC, KFA, dan SNOMED (modul `frontoffice` atau `rme`)."
    },
    {
      "name": "Pasien",
      "description": "Master pasien, consent, alergi, dokumen pasien, dan lookup identitas (modul `frontoffice`)."
    },
    {
      "name": "Kunjungan",
      "description": "Pendaftaran kunjungan dan isi rekam medis elektronik rawat jalan (modul `frontoffice`/`rme`)."
    },
    {
      "name": "Surat",
      "description": "Surat keterangan sakit, rujukan, dan sehat yang sudah diterbitkan (modul `rme`)."
    },
    {
      "name": "Booking",
      "description": "Jadwal praktik, slot, cuti/libur, dan booking pasien (modul `booking`)."
    },
    {
      "name": "Tagihan",
      "description": "Tagihan, pembayaran, deposit, paket, dan master tarif kasir; hanya baca (modul `cashier`)."
    },
    {
      "name": "Penunjang",
      "description": "Order dan hasil laboratorium serta radiologi (modul `lab`/`radiology`)."
    },
    {
      "name": "Integrasi",
      "description": "Lookup BPJS dan SATUSEHAT serta status kiriman alat lab (modul `bpjs`, `satusehat`, `lis`)."
    },
    {
      "name": "Spesialis",
      "description": "Data paket spesialis gigi, kecantikan, KIA, dan fisioterapi; hanya baca (modul `dental`, `beauty`, `kia`, `physio`)."
    },
    {
      "name": "Telekonsultasi",
      "description": "Sesi telekonsultasi terjadwal; hanya baca (modul `telecon`)."
    },
    {
      "name": "Webhook",
      "description": "Langganan event domain dan riwayat pengiriman (modul `api`). Langganan berlaku untuk seluruh organisasi."
    }
  ],
  "paths": {
    "/oauth/token": {
      "post": {
        "operationId": "issueToken",
        "tags": [
          "OAuth2"
        ],
        "summary": "Terbitkan access token (client credentials)",
        "description": "Kredensial dikirim lewat `Authorization: Basic base64(client_id:client_secret)` (disarankan) atau field\n`client_id`/`client_secret` di body. Body `application/x-www-form-urlencoded` (JSON juga diterima).\n`scope` opsional: subset scope klien dipisah spasi; default semua scope klien. Token opaque, berlaku 3600 detik,\ntidak ada refresh token. Batas laju 60 permintaan/menit/IP.\n",
        "security": [
          {
            "clientBasic": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              },
              "example": {
                "grant_type": "client_credentials",
                "scope": "patients:read encounters:read"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              },
              "example": {
                "grant_type": "client_credentials",
                "client_id": "mdn_ci_7f3k2q9x",
                "client_secret": "mdn_cs_contoh-rahasia",
                "scope": "patients:read"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token terbit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                },
                "example": {
                  "access_token": "mdn_at_Q2xpZW50Q3JlZGVudGlhbHNDb250b2g",
                  "token_type": "Bearer",
                  "expires_in": 3600,
                  "scope": "patients:read encounters:read"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`, `unsupported_grant_type`, `invalid_scope` (scope tidak diberikan ke klien), atau `unauthorized_client` (modul API tidak aktif di paket)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                },
                "example": {
                  "error": "invalid_scope",
                  "error_description": "Scope invoices:read tidak diberikan untuk klien ini."
                }
              }
            }
          },
          "401": {
            "description": "`invalid_client`: client_id tidak dikenal, secret salah, atau klien dicabut",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                },
                "example": {
                  "error": "invalid_client",
                  "error_description": "Client ID atau client secret salah, atau klien sudah dicabut."
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedIP"
          }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "operationId": "revokeToken",
        "tags": [
          "OAuth2"
        ],
        "summary": "Cabut access token (RFC 7009)",
        "description": "Selalu `200` walau token tidak dikenal atau milik klien lain (tidak membocorkan keberadaan token). Butuh autentikasi klien seperti `/oauth/token`.",
        "security": [
          {
            "clientBasic": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "Access token yang dicabut"
                  },
                  "client_id": {
                    "type": "string",
                    "description": "Alternatif Basic auth"
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "Alternatif Basic auth"
                  }
                }
              },
              "example": {
                "token": "mdn_at_Q2xpZW50Q3JlZGVudGlhbHNDb250b2g"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token dicabut (atau memang tidak berlaku)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "revoked"
                    }
                  }
                },
                "example": {
                  "status": "revoked"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                },
                "example": {
                  "error": "invalid_request",
                  "error_description": "Format permintaan tidak valid."
                }
              }
            }
          },
          "401": {
            "description": "`invalid_client`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                },
                "example": {
                  "error": "invalid_client",
                  "error_description": "Client ID atau client secret salah."
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedIP"
          }
        }
      }
    },
    "/me": {
      "get": {
        "operationId": "getTokenContext",
        "tags": [
          "Konteks"
        ],
        "summary": "Identitas token dan izin efektif",
        "description": "Identitas teknis klien API (pengguna `API: <nama>`), izin RBAC hasil scope token, cabang aktif, dan entitlement paket. Berguna untuk memeriksa scope sebelum memanggil endpoint lain.",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Konteks token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenContext"
                },
                "example": {
                  "user_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000a11",
                  "email": "mdn_ci_7f3k2q9x",
                  "name": "API: Integrasi HIS",
                  "org": {
                    "id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                    "name": "Klinik Sehat Contoh",
                    "slug": "klinik-sehat-contoh",
                    "clinic_kind": "pratama",
                    "status": "active",
                    "demo_expires_at": null,
                    "default_locale": "id"
                  },
                  "branch_id": null,
                  "branches": [],
                  "roles": [
                    "api_client"
                  ],
                  "permissions": [
                    "encounter.read",
                    "patient.read",
                    "webhook.manage"
                  ],
                  "data_scope": "org",
                  "two_factor": true,
                  "entitlements": {
                    "plan": "klinik_pro",
                    "plan_name": "Klinik Pro",
                    "status": "active",
                    "modules": {
                      "api": true,
                      "frontoffice": true,
                      "rme": true,
                      "booking": true
                    }
                  },
                  "is_demo": false,
                  "break_glass": false,
                  "locale": "id",
                  "effective_locale": "id"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/me/entitlements": {
      "get": {
        "operationId": "getEntitlements",
        "tags": [
          "Konteks"
        ],
        "summary": "Paket, modul aktif, dan batas paket organisasi",
        "description": "Gunakan `modules` untuk mengetahui endpoint mana yang akan menjawab `402 module-locked`.",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "responses": {
          "200": {
            "description": "Entitlement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entitlements"
                },
                "example": {
                  "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                  "plan": "klinik_pro",
                  "plan_name": "Klinik Pro",
                  "status": "active",
                  "billing_cycle": "annual",
                  "branches": 3,
                  "modules": {
                    "api": true,
                    "frontoffice": true,
                    "rme": true,
                    "booking": true,
                    "cashier": true,
                    "lab": true,
                    "satusehat": true,
                    "bpjs": true
                  },
                  "limits": {
                    "users": 50,
                    "branches": 3
                  },
                  "addons": [],
                  "bi_level": "basic",
                  "accounting_level": "basic",
                  "current_period_end": "2027-10-31T23:59:59+07:00",
                  "is_demo": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/org": {
      "get": {
        "operationId": "getOrganization",
        "tags": [
          "Konteks"
        ],
        "summary": "Profil organisasi (klinik)",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "responses": {
          "200": {
            "description": "Organisasi (ETag)",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Organization"
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                  "name": "Klinik Sehat Contoh",
                  "slug": "klinik-sehat-contoh",
                  "legal_name": "PT Sehat Contoh Sejahtera",
                  "npwp": null,
                  "is_pkp": false,
                  "clinic_kind": "pratama",
                  "status": "active",
                  "is_demo": false,
                  "satusehat_org_ihs": "100000000",
                  "settings": {},
                  "default_locale": "id",
                  "version": 4
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/branches": {
      "get": {
        "operationId": "listBranches",
        "tags": [
          "Konteks"
        ],
        "summary": "Daftar cabang",
        "description": "Nilai `id` dipakai sebagai header `X-Branch-ID`.",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "responses": {
          "200": {
            "description": "Cabang (urut kode)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Branch"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "code": "PST",
                      "name": "Klinik Sehat Contoh Pusat",
                      "address": "Jl. Contoh No. 1",
                      "city": "Semarang",
                      "phone": "6224000001",
                      "latitude": -6.99,
                      "longitude": 110.42,
                      "geofence_m": 150,
                      "satusehat_location_ihs": null,
                      "bpjs_ppk_code": "0000X001",
                      "is_active": true,
                      "version": 2
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/units": {
      "get": {
        "operationId": "listUnits",
        "tags": [
          "Konteks"
        ],
        "summary": "Daftar unit layanan (poli, farmasi, laboratorium, …)",
        "description": "`id` dipakai sebagai `unit_id` saat mendaftarkan kunjungan atau membaca jadwal. Tanpa `branch_id`: cabang aktif, atau semua cabang bila tidak ada cabang aktif.",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "branch_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "poli",
                "farmasi",
                "laboratorium",
                "radiologi",
                "gudang",
                "kasir",
                "admin",
                "tindakan",
                "penunjang"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Unit layanan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Unit"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "kind": "poli",
                      "code": "UMUM",
                      "name": "Poli Umum",
                      "specialty": "umum",
                      "satusehat_location_ihs": null,
                      "bpjs_poli_code": "001",
                      "is_active": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/practitioners": {
      "get": {
        "operationId": "listPractitioners",
        "tags": [
          "Konteks"
        ],
        "summary": "Daftar tenaga kesehatan aktif",
        "description": "`id` adalah ID keanggotaan yang dipakai sebagai `practitioner_id` di kunjungan, jadwal, dan booking. Difilter ke cabang aktif bila `X-Branch-ID` dikirim. Tidak memuat NIK/STR.",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Tenaga kesehatan (urut nama)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Practitioner"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "user_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
                      "name": "dr. Rina Contoh",
                      "display_title": "dr.",
                      "profession": "dokter",
                      "practitioner_ihs": null,
                      "branch_ids": [],
                      "all_branches": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/terminology/search": {
      "get": {
        "operationId": "searchTerminology",
        "tags": [
          "Terminologi"
        ],
        "summary": "Cari kode terminologi",
        "description": "Pencocokan awalan kode (dengan/tanpa titik, `j069` → J06.9) atau kata pada teks Indonesia, Inggris, dan sinonim awam. Urutan kode persis, awalan kode, lalu kemiripan teks.",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "x-medivana-module": "frontoffice | rme",
        "parameters": [
          {
            "name": "system",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "icd10",
                "icd9cm",
                "loinc",
                "kfa",
                "snomed"
              ]
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "j069"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Kode yang cocok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TerminologyCode"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "system": "icd10",
                      "code": "J06.9",
                      "display": "Infeksi saluran napas atas akut, tidak spesifik",
                      "display_en": "Acute upper respiratory infection, unspecified",
                      "synonyms": "ISPA, batuk pilek",
                      "category": "Pernapasan",
                      "unit": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/terminology/{system}/{code}": {
      "get": {
        "operationId": "getTerminologyCode",
        "tags": [
          "Terminologi"
        ],
        "summary": "Lookup satu kode terminologi",
        "security": [
          {
            "oauth2": []
          }
        ],
        "x-medivana-permissions": [],
        "x-medivana-module": "frontoffice | rme",
        "parameters": [
          {
            "name": "system",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "icd10",
                "icd9cm",
                "loinc",
                "kfa",
                "snomed"
              ]
            }
          },
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "J06.9"
          }
        ],
        "responses": {
          "200": {
            "description": "Kode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TerminologyCode"
                },
                "example": {
                  "system": "loinc",
                  "code": "8480-6",
                  "display": "Tekanan darah sistolik",
                  "display_en": "Systolic blood pressure",
                  "synonyms": null,
                  "category": "Tanda vital",
                  "unit": "mm[Hg]"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients": {
      "get": {
        "operationId": "listPatients",
        "tags": [
          "Pasien"
        ],
        "summary": "Cari atau daftar pasien",
        "description": "`q` dikenali otomatis: 16 digit → NIK (persis), 13 digit → No. BPJS, `08…`/`628…` → telepon, berisi angka tanpa\nspasi → No. RM, selain itu nama (substring lalu kemiripan ejaan). Filter eksplisit boleh digabung. Tanpa `q`/filter:\npasien terbaru berhalaman `cursor`; pencarian tidak berhalaman (maks `limit`). Identitas di daftar selalu tersamar\n(`*_masked`); nilai penuh hanya di detail.\n",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "frontoffice",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "NIK, No. BPJS, telepon, No. RM, atau nama",
            "example": "RM-000123"
          },
          {
            "name": "nik",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{16}$"
            }
          },
          {
            "name": "mrn",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bpjs_no",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{13}$"
            }
          },
          {
            "name": "birth_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "include_merged",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "include_inactive",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar pasien (identitas tersamar)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PatientSummary"
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "mrn": "RM-000123",
                      "name": "Pasien Contoh",
                      "sex": "female",
                      "birth_date": "1990-05-12",
                      "age_label": "36 th 5 bl",
                      "age_years": 36,
                      "nik_masked": "9999********0001",
                      "phone_masked": "6281******001",
                      "bpjs_no_masked": "*********0001",
                      "allergy_status": "has",
                      "is_active": true,
                      "merged_into": null
                    }
                  ],
                  "next_cursor": "eyJ0IjoiMjAyNi0xMC0yOVQwODoxNTowMiswNzowMCJ9"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createPatient",
        "tags": [
          "Pasien"
        ],
        "summary": "Daftarkan pasien baru",
        "description": "Wajib `name` dan `sex`. `mrn` kosong → nomor RM otomatis sesuai pengaturan RM klinik. Telepon dinormalkan ke `62…`.\nBila `nik` diisi dan `satusehat_ihs` kosong, server mencari IHS number ke SATUSEHAT (maks 3 detik; kegagalan tidak\nmenghalangi pendaftaran, lihat `satusehat_lookup`). NIK yang sudah terdaftar → `409` dengan `existing_patient_id`;\nbaca pasien itu alih-alih membuat baru. Menerbitkan event `patient.created`.\n",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchRequired"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatientInput"
              },
              "example": {
                "name": "Pasien Contoh",
                "sex": "female",
                "birth_date": "1990-05-12",
                "birth_place": "Semarang",
                "nik": "9999010101900001",
                "phone": "0812-0000-0001",
                "email": "pasien@contoh.test",
                "address": "Jl. Contoh No. 10",
                "city": "Semarang",
                "province": "Jawa Tengah",
                "skip_satusehat_lookup": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pasien dibuat",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Patient"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/Patient"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BranchRequired"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "description": "NIK sudah terdaftar",
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Problem"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "existing_patient_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "https://medivana.cloud/errors/conflict",
                  "title": "Terjadi konflik data",
                  "status": 409,
                  "code": "conflict",
                  "detail": "NIK sudah terdaftar atas nama Pasien Contoh (No. RM RM-000123). Buka data pasien tersebut alih-alih membuat baru.",
                  "existing_patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "instance": "/api/v1/patients",
                  "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/duplicate-check": {
      "get": {
        "operationId": "checkDuplicatePatients",
        "tags": [
          "Pasien"
        ],
        "summary": "Periksa kemungkinan pasien ganda",
        "description": "Panggil sebelum membuat pasien. Kriteria NIK sama (skor 1), telepon sama (0,6), tanggal lahir sama + nama mirip, atau nama sangat mirip.",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "frontoffice",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "birth_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "nik",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exclude_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Abaikan pasien ini (saat mengubah data)"
          }
        ],
        "responses": {
          "200": {
            "description": "Kandidat duplikat (skor tertinggi dulu)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/PatientSummary"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "reasons": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "nik",
                                    "phone",
                                    "name_birth_date",
                                    "name"
                                  ]
                                }
                              },
                              "score": {
                                "type": "number"
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "mrn": "RM-000123",
                      "name": "Pasien Contoh",
                      "sex": "female",
                      "birth_date": "1990-05-12",
                      "nik_masked": "9999********0001",
                      "reasons": [
                        "name_birth_date"
                      ],
                      "score": 0.8
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/lookup-nik": {
      "post": {
        "operationId": "lookupPatientNIK",
        "tags": [
          "Pasien"
        ],
        "summary": "Cari NIK di data lokal lalu SATUSEHAT",
        "description": "`local` berisi pasien tersamar bila NIK sudah terdaftar. SATUSEHAT dilewati (`skipped`) bila pasien lokal sudah punya IHS number. `unavailable` = integrasi belum dikonfigurasi, galat, atau timeout.",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "nik"
                ],
                "properties": {
                  "nik": {
                    "type": "string",
                    "pattern": "^[0-9]{16}$"
                  }
                }
              },
              "example": {
                "nik": "9999010101900001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hasil lookup",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "local": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/PatientSummary"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "satusehat": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "found",
                            "not_found",
                            "unavailable",
                            "skipped"
                          ]
                        },
                        "patient": {
                          "oneOf": [
                            {
                              "$ref": "#/components/schemas/SatusehatPatient"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "local": null,
                  "satusehat": {
                    "status": "found",
                    "patient": {
                      "ihs_number": "P00000000001",
                      "nik": "9999010101900001",
                      "name": "PASIEN CONTOH",
                      "birth_date": "1990-05-12T00:00:00Z",
                      "gender": "female",
                      "address": "Jl. Contoh No. 10"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/mrn-settings": {
      "get": {
        "operationId": "getMRNSettings",
        "tags": [
          "Pasien"
        ],
        "summary": "Format nomor rekam medis",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "frontoffice",
        "responses": {
          "200": {
            "description": "Pengaturan nomor RM",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "prefix": {
                      "type": "string"
                    },
                    "pad_length": {
                      "type": "integer"
                    },
                    "last_value": {
                      "type": "integer"
                    },
                    "example": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "prefix": "RM-",
                  "pad_length": 6,
                  "last_value": 122,
                  "example": "RM-000123"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getPatient",
        "tags": [
          "Pasien"
        ],
        "summary": "Detail pasien",
        "description": "Identitas lengkap (NIK, telepon, BPJS penuh). Setiap pembacaan dicatat di audit log (`patient.read`). Pasien yang sudah digabung punya `merged_into`; ikuti ke pasien tujuan.",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "frontoffice",
        "responses": {
          "200": {
            "description": "Pasien",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Patient"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/Patient"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updatePatient",
        "tags": [
          "Pasien"
        ],
        "summary": "Ubah data pasien",
        "description": "Kirim hanya field yang berubah; string kosong `\"\"` mengosongkan field opsional. Mengubah `nik` dicek duplikat (`409` + `existing_patient_id`). Pasien yang sudah digabung → `409`. Menerbitkan event `patient.updated`.",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchRequired"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatientInput"
              },
              "example": {
                "phone": "0812-0000-0002",
                "address": "Jl. Contoh Baru No. 2",
                "email": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pasien terbaru",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Patient"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BranchRequired"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/Stale"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/{id}/satusehat-lookup": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "refreshPatientSatusehat",
        "tags": [
          "Pasien"
        ],
        "summary": "Lookup ulang IHS number SATUSEHAT dari NIK tersimpan",
        "description": "Tanpa body. `422` bila pasien belum punya NIK. Respons memuat `satusehat_lookup`.",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchRequired"
          }
        ],
        "responses": {
          "200": {
            "description": "Pasien",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Patient"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BranchRequired"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/{id}/merges": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listPatientMerges",
        "tags": [
          "Pasien"
        ],
        "summary": "Riwayat penggabungan pasien",
        "description": "Penggabungan di mana pasien menjadi tujuan atau sumber. Penggabungan dilakukan petugas di aplikasi (event `patient.merged`).",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "frontoffice",
        "responses": {
          "200": {
            "description": "Riwayat gabung",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PatientMerge"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a9001",
                      "target_patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "source_patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0002",
                      "reason": "Pasien terdaftar dua kali",
                      "source_snapshot": {
                        "mrn": "RM-000124",
                        "name": "Pasien Contoh",
                        "sex": "female",
                        "birth_date": "1990-05-12",
                        "had_nik": false
                      },
                      "moved": {
                        "encounters": 1,
                        "queues": 1,
                        "observations": 6,
                        "diagnoses": 1,
                        "procedures": 0,
                        "allergies": 0,
                        "consents": 0,
                        "letters": 0,
                        "clinical_documents": 0,
                        "charges": 2,
                        "files": 0
                      },
                      "merged_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
                      "merged_at": "2026-10-29T09:00:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/{id}/consents": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listPatientConsents",
        "tags": [
          "Pasien"
        ],
        "summary": "Consent pasien (terkini per jenis dan riwayat)",
        "description": "`current[kind]` = consent terbaru per jenis (bisa `withdrawn`), `null` bila belum pernah. Jenis: `data_processing`, `photo`, `recording`, `telemedicine`, `broadcast`.",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "frontoffice",
        "responses": {
          "200": {
            "description": "Consent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "current": {
                      "type": "object",
                      "additionalProperties": {
                        "oneOf": [
                          {
                            "$ref": "#/components/schemas/Consent"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Consent"
                      }
                    }
                  }
                },
                "example": {
                  "current": {
                    "data_processing": null,
                    "photo": {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a7001",
                      "kind": "photo",
                      "status": "granted"
                    },
                    "recording": null,
                    "telemedicine": null,
                    "broadcast": null
                  },
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a7001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "kind": "photo",
                      "status": "granted",
                      "consent_version": "1.0",
                      "consent_text": "Saya setuju foto klinis diambil untuk rekam medis.",
                      "method": "written",
                      "signer_name": null,
                      "signer_relation": "self",
                      "witness_name": null,
                      "evidence_file_id": null,
                      "encounter_id": null,
                      "granted_at": "2026-10-29T08:20:00+07:00",
                      "granted_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
                      "withdrawn_at": null,
                      "withdrawn_by": null,
                      "withdraw_reason": null
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/{id}/allergies": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listPatientAllergies",
        "tags": [
          "Pasien"
        ],
        "summary": "Alergi pasien",
        "description": "`allergy_status`: `unknown` (belum dikaji), `none` (tidak ada alergi), `has`. Alergi `resolved` disembunyikan kecuali `include_resolved=true`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          },
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "patient.read"
        ],
        "x-medivana-module": "rme",
        "parameters": [
          {
            "name": "include_resolved",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alergi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "allergy_status": {
                      "type": "string",
                      "enum": [
                        "unknown",
                        "none",
                        "has"
                      ]
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Allergy"
                      }
                    }
                  }
                },
                "example": {
                  "allergy_status": "has",
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a8001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "substance": "Amoksisilin",
                      "substance_code": null,
                      "code_system": null,
                      "item_id": null,
                      "category": "obat",
                      "reaction": "Urtikaria",
                      "severity": "berat",
                      "status": "active",
                      "onset": "2019",
                      "notes": null,
                      "recorded_at": "2026-10-29T09:10:00+07:00",
                      "recorded_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
                      "resolved_at": null,
                      "version": 1
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/{id}/history-summary": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getPatientHistorySummary",
        "tags": [
          "Pasien"
        ],
        "summary": "Riwayat klinis ringkas pasien",
        "description": "Kunjungan terakhir, diagnosis berulang, tindakan, alergi aktif, dan tren tanda vital (≤10 nilai per kunci, lama → baru). Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "parameters": [
          {
            "name": "encounters",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 5,
              "maximum": 20
            },
            "description": "Jumlah kunjungan terakhir"
          }
        ],
        "responses": {
          "200": {
            "description": "Ringkasan riwayat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "patient": {
                      "$ref": "#/components/schemas/PatientBrief"
                    },
                    "allergies": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Allergy"
                      }
                    },
                    "recent_encounters": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "branch_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "registered_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "status": {
                            "type": "string"
                          },
                          "unit_name": {
                            "type": "string"
                          },
                          "practitioner_name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "chief_complaint": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "primary_diagnosis": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "display": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "diagnoses": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "display": {
                            "type": "string"
                          },
                          "count": {
                            "type": "integer"
                          },
                          "last_seen": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "procedures": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Procedure"
                      }
                    },
                    "vitals_trend": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "number"
                            },
                            "flag": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "observed_at": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "patient": {
                    "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                    "name": "Pasien Contoh",
                    "mrn": "RM-000123",
                    "sex": "female",
                    "birth_date": "1990-05-12",
                    "age_label": "36 th 5 bl",
                    "age_years": 36,
                    "allergy_status": "has"
                  },
                  "allergies": [],
                  "recent_encounters": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "registered_at": "2026-10-29T08:30:00+07:00",
                      "status": "finished",
                      "unit_name": "Poli Umum",
                      "practitioner_name": "dr. Rina Contoh",
                      "chief_complaint": "Batuk pilek 3 hari",
                      "primary_diagnosis": {
                        "code": "J06.9",
                        "display": "Infeksi saluran napas atas akut, tidak spesifik"
                      }
                    }
                  ],
                  "diagnoses": [
                    {
                      "code": "J06.9",
                      "display": "Infeksi saluran napas atas akut, tidak spesifik",
                      "count": 3,
                      "last_seen": "2026-10-29T10:45:00+07:00"
                    }
                  ],
                  "procedures": [],
                  "vitals_trend": {
                    "systolic": [
                      {
                        "value": 150,
                        "flag": "H",
                        "observed_at": "2026-10-29T09:05:00+07:00"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/patients/{id}/documents": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listPatientDocuments",
        "tags": [
          "Pasien"
        ],
        "summary": "Dokumen pasien (termasuk dokumen kunjungan)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "responses": {
          "200": {
            "description": "Dokumen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ClinicalDocument"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "encounter_id": null,
                      "file_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6101",
                      "title": "Hasil lab luar",
                      "category": "lab_external",
                      "notes": null,
                      "filename": "hasil-lab.pdf",
                      "content_type": "application/pdf",
                      "size_bytes": 182311,
                      "uploaded_by": "3f0c2a10-5b7e-4c1d-9a2e-000000000a11",
                      "created_at": "2026-10-29T08:40:00+07:00",
                      "download_url": "/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-0000000a6001/download"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "uploadPatientDocument",
        "tags": [
          "Pasien"
        ],
        "summary": "Unggah dokumen pasien",
        "description": "`multipart/form-data`, maks 20 MB. Tipe: PDF, JPG, PNG, WEBP, audio, DICOM, CSV, ZIP, JSON. `file_id` hasil unggahan bisa dipakai sebagai bukti consent di aplikasi.",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.write",
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchRequired"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "title": {
                    "type": "string",
                    "description": "Default nama berkas"
                  },
                  "category": {
                    "type": "string",
                    "enum": [
                      "general",
                      "lab_external",
                      "imaging",
                      "referral",
                      "consent",
                      "photo",
                      "identity",
                      "other"
                    ],
                    "default": "general"
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dokumen dibuat",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClinicalDocument"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ClinicalDocument"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BranchRequired"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/clinical-documents/{id}/download": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "downloadClinicalDocument",
        "tags": [
          "Pasien"
        ],
        "summary": "Unduh isi dokumen klinis",
        "description": "Isi berkas apa adanya (`Content-Disposition: inline`). Diaudit `document.read`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "responses": {
          "200": {
            "description": "Isi berkas",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/clinical-documents/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "delete": {
        "operationId": "deleteClinicalDocument",
        "tags": [
          "Pasien"
        ],
        "summary": "Hapus dokumen klinis (soft delete)",
        "description": "Dokumen kunjungan yang sudah ditandatangani tidak bisa dihapus (`409`).",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.write",
          "patient.write"
        ],
        "x-medivana-module": "frontoffice",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchRequired"
          }
        ],
        "responses": {
          "204": {
            "description": "Dihapus"
          },
          "400": {
            "$ref": "#/components/responses/BranchRequired"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/registration/payers": {
      "get": {
        "operationId": "listRegistrationPayers",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Penjamin aktif untuk pendaftaran kunjungan",
        "description": "Umum dulu, lalu BPJS, asuransi, perusahaan. `id` dipakai sebagai `payer_id` di `POST /encounters`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "patient.write",
          "queue.manage"
        ],
        "x-medivana-module": "frontoffice | rme",
        "responses": {
          "200": {
            "description": "Penjamin",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "kind": {
                            "$ref": "#/components/schemas/PayerKind"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
                      "code": "UMUM",
                      "name": "Pasien Umum",
                      "kind": "umum"
                    },
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0002",
                      "code": "BPJS",
                      "name": "BPJS Kesehatan",
                      "kind": "bpjs"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters": {
      "get": {
        "operationId": "listEncounters",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Daftar kunjungan",
        "description": "Difilter ke cabang aktif, terbaru dulu. `date` default hari ini (Asia/Jakarta) dan diabaikan bila hanya `patient_id` yang dikirim (riwayat semua tanggal).",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "queue.manage"
        ],
        "x-medivana-module": "frontoffice | rme",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "unit_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "payer_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "practitioner_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Dipisah koma: registered, in_progress, finished, cancelled",
            "example": "registered,in_progress"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Kunjungan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Encounter"
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                      "unit_name": "Poli Umum",
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "practitioner_name": "dr. Rina Contoh",
                      "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
                      "payer_name": "Pasien Umum",
                      "payer_kind": "umum",
                      "kind": "rawat_jalan",
                      "status": "in_progress",
                      "queue_label": "U-003",
                      "chief_complaint": "Batuk pilek 3 hari",
                      "registered_at": "2026-10-29T08:30:00+07:00",
                      "started_at": "2026-10-29T09:02:00+07:00",
                      "finished_at": null,
                      "version": 3
                    }
                  ],
                  "next_cursor": "eyJ0IjoiMjAyNi0xMC0yOVQwODozMDowMCswNzowMCJ9"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "registerEncounter",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Daftarkan kunjungan dan terbitkan nomor antrean",
        "description": "Wajib `patient_id` dan `unit_id` (unit poli/tindakan di cabang aktif). `payer_id` dari `GET /registration/payers`;\nkosong → Pasien Umum. `registration_fee: null` = otomatis (biaya pendaftaran untuk penjamin umum).\nPasien yang sudah terdaftar aktif di poli yang sama hari ini → `409`. Menerbitkan event `encounter.started`.\n",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.write"
        ],
        "x-medivana-module": "frontoffice | rme",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchRequired"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "patient_id",
                  "unit_id"
                ],
                "properties": {
                  "patient_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "unit_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "practitioner_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "payer_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "payer_reference": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "No. SEP/polis/jaminan"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "rawat_jalan",
                      "telekonsultasi",
                      "kunjungan_sehat"
                    ],
                    "default": "rawat_jalan"
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "normal",
                      "priority"
                    ],
                    "default": "normal"
                  },
                  "chief_complaint": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "appointment_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "registration_fee": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  }
                }
              },
              "example": {
                "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                "payer_id": null,
                "kind": "rawat_jalan",
                "priority": "normal",
                "chief_complaint": "Demam 2 hari"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dengan `appointment_id` yang sudah check-in: kunjungan yang sudah ada (idempoten)"
          },
          "201": {
            "description": "Kunjungan dan tiket antrean dibuat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "encounter": {
                      "$ref": "#/components/schemas/Encounter"
                    },
                    "queue": {
                      "$ref": "#/components/schemas/QueueTicket"
                    }
                  }
                },
                "example": {
                  "encounter": {
                    "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                    "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                    "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                    "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                    "unit_name": "Poli Umum",
                    "payer_kind": "umum",
                    "kind": "rawat_jalan",
                    "status": "registered",
                    "chief_complaint": "Demam 2 hari",
                    "registered_at": "2026-10-29T08:30:00+07:00",
                    "version": 1
                  },
                  "queue": {
                    "id": "3f0c2a10-5b7e-4c1d-9a2e-000000005001",
                    "unit_name": "Poli Umum",
                    "label": "U-003",
                    "number": 3,
                    "status": "waiting",
                    "priority": "normal",
                    "source": "registration",
                    "service_date": "2026-10-29"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BranchRequired"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getEncounter",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Detail kunjungan lengkap (RME)",
        "description": "Kunjungan beserta catatan SOAP, tanda vital, diagnosis, tindakan, alergi aktif, tanda tangan, dokumen, dan surat. Diaudit `encounter.read`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Kunjungan lengkap",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Encounter"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "note": {
                          "oneOf": [
                            {
                              "$ref": "#/components/schemas/Note"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "vitals": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Observation"
                          }
                        },
                        "diagnoses": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Diagnosis"
                          }
                        },
                        "procedures": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Procedure"
                          }
                        },
                        "allergies": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Allergy"
                          }
                        },
                        "signatures": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Signature"
                          }
                        },
                        "documents": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ClinicalDocument"
                          }
                        },
                        "letters": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Letter"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "unit_name": "Poli Umum",
                  "status": "finished",
                  "kind": "rawat_jalan",
                  "chief_complaint": "Batuk pilek 3 hari",
                  "patient": {
                    "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                    "name": "Pasien Contoh",
                    "mrn": "RM-000123",
                    "sex": "female",
                    "birth_date": "1990-05-12",
                    "age_label": "36 th 5 bl",
                    "age_years": 36,
                    "allergy_status": "has"
                  },
                  "note": {
                    "id": "3f0c2a10-5b7e-4c1d-9a2e-000000006001",
                    "subjective": "Batuk pilek 3 hari, demam ringan.",
                    "objective": "T 37,8 °C, faring hiperemis.",
                    "assessment": "ISPA",
                    "plan": "Simtomatik, kontrol bila memburuk.",
                    "status": "signed",
                    "version": 1
                  },
                  "vitals": [
                    {
                      "key": "temperature",
                      "code": "8310-5",
                      "display": "Suhu tubuh",
                      "value_num": 37.8,
                      "unit": "Cel",
                      "flag": "H",
                      "observed_at": "2026-10-29T09:05:00+07:00"
                    }
                  ],
                  "diagnoses": [
                    {
                      "icd10_code": "J06.9",
                      "display": "Infeksi saluran napas atas akut, tidak spesifik",
                      "is_primary": true,
                      "kind": "new",
                      "rank": 1
                    }
                  ],
                  "procedures": [],
                  "allergies": [],
                  "signatures": [
                    {
                      "kind": "close",
                      "note_version": 1,
                      "signer_name": "dr. Rina Contoh",
                      "signed_at": "2026-10-29T10:45:00+07:00"
                    }
                  ],
                  "documents": [],
                  "letters": [],
                  "version": 4
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/cancel": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "cancelEncounter",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Batalkan kunjungan",
        "description": "Membatalkan charge yang belum ditagih dan tiket antreannya. Kunjungan selesai/batal atau dengan charge yang sudah ditagih → `409`. Menerbitkan event `encounter.cancelled`.",
        "security": [
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.write",
          "patient.write"
        ],
        "x-medivana-module": "frontoffice | rme",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchRequired"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "reason": "Pasien pulang sebelum diperiksa"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kunjungan dibatalkan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Encounter"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BranchRequired"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/vitals": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listEncounterVitals",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Tanda vital kunjungan (LOINC + UCUM)",
        "description": "`latest` = nilai terakhir per kunci. `flag`: `N`, `L`/`H` (rendah/tinggi), `LL`/`HH` (kritis), `null` (tidak dinilai).",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Observasi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Observation"
                      }
                    },
                    "latest": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/Observation"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000007001",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "panel_id": "3f0c2a10-5b7e-4c1d-9a2e-000000007101",
                      "key": "systolic",
                      "code": "8480-6",
                      "display": "Tekanan darah sistolik",
                      "value_num": 150,
                      "value_text": null,
                      "unit": "mm[Hg]",
                      "flag": "H",
                      "status": "final",
                      "observed_at": "2026-10-29T09:05:00+07:00",
                      "recorded_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001"
                    }
                  ],
                  "latest": {
                    "systolic": {
                      "key": "systolic",
                      "code": "8480-6",
                      "value_num": 150,
                      "unit": "mm[Hg]",
                      "flag": "H"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/note": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getEncounterNote",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Catatan SOAP kunjungan",
        "description": "Bila belum ada catatan, respons adalah draf virtual dari template poli (`id: null`, `is_new: true`). `version` = versi klinis (naik saat koreksi setelah tanda tangan). Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Catatan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Note"
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000006001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "template_id": "3f0c2a10-5b7e-4c1d-9a2e-000000006101",
                  "subjective": "Batuk pilek 3 hari, demam ringan.",
                  "objective": "T 37,8 °C, faring hiperemis.",
                  "assessment": "ISPA",
                  "plan": "Simtomatik, kontrol bila memburuk.",
                  "extra": {},
                  "status": "signed",
                  "version": 1,
                  "revision": 6,
                  "signed_at": "2026-10-29T10:45:00+07:00",
                  "signed_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
                  "saved_at": "2026-10-29T10:42:13+07:00",
                  "saved_at_label": "Tersimpan 10.42",
                  "is_new": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/note/versions": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listEncounterNoteVersions",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Riwayat versi catatan yang sudah ditandatangani",
        "description": "Versi lama tidak pernah ditimpa (koreksi berversi, append-only). Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Versi (urut naik)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "version": {
                            "type": "integer"
                          },
                          "subjective": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "objective": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "assessment": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "plan": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "extra": {
                            "type": "object"
                          },
                          "content_hash": {
                            "type": "string"
                          },
                          "reason": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Alasan koreksi (null untuk versi 1)"
                          },
                          "signature_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "signer_name": {
                            "type": "string"
                          },
                          "created_by": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000006201",
                      "version": 1,
                      "subjective": "Batuk pilek 3 hari.",
                      "objective": "T 37,8 °C.",
                      "assessment": "ISPA",
                      "plan": "Simtomatik",
                      "extra": {},
                      "content_hash": "9f2c4b1e0d8a7c6b5a49382716f5e4d3c2b1a09f8e7d6c5b4a3928171605f4e3",
                      "reason": null,
                      "signature_id": "3f0c2a10-5b7e-4c1d-9a2e-000000006301",
                      "signer_name": "dr. Rina Contoh",
                      "created_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
                      "created_at": "2026-10-29T10:45:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/diagnoses": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listEncounterDiagnoses",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Diagnosis ICD-10 kunjungan",
        "description": "Diagnosis utama dulu.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Diagnosis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Diagnosis"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000008001",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "icd10_code": "J06.9",
                      "display": "Infeksi saluran napas atas akut, tidak spesifik",
                      "is_primary": true,
                      "kind": "new",
                      "rank": 1,
                      "notes": null,
                      "created_at": "2026-10-29T10:30:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/procedures": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listEncounterProcedures",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Tindakan ICD-9-CM kunjungan",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Tindakan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Procedure"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000008101",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "icd9cm_code": "93.94",
                      "display": "Pemberian obat pernapasan dengan nebulizer",
                      "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f001",
                      "service_name": "Nebulisasi",
                      "quantity": 1,
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "charge_id": "3f0c2a10-5b7e-4c1d-9a2e-000000009001",
                      "status": "done",
                      "notes": null,
                      "performed_at": "2026-10-29T10:20:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/signatures": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listEncounterSignatures",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Tanda tangan elektronik kunjungan (penutupan dan koreksi)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Tanda tangan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Signature"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000006301",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "note_id": "3f0c2a10-5b7e-4c1d-9a2e-000000006001",
                      "note_version": 1,
                      "kind": "close",
                      "content_hash": "9f2c4b1e0d8a7c6b5a49382716f5e4d3c2b1a09f8e7d6c5b4a3928171605f4e3",
                      "signer_membership_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "signer_name": "dr. Rina Contoh",
                      "method": "internal",
                      "reason": null,
                      "signed_at": "2026-10-29T10:45:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/encounters/{id}/documents": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listEncounterDocuments",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Dokumen yang terkait kunjungan",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Dokumen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ClinicalDocument"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenConfidential"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/note-templates": {
      "get": {
        "operationId": "listNoteTemplates",
        "tags": [
          "Kunjungan"
        ],
        "summary": "Template catatan SOAP",
        "description": "Bawaan: `SOAP-UMUM`, `SOAP-GIGI`, `SOAP-KIA`, `SOAP-ESTETIK`, `SOAP-FISIO`. `fields` = isian terstruktur yang tersimpan di `Note.extra`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "encounter.write"
        ],
        "x-medivana-module": "rme",
        "parameters": [
          {
            "name": "specialty",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "gigi"
          },
          {
            "name": "unit_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_inactive",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NoteTemplate"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000006101",
                      "code": "SOAP-GIGI",
                      "name": "SOAP Poli Gigi",
                      "specialty": "gigi",
                      "unit_id": null,
                      "subjective": "Keluhan utama:\n",
                      "objective": "",
                      "assessment": "",
                      "plan": "",
                      "fields": [
                        {
                          "key": "tooth_elements",
                          "label": "Elemen gigi (FDI)",
                          "type": "text"
                        }
                      ],
                      "is_default": true,
                      "is_active": true,
                      "version": 1
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/letters": {
      "get": {
        "operationId": "listLetters",
        "tags": [
          "Surat"
        ],
        "summary": "Surat yang diterbitkan untuk pasien atau kunjungan",
        "description": "Salah satu dari `patient_id` atau `encounter_id` wajib. Tanpa `content_html`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "letter.write"
        ],
        "x-medivana-module": "rme",
        "parameters": [
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "encounter_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Surat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Letter"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000004001",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "kind": "sick_leave",
                      "number": "001/SKS/X/2026",
                      "title": "Surat Keterangan Sakit",
                      "data": {
                        "rest_days": 3,
                        "start_date": "2026-10-29"
                      },
                      "paper_size": "A5",
                      "status": "issued",
                      "issued_at": "2026-10-29T10:50:00+07:00",
                      "issued_by_name": "dr. Rina Contoh",
                      "void_reason": null,
                      "print_url": "/api/v1/letters/3f0c2a10-5b7e-4c1d-9a2e-000000004001/print",
                      "patient_name": "Pasien Contoh",
                      "patient_mrn": "RM-000123"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/letters/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getLetter",
        "tags": [
          "Surat"
        ],
        "summary": "Detail surat",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "letter.write"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Surat (tanpa content_html)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Letter"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/letters/{id}/print": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "printLetter",
        "tags": [
          "Surat"
        ],
        "summary": "Halaman cetak surat (HTML)",
        "description": "HTML siap cetak (`@page` A5/A4). Surat `void` diberi watermark DIBATALKAN. Bahasa mengikuti snapshot surat. Diaudit `letter.print`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "letter.write"
        ],
        "x-medivana-module": "rme",
        "responses": {
          "200": {
            "description": "Dokumen HTML",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/appointments": {
      "get": {
        "operationId": "listAppointments",
        "tags": [
          "Booking"
        ],
        "summary": "Daftar booking",
        "description": "Default hari ini di cabang aktif. Pakai `date` atau rentang `from`/`to`. `status` boleh dipisah koma.",
        "security": [
          {
            "oauth2": [
              "appointments:read"
            ]
          },
          {
            "oauth2": [
              "appointments:write"
            ]
          },
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage",
          "appointment.read",
          "encounter.read",
          "queue.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "practitioner_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "unit_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "branch_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "booked, checked_in, cancelled, no_show, done (pisah koma)"
          }
        ],
        "responses": {
          "200": {
            "description": "Booking (urut waktu mulai)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Appointment"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a001",
                      "code": "BK-7KQ2MZ",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                      "unit_name": "Poli Umum",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "patient_name": "Pasien Contoh",
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "practitioner_name": "dr. Rina Contoh",
                      "start_at": "2026-11-02T08:15:00+07:00",
                      "end_at": "2026-11-02T08:30:00+07:00",
                      "status": "booked",
                      "source": "admin",
                      "payer_kind": "umum",
                      "complaint": "Demam 3 hari",
                      "version": 1
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createAppointment",
        "tags": [
          "Booking"
        ],
        "summary": "Buat booking",
        "description": "Isi `patient_id` (pasien terdaftar) **atau** `patient` (pasien baru; identitas disimpan terenkripsi dan pasien\ndidaftarkan saat check-in). `start_at` harus tepat pada grid slot jadwal (`GET /booking/slots`): di luar jadwal,\ntidak sejajar slot, atau sudah lewat → `422`; slot terisi, kuota penuh, atau cuti/libur → `409`.\n`notify: true` mengirim konfirmasi WhatsApp bila nomor diketahui. Menerbitkan event `appointment.booked`.\n",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "practitioner_id",
                  "start_at"
                ],
                "properties": {
                  "patient_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "patient": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "phone": {
                        "type": "string"
                      },
                      "nik": {
                        "type": "string"
                      },
                      "birth_date": {
                        "type": "string",
                        "format": "date"
                      },
                      "sex": {
                        "type": "string",
                        "enum": [
                          "male",
                          "female"
                        ]
                      }
                    }
                  },
                  "practitioner_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "unit_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "service_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "start_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "whatsapp",
                      "bpjs"
                    ],
                    "default": "admin"
                  },
                  "payer_kind": {
                    "$ref": "#/components/schemas/PayerKind"
                  },
                  "payer_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "complaint": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "notify": {
                    "type": "boolean",
                    "default": true
                  }
                }
              },
              "example": {
                "patient_id": null,
                "patient": {
                  "name": "Pasien Baru Contoh",
                  "phone": "0812-0000-0003",
                  "birth_date": "1999-09-09",
                  "sex": "female"
                },
                "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                "start_at": "2026-11-02T08:15:00+07:00",
                "source": "admin",
                "payer_kind": "umum",
                "complaint": "Demam 3 hari",
                "notify": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Booking dibuat",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/Appointment"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/appointments/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getAppointment",
        "tags": [
          "Booking"
        ],
        "summary": "Detail booking",
        "description": "`encounter_id` terisi setelah check-in.",
        "security": [
          {
            "oauth2": [
              "appointments:read"
            ]
          },
          {
            "oauth2": [
              "appointments:write"
            ]
          },
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage",
          "appointment.read",
          "encounter.read",
          "queue.manage"
        ],
        "x-medivana-module": "booking",
        "responses": {
          "200": {
            "description": "Booking",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/Appointment"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updateAppointment",
        "tags": [
          "Booking"
        ],
        "summary": "Ubah data booking",
        "description": "Hanya untuk status `booked`. Untuk mengganti waktu/dokter pakai `reschedule`.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "patient_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Hubungkan ke pasien terdaftar"
                  },
                  "complaint": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "payer_kind": {
                    "$ref": "#/components/schemas/PayerKind"
                  },
                  "payer_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "service_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                "complaint": "Demam 3 hari, batuk"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/Stale"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/appointments/{id}/cancel": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "cancelAppointment",
        "tags": [
          "Booking"
        ],
        "summary": "Batalkan booking",
        "description": "Menerbitkan event `appointment.cancelled`; `notify` mengirim pemberitahuan WhatsApp ke pasien.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string"
                  },
                  "notify": {
                    "type": "boolean",
                    "default": true
                  }
                }
              },
              "example": {
                "reason": "Pasien berhalangan",
                "notify": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking dibatalkan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/appointments/{id}/check-in": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "checkInAppointment",
        "tags": [
          "Booking"
        ],
        "summary": "Check-in pasien pada hari booking",
        "description": "Hanya status `booked` pada tanggal booking (selain itu `409`). Pasien baru wajib didaftarkan dulu\n(`POST /patients`) lalu dikirim `patient_id` (`422` bila kosong). Menerbitkan event `appointment.checked_in`;\nkunjungan dan nomor antrean dibuat otomatis (`encounter_id`).\n",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage",
          "queue.manage"
        ],
        "x-medivana-module": "booking",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "patient_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "payer_kind": {
                    "$ref": "#/components/schemas/PayerKind"
                  },
                  "payer_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                "payer_kind": "bpjs",
                "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0002"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking `checked_in` dengan `encounter_id`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/appointments/{id}/no-show": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "markAppointmentNoShow",
        "tags": [
          "Booking"
        ],
        "summary": "Tandai pasien tidak datang",
        "description": "Hanya setelah jam booking lewat dan status `booked`.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage",
          "queue.manage"
        ],
        "x-medivana-module": "booking",
        "responses": {
          "200": {
            "description": "Booking `no_show`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/appointments/{id}/reschedule": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "rescheduleAppointment",
        "tags": [
          "Booking"
        ],
        "summary": "Jadwal ulang booking",
        "description": "Aturan slot sama dengan pembuatan booking. Menerbitkan `appointment.booked` dengan `rescheduled: true`.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "start_at"
                ],
                "properties": {
                  "start_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "practitioner_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "unit_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "start_at": "2026-11-03T09:00:00+07:00"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking dengan waktu baru",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/slots": {
      "get": {
        "operationId": "listSlots",
        "tags": [
          "Booking"
        ],
        "summary": "Slot praktik dan ketersediaannya",
        "description": "Dari jadwal mingguan dikurangi cuti/libur, booking aktif, kuota sesi, dan waktu lewat. Pakai `date` atau rentang\n`from`/`to` (maks 31 hari). `reason` bila tidak tersedia: `booked`, `quota_full`, `leave`, `closed`, `past`.\n",
        "security": [
          {
            "oauth2": [
              "appointments:read"
            ]
          },
          {
            "oauth2": [
              "appointments:write"
            ]
          },
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage",
          "appointment.read",
          "encounter.read",
          "queue.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "name": "practitioner_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "branch_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "unit_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "online_only",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Hanya jadwal yang boleh dipesan daring"
          },
          {
            "name": "available_only",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Slot",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Slot"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "schedule_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a101",
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                      "date": "2026-11-02",
                      "start_at": "2026-11-02T08:00:00+07:00",
                      "end_at": "2026-11-02T08:15:00+07:00",
                      "time": "08:00",
                      "available": false,
                      "reason": "booked",
                      "remaining_quota": 9
                    },
                    {
                      "schedule_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a101",
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                      "date": "2026-11-02",
                      "start_at": "2026-11-02T08:15:00+07:00",
                      "end_at": "2026-11-02T08:30:00+07:00",
                      "time": "08:15",
                      "available": true,
                      "reason": null,
                      "remaining_quota": 9
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/schedules": {
      "get": {
        "operationId": "listSchedules",
        "tags": [
          "Booking"
        ],
        "summary": "Jadwal praktik mingguan",
        "description": "`weekday` ISO (1 = Senin … 7 = Minggu); jam `HH:MM` WIB.",
        "security": [
          {
            "oauth2": [
              "appointments:read"
            ]
          },
          {
            "oauth2": [
              "appointments:write"
            ]
          },
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage",
          "appointment.read",
          "encounter.read",
          "queue.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "name": "practitioner_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "branch_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "unit_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_inactive",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Jadwal",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Schedule"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a101",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                      "unit_name": "Poli Umum",
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "practitioner_name": "dr. Rina Contoh",
                      "weekday": 1,
                      "weekday_label": "Senin",
                      "start_time": "08:00",
                      "end_time": "12:00",
                      "slot_minutes": 15,
                      "quota": 12,
                      "slot_count": 16,
                      "allow_online": true,
                      "valid_from": "2026-11-01",
                      "valid_until": null,
                      "is_active": true,
                      "note": "Poli umum pagi",
                      "version": 1
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createSchedule",
        "tags": [
          "Booking"
        ],
        "summary": "Buat jadwal praktik",
        "description": "`branch_id` default cabang aktif; unit harus di cabang itu dan dokter bertugas di cabang itu. Jadwal bertumpuk untuk dokter yang sama di hari yang sama → `409`. `quota` ≤ jumlah slot; `allow_online: false` menyembunyikan jadwal dari portal pasien.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleInput"
              },
              "example": {
                "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                "weekday": 1,
                "start_time": "08:00",
                "end_time": "12:00",
                "slot_minutes": 15,
                "quota": 12,
                "allow_online": true,
                "valid_from": "2026-11-01",
                "valid_until": null,
                "note": "Poli umum pagi"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Jadwal dibuat",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/Schedule"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/schedules/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "patch": {
        "operationId": "updateSchedule",
        "tags": [
          "Booking"
        ],
        "summary": "Ubah jadwal praktik",
        "description": "Parsial. `quota: 0` menghapus kuota; `valid_from`/`valid_until: \"\"` mengosongkan masa berlaku.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleInput"
              },
              "example": {
                "end_time": "13:00",
                "quota": 16
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Jadwal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/Stale"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "operationId": "deactivateSchedule",
        "tags": [
          "Booking"
        ],
        "summary": "Nonaktifkan jadwal praktik",
        "description": "Booking yang sudah ada tidak dibatalkan.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "responses": {
          "204": {
            "description": "Jadwal nonaktif"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/exceptions": {
      "get": {
        "operationId": "listScheduleExceptions",
        "tags": [
          "Booking"
        ],
        "summary": "Cuti dokter dan libur cabang",
        "security": [
          {
            "oauth2": [
              "appointments:read"
            ]
          },
          {
            "oauth2": [
              "appointments:write"
            ]
          },
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage",
          "appointment.read",
          "encounter.read",
          "queue.manage"
        ],
        "x-medivana-module": "booking",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "practitioner_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pengecualian jadwal",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ScheduleException"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a201",
                      "branch_id": null,
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "date_from": "2026-11-10",
                      "date_to": "2026-11-12",
                      "start_time": null,
                      "end_time": null,
                      "kind": "leave",
                      "reason": "Seminar"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createScheduleException",
        "tags": [
          "Booking"
        ],
        "summary": "Catat cuti dokter atau libur cabang",
        "description": "Isi `practitioner_id` (cuti, `kind: leave`) atau `branch_id` saja (libur cabang, `kind: closed`). Jam opsional (sebagian hari). Booking aktif yang terdampak dikembalikan agar pasien dihubungi; tidak dibatalkan otomatis.",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "date_from",
                  "date_to",
                  "kind"
                ],
                "properties": {
                  "practitioner_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "branch_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "date_from": {
                    "type": "string",
                    "format": "date"
                  },
                  "date_to": {
                    "type": "string",
                    "format": "date"
                  },
                  "start_time": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "example": "13:00"
                  },
                  "end_time": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "leave",
                      "closed",
                      "other"
                    ]
                  },
                  "reason": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "example": {
                "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                "branch_id": null,
                "date_from": "2026-11-10",
                "date_to": "2026-11-12",
                "kind": "leave",
                "reason": "Seminar"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pengecualian dibuat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exception": {
                      "$ref": "#/components/schemas/ScheduleException"
                    },
                    "affected_appointments": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Appointment"
                      }
                    }
                  }
                },
                "example": {
                  "exception": {
                    "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a201",
                    "branch_id": null,
                    "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                    "date_from": "2026-11-10",
                    "date_to": "2026-11-12",
                    "start_time": null,
                    "end_time": null,
                    "kind": "leave",
                    "reason": "Seminar"
                  },
                  "affected_appointments": []
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/booking/exceptions/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "delete": {
        "operationId": "deleteScheduleException",
        "tags": [
          "Booking"
        ],
        "summary": "Hapus cuti/libur",
        "security": [
          {
            "oauth2": [
              "appointments:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "appointment.manage"
        ],
        "x-medivana-module": "booking",
        "responses": {
          "204": {
            "description": "Dihapus"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/invoices": {
      "get": {
        "operationId": "listInvoices",
        "tags": [
          "Tagihan"
        ],
        "summary": "Daftar tagihan pasien",
        "description": "Cabang aktif, terbaru dulu. Status: `draft → finalized → partially_paid → paid`, atau `void`. Item daftar tanpa `lines`, `discounts`, `payments`.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "encounter_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "payer_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Dipisah koma",
            "example": "finalized,partially_paid"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Tagihan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Invoice"
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b001",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "patient_name": "Pasien Contoh",
                      "patient_mrn": "RM-000123",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
                      "payer_name": "Pasien Umum",
                      "payer_kind": "umum",
                      "number": "INV-202610-00042",
                      "status": "paid",
                      "subtotal": 195000,
                      "discount": 0,
                      "total": 195000,
                      "patient_amount": 195000,
                      "payer_amount": 0,
                      "paid_amount": 195000,
                      "outstanding": 0,
                      "payer_outstanding": 0,
                      "finalized_at": "2026-10-29T11:02:00+07:00",
                      "paid_at": "2026-10-29T11:03:10+07:00",
                      "created_at": "2026-10-29T10:58:00+07:00",
                      "version": 3
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/invoices/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getInvoice",
        "tags": [
          "Tagihan"
        ],
        "summary": "Detail tagihan dengan baris, diskon, dan pembayaran",
        "description": "`outstanding` = sisa bagian pasien; `payer_outstanding` = sisa piutang penjamin. `coverage` baris: `payer`, `excluded`, `none`, `package`.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Tagihan",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/Invoice"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/invoices/{id}/receipt": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getInvoiceReceipt",
        "tags": [
          "Tagihan"
        ],
        "summary": "Kuitansi tagihan (HTML siap cetak)",
        "description": "Thermal 58/80 mm atau A5. Bahasa dari `lang`, lalu preferensi pasien, lalu default organisasi.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "58",
                "80",
                "a5"
              ],
              "default": "80"
            }
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Dokumen HTML",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/payments": {
      "get": {
        "operationId": "listPayments",
        "tags": [
          "Tagihan"
        ],
        "summary": "Daftar pembayaran",
        "description": "Status: `pending`, `completed`, `refunded`, `expired`, `failed`. `unsettled=true` = pembayaran non-tunai yang belum cair ke bank.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "invoice_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "method",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Dipisah koma: cash, debit, credit, qris, transfer, deposit"
          },
          {
            "name": "unsettled",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pembayaran",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Payment"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b101",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "invoice_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "number": "PAY-202610-00003",
                      "method": "qris",
                      "amount": 195000,
                      "tendered": null,
                      "change_amount": 0,
                      "reference": null,
                      "status": "completed",
                      "paid_at": "2026-10-29T11:03:10+07:00",
                      "cash_session_id": null,
                      "gateway_provider": null,
                      "external_id": null,
                      "settlement_id": null,
                      "refunded_at": null,
                      "refund_reason": null,
                      "created_at": "2026-10-29T11:03:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/payments/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getPayment",
        "tags": [
          "Tagihan"
        ],
        "summary": "Detail pembayaran",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Pembayaran",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/charges": {
      "get": {
        "operationId": "listCharges",
        "tags": [
          "Tagihan"
        ],
        "summary": "Charge layanan dan barang pasien",
        "description": "Charge dibuat modul klinis (pendaftaran, tindakan, obat, penunjang) lalu ditagihkan kasir. Status `pending`, `billed`, `cancelled`.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "encounter_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "billed",
                "cancelled"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Charge",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Charge"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000009001",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "source_type": "encounter",
                      "source_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f002",
                      "item_id": null,
                      "description": "Konsultasi dokter umum",
                      "quantity": 1,
                      "unit_price": null,
                      "revenue_key": "rev_consultation",
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "status": "pending",
                      "invoice_id": null,
                      "created_at": "2026-10-29T10:45:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/deposits": {
      "get": {
        "operationId": "getPatientDeposits",
        "tags": [
          "Tagihan"
        ],
        "summary": "Saldo dan mutasi deposit pasien",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "name": "patient_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deposit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "patient_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "balance": {
                      "type": "number"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "number": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "topup",
                              "usage",
                              "refund",
                              "credit",
                              "usage_reversal"
                            ]
                          },
                          "amount": {
                            "type": "number",
                            "description": "Positif masuk, negatif keluar"
                          },
                          "balance_after": {
                            "type": "number"
                          },
                          "method": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "invoice_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "payment_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "reference": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "notes": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "balance": 300000,
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b201",
                      "number": "DEP-202610-00007",
                      "kind": "topup",
                      "amount": 500000,
                      "balance_after": 500000,
                      "method": "transfer",
                      "invoice_id": null,
                      "payment_id": null,
                      "reference": "TRF-0001",
                      "notes": null,
                      "created_at": "2026-10-20T09:00:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/packages": {
      "get": {
        "operationId": "listPackages",
        "tags": [
          "Tagihan"
        ],
        "summary": "Paket prabayar yang dijual klinik",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Paket",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "service_ids": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "format": "uuid"
                            }
                          },
                          "sessions": {
                            "type": "integer"
                          },
                          "price": {
                            "type": "number"
                          },
                          "valid_days": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "is_active": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b301",
                      "code": "PKT-FISIO-8",
                      "name": "Paket Fisioterapi 8 Sesi",
                      "description": null,
                      "service_ids": [
                        "3f0c2a10-5b7e-4c1d-9a2e-00000001f003"
                      ],
                      "sessions": 8,
                      "price": 1000000,
                      "valid_days": 180,
                      "is_active": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/patient-packages": {
      "get": {
        "operationId": "listPatientPackages",
        "tags": [
          "Tagihan"
        ],
        "summary": "Paket prabayar milik pasien",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "used",
                "expired",
                "void"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paket pasien",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "branch_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "package_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "package_name": {
                            "type": "string"
                          },
                          "number": {
                            "type": "string"
                          },
                          "service_ids": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "format": "uuid"
                            }
                          },
                          "sessions_total": {
                            "type": "integer"
                          },
                          "sessions_used": {
                            "type": "integer"
                          },
                          "price": {
                            "type": "number"
                          },
                          "remaining_value": {
                            "type": "number"
                          },
                          "payment_methods": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "status": {
                            "type": "string"
                          },
                          "sold_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "expires_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b401",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "package_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b301",
                      "package_name": "Paket Fisioterapi 8 Sesi",
                      "number": "PKG-202610-00002",
                      "service_ids": [
                        "3f0c2a10-5b7e-4c1d-9a2e-00000001f003"
                      ],
                      "sessions_total": 8,
                      "sessions_used": 2,
                      "price": 1000000,
                      "remaining_value": 750000,
                      "payment_methods": [
                        "transfer"
                      ],
                      "status": "active",
                      "sold_at": "2026-10-01T10:00:00+07:00",
                      "expires_at": "2027-03-30T23:59:59+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/services": {
      "get": {
        "operationId": "listServices",
        "tags": [
          "Tagihan"
        ],
        "summary": "Master layanan dan tarif dasar",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "konsultasi",
                "tindakan",
                "laboratorium",
                "radiologi",
                "paket",
                "administrasi",
                "telekonsultasi",
                "treatment",
                "lainnya"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Layanan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Service"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f002",
                      "code": "KONS-UMUM",
                      "name": "Konsultasi dokter umum",
                      "category": "konsultasi",
                      "revenue_key": "rev_consultation",
                      "base_price": 50000,
                      "icd9cm_code": null,
                      "loinc_code": null,
                      "specialty": "umum",
                      "fee_eligible": true,
                      "is_active": true,
                      "version": 1
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/payers": {
      "get": {
        "operationId": "listPayers",
        "tags": [
          "Tagihan"
        ],
        "summary": "Penjamin dan aturan tanggungan",
        "description": "`coverage_bp` = porsi ditanggung (basis poin, 10000 = 100%); `max_per_invoice` = plafon per tagihan; `excluded_categories` = kategori yang ditanggung pasien.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Penjamin",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Payer"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0003",
                      "code": "ASR1",
                      "name": "Asuransi Contoh",
                      "kind": "insurance",
                      "payment_terms_days": 30,
                      "coverage_bp": 8000,
                      "max_per_invoice": 300000,
                      "excluded_categories": [
                        "retail",
                        "treatment"
                      ],
                      "is_active": true,
                      "version": 1
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/price-lists": {
      "get": {
        "operationId": "listPriceLists",
        "tags": [
          "Tagihan"
        ],
        "summary": "Daftar tarif per penjamin",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Daftar tarif",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "payer_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "branch_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "valid_from": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          },
                          "valid_to": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          },
                          "is_active": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b501",
                      "code": "UMUM",
                      "name": "Tarif Umum",
                      "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
                      "branch_id": null,
                      "valid_from": null,
                      "valid_to": null,
                      "is_active": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/price-lists/{id}/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listPriceListItems",
        "tags": [
          "Tagihan"
        ],
        "summary": "Harga dalam satu daftar tarif",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Harga",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "service_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "item_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "price": {
                            "type": "number"
                          },
                          "base_price": {
                            "type": "number"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f002",
                      "item_id": null,
                      "code": "KONS-UMUM",
                      "name": "Konsultasi dokter umum",
                      "price": 60000,
                      "base_price": 50000
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/prices/resolve": {
      "get": {
        "operationId": "resolvePrice",
        "tags": [
          "Tagihan"
        ],
        "summary": "Harga efektif layanan/barang untuk penjamin",
        "description": "Urutan: daftar tarif penjamin cabang → penjamin semua cabang → tarif default cabang → semua cabang → harga dasar.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "payer_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "service_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "item_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Harga",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "price": {
                      "type": "number"
                    },
                    "source": {
                      "type": "string",
                      "description": "`price_list:<kode>`, `base_price`, atau `sale_price`"
                    },
                    "payer_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    }
                  }
                },
                "example": {
                  "price": 45000,
                  "source": "price_list:ASR1",
                  "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0003"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/settings": {
      "get": {
        "operationId": "getBillingSettings",
        "tags": [
          "Tagihan"
        ],
        "summary": "Pengaturan kasir (PPN, persetujuan diskon)",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Pengaturan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "is_pkp": {
                      "type": "boolean"
                    },
                    "ppn_rate_bp": {
                      "type": "integer"
                    },
                    "discount_approval_bp": {
                      "type": "integer"
                    },
                    "discount_approval_amount": {
                      "type": "number"
                    },
                    "require_cash_session": {
                      "type": "boolean"
                    },
                    "receipt_footer": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "version": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "is_pkp": false,
                  "ppn_rate_bp": 1100,
                  "discount_approval_bp": 1000,
                  "discount_approval_amount": 100000,
                  "require_cash_session": true,
                  "receipt_footer": "Semoga lekas sembuh",
                  "version": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/cash-sessions": {
      "get": {
        "operationId": "listCashSessions",
        "tags": [
          "Tagihan"
        ],
        "summary": "Sesi kas kasir",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "closed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sesi kas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CashSession"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b601",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "user_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d2001",
                      "user_name": "Kasir Contoh",
                      "number": "KAS-202610-00001",
                      "status": "closed",
                      "opened_at": "2026-10-29T07:30:00+07:00",
                      "opening_float": 200000,
                      "cash_in": 100000,
                      "cash_out": 0,
                      "expected_cash": 300000,
                      "closed_at": "2026-10-29T16:00:00+07:00",
                      "counted_cash": 299000,
                      "difference": -1000,
                      "notes": null,
                      "version": 2
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/cash-sessions/current": {
      "get": {
        "operationId": "getCurrentCashSession",
        "tags": [
          "Tagihan"
        ],
        "summary": "Sesi kas terbuka milik pemanggil",
        "description": "Sesi kas dibuka per pengguna kasir. Identitas klien API tidak pernah membuka sesi kas, jadi untuk token API endpoint ini selalu `404`; gunakan `GET /billing/cash-sessions?status=open`.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "responses": {
          "200": {
            "description": "Sesi kas terbuka",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CashSession"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/settlements": {
      "get": {
        "operationId": "listSettlements",
        "tags": [
          "Tagihan"
        ],
        "summary": "Pencairan QRIS/kartu/gateway ke bank",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Settlement",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "branch_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "number": {
                            "type": "string"
                          },
                          "channel": {
                            "type": "string"
                          },
                          "gross": {
                            "type": "number"
                          },
                          "mdr": {
                            "type": "number"
                          },
                          "net": {
                            "type": "number"
                          },
                          "settled_at": {
                            "type": "string",
                            "format": "date"
                          },
                          "reference": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b701",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "number": "STL-202610-00004",
                      "channel": "gateway",
                      "gross": 1250000,
                      "mdr": 8750,
                      "net": 1241250,
                      "settled_at": "2026-10-30",
                      "reference": "SETTLEMENT-CONTOH-01",
                      "created_at": "2026-10-30T08:00:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/billing/reports/ar-aging": {
      "get": {
        "operationId": "getReceivablesAging",
        "tags": [
          "Tagihan"
        ],
        "summary": "Umur piutang pasien",
        "description": "Per pasien, umur dihitung sejak tagihan final.",
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "cashier.bill",
          "cashier.close",
          "cashier.pay",
          "cashier.void",
          "invoice.read"
        ],
        "x-medivana-module": "cashier",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "as_of",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Default hari ini"
          }
        ],
        "responses": {
          "200": {
            "description": "Aging",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "as_of": {
                      "type": "string",
                      "format": "date"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "patient_name": {
                            "type": "string"
                          },
                          "patient_mrn": {
                            "type": "string"
                          },
                          "invoices": {
                            "type": "integer"
                          },
                          "days_0_30": {
                            "type": "number"
                          },
                          "days_31_60": {
                            "type": "number"
                          },
                          "days_61_90": {
                            "type": "number"
                          },
                          "days_over_90": {
                            "type": "number"
                          },
                          "total": {
                            "type": "number"
                          }
                        }
                      }
                    },
                    "totals": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "number"
                      }
                    }
                  }
                },
                "example": {
                  "as_of": "2026-10-31",
                  "items": [
                    {
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "patient_name": "Pasien Contoh",
                      "patient_mrn": "RM-000123",
                      "invoices": 1,
                      "days_0_30": 45000,
                      "days_31_60": 0,
                      "days_61_90": 0,
                      "days_over_90": 0,
                      "total": 45000
                    }
                  ],
                  "totals": {
                    "days_0_30": 45000,
                    "days_31_60": 0,
                    "days_61_90": 0,
                    "days_over_90": 0,
                    "total": 45000
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/lab/orders": {
      "get": {
        "operationId": "listLabOrders",
        "tags": [
          "Penunjang"
        ],
        "summary": "Worklist order laboratorium",
        "description": "Cabang aktif kecuali `all_branches=true`. Status `ordered → in_progress → final`, atau `cancelled`. Order yang dibuat bersamaan berbagi `request_id`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "lab.order",
          "lab.result"
        ],
        "x-medivana-module": "lab",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Dipisah koma",
            "example": "ordered,in_progress"
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "encounter_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "request_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "all_branches",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DiagnosticOrder"
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/lab/orders/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getLabOrder",
        "tags": [
          "Penunjang"
        ],
        "summary": "Detail order lab dan hasil per parameter",
        "description": "`results` selalu memuat semua parameter pemeriksaan (yang belum diisi bernilai null). Flag otomatis: `N`, `L`/`H`, `LL`/`HH` (kritis), `A` (kualitatif abnormal). Hasil dari alat (`source: lis`) tetap divalidasi analis sebelum final. Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "lab.order",
          "lab.result"
        ],
        "x-medivana-module": "lab",
        "responses": {
          "200": {
            "description": "Order",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiagnosticOrder"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/LabOrder"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/lab/orders/{id}/print": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "printLabOrder",
        "tags": [
          "Penunjang"
        ],
        "summary": "Lembar hasil lab satu order (HTML A4)",
        "description": "Ditandai \"HASIL SEMENTARA — BELUM FINAL\" bila order belum final.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "lab.order",
          "lab.result"
        ],
        "x-medivana-module": "lab",
        "parameters": [
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Dokumen HTML",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/lab/requests/{request_id}/print": {
      "parameters": [
        {
          "name": "request_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "operationId": "printLabRequest",
        "tags": [
          "Penunjang"
        ],
        "summary": "Lembar hasil lab satu permintaan (semua order)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "lab.order",
          "lab.result"
        ],
        "x-medivana-module": "lab",
        "parameters": [
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Dokumen HTML",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/radiology/orders": {
      "get": {
        "operationId": "listRadiologyOrders",
        "tags": [
          "Penunjang"
        ],
        "summary": "Worklist order radiologi",
        "description": "Filter sama dengan worklist lab.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "radiology.order",
          "radiology.result"
        ],
        "x-medivana-module": "radiology",
        "parameters": [
          {
            "$ref": "#/components/parameters/BranchHeader"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "encounter_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "request_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "all_branches",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DiagnosticOrder"
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/radiology/orders/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getRadiologyOrder",
        "tags": [
          "Penunjang"
        ],
        "summary": "Detail order radiologi, ekspertise, dan berkas citra",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "radiology.order",
          "radiology.result"
        ],
        "x-medivana-module": "radiology",
        "responses": {
          "200": {
            "description": "Order",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiagnosticOrder"
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c101",
                  "request_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c1a0",
                  "number": "RAD-20261029-0001",
                  "kind": "radiology",
                  "status": "final",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "service_name": "Rontgen thorax PA",
                  "report": {
                    "technique": "Thorax PA",
                    "findings": "Cor dan pulmo dalam batas normal",
                    "impression": "Tidak tampak kelainan",
                    "reporter_name": "dr. Radiolog Contoh",
                    "reported_at": "2026-10-29T13:00:00+07:00",
                    "version": 1
                  },
                  "files": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c1f1",
                      "filename": "thorax.dcm",
                      "content_type": "application/dicom",
                      "size_bytes": 5242880,
                      "category": "imaging",
                      "created_at": "2026-10-29T12:40:00+07:00"
                    }
                  ],
                  "finalized_at": "2026-10-29T13:05:00+07:00",
                  "version": 4
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/radiology/orders/{id}/files/{file_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        },
        {
          "name": "file_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "operationId": "downloadRadiologyFile",
        "tags": [
          "Penunjang"
        ],
        "summary": "Unduh berkas citra/dokumen radiologi",
        "description": "DICOM, PDF, atau gambar sesuai `content_type` berkas. Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "radiology.order",
          "radiology.result"
        ],
        "x-medivana-module": "radiology",
        "responses": {
          "200": {
            "description": "Isi berkas",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/diagnostics/patients/{patient_id}/results": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listPatientDiagnosticResults",
        "tags": [
          "Penunjang"
        ],
        "summary": "Riwayat hasil lab dan radiologi pasien",
        "description": "Hasil final terbaru dulu; `include_pending=true` menyertakan order yang belum final (kecuali batal). Butuh modul `lab` atau `radiology`. Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "lab.order",
          "lab.result",
          "radiology.order",
          "radiology.result"
        ],
        "x-medivana-module": "lab | radiology",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "lab",
                "radiology"
              ]
            }
          },
          {
            "name": "include_pending",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Order dengan hasil",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DiagnosticOrder"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/integrations/bpjs/peserta": {
      "get": {
        "operationId": "checkBPJSMembership",
        "tags": [
          "Integrasi"
        ],
        "summary": "Cek kepesertaan BPJS Kesehatan",
        "description": "Isi `noka` (13 digit) atau `nik` (16 digit). Timeout 5 detik; `502 bpjs-unavailable` bila BPJS tidak menjawab (lanjutkan pendaftaran, cek ulang nanti). `422` bila format salah atau kredensial BPJS klinik belum dikonfigurasi.",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "bpjs",
        "parameters": [
          {
            "name": "noka",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{13}$"
            }
          },
          {
            "name": "nik",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{16}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil pengecekan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "found": {
                      "type": "boolean"
                    },
                    "eligible": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "peserta": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": true
                    }
                  }
                },
                "example": {
                  "found": true,
                  "eligible": true,
                  "message": "Peserta BPJS aktif.",
                  "peserta": {
                    "no_kartu": "0000000000001",
                    "nama": "PASIEN CONTOH",
                    "aktif": true,
                    "ket_aktif": "AKTIF",
                    "jenis_peserta": "PBI (APBN)",
                    "kelas": "KELAS III",
                    "tgl_lahir": "12-05-1990",
                    "sex": "P",
                    "ppk_kode": "0000X001",
                    "ppk_nama": "KLINIK SEHAT CONTOH",
                    "terdaftar_di_faskes_ini": true,
                    "tunggakan": 0,
                    "tgl_akhir_berlaku": "01-01-2030",
                    "hubungan_keluarga": "PESERTA"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamUnavailable"
          }
        }
      }
    },
    "/integrations/bpjs/ref/diagnosa": {
      "get": {
        "operationId": "searchBPJSDiagnoses",
        "tags": [
          "Integrasi"
        ],
        "summary": "Referensi diagnosa PCare BPJS",
        "description": "Minimal 3 huruf. Data mentah dari BPJS.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read"
        ],
        "x-medivana-module": "bpjs",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 3
            },
            "example": "J06"
          }
        ],
        "responses": {
          "200": {
            "description": "Diagnosa",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "kdDiag": {
                            "type": "string"
                          },
                          "nmDiag": {
                            "type": "string"
                          },
                          "nonSpesialis": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "kdDiag": "J06.9",
                      "nmDiag": "Acute upper respiratory infection, unspecified",
                      "nonSpesialis": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamUnavailable"
          }
        }
      }
    },
    "/integrations/satusehat/patients/lookup": {
      "get": {
        "operationId": "lookupSatusehatPatient",
        "tags": [
          "Integrasi"
        ],
        "summary": "Lookup pasien SATUSEHAT berdasarkan NIK",
        "description": "Timeout 3 detik. Nama tersamar dari SATUSEHAT tidak dikembalikan sebagai `name`. `502 satusehat-unavailable` → lanjutkan dengan data lokal.",
        "security": [
          {
            "oauth2": [
              "patients:read"
            ]
          },
          {
            "oauth2": [
              "patients:write"
            ]
          }
        ],
        "x-medivana-permissions": [
          "patient.read"
        ],
        "x-medivana-module": "satusehat",
        "parameters": [
          {
            "name": "nik",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{16}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil lookup",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "found": {
                      "type": "boolean"
                    },
                    "patient": {
                      "$ref": "#/components/schemas/SatusehatPatient"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "found": {
                    "value": {
                      "found": true,
                      "patient": {
                        "ihs_number": "P00000000001",
                        "nik": "9999010101900001",
                        "name": "PASIEN CONTOH",
                        "birth_date": "1990-05-12T00:00:00Z",
                        "gender": "female",
                        "address": "Jl. Contoh No. 10"
                      }
                    }
                  },
                  "notFound": {
                    "value": {
                      "found": false,
                      "message": "NIK belum terdaftar di SATUSEHAT. Data pasien akan didaftarkan saat sinkron kunjungan."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamUnavailable"
          }
        }
      }
    },
    "/integrations/lis/orders/{id}/messages": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listLabOrderInstrumentMessages",
        "tags": [
          "Integrasi"
        ],
        "summary": "Status kiriman order lab ke alat (LIS)",
        "description": "Pesan order keluar dan pesan hasil yang menulis ke order ini, tanpa isi mentah. `status`: `queued`, `ready`, `sent`, `acked`, `rejected`, `failed`, `cancelled`. Butuh modul `lab` dan add-on `lis`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "lab.order",
          "lab.result"
        ],
        "x-medivana-module": "lab + lis",
        "responses": {
          "200": {
            "description": "Pesan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "direction": {
                            "type": "string",
                            "enum": [
                              "in",
                              "out"
                            ]
                          },
                          "status": {
                            "type": "string"
                          },
                          "control_id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "connection_name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c201",
                      "direction": "out",
                      "status": "acked",
                      "control_id": "ORM-0001",
                      "connection_name": "Analyzer Hematologi",
                      "created_at": "2026-10-29T09:20:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/telecon/sessions": {
      "get": {
        "operationId": "listTeleconSessions",
        "tags": [
          "Telekonsultasi"
        ],
        "summary": "Sesi telekonsultasi",
        "description": "Default hari ini; dengan `patient_id` semua tanggal. Tautan undangan pasien tidak pernah dikembalikan di sini.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "telecon.manage"
        ],
        "x-medivana-module": "telecon",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "practitioner_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "patient_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "in_progress",
                "completed",
                "cancelled"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sesi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TeleconSession"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e101",
                      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "patient_name": "Pasien Contoh",
                      "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                      "practitioner_name": "dr. Rina Contoh",
                      "encounter_id": null,
                      "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f004",
                      "service_name": "Telekonsultasi umum",
                      "scheduled_start": "2026-10-29T19:00:00+07:00",
                      "scheduled_end": "2026-10-29T19:20:00+07:00",
                      "duration_minutes": 20,
                      "status": "scheduled",
                      "payment_status": "paid",
                      "payment_settled": true,
                      "paid_at": "2026-10-29T15:00:00+07:00",
                      "payment_ref": null,
                      "charge_id": "3f0c2a10-5b7e-4c1d-9a2e-000000009101",
                      "consent_at": null,
                      "started_at": null,
                      "ended_at": null,
                      "cancel_reason": null,
                      "notes": null,
                      "version": 2
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/telecon/sessions/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getTeleconSession",
        "tags": [
          "Telekonsultasi"
        ],
        "summary": "Detail sesi telekonsultasi",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "telecon.manage"
        ],
        "x-medivana-module": "telecon",
        "responses": {
          "200": {
            "description": "Sesi",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TeleconSession"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/legend": {
      "get": {
        "operationId": "getDentalLegend",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: legenda kondisi odontogram dan permukaan",
        "description": "Kode kondisi: `sehat`, `karies`, `tambalan`, `sealant`, `fraktur`, `hilang`, `sisa_akar`, `mahkota`, `jembatan`, `impaksi`, `psa`, `belum_erupsi`, `gigi_tiruan`, `implan`, `persistensi`, `goyang`. Permukaan kanonik `M`, `O`, `D`, `B`, `L`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "responses": {
          "200": {
            "description": "Legenda",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "scope": {
                            "type": "string",
                            "enum": [
                              "surface",
                              "tooth",
                              "both"
                            ]
                          },
                          "color": {
                            "type": "string"
                          },
                          "symbol": {
                            "type": "string"
                          },
                          "materials": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "clears_surfaces": {
                            "type": "boolean"
                          },
                          "material_required": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "surfaces": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "code": "karies",
                      "label": "Karies",
                      "scope": "surface",
                      "color": "#D92D20",
                      "symbol": "●",
                      "clears_surfaces": false,
                      "material_required": false
                    }
                  ],
                  "surfaces": [
                    {
                      "code": "M",
                      "label": "Mesial"
                    },
                    {
                      "code": "O",
                      "label": "Oklusal / Insisal (I)"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/patients/{patient_id}/odontogram": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "getOdontogram",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: snapshot odontogram terkini (FDI)",
        "description": "Semua gigi dentisi diminta selalu dikembalikan (default `sehat`), ditambah gigi lain yang pernah dicatat. `dentition` default dari umur (< 6 th anak, 6–12 campuran).",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "parameters": [
          {
            "name": "dentition",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "permanent",
                "primary",
                "mixed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "patient_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "dentition": {
                      "type": "string"
                    },
                    "chart": {
                      "type": "string"
                    },
                    "entries_count": {
                      "type": "integer"
                    },
                    "updated_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "teeth": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                },
                "example": {
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "dentition": "permanent",
                  "chart": "dewasa",
                  "entries_count": 4,
                  "updated_at": "2026-10-29T09:12:00+07:00",
                  "teeth": [
                    {
                      "tooth": 36,
                      "dentition": "permanent",
                      "arch": "lower",
                      "position": "posterior",
                      "condition": "sehat",
                      "surfaces": {
                        "O": {
                          "label": "O",
                          "condition": "tambalan",
                          "material": "komposit"
                        }
                      },
                      "updated_at": "2026-10-29T09:12:00+07:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/patients/{patient_id}/odontogram/entries": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listOdontogramEntries",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: semua entri odontogram (terbaru dulu)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "parameters": [
          {
            "name": "encounter_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/patients/{patient_id}/odontogram/teeth/{tooth}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        },
        {
          "name": "tooth",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "description": "Nomor gigi FDI",
          "example": 36
        }
      ],
      "get": {
        "operationId": "getToothHistory",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: riwayat satu gigi",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyObject"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/patients/{patient_id}/plans": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listDentalPlans",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: rencana perawatan pasien (tanpa item)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/plans/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getDentalPlan",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: detail rencana perawatan (tahap dan item)",
        "description": "Status item `planned`, `in_progress`, `done`, `cancelled`; `progress` merangkum jumlah per status.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "responses": {
          "200": {
            "description": "Rencana perawatan",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000002001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "title": "Rencana perawatan 2026",
                  "status": "active",
                  "estimated_total": 600000,
                  "done_total": 0,
                  "progress": {
                    "total": 2,
                    "planned": 2,
                    "in_progress": 0,
                    "done": 0,
                    "cancelled": 0
                  },
                  "phases": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000002101",
                      "phase_no": 1,
                      "name": "Fase 1 — Kontrol infeksi",
                      "status": "planned",
                      "estimated_total": 250000,
                      "items": [
                        {
                          "id": "3f0c2a10-5b7e-4c1d-9a2e-000000002201",
                          "service_name": "Scaling",
                          "tooth": null,
                          "surfaces": [],
                          "quantity": 1,
                          "estimated_cost": 250000,
                          "status": "planned"
                        }
                      ]
                    }
                  ],
                  "version": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/patients/{patient_id}/photos": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listDentalPhotos",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: foto intraoral, ekstraoral, dan rontgen",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "responses": {
          "200": {
            "description": "Foto",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ClinicalPhoto"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000002301",
                      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                      "kind": "intraoral",
                      "tooth": 16,
                      "note": null,
                      "file_id": "3f0c2a10-5b7e-4c1d-9a2e-000000002311",
                      "filename": "intraoral.png",
                      "content_type": "image/png",
                      "size_bytes": 20311,
                      "taken_at": "2026-10-29T09:15:00+07:00",
                      "url": "/api/v1/dental/photos/3f0c2a10-5b7e-4c1d-9a2e-000000002301/file"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/dental/photos/{id}/file": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "downloadDentalPhoto",
        "tags": [
          "Spesialis"
        ],
        "summary": "Gigi: unduh berkas foto",
        "description": "Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.dental"
        ],
        "x-medivana-module": "dental",
        "responses": {
          "200": {
            "$ref": "#/components/responses/BinaryFile"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/beauty/patients/{patient_id}/records": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listBeautyRecords",
        "tags": [
          "Spesialis"
        ],
        "summary": "Kecantikan: riwayat treatment (maks 200)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.beauty"
        ],
        "x-medivana-module": "beauty",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/beauty/records/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getBeautyRecord",
        "tags": [
          "Spesialis"
        ],
        "summary": "Kecantikan: detail treatment dan produk",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.beauty"
        ],
        "x-medivana-module": "beauty",
        "responses": {
          "200": {
            "description": "Rekam treatment",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000002401",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "service_name": "Chemical peeling",
                  "procedure_name": "Chemical peeling",
                  "areas": [
                    "wajah"
                  ],
                  "parameters": {
                    "agent": "glycolic 30%",
                    "durasi_menit": 3
                  },
                  "notes": "Kulit kemerahan ringan",
                  "is_package": false,
                  "revenue_key": "rev_procedure",
                  "performed_at": "2026-10-29T10:00:00+07:00",
                  "status": "done",
                  "photo_count": 2,
                  "version": 1,
                  "products": [
                    {
                      "item_name": "Serum contoh",
                      "unit": "pcs",
                      "quantity": 1,
                      "billable": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/beauty/patients/{patient_id}/photos": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listBeautyPhotos",
        "tags": [
          "Spesialis"
        ],
        "summary": "Kecantikan: foto before/after/progress",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.beauty"
        ],
        "x-medivana-module": "beauty",
        "parameters": [
          {
            "name": "record_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Foto",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ClinicalPhoto"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/beauty/patients/{patient_id}/photo-consent": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "getBeautyPhotoConsent",
        "tags": [
          "Spesialis"
        ],
        "summary": "Kecantikan: status consent foto pasien",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.beauty"
        ],
        "x-medivana-module": "beauty",
        "responses": {
          "200": {
            "description": "Consent foto",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "patient_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "const": "photo"
                    },
                    "granted": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "kind": "photo",
                  "granted": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/beauty/photos/{id}/file": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "downloadBeautyPhoto",
        "tags": [
          "Spesialis"
        ],
        "summary": "Kecantikan: unduh berkas foto",
        "description": "Diaudit.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.beauty"
        ],
        "x-medivana-module": "beauty",
        "responses": {
          "200": {
            "$ref": "#/components/responses/BinaryFile"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/calc/pregnancy": {
      "get": {
        "operationId": "calcPregnancy",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: hitung HPL dan usia kehamilan",
        "description": "Isi `lmp` (HPHT, Naegele + 280 hari) atau `edd` (HPL). `date` default hari ini.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "parameters": [
          {
            "name": "lmp",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "edd",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "edd": "2026-10-08",
                  "date": "2026-04-01",
                  "gestational_age": {
                    "weeks": 12,
                    "days": 6,
                    "total_days": 90,
                    "trimester": 1
                  },
                  "label": "12 minggu 6 hari"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/kspr-factors": {
      "get": {
        "operationId": "listKSPRFactors",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: faktor Kartu Skor Poedji Rochjati",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/patients/{patient_id}/pregnancies": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listPregnancies",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: daftar kehamilan pasien",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/pregnancies/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getPregnancy",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: detail kehamilan, kunjungan ANC, dan persalinan",
        "description": "KSPR: `KRR` (2), `KRT` (6–10), `KRST` (≥ 12).",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "responses": {
          "200": {
            "description": "Kehamilan",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000003001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "gravida": 2,
                  "para": 1,
                  "abortus": 0,
                  "living_children": 1,
                  "lmp": "2026-03-01",
                  "edd": "2026-12-06",
                  "edd_source": "hpht",
                  "status": "active",
                  "gestational_age": {
                    "weeks": 34,
                    "days": 3,
                    "total_days": 241,
                    "trimester": 3
                  },
                  "kspr_score": 10,
                  "risk_category": "KRT",
                  "visits": [],
                  "delivery": null,
                  "version": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/patients/{patient_id}/family-planning": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listFamilyPlanningVisits",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: kunjungan KB dan jadwal kunjungan ulang",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "responses": {
          "200": {
            "description": "Kunjungan KB",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "next_visit_date": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date"
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "visit_date": "2026-10-29",
                      "method": "suntik_3_bulan",
                      "method_label": "Suntik 3 bulan",
                      "is_new_acceptor": false,
                      "next_visit_date": "2027-01-21"
                    }
                  ],
                  "next_visit_date": "2027-01-21"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/immunization-schedule": {
      "get": {
        "operationId": "getImmunizationSchedule",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: jadwal imunisasi rutin nasional",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "responses": {
          "200": {
            "description": "Jadwal",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "source": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "vaccine_code": "HB0",
                      "vaccine_name": "Hepatitis B (HB0)",
                      "dose_no": 1,
                      "label": "HB0",
                      "age_days": 0,
                      "age_label": "0–24 jam",
                      "min_interval_days": 0,
                      "max_age_days": 7,
                      "grace_days": 1,
                      "group": "bayi"
                    }
                  ],
                  "source": "Program Imunisasi Nasional Kemenkes RI (imunisasi rutin lengkap)"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/patients/{patient_id}/immunizations": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listPatientImmunizations",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: riwayat imunisasi dan jadwal jatuh tempo",
        "description": "Status jadwal: `given`, `due`, `overdue`, `upcoming`, `missed`. Tanpa tanggal lahir: `schedule` kosong + `note`.",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "responses": {
          "200": {
            "description": "Imunisasi",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0003",
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-000000003101",
                      "vaccine_code": "HB0",
                      "dose_no": 1,
                      "given_at": "2026-01-10T08:00:00+07:00",
                      "status": "completed"
                    }
                  ],
                  "schedule": [
                    {
                      "vaccine_code": "BCG",
                      "dose_no": 1,
                      "label": "BCG",
                      "due_date": "2026-02-09",
                      "status": "overdue",
                      "status_label": "Terlambat"
                    }
                  ],
                  "summary": {
                    "given": 1,
                    "overdue": 1,
                    "due": 0,
                    "upcoming": 20
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/patients/{patient_id}/growth": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listGrowthMeasurements",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: pengukuran pertumbuhan anak (z-score WHO)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/patients/{patient_id}/growth/chart": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "getGrowthChart",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: data grafik pertumbuhan (kurva acuan + titik)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "parameters": [
          {
            "name": "indicator",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "wfa",
                "lhfa"
              ],
              "default": "wfa"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyObject"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/kia/growth/zscore": {
      "get": {
        "operationId": "calcGrowthZScore",
        "tags": [
          "Spesialis"
        ],
        "summary": "KIA: kalkulator z-score WHO",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.kia"
        ],
        "x-medivana-module": "kia",
        "parameters": [
          {
            "name": "sex",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "male",
                "female"
              ]
            }
          },
          {
            "name": "age_days",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "weight_kg",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "length_cm",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "position",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "recumbent",
                "standing"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Z-score",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "sex": "female",
                  "age_days": 365,
                  "age_months": 12,
                  "wfa_z": 0.02,
                  "wfa_status": {
                    "code": "normal",
                    "label": "Normal"
                  },
                  "lhfa_z": -0.04,
                  "lhfa_status": {
                    "code": "normal",
                    "label": "Normal"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/physio/patients/{patient_id}/assessments": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listPhysioAssessments",
        "tags": [
          "Spesialis"
        ],
        "summary": "Fisioterapi: daftar asesmen",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.physio"
        ],
        "x-medivana-module": "physio",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/physio/assessments/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getPhysioAssessment",
        "tags": [
          "Spesialis"
        ],
        "summary": "Fisioterapi: detail asesmen (VAS, ROM, MMT, skor fungsional)",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.physio"
        ],
        "x-medivana-module": "physio",
        "responses": {
          "200": {
            "description": "Asesmen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000003501",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "chief_complaint": "Nyeri punggung bawah",
                  "diagnosis": "LBP mekanik",
                  "pain_vas": 7,
                  "rom": [
                    {
                      "joint": "lumbal",
                      "movement": "fleksi",
                      "side": "bilateral",
                      "active_deg": 40,
                      "passive_deg": 50,
                      "normal_deg": 60
                    }
                  ],
                  "mmt": [],
                  "functional_scores": [
                    {
                      "instrument": "ODI",
                      "score": 42,
                      "max_score": 100
                    }
                  ],
                  "assessed_at": "2026-10-29T10:00:00+07:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/physio/patients/{patient_id}/programs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PatientID"
        }
      ],
      "get": {
        "operationId": "listPhysioPrograms",
        "tags": [
          "Spesialis"
        ],
        "summary": "Fisioterapi: daftar program terapi",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.physio"
        ],
        "x-medivana-module": "physio",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SpecialtyList"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/physio/programs/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "getPhysioProgram",
        "tags": [
          "Spesialis"
        ],
        "summary": "Fisioterapi: detail program, sesi, dan evaluasi",
        "security": [
          {
            "oauth2": [
              "encounters:read"
            ]
          }
        ],
        "x-medivana-permissions": [
          "encounter.read",
          "specialty.physio"
        ],
        "x-medivana-module": "physio",
        "responses": {
          "200": {
            "description": "Program",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000003601",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "goals": [
                    "Nyeri VAS < 3"
                  ],
                  "modalities": [
                    "TENS"
                  ],
                  "frequency_per_week": 2,
                  "planned_sessions": 8,
                  "completed_sessions": 1,
                  "remaining_sessions": 7,
                  "status": "active",
                  "sessions": [
                    {
                      "session_no": 1,
                      "pain_vas_before": 6,
                      "pain_vas_after": 4,
                      "status": "done"
                    }
                  ],
                  "evaluations": [],
                  "version": 2
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "operationId": "listWebhookSubscriptions",
        "tags": [
          "Webhook"
        ],
        "summary": "Daftar langganan webhook organisasi",
        "description": "Semua langganan organisasi (termasuk yang dibuat admin di aplikasi atau klien API lain). `secret` tidak pernah dikembalikan di sini.",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "responses": {
          "200": {
            "description": "Langganan (terbaru dulu)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookSubscription"
                      }
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001d001",
                      "url": "https://his.contoh.test/medivana/webhook",
                      "events": [
                        "patient.created",
                        "encounter.closed",
                        "invoice.paid"
                      ],
                      "description": "Sinkron HIS",
                      "is_active": true,
                      "failure_count": 0,
                      "disabled_reason": null,
                      "created_at": "2026-10-29T08:00:00+07:00",
                      "version": 1
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createWebhookSubscription",
        "tags": [
          "Webhook"
        ],
        "summary": "Buat langganan webhook",
        "description": "`url` wajib `https` dan tidak boleh mengarah ke jaringan internal/privat. `events` berisi nama event dari\n`GET /webhooks/events` atau `\"*\"` untuk semua event. `secret` (`whsec_…`) hanya dikembalikan sekali di respons ini;\nsimpan di brankas rahasia untuk memverifikasi `X-Medivana-Signature`.\n",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/EventName"
                    }
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "example": {
                "url": "https://his.contoh.test/medivana/webhook",
                "events": [
                  "patient.created",
                  "encounter.closed",
                  "invoice.paid"
                ],
                "description": "Sinkron HIS"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Langganan dibuat (dengan secret sekali tampil)",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/WebhookSubscription"
                    },
                    {
                      "type": "object",
                      "required": [
                        "secret"
                      ],
                      "properties": {
                        "secret": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001d001",
                  "url": "https://his.contoh.test/medivana/webhook",
                  "events": [
                    "patient.created",
                    "encounter.closed",
                    "invoice.paid"
                  ],
                  "description": "Sinkron HIS",
                  "is_active": true,
                  "failure_count": 0,
                  "disabled_reason": null,
                  "created_at": "2026-10-29T08:00:00+07:00",
                  "version": 1,
                  "secret": "whsec_contohRahasiaJanganDipakai"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/webhooks/events": {
      "get": {
        "operationId": "listWebhookEvents",
        "tags": [
          "Webhook"
        ],
        "summary": "Katalog event dan format tanda tangan",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "responses": {
          "200": {
            "description": "Katalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EventName"
                      }
                    },
                    "signature_header": {
                      "type": "string",
                      "const": "X-Medivana-Signature"
                    },
                    "signature_format": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "items": [
                    "patient.created",
                    "patient.updated",
                    "encounter.closed"
                  ],
                  "signature_header": "X-Medivana-Signature",
                  "signature_format": "t=<unix>,v1=<hex(HMAC-SHA256(secret, t + \".\" + body))>"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/webhooks/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "patch": {
        "operationId": "updateWebhookSubscription",
        "tags": [
          "Webhook"
        ],
        "summary": "Ubah langganan webhook",
        "description": "`is_active: true` mengaktifkan kembali langganan yang dinonaktifkan (mis. setelah `410 Gone`) dan mereset hitungan kegagalan.",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EventName"
                    }
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "is_active": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "events": [
                  "*"
                ],
                "is_active": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Langganan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "412": {
            "$ref": "#/components/responses/Stale"
          },
          "422": {
            "$ref": "#/components/responses/Validation"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhookSubscription",
        "tags": [
          "Webhook"
        ],
        "summary": "Hapus langganan webhook",
        "description": "Pengiriman yang masih antre untuk langganan ini dilewati.",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "responses": {
          "204": {
            "description": "Dihapus"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "rotateWebhookSecret",
        "tags": [
          "Webhook"
        ],
        "summary": "Rotasi secret HMAC",
        "description": "Secret lama langsung tidak berlaku; pengiriman berikutnya ditandatangani secret baru. Perbarui verifikasi di penerima sebelum atau segera setelah rotasi.",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "responses": {
          "200": {
            "description": "Langganan dengan secret baru (sekali tampil)",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/WebhookSubscription"
                    },
                    {
                      "type": "object",
                      "required": [
                        "secret"
                      ],
                      "properties": {
                        "secret": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/webhooks/{id}/test": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "sendWebhookTest",
        "tags": [
          "Webhook"
        ],
        "summary": "Kirim event uji `ping`",
        "description": "Mengantrekan event `ping` ke URL langganan (lihat riwayat pengiriman untuk hasilnya).",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "responses": {
          "202": {
            "description": "Diantrekan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Queued"
                },
                "example": {
                  "status": "queued"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/webhooks/{id}/deliveries": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "get": {
        "operationId": "listWebhookDeliveries",
        "tags": [
          "Webhook"
        ],
        "summary": "Riwayat pengiriman webhook",
        "description": "Terbaru dulu. `pending` (antre), `delivered` (2xx), `failed` (akan dicoba ulang), `dead` (percobaan habis atau 410).",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivered",
                "failed",
                "dead"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengiriman",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001d101",
                      "subscription_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001d001",
                      "event": "patient.created",
                      "event_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                      "entity_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                      "status": "delivered",
                      "attempts": 1,
                      "last_status_code": 200,
                      "last_error": null,
                      "delivered_at": "2026-10-29T08:15:03+07:00",
                      "created_at": "2026-10-29T08:15:02+07:00",
                      "payload": {
                        "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                        "type": "patient.created",
                        "created_at": "2026-10-29T01:15:02Z",
                        "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                        "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                        "data": {
                          "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                          "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/webhooks/deliveries/{id}/redeliver": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ID"
        }
      ],
      "post": {
        "operationId": "redeliverWebhook",
        "tags": [
          "Webhook"
        ],
        "summary": "Kirim ulang satu pengiriman",
        "description": "Payload dan `X-Medivana-Event-ID` sama dengan pengiriman asli (deduplikasi di penerima tetap berlaku); tanda tangan dihitung ulang dengan waktu dan secret saat ini.",
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "x-medivana-permissions": [
          "api_client.manage",
          "webhook.manage"
        ],
        "x-medivana-module": "api",
        "responses": {
          "202": {
            "description": "Diantrekan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Queued"
                },
                "example": {
                  "status": "queued"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ModuleLocked"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "webhooks": {
    "ping": {
      "post": {
        "operationId": "onPing",
        "summary": "Uji koneksi",
        "description": "Dikirim oleh `POST /webhooks/{id}/test`. Data entitas: `data.id` = ID langganan (subscription_id).",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "ping"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID langganan (subscription_id)"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "ping",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001d001",
                  "message": "Tes webhook Medivana"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "patient.created": {
      "post": {
        "operationId": "onPatientCreated",
        "summary": "Pasien baru terdaftar",
        "description": "Setelah `POST /patients` atau pendaftaran di aplikasi. Data entitas: `data.id` = patient_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "patient.created"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "patient_id"
                          },
                          "branch_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "patient.created",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "patient.updated": {
      "post": {
        "operationId": "onPatientUpdated",
        "summary": "Data pasien berubah",
        "description": "Identitas atau kontak pasien diubah. Data entitas: `data.id` = patient_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "patient.updated"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "patient_id"
                          },
                          "branch_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "patient.updated",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "patient.merged": {
      "post": {
        "operationId": "onPatientMerged",
        "summary": "Pasien ganda digabung",
        "description": "`data.id` = pasien yang dipertahankan; `merged_from` = pasien sumber yang kini nonaktif (`merged_into`). Pindahkan referensi di sistem Anda. Data entitas: `data.id` = patient_id (tujuan).",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "patient.merged"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "patient_id (tujuan)"
                          },
                          "merged_from": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "branch_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "patient.merged",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "merged_from": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0002",
                  "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "encounter.started": {
      "post": {
        "operationId": "onEncounterStarted",
        "summary": "Kunjungan terdaftar",
        "description": "Saat pendaftaran kunjungan (termasuk check-in booking). `appointment_id` bernilai UUID nol bila bukan dari booking. Data entitas: `data.id` = encounter_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "encounter.started"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "encounter_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "unit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "practitioner_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "payer_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "payer_kind": {
                            "type": "string"
                          },
                          "appointment_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "queue_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "encounter.started",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                  "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                  "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
                  "payer_kind": "umum",
                  "appointment_id": null,
                  "queue_id": "3f0c2a10-5b7e-4c1d-9a2e-000000005001"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "encounter.closed": {
      "post": {
        "operationId": "onEncounterClosed",
        "summary": "Kunjungan ditutup dan ditandatangani",
        "description": "Rekam medis kunjungan final (tanda tangan elektronik). Ambil isi lengkap lewat `GET /encounters/{id}`. Data entitas: `data.id` = encounter_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "encounter.closed"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "encounter_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "practitioner_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "payer_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "payer_kind": {
                            "type": "string"
                          },
                          "unit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "appointment_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "signature_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "encounter.closed",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                  "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
                  "payer_kind": "umum",
                  "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                  "appointment_id": "00000000-0000-0000-0000-000000000000",
                  "signature_id": "3f0c2a10-5b7e-4c1d-9a2e-000000006301"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "encounter.cancelled": {
      "post": {
        "operationId": "onEncounterCancelled",
        "summary": "Kunjungan dibatalkan",
        "description": "Data entitas: `data.id` = encounter_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "encounter.cancelled"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "encounter_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reason": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "encounter.cancelled",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "reason": "Pasien pulang sebelum diperiksa"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "allergy.recorded": {
      "post": {
        "operationId": "onAllergyRecorded",
        "summary": "Alergi dicatat",
        "description": "Data entitas: `data.id` = allergy_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "allergy.recorded"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "allergy_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "obat",
                              "makanan",
                              "lingkungan"
                            ]
                          },
                          "severity": {
                            "type": "string",
                            "enum": [
                              "ringan",
                              "sedang",
                              "berat"
                            ]
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "allergy.recorded",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a8001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "category": "obat",
                  "severity": "berat"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "queue.called": {
      "post": {
        "operationId": "onQueueCalled",
        "summary": "Nomor antrean dipanggil",
        "description": "Termasuk panggil ulang (`call_count` bertambah). Data entitas: `data.id` = queue_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "queue.called"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "queue_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "unit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "number": {
                            "type": "integer"
                          },
                          "label": {
                            "type": "string"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "call_count": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "queue.called",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000005001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                  "number": 3,
                  "label": "U-003",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "call_count": 1
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "prescription.created": {
      "post": {
        "operationId": "onPrescriptionCreated",
        "summary": "Resep dibuat",
        "description": "Modul farmasi. Data entitas: `data.id` = prescription_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "prescription.created"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "prescription_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "prescription.created",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "dispense.completed": {
      "post": {
        "operationId": "onDispenseCompleted",
        "summary": "Obat diserahkan",
        "description": "Modul farmasi. Data entitas: `data.id` = dispense_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "dispense.completed"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "dispense_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "prescription_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "dispense.completed",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001101",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "prescription_id": "3f0c2a10-5b7e-4c1d-9a2e-000000001001"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "dispense.returned": {
      "post": {
        "operationId": "onDispenseReturned",
        "summary": "Obat diretur",
        "description": "`billed_charges` = jumlah charge retur yang sudah ditagih (memicu nota kredit). Data entitas: `data.id` = dispense_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "dispense.returned"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "dispense_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "return_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reason": {
                            "type": "string"
                          },
                          "billed_charges": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "dispense.returned",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001101",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "return_id": "3f0c2a10-5b7e-4c1d-9a2e-000000001201",
                  "reason": "Pasien alergi",
                  "billed_charges": 0
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "lab.order_created": {
      "post": {
        "operationId": "onLabOrderCreated",
        "summary": "Order laboratorium dibuat",
        "description": "Satu event per pemeriksaan; order sekali kirim berbagi `request_id`. Data entitas: `data.id` = order_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "lab.order_created"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "order_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "service_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "request_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "priority": {
                            "type": "string",
                            "enum": [
                              "routine",
                              "cito"
                            ]
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "lab.order_created",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f001",
                  "request_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c0a0",
                  "priority": "cito"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "radiology.order_created": {
      "post": {
        "operationId": "onRadiologyOrderCreated",
        "summary": "Order radiologi dibuat",
        "description": "Data entitas: `data.id` = order_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "radiology.order_created"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "order_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "service_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "request_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "priority": {
                            "type": "string",
                            "enum": [
                              "routine",
                              "cito"
                            ]
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "radiology.order_created",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c101",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f001",
                  "request_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c0a0",
                  "priority": "routine"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "lab.result_final": {
      "post": {
        "operationId": "onLabResultFinal",
        "summary": "Hasil laboratorium final",
        "description": "`critical: true` bila ada nilai kritis. Ambil hasil lewat `GET /lab/orders/{id}`. Data entitas: `data.id` = order_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "lab.result_final"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "order_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "request_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "service_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "critical": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "lab.result_final",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "request_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c0a0",
                  "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f001",
                  "critical": true
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "radiology.result_final": {
      "post": {
        "operationId": "onRadiologyResultFinal",
        "summary": "Ekspertise radiologi final",
        "description": "Ambil ekspertise dan berkas lewat `GET /radiology/orders/{id}`. Data entitas: `data.id` = order_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "radiology.result_final"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "order_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "request_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "service_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "critical": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "radiology.result_final",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c101",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "request_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c0a0",
                  "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f001",
                  "critical": false
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "immunization.recorded": {
      "post": {
        "operationId": "onImmunizationRecorded",
        "summary": "Imunisasi dicatat",
        "description": "Modul KIA. `encounter_id` null bila dicatat tanpa kunjungan. Data entitas: `data.id` = immunization_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "immunization.recorded"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "immunization_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "vaccine_code": {
                            "type": "string"
                          },
                          "dose_no": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "immunization.recorded",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000003101",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0003",
                  "encounter_id": null,
                  "vaccine_code": "DPT-HB-HIB",
                  "dose_no": 1
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "appointment.booked": {
      "post": {
        "operationId": "onAppointmentBooked",
        "summary": "Booking dibuat atau dijadwal ulang",
        "description": "`rescheduled: true` bila berasal dari jadwal ulang. `patient_id` null untuk pasien baru yang belum terdaftar. Data entitas: `data.id` = appointment_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "appointment.booked"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "appointment_id"
                          },
                          "patient_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "practitioner_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "start_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "unit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "source": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string"
                          },
                          "rescheduled": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "appointment.booked",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                  "start_at": "2026-11-02T08:15:00+07:00",
                  "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                  "source": "admin",
                  "code": "BK-7KQ2MZ"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "appointment.cancelled": {
      "post": {
        "operationId": "onAppointmentCancelled",
        "summary": "Booking dibatalkan",
        "description": "Data entitas: `data.id` = appointment_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "appointment.cancelled"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "appointment_id"
                          },
                          "patient_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "practitioner_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "start_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "reason": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "appointment.cancelled",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                  "start_at": "2026-11-02T08:15:00+07:00",
                  "reason": "Pasien berhalangan"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "appointment.checked_in": {
      "post": {
        "operationId": "onAppointmentCheckedIn",
        "summary": "Pasien check-in booking",
        "description": "Kunjungan dan antrean dibuat otomatis (lihat `encounter.started`). Data entitas: `data.id` = appointment_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "appointment.checked_in"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "appointment_id"
                          },
                          "appointment_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "practitioner_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "unit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "payer_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "payer_kind": {
                            "type": "string"
                          },
                          "branch_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "start_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "complaint": {
                            "type": "string"
                          },
                          "chief_complaint": {
                            "type": "string"
                          },
                          "source": {
                            "type": "string"
                          },
                          "service_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "appointment.checked_in",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a001",
                  "appointment_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
                  "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
                  "payer_id": null,
                  "payer_kind": "umum",
                  "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                  "start_at": "2026-11-02T08:15:00+07:00",
                  "complaint": "Demam 3 hari",
                  "chief_complaint": "Demam 3 hari",
                  "source": "admin",
                  "service_id": null
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "invoice.finalized": {
      "post": {
        "operationId": "onInvoiceFinalized",
        "summary": "Tagihan final (nomor terbit)",
        "description": "Bila bagian pasien 0, langsung diikuti `invoice.paid`. Data entitas: `data.id` = invoice_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "invoice.finalized"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "invoice_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "payer_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "total": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          },
                          "patient_amount": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          },
                          "payer_amount": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "invoice.finalized",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
                  "total": "195000",
                  "patient_amount": "195000",
                  "payer_amount": "0"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "invoice.paid": {
      "post": {
        "operationId": "onInvoicePaid",
        "summary": "Tagihan lunas (bagian pasien)",
        "description": "Data entitas: `data.id` = invoice_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "invoice.paid"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "invoice_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "invoice.paid",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "invoice.voided": {
      "post": {
        "operationId": "onInvoiceVoided",
        "summary": "Tagihan dibatalkan (void)",
        "description": "Data entitas: `data.id` = invoice_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "invoice.voided"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "invoice_id"
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "encounter_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reason": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "invoice.voided",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b001",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
                  "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
                  "reason": "Salah penjamin"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "payment.received": {
      "post": {
        "operationId": "onPaymentReceived",
        "summary": "Pembayaran diterima",
        "description": "Satu event per pembayaran (pembayaran campuran → beberapa event). Data entitas: `data.id` = payment_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "payment.received"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "payment_id"
                          },
                          "invoice_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "amount": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          },
                          "method": {
                            "type": "string",
                            "enum": [
                              "cash",
                              "debit",
                              "credit",
                              "qris",
                              "transfer",
                              "deposit"
                            ]
                          },
                          "patient_id": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "payment.received",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b101",
                  "invoice_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b001",
                  "amount": "195000",
                  "method": "qris",
                  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "claim.submitted": {
      "post": {
        "operationId": "onClaimSubmitted",
        "summary": "Klaim penjamin diajukan",
        "description": "Modul klaim. `kind` = jenis klaim. Data entitas: `data.id` = claim_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "claim.submitted"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "claim_id"
                          },
                          "payer_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "amount": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          },
                          "kind": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "claim.submitted",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001301",
                  "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0003",
                  "amount": "1250000",
                  "kind": "insurance"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "claim.paid": {
      "post": {
        "operationId": "onClaimPaid",
        "summary": "Klaim dibayar penjamin",
        "description": "`amount` = nominal pembayaran yang dicatat. Data entitas: `data.id` = claim_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "claim.paid"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "claim_id"
                          },
                          "payer_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "amount": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          },
                          "kind": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "claim.paid",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001301",
                  "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0003",
                  "amount": "1200000",
                  "kind": "insurance"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "claim.rejected": {
      "post": {
        "operationId": "onClaimRejected",
        "summary": "Klaim ditolak penjamin",
        "description": "Data entitas: `data.id` = claim_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "claim.rejected"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "claim_id"
                          },
                          "payer_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "amount": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          },
                          "kind": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "claim.rejected",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001301",
                  "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0003",
                  "amount": "1250000",
                  "kind": "insurance"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "stock.below_minimum": {
      "post": {
        "operationId": "onStockBelowMinimum",
        "summary": "Stok di bawah minimum",
        "description": "Maksimal sekali per barang per gudang per hari. `data.id` = ID barang. Data entitas: `data.id` = item_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "stock.below_minimum"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "item_id"
                          },
                          "warehouse_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "on_hand": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          },
                          "min_stock": {
                            "type": "string",
                            "description": "Angka desimal rupiah sebagai string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "stock.below_minimum",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001401",
                  "warehouse_id": "3f0c2a10-5b7e-4c1d-9a2e-000000001501",
                  "on_hand": "8",
                  "min_stock": "20"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "subscription.activated": {
      "post": {
        "operationId": "onSubscriptionActivated",
        "summary": "Langganan Medivana aktif",
        "description": "Paket organisasi aktif (tanpa `branch_id`). Data entitas: `data.id` = subscription_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "subscription.activated"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "subscription_id"
                          },
                          "plan": {
                            "type": "string"
                          },
                          "billing_cycle": {
                            "type": "string"
                          },
                          "branches": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "subscription.activated",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001601",
                  "plan": "klinik_pro",
                  "billing_cycle": "annual",
                  "branches": 3
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "subscription.changed": {
      "post": {
        "operationId": "onSubscriptionChanged",
        "summary": "Paket langganan berubah",
        "description": "Upgrade/downgrade paket (tanpa `branch_id`). Data entitas: `data.id` = subscription_id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventIDHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEvent"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "const": "subscription.changed"
                      },
                      "data": {
                        "type": "object",
                        "required": [
                          "id"
                        ],
                        "additionalProperties": true,
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "subscription_id"
                          },
                          "plan": {
                            "type": "string"
                          },
                          "previous_plan": {
                            "type": "string"
                          },
                          "billing_cycle": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001e001",
                "type": "subscription.changed",
                "created_at": "2026-10-29T01:15:02Z",
                "org_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
                "data": {
                  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000001601",
                  "plan": "enterprise",
                  "previous_plan": "klinik_pro",
                  "billing_cycle": "annual"
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "$ref": "#/components/responses/WebhookGone"
          },
          "2XX": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 client credentials. Token opaque `mdn_at_…`, berlaku 3600 detik.",
        "x-medivana-scope-permissions": {
          "patients:read": [
            "patient.read"
          ],
          "patients:write": [
            "patient.read",
            "patient.write"
          ],
          "encounters:read": [
            "encounter.read"
          ],
          "appointments:read": [
            "appointment.read"
          ],
          "appointments:write": [
            "appointment.read",
            "appointment.manage"
          ],
          "invoices:read": [
            "invoice.read"
          ],
          "webhooks:manage": [
            "webhook.manage"
          ]
        },
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://api.medivana.cloud/api/v1/oauth/token",
            "scopes": {
              "patients:read": "Baca data pasien",
              "patients:write": "Daftarkan dan ubah data pasien",
              "encounters:read": "Baca kunjungan dan rekam medis",
              "appointments:read": "Baca booking dan jadwal",
              "appointments:write": "Buat dan ubah booking",
              "invoices:read": "Baca tagihan pasien",
              "webhooks:manage": "Kelola langganan webhook"
            }
          }
        }
      },
      "clientBasic": {
        "type": "http",
        "scheme": "basic",
        "description": "`client_id` sebagai username, `client_secret` sebagai password (hanya untuk endpoint OAuth)."
      }
    },
    "parameters": {
      "ID": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "PatientID": {
        "name": "patient_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "description": "Nilai `next_cursor` dari halaman sebelumnya",
        "schema": {
          "type": "string"
        }
      },
      "BranchHeader": {
        "name": "X-Branch-ID",
        "in": "header",
        "description": "Cabang aktif (opsional). Nilai di luar cabang klien diabaikan.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "BranchRequired": {
        "name": "X-Branch-ID",
        "in": "header",
        "required": true,
        "description": "Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → `400`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "description": "Versi dari `ETag` (mis. `\"3\"`). Bila tidak cocok → `412 stale`.",
        "schema": {
          "type": "string",
          "example": "\"3\""
        }
      },
      "Lang": {
        "name": "lang",
        "in": "query",
        "description": "Bahasa dokumen cetak; default bahasa pasien lalu default organisasi.",
        "schema": {
          "type": "string",
          "enum": [
            "id",
            "en"
          ]
        }
      },
      "WebhookEventHeader": {
        "name": "X-Medivana-Event",
        "in": "header",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/EventName"
        }
      },
      "WebhookEventIDHeader": {
        "name": "X-Medivana-Event-ID",
        "in": "header",
        "required": true,
        "description": "Sama dengan `id` di body; gunakan untuk deduplikasi (pengiriman ulang memakai ID yang sama).",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "WebhookDeliveryHeader": {
        "name": "X-Medivana-Delivery",
        "in": "header",
        "required": true,
        "description": "ID pengiriman (lihat `GET /webhooks/{id}/deliveries`).",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "WebhookSignatureHeader": {
        "name": "X-Medivana-Signature",
        "in": "header",
        "required": true,
        "description": "`t=<unix>,v1=<hex>` dengan `v1 = HEX(HMAC-SHA256(secret, \"<t>.\" + body mentah))`. Tolak bila `|now − t| > 300` detik.",
        "schema": {
          "type": "string",
          "example": "t=1793251200,v1=5f2c8e…"
        }
      }
    },
    "headers": {
      "ETag": {
        "description": "Versi baris, mis. `\"3\"`; kirim kembali sebagai `If-Match`.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Parameter atau format permintaan tidak valid",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/bad-request",
              "title": "Permintaan tidak valid",
              "status": 400,
              "code": "bad-request",
              "detail": "Parameter tanggal tidak valid.",
              "instance": "/api/v1/encounters",
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "BranchRequired": {
        "description": "Cabang aktif belum dipilih (`X-Branch-ID`)",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/bad-request",
              "title": "Permintaan tidak valid",
              "status": 400,
              "code": "bad-request",
              "detail": "Pilih cabang terlebih dahulu (header X-Branch-ID).",
              "instance": "/api/v1/patients",
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Token tidak ada, tidak valid, kedaluwarsa, atau dicabut",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/unauthorized",
              "title": "Perlu masuk",
              "status": 401,
              "code": "unauthorized",
              "detail": "Token akses tidak valid atau kedaluwarsa.",
              "instance": "/api/v1/patients",
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "ModuleLocked": {
        "description": "Modul tidak aktif di paket organisasi",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/module-locked",
              "title": "Modul belum aktif",
              "status": 402,
              "code": "module-locked",
              "detail": "Modul Booking & Jadwal belum aktif di paket Anda. Hubungi admin untuk menambah add-on atau lihat demo modulnya.",
              "instance": "/api/v1/booking/appointments",
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Scope token tidak memberi izin (`forbidden`), atau langganan klinik baca-saja untuk operasi tulis (`read-only`)",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/forbidden",
              "title": "Akses ditolak",
              "status": 403,
              "code": "forbidden",
              "detail": "Peran Anda tidak memiliki izin untuk aksi ini.",
              "instance": "/api/v1/billing/invoices",
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "ForbiddenConfidential": {
        "description": "Scope tidak memberi izin (`forbidden`), rekam medis ditandai rahasia (`confidential-record`), atau baca-saja (`read-only`)",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "examples": {
              "forbidden": {
                "value": {
                  "type": "https://medivana.cloud/errors/forbidden",
                  "title": "Akses ditolak",
                  "status": 403,
                  "code": "forbidden",
                  "detail": "Peran Anda tidak memiliki izin untuk aksi ini."
                }
              },
              "confidential": {
                "value": {
                  "type": "https://medivana.cloud/errors/confidential-record",
                  "title": "Rekam medis rahasia",
                  "status": 403,
                  "code": "confidential-record",
                  "detail": "Rekam medis ini ditandai rahasia. Hanya tenaga kesehatan dengan izin rekam medis rahasia yang dapat membukanya."
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Data tidak ada, milik organisasi lain, atau di luar cakupan cabang klien",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/not-found",
              "title": "Data tidak ditemukan",
              "status": 404,
              "code": "not-found",
              "detail": "Pasien tidak ditemukan.",
              "instance": "/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-0000000a0009",
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "Conflict": {
        "description": "Konflik data atau status tidak mengizinkan aksi",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/conflict",
              "title": "Terjadi konflik data",
              "status": 409,
              "code": "conflict",
              "detail": "Slot sudah dipesan pasien lain. Pilih jam lain.",
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "Stale": {
        "description": "`If-Match` tidak cocok dengan versi terbaru",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/stale",
              "title": "Data sudah diubah pengguna lain",
              "status": 412,
              "code": "stale",
              "detail": "Data ini sudah diubah orang lain sejak Anda membukanya. Muat ulang lalu ulangi perubahan."
            }
          }
        }
      },
      "Validation": {
        "description": "Validasi gagal; rincian per field di `errors`",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/validation",
              "title": "Data belum lengkap atau tidak valid",
              "status": 422,
              "code": "validation",
              "errors": [
                {
                  "field": "nik",
                  "message": "NIK harus 16 digit"
                }
              ],
              "request_id": "01JC9Z3Y8M4N2P5Q7R9S0T1V2W"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Batas laju klien (`rate_limit_per_min`) terlampaui; coba lagi pada menit berikutnya",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/rate-limited",
              "title": "Terlalu banyak permintaan",
              "status": 429,
              "code": "rate-limited",
              "detail": "Tunggu sebentar lalu coba lagi."
            }
          }
        }
      },
      "RateLimitedIP": {
        "description": "60 permintaan per menit per IP terlampaui",
        "headers": {
          "Retry-After": {
            "description": "Detik sampai jendela berikutnya",
            "schema": {
              "type": "integer",
              "example": 60
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/rate-limited",
              "title": "Terlalu banyak permintaan",
              "status": 429,
              "code": "rate-limited",
              "detail": "Tunggu sebentar lalu coba lagi."
            }
          }
        }
      },
      "UpstreamUnavailable": {
        "description": "Layanan pemerintah tidak menjawab (`satusehat-unavailable` / `bpjs-unavailable`); lanjutkan proses dan coba lagi nanti",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            },
            "example": {
              "type": "https://medivana.cloud/errors/bpjs-unavailable",
              "title": "BPJS tidak dapat dihubungi",
              "status": 502,
              "code": "bpjs-unavailable"
            }
          }
        }
      },
      "SpecialtyList": {
        "description": "Daftar data paket spesialis",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "items"
              ],
              "properties": {
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        }
      },
      "SpecialtyObject": {
        "description": "Data paket spesialis",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "BinaryFile": {
        "description": "Isi berkas (`Content-Type` sesuai berkas)",
        "content": {
          "application/octet-stream": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      },
      "WebhookAck": {
        "description": "Diterima. Balas 2xx dalam 10 detik; selain itu dicoba ulang 1, 5, 15, 60 menit lalu tiap 6 jam selama 3 hari."
      },
      "WebhookGone": {
        "description": "Endpoint tidak dipakai lagi; langganan langsung dinonaktifkan (`disabled_reason`)."
      }
    },
    "schemas": {
      "TokenRequest": {
        "type": "object",
        "required": [
          "grant_type"
        ],
        "properties": {
          "grant_type": {
            "type": "string",
            "const": "client_credentials"
          },
          "scope": {
            "type": "string",
            "description": "Subset scope dipisah spasi; default semua scope klien."
          },
          "client_id": {
            "type": "string",
            "description": "Alternatif Basic auth"
          },
          "client_secret": {
            "type": "string",
            "description": "Alternatif Basic auth"
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "scope"
        ],
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "const": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "description": "Detik"
          },
          "scope": {
            "type": "string",
            "description": "Scope yang diberikan, dipisah spasi"
          }
        }
      },
      "OAuthError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "invalid_request",
              "invalid_client",
              "unsupported_grant_type",
              "invalid_scope",
              "unauthorized_client"
            ]
          },
          "error_description": {
            "type": "string"
          }
        }
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details",
        "required": [
          "type",
          "title",
          "status"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "Kode stabil untuk logika klien",
            "examples": [
              "bad-request",
              "unauthorized",
              "forbidden",
              "confidential-record",
              "read-only",
              "not-found",
              "conflict",
              "stale",
              "validation",
              "module-locked",
              "rate-limited",
              "internal"
            ]
          },
          "instance": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Queued": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "queued"
          }
        }
      },
      "PayerKind": {
        "type": "string",
        "enum": [
          "umum",
          "bpjs",
          "insurance",
          "company"
        ]
      },
      "TokenContext": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identitas teknis klien API"
          },
          "email": {
            "type": "string",
            "description": "`client_id` klien"
          },
          "name": {
            "type": "string"
          },
          "org": {
            "type": "object",
            "additionalProperties": true
          },
          "branch_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Cabang aktif permintaan ini"
          },
          "branches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Branch"
            }
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Izin RBAC hasil scope token"
          },
          "data_scope": {
            "type": "string"
          },
          "two_factor": {
            "type": "boolean"
          },
          "entitlements": {
            "$ref": "#/components/schemas/Entitlements"
          },
          "is_demo": {
            "type": "boolean"
          },
          "break_glass": {
            "type": "boolean"
          },
          "locale": {
            "type": "string"
          },
          "effective_locale": {
            "type": "string"
          }
        }
      },
      "Entitlements": {
        "type": "object",
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid"
          },
          "plan": {
            "type": "string"
          },
          "plan_name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "grace",
              "read_only",
              "cancelled",
              "none"
            ]
          },
          "billing_cycle": {
            "type": "string"
          },
          "branches": {
            "type": "integer"
          },
          "modules": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            }
          },
          "limits": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "addons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bi_level": {
            "type": "string"
          },
          "accounting_level": {
            "type": "string"
          },
          "current_period_end": {
            "type": "string",
            "format": "date-time"
          },
          "grace_until": {
            "type": "string",
            "format": "date-time"
          },
          "is_demo": {
            "type": "boolean"
          }
        }
      },
      "Organization": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "legal_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "npwp": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_pkp": {
            "type": "boolean"
          },
          "clinic_kind": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "is_demo": {
            "type": "boolean"
          },
          "satusehat_org_ihs": {
            "type": [
              "string",
              "null"
            ]
          },
          "settings": {
            "type": "object",
            "additionalProperties": true
          },
          "default_locale": {
            "type": "string",
            "enum": [
              "id",
              "en"
            ]
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "Branch": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "latitude": {
            "type": [
              "number",
              "null"
            ]
          },
          "longitude": {
            "type": [
              "number",
              "null"
            ]
          },
          "geofence_m": {
            "type": "integer"
          },
          "satusehat_location_ihs": {
            "type": [
              "string",
              "null"
            ]
          },
          "bpjs_ppk_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_active": {
            "type": "boolean"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "Unit": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "specialty": {
            "type": [
              "string",
              "null"
            ]
          },
          "satusehat_location_ihs": {
            "type": [
              "string",
              "null"
            ]
          },
          "bpjs_poli_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_active": {
            "type": "boolean"
          }
        }
      },
      "Practitioner": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID keanggotaan (practitioner_id)"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "display_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "profession": {
            "type": "string"
          },
          "practitioner_ihs": {
            "type": [
              "string",
              "null"
            ]
          },
          "branch_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "all_branches": {
            "type": "boolean"
          }
        }
      },
      "TerminologyCode": {
        "type": "object",
        "properties": {
          "system": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "display": {
            "type": "string"
          },
          "display_en": {
            "type": [
              "string",
              "null"
            ]
          },
          "synonyms": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unit UCUM (LOINC tanda vital)"
          }
        }
      },
      "PatientBrief": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "mrn": {
            "type": "string"
          },
          "sex": {
            "type": "string",
            "enum": [
              "male",
              "female"
            ]
          },
          "birth_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "age_label": {
            "type": "string"
          },
          "age_years": {
            "type": [
              "integer",
              "null"
            ]
          },
          "allergy_status": {
            "type": "string",
            "enum": [
              "unknown",
              "none",
              "has"
            ]
          }
        }
      },
      "PatientSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "mrn": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "sex": {
            "type": "string",
            "enum": [
              "male",
              "female"
            ]
          },
          "birth_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "age_label": {
            "type": "string"
          },
          "age_years": {
            "type": [
              "integer",
              "null"
            ]
          },
          "nik_masked": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone_masked": {
            "type": [
              "string",
              "null"
            ]
          },
          "bpjs_no_masked": {
            "type": [
              "string",
              "null"
            ]
          },
          "allergy_status": {
            "type": "string",
            "enum": [
              "unknown",
              "none",
              "has"
            ]
          },
          "is_active": {
            "type": "boolean"
          },
          "merged_into": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        }
      },
      "Patient": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PatientSummary"
          },
          {
            "type": "object",
            "properties": {
              "nik": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "bpjs_no": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "birth_place": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "address": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "village": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "district": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "city": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "province": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "postal_code": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "religion": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "marital_status": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "single",
                  "married",
                  "divorced",
                  "widowed",
                  null
                ]
              },
              "occupation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "education": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "blood_type": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "nationality": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "mother_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "emergency_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "emergency_relation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "emergency_phone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "satusehat_ihs": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "registered_branch_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "notes": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              },
              "version": {
                "type": "integer"
              },
              "satusehat_lookup": {
                "type": "string",
                "enum": [
                  "found",
                  "not_found",
                  "unavailable",
                  "skipped"
                ],
                "description": "Hanya pada respons create/lookup"
              }
            }
          }
        ]
      },
      "PatientInput": {
        "type": "object",
        "description": "POST wajib `name` dan `sex`. PATCH: kirim field yang berubah saja; `\"\"` mengosongkan field opsional.",
        "properties": {
          "name": {
            "type": "string"
          },
          "sex": {
            "type": "string",
            "enum": [
              "male",
              "female",
              "L",
              "P"
            ]
          },
          "birth_date": {
            "type": "string",
            "format": "date"
          },
          "birth_place": {
            "type": "string"
          },
          "nik": {
            "type": "string",
            "pattern": "^[0-9]{16}$"
          },
          "phone": {
            "type": "string"
          },
          "bpjs_no": {
            "type": "string",
            "pattern": "^[0-9]{13}$"
          },
          "email": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "village": {
            "type": "string"
          },
          "district": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "province": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "religion": {
            "type": "string"
          },
          "marital_status": {
            "type": "string",
            "enum": [
              "single",
              "married",
              "divorced",
              "widowed"
            ]
          },
          "occupation": {
            "type": "string"
          },
          "education": {
            "type": "string"
          },
          "blood_type": {
            "type": "string"
          },
          "nationality": {
            "type": "string"
          },
          "mother_name": {
            "type": "string"
          },
          "emergency_name": {
            "type": "string"
          },
          "emergency_relation": {
            "type": "string"
          },
          "emergency_phone": {
            "type": "string"
          },
          "satusehat_ihs": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "mrn": {
            "type": [
              "string",
              "null"
            ],
            "description": "Kosong = nomor RM otomatis"
          },
          "skip_satusehat_lookup": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "SatusehatPatient": {
        "type": "object",
        "properties": {
          "ihs_number": {
            "type": "string"
          },
          "nik": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "birth_date": {
            "type": "string"
          },
          "gender": {
            "type": "string"
          },
          "address": {
            "type": "string"
          }
        }
      },
      "PatientMerge": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "target_patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "source_patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "reason": {
            "type": "string"
          },
          "source_snapshot": {
            "type": "object",
            "additionalProperties": true
          },
          "moved": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "merged_by": {
            "type": "string",
            "format": "uuid"
          },
          "merged_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Consent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "data_processing",
              "photo",
              "recording",
              "telemedicine",
              "broadcast"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "granted",
              "withdrawn"
            ]
          },
          "consent_version": {
            "type": "string"
          },
          "consent_text": {
            "type": "string"
          },
          "method": {
            "type": "string",
            "enum": [
              "written",
              "verbal",
              "digital",
              "kiosk"
            ]
          },
          "signer_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "signer_relation": {
            "type": "string"
          },
          "witness_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "evidence_file_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "granted_at": {
            "type": "string",
            "format": "date-time"
          },
          "granted_by": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "withdrawn_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "withdrawn_by": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "withdraw_reason": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Allergy": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "substance": {
            "type": "string"
          },
          "substance_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "code_system": {
            "type": [
              "string",
              "null"
            ]
          },
          "item_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "category": {
            "type": "string",
            "enum": [
              "obat",
              "makanan",
              "lingkungan"
            ]
          },
          "reaction": {
            "type": [
              "string",
              "null"
            ]
          },
          "severity": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "ringan",
              "sedang",
              "berat",
              null
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "resolved",
              "entered_in_error"
            ]
          },
          "onset": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "recorded_at": {
            "type": "string",
            "format": "date-time"
          },
          "recorded_by": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "resolved_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "ClinicalDocument": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "file_id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "enum": [
              "general",
              "lab_external",
              "imaging",
              "referral",
              "consent",
              "photo",
              "identity",
              "other"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "filename": {
            "type": "string"
          },
          "content_type": {
            "type": "string"
          },
          "size_bytes": {
            "type": "integer"
          },
          "uploaded_by": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "download_url": {
            "type": "string",
            "description": "Path relatif `GET /clinical-documents/{id}/download`"
          }
        }
      },
      "Encounter": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "unit_id": {
            "type": "string",
            "format": "uuid"
          },
          "unit_name": {
            "type": "string"
          },
          "unit_specialty": {
            "type": [
              "string",
              "null"
            ]
          },
          "practitioner_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "practitioner_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "payer_id": {
            "type": "string",
            "format": "uuid"
          },
          "payer_name": {
            "type": "string"
          },
          "payer_kind": {
            "$ref": "#/components/schemas/PayerKind"
          },
          "payer_reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "rawat_jalan",
              "telekonsultasi",
              "kunjungan_sehat"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "registered",
              "in_progress",
              "finished",
              "cancelled"
            ]
          },
          "appointment_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "queue_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "queue_label": {
            "type": [
              "string",
              "null"
            ]
          },
          "queue_status": {
            "type": [
              "string",
              "null"
            ]
          },
          "chief_complaint": {
            "type": [
              "string",
              "null"
            ]
          },
          "anamnesis": {
            "type": "object",
            "additionalProperties": true
          },
          "registered_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancelled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancel_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "type": "integer"
          },
          "patient": {
            "$ref": "#/components/schemas/PatientBrief"
          }
        }
      },
      "QueueTicket": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "unit_id": {
            "type": "string",
            "format": "uuid"
          },
          "unit_name": {
            "type": "string"
          },
          "patient_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "appointment_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "service_date": {
            "type": "string",
            "format": "date"
          },
          "number": {
            "type": "integer"
          },
          "label": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "waiting",
              "called",
              "in_service",
              "pharmacy",
              "cashier",
              "done",
              "cancelled"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "normal",
              "priority"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "registration",
              "appointment",
              "kiosk"
            ]
          },
          "call_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "Note": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "encounter_id": {
            "type": "string",
            "format": "uuid"
          },
          "template_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "subjective": {
            "type": [
              "string",
              "null"
            ]
          },
          "objective": {
            "type": [
              "string",
              "null"
            ]
          },
          "assessment": {
            "type": [
              "string",
              "null"
            ]
          },
          "plan": {
            "type": [
              "string",
              "null"
            ]
          },
          "extra": {
            "type": "object",
            "additionalProperties": true
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "signed"
            ]
          },
          "version": {
            "type": "integer",
            "description": "Versi klinis"
          },
          "revision": {
            "type": "integer",
            "description": "Penghitung simpan"
          },
          "signed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "signed_by": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "saved_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "saved_at_label": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_new": {
            "type": "boolean"
          }
        }
      },
      "NoteTemplate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "specialty": {
            "type": [
              "string",
              "null"
            ]
          },
          "unit_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "subjective": {
            "type": "string"
          },
          "objective": {
            "type": "string"
          },
          "assessment": {
            "type": "string"
          },
          "plan": {
            "type": "string"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "is_default": {
            "type": "boolean"
          },
          "is_active": {
            "type": "boolean"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "Observation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "panel_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "key": {
            "type": "string",
            "enum": [
              "systolic",
              "diastolic",
              "heart_rate",
              "respiratory_rate",
              "temperature",
              "spo2",
              "weight",
              "height",
              "bmi",
              "pain_score",
              "head_circumference",
              "waist_circumference"
            ]
          },
          "code": {
            "type": "string",
            "description": "LOINC"
          },
          "display": {
            "type": "string"
          },
          "value_num": {
            "type": [
              "number",
              "null"
            ]
          },
          "value_text": {
            "type": [
              "string",
              "null"
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "UCUM"
          },
          "flag": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "N",
              "L",
              "H",
              "LL",
              "HH",
              null
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "final",
              "entered_in_error"
            ]
          },
          "observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "recorded_by": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        }
      },
      "Diagnosis": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "icd10_code": {
            "type": "string"
          },
          "display": {
            "type": "string"
          },
          "is_primary": {
            "type": "boolean"
          },
          "kind": {
            "type": "string",
            "enum": [
              "new",
              "old"
            ]
          },
          "rank": {
            "type": "integer"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Procedure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "icd9cm_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "display": {
            "type": [
              "string",
              "null"
            ]
          },
          "service_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "service_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "quantity": {
            "type": "number"
          },
          "practitioner_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "charge_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "performed_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Signature": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": "string",
            "format": "uuid"
          },
          "note_id": {
            "type": "string",
            "format": "uuid"
          },
          "note_version": {
            "type": "integer"
          },
          "kind": {
            "type": "string",
            "enum": [
              "close",
              "correction"
            ]
          },
          "content_hash": {
            "type": "string",
            "description": "SHA-256 konten kanonik"
          },
          "signer_membership_id": {
            "type": "string",
            "format": "uuid"
          },
          "signer_name": {
            "type": "string"
          },
          "method": {
            "type": "string"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "signed_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Letter": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "template_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "sick_leave",
              "referral",
              "health_certificate",
              "other"
            ]
          },
          "number": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "additionalProperties": true
          },
          "paper_size": {
            "type": "string",
            "enum": [
              "A4",
              "A5"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "issued",
              "void"
            ]
          },
          "issued_at": {
            "type": "string",
            "format": "date-time"
          },
          "issued_by": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "issued_by_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "void_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "print_url": {
            "type": "string"
          },
          "patient_name": {
            "type": "string"
          },
          "patient_mrn": {
            "type": "string"
          }
        }
      },
      "Appointment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "unit_id": {
            "type": "string",
            "format": "uuid"
          },
          "unit_name": {
            "type": "string"
          },
          "patient_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "patient_name": {
            "type": "string"
          },
          "patient_phone_masked": {
            "type": [
              "string",
              "null"
            ]
          },
          "patient_sex": {
            "type": [
              "string",
              "null"
            ]
          },
          "patient_birth_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "is_new_patient": {
            "type": "boolean"
          },
          "practitioner_id": {
            "type": "string",
            "format": "uuid"
          },
          "practitioner_name": {
            "type": "string"
          },
          "schedule_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "service_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "start_at": {
            "type": "string",
            "format": "date-time"
          },
          "end_at": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "enum": [
              "booked",
              "checked_in",
              "cancelled",
              "no_show",
              "done"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "portal",
              "whatsapp",
              "admin",
              "bpjs"
            ]
          },
          "payer_kind": {
            "$ref": "#/components/schemas/PayerKind"
          },
          "payer_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "complaint": {
            "type": [
              "string",
              "null"
            ]
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "checked_in_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancelled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancel_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "reminder_sent_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "Slot": {
        "type": "object",
        "properties": {
          "schedule_id": {
            "type": "string",
            "format": "uuid"
          },
          "practitioner_id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "unit_id": {
            "type": "string",
            "format": "uuid"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "start_at": {
            "type": "string",
            "format": "date-time"
          },
          "end_at": {
            "type": "string",
            "format": "date-time"
          },
          "time": {
            "type": "string"
          },
          "available": {
            "type": "boolean"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "booked",
              "quota_full",
              "leave",
              "closed",
              "past",
              null
            ]
          },
          "remaining_quota": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "ScheduleInput": {
        "type": "object",
        "properties": {
          "practitioner_id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "unit_id": {
            "type": "string",
            "format": "uuid"
          },
          "weekday": {
            "type": "integer",
            "minimum": 1,
            "maximum": 7
          },
          "start_time": {
            "type": "string",
            "example": "08:00"
          },
          "end_time": {
            "type": "string",
            "example": "12:00"
          },
          "slot_minutes": {
            "type": "integer"
          },
          "quota": {
            "type": [
              "integer",
              "null"
            ]
          },
          "allow_online": {
            "type": "boolean"
          },
          "valid_from": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "valid_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Schedule": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ScheduleInput"
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "unit_name": {
                "type": "string"
              },
              "practitioner_name": {
                "type": "string"
              },
              "weekday_label": {
                "type": "string"
              },
              "slot_count": {
                "type": "integer"
              },
              "is_active": {
                "type": "boolean"
              },
              "version": {
                "type": "integer"
              }
            }
          }
        ]
      },
      "ScheduleException": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "practitioner_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "date_from": {
            "type": "string",
            "format": "date"
          },
          "date_to": {
            "type": "string",
            "format": "date"
          },
          "start_time": {
            "type": [
              "string",
              "null"
            ]
          },
          "end_time": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "leave",
              "closed",
              "other"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_name": {
            "type": "string"
          },
          "patient_mrn": {
            "type": "string"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "payer_id": {
            "type": "string",
            "format": "uuid"
          },
          "payer_name": {
            "type": "string"
          },
          "payer_kind": {
            "$ref": "#/components/schemas/PayerKind"
          },
          "number": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "finalized",
              "partially_paid",
              "paid",
              "void"
            ]
          },
          "subtotal": {
            "type": "number"
          },
          "discount": {
            "type": "number"
          },
          "total": {
            "type": "number"
          },
          "patient_amount": {
            "type": "number"
          },
          "payer_amount": {
            "type": "number"
          },
          "package_amount": {
            "type": "number"
          },
          "paid_amount": {
            "type": "number"
          },
          "credit_patient_amount": {
            "type": "number"
          },
          "credit_payer_amount": {
            "type": "number"
          },
          "payer_paid_amount": {
            "type": "number"
          },
          "payer_adjusted_amount": {
            "type": "number"
          },
          "outstanding": {
            "type": "number"
          },
          "payer_outstanding": {
            "type": "number"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "finalized_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "voided_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "void_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "line_no": {
                  "type": "integer"
                },
                "charge_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "service_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "item_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "practitioner_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "revenue_key": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "unit_price": {
                  "type": "number"
                },
                "gross": {
                  "type": "number"
                },
                "discount": {
                  "type": "number"
                },
                "total": {
                  "type": "number"
                },
                "payer_share": {
                  "type": "number"
                },
                "patient_share": {
                  "type": "number"
                },
                "coverage": {
                  "type": "string",
                  "enum": [
                    "payer",
                    "excluded",
                    "none",
                    "package"
                  ]
                }
              }
            }
          },
          "discounts": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "payments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Payment"
            }
          }
        }
      },
      "Payment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "invoice_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "string"
          },
          "method": {
            "type": "string",
            "enum": [
              "cash",
              "debit",
              "credit",
              "qris",
              "transfer",
              "deposit"
            ]
          },
          "amount": {
            "type": "number"
          },
          "tendered": {
            "type": [
              "number",
              "null"
            ]
          },
          "change_amount": {
            "type": "number"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "completed",
              "refunded",
              "expired",
              "failed"
            ]
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cash_session_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "gateway_provider": {
            "type": [
              "string",
              "null"
            ]
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "settlement_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "refunded_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "refund_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Charge": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "source_type": {
            "type": "string"
          },
          "source_id": {
            "type": "string"
          },
          "service_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "item_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "description": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "unit_price": {
            "type": [
              "number",
              "null"
            ],
            "description": "null = harga dari daftar tarif saat ditagih"
          },
          "revenue_key": {
            "type": "string"
          },
          "practitioner_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "billed",
              "cancelled"
            ]
          },
          "invoice_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Service": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "revenue_key": {
            "type": "string"
          },
          "base_price": {
            "type": "number"
          },
          "icd9cm_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "loinc_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "specialty": {
            "type": [
              "string",
              "null"
            ]
          },
          "fee_eligible": {
            "type": "boolean"
          },
          "is_active": {
            "type": "boolean"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "Payer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/PayerKind"
          },
          "payment_terms_days": {
            "type": [
              "integer",
              "null"
            ]
          },
          "coverage_bp": {
            "type": "integer"
          },
          "max_per_invoice": {
            "type": [
              "number",
              "null"
            ]
          },
          "excluded_categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "is_active": {
            "type": "boolean"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "CashSession": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "user_name": {
            "type": "string"
          },
          "number": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ]
          },
          "opened_at": {
            "type": "string",
            "format": "date-time"
          },
          "opening_float": {
            "type": "number"
          },
          "cash_in": {
            "type": "number"
          },
          "cash_out": {
            "type": "number"
          },
          "expected_cash": {
            "type": "number"
          },
          "closed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "counted_cash": {
            "type": [
              "number",
              "null"
            ]
          },
          "difference": {
            "type": [
              "number",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "DiagnosticOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "lab",
              "radiology"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ordered",
              "in_progress",
              "final",
              "cancelled"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "routine",
              "cito"
            ]
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_name": {
            "type": "string"
          },
          "patient_mrn": {
            "type": "string"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "service_id": {
            "type": "string",
            "format": "uuid"
          },
          "service_name": {
            "type": "string"
          },
          "practitioner_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "practitioner_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "ordered_at": {
            "type": "string",
            "format": "date-time"
          },
          "clinical_notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "specimen_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "specimen_collected_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "result_note": {
            "type": [
              "string",
              "null"
            ]
          },
          "validated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "finalized_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "has_critical": {
            "type": "boolean"
          },
          "has_abnormal": {
            "type": "boolean"
          },
          "version": {
            "type": "integer"
          },
          "results": {
            "type": "array",
            "description": "Hanya lab",
            "items": {
              "type": "object",
              "properties": {
                "parameter_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "code": {
                  "type": "string"
                },
                "local_code": {
                  "type": "string"
                },
                "loinc_code": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "unit": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "value_type": {
                  "type": "string"
                },
                "value_num": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "value_text": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "display": {
                  "type": "string"
                },
                "ref_low": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "ref_high": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "ref_text": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "flag": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "N",
                    "L",
                    "H",
                    "LL",
                    "HH",
                    "A",
                    null
                  ]
                },
                "critical": {
                  "type": "boolean"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "manual",
                    "lis"
                  ]
                },
                "entered_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              }
            }
          },
          "report": {
            "type": [
              "object",
              "null"
            ],
            "description": "Hanya radiologi",
            "properties": {
              "technique": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "findings": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "impression": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "reported_by": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "reporter_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "reported_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "version": {
                "type": "integer"
              }
            }
          },
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Hanya radiologi"
          }
        }
      },
      "ClinicalPhoto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "record_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "kind": {
            "type": "string"
          },
          "tooth": {
            "type": [
              "integer",
              "null"
            ]
          },
          "area": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "file_id": {
            "type": "string",
            "format": "uuid"
          },
          "filename": {
            "type": "string"
          },
          "content_type": {
            "type": "string"
          },
          "size_bytes": {
            "type": "integer"
          },
          "taken_at": {
            "type": "string",
            "format": "date-time"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "TeleconSession": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_id": {
            "type": "string",
            "format": "uuid"
          },
          "patient_name": {
            "type": "string"
          },
          "practitioner_id": {
            "type": "string",
            "format": "uuid"
          },
          "practitioner_name": {
            "type": "string"
          },
          "encounter_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "service_id": {
            "type": "string",
            "format": "uuid"
          },
          "service_name": {
            "type": "string"
          },
          "scheduled_start": {
            "type": "string",
            "format": "date-time"
          },
          "scheduled_end": {
            "type": "string",
            "format": "date-time"
          },
          "duration_minutes": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "in_progress",
              "completed",
              "cancelled"
            ]
          },
          "payment_status": {
            "type": "string",
            "enum": [
              "unpaid",
              "paid"
            ]
          },
          "payment_settled": {
            "type": "boolean"
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "payment_ref": {
            "type": [
              "string",
              "null"
            ]
          },
          "charge_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "consent_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancel_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "EventName": {
        "type": "string",
        "enum": [
          "*",
          "ping",
          "patient.created",
          "patient.updated",
          "patient.merged",
          "encounter.started",
          "encounter.closed",
          "encounter.cancelled",
          "allergy.recorded",
          "queue.called",
          "prescription.created",
          "dispense.completed",
          "dispense.returned",
          "lab.order_created",
          "radiology.order_created",
          "lab.result_final",
          "radiology.result_final",
          "immunization.recorded",
          "appointment.booked",
          "appointment.cancelled",
          "appointment.checked_in",
          "invoice.finalized",
          "invoice.paid",
          "invoice.voided",
          "payment.received",
          "claim.submitted",
          "claim.paid",
          "claim.rejected",
          "stock.below_minimum",
          "subscription.activated",
          "subscription.changed"
        ]
      },
      "WebhookSubscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventName"
            }
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_active": {
            "type": "boolean"
          },
          "failure_count": {
            "type": "integer",
            "description": "Kegagalan beruntun; direset setelah pengiriman sukses"
          },
          "disabled_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "subscription_id": {
            "type": "string",
            "format": "uuid"
          },
          "event": {
            "$ref": "#/components/schemas/EventName"
          },
          "event_id": {
            "type": "string",
            "format": "uuid"
          },
          "entity_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "delivered",
              "failed",
              "dead"
            ]
          },
          "attempts": {
            "type": "integer"
          },
          "last_status_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "payload": {
            "$ref": "#/components/schemas/WebhookEvent"
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "required": [
          "id",
          "type",
          "created_at",
          "org_id",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID event (= header X-Medivana-Event-ID); pakai untuk deduplikasi"
          },
          "type": {
            "$ref": "#/components/schemas/EventName"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu event (UTC)"
          },
          "org_id": {
            "type": "string",
            "format": "uuid"
          },
          "branch_id": {
            "type": "string",
            "format": "uuid",
            "description": "Tidak ada untuk event tingkat organisasi"
          },
          "data": {
            "type": "object",
            "description": "`id` entitas + kunci data event. Ambil detail lengkap lewat API dengan token.",
            "required": [
              "id"
            ],
            "additionalProperties": true,
            "properties": {
              "id": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "examples": {
      "Patient": {
        "summary": "Pasien (detail)",
        "value": {
          "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
          "mrn": "RM-000123",
          "name": "Pasien Contoh",
          "sex": "female",
          "birth_date": "1990-05-12",
          "birth_place": "Semarang",
          "age_label": "36 th 5 bl",
          "age_years": 36,
          "nik_masked": "9999********0001",
          "nik": "9999010101900001",
          "phone_masked": "6281******001",
          "phone": "6281200000001",
          "bpjs_no_masked": null,
          "bpjs_no": null,
          "email": "pasien@contoh.test",
          "address": "Jl. Contoh No. 10",
          "city": "Semarang",
          "province": "Jawa Tengah",
          "satusehat_ihs": "P00000000001",
          "allergy_status": "unknown",
          "is_active": true,
          "merged_into": null,
          "registered_branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
          "notes": null,
          "created_at": "2026-10-29T08:15:02+07:00",
          "updated_at": "2026-10-29T08:15:02+07:00",
          "version": 1,
          "satusehat_lookup": "found"
        }
      },
      "ClinicalDocument": {
        "summary": "Dokumen klinis",
        "value": {
          "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6001",
          "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
          "encounter_id": null,
          "file_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6101",
          "title": "Hasil lab luar",
          "category": "lab_external",
          "notes": null,
          "filename": "hasil-lab.pdf",
          "content_type": "application/pdf",
          "size_bytes": 182311,
          "uploaded_by": "3f0c2a10-5b7e-4c1d-9a2e-000000000a11",
          "created_at": "2026-10-29T08:40:00+07:00",
          "download_url": "/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-0000000a6001/download"
        }
      },
      "Appointment": {
        "summary": "Booking",
        "value": {
          "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a001",
          "code": "BK-7KQ2MZ",
          "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
          "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
          "unit_name": "Poli Umum",
          "patient_id": null,
          "patient_name": "Pasien Baru Contoh",
          "patient_phone_masked": "62812****0003",
          "patient_sex": "female",
          "patient_birth_date": "1999-09-09",
          "is_new_patient": true,
          "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
          "practitioner_name": "dr. Rina Contoh",
          "schedule_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a101",
          "service_id": null,
          "start_at": "2026-11-02T08:15:00+07:00",
          "end_at": "2026-11-02T08:30:00+07:00",
          "status": "booked",
          "source": "admin",
          "payer_kind": "umum",
          "payer_id": null,
          "complaint": "Demam 3 hari",
          "encounter_id": null,
          "checked_in_at": null,
          "cancelled_at": null,
          "cancel_reason": null,
          "reminder_sent_at": null,
          "created_at": "2026-10-30T14:02:00+07:00",
          "version": 1
        }
      },
      "Schedule": {
        "summary": "Jadwal praktik",
        "value": {
          "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001a101",
          "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
          "unit_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000c0001",
          "unit_name": "Poli Umum",
          "practitioner_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000d0001",
          "practitioner_name": "dr. Rina Contoh",
          "weekday": 1,
          "weekday_label": "Senin",
          "start_time": "08:00",
          "end_time": "12:00",
          "slot_minutes": 15,
          "quota": 12,
          "slot_count": 16,
          "allow_online": true,
          "valid_from": "2026-11-01",
          "valid_until": null,
          "is_active": true,
          "note": "Poli umum pagi",
          "version": 1
        }
      },
      "Invoice": {
        "summary": "Tagihan lunas",
        "value": {
          "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b001",
          "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
          "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
          "patient_name": "Pasien Contoh",
          "patient_mrn": "RM-000123",
          "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
          "payer_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000f0001",
          "payer_name": "Pasien Umum",
          "payer_kind": "umum",
          "number": "INV-202610-00042",
          "status": "paid",
          "subtotal": 195000,
          "discount": 0,
          "total": 195000,
          "patient_amount": 195000,
          "payer_amount": 0,
          "package_amount": 0,
          "paid_amount": 195000,
          "outstanding": 0,
          "payer_outstanding": 0,
          "finalized_at": "2026-10-29T11:02:00+07:00",
          "paid_at": "2026-10-29T11:03:10+07:00",
          "created_at": "2026-10-29T10:58:00+07:00",
          "version": 3,
          "lines": [
            {
              "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b011",
              "line_no": 1,
              "charge_id": "3f0c2a10-5b7e-4c1d-9a2e-000000009001",
              "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f002",
              "item_id": null,
              "revenue_key": "rev_consultation",
              "category": "konsultasi",
              "description": "Konsultasi dokter umum",
              "quantity": 1,
              "unit_price": 50000,
              "gross": 50000,
              "discount": 0,
              "total": 50000,
              "payer_share": 0,
              "patient_share": 50000,
              "coverage": "none"
            },
            {
              "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b012",
              "line_no": 2,
              "charge_id": "3f0c2a10-5b7e-4c1d-9a2e-000000009002",
              "service_id": null,
              "item_id": "3f0c2a10-5b7e-4c1d-9a2e-000000001701",
              "revenue_key": "rev_drug",
              "category": "obat",
              "description": "Amoksisilin 500 mg",
              "quantity": 15,
              "unit_price": 3000,
              "gross": 45000,
              "discount": 0,
              "total": 45000,
              "payer_share": 0,
              "patient_share": 45000,
              "coverage": "none"
            }
          ],
          "discounts": [],
          "payments": [
            {
              "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001b101",
              "number": "PAY-202610-00003",
              "method": "qris",
              "amount": 195000,
              "status": "completed",
              "paid_at": "2026-10-29T11:03:10+07:00"
            }
          ]
        }
      },
      "LabOrder": {
        "summary": "Order lab dengan nilai kritis",
        "value": {
          "id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c001",
          "request_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c0a0",
          "number": "LAB-20261029-0001",
          "kind": "lab",
          "status": "final",
          "priority": "cito",
          "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
          "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
          "patient_name": "Pasien Contoh",
          "patient_mrn": "RM-000123",
          "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
          "service_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001f001",
          "service_name": "Darah rutin",
          "practitioner_name": "dr. Rina Contoh",
          "ordered_at": "2026-10-29T09:15:00+07:00",
          "specimen_type": "darah_vena_edta",
          "specimen_collected_at": "2026-10-29T09:25:00+07:00",
          "result_note": "Hb kritis sudah dilaporkan ke dokter",
          "validated_at": "2026-10-29T10:05:00+07:00",
          "finalized_at": "2026-10-29T10:06:00+07:00",
          "has_critical": true,
          "has_abnormal": true,
          "version": 5,
          "results": [
            {
              "parameter_id": "3f0c2a10-5b7e-4c1d-9a2e-00000001c011",
              "code": "718-7",
              "local_code": "HB",
              "loinc_code": "718-7",
              "name": "Hemoglobin",
              "unit": "g/dL",
              "value_type": "numeric",
              "value_num": 6.5,
              "value_text": null,
              "display": "6,5",
              "ref_low": 12,
              "ref_high": 15,
              "ref_text": "12,0 – 15,0",
              "flag": "LL",
              "critical": true,
              "source": "manual",
              "entered_at": "2026-10-29T09:50:00+07:00"
            }
          ]
        }
      }
    }
  }
}
