Modern brokerage investors expect frictionless, mobile-first funding capabilities. Relying on mail-in checks or wire transfers introduces unacceptable friction and delays fund availability.
This project will deliver a highly available, ACID-compliant Mobile Check Deposit system. The system will ingest check images via a minimal mobile-simulation UI, orchestrate third-party Image Quality Assessment (IQA) and Optical Character Recognition (OCR), apply strict business routing rules (including contribution types), post funds to an immutable double-entry ledger, and automatically generate daily X9.37 Image Cash Letter files for bank settlement. It also includes operational web UIs for manual review, cap-table visualization, and exception handling.
This system must balance user convenience with strict regulatory compliance and risk mitigation. It enforces deposit caps, contribution limits, and operational review gates while maintaining a perfect financial audit trail.
Key Performance Indicators (KPIs) & Success Metrics:
- Ledger Integrity: 100% of approved deposits reconcile perfectly between the internal
ledger_entriestable and the generated X9 settlement files. Zero orphan records. - Gating Correctness: 0 deposits bypass business rules (e.g., $5,000 limits, duplicate checks).
- Automated Throughput: >85% of deposits pass straight-through processing (STP) without operator intervention.
- Operator SLA: Items flagged for review surface in the Operator UI in < 1 second.
- CI/CD Reliability: 100% deterministic test passes in CI environments via the internal Vendor Stub, maintaining high test coverage metrics.
The backend will be built as a set of bounded contexts (Go microservices or heavily modularized monolith) interacting with a PostgreSQL database.
- Mobile Submission UI & Deposit Capture API: A minimal UI simulating a mobile client and the public-facing REST API to submit check images and metadata.
- Vendor Integration Layer: Interfaces with the external IQA/MICR vendor. In lower environments, traffic routes to a configurable Deterministic Vendor Stub.
- Funding Service (The FSM): The core state machine and business rules engine.
- Core Ledger & Audit Datastore (PostgreSQL): A strict double-entry accounting module, alongside first-class tables for decision tracing and localized notifications.
- Operator & Ledger UIs: Endpoints and web interfaces supporting back-office tools for exception handling, notification monitoring, cap-table viewing, and settlement monitoring.
- Settlement Engine: An asynchronous worker that runs daily at 6:30 PM CT to generate X9 files and track bank acknowledgments.
- State Machine Semantics & Transitions: The system must enforce a strict Finite State Machine (FSM).
| State | Description |
|---|---|
| REQUESTED | Deposit submitted by the investor via the mobile UI. |
| VALIDATING | Payload sent to the Vendor Service stub for IQA/MICR/OCR analysis. |
| ANALYZING | Business rules (limits, duplicates, eligibility) being applied by Funding Service. |
| APPROVED | Passed all checks and business rules; awaiting ledger posting. |
| FUNDS_POSTED | Provisional credit successfully posted to the investor's ledger account. |
| COMPLETED | Settlement file generated and confirmed by the Settlement Bank. |
| REJECTED | Failed vendor validation, business rule gating, or operator manual review. |
| RETURNED | Check bounced post-settlement; reversal and fee postings applied. |
-
Valid Transitions:
-
Happy Path:
REQUESTED→VALIDATING→ANALYZING→APPROVED→FUNDS_POSTED→COMPLETED -
Validation Rejection Path:
REQUESTED→VALIDATING→REJECTED -
Business Rule Rejection Path:
...→ANALYZING→REJECTED -
Return Path:
...→FUNDS_POSTED→RETURNED(orCOMPLETED→RETURNED) -
Re-submission Flow for IQA Failures: The system must support re-submission for actionable IQA failures (Blur or Glare). The error messages must explicitly map to the specific image that failed.
-
Configurable Vendor Stub: A deterministic Vendor Stub configured to return specific scenarios via specific test Account Numbers.
-
Configuration Mechanism: Submitting a deposit with a predefined account number will trigger a matching stub response without code changes (e.g., Account
111111= Clean Pass,222222= IQA Fail Blur,333333= MICR Read Failure, etc.). -
Required Stub Scenarios: 1. Clean Pass, 2. IQA Pass, 3. IQA Fail (Blur), 4. IQA Fail (Glare), 5. MICR Read Failure, 6. Duplicate Detected, 7. Amount Mismatch.
-
Investor Session & Account Eligibility: Validate the user session and resolve the public Account ID to the internal ledger account number. Enforce strict eligibility gates before processing:
-
Account Status: Must be
ACTIVE(reject frozen, closed, or pending accounts). -
Account Type: Must support check deposits (e.g., reject unsupported trust or margin-only configurations if applicable).
-
Correspondent Omnibus Resolution: Look up the Correspondent associated with the investor's account and resolve the specific Omnibus Account ID for the
From AccountId. -
Deposit Limits: Enforce a hard-coded MVP deposit limit of $5,000.
-
Contribution Types: Enforce contribution type defaults (e.g., defaulting to "Individual Contribution" for retirement accounts).
-
Duplicate Detection: Query the ledger for matching MICR data (routing + account number) and deposit amounts specifically within a strict 90-day trailing window.
- Financial transactions must be appended as immutable rows in a
ledger_entriestable. EveryFUNDS_POSTEDtransition requires a balanced, atomic transaction. - Required Schema Attributes:
To AccountId,From AccountId,Type: MOVEMENT,Memo: FREE,SubType: DEPOSIT,Transfer Type: CHECK,Currency: USD,Amount,SourceApplicationId: TransferID. - Any imbalance must trigger a complete database rollback.
- A first-class
decision_tracestable linked to the coretransferstable viaTransferId. - Attributes:
TransferId,EventTimestamp,EventType, andPayload(JSONB capturing exact inputs/outputs like the vendor's raw response or operator override notes).
- Execution Trigger: A cron job executing exactly at 18:30:00 CT (6:30 PM CT) on valid banking days.
- File Generation: Construct a balanced X9 file (or structured JSON equivalent).
- Rollover Logic: Boundaries are strictly
> 18:30:00 CTon the previous business day to<= 18:30:00 CTon the current business day.
- Webhook Ingestion: Expose an endpoint to ingest simulated returned check notifications.
- Ledger Postings: Automatically execute two atomic postings:
- Reversal: Debit Investor Account, Credit Omnibus Account (original amount).
- Penalty: Debit Investor Account, Credit Internal Fee Account ($30.00).
- Simulated Notifications: Write a record to a local
notificationstable containingInvestorId,TransferId,Type(RETURN_FEE_NOTICE),MessageBody, andSentTimestamp. - Deliberate Scoping Decision: Utilizing a local database table to track notifications deliberately satisfies the "notify investor" requirement without introducing the unnecessary complexity and overhead of integrating third-party email/SMS providers for this MVP.
- A lightweight frontend simulating a mobile app. Uses inputs for the test Account Number (to trigger stub responses), amount, and synthetic dummy image data to satisfy the backend contract.
- Review Queue: Surfaces flagged deposits, displaying base64 check images, MICR data, vendor confidence scores, risk indicators, and recognized vs. entered amount comparisons.
- Controls: Approve/Reject with mandatory audit logging, and override capabilities for contribution types.
- Search & Filter Capabilities: Operators must be able to query the review queue and historical decisions. The UI and underlying API must support filtering by date range, current transfer status, account identifier, and deposit amount.
- Communications Tab: A dedicated view where operators can query the
notificationstable to verify return/fee notices.
- Displays the internal cap-table state, showing resolved investor account balances, omnibus balances, and a chronological list of all posted ledger entries.
- Tracks settlement file generation, generation timestamps, and Settlement Bank acknowledgment statuses.
- REST Endpoint: Expose a dedicated
GET /transfers/{TransferId}endpoint allowing clients to poll or retrieve the real-time status of a specific deposit. - Lifecycle UI/CLI: Provide a minimal view or CLI command that takes a
TransferIdand returns its current state in the FSM, along with a timestamped history of its transitions (leveraging thedecision_tracestable).
| Category | Requirement |
|---|---|
| Language & DB | Go (Golang) microservices or modular monolith. PostgreSQL required for SERIALIZABLE or READ COMMITTED ACID transactions. |
| Testing & Coverage | Minimum 10 tests required covering: Happy path, Vendor stub scenarios (all 7), Business rules, State Machine boundaries, Reversals, and Settlement. |
| Observability | Structured JSON logs. decision_traces table for end-to-end audit query. Every log entry must include a source field. |
| Data Privacy | Synthetic Data Only: Absolutely no real PII, real account numbers, or actual check images. |
| Performance | Validation < 1 sec; Ledger Posting in seconds; State Transitions < 1 sec; Settlement batch in seconds. |
The final deliverable must include a GitHub repository with a single-command setup (e.g., task dev or docker compose up) and the following layout:
-
README.mdorSUBMISSION.md: Must explicitly include: -
Project name & Summary: What was built, key design choices, trade-offs.
-
How to run (copy-paste commands): Must explicitly instruct the user to copy
.env.exampleto.envas the first step before running Docker/Make. -
Test/eval results: Screenshot/log snippet and link to
/reports. -
With one more week, we would:
-
Risks and limitations: (State no compliance/regulatory claims).
-
How should ACME evaluate production readiness?
-
Deterministic Demo Scripts: A prominently featured, standalone directory (e.g.,
/scripts/demo) containing executable shell/bash scripts designed to automatically exercise all paths for operators. Must include flows for: -
Happy Path end-to-end
-
Rejection paths (all 7 Vendor Stub scenarios triggered via test accounts)
-
Manual Review routing and operator resolution
-
Return/Reversal triggering
-
/docs/decision_log.md: Key technical decisions (including the notification table scoping and stub mapping logic). -
/docs/architecture.md: System diagram, data flow. -
/tests: Test cases and suites. -
/reports: Contains the test report artifact (e.g., acoverage.htmlvisual report and atest_output.txtfile of the verbose Go test logs) proving minimum test coverage and successful execution of all required scenarios. -
.env.example: Required environment variables.
- System Design: Clear boundaries, Go implementations, PostgreSQL schema (Ledger + Audit).
- Core Correctness: Happy path functions, business rules enforce 90-day deduplication, ledger balances, X9 files generate.
- Vendor Service Stub Quality: 7 differentiated responses configurable without code changes.
- Operator Workflows: Review UI, Notification UI, Cap-table, and Monitoring function correctly with queryable
decision_traces. - Return Handling: Reversals post with fees and populate the
notificationstable. - Testing Rigor: Minimum 10+ tests passing, thoroughly exercising the happy path, all 7 vendor stub scenarios, invalid state transition attempts, business rule gating, reversal calculations, and settlement file contents.