forked from aws-samples/aws-mainframe-modernization-carddemo
-
Notifications
You must be signed in to change notification settings - Fork 5
feature: migrate Bill Payment (CB00/COBIL00C) to Spring Boot + DB2 + Angular #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
devin-ai-integration
wants to merge
2
commits into
main
Choose a base branch
from
devin/1784652290-billpay-cobol-to-java-angular
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| name: BillPay CI | ||
|
|
||
| on: | ||
| push: | ||
| paths: | ||
| - 'stack/backend/**' | ||
| - 'stack/frontend/**' | ||
| - '.github/workflows/billpay-ci.yml' | ||
| pull_request: | ||
| paths: | ||
| - 'stack/backend/**' | ||
| - 'stack/frontend/**' | ||
| - '.github/workflows/billpay-ci.yml' | ||
|
|
||
| jobs: | ||
| backend: | ||
| name: Backend (Spring Boot / mvn test) | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: stack/backend | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: '17' | ||
| cache: maven | ||
| - name: Build and test | ||
| run: mvn -B verify | ||
|
|
||
| frontend: | ||
| name: Frontend (Angular build + test) | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: stack/frontend | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Set up Node.js 20 | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: npm | ||
| cache-dependency-path: stack/frontend/package-lock.json | ||
| - name: Install dependencies | ||
| run: npm ci | ||
| - name: Install Chromium for headless tests | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y chromium-browser || sudo apt-get install -y chromium | ||
| - name: Unit tests (headless) | ||
| env: | ||
| CHROME_BIN: /usr/bin/chromium-browser | ||
| run: npx ng test --watch=false | ||
| - name: Production build | ||
| run: npx ng build | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # CardDemo — Module Stream Map (Step 1: `!identify_module_streams`) | ||
|
|
||
| **Repo (SOURCE):** `COG-GTM/mainframe-modernization-carddemo` @ `main` | ||
| **Generated by:** orchestrator (inline), CardDemo online transaction inventory | ||
| **Purpose:** enumerate the online transaction *streams* so one can be selected for COBOL→Java/DB2/Angular migration (STOP 1). | ||
|
|
||
| A *stream* = a user-facing online transaction (a CICS `TransID`) plus the programs, BMS maps, copybooks and VSAM files it touches. | ||
|
|
||
| ## Online transaction streams (from `README.md` transaction table + `app/cbl`) | ||
|
|
||
| | Stream | TransID | Program | BMS map | UI-bearing | Primary files touched | Writes? | Coupling | Status | | ||
| |--------|---------|---------|---------|-----------|-----------------------|---------|----------|--------| | ||
| | Sign-on | CC00 | COSGN00C | COSGN00 | yes | USRSEC | no | entrypoint | active | | ||
| | Main Menu | CM00 | COMEN01C | COMEN01 | yes | — (routing) | no | routes to all | active | | ||
| | Admin Menu | CA00 | COADM01C | COADM01 | yes | — (routing) | no | routes to admin | active | | ||
| | Account View | CAVW | COACTVWC | COACTVW | yes | ACCTDAT, CXACAIX, CUSTDAT | no | reads acct/cust | active | | ||
| | Account Update | CAUP | COACTUPC | COACTUP | yes | ACCTDAT, CUSTDAT | yes | R/W acct/cust | active | | ||
| | Card List | CCLI | COCRDLIC | COCRDLI | yes | CARDDAT, CXACAIX | no | reads card | active | | ||
| | Card View | CCDL | COCRDSLC | COCRDSL | yes | CARDDAT | no | reads card | active | | ||
| | Card Update | CCUP | COCRDUPC | COCRDUP | yes | CARDDAT | yes | R/W card | active | | ||
| | Transaction List | CT00 | COTRN00C | COTRN00 | yes | TRANSACT | no | reads tran | active | | ||
| | Transaction View | CT01 | COTRN01C | COTRN01 | yes | TRANSACT | no | reads tran | active | | ||
| | Transaction Add | CT02 | COTRN02C | COTRN02 | yes | TRANSACT, CCXREF, ACCTDAT | yes | R/W tran | active | | ||
| | **Bill Payment** | **CB00** | **COBIL00C** | **COBIL00** | **yes** | **ACCTDAT, CXACAIX, TRANSACT** | **yes** | **self-contained** | **active** | | ||
| | Report Request | CR00 | CORPT00C | CORPT00 | yes | TRANSACT (batch submit) | (JCL) | submits batch | active | | ||
| | User List | CU00 | COUSR00C | COUSR00 | yes | USRSEC | no | admin | active | | ||
| | User Add | CU01 | COUSR01C | COUSR01 | yes | USRSEC | yes | admin | active | | ||
| | User Update | CU02 | COUSR02C | COUSR02 | yes | USRSEC | yes | admin | active | | ||
| | User Delete | CU03 | COUSR03C | COUSR03 | yes | USRSEC | yes | admin | active | | ||
|
|
||
| Batch programs (`CBACT0*`, `CBTRN0*`, `CBSTM03*`, `CBCUS01C`) are **out of scope** for online-transaction migration and are not streams here. | ||
|
|
||
| ## Blocked / dead | ||
| - None detected among the online streams; all have present programs + maps + copybooks on `main`. | ||
|
|
||
| ## Recommended selection for this run | ||
| **Bill Payment (`CB00` / `COBIL00C`)** — selected at STOP 1 (user delegated judgment). | ||
|
|
||
| Rationale: | ||
| - **Self-contained, small, high-value** online write transaction (572 LOC, single program, single map). Ideal first 1/1-parity slice. | ||
| - Touches exactly three data stores (**ACCTDAT** account, **CXACAIX** card-xref AIX, **TRANSACT** transaction) — all with simple copybook layouts, giving a clean DB2 schema. | ||
| - Exercises the full online write path: validate → read → confirm → generate next key → insert transaction → decrement balance → rewrite account — a strong demonstration of behavioral parity including the money-movement invariant. | ||
| - No dependency on other online programs' internals (only shares data files), so it migrates without pulling in the whole app. | ||
|
|
||
| **Stream program set:** `COBIL00C` (1 program). **Maps:** `COBIL00`. **Copybooks:** `COBIL00` (map), `CVACT01Y` (account), `CVACT03Y` (card xref), `CVTRA05Y` (transaction), plus shared `COCOM01Y`, `CSDAT01Y`, `CSMSG01Y`, `COTTL01Y`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| # Bill Payment Stream — Analysis (Step 2a: `!analyze_stream`) | ||
|
|
||
| **Stream:** Bill Payment — TransID `CB00`, program `COBIL00C` | ||
| **SOURCE:** `app/cbl/COBIL00C.cbl` (572 lines), map `app/bms/COBIL00.bms`, DSECT `app/cpy-bms/COBIL00.CPY` | ||
| **Copybooks:** `CVACT01Y` (ACCOUNT-RECORD), `CVACT03Y` (CARD-XREF-RECORD), `CVTRA05Y` (TRAN-RECORD) | ||
|
|
||
| ## Program inventory & leaf-first dependency DAG | ||
|
|
||
| Single online program with paragraph-level sub-routines. Data-access "leaves" (map to persistence layer): | ||
|
|
||
| ``` | ||
| COBIL00C (orchestrator / UI-bearing) | ||
| ├── READ-ACCTDAT-FILE → ACCTDAT (READ ... UPDATE) [leaf: Account read-for-update] | ||
| ├── READ-CXACAIX-FILE → CXACAIX (READ) [leaf: Card-xref lookup by acct] | ||
| ├── STARTBR/READPREV/ENDBR-TRANSACT-FILE → TRANSACT (browse) [leaf: max TRAN-ID discovery] | ||
| ├── WRITE-TRANSACT-FILE → TRANSACT (WRITE) [leaf: Transaction insert] | ||
| └── UPDATE-ACCTDAT-FILE → ACCTDAT (REWRITE) [leaf: Account balance rewrite] | ||
| ``` | ||
|
|
||
| Wave grouping (leaf-first): | ||
| - **Wave A (data-access leaves):** Account repository (read/update), CardXref repository (read), Transaction repository (max-id + insert). Plain JPA — **no stored procedures** (see SP table). | ||
| - **Wave B (orchestrator, UI-bearing):** `COBIL00C` business orchestration → `BillPaymentService` + REST controller + Angular `COBIL00` screen. | ||
|
|
||
| ## uiSurface (per program) | ||
| `COBIL00C` — **UI-bearing**. Map `COBIL0A` (mapset `COBIL00`), 24×80 screen "Bill Payment". | ||
| - Input fields: `ACTIDIN` (Acct ID, len 11), `CONFIRM` (Y/N, len 1). | ||
| - Output/protected fields: `CURBAL` (current balance, len 14), `ERRMSG` (message line, len 78, RED normally / GREEN on success), plus header (`TRNNAME`,`TITLE01/02`,`CURDATE`,`PGMNAME`,`CURTIME`). | ||
| - AID keys: `ENTER`=continue/process, `PF3`=back (to `CDEMO-FROM-PROGRAM` or `COMEN01C`), `PF4`=clear. | ||
|
|
||
| ## Field dictionary (source copybooks → canonical types) | ||
|
|
||
| ### ACCOUNT-RECORD (`CVACT01Y`, RECLN 300) | ||
| | COBOL field | PIC | Meaning | Canonical type | | ||
| |-------------|-----|---------|----------------| | ||
| | ACCT-ID | 9(11) | account id (PK) | long / 11-digit | | ||
| | ACCT-ACTIVE-STATUS | X(01) | active flag | char(1) | | ||
| | ACCT-CURR-BAL | S9(10)V99 | current balance | decimal(12,2) | | ||
| | ACCT-CREDIT-LIMIT | S9(10)V99 | credit limit | decimal(12,2) | | ||
| | ACCT-CASH-CREDIT-LIMIT | S9(10)V99 | cash limit | decimal(12,2) | | ||
| | ACCT-OPEN-DATE | X(10) | open date | char(10) | | ||
| | ACCT-EXPIRAION-DATE | X(10) | expiry date | char(10) | | ||
| | ACCT-REISSUE-DATE | X(10) | reissue date | char(10) | | ||
| | ACCT-CURR-CYC-CREDIT | S9(10)V99 | cycle credit | decimal(12,2) | | ||
| | ACCT-CURR-CYC-DEBIT | S9(10)V99 | cycle debit | decimal(12,2) | | ||
| | ACCT-ADDR-ZIP | X(10) | zip | char(10) | | ||
| | ACCT-GROUP-ID | X(10) | group id | char(10) | | ||
| | FILLER | X(178) | filler | — | | ||
|
|
||
| ### CARD-XREF-RECORD (`CVACT03Y`, RECLN 50) — indexed by ACCT (AIX `CXACAIX`) | ||
| | COBOL field | PIC | Meaning | Canonical type | | ||
| |-------------|-----|---------|----------------| | ||
| | XREF-CARD-NUM | X(16) | card number | char(16) | | ||
| | XREF-CUST-ID | 9(09) | customer id | long | | ||
| | XREF-ACCT-ID | 9(11) | account id (AIX key) | long | | ||
| | FILLER | X(14) | filler | — | | ||
|
|
||
| ### TRAN-RECORD (`CVTRA05Y`, RECLN 350) | ||
| | COBOL field | PIC | Meaning | Canonical type | | ||
| |-------------|-----|---------|----------------| | ||
| | TRAN-ID | X(16) | transaction id (PK, numeric string) | char(16) | | ||
| | TRAN-TYPE-CD | X(02) | type code (`'02'` for bill pay) | char(2) | | ||
| | TRAN-CAT-CD | 9(04) | category code (`2`) | int | | ||
| | TRAN-SOURCE | X(10) | source (`'POS TERM'`) | char(10) | | ||
| | TRAN-DESC | X(100) | description (`'BILL PAYMENT - ONLINE'`) | char(100) | | ||
| | TRAN-AMT | S9(09)V99 | amount | decimal(11,2) | | ||
| | TRAN-MERCHANT-ID | 9(09) | merchant id (`999999999`) | long | | ||
| | TRAN-MERCHANT-NAME | X(50) | merchant name (`'BILL PAYMENT'`) | char(50) | | ||
| | TRAN-MERCHANT-CITY | X(50) | merchant city (`'N/A'`) | char(50) | | ||
| | TRAN-MERCHANT-ZIP | X(10) | merchant zip (`'N/A'`) | char(10) | | ||
| | TRAN-CARD-NUM | X(16) | card number (from xref) | char(16) | | ||
| | TRAN-ORIG-TS | X(26) | origination timestamp | char(26) | | ||
| | TRAN-PROC-TS | X(26) | processing timestamp | char(26) | | ||
| | FILLER | X(20) | filler | — | | ||
|
|
||
| ## Control flow (COBIL00C) — line-cited | ||
| - **Entry / reentry** (`MAIN-PARA`, lines 99–149): `EIBCALEN=0` → return to `COSGN00C`. First entry → send empty screen; if `CDEMO-CB00-TRN-SELECTED` was passed, prefill Acct ID and process. Reentry → receive map, dispatch on AID (`ENTER`→`PROCESS-ENTER-KEY`; `PF3`→back; `PF4`→clear; other→"invalid key"). | ||
| - **PROCESS-ENTER-KEY** (154–244): the core business logic. | ||
| - **V1** Acct ID empty (159–164) → `'Acct ID can NOT be empty...'`. | ||
| - Move Acct ID to `ACCT-ID`/`XREF-ACCT-ID` (170–171). | ||
| - **Confirm dispatch** (173–191): `Y/y`→confirm-yes, read account; `N/n`→clear + stop; blank→read account (unconfirmed); other→`'Invalid value. Valid values are (Y/N)...'` (V2). | ||
| - Move balance to screen (193–194). | ||
| - **V3** balance ≤ 0 with non-empty acct (198–205) → `'You have nothing to pay...'`. | ||
| - **Payment path (confirm=Y)** (210–235): read CXACAIX (card num); browse TRANSACT descending for max TRAN-ID; `newId = maxId + 1`; build TRAN-RECORD with the fixed bill-pay constants + `TRAN-AMT = ACCT-CURR-BAL` + card num + timestamps; WRITE transaction; `ACCT-CURR-BAL = ACCT-CURR-BAL - TRAN-AMT` (→ 0); REWRITE account. | ||
| - **Unconfirmed path** (236–240) → `'Confirm to make a bill payment...'`. | ||
| - **WRITE-TRANSACT-FILE** (510–547): on success → clear fields + GREEN message `'Payment successful. Your Transaction ID is <id>.'`; DUPKEY/DUPREC → `'Tran ID already exist...'`. | ||
| - **Read/Update ACCTDAT** (343–403): NOTFND → `'Account ID NOT found...'`; other → `'Unable to lookup/Update Account...'`. | ||
| - **READ-CXACAIX** (408–436): NOTFND → `'Account ID NOT found...'`; other → `'Unable to lookup XREF AIX file...'`. | ||
| - **Browse TRANSACT** (441–496): ENDFILE on READPREV → start numbering at 0 (so first id = 1). | ||
| - Header population = current date/time (`POPULATE-HEADER-INFO`, 319–338). | ||
|
|
||
| ## Business invariants (the parity oracle) | ||
| 1. A confirmed payment **inserts exactly one** TRANSACT row with `TRAN-AMT = pre-payment ACCT-CURR-BAL` and the fixed bill-pay constants. | ||
| 2. New `TRAN-ID = (max existing numeric TRAN-ID) + 1`, zero-padded to 16 (first ever = 1). | ||
| 3. After a confirmed payment, `ACCT-CURR-BAL` becomes `0` (balance − amount, amount == balance). | ||
| 4. Payment blocked when balance ≤ 0 ("nothing to pay") and when not confirmed ("confirm..."). | ||
| 5. Card number on the transaction comes from the account→card xref (`CXACAIX`). | ||
| 6. Success message is GREEN and echoes the new Transaction ID. | ||
|
|
||
| ## Stored-procedure candidate table | ||
| | Data-access leaf | Physical layer | SP? | Language | Decision | | ||
| |------------------|----------------|-----|----------|----------| | ||
| | Account read-for-update / rewrite | VSAM KSDS ACCTDAT | **No** | — | plain JPA `AccountRepository` | | ||
| | Card-xref lookup by acct | VSAM AIX CXACAIX | **No** | — | plain JPA `CardXrefRepository` (query by acctId) | | ||
| | Max TRAN-ID + insert | VSAM KSDS TRANSACT | **No** | — | plain JPA `TransactionRepository` (`max(id)` + save) | | ||
|
|
||
| **No stored procedures** — all three leaves are simple keyed VSAM operations with no server-side procedural logic; native JPA repositories preserve behavior. No DBA registration requests required for this stream. | ||
|
|
||
| ## Absent-module flags | ||
| - None. All source, maps and copybooks are present on `main`. | ||
|
|
||
| ## Hard-stop boundary | ||
| This slice migrates **only** the online Bill Payment transaction (`COBIL00C`) and the three data stores it touches. It does **not** migrate the sign-on, menu routing, or the batch posting programs; navigation targets (`COSGN00C`, `COMEN01C`) are represented only as return signals, not migrated here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| # Bill Payment — Functional Requirements (Step 2a-FR: `!generate_fr_transaction`) | ||
|
|
||
| **Stream:** Bill Payment (`CB00` / `COBIL00C`). **This document is the acceptance / sign-off oracle.** | ||
| Every requirement is a *business-visible* behavior (trigger → user-visible result), cited to `COBIL00C.cbl:line`. | ||
|
|
||
| ## Functional requirements (business sign-off set) | ||
|
|
||
| | ID | As a user I can… | Trigger | User-visible result | Source cite | | ||
| |----|------------------|---------|---------------------|-------------| | ||
| | FR-1 | Open the Bill Payment screen | Navigate to CB00 | Empty Bill Payment screen: Acct ID + Confirm inputs, balance & message blank, header shows date/time/prog/tran | `COBIL00C.cbl:114-122`, `289-301` | | ||
| | FR-2 | See my current balance for an account | Enter a valid Acct ID, ENTER (confirm blank) | Screen shows the account's current balance and prompt `Confirm to make a bill payment...` | `COBIL00C.cbl:170-194`, `236-240` | | ||
| | FR-3 | Pay my balance in full | Enter valid Acct ID with balance > 0, Confirm = `Y`, ENTER | One transaction is recorded, balance becomes 0, GREEN message `Payment successful. Your Transaction ID is <id>.` | `COBIL00C.cbl:210-235`, `522-532` | | ||
| | FR-4 | Be stopped from paying an empty account id | ENTER with Acct ID blank | RED error `Acct ID can NOT be empty...` | `COBIL00C.cbl:159-164` | | ||
| | FR-5 | Be stopped from paying when nothing is owed | Valid Acct ID whose balance ≤ 0, ENTER | RED error `You have nothing to pay...`; no transaction, balance unchanged | `COBIL00C.cbl:198-205` | | ||
| | FR-6 | Be told when the account does not exist | Unknown Acct ID, ENTER | RED error `Account ID NOT found...` | `COBIL00C.cbl:359-363` | | ||
| | FR-7 | Be forced to confirm before paying | Valid Acct ID, balance > 0, Confirm blank, ENTER | RED prompt `Confirm to make a bill payment...`; no transaction, balance unchanged | `COBIL00C.cbl:236-240` | | ||
| | FR-8 | Be rejected for an invalid confirm value | Confirm not in {Y,y,N,n,blank}, ENTER | RED error `Invalid value. Valid values are (Y/N)...` | `COBIL00C.cbl:185-190` | | ||
| | FR-9 | Decline the payment | Confirm = `N`, ENTER | Screen fields cleared; no transaction, balance unchanged | `COBIL00C.cbl:178-181`, `552-566` | | ||
| | FR-10 | Clear the screen | Press PF4 | All input fields cleared | `COBIL00C.cbl:136-137`, `552-566` | | ||
| | FR-11 | Go back | Press PF3 | Return to the calling screen (menu) | `COBIL00C.cbl:128-135` | | ||
|
|
||
| ## Screen / UI field spec (map `COBIL0A`) | ||
| | Field | Kind | Len | Notes | | ||
| |-------|------|-----|-------| | ||
| | Acct ID (`ACTIDIN`) | input | 11 | numeric account id | | ||
| | Confirm (`CONFIRM`) | input | 1 | Y/N | | ||
| | Current balance (`CURBAL`) | output | 14 | signed, 2 decimals; e.g. `+0000123.45` style | | ||
| | Message (`ERRMSG`) | output | 78 | RED for errors, GREEN on payment success | | ||
| | Header | output | — | Tran `CB00`, Prog `COBIL00C`, title, current date `mm/dd/yy`, time `hh:mm:ss` | | ||
| | Footer | static | — | `ENTER=Continue F3=Back F4=Clear` | | ||
|
|
||
| ## Validation / error catalogue (exact strings — parity-critical) | ||
| - `Acct ID can NOT be empty...` | ||
| - `Invalid value. Valid values are (Y/N)...` | ||
| - `You have nothing to pay...` | ||
| - `Confirm to make a bill payment...` | ||
| - `Account ID NOT found...` | ||
| - `Payment successful. Your Transaction ID is <TRAN-ID>.` (GREEN) | ||
| - (defensive) `Unable to lookup Account...`, `Unable to Update Account...`, `Unable to lookup XREF AIX file...`, `Tran ID already exist...` | ||
|
|
||
| ## Acceptance criteria | ||
| - **AC-1 (money movement):** confirmed payment on balance `B>0` ⇒ exactly one new transaction with `amount == B`, account balance ⇒ `0`. (FR-3) | ||
| - **AC-2 (id sequencing):** new transaction id = `max(existing numeric id) + 1`, 16-char zero-padded; first ever = `1`. (FR-3) | ||
| - **AC-3 (transaction content):** new transaction has `typeCode='02'`, `categoryCode=2`, `source='POS TERM'`, `description='BILL PAYMENT - ONLINE'`, `merchantId=999999999`, `merchantName='BILL PAYMENT'`, `merchantCity='N/A'`, `merchantZip='N/A'`, `cardNumber` = the account's xref card. (FR-3) | ||
| - **AC-4 (guards):** empty id, balance ≤ 0, unknown account, unconfirmed, invalid confirm each block the payment with the exact message above and leave data unchanged. (FR-4..FR-8) | ||
| - **AC-5 (decline/clear/back):** N declines & clears; PF4 clears; PF3 navigates back — none mutate data. (FR-9..FR-11) | ||
|
|
||
| ## Traceability matrix (requirement ↔ source ↔ test ↔ UI-verification case) | ||
| | FR | Source cite | Backend test | UI recording case | | ||
| |----|-------------|--------------|-------------------| | ||
| | FR-2 | 170-194 | `inquiry_returnsBalanceAndConfirmPrompt` | REC-02 | | ||
| | FR-3 | 210-235,522-532 | `pay_confirmed_insertsTxnAndZeroesBalance`, E2E `billPay_persistsRowAndBalance` | REC-03 | | ||
| | FR-4 | 159-164 | `pay_emptyAcct_error` | REC-04 | | ||
| | FR-5 | 198-205 | `pay_nonPositiveBalance_error` | REC-05 | | ||
| | FR-6 | 359-363 | `pay_unknownAcct_error` | REC-06 | | ||
| | FR-7 | 236-240 | `pay_unconfirmed_prompt` | REC-07 | | ||
| | FR-8 | 185-190 | `pay_invalidConfirm_error` | REC-08 | | ||
| | FR-9 | 178-181 | `pay_declined_noChange` | REC-09 | | ||
| | FR-10/11 | 136-137,128-135 | (UI) | REC-10/REC-11 | | ||
|
|
||
| Demoted (NOT functional requirements): CICS reentry/commarea mechanics, XCTL routing, timestamp formatting, browse cursor mechanics, defensive VSAM RESP handling. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔍 Chromium fallback path is inconsistent
The fallback installs
chromium, whileCHROME_BINstill nameschromium-browser. A runner lacking that alias cannot start frontend tests.Was this helpful? React with 👍 or 👎 to provide feedback.