4. Gaps, Risks & Deliverables

Withdrawal gap, recurring gap, OLZ dormant code, risk register, and sprint plan

Gap 1: Withdrawal (ACHD) for AV Channel

ScaAchService already handles ACHD. The gap is AvAchService which currently only processes ACHC (contributions). The OLZ BetaRequestFactory, RttRequestFactory, and WwsInstruction all have dormant ACHD logic that was never exposed via a handler.
flowchart TD REQ(["POST /ach/transaction
TransactionType = ACHD"]) R{"Route by OriginId"} SCA["ScaAchService
Already handles ACHD ✓"] AV["AvAchService
Currently ACHC only ✗"] GAP["GAP: AvAchService needs
1. ACHD routing
2. Distribution PECO code
3. Tax withholding calc
4. Net vs Gross distribution
5. IRA-specific eligibility rules"] OLZ["OLZ Reference:
BetaRequestFactory has ACHD PECO codes
RttRequestFactory has ACHD SLA logic
WwsInstruction infers ACHD type"] REUSE["Reuse NLZ pattern:
Add ACHD branches to
EligibilityService + ComplianceService"] REQ --> R R -->|SCA| SCA R -->|AccountView| AV --> GAP GAP --> OLZ OLZ --> REUSE style SCA fill:#e6faf5,stroke:#00b894 style GAP fill:#fde8e6,stroke:#e74c3c style OLZ fill:#fff8ec,stroke:#f39c12 style REUSE fill:#e3f0ff,stroke:#1e88e5

OLZ Dormant Withdrawal Code

File (investor-ach-api)ACHD Logic
BetaRequestFactory.csAchType hardcoded to "ACHD". GetIrasPecoCode: ACHD → "Net Distribution PECO Code", ACHC → "Contribution PECO Code". Handles INS_PER_U/INS_PER_C with inner ACHD/ACHC switch.
RttRequestFactory.csSLA routing: margin+ACHD = SLA 2, managed+INS_PER = SLA 3, IRA (ZH/ZE/ZG) = SLA 3, advisory ops = SLA 1
WwsInstruction.csInferTransactionType(): ManualCreditIndicator=true + ManualDebitIndicator=false → "ACHD"
RulesRequestFactory.csSelectedNetGrossDistribution, FullDistribution balance. Recognizes INS_PER_C/R/U, INS_STD_C/U
CmRequestFactory.csDistributionDay and TotalWithdrawalAmt fields exist but set to null (never populated)

Gap 2: Recurring/Periodic ACH

Must be built from scratch. OLZ has the DB schema (CmPeriodicInstruction) and request type codes (INS_PER_C/R/U) but zero handler code. NLZ has nothing for recurring.
flowchart TD subgraph OLZ_Schema["OLZ: Schema exists but unused"] DB1["CmPeriodicInstruction table
FrequencyCode · CycleBeginDate · CycleEndDate"] DB2["CmRequestAggregate
PeriodicFrequencyCode · BETAPeriodicInstructionId"] DB3["Stored procs support CmPeriodicInstructionId"] DB4["Request type codes
INS_PER_C · INS_PER_R · INS_PER_U"] DB5["Zero handler code ✗"] end subgraph NLZ_Gap["NLZ: Must build in cam repos"] N1["New endpoint: POST /ach/periodic-instruction"] N2["PeriodicInstructionService
Frequency calc: W · BW · M · Q · A"] N3["EligibilityService: pre-validation at setup"] N4["cam-system-api: new periodic DB schema"] N5["cam-mm-backgroundservice-api:
ProcessPeriodicTransactionRequestsService"] N6["RTT: INS_PER_C + INS_PER_R SLA routing"] N7["Kafka: periodic lifecycle events"] end DB1 -.->|Reference| N4 DB4 -.->|Reference| N6 DB5 -.->|Must build| N1 DB5 -.->|Must build| N2 DB5 -.->|Must build| N5 style OLZ_Schema fill:#fff8ec,stroke:#f39c12,color:#1a1d2e style NLZ_Gap fill:#fde8e6,stroke:#e74c3c,color:#1a1d2e

Gap 3: Future-Dated Deposits

OLZ bug: ProcessRequestsHandler.cs lines 161-170 explicitly cancel FutureDate requests — only AfterHours type is processed. NLZ's CheckBetaOffHours handles off-hours queueing, but explicit future-date support in AvAchService needs verification.

Request Type Code Reference

CodeMeaningOLZ UsageNLZ Status
ACHCOne-time ACH Contribution (deposit)PostAchContributionsHandlerBuilt
ACHDOne-time ACH Distribution (withdrawal)BetaRequestFactory, RttRequestFactory — no handlerPartial SCA has it, AV gap
INS_PER_CPeriodic Instruction CreateRTT SLA only, no handlerNot built
INS_PER_RPeriodic Instruction RecurringRTT SLA only, no handlerNot built
INS_PER_UPeriodic Instruction UpdateBetaRequestFactory PECO code onlyNot built

Risk Register

RiskSeverityMitigation
EligibilityService has no ACHD-specific rules (IRA limits, margin checks)HighPort OLZ FICO ACHD rules into NLZ inline EligibilityService. Reference RttRequestFactory IRA/margin/managed-account SLA logic.
Periodic scheduler double-execution across multiple backgroundservice podsHighAdd distributed lock (Redis or DB advisory) to ProcessPeriodicTransactionRequestsService
cam-system-api BETA payload may not support distribution PECO codesMediumVerify cam-system-api BETA request builder handles ACHD. Reference OLZ BetaRequestFactory.GetIrasPecoCode()
Tax withholding logic not in any NLZ serviceMediumBuild TaxWithholdingService in cam-movemoney-process-api. OLZ CmRequest has FedTax/StateTax fields but never populated.
No periodic instruction DB schema in cam-system-apiMediumDesign new table based on OLZ CmPeriodicInstruction (FrequencyCode, CycleBeginDate, CycleEndDate, AmountType)
OLZ FutureDate requests canceled in ProcessRequestsHandlerLowNLZ handles off-hours queueing. Verify explicit future-date support in AvAchService.

POC Deliverables

#ItemNLZ RepoOwnerTarget
1Add ACHD handling to AvAchService (distribution PECO, tax withholding, IRA rules)cam-movemoney-process-apiDevSprint +1
2Add ACHD-specific eligibility rules to inline EligibilityServicecam-movemoney-process-apiDevSprint +1
3Design periodic instruction DB schemacam-movemoney-system-apiKaushikSprint +1
4Build POST /ach/periodic-instruction endpoint (create/modify/cancel)cam-movemoney-process-apiDevSprint +2
5Build ProcessPeriodicTransactionRequestsServicecam-mm-backgroundservice-apiDevSprint +2
6Verify cam-system-api BETA request supports ACHD PECO codescam-movemoney-system-apiKaushik + BETA teamSprint +1
7Integration test: ACHD via NLZ path (flag ON, AV channel)cam-movemoney-process-apiQESprint +2
8Add Kafka events for periodic transaction lifecyclecam-movemoney-process-apiDevSprint +2