INEX MM | ACH Withdrawal & Deposit | SD 2026.04

Solution Design — NLZ Migration

Key Details

Product CodeINEX
Product NameInvestor Experience
DifferentiatorMoney Movement ACH
New / UpdatedUpdated
External Client FacingYes (Investor portal)
Regulatory RequirementsSEC/FINRA ACH transaction rules, SEC Rule 17a-4 (books & records)
Vendor DependenciesBETA (core transaction processing)

1.0 Document Control

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

2.0 Business Drivers

Enable ACH withdrawals and recurring transactions through the NLZ cloud-native platform, achieving feature parity with OLZ while leveraging NLZ architectural improvements (inline rules, Kafka events, parallel processing, channel routing).

2.1 Business Conceptual Diagram

graph LR Investor(["Investor"]) --> SPA["NLZ SPA"] SPA --> BFF["BFF Bridge
investor-cash-mgmt-process-api"] BFF --> CAM["cam-movemoney-process-api
Orchestrator"] CAM --> BETA(["BETA
Core Transactions"]) CAM --> Notify(["Notification
Email/SMS"]) CAM --> Track(["RTT
Request Tracking"]) style Investor fill:#e8ecff,stroke:#4f6bed style CAM fill:#e6faf5,stroke:#00b894 style BETA fill:#f0eeff,stroke:#6c5ce7

3.0 Architecture Drivers — C4 Model

C4 Level 1: System Context

Shows the ACH Money Movement system in the context of its users and external systems.

graph LR INV(["Investor\n[Person]"]) ADV(["Financial Advisor\n[Person]"]) SPA["Investor Experience\nNLZ SPA\n[Software System]"] MM["ACH Money Movement\n[Software System]\ncam-movemoney-*"] BETA(["BETA\n[External System]\nCore Transaction Processing"]) BANK(["Bank / ACH Network\n[External System]"]) RTT(["RTT\n[External System]\nRequest Tracking"]) NOTIF(["Notification\n[External System]\nEmail / SMS"]) INV -->|Submits deposits\nand withdrawals| SPA ADV -->|Submits on behalf\nof investor| SPA SPA -->|API calls| MM MM -->|Submits ACH\ntransaction| BETA BETA -->|Settles\nfunds| BANK MM -->|Tracks\nrequest status| RTT MM -->|Sends\nconfirmations| NOTIF style INV fill:#e8ecff,stroke:#4f6bed style ADV fill:#e8ecff,stroke:#4f6bed style SPA fill:#e6faf5,stroke:#00b894 style MM fill:#c8e6c9,stroke:#388e3c style BETA fill:#f0eeff,stroke:#6c5ce7 style BANK fill:#f0eeff,stroke:#6c5ce7 style RTT fill:#fce4ec,stroke:#e91e63 style NOTIF fill:#f0eeff,stroke:#6c5ce7

C4 Level 2: Container Diagram

Zooms into the ACH Money Movement system showing individual deployable containers.

graph TD SPA["NLZ SPA\n[Container: React]\nInvestor-facing UI"] BFF["investor-cash-mgmt-process-api\n[Container: .NET 8 / EKS]\nBFF Bridge + flag routing"] PROC["cam-movemoney-process-api\n[Container: .NET 8 / EKS]\nACH orchestrator + rules engine"] SYS["cam-movemoney-system-api\n[Container: .NET 8 / EKS]\nDB CRUD + BETA submission + audit"] INST["cam-mm-instruction-system-api\n[Container: .NET 8 / EKS]\nBank instruction management"] BG["cam-mm-backgroundservice-api\n[Container: .NET 8 / EKS]\nTimer-based queue processor"] DB[("SQL Server\n[Container: Database]\nTransaction + audit data")] KAFKA["Kafka\n[Container: Message Broker]\nTransaction status events"] SPA -->|HTTPS/JSON| BFF BFF -->|REST + Bearer token| PROC BG -->|REST| PROC PROC -->|Refit| SYS PROC -->|Refit| INST SYS -->|EF Core| DB PROC -->|Confluent producer| KAFKA style SPA fill:#e6faf5,stroke:#00b894 style BFF fill:#fff8ec,stroke:#f39c12 style PROC fill:#c8e6c9,stroke:#388e3c style SYS fill:#e3f0ff,stroke:#1e88e5 style INST fill:#e3f0ff,stroke:#1e88e5 style BG fill:#c8e6c9,stroke:#388e3c style DB fill:#f0eeff,stroke:#6c5ce7 style KAFKA fill:#fff8ec,stroke:#f39c12

C4 Level 3: Component Diagram (cam-movemoney-process-api)

Internal components of the NLZ orchestrator showing channel routing, rules engine, and shared pipeline.

graph TD subgraph API["API Layer"] CTRL["AchController\n[Component]\nREST endpoints"] VAL["FluentValidation\n[Component]\nRequest validation"] end subgraph Routing["Channel Routing"] SVC["AchService\n[Component]\nOriginId router"] AV["AvAchService\n[Component]\nAccountView channel"] SCA["ScaAchService\n[Component]\nSCA channel + RulesService"] QUEUE["AchQueueService\n[Component]\nQueued transaction resubmission"] end subgraph Rules["Inline Rules Engine"] ELIG["EligibilityService\n[Component]\nAccount class + BORD +\nhouse acct + high-dollar"] COMP["ComplianceService\n[Component]\nReg type + employee class"] end subgraph Pipeline["Shared Pipeline"] COMMON["AchCommonService\n[Component]\nParallel fetch + BETA + RTT +\nnotify + audit + Kafka"] MAP["AchTransactionMapper\n[Component]\nRequest/response mapping"] BIZ["AchBusinessHelper\n[Component]\nValidation + error responses"] BDAY["BusinessDayCalculatorService\n[Component]\nHoliday + business hours"] end CTRL --> VAL --> SVC SVC -->|AccountView| AV SVC -->|SCA| SCA CTRL --> QUEUE AV --> ELIG --> COMP AV --> COMMON SCA --> COMMON QUEUE --> COMMON COMMON --> MAP COMMON --> BIZ COMMON --> BDAY style API fill:#e8ecff,stroke:#4f6bed,color:#1a1d2e style Routing fill:#fff8ec,stroke:#f39c12,color:#1a1d2e style Rules fill:#fde8e6,stroke:#e74c3c,color:#1a1d2e style Pipeline fill:#e6faf5,stroke:#00b894,color:#1a1d2e

C4 Level 4: Code Diagram (AvAchService Pipeline)

Execution flow inside AvAchService showing the 10-step transaction processing pipeline.

flowchart TD E["PostAchTransactionAsync()"] S1["FetchAccountDataParallelAsync()\n4 concurrent: AccountDetails +\nRestrictions + Transfers + BetaInstructions"] S2["ValidateAvDetails() + extract AchInstruction"] S3["AchTransactionMapper.MapTransactionRequest()\nTryInsertTransactionRequestAsync()"] S4["EnqueueNotificationAsync()\n(fire-and-forget)"] S5["UpdateRttAsync(RttUpdate.Submitted)"] S6["EligibilityService.EvaluateEligibility()"] S7["ComplianceService.EvaluateCompliance()"] S8["UpdateStatusAsync(Approved)\nSafeAuditUpdateAsync()"] S9["CheckBetaOffHours() ||\nPostBetaAsync()"] S10["PatchBetaIdentifiersAsync()\nUpdateStatusAsync(Completed)\nUpdateRttAsync(Completed)\nKafka publish"] E --> S1 --> S2 --> S3 --> S4 --> S5 --> S6 --> S7 --> S8 --> S9 --> S10 style E fill:#e8ecff,stroke:#4f6bed style S1 fill:#e3f0ff,stroke:#1e88e5 style S6 fill:#fde8e6,stroke:#e74c3c style S7 fill:#fde8e6,stroke:#e74c3c style S9 fill:#f0eeff,stroke:#6c5ce7 style S10 fill:#e6faf5,stroke:#00b894

Security Architecture Diagram (HLD)

Security boundaries, authentication flows, and data protection controls.

graph TD subgraph Internet["Internet / Investor"] USER(["Investor Browser"]) end subgraph Edge["Edge / Gateway"] WAF["WAF / API Gateway\n[TLS termination]"] FR["ForgeRock\n[IdP: JWT issuance + JWKS]"] end subgraph EKS["EKS Cluster (Internal)"] subgraph Public["DMZ Pods"] BFF2["investor-cash-mgmt-process-api\n[JWT validation via JWKS]\n[Bearer token propagation]"] end subgraph Internal["Internal Service Mesh"] CAM2["cam-movemoney-process-api\n[JWT validation]\n[PII masking: DataMaskUtility]\n[Polly circuit breaker]"] SYS2["cam-movemoney-system-api\n[Service-to-service auth]\n[SQL TDE: encryption at rest]"] BG2["cam-mm-backgroundservice-api\n[Service account auth]\n[No external exposure]"] end end subgraph Data["Data Layer"] SQL[("SQL Server\n[TDE encryption at rest]\n[Access via EF Core]")] KAFKA2["Kafka\n[TLS in transit]\n[No PII in events]"] end subgraph External2["External Systems"] BETA2(["BETA\n[Mutual TLS]"]) RTT2(["RTT\n[Bearer token]"]) end USER -->|HTTPS| WAF USER -->|OAuth2 / OIDC| FR FR -->|JWT + JWKS| WAF WAF -->|TLS 1.2+| BFF2 BFF2 -->|Bearer propagation| CAM2 BG2 -->|Internal REST| CAM2 CAM2 -->|Refit + Bearer| SYS2 SYS2 -->|EF Core| SQL CAM2 -->|TLS| KAFKA2 SYS2 -->|Mutual TLS| BETA2 CAM2 -->|Bearer| RTT2 style Internet fill:#fde8e6,stroke:#e74c3c,color:#1a1d2e style Edge fill:#fff8ec,stroke:#f39c12,color:#1a1d2e style EKS fill:#e6faf5,stroke:#00b894,color:#1a1d2e style Public fill:#fff8ec,stroke:#f39c12,color:#1a1d2e style Internal fill:#e6faf5,stroke:#00b894,color:#1a1d2e style Data fill:#e3f0ff,stroke:#1e88e5,color:#1a1d2e style External2 fill:#f0eeff,stroke:#6c5ce7,color:#1a1d2e

Security Controls Summary

LayerControlImplementation
AuthenticationForgeRock OAuth2 / OIDCJWT with JWKS key rotation (240-min cache via JwksService)
AuthorizationBearer token propagationAll Refit clients inject Bearer per request; BFF validates before forwarding
Transit encryptionTLS 1.2+ everywhereWAF termination; internal service mesh TLS; Kafka TLS
At-rest encryptionSQL Server TDETransparent Data Encryption on all databases
PII protectionLog maskingDataMaskUtility.MaskAccountNumber() on all log output
Network isolationEKS service meshInternal pods not exposed publicly; BETA via mutual TLS
ResiliencyPolly circuit breaker5 failures in 30s = break for 60s on all downstream calls
AuditFull pipeline audit trailEvery step persisted via UpdateTransactionRequestAuditDetailsAsync
Kafka eventsNo PII in payloadTransaction events use masked account references only

3.1.1 Technology Architecture View

graph TD subgraph Presentation["Presentation Layer"] SPA["NLZ SPA
React"] end subgraph Process["Process Layer (NLZ Cloud)"] BFF["investor-cash-mgmt-process-api
BFF Bridge · Flag routing"] CAM["cam-movemoney-process-api
.NET 8 · EKS
AchService · EligibilityService
ComplianceService · Kafka"] BG["cam-mm-backgroundservice-api
.NET BackgroundService
Queue + Periodic processor"] end subgraph System["System Layer (NLZ Cloud)"] SYS["cam-movemoney-system-api
DB · BETA · Audit · Status"] INST["cam-mm-instruction-system-api
Bank instructions"] end subgraph External["External Services"] BETA(["BETA"]) RTT(["RTT"]) NOTIF(["Notification"]) ACCT(["Account Details"]) KAFKA(["Kafka"]) end SPA --> BFF --> CAM BG --> CAM CAM --> SYS CAM --> INST SYS --> BETA CAM --> RTT CAM --> NOTIF CAM --> ACCT CAM --> KAFKA style Presentation fill:#e8ecff,stroke:#4f6bed,color:#1a1d2e style Process fill:#e6faf5,stroke:#00b894,color:#1a1d2e style System fill:#e3f0ff,stroke:#1e88e5,color:#1a1d2e style External fill:#f0eeff,stroke:#6c5ce7,color:#1a1d2e

3.1.2 Key Integrations

FromToProtocolPurpose
BFF Bridgecam-process-apiREST/JSON (Bearer token)Transaction submission, instructions
cam-process-apicam-system-apiRefit (internal)DB CRUD, BETA submit, audit, status
cam-process-apicam-instruction-apiRefit (internal)Beta bank instruction lookup
cam-process-apiKafkaConfluent producerTransaction status events
cam-backgroundservicecam-process-apiREST/JSONQueue/periodic processing dispatch

3.1.3 Security

3.2 Compliance

Books & Records

ACH transactions are books and records under SEC Rule 17a-4. Full audit trail maintained at every pipeline step via cam-system-api.

Data Privacy

PII: account numbers, bank account numbers, SSN (tax withholding pass-through). Protected: TLS in transit, encryption at rest, masked in logs.

Accessibility

NLZ SPA complies with WCAG 2.2 AA.

3.3 Non-Functional Requirements

High-level targets. Measurable NFRs with specific numbers are defined in the SyDD.
CategoryRequirement
Availability99.9% during business hours (6 AM – 8 PM ET, Mon-Fri)
Capacity & ScalabilitySupport current AV volume (~5,000 ACH/day) with 3x headroom
Performance< 5s end-to-end for transaction submission (P95)
ReliabilityAt-least-once delivery via Kafka; idempotent transaction processing
ResiliencyPolly circuit breaker on all downstream calls; feature flag rollback to OLZ
ObservabilityStructured logging (Serilog → ELK), Kafka event trail, health checks
InteroperabilityREST/JSON APIs; Refit typed clients; Kafka events for async consumers
MaintainabilityClean architecture layers (API/Business/Domain/Data); FluentValidation; unit tests