INEX MM | ACH Withdrawal & Deposit | SyDD 2026.04

System Design Description — NLZ Migration

Key Details

Product CodeINEX
System Namecam-movemoney-process-api + cam-mm-backgroundservice-api
SD ReferenceINEX MM | ACH Withdrawal & Deposit | SD 2026.04
Key ContactsKaushik Sarkar (Architect), Move Money Team (Development)

1.0 Document Control

VersionDateAuthorChanges
1.02026-04-21Kaushik SarkarInitial draft — POC scope

1.2 Governance Approvals

ReviewApproverStatusDate
API ReviewTBDPending
Security ReviewTBDPending
SRE ReviewTBDPending
Event ReviewTBDPending

2.0 System Overview

Purpose: NLZ ACH transaction processing for one-time deposits, one-time withdrawals, and recurring/periodic ACH. Replaces OLZ investor-ach-api with cloud-native architecture.

2.1 System Context Diagram

graph TD subgraph cam_process["cam-movemoney-process-api"] CTRL["AchController"] ACH["AchService
Channel Router"] AV["AvAchService"] SCA["ScaAchService"] ELIG["EligibilityService
(inline)"] COMP["ComplianceService
(inline)"] COMMON["AchCommonService
Shared pipeline"] QUEUE["AchQueueService"] end CTRL --> ACH ACH -->|AV| AV ACH -->|SCA| SCA AV --> ELIG AV --> COMP AV --> COMMON SCA --> COMMON CTRL --> QUEUE COMMON --> SYS["cam-movemoney-system-api"] COMMON --> INST["cam-mm-instruction-system-api"] COMMON --> ACCT(["Account Details"]) COMMON --> RTT(["RTT"]) COMMON --> KAFKA(["Kafka"]) SYS --> BETA(["BETA"]) style cam_process fill:#e6faf5,stroke:#00b894,color:#1a1d2e style ELIG fill:#fde8e6,stroke:#e74c3c style COMP fill:#fde8e6,stroke:#e74c3c style SYS fill:#e3f0ff,stroke:#1e88e5 style BETA fill:#f0eeff,stroke:#6c5ce7

3.0 Design Considerations

3.1.1 System Inputs

EndpointInput ModelKey Fields
POST /ach/transactionTransactionRequestLplAccountNumber, Amount, TransactionType (ACHC/ACHD), BetaInstructionNumber, OriginId (AV/SCA), RequestedExecutionDate
POST /ach/queueprocessQuery paramsrequestId, requestedBy, origin
POST /ach/periodic-instructionPeriodicInstructionRequest NEWFrequencyCode (W/BW/M/Q/A), CycleBeginDate, CycleEndDate, Amount, AmountType, TransactionType

3.1.2 System Outputs

OutputModelKey Fields
Transaction responseTransactionResponseCmRequestId, Status, ErrorMessage
Kafka eventTransactionDatatransactionId, status, accountNumber (masked), amount, timestamp

3.1.3 System Behavior: 10-Step Pipeline

flowchart TD S1["1. PARALLEL: Account + Restrictions
+ Transfers + Instructions"] S2["2. Validate + Map + Insert DB
Status = Received"] S3["3. Enqueue notification
(fire-and-forget)"] S4["4. RTT → Submitted"] S5["5a. EligibilityService (inline)
5b. ComplianceService (inline)"] S6["6. Status → Approved + Audit"] S7["7. Check Beta off-hours"] S8["8. PostBeta via cam-system-api"] S9["9. Patch Beta identifiers"] S10["10. Status → Completed
RTT → Completed
Kafka event"] S1 --> S2 --> S3 --> S4 --> S5 --> S6 --> S7 --> S8 --> S9 --> S10 style S1 fill:#e3f0ff,stroke:#1e88e5 style S5 fill:#fde8e6,stroke:#e74c3c style S8 fill:#f0eeff,stroke:#6c5ce7 style S10 fill:#e6faf5,stroke:#00b894

3.1.4 New: ACHD Withdrawal Additions

ComponentChange Required
AvAchServiceHandle TransactionType=ACHD alongside ACHC
EligibilityServiceAdd ACHD rules: IRA distribution limits, margin account checks, high-dollar withdrawal threshold
cam-system-api BETAMap distribution PECO codes (reference OLZ BetaRequestFactory.GetIrasPecoCode)
TaxWithholdingService NEWFedTax/StateTax calculation, net vs gross distribution

3.1.5 New: Periodic Instruction Schema

ColumnTypeDescription
PeriodicInstructionIdint (PK)Auto-increment identifier
InstructionIdint (FK)Reference to bank instruction
LplAccountNovarcharAccount number
TransactionTypevarcharACHC or ACHD
FrequencyCodevarcharW (weekly), BW (biweekly), M (monthly), Q (quarterly), A (annual)
AmountTypevarcharFixed or Variable
AmountdecimalTransaction amount
CycleBeginDatedatetimeFirst execution date
CycleEndDatedatetime (nullable)Optional end date
StatusvarcharActive / Inactive / Cancelled
NextExecutionDatedatetimeCalculated next cycle date
LastExecutedDatedatetime (nullable)Last successful execution

3.1.6 PII Data Attributes

AttributeClassificationProtection
LplAccountNumberPII / ConfidentialMasked in logs (DataMaskUtility), encrypted at rest
BankAccountNumberPII / ConfidentialMasked in logs, encrypted at rest, TLS in transit
SSN (tax withholding)PII / RestrictedPass-through only, not stored in MM system

3.1.7 Monitoring & Health Checks

4.0 Technology Security Architecture

Authentication

  • ForgeRock JWKS with key rotation
  • JWT validation (240-min cache)
  • Bearer token injection on all Refit clients

Data Security

  • TLS 1.2+ in transit
  • SQL Server TDE at rest
  • PII masked in all logs

Network

  • EKS service mesh (internal only)
  • No public endpoint exposure
  • Polly circuit breaker on all downstream

Audit & Logging

  • Audit trail at every pipeline step
  • Structured JSON via Serilog
  • Correlation IDs for distributed tracing

5.0 Non-Functional Requirements

CategoryMetricTarget
Business HoursOperating window6:00 AM – 8:00 PM ET (Mon-Fri, excl. market holidays)
Deployment DowntimeMax outage per deploy0 (rolling EKS deployment)
Availability (DR Tier 2)RTO / RPORTO: 4 hours / RPO: 1 hour
CapacityAuthorized users~2M investors
CapacityConcurrent (peak)~500 requests/min
Capacity3-year projection3x current volume
Performance (OLTP)P95 latency< 3 seconds
Performance (OLTP)P99 latency< 5 seconds
Performance (Batch)Queue interval60 min (configurable)
ObservabilitySLITransaction success rate, P95 latency
ObservabilitySLO99.5% success, P95 < 3s
ObservabilityAlertingError rate > 1% triggers alert
ResiliencyCircuit breakerPolly: 5 failures in 30s = break 60s
ResiliencyRollbackFeature flag to OLZ (NEW_MOVE_MONEY_API_ENABLE=0)
ReliabilityKafka deliveryAt-least-once; idempotent processing

6.0 APIs

MethodEndpointAuthDescription
POST/ach/transactionJWTSubmit ACH transaction (ACHC/ACHD)
POST/ach/queueprocessJWTProcess queued transaction
POST/ach/transactions/searchJWTSearch transaction history
PATCH/ach/transactionJWTBackoffice status update
POST/ach/periodic-instructionJWTNEW Create/modify/cancel recurring
POST/ach/transaction/{id}/publish-eventJWTPublish Kafka event

6.3 Events / Message Formats

EventTopicTriggerPayload
Transaction Receivedmm.ach.transactionDB insert (step 2)transactionId, status=Received, accountNo (masked), amount
Transaction Submittedmm.ach.transactionRTT update (step 4)transactionId, status=Submitted
Transaction Approvedmm.ach.transactionCompliance pass (step 6)transactionId, status=Approved
Transaction Completedmm.ach.transactionBETA success (step 10)transactionId, status=Completed, betaConfirmation
Transaction Nigomm.ach.transactionEligibility/compliance failtransactionId, status=Nigo, reason
Periodic Createdmm.ach.periodicNew periodic instructionperiodicId, frequencyCode, nextExecDate