Service Map
Olly is composed of 14 Go services, each owning its own PostgreSQL database and event stream. Services communicate synchronously via gRPC/REST for blocking lookups (eligibility checks, provider NPI verification) and asynchronously via Kafka for event-driven workflows (enrollment sagas, payment pipelines). Every service follows the same internal layout: cmd/server/main.go → config → DB migrations → dependency wiring → HTTP server.
Service Summary
| Service | Port | Database | Publishes Events? | Consumes Events? | Notes |
|---|---|---|---|---|---|
| claims | 4001 | claims | Yes — claims.* | Yes — billing.payment.completed | Core adjudication engine; calls eligibility + provider synchronously |
| eligibility | 4002 | eligibility | Yes — eligibility.coverage.* | Yes — enrollment.*, provider.credentialing.* | Maintains accumulator balances; responds to 270/271 FHIR queries |
| enrollment | 4003 | enrollment | Yes — enrollment.*, enrollment.cobra.* | Yes — billing.payment.missed | Temporal workflows for COBRA timelines; EDI 834 ingest |
| billing | 4004 | billing | Yes — billing.* | Yes — claims.claim.adjudicated, enrollment.* | Initiates ACH provider payments; manages premium invoicing |
| provider | 4005 | provider | Yes — provider.* | No | Temporal workflows for credentialing; NPPES/CAQH document processing |
| notifications | 4006 | notifications | No | Yes — claims.*, enrollment.*, billing.*, provider.* | Fan-in consumer; dispatches via FCM, Twilio, SendGrid |
| policy-admin | 4007 | policy_admin | No | No | Manages plan configurations, benefit rules, rate tables; feeds OpenSearch |
| triage | 4008 | triage | No | No | AI-assisted symptom triage and clinical routing |
| care | 4009 | care | No | No | Care management, chronic condition tracking, care plans |
| group-scheme | 4010 | group_scheme | No | No | Employer group setup, census management, open enrollment windows |
| broker-api | 4011 | broker | No | No | Broker/agent commission tracking and quoting |
| consent | 4012 | consent | Yes — consent.* | No | PHI consent records; HIPAA authorization management |
| document-service | 4013 | documents | No | No | EOB PDF generation, S3 storage, signed URL delivery |
| member-portal-api | 4014 | member_portal | No | No | BFF for member web portal; aggregates claims, coverage, billing data |
Service Patterns
Outbox Pattern
Every service that publishes to Kafka uses the transactional outbox pattern. Within the same database transaction as the business write, the service inserts a row into its local outbox table containing the topic, key, and serialized Avro payload. A background goroutine polls the outbox table, publishes each row to Kafka, then deletes it. This guarantees exactly-once semantics between the database state and the Kafka event — a service restart between publish and delete is safe because the outbox row will be re-published on restart (idempotent consumers deduplicate using an ElastiCache set with a 24-hour TTL).
Saga Pattern
Multi-step workflows that span service boundaries are implemented as choreography-based sagas. There is no central saga orchestrator. Each service listens for events it cares about, performs its local action, and emits the next event. Compensation events handle rollback paths (e.g., enrollment.enrollment.cancelled rolls back pending coverage records and staged invoices). Temporal is used for long-running sagas with durable timers — COBRA election windows (60 days), credentialing recheck schedules, and grace period expirations.
Projection Tables
Services that need to query data owned by another service maintain local projection tables populated by Kafka events. For example, the Claims Service maintains a member_accumulators projection updated by eligibility.coverage.verified events. This avoids synchronous cross-service queries for hot-path operations and eliminates inter-service coupling at query time.
Internal vs External Routes
Routes prefixed /internal/ bypass JWT middleware — they are accessible only from within the service mesh (enforced at the Istio network policy level). External routes under /v1/ require a valid Bearer token and are subject to OPA authorization. EDI ingest endpoints (/internal/claims/edi-ingest, /internal/enrollment/edi-ingest) are internal-only, called by Mirth Connect over mTLS.
Inter-Service Call Graph (Synchronous)
The following shows synchronous HTTP/gRPC calls between services. Async Kafka flows are covered in Event Flow.