Case Study 2: MedClaim's Adjudication Engine Parameter Architecture

Background

MedClaim's claims adjudication engine processes 500,000 insurance claims per month. Each claim passes through six processing stages: eligibility verification, benefit determination, pricing, deductible/copay calculation, payment calculation, and audit trail writing. When James Okafor redesigned the engine in 2020, his central challenge was: how should data flow between these six tightly coupled stages?

"The old system passed 15 separate parameters between programs," James recalls. "The CALL statement wrapped across four lines. Adding a new field meant changing the CALL statement and the PROCEDURE DIVISION USING in every program. We once introduced a bug by adding a parameter in position 7 in the caller but position 8 in the callee. That cost us a week."

The Design Challenge

Each adjudication stage needs different data:

  • Eligibility needs member information and service dates
  • Benefits needs eligibility results plus plan information
  • Pricing needs procedure codes and provider information
  • Deductible needs pricing results plus member's year-to-date totals
  • Payment needs all of the above
  • Audit needs everything

With separate parameters, the later stages would require increasingly long parameter lists. And every stage's output becomes the next stage's input — a classic pipeline.

The Solution: Unified COMMAREA

James designed a single communication area (ADJUD-COMMAREA) that carries all data through the pipeline:

      *================================================================
      * COMARECP — MedClaim Adjudication COMMAREA
      * Version: 3.2 — Last updated: 2024-01-15
      *
      * CHANGE HISTORY:
      * v3.2: Added CA-TELEHEALTH-FLAG for virtual visit support
      * v3.1: Added CA-PRIOR-AUTH fields
      * v3.0: Complete redesign for ICD-11 support
      *================================================================
       01  ADJUD-COMMAREA.
      *    --- Control Section ---
           05  CA-CONTROL.
               10  CA-FUNCTION        PIC X(4).
               10  CA-STEP-NUMBER     PIC 9(2).
               10  CA-TIMESTAMP       PIC X(26).
               10  CA-USER-ID         PIC X(8).
               10  CA-BATCH-ID        PIC X(12).
               10  CA-TRACE-LEVEL     PIC 9.
                   88  CA-NO-TRACE    VALUE 0.
                   88  CA-TRACE-ERROR VALUE 1.
                   88  CA-TRACE-ALL   VALUE 9.

      *    --- Claim Input Section ---
           05  CA-CLAIM-INPUT.
               10  CA-CLAIM-ID        PIC X(15).
               10  CA-MEMBER-ID       PIC X(12).
               10  CA-PROVIDER-ID     PIC X(10).
               10  CA-FACILITY-ID     PIC X(10).
               10  CA-SERVICE-DATE    PIC 9(8).
               10  CA-SUBMIT-DATE     PIC 9(8).
               10  CA-TELEHEALTH-FLAG PIC X.
                   88  CA-TELEHEALTH  VALUE 'Y'.
               10  CA-PRIOR-AUTH-NUM  PIC X(15).

      *    --- Diagnosis Codes (up to 12) ---
           05  CA-DIAGNOSES.
               10  CA-DIAG-COUNT      PIC 9(2).
               10  CA-DIAG-ENTRY OCCURS 12 TIMES.
                   15  CA-DIAG-CODE   PIC X(8).
                   15  CA-DIAG-DESC   PIC X(40).
                   15  CA-DIAG-TYPE   PIC X.

      *    --- Procedure Lines (up to 25) ---
           05  CA-PROCEDURES.
               10  CA-PROC-COUNT      PIC 9(2).
               10  CA-PROC-LINE OCCURS 25 TIMES.
                   15  CA-PROC-CODE   PIC X(5).
                   15  CA-PROC-MOD    PIC X(2) OCCURS 4.
                   15  CA-PROC-UNITS  PIC 9(3).
                   15  CA-CHARGE-AMT  PIC S9(7)V99 COMP-3.
                   15  CA-ALLOWED-AMT PIC S9(7)V99 COMP-3.
                   15  CA-PAID-AMT    PIC S9(7)V99 COMP-3.
                   15  CA-LINE-STATUS PIC X(2).

      *    --- Eligibility Results (set by ADJELIG) ---
           05  CA-ELIG-RESULTS.
               10  CA-ELIG-STATUS     PIC X(2).
                   88  CA-ELIG-ACTIVE VALUE 'AC'.
                   88  CA-ELIG-TERMED VALUE 'TR'.
                   88  CA-ELIG-COBRA  VALUE 'CB'.
               10  CA-PLAN-ID         PIC X(10).
               10  CA-GROUP-ID        PIC X(10).
               10  CA-EFF-DATE        PIC 9(8).
               10  CA-TERM-DATE       PIC 9(8).

      *    --- Benefit Results (set by ADJBNFT) ---
           05  CA-BENEFIT-RESULTS.
               10  CA-COVERED-FLAG    PIC X.
               10  CA-BENEFIT-PCT     PIC 9(3).
               10  CA-COPAY-TYPE      PIC X.
               10  CA-COPAY-FLAT      PIC S9(5)V99 COMP-3.
               10  CA-DEDUCT-APPLIES  PIC X.
               10  CA-MAX-BENEFIT     PIC S9(7)V99 COMP-3.

      *    --- Financial Results (set by ADJDEDC/ADJPAY) ---
           05  CA-FINANCIAL-RESULTS.
               10  CA-TOTAL-CHARGES   PIC S9(9)V99 COMP-3.
               10  CA-TOTAL-ALLOWED   PIC S9(9)V99 COMP-3.
               10  CA-TOTAL-DEDUCT    PIC S9(7)V99 COMP-3.
               10  CA-TOTAL-COPAY     PIC S9(7)V99 COMP-3.
               10  CA-TOTAL-COINS     PIC S9(7)V99 COMP-3.
               10  CA-TOTAL-PAID      PIC S9(9)V99 COMP-3.
               10  CA-MEMBER-RESP     PIC S9(9)V99 COMP-3.

      *    --- Error Section ---
           05  CA-ERROR-INFO.
               10  CA-RETURN-CODE     PIC S9(4) COMP.
                   88  CA-SUCCESS     VALUE 0.
                   88  CA-WARNING     VALUE 4.
                   88  CA-ERROR       VALUE 8.
                   88  CA-SEVERE      VALUE 12.
               10  CA-ERROR-COUNT     PIC 9(2).
               10  CA-ERRORS.
                   15  CA-ERR-ENTRY OCCURS 10 TIMES.
                       20  CA-ERR-STEP    PIC 9(2).
                       20  CA-ERR-CODE    PIC X(8).
                       20  CA-ERR-MSG     PIC X(50).
                       20  CA-ERR-FIELD   PIC X(20).

Key Design Decisions

Decision 1: BY REFERENCE for the COMMAREA

Since all stages need to both read and modify the COMMAREA, it is always passed BY REFERENCE:

CALL 'ADJELIG' USING BY REFERENCE ADJUD-COMMAREA

James considered passing some sections BY CONTENT to protect them, but rejected it: "The copy overhead for a structure this size — about 3KB — multiplied by 500,000 claims is significant. And every stage needs to write its results into the structure. BY REFERENCE is the right choice here."

Decision 2: Accumulating Errors

Rather than stopping at the first error, the COMMAREA accumulates up to 10 errors. This allows the system to report all validation failures in a single pass:

       ADD-ERROR.
           IF CA-ERROR-COUNT < 10
               ADD 1 TO CA-ERROR-COUNT
               MOVE CA-STEP-NUMBER TO
                   CA-ERR-STEP(CA-ERROR-COUNT)
               MOVE WS-ERR-CODE TO
                   CA-ERR-CODE(CA-ERROR-COUNT)
               MOVE WS-ERR-MSG TO
                   CA-ERR-MSG(CA-ERROR-COUNT)
           END-IF

      *    Set return code to highest severity
           IF WS-ERR-SEVERITY > CA-RETURN-CODE
               MOVE WS-ERR-SEVERITY TO CA-RETURN-CODE
           END-IF.

Decision 3: Version Control via FILLER

To support backward compatibility when the COMMAREA grows, James reserved space at the end:

      *    --- Reserved for future use ---
           05  CA-RESERVED         PIC X(200).

When new fields are needed, they are added by reducing CA-RESERVED and defining new fields before it. Existing compiled programs that pass the full COMMAREA continue to work because the overall structure size does not change.

Results

Metric 15-Parameter Design COMMAREA Design
CALL statement complexity 4-5 lines per CALL 1 line per CALL
Risk of parameter order bugs High Eliminated
Adding a new data field Change 12 programs Change copybook only
Error reporting First error only Up to 10 errors
Cross-stage data access Complex chaining Direct field access

Sarah Kim observed the business impact: "When we needed to add telehealth support during the 2020 pandemic, we added CA-TELEHEALTH-FLAG to the COMMAREA, modified ADJBNFT to check it, and deployed in three days. Under the old architecture, that would have been a three-week project touching six programs."

Limitations Encountered

  1. Structure size: At 3KB, the COMMAREA is not small. In CICS, where COMMAREAs are limited (typically 32KB max, but best practice is under 4KB), this is close to the limit.

  2. Every program sees everything: The pricing module can read and modify eligibility results, even though it should not need to. Discipline replaces enforcement.

  3. Binary compatibility: Recompiling only some programs after a copybook change can cause alignment issues if COMP fields shift position.

Discussion Questions

  1. James rejected BY CONTENT for performance reasons. At what COMMAREA size would the copy overhead become negligible compared to other processing costs? How would you measure this?

  2. The reserved space pattern (CA-RESERVED) provides forward compatibility. What happens when the reserved space runs out? How would you handle a major restructuring?

  3. Each subprogram has access to the entire COMMAREA, including sections it should not modify. How would you enforce access discipline without compiler support?

  4. The error accumulation pattern stops at 10 errors. What should the system do if more than 10 errors occur? Is there a better approach?

  5. If you were redesigning this system today, would you still use a single COMMAREA, or would you split it into smaller, stage-specific structures? What factors would influence your decision?