Files

1353 lines
63 KiB
Markdown

# Flat JSON Bodies & DTO Specifications — SATUSEHAT Service
> Documenting all flat (non-nested) JSON request payloads, validation rules, path/query parameters, and patch request specifications for all **20 FHIR use cases** and **Reference modules** exposed by `service-satusehat`.
>
> **Last updated:** 2026-07-29
---
## 📌 Architecture & Design Conventions
1. **Flat Body Architecture**: API clients submit flat JSON request payloads. Internal mappers translate flat DTO fields into nested FHIR R4 JSON payloads before sending to SATUSEHAT.
2. **Field Conventions**:
- `*_id`: Raw identifier string (e.g. `"patient_id": "P03647103112"`). Mappers generate FHIR references like `"Patient/P03647103112"`.
- `*_name` / `*_display`: Human-readable display text.
- `*_code` + `*_display` + `*_system`: Flat representation of FHIR `CodeableConcept`.
- `*_value` + `*_unit` + `*_system` + `*_code`: Flat representation of FHIR `Quantity`.
3. **Date-Time Formats**:
- ISO-8601 / RFC-3339 format: `2026-05-13T08:00:00+07:00` for all standard `time.Time` fields.
- `Encounter` period uses custom WIB format `YYYY-MM-DD HH:MM:SS` (e.g., `"2026-05-13 08:00:00"`).
4. **Validation Rules (`binding`)**:
- `required`: Mandatory field. Request will return `HTTP 400 Bad Request` (`INVALID_INPUT`) if missing.
- `oneof=...`: Value must be one of the listed enum strings.
5. **Organization ID Injection**: `organization_id` is optional in request bodies. If omitted, the service injects the configured default organisation ID (`cfg.SatuSehat.OrgID`).
6. **Patch Requests**: All FHIR use cases accept `PATCH /satusehat/{resource}/:id` with a JSON body of array of JSON Patch operations (`JSONPatchRequest = []map[string]interface{}`).
---
## 📑 Use Cases (FHIR Resources)
---
### 1. Encounter
- **POST Route:** `/satusehat/encounter`
- **PUT Route:** `/satusehat/encounter/:id`
- **PATCH Route:** `/satusehat/encounter/:id`
- **GET Route:** `/satusehat/encounter/:id` or `/satusehat/encounter`
#### DTO Field Specification (`EncounterRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Faskes |
| `EncounterID` | `encounter_id` | `string` | Optional | ID Kunjungan (jika ditentukan client) |
| `Status` | `status` | `string` | **Required**, `oneof=planned arrived triaged in-progress onleave finished cancelled entered-in-error unknown` | Status kunjungan |
| `Class` | `class` | `string` | **Required**, `oneof=AMB EMER IMP` | Kelas perawatan (AMB=Rawat Jalan, EMER=IGD, IMP=Rawat Inap) |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `PractitionerID` | `practitioner_id` | `string` | Optional | ID Dokter/Tenaga Medis |
| `PractitionerName` | `practitioner_name` | `string` | Optional | Nama dokter |
| `LocationID` | `location_id` | `string` | Optional | ID Lokasi/Poli |
| `LocationName` | `location_name` | `string` | Optional | Nama lokasi |
| `PeriodStart` | `period_start` | `string` (`CustomTime`) | **Required** (`YYYY-MM-DD HH:MM:SS`) | Waktu mulai kunjungan |
| `PeriodEnd` | `period_end` | `string` (`CustomTime`) | Optional (`YYYY-MM-DD HH:MM:SS`) | Waktu selesai kunjungan |
| `DiagnosisConditionID` | `diagnosis_condition_id` | `string` | Optional | ID Condition diagnosis utama |
| `DiagnosisUseSystem` | `diagnosis_use_system` | `string` | Optional | System ICD/Diagnosis Use |
| `DiagnosisUseCode` | `diagnosis_use_code` | `string` | Optional | Kode peranan diagnosis (mis: AD) |
| `DiagnosisUseDisplay` | `diagnosis_use_display` | `string` | Optional | Deskripsi peranan diagnosis |
| `DiagnosisRank` | `diagnosis_rank` | `int` | Optional | Ranking diagnosis (1 = Utama) |
#### Example Request Payload
```json
{
"encounter_id": "ENC-0012345",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"practitioner_id": "N10000001",
"practitioner_name": "Dr. Andi",
"location_id": "a6bab5d0-ba3c-4f73-8450-f44d6ca8e9d4",
"location_name": "Poli Umum",
"status": "arrived",
"class": "AMB",
"period_start": "2026-05-13 08:00:00",
"period_end": "2026-05-13 09:30:00",
"diagnosis_condition_id": "C-0001",
"diagnosis_use_code": "AD",
"diagnosis_use_display": "Admission diagnosis",
"diagnosis_rank": 1
}
```
---
### 2. EpisodeOfCare
- **POST Route:** `/satusehat/episodeofcare`
- **PUT Route:** `/satusehat/episodeofcare/:id`
- **PATCH Route:** `/satusehat/episodeofcare/:id`
#### DTO Field Specification (`EpisodeOfCareRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Pembuat |
| `EpisodeOfCareID` | `episode_of_care_id` | `string` | Optional | ID Episode Perawatan |
| `Status` | `status` | `string` | **Required**, `oneof=planned waitlist active onhold finished cancelled entered-in-error` | Status episode perawatan |
| `TypeSystem` | `type_system` | `string` | Optional | System tipe episode |
| `TypeCode` | `type_code` | `string` | Optional | Kode tipe episode (e.g. HACC) |
| `TypeDisplay` | `type_display` | `string` | Optional | Deskripsi tipe episode |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `ManagingOrganizationID` | `managing_organization_id` | `string` | Optional | ID Organisasi pengelola |
| `PeriodStart` | `period_start` | `time.Time` | Optional (ISO-8601) | Tanggal mulai episode |
| `PeriodEnd` | `period_end` | `time.Time` | Optional (ISO-8601) | Tanggal selesai episode |
| `CareManagerID` | `care_manager_id` | `string` | Optional | ID Dokter/DPJP pengelola |
| `CareManagerName` | `care_manager_name` | `string` | Optional | Nama DPJP |
| `DiagnosisConditionID` | `diagnosis_condition_id` | `string` | Optional | ID Condition diagnosis |
| `DiagnosisRoleSystem` | `diagnosis_role_system` | `string` | Optional | System role diagnosis |
| `DiagnosisRoleCode` | `diagnosis_role_code` | `string` | Optional | Kode role diagnosis |
| `DiagnosisRoleDisplay` | `diagnosis_role_display` | `string` | Optional | Deskripsi role diagnosis |
| `DiagnosisRank` | `diagnosis_rank` | `int` | Optional | Ranking diagnosis |
#### Example Request Payload
```json
{
"episode_of_care_id": "EOC-12345",
"organization_id": "10000004",
"managing_organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"care_manager_id": "N10000001",
"care_manager_name": "Dr. Andi",
"status": "active",
"type_code": "HACC",
"type_display": "Home and Community Care",
"period_start": "2026-05-13T08:00:00+07:00",
"period_end": "2026-08-13T17:00:00+07:00",
"diagnosis_condition_id": "C-0001",
"diagnosis_role_code": "CC",
"diagnosis_role_display": "Chief complaint",
"diagnosis_rank": 1
}
```
---
### 3. Condition
- **POST Route:** `/satusehat/condition`
- **PUT Route:** `/satusehat/condition/:id`
- **PATCH Route:** `/satusehat/condition/:id`
#### DTO Field Specification (`ConditionRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Faskes |
| `ConditionID` | `condition_id` | `string` | Optional | ID Condition |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama Pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan (Encounter) |
| `ClinicalStatus` | `clinical_status` | `string` | **Required**, `oneof=active recurrence relapse inactive remission resolved` | Status klinis diagnosis |
| `CategoryCode` | `category_code` | `string` | Optional | Kode kategori (e.g. encounter-diagnosis) |
| `CategoryDisplay` | `category_display` | `string` | Optional | Deskripsi kategori |
| `CategorySystem` | `category_system` | `string` | Optional | System kategori |
| `CodeSystem` | `code_system` | `string` | Optional | System kode ICD-10 |
| `Code` | `code` | `string` | **Required** | Kode ICD-10 (mis: J06.9) |
| `CodeDisplay` | `code_display` | `string` | Optional | Nama diagnosis ICD-10 |
| `OnsetDateTime` | `onset_date_time` | `time.Time` | Optional (ISO-8601) | Waktu awal mula gejala |
| `RecordedDate` | `recorded_date` | `time.Time` | Optional (ISO-8601) | Tanggal pencatatan |
#### Example Request Payload
```json
{
"condition_id": "COND-9001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"clinical_status": "active",
"category_code": "encounter-diagnosis",
"category_display": "Encounter Diagnosis",
"code_system": "http://hl7.org/fhir/sid/icd-10",
"code": "J06.9",
"code_display": "Acute upper respiratory infection, unspecified",
"onset_date_time": "2026-05-13T08:15:00+07:00",
"recorded_date": "2026-05-13T08:20:00+07:00"
}
```
---
### 4. Observation
- **POST Route:** `/satusehat/observation`
- **PUT Route:** `/satusehat/observation/:id`
- **PATCH Route:** `/satusehat/observation/:id`
#### DTO Field Specification (`ObservationRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Faskes |
| `ObservationID` | `observation_id` | `string` | Optional | ID Hasil Observasi |
| `Status` | `status` | `string` | **Required**, `oneof=registered preliminary final amended corrected cancelled entered-in-error unknown` | Status observasi |
| `CategorySystem` | `category_system` | `string` | Optional | System kategori |
| `CategoryCode` | `category_code` | `string` | **Required** | Kode kategori (mis: vital-signs, laboratory) |
| `CategoryDisplay` | `category_display` | `string` | Optional | Deskripsi kategori |
| `CodeSystem` | `code_system` | `string` | Optional | System LOINC/SNOMED |
| `Code` | `code` | `string` | **Required** | Kode LOINC/SNOMED (mis: 8867-4) |
| `CodeDisplay` | `code_display` | `string` | Optional | Nama pemeriksaan |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama Pasien |
| `EncounterID` | `encounter_id` | `string` | Optional | ID Kunjungan (Encounter) |
| `EffectiveDateTime` | `effective_datetime` | `time.Time` | Optional (ISO-8601) | Waktu observasi dilakukan |
| `Issued` | `issued` | `time.Time` | Optional (ISO-8601) | Waktu hasil dirilis |
| `PerformerID` | `performer_id` | `string` | Optional | ID Pemeriksa (Dokter/Nakes) |
| `PerformerName` | `performer_name` | `string` | Optional | Nama pemeriksa |
| `SpecimenID` | `specimen_id` | `string` | Optional | ID Spesimen terkait |
| `BodySiteSystem` | `body_site_system` | `string` | Optional | System lokasi tubuh |
| `BodySiteCode` | `body_site_code` | `string` | Optional | Kode lokasi tubuh |
| `BodySiteDisplay` | `body_site_display` | `string` | Optional | Nama lokasi tubuh |
| `ValueQuantityValue` | `value_quantity_value` | `float64` | Optional | Angka nilai pengukuran |
| `ValueQuantityUnit` | `value_quantity_unit` | `string` | Optional | Satuan nilai (mis: beats/minute) |
| `ValueQuantitySystem` | `value_quantity_system` | `string` | Optional | System UCUM |
| `ValueQuantityCode` | `value_quantity_code` | `string` | Optional | Kode UCUM (mis: /min) |
| `ValueCodeSystem` | `value_code_system` | `string` | Optional | System nilai kualitatif |
| `ValueCode` | `value_code` | `string` | Optional | Kode nilai kualitatif |
| `ValueCodeDisplay` | `value_code_display` | `string` | Optional | Deskripsi nilai kualitatif |
| `ValueString` | `value_string` | `string` | Optional | Nilai teks observasi |
| `ValueBoolean` | `value_boolean` | `bool` | Optional | Nilai boolean observasi |
| `InterpretationSystem` | `interpretation_system` | `string` | Optional | System interpretasi |
| `InterpretationCode` | `interpretation_code` | `string` | Optional | Kode interpretasi (N, H, L) |
| `InterpretationDisplay` | `interpretation_display` | `string` | Optional | Deskripsi interpretasi |
| `ReferenceRangeLowValue` | `reference_range_low_value` | `float64` | Optional | Nilai batas bawah rujukan |
| `ReferenceRangeHighValue` | `reference_range_high_value` | `float64` | Optional | Nilai batas atas rujukan |
| `ReferenceRangeUnit` | `reference_range_unit` | `string` | Optional | Satuan batas rujukan |
| `ReferenceRangeText` | `reference_range_text` | `string` | Optional | Teks keterangan rujukan |
| `ServiceRequestID` | `service_request_id` | `string` | Optional | ID Order ServiceRequest |
| `ResultObservationIDs` | `result_observation_ids` | `[]string` | Optional | Array ID observasi turunan |
| `ResultObservationSystem` | `result_observation_system` | `[]string` | Optional | Array system observasi turunan |
| `ResultObservationCode` | `result_observation_code` | `[]string` | Optional | Array kode observasi turunan |
| `ResultObservationDisplay` | `result_observation_display` | `[]string` | Optional | Array display observasi turunan |
#### Example Request Payload
```json
{
"observation_id": "OBS-7001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"encounter_id": "ENC-0012345",
"performer_id": "N10000001",
"performer_name": "Dr. Andi",
"status": "final",
"category_code": "vital-signs",
"category_display": "Vital Signs",
"code_system": "http://loinc.org",
"code": "8867-4",
"code_display": "Heart rate",
"effective_datetime": "2026-05-13T08:10:00+07:00",
"issued": "2026-05-13T08:12:00+07:00",
"value_quantity_value": 80,
"value_quantity_unit": "beats/minute",
"value_quantity_system": "http://unitsofmeasure.org",
"value_quantity_code": "/min",
"body_site_code": "40983000",
"body_site_display": "Arm",
"interpretation_code": "N",
"interpretation_display": "Normal",
"reference_range_low_value": 60,
"reference_range_high_value": 100,
"reference_range_unit": "beats/minute",
"reference_range_text": "Normal adult resting heart rate"
}
```
---
### 5. AllergyIntolerance
- **POST Route:** `/satusehat/allergyintolerance`
- **PUT Route:** `/satusehat/allergyintolerance/:id`
- **PATCH Route:** `/satusehat/allergyintolerance/:id`
#### DTO Field Specification (`AllergyIntoleranceRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `AllergyID` | `allergy_id` | `string` | Optional | ID Alergi |
| `ClinicalStatus` | `clinical_status` | `string` | **Required**, `oneof=active inactive resolved` | Status klinis alergi |
| `VerificationStatus` | `verification_status` | `string` | **Required**, `oneof=unconfirmed presumed confirmed refuted entered-in-error` | Status verifikasi alergi |
| `Category` | `category` | `string` | Optional | Kategori (food, medication, environment, biologic) |
| `CodeSystem` | `code_system` | `string` | Optional | System SNOMED CT |
| `Code` | `code` | `string` | **Required** | Kode alergi SNOMED CT |
| `CodeDisplay` | `code_display` | `string` | Optional | Nama zat/alergen |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `EncounterDisplay` | `encounter_display` | `string` | Optional | Deskripsi kunjungan |
| `RecordedDate` | `recorded_date` | `time.Time` | **Required** (ISO-8601) | Tanggal dicatat |
| `RecorderID` | `recorder_id` | `string` | Optional | ID Pencatat (Dokter/Nakes) |
| `RecorderDisplay` | `recorder_display` | `string` | Optional | Nama pencatat |
#### Example Request Payload
```json
{
"allergy_id": "ALG-0001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"encounter_display": "Poli Umum 13 Mei 2026",
"recorder_id": "N10000001",
"recorder_display": "Dr. Andi",
"clinical_status": "active",
"verification_status": "confirmed",
"category": "medication",
"code_system": "http://snomed.info/sct",
"code": "294505008",
"code_display": "Allergy to amoxicillin",
"recorded_date": "2026-05-13T08:25:00+07:00"
}
```
---
### 6. CarePlan
- **POST Route:** `/satusehat/careplan`
- **PUT Route:** `/satusehat/careplan/:id`
- **PATCH Route:** `/satusehat/careplan/:id`
#### DTO Field Specification (`CarePlanRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `CarePlanID` | `care_plan_id` | `string` | Optional | ID Rencana Perawatan |
| `Status` | `status` | `string` | **Required**, `oneof=draft active on-hold revoked completed entered-in-error unknown` | Status rencana perawatan |
| `Intent` | `intent` | `string` | **Required**, `oneof=proposal plan order option` | Niat rencana |
| `CategoryCode` | `category_code` | `string` | Optional | Kode kategori rencana |
| `CategoryDisplay` | `category_display` | `string` | Optional | Deskripsi kategori |
| `CategorySystem` | `category_system` | `string` | Optional | System kategori |
| `Title` | `title` | `string` | Optional | Judul rencana perawatan |
| `Description` | `description` | `string` | Optional | Keterangan/deskripsi rencana |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientDisplay` | `patient_display` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `EncounterDisplay` | `encounter_display` | `string` | Optional | Deskripsi kunjungan |
| `CreatedDate` | `created_date` | `time.Time` | Optional (ISO-8601) | Tanggal pembuat |
| `AuthorID` | `author_id` | `string` | Optional | ID Pembuat (Dokter) |
| `AuthorDisplay` | `author_display` | `string` | Optional | Nama pembuat |
| `GoalIDs` | `goal_ids` | `[]string` | Optional | Array ID sasaran/tujuan perawatan |
#### Example Request Payload
```json
{
"care_plan_id": "CP-0001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_display": "Budi Santoso",
"encounter_id": "ENC-0012345",
"encounter_display": "Poli Umum 13 Mei 2026",
"author_id": "N10000001",
"author_display": "Dr. Andi",
"status": "active",
"intent": "plan",
"category_code": "assess-plan",
"category_display": "Assessment and Plan of Treatment",
"title": "Rencana perawatan ISPA",
"description": "Antibiotik 5 hari, kontrol H+3",
"created_date": "2026-05-13T08:30:00+07:00",
"goal_ids": ["GOAL-001", "GOAL-002"]
}
```
---
### 7. ClinicalImpression
- **POST Route:** `/satusehat/clinicalimpression`
- **PUT Route:** `/satusehat/clinicalimpression/:id`
- **PATCH Route:** `/satusehat/clinicalimpression/:id`
#### DTO Field Specification (`ClinicalImpressionRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `ClinicalImpressionID` | `clinical_impression_id` | `string` | Optional | ID Imresi Klinis |
| `Status` | `status` | `string` | **Required**, `oneof=in-progress completed entered-in-error` | Status impresi |
| `CodeSystem` | `code_system` | `string` | Optional | System kode impresi |
| `Code` | `code` | `string` | Optional | Kode impresi SNOMED CT |
| `CodeDisplay` | `code_display` | `string` | Optional | Deskripsi impresi |
| `Description` | `description` | `string` | Optional | Penjelasan detail |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientDisplay` | `patient_display` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `EncounterDisplay` | `encounter_display` | `string` | Optional | Deskripsi kunjungan |
| `EffectiveDateTime` | `effective_datetime` | `time.Time` | Optional (ISO-8601) | Waktu evaluasi |
| `Date` | `date` | `time.Time` | Optional (ISO-8601) | Tanggal laporan |
| `AssessorID` | `assessor_id` | `string` | Optional | ID Dokter Penilai |
| `AssessorDisplay` | `assessor_display` | `string` | Optional | Nama Dokter Penilai |
| `ProblemConditionIDs` | `problem_condition_ids` | `[]string` | Optional | Array ID Condition masalah |
| `Summary` | `summary` | `string` | Optional | Ringkasan kesimpulan |
| `FindingSystem` | `finding_system` | `string` | Optional | System temuan |
| `FindingCode` | `finding_code` | `string` | Optional | Kode temuan klinis |
| `FindingDisplay` | `finding_display` | `string` | Optional | Deskripsi temuan |
| `PrognosisSystem` | `prognosis_system` | `string` | Optional | System prognosis |
| `PrognosisCode` | `prognosis_code` | `string` | Optional | Kode prognosis |
| `PrognosisDisplay` | `prognosis_display` | `string` | Optional | Deskripsi prognosis |
#### Example Request Payload
```json
{
"clinical_impression_id": "CI-0001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_display": "Budi Santoso",
"encounter_id": "ENC-0012345",
"encounter_display": "Poli Umum 13 Mei 2026",
"assessor_id": "N10000001",
"assessor_display": "Dr. Andi",
"status": "completed",
"code_system": "http://snomed.info/sct",
"code": "162673000",
"code_display": "General examination of patient",
"description": "Pasien sadar, demam, batuk produktif",
"effective_datetime": "2026-05-13T08:35:00+07:00",
"date": "2026-05-13T08:40:00+07:00",
"summary": "ISPA non-pneumonia",
"problem_condition_ids": ["COND-9001"],
"finding_code": "386661006",
"finding_display": "Fever",
"prognosis_code": "170968001",
"prognosis_display": "Prognosis good"
}
```
---
### 8. Composition
- **POST Route:** `/satusehat/composition`
- **PUT Route:** `/satusehat/composition/:id`
- **PATCH Route:** `/satusehat/composition/:id`
#### DTO Field Specification (`CompositionRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `CompositionID` | `composition_id` | `string` | Optional | ID Dokumen Komposisi |
| `Status` | `status` | `string` | **Required**, `oneof=preliminary final amended entered-in-error` | Status komposisi |
| `TypeSystem` | `type_system` | `string` | Optional | System tipe dokumen |
| `TypeCode` | `type_code` | `string` | **Required** | Kode tipe dokumen (LOINC) |
| `TypeDisplay` | `type_display` | `string` | Optional | Nama tipe dokumen |
| `CategorySystem` | `category_system` | `string` | Optional | System kategori |
| `CategoryCode` | `category_code` | `string` | Optional | Kode kategori |
| `CategoryDisplay` | `category_display` | `string` | Optional | Nama kategori |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientDisplay` | `patient_display` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `EncounterDisplay` | `encounter_display` | `string` | Optional | Deskripsi kunjungan |
| `Date` | `date` | `time.Time` | **Required** (ISO-8601) | Tanggal dokumen |
| `AuthorID` | `author_id` | `string` | **Required** | ID Penulis / Dokter |
| `AuthorDisplay` | `author_display` | `string` | Optional | Nama Penulis |
| `Title` | `title` | `string` | **Required** | Judul dokumen medis |
| `SectionTitle` | `section_title` | `string` | Optional | Judul bagian |
| `SectionSystem` | `section_system` | `string` | Optional | System kode bagian |
| `SectionCode` | `section_code` | `string` | Optional | Kode LOINC bagian |
| `SectionDisplay` | `section_display` | `string` | Optional | Nama bagian |
| `SectionText` | `section_text` | `string` | Optional | Isi narasi bagian |
#### Example Request Payload
```json
{
"composition_id": "COMP-0001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_display": "Budi Santoso",
"encounter_id": "ENC-0012345",
"encounter_display": "Poli Umum 13 Mei 2026",
"author_id": "N10000001",
"author_display": "Dr. Andi",
"status": "final",
"type_system": "http://loinc.org",
"type_code": "11488-4",
"type_display": "Consult note",
"category_code": "LP173421-1",
"category_display": "Report",
"title": "Catatan Konsultasi Poli Umum",
"date": "2026-05-13T09:00:00+07:00",
"section_title": "Anamnesis & Pemeriksaan",
"section_code": "55109-3",
"section_display": "Reason for visit Narrative",
"section_text": "Pasien datang dengan keluhan batuk dan demam selama 3 hari."
}
```
---
### 9. DiagnosticReport
- **POST Route:** `/satusehat/diagnosticreport`
- **PUT Route:** `/satusehat/diagnosticreport/:id`
- **PATCH Route:** `/satusehat/diagnosticreport/:id`
#### DTO Field Specification (`DiagnosticReportRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Faskes |
| `DiagnosticID` | `diagnostic_id` | `string` | Optional | ID Laporan Diagnostik |
| `Status` | `status` | `string` | **Required**, `oneof=registered partial preliminary final amended corrected appended cancelled entered-in-error unknown` | Status laporan |
| `CategorySystem` | `category_system` | `string` | Optional | System kategori |
| `CategoryCode` | `category_code` | `string` | Optional | Kode kategori (LAB, RAD) |
| `CategoryDisplay` | `category_display` | `string` | Optional | Deskripsi kategori |
| `CodeSystem` | `code_system` | `string` | Optional | System LOINC |
| `Code` | `code` | `string` | **Required** | Kode panel LOINC |
| `CodeDisplay` | `code_display` | `string` | Optional | Nama panel pemeriksaan |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `EffectiveDateTime` | `effective_datetime` | `time.Time` | Optional (ISO-8601) | Waktu efektif pemeriksaan |
| `Issued` | `issued` | `time.Time` | Optional (ISO-8601) | Waktu hasil rilis |
| `PerformerID` | `performer_id` | `string` | Optional | ID Pemeriksa (Dokter/Lab) |
| `PerformerName` | `performer_name` | `string` | Optional | Nama pemeriksa |
| `ResultObservationIDs` | `result_observation_ids` | `[]string` | Optional | Array ID Observation hasil |
| `ResultObservationSystem` | `result_observation_system` | `[]string` | Optional | Array system Observation |
| `ResultObservationCode` | `result_observation_code` | `[]string` | Optional | Array kode Observation |
| `ResultObservationDisplay` | `result_observation_display` | `[]string` | Optional | Array display Observation |
| `SpecimenIDs` | `specimen_ids` | `[]string` | Optional | Array ID Specimen |
| `BasedOnIDs` | `based_on_service_request_ids` | `[]string` | Optional | Array ID ServiceRequest perujuk |
| `ImagingStudyIDs` | `imaging_study_ids` | `[]string` | Optional | Array ID ImagingStudy terkait |
| `ConclusionCode` | `conclusion_code` | `string` | Optional | Kode SNOMED kesimpulan |
| `ConclusionCodeDisplay` | `conclusion_code_display` | `string` | Optional | Deskripsi kode kesimpulan |
| `Conclusion` | `conclusion` | `string` | Optional | Teks kesimpulan / narasi hasil |
#### Example Request Payload
```json
{
"diagnostic_id": "DR-5001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"encounter_id": "ENC-0012345",
"performer_id": "N10000001",
"performer_name": "Dr. Andi",
"status": "final",
"category_code": "LAB",
"category_display": "Laboratory",
"code_system": "http://loinc.org",
"code": "58410-2",
"code_display": "Complete blood count (hemogram) panel",
"effective_datetime": "2026-05-13T09:10:00+07:00",
"issued": "2026-05-13T09:30:00+07:00",
"result_observation_ids": ["OBS-7001", "OBS-7002"],
"specimen_ids": ["SPC-3001"],
"imaging_study_ids": [],
"conclusion_code": "162673000",
"conclusion_display": "General examination of patient",
"conclusion": "Hasil dalam batas normal"
}
```
---
### 10. ImagingStudy
- **POST Route:** `/satusehat/imagingstudy`
- **PUT Route:** `/satusehat/imagingstudy/:id`
- **PATCH Route:** `/satusehat/imagingstudy/:id`
#### DTO Field Specification (`ImagingStudyRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `AccessionNumber` | `accession_number` | `string` | Optional | Nomor Aksesi Radiologi |
| `ServiceRequestID` | `service_request_id` | `string` | Optional | ID Order ServiceRequest |
| `PatientID` | `patient_id` | `string` | Optional | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | Optional | ID Kunjungan |
| `PractitionerID` | `practitioner_id` | `string` | Optional | ID Radiolog/Dokter |
| `PractitionerName` | `practitioner_name` | `string` | Optional | Nama Dokter |
| `Status` | `status` | `string` | Optional (`registered, available, cancelled, entered-in-error, unknown`) | Status studi radiologi |
| `Started` | `started` | `time.Time` | Optional (ISO-8601) | Waktu studi dimulai |
| `NumberOfSeries` | `number_of_series` | `int` | Optional | Jumlah seri gambar |
| `NumberOfInstances` | `number_of_instances` | `int` | Optional | Jumlah total file citra (frame/instance) |
| `ProcedureCode` | `procedure_code` | `string` | Optional | Kode prosedur SNOMED CT |
| `ProcedureDisplay` | `procedure_display` | `string` | Optional | Deskripsi prosedur |
| `Description` | `description` | `string` | Optional | Deskripsi studi |
#### Example Request Payload
```json
{
"accession_number": "ACC-0001",
"organization_id": "10000004",
"service_request_id": "SR-0001",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"practitioner_id": "N10000001",
"practitioner_name": "Dr. Andi",
"status": "available",
"started": "2026-05-13T09:00:00+07:00",
"number_of_series": 1,
"number_of_instances": 24,
"procedure_code": "168731009",
"procedure_display": "Chest X-ray",
"description": "Thorax PA"
}
```
---
### 11. Immunization
- **POST Route:** `/satusehat/immunization`
- **PUT Route:** `/satusehat/immunization/:id`
- **PATCH Route:** `/satusehat/immunization/:id`
#### DTO Field Specification (`ImmunizationRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Faskes |
| `ImmunizationID` | `immunization_id` | `string` | Optional | ID Imunisasi |
| `Status` | `status` | `string` | **Required**, `oneof=completed entered-in-error not-done` | Status pemberian imunisasi |
| `VaccineCodeSystem` | `vaccine_code_system` | `string` | Optional | System Kemenkes Vaccine |
| `VaccineCode` | `vaccine_code` | `string` | **Required** | Kode vaksin KFA/Kemenkes |
| `VaccineCodeDisplay` | `vaccine_display` | `string` | Optional | Nama merk/jenis vaksin |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `EncounterDisplay` | `encounter_display` | `string` | Optional | Deskripsi kunjungan |
| `OccurrenceDateTime` | `occurrence_date_time` | `time.Time` | Optional (ISO-8601) | Waktu penyuntikan vaksin |
| `PrimarySource` | `primary_source` | `bool` | Optional | Apakah sumber data primer (true/false) |
| `LotNumber` | `lot_number` | `string` | Optional | Nomor batch/lot vaksin |
| `PerformerID` | `performer_id` | `string` | Optional | ID Vaksinator (Nakes) |
| `PerformerName` | `performer_name` | `string` | Optional | Nama Vaksinator |
| `LocationID` | `location_id` | `string` | Optional | ID Lokasi penyuntikan |
| `LocationName` | `location_name` | `string` | Optional | Nama lokasi |
| `DoseQuantityValue` | `dose_quantity_value` | `float64` | Optional | Dosis (angka) |
| `DoseQuantityUnit` | `dose_quantity_unit` | `string` | Optional | Satuan dosis (mis: mL) |
| `RouteCode` | `route_code` | `string` | Optional | Kode rute pemberian (mis: IM) |
| `RouteDisplay` | `route_display` | `string` | Optional | Nama rute (Intramuscular) |
#### Example Request Payload
```json
{
"immunization_id": "IMM-0001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"encounter_display": "Poli Umum 13 Mei 2026",
"performer_id": "N10000001",
"performer_name": "Dr. Andi",
"location_id": "a6bab5d0-ba3c-4f73-8450-f44d6ca8e9d4",
"location_name": "Poli Umum",
"status": "completed",
"vaccine_code_system": "http://sys-ids.kemkes.go.id/vaccine",
"vaccine_code": "1010101010",
"vaccine_display": "Sinovac",
"occurrence_date_time": "2026-05-13T09:05:00+07:00",
"primary_source": true,
"lot_number": "BATCH-XYZ-2026-001",
"dose_quantity_value": 0.5,
"dose_quantity_unit": "mL",
"dose_quantity_system": "http://unitsofmeasure.org",
"dose_quantity_code": "mL",
"route_code": "IM",
"route_display": "Intramuscular"
}
```
---
### 12. Medication
- **POST Route:** `/satusehat/medication`
- **PUT Route:** `/satusehat/medication/:id`
- **PATCH Route:** `/satusehat/medication/:id`
#### DTO Field Specification (`MedicationRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `MedicationID` | `medication_id` | `string` | Optional | ID Obat |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Pembuat |
| `StatusCode` | `status_code` | `string` | **Required**, `oneof=active inactive entered-in-error` | Status master obat |
| `KfaCode` | `kfa_code` | `string` | **Required** | Kode KFA (Kamus Farmasi dan Alat Kesehatan) |
| `KfaDisplay` | `kfa_display` | `string` | Optional | Nama master obat KFA |
| `FormCode` | `form_code` | `string` | Optional | Kode bentuk sediaan (mis: TAB) |
| `FormDisplay` | `form_display` | `string` | Optional | Nama bentuk sediaan (Tablet) |
| `ManufacturerID` | `manufacturer_id` | `string` | Optional | ID Organisasi Pabrik / Distributor |
| `BatchNumber` | `batch_number` | `string` | Optional | Nomor batch produksi |
| `ExpirationDate` | `expiration_date` | `time.Time` | Optional (ISO-8601) | Tanggal kedaluwarsa |
#### Example Request Payload
```json
{
"medication_id": "MED-0001",
"organization_id": "10000004",
"manufacturer_id": "100099999",
"status_code": "active",
"kfa_code": "92000001",
"kfa_display": "Paracetamol 500 mg tablet",
"form_code": "TAB",
"form_display": "Tablet",
"batch_number": "BTC-XYZ-2026-09",
"expiration_date": "2027-12-31T00:00:00+07:00"
}
```
---
### 13. MedicationDispense
- **POST Route:** `/satusehat/medicationdispense`
- **PUT Route:** `/satusehat/medicationdispense/:id`
- **PATCH Route:** `/satusehat/medicationdispense/:id`
#### DTO Field Specification (`MedicationDispenseRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Faskes |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `MedicationID` | `medication_id` | `string` | **Required** | ID Master Obat Medication |
| `MedicationDisplay` | `medication_display` | `string` | Optional | Nama obat |
| `PractitionerID` | `practitioner_id` | `string` | **Required** | ID Apoteker / Petugas Farmasi |
| `PractitionerName` | `practitioner_name` | `string` | Optional | Nama Apoteker |
| `LocationID` | `location_id` | `string` | **Required** | ID Apotek/Depo Farmasi |
| `LocationName` | `location_name` | `string` | Optional | Nama depo farmasi |
| `PrescriptionID` | `prescription_id` | `string` | **Required** | Nomor Resep (Prescription Identifier) |
| `PrescriptionItemID` | `prescription_item_id` | `string` | Optional | Identifier item resep |
| `Status` | `status` | `string` | **Required**, `oneof=preparation in-progress cancelled on-hold completed entered-in-error stopped declined unknown` | Status penyerahan obat |
| `Category` | `category` | `string` | Optional, `oneof=outpatient inpatient community discharge` | Kategori penyerahan |
| `PreparedDate` | `prepared_date` | `time.Time` | **Required** (ISO-8601) | Waktu obat disiapkan |
| `HandedOverDate` | `handed_over_date` | `time.Time` | **Required** (ISO-8601) | Waktu obat diserahkan ke pasien |
| `QuantityValue` | `quantity_value` | `float64` | **Required** | Jumlah total obat yang diserahkan |
| `QuantityUnit` | `quantity_unit` | `string` | **Required** | Satuan jumlah (mis: TAB) |
| `DaysSupplyValue` | `days_supply_value` | `int` | Optional | Estimasi hari konsumsi obat |
| `DosageText` | `dosage_text` | `string` | Optional | Aturan pakai (mis: 3x1 sehari) |
| `TimingFrequency` | `timing_frequency` | `int` | Optional | Frekuensi (mis: 3) |
| `TimingPeriod` | `timing_period` | `int` | Optional | Periode (mis: 1) |
| `TimingPeriodUnit` | `timing_period_unit` | `string` | Optional | Satuan periode (d=hari, h=jam) |
| `DoseQuantityValue` | `dose_quantity_value` | `float64` | Optional | Dosis per sekali minum (mis: 1) |
| `DoseQuantityUnit` | `dose_quantity_unit` | `string` | Optional | Satuan dosis per minum (TAB) |
| `MedicationRequestID` | `medication_request_id` | `string` | **Required** | ID Resource MedicationRequest pendukung |
#### Example Request Payload
```json
{
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"practitioner_id": "N10000001",
"practitioner_name": "Apt. Sari",
"location_id": "a6bab5d0-ba3c-4f73-8450-f44d6ca8e9d4",
"location_name": "Apotek Rawat Jalan",
"medication_id": "MED-0001",
"medication_display": "Paracetamol 500 mg tablet",
"medication_request_id": "MR-0001",
"prescription_id": "RX-2026-000123",
"prescription_item_id": "RX-2026-000123-1",
"status": "completed",
"category": "outpatient",
"prepared_date": "2026-05-13T09:40:00+07:00",
"handed_over_date": "2026-05-13T09:45:00+07:00",
"quantity_value": 10,
"quantity_unit": "TAB",
"days_supply_value": 5,
"dosage_text": "1 tablet, 3x sehari sesudah makan",
"timing_frequency": 3,
"timing_period": 1,
"timing_period_unit": "d",
"dose_quantity_value": 1,
"dose_quantity_unit": "TAB"
}
```
---
### 14. MedicationRequest
- **POST Route:** `/satusehat/medicationrequest`
- **PUT Route:** `/satusehat/medicationrequest/:id`
- **PATCH Route:** `/satusehat/medicationrequest/:id`
#### DTO Field Specification (`MedicationRequestRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `MedicationRequestID` | `medicationrequest_id` | `string` | Optional | ID Resep Dokter |
| `PrescriptionItemID` | `prescription_item_id` | `string` | Optional | ID item resep |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi Faskes |
| `Category` | `category` | `string` | Optional, `oneof=outpatient inpatient community discharge` | Kategori resep |
| `Priority` | `priority` | `string` | Optional, `oneof=routine urgent asap stat` | Prioritas permintaan |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | **Required** | ID Kunjungan |
| `PractitionerID` | `practitioner_id` | `string` | **Required** | ID Dokter Resep |
| `PractitionerName` | `practitioner_name` | `string` | Optional | Nama Dokter |
| `MedicationID` | `medication_id` | `string` | **Required** | ID Master Medication |
| `MedicationDisplay` | `medication_display` | `string` | Optional | Nama obat |
| `ReasonCode` | `reason_code` | `string` | Optional | Kode ICD-10 indikasi resep |
| `ReasonDisplay` | `reason_display` | `string` | Optional | Deskripsi indikasi resep |
| `CourseOfTherapyCode` | `course_of_therapy_code` | `string` | Optional | Kode alur terapi (acute, continuous) |
| `CourseOfTherapyDisplay` | `course_of_therapy_display` | `string` | Optional | Nama alur terapi |
| `Status` | `status` | `string` | **Required**, `oneof=active on-hold cancelled completed entered-in-error stopped draft unknown` | Status permintaan resep |
| `Intent` | `intent` | `string` | **Required**, `oneof=proposal plan order original-order reflex-order filler-order instance-order option` | Niat peresepan (order) |
| `AuthoredOn` | `authored_on` | `time.Time` | **Required** (ISO-8601) | Waktu resep dibuat dokter |
| `DosageText` | `dosage_text` | `string` | Optional | Aturan pakai obat |
| `AdditionalInstruction` | `additional_instruction` | `string` | Optional | Instruksi tambahan farmasi |
| `PatientInstr` | `patient_instruction` | `string` | Optional | Petunjuk khusus untuk pasien |
| `TimingFrequency` | `timing_frequency` | `int` | Optional | Frekuensi minum |
| `TimingPeriod` | `timing_period` | `int` | Optional | Periode minum |
| `TimingPeriodUnit` | `timing_period_unit` | `string` | Optional | Satuan periode (d=hari, h=jam) |
| `RouteCode` | `route_code` | `string` | Optional | Kode rute (mis: O = Oral) |
| `RouteDisplay` | `route_display` | `string` | Optional | Nama rute pemberian |
| `DoseQuantityValue` | `dose_quantity_value` | `float64` | Optional | Dosis per minum |
| `DoseQuantityUnit` | `dose_quantity_unit` | `string` | Optional | Satuan dosis (TAB, CAP) |
| `DispenseInterval` | `dispense_interval` | `int` | Optional | Interval penyerahan |
| `DispenseValue` | `dispense_value` | `float64` | Optional | Jumlah total yang diresepkan |
| `DispenseUnit` | `dispense_unit` | `string` | Optional | Satuan penyerahan |
| `SupplyDuration` | `supply_duration` | `int` | Optional | Durasi pemberian (dalam hari) |
| `ValidityPeriodStart` | `validity_period_start` | `time.Time` | Optional (ISO-8601) | Masa berlaku resep mulai |
| `ValidityPeriodEnd` | `validity_period_end` | `time.Time` | Optional (ISO-8601) | Masa berlaku resep selesai |
#### Example Request Payload
```json
{
"medicationrequest_id": "MR-0001",
"prescription_item_id": "RX-2026-000123-1",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"practitioner_id": "N10000001",
"practitioner_name": "Dr. Andi",
"medication_id": "MED-0001",
"medication_display": "Paracetamol 500 mg tablet",
"category": "outpatient",
"priority": "routine",
"status": "active",
"intent": "order",
"authored_on": "2026-05-13T09:35:00+07:00",
"reason_code": "J06.9",
"reason_display": "Acute upper respiratory infection",
"course_of_therapy_code": "acute",
"course_of_therapy_display": "Short course (acute) therapy",
"dosage_text": "1 tablet, 3x sehari sesudah makan",
"additional_instruction": "Habiskan",
"patient_instruction": "Minum dengan air putih",
"timing_frequency": 3,
"timing_period": 1,
"timing_period_unit": "d",
"route_code": "O",
"route_display": "Oral",
"dose_quantity_value": 1,
"dose_quantity_unit": "TAB",
"dispense_interval": 0,
"dispense_value": 15,
"dispense_unit": "TAB",
"supply_duration": 5,
"validity_period_start": "2026-05-13T09:35:00+07:00",
"validity_period_end": "2026-05-20T23:59:59+07:00"
}
```
---
### 15. MedicationStatement
- **POST Route:** `/satusehat/medicationstatement`
- **PUT Route:** `/satusehat/medicationstatement/:id`
- **PATCH Route:** `/satusehat/medicationstatement/:id`
#### DTO Field Specification (`MedicationStatementRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `StatementID` | `statement_id` | `string` | Optional | ID Pernyataan Konsumsi Obat |
| `Status` | `status` | `string` | **Required**, `oneof=active completed entered-in-error intended stopped on-hold unknown not-taken` | Status konsumsi obat |
| `CategorySystem` | `category_system` | `string` | Optional | System kategori |
| `CategoryCode` | `category_code` | `string` | Optional | Kode kategori (mis: outpatient) |
| `CategoryDisplay` | `category_display` | `string` | Optional | Deskripsi kategori |
| `MedicationCodeSystem` | `medication_code_system` | `string` | Optional | System kode obat (KFA) |
| `MedicationCode` | `medication_code` | `string` | **Required** | Kode obat KFA |
| `MedicationDisplay` | `medication_display` | `string` | Optional | Nama obat |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | Optional | ID Kunjungan |
| `EffectiveDateTime` | `effective_date_time` | `time.Time` | Optional (ISO-8601) | Waktu konsumsi obat |
| `DateAsserted` | `date_asserted` | `time.Time` | Optional (ISO-8601) | Tanggal klaim/pernyataan |
| `InformationSourceID` | `information_source_id` | `string` | Optional | ID Sumber informasi (Pasien/Kelurga) |
| `InformationSourceName` | `information_source_name` | `string` | Optional | Nama sumber informasi |
| `InformationSourceType` | `information_source_type` | `string` | Optional (default: `Patient`) | Tipe sumber informasi |
| `DosageText` | `dosage_text` | `string` | Optional | Aturan pakai |
| `DosagePatientInstruction` | `dosage_patient_instruction` | `string` | Optional | Petunjuk pasien |
| `DosageRouteSystem` | `dosage_route_system` | `string` | Optional | System rute |
| `DosageRouteCode` | `dosage_route_code` | `string` | Optional | Kode rute (O) |
| `DosageRouteDisplay` | `dosage_route_display` | `string` | Optional | Nama rute (Oral) |
| `DoseQuantityValue` | `dose_quantity_value` | `float64` | Optional | Dosis per minum |
| `DoseQuantityUnit` | `dose_quantity_unit` | `string` | Optional | Satuan dosis |
#### Example Request Payload
```json
{
"statement_id": "MS-0001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"information_source_id": "P03647103112",
"information_source_name": "Budi Santoso",
"status": "active",
"category_code": "outpatient",
"category_display": "Outpatient",
"medication_code_system": "http://sys-ids.kemkes.go.id/kfa",
"medication_code": "92000001",
"medication_display": "Paracetamol 500 mg tablet",
"effective_date_time": "2026-05-13T09:35:00+07:00",
"date_asserted": "2026-05-13T09:36:00+07:00",
"dosage_text": "1 tablet, 3x sehari sesudah makan",
"dosage_patient_instruction": "Minum dengan air putih",
"dosage_route_code": "O",
"dosage_route_display": "Oral",
"dose_quantity_value": 1,
"dose_quantity_unit": "TAB"
}
```
---
### 16. Procedure
- **POST Route:** `/satusehat/procedure`
- **PUT Route:** `/satusehat/procedure/:id`
- **PATCH Route:** `/satusehat/procedure/:id`
#### DTO Field Specification (`ProcedureRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `ProcedureID` | `procedure_id` | `string` | Optional | ID Tindakan Medis |
| `Status` | `status` | `string` | **Required**, `oneof=preparation in-progress not-done on-hold stopped completed entered-in-error unknown` | Status tindakan |
| `CategoryCode` | `category_code` | `string` | Optional | Kode kategori tindakan |
| `CategoryDisplay` | `category_display` | `string` | Optional | Deskripsi kategori |
| `CategorySystem` | `category_system` | `string` | Optional | System kategori |
| `CodeSystem` | `code_system` | `string` | Optional | System ICD-9-CM / SNOMED |
| `Code` | `code` | `string` | **Required** | Kode tindakan (mis: 89.61) |
| `CodeDisplay` | `code_display` | `string` | Optional | Nama tindakan |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | Optional | ID Kunjungan |
| `EncounterDisplay` | `encounter_display` | `string` | Optional | Deskripsi kunjungan |
| `PerformedDateTime` | `performed_date_time` | `time.Time` | Optional (ISO-8601) | Waktu pelaksanaan tindakan |
| `PerformedStart` | `performed_start` | `time.Time` | Optional (ISO-8601) | Waktu mulai tindakan |
| `PerformedEnd` | `performed_end` | `time.Time` | Optional (ISO-8601) | Waktu selesai tindakan |
| `PerformerID` | `performer_id` | `string` | Optional | ID Pelaksana (Dokter/Perawat) |
| `PerformerName` | `performer_name` | `string` | Optional | Nama Pelaksana |
| `ReasonCode` | `reason_code` | `string` | Optional | Kode alasan tindakan (ICD-10) |
| `ReasonDisplay` | `reason_display` | `string` | Optional | Deskripsi alasan tindakan |
| `BodySiteCode` | `body_site_code` | `string` | Optional | Kode lokasi tubuh SNOMED |
| `BodySiteDisplay` | `body_site_display` | `string` | Optional | Nama lokasi tubuh |
| `Note` | `note` | `string` | Optional | Catatan tindakan |
#### Example Request Payload
```json
{
"procedure_id": "PROC-0001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"encounter_id": "ENC-0012345",
"performer_id": "N10000001",
"performer_name": "Dr. Andi",
"status": "completed",
"category_code": "103693007",
"category_display": "Diagnostic procedure",
"code_system": "http://hl7.org/fhir/sid/icd-9-cm",
"code": "89.61",
"code_display": "Continuous blood gas monitoring",
"performed_date_time": "2026-05-13T09:15:00+07:00",
"performed_start": "2026-05-13T09:15:00+07:00",
"performed_end": "2026-05-13T09:25:00+07:00",
"reason_code": "J06.9",
"reason_display": "Acute upper respiratory infection",
"body_site_code": "302551006",
"body_site_display": "Entire thorax",
"note": "Pasien kooperatif, prosedur selesai tanpa komplikasi"
}
```
---
### 17. QuestionnaireResponse
- **POST Route:** `/satusehat/questionnaireresponse`
- **PUT Route:** `/satusehat/questionnaireresponse/:id`
- **PATCH Route:** `/satusehat/questionnaireresponse/:id`
#### DTO Field Specification (`QuestionnaireResponseRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `QuestionnaireResponseID` | `questionnaire_response_id` | `string` | Optional | ID Jawaban Kuesioner |
| `QuestionnaireURL` | `questionnaire_url` | `string` | **Required** | URL template Kuesioner Kemenkes |
| `Status` | `status` | `string` | **Required**, `oneof=in-progress completed amended entered-in-error stopped` | Status pengisian |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | Optional | ID Kunjungan |
| `EncounterDisplay` | `encounter_display` | `string` | Optional | Deskripsi kunjungan |
| `AuthorID` | `author_id` | `string` | Optional | ID Pengisi (Dokter/Nakes) |
| `AuthorName` | `author_name` | `string` | Optional | Nama Pengisi |
| `AuthorType` | `author_type` | `string` | Optional (default: `Practitioner`) | Tipe Pengisi |
| `SourceID` | `source_id` | `string` | Optional | ID Sumber informasi |
| `SourceName` | `source_name` | `string` | Optional | Nama Sumber |
| `SourceType` | `source_type` | `string` | Optional (default: `Patient`) | Tipe Sumber |
| `Authored` | `authored` | `time.Time` | **Required** (ISO-8601) | Waktu kuesioner diisi |
| `Items` | `items` | `[]ItemDTO` | **Required**, `min=1` | Array butir pertanyaan dan jawaban |
#### ItemDTO Field Details (`items[]`)
Setiap elemen dalam `items` wajib menentukan **satu** field jawaban (`answer_*`):
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `LinkID` | `link_id` | `string` | **Required** | ID pertanyaan dalam kuesioner |
| `Text` | `text` | `string` | Optional | Teks pertanyaan |
| `AnswerBoolean` | `answer_boolean` | `*bool` | Optional | Jawaban berupa true/false |
| `AnswerString` | `answer_string` | `string` | Optional | Jawaban berupa teks |
| `AnswerInteger` | `answer_integer` | `*int` | Optional | Jawaban berupa angka bulat |
| `AnswerDecimal` | `answer_decimal` | `*float64` | Optional | Jawaban berupa desimal |
| `AnswerDate` | `answer_date` | `*time.Time` | Optional | Jawaban tanggal |
| `AnswerDateTime` | `answer_datetime` | `*time.Time` | Optional | Jawaban tanggal & waktu |
| `AnswerQuantityValue` | `answer_quantity_value` | `*float64` | Optional | Nilai besaran (mis: 38.2) |
| `AnswerQuantityUnit` | `answer_quantity_unit` | `string` | Optional | Satuan besaran (mis: Cel) |
| `AnswerQuantitySystem` | `answer_quantity_system` | `string` | Optional | System UCUM |
| `AnswerQuantityCode` | `answer_quantity_code` | `string` | Optional | Kode UCUM |
| `AnswerCodingSystem` | `answer_coding_system` | `string` | Optional | System pilihan kode |
| `AnswerCodingCode` | `answer_coding_code` | `string` | Optional | Kode pilihan |
| `AnswerCodingDisplay` | `answer_coding_display` | `string` | Optional | Deskripsi pilihan |
#### Example Request Payload
```json
{
"questionnaire_response_id": "QR-0001",
"organization_id": "10000004",
"questionnaire_url": "https://fhir.kemkes.go.id/Questionnaire/Q0007",
"patient_id": "P03647103112",
"encounter_id": "ENC-0012345",
"author_id": "N10000001",
"author_name": "Dr. Andi",
"source_id": "P03647103112",
"source_name": "Budi Santoso",
"status": "completed",
"authored": "2026-05-13T09:00:00+07:00",
"items": [
{
"link_id": "1",
"text": "Apakah Anda merokok?",
"answer_boolean": false
},
{
"link_id": "2",
"text": "Berapa suhu tubuh Anda hari ini?",
"answer_quantity_value": 38.2,
"answer_quantity_unit": "Cel"
}
]
}
```
---
### 18. ServiceRequest
- **POST Route:** `/satusehat/servicerequest`
- **PUT Route:** `/satusehat/servicerequest/:id`
- **PATCH Route:** `/satusehat/servicerequest/:id`
#### DTO Field Specification (`ServiceRequestRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `ServiceRequestID` | `service_request_id` | `string` | Optional | ID Order Permintaan Layanan |
| `PatientID` | `patient_id` | `string` | Optional | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `EncounterID` | `encounter_id` | `string` | Optional | ID Kunjungan |
| `RequesterID` | `requester_id` | `string` | Optional | ID Dokter peminta order |
| `RequesterName` | `requester_name` | `string` | Optional | Nama Dokter peminta |
| `PerformerID` | `performer_id` | `string` | Optional | ID Unit pelaksana (mis: Lab/Rad) |
| `PerformerName` | `performer_name` | `string` | Optional | Nama Unit pelaksana |
| `Status` | `status` | `string` | Optional, `oneof=draft active on-hold revoked completed entered-in-error unknown` | Status order permintaan |
| `Intent` | `intent` | `string` | Optional, `oneof=proposal plan directive order original-order reflex-order filler-order instance-order option` | Niat permintaan (order) |
| `Code` | `code` | `string` | Optional | Kode pemeriksaan LOINC/SNOMED |
| `System` | `system` | `string` | Optional | System LOINC |
| `Display` | `display` | `string` | Optional | Nama jenis pemeriksaan yang diminta |
| `AuthoredOn` | `authored_on` | `time.Time` | Optional (ISO-8601) | Waktu order dibuat |
#### Example Request Payload
```json
{
"organization_id": "10000004",
"patient_id": "P03647103112",
"patient_name": "Budi Santoso",
"encounter_id": "ENC-0012345",
"requester_id": "N10000001",
"requester_name": "Dr. Andi",
"performer_id": "N10000099",
"performer_name": "Lab Pathology Unit",
"status": "active",
"intent": "order",
"code": "58410-2",
"display": "Complete blood count panel",
"authored_on": "2026-05-13T09:05:00+07:00"
}
```
---
### 19. Specimen
- **POST Route:** `/satusehat/specimen`
- **PUT Route:** `/satusehat/specimen/:id`
- **PATCH Route:** `/satusehat/specimen/:id`
#### DTO Field Specification (`SpecimenRequest`)
| Field Name | JSON Key | Data Type | Validation / Binding | Description |
| --- | --- | --- | --- | --- |
| `OrganizationID` | `organization_id` | `string` | Optional | ID Organisasi |
| `SpecimenID` | `specimen_id` | `string` | Optional | ID Spesimen |
| `Status` | `status` | `string` | **Required**, `oneof=available unavailable unsatisfactory entered-in-error` | Status kelayakan spesimen |
| `TypeSystem` | `type_system` | `string` | Optional | System tipe spesimen |
| `TypeCode` | `type_code` | `string` | **Required** | Kode tipe spesimen (mis: BLD = Darah) |
| `TypeDisplay` | `type_display` | `string` | Optional | Nama tipe spesimen |
| `PatientID` | `patient_id` | `string` | **Required** | ID Pasien Satu Sehat |
| `PatientName` | `patient_name` | `string` | Optional | Nama pasien |
| `ReceivedDateTime` | `received_date_time` | `time.Time` | Optional (ISO-8601) | Waktu spesimen diterima lab |
| `CollectedDateTime` | `collected_date_time` | `time.Time` | Optional (ISO-8601) | Waktu sampel diambil |
| `CollectorID` | `collector_id` | `string` | Optional | ID Petugas pengambil |
| `CollectorName` | `collector_name` | `string` | Optional | Nama petugas |
| `CollectionQuantityValue` | `collection_quantity_value` | `float64` | Optional | Volume/jumlah spesimen |
| `CollectionQuantityUnit` | `collection_quantity_unit` | `string` | Optional | Satuan volume (mL) |
| `CollectionMethodSystem` | `collection_method_system` | `string` | Optional | System metode pengambilan |
| `CollectionMethodCode` | `collection_method_code` | `string` | Optional | Kode metode (SNOMED) |
| `CollectionMethodDisplay` | `collection_method_display` | `string` | Optional | Nama metode |
| `BodySiteCode` | `body_site_code` | `string` | Optional | Kode lokasi pengambilan sampel |
| `BodySiteDisplay` | `body_site_display` | `string` | Optional | Nama lokasi |
| `FastingStatusCode` | `fasting_status_code` | `string` | Optional | Kode status puasa (F = Fasting) |
| `FastingStatusDisplay` | `fasting_status_display` | `string` | Optional | Nama status puasa |
| `ProcessingProcedureCode` | `processing_procedure_code` | `string` | Optional | Kode prosedur pengolahan |
| `ProcessingProcedureDisplay` | `processing_procedure_display` | `string` | Optional | Nama prosedur pengolahan |
| `ProcessingTimeDateTime` | `processing_time_datetime` | `time.Time` | Optional (ISO-8601) | Waktu pengolahan sampel |
| `Conditions` | `conditions` | `[]string` | Optional | Array kondisi spesimen (refrigerated) |
| `RequestServiceRequestIDs` | `request_service_request_ids` | `[]string` | Optional | Array ID ServiceRequest pendukung |
#### Example Request Payload
```json
{
"specimen_id": "SPC-3001",
"organization_id": "10000004",
"patient_id": "P03647103112",
"status": "available",
"type_system": "http://terminology.hl7.org/CodeSystem/v2-0487",
"type_code": "BLD",
"type_display": "Whole blood",
"received_date_time": "2026-05-13T09:20:00+07:00",
"collected_date_time": "2026-05-13T09:10:00+07:00",
"collector_id": "N10000001",
"collector_name": "Perawat Sari",
"collection_quantity_value": 5,
"collection_quantity_unit": "mL",
"collection_method_code": "129316008",
"collection_method_display": "Aspiration - action",
"body_site_code": "368208006",
"body_site_display": "Left upper arm",
"fasting_status_code": "F",
"fasting_status_display": "Fasting",
"processing_procedure_code": "9718006",
"processing_procedure_display": "Centrifugation",
"processing_time_datetime": "2026-05-13T09:25:00+07:00",
"conditions": ["refrigerated"],
"request_service_request_ids": ["SR-0001"]
}
```
---
### 20. Studies (DICOM Upload)
- **POST Route:** `/satusehat/dicom/studies/upload`
- **Content-Type:** `multipart/form-data`
#### Request Parameters
| Parameter Name | Field Type | Requirement | Description |
| --- | --- | --- | --- |
| `file` | Binary (file upload) | **Required** | File tarball DICOM (`.tar.gz` atau `.zip`) |
| `organization_id` | String / Form Data | Optional | ID Organisasi Faskes |
| `patient_id` | String / Form Data | Optional | ID Pasien Satu Sehat |
| `accession_number` | String / Form Data | Optional | Nomor aksesi radiologi |
---
## 🔍 Reference Endpoints & Search Parameters
Selain 20 FHIR resource usecases di atas, `service-satusehat` menyediakan modul **Reference** untuk pencarian dan pemetaan master data.
### 1. Patient Reference
- **POST Route:** `/satusehat/patient` (Create Patient)
- **GET Route:** `/satusehat/patient` (Search Patient)
#### Create Patient Payload (`CreatePatientRequest`)
```json
{
"nik": "3515010101900001",
"name": "Budi Santoso",
"gender": "male",
"birth_date": "1990-01-01",
"phone": "081234567890",
"address": "Jl. Merdeka No. 10"
}
```
#### Search Patient Query Parameters (`PatientSearchParams`)
- `name`: Nama Pasien
- `birthdate`: Tanggal Lahir (`YYYY-MM-DD`)
- `gender`: Jenis Kelamin (`male`, `female`, `other`, `unknown`)
- `nik`: Nomor Induk Kependudukan (16 digit)
- `nik_ibu`: NIK Ibu Kandung (untuk bayi baru lahir)
---
### 2. Practitioner Reference
- **GET Route:** `/satusehat/practitioner`
#### Query Parameters (`PractitionerSearchParams`)
- `name`: Nama Tenaga Medis / Dokter
- `nik`: NIK Tenaga Medis
- `gender`: Jenis Kelamin (`male`, `female`)
- `birthdate`: Tanggal Lahir (`YYYY-MM-DD`)
---
### 3. Organization Reference
- **GET Route:** `/satusehat/organization`
#### Query Parameters (`OrganizationSearchParams`)
- `name`: Nama Organisasi / Faskes
- `partof`: ID Organisasi Induk / Parent
- `identifier`: Identifier Spesifik (misal: `http://sys-ids.kemkes.go.id/organization/10000004|R220001`)
---
### 4. Location Reference
- **GET Route:** `/satusehat/location`
#### Query Parameters (`LocationSearchParams`)
- `name`: Nama Ruangan / Poli / Lokasi
- `organization`: ID Faskes pembuat lokasi
- `identifier`: System/Value Identifier
---
### 5. KFA (Kamus Farmasi dan Alat Kesehatan)
- **GET Route:** `/satusehat/kfa`
#### Query Parameters (`KFASearchParams`)
- `page`: Nomor halaman (default: `1`)
- `size`: Jumlah item per halaman (default: `10`)
- `product_type`: Tipe produk (`farmasi`, `alkes`)
- `keyword`: Kata kunci pencarian nama obat/alkes
- `from_`: Filter rentang waktu update KFA
---
### 6. KYC (Know Your Customer / Verifikasi Nakes)
- **POST Route:** `/satusehat/kyc/generate-url`
- **POST Route:** `/satusehat/kyc/callback`
#### Generate URL Payload (`GenerateURLRequest`)
```json
{
"agent_name": "Dr. Andi",
"agent_nik": "3515010101900001"
}
```
---
## 🛠️ Validation Error Summary
Jika payload JSON yang dikirimkan ke endpoint API tidak memenuhi aturan `binding` DTO di atas, server akan mengembalikan respons `HTTP 400 Bad Request` dengan format standar berikut:
```json
{
"status": "error",
"error": {
"code": "INVALID_INPUT",
"details": {
"additional_details": "Field validation for 'Status' failed on the 'required' tag",
"reason": "Format permintaan tidak valid",
"timestamp": "2026-07-29T02:15:00Z"
},
"message": "Invalid input provided",
"request_id": "req_1785290642391284101",
"retryable": false,
"stack_trace": null,
"timestamp": "2026-07-29T02:15:00Z"
},
"meta": {
"category": "validation",
"http_status": 400
}
}
```