Files
satusehat-service/docs/PRD.md
T

12 KiB
Raw Blame History

Product Requirements Document (PRD)

Service: service-satusehat

Field Value
Document Version 1.0
Status Draft
Owner Backend Engineering — Meninjar
Last Updated 2026-05-13
Repository goprint/service-satusehat
Primary Language Go 1.25
Target Audience Backend engineers, integration partners, ops, hospital IT (RS)

1. Overview

1.1 Product Summary

service-satusehat is a backend microservice that acts as the integration gateway between an Indonesian hospital information system (SIMRS / HIS) and Indonesia's national health platforms — primarily SATUSEHAT (HL7 FHIR R4) operated by the Ministry of Health, with secondary integration paths for BPJS Kesehatan (VClaim, Antrol, Apotek, Aplicare, IHS) and supporting infrastructure (Keycloak SSO, MinIO object storage, Redis cache, Prometheus observability).

The service exposes a dual transport surface (REST via Gin and gRPC) and is built on Clean Architecture + Domain-Driven Design + CQRS. It centralizes all outbound calls to SATUSEHAT, normalizes FHIR resource construction, manages OAuth2 tokens, and protects upstream callers from FHIR/JSON-Patch complexity.

1.2 Problem Statement

Hospitals in Indonesia are mandated by the Ministry of Health to send clinical encounter data to SATUSEHAT (HL7 FHIR). Direct integration is hard because:

  1. Heterogeneous internal data sources — most hospitals have data spread across multiple databases (PostgreSQL / MySQL / SQL Server) and legacy systems.
  2. Strict FHIR R4 contract — resource structure, references, codings, and identifier systems must follow SATUSEHAT IG.
  3. OAuth2 token lifecycle — SATUSEHAT requires short-lived tokens with automatic refresh and concurrency-safe caching.
  4. Auxiliary services — KFA (drug master), KYC, Consent, DICOM, BPJS all have different auth, signing, and payload conventions.
  5. Observability & auditability — every regulated submission must be logged, traceable, and retryable.

A single integration service that solves the above once, and is reusable across hospital products, is significantly cheaper than re-implementing the contract in every product team.

1.3 Goals

# Goal Success indicator
G1 Provide one canonical Go service that submits every required FHIR resource to SATUSEHAT All 19 FHIR resources implemented with Create/Update/Patch/Get/Search
G2 Abstract OAuth2 + auxiliary auth (KFA, KYC, Consent, DICOM) from callers Single client handles token caching and header injection
G3 Be deployable in a hospital data center with minimal ops effort Single Docker image, distroless, Compose stack with dev/prod profiles
G4 Stay observable in production Prometheus metrics, structured logs, health endpoints, request tracing fields
G5 Stay vendor-agnostic at the storage layer Multi-DB support (Postgres, MySQL, SQL Server, MongoDB, SQLite) with read replicas
G6 Be safe to refactor and extend Clean Architecture boundaries, generated code, CQRS separation

1.4 Non-Goals

  • Front-end UI — this is a backend service only.
  • Long-term clinical data storage — the hospital's primary database remains the source of truth.
  • Generic FHIR server — only SATUSEHAT-required resources and profiles are supported, not the full HL7 FHIR spec.
  • BPJS claim submission UI/UX — only the integration layer is in scope.
  • HL7 v2 messaging — out of scope.

2. Target Users & Personas

2.1 Primary Users (callers)

Persona Description What they need
SIMRS Backend Internal hospital ERP/HIS server that emits clinical events A stable REST/gRPC contract that hides SATUSEHAT details
Mobile / Web App teams Patient portal, clinician app A simple "submit encounter" API; no FHIR construction
Data engineering Builds dashboards / reports on submitted resources Read-back, search, and audit logs

2.2 Secondary Users

Persona Description
Ops / SRE Runs the container in the hospital data center. Cares about logs, metrics, health, restart safety
Integration developers Add new SATUSEHAT resources, debug failures
Compliance / regulators Need audit trail of submissions for inspection

3. Functional Requirements

3.1 SATUSEHAT FHIR Submission (P0 — core value)

The service MUST expose endpoints for the following 19 FHIR resources, each with Create / Update (full) / Patch (JSON Patch RFC 6902) / Get-by-ID / Search:

# Resource Use case
1 AllergyIntolerance Patient allergy registry
2 CarePlan Treatment plan
3 ClinicalImpression Clinician assessment
4 Composition Document grouping
5 Condition Diagnosis (ICD-10)
6 DiagnosticReport Lab / radiology report
7 Encounter Patient visit (rawat jalan/inap/IGD)
8 EpisodeOfCare Continuous treatment episode
9 ImagingStudy Radiology study link
10 Immunization Vaccination record
11 Medication Drug definition
12 MedicationDispense Pharmacy dispense event
13 MedicationRequest Prescription
14 MedicationStatement Patient-reported medication
15 Observation Vital signs, lab results
16 Procedure Performed procedure (ICD-9-CM)
17 QuestionnaireResponse Form / triage answers
18 ServiceRequest Lab / radiology order
19 Specimen Lab specimen

Plus minimal Studies (DICOM) for imaging linkage.

3.2 SATUSEHAT Reference Lookups (P0)

The service MUST proxy reads to the following SATUSEHAT registries:

  • Patient — search by NIK, name, DOB
  • Practitioner — by NIK or NPP
  • Organization — facility registry
  • Location — room/bed
  • KFA — Katalog Farmasi Alkes (drug & device master)
  • KYC — verifikasi identitas
  • Auth — token refresh / validate

3.3 Authentication & Authorization (P0)

  • Inbound: JWT-based auth (with Keycloak, static-token, and hybrid modes). RBAC via Role / Page / Permission / Access master tables.
  • Outbound: OAuth2 client-credentials flow to SATUSEHAT with concurrency-safe in-memory token caching (≥1 minute buffer before expiry).
  • BPJS: HMAC-SHA256 signature header per BPJS spec (cons-id + secret).

3.4 Storage & Master Data (P1)

  • Multi-database support (Postgres preferred) for:
    • Auth (users, sessions, tokens)
    • Role / Page / Permission / Access (RBAC master)
    • Audit log of SATUSEHAT submissions (TBD — see §7 Gaps)
  • Read replicas with round-robin load balancing.
  • GORM as primary ORM; raw SQL via sqlx / squirrel where ORM is too slow.

3.5 Cross-Cutting (P1)

  • Structured logging (logrus) to console + daily file logs/YYYY/MM/YYYY-MM-DD.log.
  • Prometheus metrics: HTTP request counts/latency, DB pool stats, cache hit ratio, error counters by code.
  • Health endpoints: overall + per-database + external (SATUSEHAT, KFA, KYC).
  • i18n-ready error system (English + Indonesian).
  • Soft-delete + audit trail at the master-data layer.

3.6 Object Storage (P2)

  • MinIO integration for storing supporting artifacts (e.g., DICOM tarballs, KYC scans, consent PDFs). Buckets configurable per environment.

4. Non-Functional Requirements

Category Requirement
Performance P95 latency for outbound SATUSEHAT create ≤ 2 s when SATUSEHAT responds within SLA; service overhead ≤ 50 ms
Throughput ≥ 100 sustained writes/sec per service instance (single-node, 4 vCPU)
Availability 99.5 % (hospital data-center, single instance acceptable; horizontal scale-out supported)
Recovery Graceful shutdown ≤ 5 s; in-flight requests drained on SIGTERM
Security No plaintext secrets in logs; parameterised queries; CORS configurable; rate-limit configurable
Compliance Comply with Permenkes 24/2022 (rekam medis elektronik) and SATUSEHAT IG R4
Observability Every outbound SATUSEHAT call MUST be traceable by request_id (TBD)
Portability Single static binary, distroless image, runs on amd64 Linux
Time zone All timestamps in Asia/Jakarta (WIB); FHIR payloads use ISO-8601 with offset

5. Out-of-Scope Items (deliberately excluded)

  • Web frontend / admin UI.
  • Long-term clinical archival.
  • HL7 v2 messaging.
  • Direct BPJS claim file generation (RBAC adjustments only).
  • Patient-facing mobile API.

6. Dependencies

6.1 External (third-party)

Dependency Purpose Notes
SATUSEHAT FHIR R4 Primary integration target Staging + production base URLs configured
SATUSEHAT KFA Drug & device master Separate endpoint and headers
SATUSEHAT KYC Identity verification Public/private key pair (config)
SATUSEHAT Consent Patient consent Webhook secret configured
SATUSEHAT DICOM Imaging study upload Separate endpoint
BPJS VClaim / Antrol / Apotek / Aplicare / IHS Insurance integration HMAC-SHA256 auth
Keycloak SSO / OAuth2 issuer (optional) JWKS validation

6.2 Internal

  • PostgreSQL 12+ (recommended)
  • Redis 6+ (cache, rate limit) — optional but recommended
  • MinIO (S3-compatible) — optional
  • Prometheus (scrape /metrics)

7. Known Gaps & Risks (carried into DEVPLAN)

# Gap Severity Owner
R1 gRPC defined in config but no .proto files committed and registry empty High Backend
R2 Test coverage ≈ 2 files total — query builder only High Backend
R3 Rate-limit config exists, no middleware implementation Medium Backend
R4 Auth logout does not revoke refresh tokens in DB (TODO at internal/auth/service.go:233) Medium Backend
R5 KYC service does not persist verification to local DB Medium Backend
R6 Role / Page / Permission services have TODO cache invalidation Medium Backend
R7 60+ fmt.Printf debug calls in pkg/utils/query — leaks to stdout in production Low Backend
R8 NoOp cache fallback is not thread-safe (map without mutex) Medium Backend
R9 Folder name typo internal/master/role/accses/ (should be access) Low Backend
R10 Audit-log table for SATUSEHAT submissions not yet defined High Backend
R11 No CI pipeline committed High Ops

8. Success Metrics

Metric Target
SATUSEHAT submission success rate ≥ 99 % (per resource, per hour)
Coverage on internal/satusehat/usecase/** ≥ 60 % unit tests, ≥ 1 contract test per resource
Mean time to add a new FHIR resource ≤ 1 day (via code-gen template)
Production crash-loop incidents 0 per month
Time to detect a SATUSEHAT outage ≤ 1 minute via health probe

9. Release Plan (high-level — detail in DEVPLAN)

Milestone Description
M1 — Hardening Fix R1R3, R7, R8; add CI; unit-test FHIR mappers
M2 — Auditability Implement audit-log table + middleware emitting one row per outbound SATUSEHAT call (R10)
M3 — gRPC Author proto files; generate; register services for at least Encounter, EpisodeOfCare, Condition, Observation
M4 — Resilience Retry with exponential backoff for SATUSEHAT 5xx + circuit breaker
M5 — Production rollout Single-instance deployment in hospital DC, then dual-instance behind nginx

10. Glossary

Term Meaning
SATUSEHAT Indonesia national health-data platform (Kemenkes)
FHIR Fast Healthcare Interoperability Resources (HL7 R4)
BPJS Badan Penyelenggara Jaminan Sosial — Indonesian social insurance
VClaim BPJS claim API
KFA Katalog Farmasi Alkes (drug/device catalogue)
KYC Know Your Customer — identity verification
SIMRS Sistem Informasi Manajemen Rumah Sakit (hospital management system)
IHS Indonesia Health Services (BPJS)
CQRS Command Query Responsibility Segregation
DDD Domain-Driven Design