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:
-
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.
-
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.
-
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.
-
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
-
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.
-
Always build a fallback. The 10 minutes James spent implementing the copybook fallback saved 4 hours of downtime during the library regression incident.
-
Performance monitoring at the boundary matters. Without timing data, the regression would have caused silent performance degradation affecting claim processing throughput.
-
Caching amplifies benefits. The WORKING-STORAGE cache reduced inter-language call overhead by 60%, making the integration even more compelling.
Discussion Questions
- 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?
- 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?
- 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?
- James timed C library calls and triggered fallback at 50ms. How would you determine the right threshold? What factors would influence this number?