Case Study 1: Designing Working Storage for a Loan Processing System

Background

First National Bank (FNB) processes thousands of loan applications daily across its 200 branch locations. In early 2024, the bank initiated a modernization project to replace its aging batch loan processing system -- originally written in 1992 -- with a new COBOL program that would improve processing speed, enhance validation, and produce more detailed reports for regulatory compliance.

Teresa Nguyen, a senior COBOL developer with 18 years of experience, was assigned as the lead developer. Her first and most critical task: designing the WORKING-STORAGE SECTION for the new loan processing program. Teresa knew from experience that a well-designed WORKING-STORAGE section would make the rest of the program straightforward to write and maintain, while a poorly designed one would create cascading problems throughout development.

The Requirements

The loan processing program needed to handle four types of loans:

  1. Personal loans -- up to $50,000, terms of 12-60 months
  2. Auto loans -- up to $100,000, terms of 12-60 months
  3. Home loans -- up to $750,000, terms of 120-360 months
  4. Business loans -- up to $500,000, terms of 12-240 months

For each application, the program must:

  • Validate the applicant's personal information (name, SSN, address)
  • Verify financial qualifications (income, debt-to-income ratio, credit score)
  • Check loan parameters against product limits (amount, term, purpose)
  • Calculate monthly payments, total interest, and origination fees
  • Make an automated decision (approve, deny, or flag for manual review)
  • Accumulate statistics for the daily processing report

The program would read loan applications from a sequential file, process each one, write decisions to an output file, and produce a summary report.

Teresa's Design Process

Step 1: Identify All Data Categories

Teresa began by listing every piece of data the program would need, then categorizing them:

Constants (things that never change during a run): - Program identification (name, version) - Loan product limits (maximum amounts per type) - Interest rate ranges (minimum and maximum APR per type) - Fee rates (origination fee, late penalty, insurance) - Credit score thresholds (excellent, good, fair, poor) - Debt-to-income ratio limits (different by product type)

Flags (on/off indicators): - End-of-file indicator - First-record indicator - Application-valid indicator - Individual validation results (credit OK, DTI OK, income verified, collateral OK) - Final decision indicator (approve/deny/review/pending)

Counters (things we count): - Applications read, processed, approved, denied, sent to review, in error - Applications by type (personal, auto, home, business)

Accumulators (running totals): - Total amount requested, approved, denied - Total fees generated - Average loan amount, average credit score

Input record layout: - Application header (ID, date, branch, loan officer) - Customer information (name, SSN, DOB, address, phone, email) - Financial information (income, debts, credit score, employment) - Loan request (type, amount, term, purpose, collateral value)

Calculation work fields: - DTI ratio, monthly payment, total interest, total repayment - Origination fee, insurance cost - Interest rate (annual and monthly) - Loan-to-value ratio - Power factor and temporary calculation fields - Error message accumulation

Decision output record: - Application ID, decision status, approved amount, rate, term - Monthly payment, risk rating, conditions, officer, timestamp

Display/report fields: - Header lines, detail lines, separator lines - Formatted amounts, rates, percentages, counts

Step 2: Design the Data Hierarchy

Teresa made critical decisions about grouping. Rather than defining hundreds of independent 01-level items, she grouped related fields under meaningful group names:

       01  WS-C-PROGRAM-CONSTANTS.
           05  WS-C-PROGRAM-ID       PIC X(20).
           05  WS-C-PROGRAM-VER      PIC X(05).
           ...

       01  WS-C-LOAN-LIMITS.
           05  WS-C-PERSONAL-MAX     PIC 9(09)V99.
           05  WS-C-AUTO-MAX         PIC 9(09)V99.
           ...

This approach had several advantages: - Related constants could be found together - INITIALIZE could clear an entire group at once - The hierarchical structure documented the data relationships

Step 3: Choose Field Sizes Carefully

Teresa followed a crucial principle: size numeric fields generously, but not wastefully. For loan amounts, she used PIC 9(09)V99 (up to $9,999,999.99) even though the maximum home loan was $750,000. This gave a comfortable margin for future product changes without wasting significant storage.

For accumulators that would sum many loan amounts, she used PIC 9(13)V99 -- large enough for the total of all loans processed in a day.

For calculation work fields involving division and multiplication, she used extra decimal places: PIC 9(05)V9(10) for the power factor in the monthly payment formula. Insufficient precision in financial calculations is a frequent source of penny-rounding errors that can accumulate to significant amounts.

Step 4: Design 88-Level Conditions Extensively

Teresa's most impactful design decision was her thorough use of 88-level conditions. Every field that would be tested in the PROCEDURE DIVISION received condition names:

       01  WS-APP-LOAN-TYPE      PIC X(02).
           88  WS-LOAN-PERSONAL      VALUE 'PL'.
           88  WS-LOAN-AUTO          VALUE 'AL'.
           88  WS-LOAN-HOME          VALUE 'HL'.
           88  WS-LOAN-BUSINESS      VALUE 'BL'.
           88  WS-LOAN-VALID-TYPE
               VALUE 'PL' 'AL' 'HL' 'BL'.

The WS-LOAN-VALID-TYPE condition was particularly useful -- it allowed a single IF statement to validate the loan type instead of checking four individual values.

For the credit score, she used THRU ranges that directly matched the bank's credit classification policy:

       01  WS-APP-CREDIT-SCORE   PIC 9(03).
           88  WS-SCORE-EXCELLENT    VALUE 750 THRU 850.
           88  WS-SCORE-GOOD         VALUE 670 THRU 749.
           88  WS-SCORE-FAIR         VALUE 580 THRU 669.
           88  WS-SCORE-POOR         VALUE 300 THRU 579.

When the bank changed its credit classification thresholds six months later (lowering the "good" threshold from 670 to 660), only one line in WORKING-STORAGE needed to change. The entire PROCEDURE DIVISION, which had dozens of references to WS-SCORE-GOOD, required no modifications.

Step 5: Plan the Error Handling Structure

Teresa designed an error message accumulation table:

       01  WS-WK-ERROR-MESSAGES.
           05  WS-WK-ERROR-COUNT     PIC 9(02) VALUE ZERO.
           05  WS-WK-ERROR-ENTRY OCCURS 10 TIMES.
               10  WS-WK-ERROR-CODE  PIC X(04).
               10  WS-WK-ERROR-DESC  PIC X(50).

This allowed the validation logic to accumulate multiple errors per application rather than stopping at the first error. The loan officer review screen could then display all issues at once, making corrections faster.

Step 6: Design the Processing Loop Reset Strategy

One of Teresa's most important decisions was identifying which fields needed to be reset between application records and which should persist:

Reset between records (INITIALIZE each iteration): - The input record layout - All calculation work fields - The error message table - Validation flags - The decision result

Persist across records (never INITIALIZE): - Counters (they accumulate) - Running total accumulators (they accumulate) - Constants (they never change) - The EOF flag (it changes once)

She encapsulated the reset logic:

       2100-CLEAR-APPLICATION.
           INITIALIZE WS-LOAN-APPLICATION
           INITIALIZE WS-WK-CALCULATION-FIELDS
           INITIALIZE WS-WK-ERROR-MESSAGES
           INITIALIZE WS-DECISION-RESULT
           INITIALIZE WS-F-VALIDATION-FLAGS
           MOVE 'P' TO WS-F-DECISION-FLAG
           .

This paragraph was called at the beginning of each iteration, guaranteeing clean work fields.

The Result

Teresa's WORKING-STORAGE section totaled approximately 350 lines of data definitions. It was organized into eight clearly labeled sections, used consistent naming conventions throughout, and included thorough 88-level conditions on every field that participated in conditional logic.

When the four junior developers on her team began writing the PROCEDURE DIVISION paragraphs, they found that the well-organized WORKING-STORAGE made their work significantly easier:

  • The validation logic was clean and readable because of 88-level conditions. Instead of IF WS-APP-CREDIT-SCORE >= 750, they wrote IF WS-SCORE-EXCELLENT, which exactly matched the business requirements document.

  • The calculation logic had all the work fields it needed, properly sized, in a single group that could be INITIALIZED in one statement.

  • The report logic had pre-formatted display lines with FILLER items for spacing, matching the report specification exactly.

  • Debugging was straightforward because each field's purpose was apparent from its name and its location in the organizational structure.

The program went into production on schedule and processed an average of 12,000 loan applications per day. In its first year, only two maintenance changes were required -- both were changes to business rules (credit score thresholds and fee rates) that required modifying only VALUE clauses in the constants section.

Lessons Learned

1. Time Spent on WORKING-STORAGE Design Pays Dividends

Teresa spent three full days designing the WORKING-STORAGE section before writing a single line of PROCEDURE DIVISION code. Her team completed the rest of the program in two weeks. A comparable project the previous year, where WORKING-STORAGE was designed ad hoc as the PROCEDURE DIVISION was written, took six weeks and required two refactoring passes.

2. 88-Level Conditions Are Not Optional

Every field that participates in any condition should have 88-levels. The small upfront investment makes the PROCEDURE DIVISION dramatically more readable and makes maintenance changes localized to data definitions rather than scattered throughout the program.

3. Group Your Data Logically

Teresa's eight-section organization (constants, flags, counters, accumulators, input layout, work fields, decision output, display fields) became a template that the team used for all subsequent programs. New team members could navigate any program's WORKING-STORAGE in minutes.

4. Size Fields for the Future

Teresa's generous field sizes (PIC 9(09)V99 for amounts that currently max at $750,000) meant that when FNB later introduced a "jumbo home loan" product up to $2,000,000, the existing field sizes accommodated it without any changes.

5. Separate Constants from Calculations

By isolating all business-rule values as named constants at the top of WORKING-STORAGE, Teresa ensured that business rule changes -- the most common type of maintenance -- were quick, safe, and confined to a single area of the code.

The Complete Implementation

The full WORKING-STORAGE implementation for this case study is available in code/case-study-code.cob. It includes all eight organizational sections, comprehensive 88-level conditions, and a demonstration PROCEDURE DIVISION that processes three sample loan applications and produces a summary report.

Study the code carefully, noting how the organizational structure translates from the design discussion above into actual COBOL data definitions. Pay particular attention to:

  • How constants are grouped by business function
  • How each flag has both TRUE and FALSE 88-level conditions
  • How the REDEFINES on the application date field allows both whole-date and part-date access
  • How the error message table uses OCCURS to accumulate multiple validation failures
  • How display fields mirror their corresponding work fields with appropriate formatting