DEV Community

Choirunnisa Hapsari
Choirunnisa Hapsari

Posted on • Originally published at medminutes.io

Building an AI Clinical Decision Support System (CDSS) for Indonesian Hospitals

Medication errors remain one of the leading causes of preventable patient harm worldwide. The WHO estimates that unsafe medication practices cost $42 billion annually and that CDSS implementations can reduce prescribing errors by up to 55%. In Indonesia, where over 2,800 hospitals serve 270+ million people, the challenge is amplified by fragmented health IT systems and varying levels of digital maturity.

This article walks through how we approached building a Clinical Decision Support System (CDSS) tailored to Indonesian hospital workflows — the architecture decisions, module design, and integration patterns that make it work in practice.

The Regulatory Push

Indonesia's Permenkes No. 24/2022 on Electronic Medical Records explicitly calls for clinical decision support capabilities in hospital information systems. This isn't just a nice-to-have — hospitals pursuing accreditation (SNARS) need to demonstrate medication safety protocols, and CDSS directly supports that requirement.

The regulation also aligns with the broader SATUSEHAT national health data platform initiative, which mandates HL7 FHIR-based interoperability. Any CDSS needs to work within this ecosystem.

Architecture: Why a Chrome Extension + API Gateway

Here's the reality in Indonesian hospitals: most already run some form of SIMRS (Hospital Information System) or RME (Electronic Medical Record). Ripping that out and replacing it is expensive, disruptive, and politically difficult.

Our approach: overlay, don't replace.

┌─────────────────────────────────────────────┐
│  Hospital Browser (any SIMRS/RME web app)   │
│  ┌───────────────────────────────────────┐  │
│  │  Chrome Extension (Content Script)     │  │
│  │  - Reads clinical context from DOM     │  │
│  │  - Injects CDSS overlay panels         │  │
│  │  - Sends anonymized queries to API     │  │
│  └──────────────┬────────────────────────┘  │
└─────────────────┼───────────────────────────┘
                  │ HTTPS
┌─────────────────▼───────────────────────────┐
│  API Gateway (Cloud Run — Jakarta region)    │
│  - Authentication & rate limiting            │
│  - Routes to appropriate CDSS module         │
│  - Tier-based access control                 │
├──────────────────────────────────────────────┤
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│  │ ICD-10   │ │ Drug     │ │ AI Resume    │ │
│  │ Engine   │ │ Interact.│ │ Generator    │ │
│  └──────────┘ └──────────┘ └──────────────┘ │
└──────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

The Chrome Extension reads the clinical context from whatever web-based SIMRS the hospital is using, then sends queries to our Cloud Run API Gateway deployed in the Jakarta (asia-southeast2) region for low latency. This means zero changes to the hospital's existing system.

The 4 CDSS Modules

1. SOAP Extraction

Extracts structured SOAP (Subjective, Objective, Assessment, Plan) data from free-text clinical notes in the RME. This feeds downstream modules.

# Simplified extraction flow
def extract_soap(clinical_note: str) -> SOAPResult:
    """Extract SOAP components using LLM with medical prompt."""
    response = model.generate(
        prompt=SOAP_EXTRACTION_PROMPT,
        input_text=clinical_note,
        output_schema=SOAPSchema
    )
    return validate_soap(response)
Enter fullscreen mode Exit fullscreen mode

2. ICD-10 AI Recommendations

Takes the extracted SOAP data and suggests appropriate ICD-10 and ICD-9-CM codes. This is powered by a FastAPI backend with ChromaDB for vector similarity search against the full ICD codeset, combined with Gemini 2.0 Flash for contextual reasoning.

# ICD recommendation engine
@app.post("/api/icd/recommend")
async def recommend_icd(soap: SOAPInput):
    # Vector search for candidate codes
    candidates = chromadb_collection.query(
        query_texts=[soap.assessment],
        n_results=10
    )
    # LLM re-ranking with clinical context
    ranked = await rerank_with_context(
        candidates=candidates,
        soap=soap,
        coding_guidelines=ICD_10_RULES
    )
    return ranked[:5]  # Top 5 recommendations
Enter fullscreen mode Exit fullscreen mode

Why this matters: accurate ICD coding directly affects BPJS (national insurance) claim approval rates. Miscoding means rejected claims, which means revenue loss for the hospital.

3. Drug Interaction Detection

Real-time detection of drug-drug interactions when a physician prescribes medication. The interaction database covers severity levels (minor, moderate, major, contraindicated) and includes Indonesian formulary (FORNAS) context.

// Example API response
{
  "interaction_found": true,
  "severity": "major",
  "drug_a": "Warfarin",
  "drug_b": "Aspirin",
  "mechanism": "Increased bleeding risk via additive anticoagulant effects",
  "recommendation": "Consider alternative or adjust dosing with INR monitoring",
  "references": ["DrugBank:DB00682", "MIMS Indonesia"]
}
Enter fullscreen mode Exit fullscreen mode

4. AI Medical Resume Generator

Automatically generates structured medical resumes (discharge summaries) from the patient's encounter data. This saves physicians significant documentation time — in our observations, 15-30 minutes per patient discharge.

Integration Pattern: The Overlay Approach

The key insight is that hospital IT teams are cautious (rightfully so). A Chrome Extension gives us:

  • Zero infrastructure changes at the hospital
  • Gradual rollout — install on one workstation, test, then expand
  • Works with any web-based SIMRS — we read DOM elements, not database tables
  • Easy updates — push new extension versions without hospital IT involvement

The extension uses content scripts to detect which SIMRS is running, then applies the appropriate DOM selectors to extract clinical context:

// Detect SIMRS and load appropriate adapter
const adapters = {
  "simrs-khanza": KhanzaAdapter,
  "e-puskesmas": EPuskesmasAdapter,
  generic: GenericFormAdapter,
};

const detected = detectSIMRS(document);
const adapter = new adapters[detected]();
const clinicalContext = adapter.extractContext();
Enter fullscreen mode Exit fullscreen mode

Deployment Considerations

Indonesian hospitals have diverse IT setups. Some have reliable internet; others are in remote areas with intermittent connectivity. We support both:

  • Cloud deployment: API Gateway on Cloud Run (Jakarta region), auto-scaling, pay-per-request
  • On-premise deployment: Docker containers for hospitals that require data to stay on-site (common for military and government hospitals)

Latency matters in clinical workflows. A drug interaction check that takes 5 seconds won't get used. Our p95 response time for the Drug Interaction module is under 200ms from Jakarta-region hospitals.

What We Learned

  1. Clinician trust is earned, not assumed. We added confidence scores and literature references to every recommendation. Physicians won't act on a black-box suggestion.

  2. Local formulary matters. International drug databases don't cover all medications available in Indonesia. We maintain an Indonesian drug mapping layer.

  3. Start with one module. Hospitals that adopted Drug Interaction first, then expanded to ICD recommendations, had much higher sustained usage than those that tried to deploy everything at once.

  4. Regulatory alignment opens doors. Framing CDSS as a Permenkes 24/2022 compliance tool made procurement conversations significantly easier.

Resources


MedMinutes builds health IT tools for Indonesian hospitals, including AI-powered CDSS, claim audit systems, and SATUSEHAT integration. We're based in Indonesia and serve 50+ hospitals across 8+ provinces.

Top comments (0)