Skip to content

Instantly share code, notes, and snippets.

@sscotth
Created March 13, 2026 00:32
Show Gist options
  • Select an option

  • Save sscotth/03d935cbeb6407502de9526374cbf924 to your computer and use it in GitHub Desktop.

Select an option

Save sscotth/03d935cbeb6407502de9526374cbf924 to your computer and use it in GitHub Desktop.
PRD.md

Product Requirements Document: Mobile Check Deposit System

1. Executive Summary & Problem Statement

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.

2. Business Context & Impact Metrics

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_entries table 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.

3. High-Level System Architecture

The backend will be built as a set of bounded contexts (Go microservices or heavily modularized monolith) interacting with a PostgreSQL database.

Core Components:

  1. 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.
  2. Vendor Integration Layer: Interfaces with the external IQA/MICR vendor. In lower environments, traffic routes to a configurable Deterministic Vendor Stub.
  3. Funding Service (The FSM): The core state machine and business rules engine.
  4. Core Ledger & Audit Datastore (PostgreSQL): A strict double-entry accounting module, alongside first-class tables for decision tracing and localized notifications.
  5. Operator & Ledger UIs: Endpoints and web interfaces supporting back-office tools for exception handling, notification monitoring, cap-table viewing, and settlement monitoring.
  6. Settlement Engine: An asynchronous worker that runs daily at 6:30 PM CT to generate X9 files and track bank acknowledgments.

4. Functional Requirements

4.1. Deposit Submission, Validation & State Machine

  • 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: REQUESTEDVALIDATINGANALYZINGAPPROVEDFUNDS_POSTEDCOMPLETED

  • Validation Rejection Path: REQUESTEDVALIDATINGREJECTED

  • Business Rule Rejection Path: ...ANALYZINGREJECTED

  • Return Path: ...FUNDS_POSTEDRETURNED (or COMPLETEDRETURNED)

  • 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.

4.2. Funding Service, Rules & Omnibus Resolution

  • 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.

4.3. Double-Entry Ledger System & Schema

  • Financial transactions must be appended as immutable rows in a ledger_entries table. Every FUNDS_POSTED transition 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.

4.4. Per-Deposit Decision Trace & Audit Trail

  • A first-class decision_traces table linked to the core transfers table via TransferId.
  • Attributes: TransferId, EventTimestamp, EventType, and Payload (JSONB capturing exact inputs/outputs like the vendor's raw response or operator override notes).

4.5. Settlement File Generation & Rollover Logic

  • 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 CT on the previous business day to <= 18:30:00 CT on the current business day.

4.6. Returns & Reversals (With Notifications)

  • Webhook Ingestion: Expose an endpoint to ingest simulated returned check notifications.
  • Ledger Postings: Automatically execute two atomic postings:
  1. Reversal: Debit Investor Account, Credit Omnibus Account (original amount).
  2. Penalty: Debit Investor Account, Credit Internal Fee Account ($30.00).
  • Simulated Notifications: Write a record to a local notifications table containing InvestorId, TransferId, Type (RETURN_FEE_NOTICE), MessageBody, and SentTimestamp.
  • 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.

5. User Interfaces

5.1. Minimal Mobile Submission UI (Simulator)

  • 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.

5.2. Operator Review & Notifications UI

  • 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 notifications table to verify return/fee notices.

5.3. Cap-Table / Ledger View UI

  • Displays the internal cap-table state, showing resolved investor account balances, omnibus balances, and a chronological list of all posted ledger entries.

5.4. Settlement Monitoring View

  • Tracks settlement file generation, generation timestamps, and Settlement Bank acknowledgment statuses.

5.5. Transfer Status Tracking API & View

  • 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 TransferId and returns its current state in the FSM, along with a timestamped history of its transitions (leveraging the decision_traces table).

6. Non-Functional & Technical Requirements

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.

7. Deliverables & Repository Structure

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.md or SUBMISSION.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.example to .env as 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., a coverage.html visual report and a test_output.txt file of the verbose Go test logs) proving minimum test coverage and successful execution of all required scenarios.

  • .env.example: Required environment variables.


8. Evaluation Criteria for Production Readiness

  • 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 notifications table.
  • 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment