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
| Layer | Control | Implementation |
| Authentication | ForgeRock OAuth2 / OIDC | JWT with JWKS key rotation (240-min cache via JwksService) |
| Authorization | Bearer token propagation | All Refit clients inject Bearer per request; BFF validates before forwarding |
| Transit encryption | TLS 1.2+ everywhere | WAF termination; internal service mesh TLS; Kafka TLS |
| At-rest encryption | SQL Server TDE | Transparent Data Encryption on all databases |
| PII protection | Log masking | DataMaskUtility.MaskAccountNumber() on all log output |
| Network isolation | EKS service mesh | Internal pods not exposed publicly; BETA via mutual TLS |
| Resiliency | Polly circuit breaker | 5 failures in 30s = break for 60s on all downstream calls |
| Audit | Full pipeline audit trail | Every step persisted via UpdateTransactionRequestAuditDetailsAsync |
| Kafka events | No PII in payload | Transaction events use masked account references only |