Skip to content

bluecontract/demo-bank-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

232 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Demo Bank App

Demo Bank App is the end-to-end reference for modelling banking workflows using PayNotes and driving them through the MyOS.

A PayNote is a programmable payment agreement shared by a payer, payee, and guarantor. It captures the commercial promise, the evidence required to fulfill it, and the automated actions that release or refund funds. Everyone sees the same terms and same timeline.

PayNote + MyOS Integration (only ~500 lines of code)

  • POST /v1/paynotes/bootstrap β†’ apps/bank-api/src/paynote/bootstrapPayNote.ts validates the uploaded PayNote, hydrates payer/payee accounts, and forwards the document plus channel bindings to MyOS POST /documents/bootstrap so processing begins instantly.
  • POST /v1/paynotes/webhook β†’ apps/bank-api/src/paynote/webhook.ts ingests MyOS callbacks, downloads event detail via GET /myos-events/{eventId}, and maps capture events to real ledger transfers.
  • Together these handlers amount to ~500 lines of code illustrating how little code is required to wrap a PayNote flow with bank-grade system.

Flow at a Glance

  1. The web app collects the PayNote (YAML or parsed PDF), prompts for source/destination accounts, then calls POST /v1/paynotes/bootstrap.
  2. The bootstrap handler verifies the document, binds participants, and hands it to MyOS via POST /documents/bootstrap.
  3. MyOS processes the PayNote and calls back into POST /v1/paynotes/webhook; the handler retrieves the full payload with GET /myos-events/{eventId}.
  4. When capture events (for example PayNote/Capture Funds Requested or PayNote/Reserve Funds and Capture Immediately Requested) appear, the webhook performs the corresponding bank transfer and logs the result.

πŸš€ Quick Start

Prerequisites

  • Node.js 22+ (LTS) - JavaScript runtime environment
  • npm - Package manager
  • Docker - Required for LocalStack (AWS service emulation)
  • AWS SAM CLI - Required for local Lambda development and testing
  • Localstack samlocal - Required for local Lambda development and testing

Install AWS SAM CLI

Choose one of the following installation methods:

Option 1: Using pip (Recommended)

pip3 install aws-sam-cli

Option 2: Using other methods See the official AWS SAM CLI installation guide for Windows, Linux, and other installation options.

Verify Installation

sam --version

⚠️ Troubleshooting SAM CLI: If you get a "bad interpreter" error, SAM CLI may have been installed with an older Python version. Solutions:

Option 1: Reinstall with current Python

pip3 uninstall aws-sam-cli
pip3 install aws-sam-cli

Option 2: Add Python bin to PATH (if you see PATH warnings)

# Add to your shell profile (.zshrc, .bashrc, etc.)
export PATH="$(python3 -m site --user-base)/bin:$PATH"

Install samlocal

pip3 install aws-sam-cli-local

Verify Installation

samlocal --version

Run the Application

# 1. Install dependencies
npm install

# 2. Ensure Docker is running
npm run docker:check

# 3. Start all services (frontend, backend, localstack)
npm run serve:all

The app will be available at:

Available Scripts

Command Description
npm start Start development server
npm run dev Start development server (alias)
npm test Run tests for affected projects
npm run test:all Run tests for all projects
npm run test:integration Run integration tests for affected projects
npm run test:integration:all Run integration tests for all projects
npm run test:watch Run tests in watch mode
npm run e2e Run E2E tests locally
npm run e2e:dev Run E2E tests against dev environment
npm run e2e:prod Run E2E tests against production environment
npm run build Build affected projects
npm run build:all Build all projects
npm run lint Lint affected projects
npm run lint:all Lint all projects
npm run lint:fix Lint and auto-fix affected issues
npm run typecheck Run TypeScript type checking for all projects
npm run format Format code with Prettier
npm run format:check Check code formatting
npm run format:staged Format only staged files with Prettier
npm run security:audit Run security audit on production dependencies
npm run security:audit:dev Run security audit on development dependencies
npm run security:audit:fix Fix security vulnerabilities
npm run pre-commit Run pre-commit checks manually
npm run validate-commit Validate commit message format
npm run generate-docs Generate OpenAPI docs from TypeScript
npm run wait-for-backend Wait for backend to be ready
npm run clean Reset Nx cache
npm run graph View dependency graph
npm run serve:all Start all services with Nx
npm run serve:stack Start backend stack (LocalStack + Lambda)
npm run docker:check Verify Docker is running

πŸ’‘ Affected vs All: By default, commands run only on "affected" projects (those changed since the last commit). Use :all variants to run on all projects.

🎯 Multi-Service Development

Start all services with Nx orchestration:

# Start all services with dependency management
npm run serve:all

# Start individual services
nx serve localstack           # ensures LocalStack is running
nx serve @demo-bank-app/bank-api  # Backend API only (starts localstack)
nx serve @demo-bank-app/bank-web-app # Frontend only

# Check service status
docker ps --filter 'name=localstack-demo-bank-app'

# Stop services when done
docker stop localstack-demo-bank-app

πŸ§ͺ Testing

Run Tests

# All tests
npm test

# Unit tests in watch mode
npm run test:watch

# E2E tests (full-stack local testing)
npm run e2e

# E2E tests against remote environments
npm run e2e:dev   # Test against dev environment
npm run e2e:prod  # Test against production environment

Note: For local E2E testing, start the backend services first, then run E2E tests:

# Terminal 1: Start the full stack
npm run serve:all

# Terminal 2: Run E2E tests (includes automatic health check)
npm run e2e

The E2E command automatically waits for the backend to become healthy before running tests.

Environment Variables:

Security Auditing

# Run security audit (production dependencies only, moderate+)
npm run security:audit

# Run security audit (all dependencies, high+ only)
npm run security:audit:dev

# Automatically fix security vulnerabilities
npm run security:audit:fix

# Check all vulnerability levels (including low)
npm audit

Build & Deploy

# Build affected projects
npm run build

# Build all projects (when needed)
npm run build:all

# Preview production build
npx nx preview bank-web-app

# Utility commands
npm run clean  # Reset Nx cache
npm run graph  # View dependency graph

πŸ“š Project Documentation

πŸ—οΈ Repository Structure

This project follows a hexagonal architecture within an Nx monorepo.

demo-bank-app/
β”œβ”€β”€ apps/                           # Deployable applications
β”‚   β”œβ”€β”€ bank-web-app/              # React SPA (Vite + Tailwind)
β”‚   β”‚   β”œβ”€β”€ src/                   # Frontend source code
β”‚   β”‚   β”œβ”€β”€ tailwind.config.js     # Styling configuration
β”‚   β”‚   └── vite.config.ts         # Build configuration
β”‚   β”œβ”€β”€ bank-api/                  # AWS Lambda backend
β”‚   β”‚   β”œβ”€β”€ src/                   # Lambda source code
β”‚   β”‚   └── project.json           # SAM local serve config
β”‚   β”œβ”€β”€ localstack/                # LocalStack service wrapper
β”‚   β”‚   └── project.json           # LocalStack serve config
β”‚   └── bank-web-app-e2e/          # Playwright E2E tests
β”‚       β”œβ”€β”€ src/                   # E2E test suites
β”‚       └── playwright.config.ts   # Test configuration
β”œβ”€β”€ libs/                          # Shared libraries
β”‚   β”œβ”€β”€ bank-api-contract/         # Shared API contracts (ts-rest + Zod)
β”‚   β”œβ”€β”€ domain/                    # Domain logic (business rules)
β”‚   β”œβ”€β”€ application/               # Use cases & application services
β”‚   └── infrastructure/            # External adapters (DB, APIs)
β”œβ”€β”€ docs/                          # Architecture & requirements
β”‚   β”œβ”€β”€ adr/                       # Architectural Decision Records
β”‚   β”œβ”€β”€ requirements/              # Functional & non-functional specs
β”‚   └── design/                    # Technical design documents
└── nx.json                        # Nx workspace configuration

Architectural Patterns

πŸ“ /apps vs /libs Split

  • /apps: Deployable units (SPAs, Lambdas, E2E tests)
  • /libs: Reusable code shared between applications

πŸ”· Hexagonal Architecture (Ports & Adapters)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     /apps (Adapters)                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  bank-web-app/     β”‚  bank-api/        β”‚  bank-web-app-e2e/ β”‚
β”‚  (React SPA)       β”‚  (AWS Lambda)     β”‚  (E2E Tests)       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚              β”‚               β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   /libs/domain/   β”‚   β”‚ /libs/app/   β”‚   β”‚ /libs/infra/   β”‚
β”‚  (Business Logic) β”‚   β”‚ (Application)β”‚   β”‚   (Adapters)   β”‚
β”‚  β€’ Accounts       β”‚   β”‚ β€’ Ports      β”‚   β”‚ β€’ DynamoDB     β”‚
β”‚  β€’ Transfers      β”‚   β”‚ β€’ Commands   β”‚   β”‚ β€’ MyOS Client  β”‚
β”‚  β€’ Blue Docs      β”‚   β”‚ β€’ Queries    β”‚   β”‚ β€’ S3 Storage   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🏒 Infrastructure Colocation

Each app manages its own infrastructure-as-code:

  • bank-web-app/: S3 bucket, CloudFront distribution
  • bank-api/: AWS Lambda, API Gateway, DynamoDB
  • Shared resources: Defined in dedicated infrastructure packages

πŸ“¦ Dependency Management Strategy

Single Version Policy

  • DevDependencies centralized at root - All build tools, linters, and testing frameworks managed in workspace root
  • Runtime dependencies per project - Only production dependencies live in individual app/lib package.json files
  • Nx workspace resolution - Enables consistent tooling versions across all projects

⚑ Lambda Production Optimization

Optimized Bundle Generation

  • Tree-shaking enabled: Only used code included via esbuild bundling
  • Minification in production: Code compression for faster cold starts
  • Source maps: Bundled source maps for clear stack traces
# Development build (fast iteration)
nx serve bank-api        # No minification and tree shaking

# Production build (optimized)
nx build bank-api        # Minified tree-shaked bundle, all dependencies inlined

πŸ”— API Contract & Documentation

Shared Contract Library (libs/bank-api-contract)

  • Centralized contracts: TypeScript API definitions using ts-rest + Zod
  • Cross-app consistency: Backend, frontend, and SDKs import the same contract
  • Type safety: Compile-time API validation between client and server
  • Auto-completion: Full IDE support for API endpoints and schemas

Documentation Generation

# Generate OpenAPI docs from TypeScript contract
npm run generate-docs       # Creates docs/api/openapi.{json,yaml}

Benefits:

  • πŸ“Š Contract-first development
  • πŸ”„ Documentation stays in sync with code
  • πŸ“± Enables SDK generation for multiple platforms
  • βœ… Single source of truth for API structure

πŸ› οΈ Technology Stack

  • Frontend: React, TypeScript, Tailwind CSS, Vite
  • Backend Node.js, AWS Lambda, DynamoDB
  • Testing: Vitest, Playwright
  • Build: Nx, esbuild
  • Deployment: AWS SAM, GitHub Actions
  • Local development Localstack / Docker

🎯 Code Quality & Git Hooks

Automatic Quality Enforcement

This project uses automated git hooks to ensure code quality and security:

# Pre-commit (automatic on git commit)
- Phase 1: Format staged files with Prettier + ESLint
- Phase 2: Security audit (production: moderate+, dev: high+ only)
- Phase 3: Run affected tests
- Block commit if any phase fails

# Commit message (automatic on git commit)
- Validate conventional commit format
- Ensure consistent commit history

Git Hook Setup

Git hooks are automatically installed via Husky:

  • βœ… Pre-commit: Formats code + security audit + runs tests
  • βœ… Commit-msg: Validates conventional commit format
  • βœ… Security audit: Blocks commits with vulnerabilities (moderate+ in prod, high+ in dev)
  • βœ… Staged-only formatting: Fast iteration (formats only changed files)

Conventional Commit Format: type: description (feat, fix, docs, chore, etc.)

πŸš€ CI/CD Pipeline

Pipeline Flow

graph TB
    A[Push/PR] --> B["πŸ§ͺ Quality Gates<br/>Unit Tests β€’ Lint β€’ Build β€’ Security"]
    B --> C["🐳 Integration Tests<br/>AWS Services via LocalStack"]
    C --> D["⚑ Local Stack E2E<br/>SAM Local + React Dev + E2E"]
    D --> E{Branch Type?}
    E -->|PR to main| F["πŸš€ Deploy Dev<br/>+ Cloud E2E Tests"]
    E -->|Push to main| G["πŸš€ Deploy Production<br/>+ Cloud E2E Tests"]

    subgraph "Pre-Deployment Test Pyramid"
        direction TB
        T1["1️⃣ Unit Tests<br/>(Fast, Isolated)"]
        T2["2️⃣ Integration Tests<br/>(AWS Services)"]
        T3["3️⃣ Local E2E<br/>(Full Stack)"]
        T1 --> T2 --> T3
    end

    subgraph "Post-Deployment"
        T4["4️⃣ Cloud E2E<br/>(Live Environment)"]
    end

    %% Connect pyramid to main flow
    B -.-> T1
    C -.-> T2
    D -.-> T3
    F -.-> T4
    G -.-> T4

    style A fill:#e1f5fe
    style E fill:#fff3e0
    style F fill:#e8f5e8
    style G fill:#fff8e1
    style T1 fill:#f3e5f5
    style T2 fill:#e8f5e8
    style T3 fill:#fff3e0
    style T4 fill:#fce4ec
Loading

Test Strategy

4-Tier Test Pyramid:

  1. Unit Tests: Fast, isolated tests without external dependencies
  2. Integration Tests: AWS service integration via LocalStack containers
  3. Local Stack E2E: Full-stack tests against local services (pre-deployment validation)
  4. Cloud E2E: End-to-end tests against live AWS environments (post-deployment verification)

Deployment Flow:

  • PR to main β†’ Deploy to dev environment + run cloud E2E tests
  • Merge to main β†’ Deploy to production + run cloud E2E tests
  • Zero manual approvals - Fully automated with proper test gates

This project demonstrates modern TypeScript/Node.js development with AWS serverless architecture, following hexagonal architecture principles and industry best practices.

Releases

No releases published

Packages

 
 
 

Contributors

Languages