# 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 } } ```