Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Clearinghouse Integration — Integration
Version: 2.0.0Status: 📝 Planned
Last Updated: 2026-03-27
Spec (Phase 1): PM-15 Clearinghouse Integration
Spec (Phase 2): PM-15-P2 Production Clearinghouse Transport
Constitution Reference: Section 1.3 (Integration Patterns), Section 2.1 (Integration points documented in
/docs/architecture/integrations/)
Quick Reference
| I need to… | Pattern | Location |
|---|---|---|
| Submit a claim batch (SFTP) | ClearinghouseAdapter.submitBatchFile() | supabase/functions/_shared/transport/ (Phase 2a) |
| Submit a single claim (REST API) | ClearinghouseAdapter.submitClaim() | src/cores/pm/types/clearinghouse.ts |
| Retrieve ERA/835 from clearinghouse | ClearinghouseAdapter.fetchRemittance() | Same adapter interface |
| Check eligibility via 270/271 | ClearinghouseAdapter.checkEligibility() | Same adapter interface |
| Generate X12 837P from claims | generate837P(claims, config) | supabase/functions/_shared/x12/generate-837p.ts (Phase 2b) |
| Parse 835 ERA file | parse835(x12Content) | supabase/functions/_shared/x12/parse-835.ts (Phase 2b) |
| Configure clearinghouse connection | pm_clearinghouse_config table | PM-15-T1 migration |
| Schedule batch submission | pm_clearinghouse_config.submission_schedule | Phase 2a migration |
| View connection health | pm_clearinghouse_config.health_status | Phase 2c; gated by pm.clearinghouse.view |
| View transaction audit log | pm_transaction_log (append-only) | RLS: SELECT only |
Decision Tree
-
Need to submit a claim electronically?
→ Use PM-15
ClearinghouseAdapter.submitClaim()via PM-08 claim workflow. → Credentials resolved from vault refs at runtime; never stored in code. -
Need to process an ERA/835?
→ Use
ClearinghouseAdapter.fetchRemittance()→ parse → feed PM-09 payment posting. → 835 SVC segments map topm_claim_lines. -
Need to check eligibility in real-time?
→ Use
ClearinghouseAdapter.checkEligibility()for 270/271 (PM-02 integration).
Common Mistakes
| Symptom | Fix |
|---|---|
| Credentials in code or migration | Store as vault refs in pm_clearinghouse_config; resolve at runtime in edge function |
| Missing org filter on batch queries | Add .eq('organization_id', orgId) to all mutations |
Editing pm_transaction_log rows | Table is append-only; RLS denies UPDATE/DELETE |
| Direct import from PM-08 hooks | Use adapter interface; PM-15 is invoked by PM-08, not the reverse |
Pre-Flight Checklist
- PM-08 and PM-09 schemas exist (claims, claim_lines, payments)
- Vault refs configured for clearinghouse credentials
- RLS enabled with FORCE on all four tables
- UPDATE policies include WITH CHECK
- No secrets in code, migrations, or docs
Overview
PM-15 provides clearinghouse connectivity for ANSI X12 transactions (837P/I, 835, 270/271, 276/277, 278, 999/277CA). It defines the data model (pm_clearinghouse_config with clearinghouse_provider, sender_id, receiver_id, connection_type, vault refs, host/port/paths or api_endpoint; pm_transaction_batches, pm_transaction_log, pm_payer_enrollments), RLS, and the generic ClearinghouseAdapter interface. Implementations (Waystar first, then Availity, Change Healthcare, etc.) are configured per organization; credentials are stored in vault only.
Integration Points
| Dependency | Pattern | Purpose |
|---|---|---|
| PM-08 | Data / API | Claim submission: PM-08 builds claim and invokes adapter submitClaim(); 999/277CA and line-level rejections feed PM-08 denial workflow. |
| PM-09 | Data / API | ERA retrieval: adapter fetchRemittance() returns 835; SVC segments map to pm_claim_lines; line-level posting. |
| PM-02 | API | Eligibility: adapter checkEligibility() for 270/271 (when supported by clearinghouse). |
| PM-10 | API | Prior auth: adapter submitPriorAuth() for 278 (when supported). |
| External clearinghouse | API / SFTP | Waystar (and future adapters): REST or sFTP per pm_clearinghouse_config.connection_type; credentials via vault refs. |
API / Adapter Contract
Clearinghouse adapter interface is defined in X12 EDI Technical Design.Phase 1 methods (adapter interface)
| Method | Description |
|---|---|
submitClaim(claimId, payload) | 837P/I REST per-claim submission; returns trace/reference |
fetchRemittance(config) | Retrieve 835 file; returns raw X12 content for Phase 2b parser |
checkEligibility(config, request) | 270/271 eligibility inquiry/response (PM-02) |
checkClaimStatus(config, traceId) | 276/277 claim status inquiry/response |
submitPriorAuth(config, request) | 278 prior auth (PM-10; Phase 3) |
validateCredentials(config) | SFTP handshake or API ping for health check |
getSubmissionWindow() | Submission window per clearinghouse |
Phase 2a additions (transport layer)
| Method | Description | Location |
|---|---|---|
submitBatchFile(config, x12Content, fileName) | SFTP batch file upload; returns remote file path | supabase/functions/_shared/transport/sftp-transport.ts |
downloadFile(config, remoteFileName) | SFTP file download; returns raw file content | Same |
| Waystar OAuth2 token | Acquired and cached per invocation via waystar-rest-transport.ts | supabase/functions/_shared/transport/waystar-rest-transport.ts |
| Retry logic | Exponential backoff (2s, 4s, 8s); max 3 retries; dead-letter → clearinghouse_batch_error event | supabase/functions/_shared/transport/retry.ts |
Phase 2b additions (X12 utilities — shared, pure TypeScript)
| Utility | Input | Output | Location |
|---|---|---|---|
generate837P(claims, config) | pm_claims + pm_claim_lines + COB (PM-30) | X12 837P string | _shared/x12/generate-837p.ts |
parse835(x12Content) | Raw 835 X12 string | pm_era_files metadata + CLP/SVC payment data | _shared/x12/parse-835.ts |
generate270(config, request) | Eligibility inquiry params | X12 270 string | _shared/x12/generate-270.ts |
parse271(x12Content) | Raw 271 X12 string | Structured eligibility response | _shared/x12/parse-271.ts |
parse999(x12Content) | Raw 999 X12 string | Functional ack status + error codes | _shared/x12/parse-999.ts |
parse277CA(x12Content) | Raw 277CA X12 string | Line-level rejection statuses | _shared/x12/parse-277ca.ts |
buildEnvelope(params) | ISA/GS/ST params | X12 envelope segments | _shared/x12/envelope.ts |
835 parser → PM-09 interface
The Phase 2b 835 parser writes to PM-09-owned tables:- Creates
pm_era_filesrecord:file_name,received_date,payer_id(from GS/TRN),check_eft_number,total_paid,claim_count,status = 'received' - Emits
clearinghouse_era_receivedevent (payload below) for PM-09 to pick up - PM-09 payment posting pipeline consumes the event and creates
pm_payments+pm_payment_applications
era_file_id.
Pattern Library
- Adapter abstraction pattern: PM workflows call
ClearinghouseAdaptermethods, not vendor SDKs directly. - Vault reference pattern: runtime credential resolution from
pm_clearinghouse_config, never plaintext secrets in code. - Append-only ledger pattern:
pm_transaction_logis immutable and used for traceability.
Event Contracts
Events are defined in EVENT_CONTRACTS.md. Phase 2 adds the following:| Event | Emitter | Consumers | Payload |
|---|---|---|---|
clearinghouse_batch_submitted | clearinghouse-submit edge fn | PM-08 (batch status tracking) | { batch_id, organization_id, claim_count, transport_type: 'sftp' | 'api' } |
clearinghouse_batch_error | clearinghouse-submit (dead-letter after 3 retries) | PM-08 (denial routing), PF-10 (billing admin alert) | { batch_id, organization_id, transport_error: string, retry_count: number } |
clearinghouse_era_received | clearinghouse-retrieve after creating pm_era_files | PM-09 (payment posting) | { era_file_id, organization_id, batch_id, claim_count, total_paid } |
clearinghouse_health_changed | clearinghouse-health-check on status transition | PF-10 (alert on down/degraded; throttled recovery on 2× healthy) | { config_id, organization_id, old_status, new_status, checked_at } |
Note:clearinghouse_batch_submittedandclearinghouse_batch_errorwere defined in Phase 1 (PM-15 Errata F-5).clearinghouse_era_receivedandclearinghouse_health_changedare new in Phase 2.
Phase 2c: Connection Health Monitoring
Theclearinghouse-health-check edge function runs every 30 minutes (Supabase cron) and performs a connection test (SFTP handshake via validateCredentials() or Waystar API ping):
- On status change → updates
pm_clearinghouse_config.health_statusandlast_health_check_at - On
downordegraded→ emitsclearinghouse_health_changedimmediately; PF-10 alert fired - On recovery to
healthy→ requires 2 consecutive healthy checks before emitting recovery event (anti-flap throttle) - Health badge in UI is gated by
pm.clearinghouse.view
Security & Tenant Isolation
- All clearinghouse tables are scoped by
organization_id; RLS and SECURITY DEFINER helpers enforce isolation. - Credentials stored in vault only; config holds vault refs; resolution at runtime in edge function or backend.
- PHI in 837/835: encrypt in transit (TLS); audit access to batch and transaction log.
References
- PM-15: Clearinghouse Integration — Phase 1 (tables, RLS, adapter interface, UI stubs)
- PM-15-P2: Production Clearinghouse Transport — Phase 2 (transport, X12, health monitoring)
- PM-15: Clearinghouse Vendor Selection & Waystar-First Integration
- PM-09: Payment Posting & ERA Processing —
pm_era_files,pm_payments,pm_payment_applicationsschema - X12 EDI Technical Design
- REGULATORY_COMPLIANCE_TRACKER.md — PM-15-P2 HIPAA EDI Transport row