From b8e219868d25507f402295589cbb36d7c5f29f29 Mon Sep 17 00:00:00 2001 From: meninjar Date: Wed, 29 Jul 2026 02:19:04 +0000 Subject: [PATCH 1/2] update mapping json obeservsi dan diagnosis report --- docs/api-flat-bodies.md | 917 +++++++++++++++--- .../satusehat/usecase/diagnosticreport/dto.go | 26 +- .../usecase/diagnosticreport/mapper.go | 8 + internal/satusehat/usecase/observation/dto.go | 7 + .../satusehat/usecase/observation/mapper.go | 6 + 5 files changed, 829 insertions(+), 135 deletions(-) diff --git a/docs/api-flat-bodies.md b/docs/api-flat-bodies.md index 8e4adb5..1d0d338 100644 --- a/docs/api-flat-bodies.md +++ b/docs/api-flat-bodies.md @@ -1,36 +1,64 @@ -# Flat JSON Bodies — All SatuSehat Use Cases +# Flat JSON Bodies & DTO Specifications — SATUSEHAT Service -> Flat (non-nested) POST body for **every** FHIR resource currently -> exposed by `service-satusehat`. +> 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`. > -> **Status:** ✅ **Implemented**. As of 2026-05-13, all 19 FHIR usecases + -> EpisodeOfCare + QuestionnaireResponse accept the flat shape below. Internal -> mappers compose the nested FHIR R4 payload before submission to SATUSEHAT. -> No `*DTO` types from `internal/satusehat/common` are exposed at the API -> surface anymore. -> -> Conventions used in every body below: -> -> - `*_id` carries the **raw identifier**; the mapper composes -> `Patient/{id}`, `Practitioner/{id}`, `Encounter/{id}`, etc. -> - `*_name` (or `*_display`) is the human-readable display. -> - `*_code` + `*_display` (+ optional `*_system`) replace nested -> `CodeableConceptDTO`. -> - `*_value` + `*_unit` (+ optional `*_system`, `*_code`) replace nested -> `QuantityDTO`. -> - Date-times use ISO-8601 `2026-05-13T08:00:00+07:00` (RFC 3339). -> Encounter alone accepts the simpler `YYYY-MM-DD HH:MM:SS` form for -> `period_start` / `period_end` via the project's `CustomTime` (WIB). -> - Status / class / intent values match the validator `oneof=` lists in the -> DTOs verbatim. -> - `organization_id` is optional — if omitted, the service injects -> `cfg.SatuSehat.OrgID` at the boundary. +> **Last updated:** 2026-07-29 --- -## 1. Encounter +## 📌 Architecture & Design Conventions -`POST /satusehat/encounter` +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 { @@ -55,9 +83,36 @@ --- -## 2. EpisodeOfCare +### 2. EpisodeOfCare -`POST /satusehat/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 { @@ -82,9 +137,32 @@ --- -## 3. Condition +### 3. Condition -`POST /satusehat/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 { @@ -106,9 +184,59 @@ --- -## 4. Observation +### 4. Observation -`POST /satusehat/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 { @@ -143,9 +271,33 @@ --- -## 5. AllergyIntolerance +### 5. AllergyIntolerance -`POST /satusehat/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 { @@ -169,9 +321,35 @@ --- -## 6. CarePlan +### 6. CarePlan -`POST /satusehat/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 { @@ -196,9 +374,41 @@ --- -## 7. ClinicalImpression +### 7. ClinicalImpression -`POST /satusehat/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 { @@ -228,9 +438,40 @@ --- -## 8. Composition +### 8. Composition -`POST /satusehat/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 { @@ -259,9 +500,43 @@ --- -## 9. DiagnosticReport +### 9. DiagnosticReport -`POST /satusehat/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 { @@ -290,9 +565,33 @@ --- -## 10. ImagingStudy +### 10. ImagingStudy -`POST /satusehat/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 { @@ -316,9 +615,39 @@ --- -## 11. Immunization +### 11. Immunization -`POST /satusehat/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 { @@ -350,9 +679,28 @@ --- -## 12. Medication +### 12. Medication -`POST /satusehat/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 { @@ -371,9 +719,44 @@ --- -## 13. MedicationDispense +### 13. MedicationDispense -`POST /satusehat/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 { @@ -392,8 +775,8 @@ "prescription_item_id": "RX-2026-000123-1", "status": "completed", "category": "outpatient", - "prepared_date": "2026-05-13 09:40:00", - "handed_over_date": "2026-05-13 09:45:00", + "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, @@ -408,9 +791,53 @@ --- -## 14. MedicationRequest +### 14. MedicationRequest -`POST /satusehat/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 { @@ -454,9 +881,42 @@ --- -## 15. MedicationStatement +### 15. MedicationStatement -`POST /satusehat/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 { @@ -486,9 +946,41 @@ --- -## 16. Procedure +### 16. Procedure -`POST /satusehat/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 { @@ -517,9 +1009,56 @@ --- -## 17. QuestionnaireResponse +### 17. QuestionnaireResponse -`POST /satusehat/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 { @@ -550,14 +1089,35 @@ } ``` -> Note: `items` remains an array because QuestionnaireResponse is -> intrinsically list-shaped — but each item is itself flat. - --- -## 18. ServiceRequest +### 18. ServiceRequest -`POST /satusehat/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 { @@ -579,9 +1139,44 @@ --- -## 19. Specimen +### 19. Specimen -`POST /satusehat/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 { @@ -614,84 +1209,144 @@ --- -## 20. Studies (DICOM upload) +### 20. Studies (DICOM Upload) -The `studies` module today is a thin DICOM tarball uploader and does not -take a structured body. The recommended request is `multipart/form-data`: +- **POST Route:** `/satusehat/dicom/studies/upload` +- **Content-Type:** `multipart/form-data` -```http -POST /satusehat/dicom/studies/upload -Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXyz +#### Request Parameters -------WebKitFormBoundaryXyz -Content-Disposition: form-data; name="organization_id" +| 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 | -10000004 -------WebKitFormBoundaryXyz -Content-Disposition: form-data; name="patient_id" +--- -P03647103112 -------WebKitFormBoundaryXyz -Content-Disposition: form-data; name="accession_number" +## 🔍 Reference Endpoints & Search Parameters -ACC-0001 -------WebKitFormBoundaryXyz -Content-Disposition: form-data; name="file"; filename="study.tar.gz" -Content-Type: application/gzip +Selain 20 FHIR resource usecases di atas, `service-satusehat` menyediakan modul **Reference** untuk pencarian dan pemetaan master data. - -------WebKitFormBoundaryXyz-- -``` +### 1. Patient Reference -If a JSON metadata-only endpoint is added later, the flat shape would be: +- **POST Route:** `/satusehat/patient` (Create Patient) +- **GET Route:** `/satusehat/patient` (Search Patient) + +#### Create Patient Payload (`CreatePatientRequest`) ```json { - "organization_id": "10000004", - "patient_id": "P03647103112", - "accession_number": "ACC-0001", - "study_instance_uid": "1.2.840.113619.2.5.1762583153.1762583153.1762583153.1", - "modality": "CR", - "started": "2026-05-13T09:00:00+07:00", - "description": "Thorax PA" + "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" } ``` --- -## Implementation notes +## 🛠️ Validation Error Summary -All 20 usecases now share the same internal pattern: +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: -1. **`dto.go`** — pure flat struct with `binding:"required,..."` tags only on - scalar fields. No `common.ReferenceDTO` / `common.CodeableConceptDTO` - imports at the request boundary. -2. **`mapper.go`** — `MapRequestToFHIR(req)` builds the nested FHIR R4 - payload. Mapper is pure: no env reads, no I/O. -3. **`repository.go`** — thin wrapper over `SatuSehatClient.DoRequest`. The - old `hiddenCtx` wrapper has been removed; `context.Context` flows through - unchanged for proper deadline / cancellation propagation. -4. **`service.go`** — `NewService(repo, orgID string)` takes the default - organisation identifier from `cfg.SatuSehat.OrgID` at boot. When a caller - omits `organization_id` in the request body, the service fills it in. - -The full audit trail is in `docs/DEVLOG.md`. - -## Field-shape cheat-sheet (nested → flat) - -| Nested FHIR field | Flat replacement | -| --- | --- | -| `subject.reference = "Patient/X"` | `patient_id = "X"` (+ optional `patient_name`) | -| `encounter.reference = "Encounter/X"` | `encounter_id = "X"` (+ `encounter_display`) | -| `performer[].reference = "Practitioner/X"` | `performer_id = "X"` (+ `performer_name`) | -| `location[].location.reference = "Location/X"` | `location_id = "X"` (+ `location_name`) | -| `managingOrganization.reference = "Organization/X"` | `managing_organization_id = "X"` | -| `code.system / .code / .display` | `code_system / code / code_display` | -| `category.code / .display` | `category_code / category_display` | -| `valueQuantity.value / .unit / .system / .code` | `value_quantity_value / _unit / _system / _code` | -| `period.start / .end` | `period_start / period_end` | -| `dosage.route.code` | `route_code` / `dosage_route_code` | - -When a list of references exists (e.g. `result_observation_ids`, -`specimen_ids`), keep it as a flat array of IDs — the mapper turns them -into `["Observation/{id}", …]`. +```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 + } +} +``` diff --git a/internal/satusehat/usecase/diagnosticreport/dto.go b/internal/satusehat/usecase/diagnosticreport/dto.go index e6fe8e4..a7af73b 100644 --- a/internal/satusehat/usecase/diagnosticreport/dto.go +++ b/internal/satusehat/usecase/diagnosticreport/dto.go @@ -27,15 +27,33 @@ type DiagnosticReportRequest struct { PerformerID string `json:"performer_id,omitempty"` PerformerName string `json:"performer_name,omitempty"` - ResultObservationIDs []string `json:"result_observation_ids,omitempty"` - SpecimenIDs []string `json:"specimen_ids,omitempty"` - BasedOnIDs []string `json:"based_on_service_request_ids,omitempty"` - ImagingStudyIDs []string `json:"imaging_study_ids,omitempty"` + ResultObservationIDs []string `json:"result_observation_ids,omitempty"` + ResultObservationSystem []string `json:"result_observation_system,omitempty"` + ResultObservationCode []string `json:"result_observation_code,omitempty"` + ResultObservationDisplay []string `json:"result_observation_display,omitempty"` + + SpecimenIDs []string `json:"specimen_ids,omitempty"` + SpecimenSystem []string `json:"specimen_system,omitempty"` + SpecimenCode []string `json:"specimen_code,omitempty"` + SpecimenDisplay []string `json:"specimen_display,omitempty"` + + BasedOnIDs []string `json:"based_on_service_request_ids,omitempty"` + BasedOnSystem []string `json:"based_on_service_request_system,omitempty"` + BasedOnCode []string `json:"based_on_service_request_code,omitempty"` + BasedOnDisplay []string `json:"based_on_service_request_display,omitempty"` + + ImagingStudyIDs []string `json:"imaging_study_ids,omitempty"` + ImagingStudySystem []string `json:"imaging_study_system,omitempty"` + ImagingStudyCode []string `json:"imaging_study_code,omitempty"` + ImagingStudyDisplay []string `json:"imaging_study_display,omitempty"` ConclusionCodeSystem string `json:"conclusion_code_system,omitempty"` ConclusionCode string `json:"conclusion_code,omitempty"` ConclusionCodeDisplay string `json:"conclusion_code_display,omitempty"` Conclusion string `json:"conclusion,omitempty"` + + ObservationID string `json:"observation_id,omitempty"` + ServiceRequestID string `json:"service_request_id,omitempty"` } type DiagnosticReportPatchRequest []map[string]interface{} diff --git a/internal/satusehat/usecase/diagnosticreport/mapper.go b/internal/satusehat/usecase/diagnosticreport/mapper.go index b65d2fb..1591626 100644 --- a/internal/satusehat/usecase/diagnosticreport/mapper.go +++ b/internal/satusehat/usecase/diagnosticreport/mapper.go @@ -120,5 +120,13 @@ func MapRequestToFHIR(req DiagnosticReportRequest) satusehat.FHIRPayload { payload.Set("conclusion", req.Conclusion) } + if req.ObservationID != "" { + payload.Set("observation", map[string]interface{}{"reference": "Observation/" + req.ObservationID}) + } + + if req.ServiceRequestID != "" { + payload.Set("serviceRequest", map[string]interface{}{"reference": "ServiceRequest/" + req.ServiceRequestID}) + } + return payload } diff --git a/internal/satusehat/usecase/observation/dto.go b/internal/satusehat/usecase/observation/dto.go index bfc1bf8..b9b7952 100644 --- a/internal/satusehat/usecase/observation/dto.go +++ b/internal/satusehat/usecase/observation/dto.go @@ -55,6 +55,13 @@ type ObservationRequest struct { ReferenceRangeHighValue *float64 `json:"reference_range_high_value,omitempty"` ReferenceRangeUnit string `json:"reference_range_unit,omitempty"` ReferenceRangeText string `json:"reference_range_text,omitempty"` + + ServiceRequestID string `json:"service_request_id,omitempty"` + + ResultObservationIDs []string `json:"result_observation_ids,omitempty"` + ResultObservationSystem []string `json:"result_observation_system,omitempty"` + ResultObservationCode []string `json:"result_observation_code,omitempty"` + ResultObservationDisplay []string `json:"result_observation_display,omitempty"` } type ObservationPatchRequest []map[string]interface{} diff --git a/internal/satusehat/usecase/observation/mapper.go b/internal/satusehat/usecase/observation/mapper.go index 4206744..4fcb039 100644 --- a/internal/satusehat/usecase/observation/mapper.go +++ b/internal/satusehat/usecase/observation/mapper.go @@ -95,6 +95,12 @@ func MapRequestToFHIR(req ObservationRequest) satusehat.FHIRPayload { payload.Set("bodySite", map[string]interface{}{"coding": []map[string]interface{}{coding}}) } + if req.ServiceRequestID != "" { + payload.Set("basedOn", []map[string]interface{}{ + {"reference": "ServiceRequest/" + req.ServiceRequestID}, + }) + } + switch { case req.ValueQuantityValue != nil: sys := req.ValueQuantitySystem From ccd5a0974d5512df1cdfd1b87ffc4e26d131e896 Mon Sep 17 00:00:00 2001 From: meninjar Date: Tue, 4 Aug 2026 11:46:50 +0000 Subject: [PATCH 2/2] update mappping --- .../satusehat/usecase/diagnosticreport/dto.go | 4 ++-- .../usecase/diagnosticreport/mapper.go | 16 +++++-------- .../satusehat/usecase/servicerequest/dto.go | 24 +++++++++---------- .../usecase/servicerequest/mapper.go | 2 +- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/internal/satusehat/usecase/diagnosticreport/dto.go b/internal/satusehat/usecase/diagnosticreport/dto.go index a7af73b..f1072f9 100644 --- a/internal/satusehat/usecase/diagnosticreport/dto.go +++ b/internal/satusehat/usecase/diagnosticreport/dto.go @@ -27,7 +27,7 @@ type DiagnosticReportRequest struct { PerformerID string `json:"performer_id,omitempty"` PerformerName string `json:"performer_name,omitempty"` - ResultObservationIDs []string `json:"result_observation_ids,omitempty"` + ResultObservationIDs string `json:"result_observation_ids,omitempty"` ResultObservationSystem []string `json:"result_observation_system,omitempty"` ResultObservationCode []string `json:"result_observation_code,omitempty"` ResultObservationDisplay []string `json:"result_observation_display,omitempty"` @@ -37,7 +37,7 @@ type DiagnosticReportRequest struct { SpecimenCode []string `json:"specimen_code,omitempty"` SpecimenDisplay []string `json:"specimen_display,omitempty"` - BasedOnIDs []string `json:"based_on_service_request_ids,omitempty"` + BasedOnIDs string `json:"based_on_service_request_ids,omitempty"` BasedOnSystem []string `json:"based_on_service_request_system,omitempty"` BasedOnCode []string `json:"based_on_service_request_code,omitempty"` BasedOnDisplay []string `json:"based_on_service_request_display,omitempty"` diff --git a/internal/satusehat/usecase/diagnosticreport/mapper.go b/internal/satusehat/usecase/diagnosticreport/mapper.go index 1591626..5550adf 100644 --- a/internal/satusehat/usecase/diagnosticreport/mapper.go +++ b/internal/satusehat/usecase/diagnosticreport/mapper.go @@ -73,11 +73,9 @@ func MapRequestToFHIR(req DiagnosticReportRequest) satusehat.FHIRPayload { payload.Set("performer", []map[string]interface{}{perf}) } - if len(req.ResultObservationIDs) > 0 { - results := make([]map[string]interface{}, 0, len(req.ResultObservationIDs)) - for _, id := range req.ResultObservationIDs { - results = append(results, map[string]interface{}{"reference": "Observation/" + id}) - } + if req.ResultObservationIDs != "" { + results := make([]map[string]interface{}, 0, 1) + results = append(results, map[string]interface{}{"reference": "Observation/" + req.ResultObservationIDs}) payload.Set("result", results) } if len(req.SpecimenIDs) > 0 { @@ -87,11 +85,9 @@ func MapRequestToFHIR(req DiagnosticReportRequest) satusehat.FHIRPayload { } payload.Set("specimen", specs) } - if len(req.BasedOnIDs) > 0 { - basedOns := make([]map[string]interface{}, 0, len(req.BasedOnIDs)) - for _, id := range req.BasedOnIDs { - basedOns = append(basedOns, map[string]interface{}{"reference": "ServiceRequest/" + id}) - } + if req.BasedOnIDs != "" { + basedOns := make([]map[string]interface{}, 0, 1) + basedOns = append(basedOns, map[string]interface{}{"reference": "ServiceRequest/" + req.BasedOnIDs}) payload.Set("basedOn", basedOns) } if len(req.ImagingStudyIDs) > 0 { diff --git a/internal/satusehat/usecase/servicerequest/dto.go b/internal/satusehat/usecase/servicerequest/dto.go index 4dfa48f..32049b6 100644 --- a/internal/satusehat/usecase/servicerequest/dto.go +++ b/internal/satusehat/usecase/servicerequest/dto.go @@ -6,18 +6,18 @@ type ServiceRequestRequest struct { OrganizationID string `json:"organization_id,omitempty"` ServiceRequestID string `json:"service_request_id,omitempty"` PatientID string `json:"patient_id,omitempty"` - PatientName string `json:"patient_name,omitempty"` - EncounterID string `json:"encounter_id,omitempty"` - RequesterID string `json:"requester_id,omitempty"` - PerformerID string `json:"performer_id,omitempty"` - RequesterName string `json:"requester_name,omitempty"` - PerformerName string `json:"performer_name,omitempty"` - Status string `json:"status,omitempty" binding:"omitempty,oneof=draft active on-hold revoked completed entered-in-error unknown"` - Intent string `json:"intent,omitempty" binding:"omitempty,oneof=proposal plan directive order original-order reflex-order filler-order instance-order option"` - Code string `json:"code,omitempty"` - System string `json:"system,omitempty"` - Display string `json:"display,omitempty"` - AuthoredOn time.Time `json:"authored_on,omitempty"` + PatientName string `json:"patient_name,omitempty"` + EncounterID string `json:"encounter_id,omitempty"` + RequesterID string `json:"requester_id,omitempty"` + PerformerID string `json:"performer_id,omitempty"` + RequesterName string `json:"requester_name,omitempty"` + PerformerName string `json:"performer_name,omitempty"` + Status string `json:"status,omitempty" binding:"omitempty,oneof=draft active on-hold revoked completed entered-in-error unknown"` + Intent string `json:"intent,omitempty" binding:"omitempty,oneof=proposal plan directive order original-order reflex-order filler-order instance-order option"` + Code []string `json:"code,omitempty"` + System string `json:"system,omitempty"` + Display string `json:"display,omitempty"` + AuthoredOn time.Time `json:"authored_on,omitempty"` } type ServiceRequestPatchRequest []map[string]interface{} diff --git a/internal/satusehat/usecase/servicerequest/mapper.go b/internal/satusehat/usecase/servicerequest/mapper.go index 40549fe..3df5389 100644 --- a/internal/satusehat/usecase/servicerequest/mapper.go +++ b/internal/satusehat/usecase/servicerequest/mapper.go @@ -27,7 +27,7 @@ func MapRequestToFHIR(req ServiceRequestRequest) satusehat.FHIRPayload { payload.Set("intent", req.Intent) } - if req.Code != "" { + if len(req.Code) > 0 { system := "http://snomed.info/sct" if req.System != "" { system = req.System