Skip to content

Repository files navigation

satusehat-integration

Open-source Node.js SDK for integrating with SATUSEHAT — Indonesia's national health data platform powered by FHIR R4. Pure JavaScript/TypeScript, no framework dependency.

Node.js FHIR R4 License CI npm npm


Overview

satusehat-integration is an open-source Node.js SDK for integrating with SATUSEHAT — Indonesia's national health data platform powered by FHIR R4.

Built on the official SATUSEHAT Platform Guidelines. Ships with:

  • 115+ PayloadBuilder classes — fluent builders for all FHIR R4 resources (Patient, Practitioner, Organization, Encounter, Observation, Procedure, etc.)
  • 50 DataType interfaces — composable FHIR R4 value objects with toJSON() serialization
  • TerminologyResolver — castable terminology strings ("ICD10:A00", "LOINC:2951-2", "SNOMED:38341003") directly to CodeableConcept
  • 3 SATUSEHAT-specific resources: BillingStatus (NON-FHIR JSON), PurificationDecision (NON-FHIR JSON), Endpoint (FHIR R4)
  • Queue + Rate Limiter — in-memory queue with configurable RPM rate limiting
  • Vitest test suite — all builders have comprehensive unit tests

Zero dependencies beyond TypeScript runtime. Works with any JS framework or plain Node.js.


Requirements

  • Node.js 20 or later (LTS recommended)
  • npm 9+ or yarn 1.22+

Quick Install

npm install @ivanwilliammd/satusehat-integration
# or
yarn add @ivanwilliammd/satusehat-integration
# .env
SATUSEHAT_ENV=DEV          # DEV | STG | PROD
SATUSEHAT_BASE_URL_DEV=https://api-satusehat-dev.dto.kemkes.go.id
CLIENTID_DEV=your_client_id
CLIENTSECRET_DEV=your_client_secret
ORGID_DEV=your_org_id

Architecture

DataType Interfaces (src/datatype/)

Atomic FHIR R4 value interfaces. All provide a toJSON() method — nested types serialize to clean FHIR JSON automatically.

Category Types
Core Coding, CodeableConcept, Identifier, ContactPoint, Address, HumanName, Reference
Quantity Age, Quantity
Utility Period, ParameterComponent

Example — HumanName:

import { HumanName } from '@ivanwilliammd/satusehat-integration';

const name: HumanName = {
    family: 'Doe',
    given: ['John', 'Michael'],
    use: 'official',
};
// name.toJSON() → { family: 'Doe', given: ['John', 'Michael'], use: 'official' }

PayloadBuilder Pattern (src/builder/)

Fluent builder for each FHIR resource. Each builder exposes chainable methods and returns the resource payload via toJSON().

import { PatientBuilder, HumanName } from '@ivanwilliammd/satusehat-integration';

const patient = new PatientBuilder()
    .setId('12345678-1234-1234-1234-123456789012')
    .addName({ family: 'Doe', given: ['John'], use: 'official' })
    .setGender('male')
    .setBirthDate('1990-01-15');

const payload = patient.toJSON();

Supported FHIR Resources

115+ PayloadBuilder classes covering all FHIR R4 resources used in SATUSEHAT interoperability, plus 3 SATUSEHAT-specific resources.

SATUSEHAT Interoperability Resources (47)

# Resource Builder
1 Account AccountBuilder
2 AllergyIntolerance AllergyIntoleranceBuilder
3 BillingStatus ⚡NON-FHIR BillingStatusBuilder
4 CarePlan CarePlanBuilder
5–7 ChargeItem, ChargeItemDefinition, ChargeItemResponse ChargeItemBuilder, ChargeItemDefinitionBuilder, ChargeItemResponseBuilder
8–9 Claim, ClaimResponse ClaimBuilder, ClaimResponseBuilder
10 ClinicalImpression ClinicalImpressionBuilder
11 Composition CompositionBuilder
12 Condition ConditionBuilder
13 Coverage CoverageBuilder
14–15 CoverageEligibilityRequest, CoverageEligibilityResponse CoverageEligibilityRequestBuilder, CoverageEligibilityResponseBuilder
16 DiagnosticReport DiagnosticReportBuilder
17 DocumentReference DocumentReferenceBuilder
18 Encounter EncounterBuilder
19 Endpoint EndpointBuilder
20 EpisodeOfCare EpisodeOfCareBuilder
21 FamilyMemberHistory FamilyMemberHistoryBuilder
22 Goal GoalBuilder
23 ImagingStudy ImagingStudyBuilder
24 Immunization ImmunizationBuilder
25 Invoice InvoiceBuilder
26 Location LocationBuilder
27–31 Medication, MedicationAdministration, MedicationDispense, MedicationRequest, MedicationStatement MedicationBuilder, MedicationAdministrationBuilder, MedicationDispenseBuilder, MedicationRequestBuilder, MedicationStatementBuilder
32 NutritionOrder NutritionOrderBuilder
33 Observation ObservationBuilder
34 Organization OrganizationBuilder
35 Patient PatientBuilder
36–37 PaymentNotice, PaymentReconciliation PaymentNoticeBuilder, PaymentReconciliationBuilder
38 Practitioner PractitionerBuilder
39 Procedure ProcedureBuilder
40 QuestionnaireResponse QuestionnaireResponseBuilder
41 RelatedPerson RelatedPersonBuilder
42 RiskAssessment RiskAssessmentBuilder
43 ServiceRequest ServiceRequestBuilder
44 Specimen SpecimenBuilder
45 Substance SubstanceBuilder
46 Task TaskBuilder
47 PurificationDecision ⚡NON-FHIR PurificationDecisionBuilder

⚡ = NON-FHIR JSON (SATUSEHAT-specific extension)

BillingStatus (NON-FHIR JSON)

import { BillingStatusBuilder } from '@ivanwilliammd/satusehat-integration';

const billing = new BillingStatusBuilder()
  .setId('bs-001')
  .addIdentifier('http://sys-ids.kemkes.go.id/billing/org-001', 'BILL-12345')
  .setStatus('active')
  .setInsurer('Organization/org-bpjs', 'BPJS Kesehatan')
  .setSubject('100000030009', 'Budi Santoso')
  .setRequest('cer-001');

Endpoint (FHIR R4)

import { EndpointBuilder } from '@ivanwilliammd/satusehat-integration';

const endpoint = new EndpointBuilder()
  .setId('ep-001')
  .setStatus('active')
  .setConnectionType('ihe-xcpd', 'IHE XCPD')
  .setName('SATUSEHAT FHIR Endpoint')
  .setManagingOrganization('Organization/org-ihs')
  .setAddress('https://satusehat-api.example.com/fhir/r4');

PurificationDecision (NON-FHIR JSON)

import { PurificationDecisionBuilder } from '@ivanwilliammd/satusehat-integration';

const pd = new PurificationDecisionBuilder()
  .setId('pd-001')
  .addIdentifier('http://sys-ids.kemkes.go.id/purification/org-001', 'PD-12345')
  .setStatus('approved', 'Approved')
  .setInsurer('Organization/org-bpjs', 'BPJS Kesehatan')
  .setProvider('Organization/hos-001', 'Rumah Sakit Sehat')
  .setClaimResponse('cr-001')
  .setCreated('2024-01-15T10:35:00+00:00');

TerminologyResolver — castable codes

import { TerminologyResolver } from '@ivanwilliammd/satusehat-integration';

// Cast terminology strings directly to CodeableConcept
TerminologyResolver.resolve('ICD10:A00');
// → { coding: [{ system: 'http://hl7.org/fhir/sid/icd-10', code: 'A00', display: 'A00' }], text: 'A00' }

TerminologyResolver.resolve('LOINC:2951-2');
// → { coding: [{ system: 'http://loinc.org', code: '2951-2', display: '2951-2' }], text: '2951-2' }

// Batch expand
TerminologyResolver.expandArray(['ICD10:A00', 'ICD10:J18.9']);

Usage Examples

Patient

import { PatientBuilder } from '@ivanwilliammd/satusehat-integration';

const patient = new PatientBuilder()
    .setId('12345678-1234-1234-1234-123456789012')
    .setName({ family: 'Doe', given: ['John'], use: 'official' })
    .setGender('male')
    .setBirthDate('1990-01-15')
    .addTelecom({ system: 'phone', value: '081234567890', use: 'mobile' });

const payload = patient.toJSON();
console.log(JSON.stringify(payload, null, 2));

Claim (BPJS Klaim)

import { ClaimBuilder } from '@ivanwilliammd/satusehat-integration';

const claim = new ClaimBuilder()
    .setStatus('active')
    .setUse('claim')
    .setType('institutional')
    .setPatient('pat-123', 'enc-456')
    .addItem(1, 'PROCID001', 150000, 'IDR')
    .setTotal(150000, 'IDR');

const payload = claim.toJSON();

Documentation

Page Description
Wiki Home Full documentation
Getting Started Installation, configuration
DataTypes Complete type reference
Builders Builder usage guide
Resources All FHIR resources
Claim Module BPJS Klaim integration

External Resources


Contributing

Contributions are welcome. Please ensure tests pass and follow existing code conventions.


License

MIT — see LICENSE.

About

SATUSEHAT FHIR R4 SDK for Node.js — easy way to create FHIR R4 resource object

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages