37 use cases implemented, 15 out of scope, 2 stubbed — all one-time (recurring/future-dated excluded)
AvAchService pipeline in cam-movemoney-process-api is exercised end-to-end. EligibilityService widened from 3 account codes (BBK/BFL/BMM) to 32 codes covering all Q*/R* retirement codes plus HSA. Six new inline rule services are wired between Eligibility and Compliance: ContributionLimitService, PriorYearCodingService, RolloverRuleService, ConversionService, HsaEligibilityService, and ExcessContributionService. Recurring / future-dated routing remains unreachable (no scheduler present).
All 54 use cases (17 deposit/withdrawal + 37 retirement). Status badges: ✓ implemented, ⚠ stubbed, ✗ out of scope.
| ID | Category | Description | Status | Code File Touched | Sample cURL |
|---|---|---|---|---|---|
| UC-D1 | Deposit | One-time brokerage deposit | ✓ Implemented | Controllers/DepositController.cs, AvAchService.cs | curl -X POST http://localhost:5001/ach/deposit -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000001,"amount":2500}}' |
| UC-D2 | Deposit | Future-dated deposit | ✗ Out of scope | — | — |
| UC-D3 | Deposit | Advisor-initiated deposit | ✓ Implemented | DepositController.cs, ActorContext.cs | curl -X POST http://localhost:5001/ach/deposit -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000001,"amount":2500},"actor":{"type":"Advisor","repId":"R12345"}}' |
| UC-D4 | Deposit | Queued after-hours deposit | ⚠ Stubbed | QueueStubController.cs | — |
| UC-W1 | Withdrawal | One-time withdrawal | ✓ Implemented (Wave 1) | WithdrawalController.cs, AvAchService.cs | curl -X POST http://localhost:5001/ach/withdrawal -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000002,"amount":5000}}' |
| UC-W2 | Withdrawal | Withdrawal with reason codes (RMD, excess) | ✓ Implemented | WithdrawalController.cs, TransferReason.cs | curl -X POST http://localhost:5001/ach/withdrawal/with-reason -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000002,"amount":5000},"transferReason":"RMD"}' |
| UC-W3 | Withdrawal | Advisor-initiated withdrawal | ✓ Implemented | WithdrawalController.cs, ActorContext.cs | curl -X POST http://localhost:5001/ach/withdrawal -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000002,"amount":5000},"actor":{"type":"Advisor","repId":"R12345"}}' |
| UC-W4 | Withdrawal | Cancel queued withdrawal | ⚠ Stubbed | QueueStubController.cs | curl -X DELETE http://localhost:5001/ach/queued/ABC-123 |
| UC-RD1 | Recurring Deposit | Set up recurring deposit | ✗ Out of scope (recurring) | — | — |
| UC-RD2 | Recurring Deposit | Modify active recurring deposit | ✗ Out of scope (recurring) | — | — |
| UC-RD3 | Recurring Deposit | Cancel recurring deposit | ✗ Out of scope (recurring) | — | — |
| UC-RD4 | Recurring Deposit | Auto-execute recurring deposit | ✗ Out of scope (recurring) | — | — |
| UC-RD5 | Recurring Deposit | Skip holiday/weekend | ✗ Out of scope (recurring) | — | — |
| UC-RW1 | Recurring Withdrawal | Set up recurring withdrawal | ✗ Out of scope (recurring) | — | — |
| UC-RW2 | Recurring Withdrawal | Modify/cancel recurring withdrawal | ✗ Out of scope (recurring) | — | — |
| UC-RW3 | Recurring Withdrawal | Auto-execute recurring withdrawal | ✗ Out of scope (recurring) | — | — |
| UC-RW4 | Recurring Withdrawal | Tax withholding on recurring | ✗ Out of scope (recurring) | — | — |
| UC-RW5 | Recurring Withdrawal | NIGO notify + retry | ✗ Out of scope (recurring) | — | — |
| UC-RC1 | IRA | Traditional IRA current-year contribution | ✓ Implemented | ContributionController.cs, EligibilityService.cs | curl -X POST http://localhost:5001/ach/contribution -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000013,"amount":7000},"contributionMetadata":{"contributionYear":2026,"contributionType":"Regular","actorType":"Investor"}}' |
| UC-RC2 | IRA | Roth IRA current-year | ✓ Implemented | ContributionController.cs | — |
| UC-RC3 | IRA | Prior-year contribution (Jan 1–Apr 15) | ✓ Implemented | PriorYearCodingService.cs | — |
| UC-RC4 | IRA | Catch-up contribution (50+) | ✓ Implemented | ContributionLimitService.cs | — |
| UC-RC5 | IRA | Advisor-initiated IRA contribution | ✓ Implemented | ContributionController.cs, ActorContext.cs | — |
| UC-RC6 | IRA | Spousal IRA contribution | ✓ Implemented | ContributionLimitService.cs | — |
| UC-RC7 | SEP | Employer SEP-IRA contribution | ✓ Implemented | ContributionController.cs, EligibilityService.cs | — |
| UC-RC8 | SEP | Self-employed SEP-IRA | ✓ Implemented | ContributionLimitService.cs | — |
| UC-RC9 | SIMPLE | SIMPLE IRA salary deferral | ✓ Implemented | ContributionController.cs | — |
| UC-RC10 | SIMPLE | SIMPLE IRA employer match | ✓ Implemented | ContributionController.cs | — |
| UC-RC11 | SEP/SIMPLE | Prior-year SEP/profit-sharing | ✓ Implemented | PriorYearCodingService.cs | — |
| UC-RC12 | Rollover | Direct 401(k) → Traditional IRA | ✓ Implemented | RolloverRuleService.cs | curl -X POST http://localhost:5001/ach/rollover -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000013,"amount":150000},"rolloverMetadata":{"rolloverType":"Direct","sourcePlan":"401k"}}' |
| UC-RC13 | Rollover | Roth 401(k) → Roth IRA | ✓ Implemented | RolloverRuleService.cs | — |
| UC-RC14 | Rollover | Indirect 60-day rollover | ✓ Implemented | RolloverRuleService.cs | — |
| UC-RC15 | Rollover | IRA-to-IRA rollover (once-per-12mo) | ✓ Implemented | RolloverRuleService.cs | — |
| UC-RC16 | Rollover | Spousal beneficiary rollover | ✓ Implemented | RolloverRuleService.cs | — |
| UC-RC17 | Rollover | Inherited IRA setup (non-spouse) | ✓ Implemented | EligibilityService.cs | — |
| UC-RC18 | Conversion | Full Traditional → Roth conversion | ✓ Implemented | ConversionService.cs | curl -X POST http://localhost:5001/ach/conversion -H 'Content-Type: application/json' -d '{"sourceAcctId":10000013,"targetAcctId":10000023,"amount":50000,"conversionType":"Full"}' |
| UC-RC19 | Conversion | Partial Roth conversion | ✓ Implemented | ConversionService.cs | — |
| UC-RC20 | Conversion | Backdoor Roth (pro-rata check) | ✓ Implemented | ConversionService.cs | — |
| UC-RC21 | Recharacterization | Recharacterize regular contribution | ✓ Implemented | ConversionService.cs | — |
| UC-RC22 | HSA | HSA contribution | ✓ Implemented | HsaEligibilityService.cs | curl -X POST http://localhost:5001/ach/hsa -H 'Content-Type: application/json' -d '{"transactionRequest":{"acctId":10000045,"amount":1100},"hsaMetadata":{"hdhpCovered":true,"coverageType":"Single"}}' |
| UC-RC23 | HSA | HSA catch-up (55+) | ✓ Implemented | HsaEligibilityService.cs | — |
| UC-RC24 | HSA | Employer HSA contribution | ✓ Implemented | HsaEligibilityService.cs | — |
| UC-RC25 | Recurring Retirement | Monthly DCA contribution | ✗ Out of scope (recurring) | — | — |
| UC-RC26 | Recurring Retirement | Auto-stop at limit | ✗ Out of scope (recurring) | — | — |
| UC-RC27 | Recurring Retirement | Modify/cancel recurring | ✗ Out of scope (recurring) | — | — |
| UC-RC28 | Recurring Retirement | Auto-execute recurring retirement | ✗ Out of scope (recurring) | — | — |
| UC-RC29 | System | Enforce IRS limit by type/age | ✓ Implemented | ContributionLimitService.cs | — |
| UC-RC30 | System | Prior-year coding window | ✓ Implemented | PriorYearCodingService.cs | — |
| UC-RC31 | System | 5498 reporting code assignment | ✓ Implemented | Form5498CodeMapper.cs | — |
| UC-RC32 | System | YTD aggregation across accounts | ✓ Implemented | ContributionLimitService.cs | — |
| UC-RC33 | System | Once-per-12-months rollover rule | ✓ Implemented | RolloverRuleService.cs | — |
| UC-RC34 | System | HSA HDHP eligibility check | ✓ Implemented | HsaEligibilityService.cs | — |
| UC-RC35 | Excess | Return excess before deadline | ✓ Implemented | ExcessContributionService.cs | curl -X POST http://localhost:5001/ach/excess-return -H 'Content-Type: application/json' -d '{"acctId":10000014,"excessAmount":1000,"earningsAmount":25.00,"beforeDeadline":true}' |
| UC-RC36 | Excess | Return excess after deadline (6% penalty) | ✓ Implemented | ExcessContributionService.cs | — |
| UC-RC37 | Excess | Absorb prior-year excess | ✓ Implemented | ExcessContributionService.cs | — |
AvAchService pipeline with inline EligibilityService + ComplianceService.AvAchService sequence between Eligibility and Compliance.cam-mm-backgroundservice-api timer + the CmPeriodicInstruction schema wired up. Out of scope for this POC — separate wave.investor-cash-mgmt-process-api is not part of the POC; we drive cam-movemoney-process-api directly.ScaAchService was left untouched — POC only exercises AvAchService.12 illustrative accounts reconciled against the fixture cam-mm-mock-api/api/1-Api/camMMmockApis.Api/Data/Fixtures/accounts.json (60 accounts total, source of truth). Use these AcctIds for smoke tests and demo cURLs. Earlier drafts referenced 10000055 as R1H and 10000040/10000050 as HSA — fixture actually maps 10000055 to RMO profit sharing, R1H to 10000041/10000042, and HSA to the 10000045–10000048 block.
| AcctId | Class Code | Category | ClientId | Key IraData | Use for |
|---|---|---|---|---|---|
10000001 | BBK | Brokerage | CLT-001 | IraData=null | UC-D1 / UC-W1 brokerage happy-path |
10000013 | QMM | Traditional IRA | CLT-013 | age 51, YTD $3,500 | UC-RC1 happy-path Traditional IRA contribution |
10000014 | QMM | Traditional IRA | CLT-014 | age 63, YTD $8,000 | UC-RC35 excess-return trigger (over $7,000 limit) |
10000016 | RMM | Traditional IRA | CLT-016 | age 68, YTD $7,200, RMD age | UC-W2 RMD withdrawal illustration |
10000023 | RRH | Roth IRA | CLT-023 | age 37, YTD $5,500 | UC-RC2 Roth happy-path + UC-RC18 conversion destination |
10000024 | RRH | Roth IRA | CLT-024 | age 65, YTD $7,800, catch-up eligible | UC-RC4 catch-up near $8,000 combined limit |
10000031 | QOI | SEP-IRA | CLT-031 | age 54, YTD $35,000 | UC-RC7 SEP contribution (under $70,000 limit) |
10000037 | QIS | SIMPLE IRA | CLT-037 | age 43, YTD $8,000 | UC-RC9 SIMPLE deferral |
10000041 | R1H | Inherited IRA (spouse) | CLT-041 | age 54, inherited from spouse d. 2022-09-11 | UC-RC17 rollover-in + contribution NIGO |
10000045 | HBK | HSA | CLT-045 | age 41, YTD $3,200, IsHdhpCovered=true | UC-RC22 HSA happy-path (headroom $1,100 single) |
10000047 | HMM | HSA | CLT-047 | age 34, YTD $1,800, IsHdhpCovered=false | UC-RC22 / UC-RC34 NIGO-HsaNoHdhp rejection |
10000055 | RMO | Other qualified (profit sharing) | CLT-055 | age 56, YTD $23,500 | UC-RC29 RMO allow-list check (not inherited) |
See WAVE2-IMPLEMENTATION-STATUS.md in ~/code/ach-poc/ for the engineering log, diff summary per service, and verification commands.