update All feture and service

This commit is contained in:
meninjar
2026-06-03 02:54:26 +00:00
parent af32d9cfdd
commit ce0fa1a291
98 changed files with 272469 additions and 1606 deletions
+252
View File
@@ -0,0 +1,252 @@
# 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 |