Case Study 26.2: MedClaim's External Validation Library

Background

MedClaim's claim processing system validated diagnosis codes (ICD-10) and procedure codes (CPT) against an internal table — a COBOL copybook containing 72,000 ICD-10 codes and 10,000 CPT codes. This table required quarterly updates when the American Medical Association released new CPT codes and the WHO released ICD-10 updates.

The update process was painful: Sarah Kim would receive a spreadsheet of changes, a programmer would manually update the copybook, the affected programs would be recompiled, tested, and migrated to production. The entire cycle took 3-4 weeks and was error-prone — twice in the past year, valid codes had been incorrectly rejected because of copy-paste errors in the copybook update.

The Opportunity

A healthcare industry consortium offered a C library (libmedcodes) that: - Contained the complete, current ICD-10 and CPT code sets - Was updated monthly via an automated process - Provided validation, description lookup, and code relationship queries - Was used by 200+ healthcare organizations

James Okafor saw an opportunity to eliminate the manual copybook update entirely.

Technical Challenges

Challenge 1: String format mismatch. The C library expected null-terminated ASCII strings. MedClaim's COBOL programs used space-padded EBCDIC strings. Every code passed to the library needed conversion.

Challenge 2: EBCDIC to ASCII. On z/OS, COBOL strings are in EBCDIC encoding. The C library expected ASCII. The Language Environment could handle this conversion, but it needed to be explicitly configured.

Challenge 3: Thread safety. MedClaim's CICS region processed claims concurrently. The C library needed to be thread-safe. Testing confirmed it was, but this required running stress tests under CICS rather than in batch.

Challenge 4: Library updates. The C library was distributed as a shared object (.so on USS, or a load module on z/OS). Updating it required coordination with the systems programming team, who controlled library installations.

Implementation

Tomás Rivera led the technical implementation:

  1. Wrapper program: A COBOL program (CLM-VALIDATE) that handled all string conversion and encoding, called the C library, and returned results in COBOL-native formats. This isolated the rest of the claim processing system from the C interface.

  2. Fallback mechanism: If the C library call failed (return code = -99, indicating library not loaded), the wrapper fell back to the old copybook-based validation. This ensured that a library installation failure would not stop claim processing.

  3. Caching: The wrapper cached the last 1,000 validated codes in a WORKING-STORAGE table. Since claims often repeat the same diagnosis and procedure codes, this cache hit rate was 60%, reducing C library calls significantly.

  4. Monitoring: Every call to the C library was timed. If response time exceeded 50 milliseconds (indicating a problem), the wrapper switched to the fallback copybook and raised an alert.

Results

After three months in production: - Quarterly copybook updates eliminated (saving 3-4 weeks of effort per quarter) - Code validation accuracy improved from 99.7% to 99.99% (the C library caught valid codes that the copybook had missed) - Average validation time decreased from 2.3ms (copybook search) to 0.8ms (C library hash lookup) - One incident: a library update introduced a regression that the monitoring caught within 30 seconds, triggering automatic fallback

Lessons Learned

  1. The wrapper pattern is essential. By isolating the C library behind a COBOL wrapper, James could change the validation implementation without touching any calling programs. The 15 programs that called CLM-VALIDATE never knew that validation switched from copybook to C library.

  2. Always build a fallback. The 10 minutes James spent implementing the copybook fallback saved 4 hours of downtime during the library regression incident.

  3. Performance monitoring at the boundary matters. Without timing data, the regression would have caused silent performance degradation affecting claim processing throughput.

  4. Caching amplifies benefits. The WORKING-STORAGE cache reduced inter-language call overhead by 60%, making the integration even more compelling.

Discussion Questions

  1. The wrapper pattern added a layer of indirection. Is this always worth the cost? When would you bypass the wrapper and call C directly from the claim processing programs?
  2. The caching strategy used WORKING-STORAGE, which means each CICS task has its own cache. Would a shared cache (in CICS shared storage or a DB2 table) be better? What are the trade-offs?
  3. The fallback mechanism uses the old copybook that is no longer being updated. Over time, the copybook will become increasingly stale. Is this acceptable? What is the shelf life of a fallback mechanism?
  4. James timed C library calls and triggered fallback at 50ms. How would you determine the right threshold? What factors would influence this number?