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:
- Personal loans -- up to $50,000, terms of 12-60 months
- Auto loans -- up to $100,000, terms of 12-60 months
- Home loans -- up to $750,000, terms of 120-360 months
- 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 wroteIF 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