Enterprise Integration — Quick Reference
One-Line Definition
Enterprise integration for AI connects LLM inference, RAG pipelines, and AI workflows to the existing enterprise data landscape — EHRs, data warehouses, event buses, ESB middleware, and identity providers — without bypassing the governance controls those systems enforce.
Pattern Selection Guide
| Requirement | Pattern | Implementation |
|---|---|---|
| User waiting; < 5s SLA | Synchronous | REST with timeout + fallback |
| User waiting; 5–60s | SSE streaming | FastAPI + StreamingResponse |
| Server-to-server; minutes | Async + Webhook | Kafka + HMAC webhook |
| Offline / scheduled | Batch | Airflow DAG + checkpointing |
| Client behind firewall | Async + Polling | Job submission → GET /jobs/{id} |
FHIR R4 — Quick Reference
Minimum FHIR Reads for Clinical RAG Context
GET /Patient/{id}
GET /Encounter/{id}
GET /Condition?patient={id}&clinical-status=active
GET /MedicationRequest?patient={id}&status=active
GET /Observation?patient={id}&category=laboratory&date=ge{30d_ago}
GET /AllergyIntolerance?patient={id}Always execute in parallel (asyncio.gather) — sequential FHIR reads in CDS Hooks will exceed the 5-second EHR timeout.
AI Document Write
{
"resourceType": "DocumentReference",
"docStatus": "preliminary", # ✅ AI drafts are ALWAYS "preliminary"
"status": "current",
"type": {"coding": [{"system": "http://loinc.org", "code": "18842-5"}]},
"content": [{"attachment": {"contentType": "text/plain", "data": "<base64>"}}],
"extension": [{"url": "...ai-generated", "valueBoolean": True}]
}CDS Hooks Response Pattern
# EHR SLA: respond within 5 seconds or return empty cards
try:
cards = await asyncio.wait_for(_generate_cards(request), timeout=4.5)
except asyncio.TimeoutError:
return CDSResponse(cards=[]) # Empty cards, never block EHRSMART on FHIR — Quick Reference
Minimum Necessary Scopes
CDS Hooks (read-only):
system/Patient.read
system/Encounter.read
system/Condition.read
system/MedicationRequest.read
system/Observation.read
system/AllergyIntolerance.read
AI Document Write (adds):
system/DocumentReference.writeNever request: system/*.read — over-broad scope is a HIPAA minimum-necessary violation.
Backend Service Auth Flow
1. Build JWT assertion (iss, sub, aud, exp, jti)
2. Sign with RSA-384 private key registered with EHR
3. POST to token_endpoint:
grant_type=client_credentials
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion={JWT}
4. Receive access_token (typically 1-hour expiry)
5. Use in Authorization: Bearer {token} for all FHIR calls
6. Refresh 60 seconds before expiryKafka Event-Driven AI — Quick Reference
Topic Design Rules
Partition by patient_id → guarantees per-patient event ordering
Retention: 7 days minimum → allows replay on consumer restart
DLQ topic: retain 30 days → investigation window for failuresConsumer Idempotency Pattern
# Check before processing; commit only after success
if await dedup_cache.exists(f"processed:{event.event_id}"):
await consumer.commit()
return
try:
await ai_processor.process(event)
await dedup_cache.setex(f"processed:{event.event_id}", 86400, "1")
await consumer.commit()
except Exception:
await route_to_dlq(event)
await consumer.commit() # commit to avoid infinite retryNever: enable<em>auto</em>commit=True — commits before processing; events are lost on crash.
Consumer Lag Alerts
>1000 messages sustained for 5m → CRITICAL (scale out consumers)
DLQ growing >10 messages → WARNING (investigate failures)Webhook Security — Quick Reference
Signature Pattern
# Sender: sign every delivery
signature = hmac.new(secret, payload_bytes, sha256).hexdigest()
headers["X-AI-Platform-Signature"] = f"sha256={signature}"
# Receiver: verify before processing
expected = hmac.new(secret, body, sha256).hexdigest()
if not hmac.compare_digest(expected, received[7:]): # strip "sha256="
return 401 # Reject unverified webhooksRetry Policy
Attempt 1: 5 seconds
Attempt 2: 30 seconds
Attempt 3: 2 minutes
Attempt 4: 10 minutes
Attempt 5: 30 minutes → DLQ on failureSSE Streaming — Quick Reference
# FastAPI SSE response
return StreamingResponse(
generator(),
media_type="text/event-stream",
headers={
"Cache-Control": "no-cache",
"X-Accel-Buffering": "no", # Required: disable nginx buffering
}
)
# Token event format
yield f"data: {json.dumps({'type': 'token', 'content': text})}\n\n"
# Heartbeat (every 15s to prevent proxy timeout)
yield ": keep-alive\n\n"
# Completion event
yield "data: [DONE]\n\n"Identity & Access — Quick Reference
Credential Rules
✅ Store API keys in Secrets Manager (AWS) or Key Vault (Azure)
✅ Retrieve at runtime; cache for 5 minutes
✅ Rotate on 90-day schedule (LLM API keys)
✅ Dedicated service account per AI platform component
❌ Never hardcode credentials in config or environment variables
❌ Never share service accounts across componentsCommon Interview Questions
Q: A CDS Hook response is timing out. What are the likely causes? (1) FHIR reads in series instead of parallel — fix with asyncio.gather. (2) AI inference too slow — add 4.5s timeout and return empty cards. (3) No FHIR prefetch configured — EHR makes extra round-trip on every hook call. Always configure prefetch for the FHIR resources the hook needs.
Q: A Kafka consumer is processing duplicate events and writing duplicate AI documents to the EHR. What's the root cause? enable<em>auto</em>commit=True commits the offset before processing. If the consumer crashes between commit and writing to EHR, the event is committed (won't be retried) but the write didn't happen. The reverse — commit after processing — means crashed consumers will reprocess. Fix: manual commit after successful processing + idempotency check (event_id in dedup cache).
Q: What FHIR scopes would you request for a CDS Hooks service? Only the specific resource types the hook reads: Patient.read, Encounter.read, Condition.read, MedicationRequest.read, Observation.read, AllergyIntolerance.read — all as system/ scopes for backend service auth. Never system/*.read. Document write scope only if the hook writes back to the EHR.