Architecture Case Study Built

Platform Unity via Middleware Connectors

How we bridge KashaCH (Heidi) and Kasha Platform into a single ecosystem — starting with KYC as proof of concept, establishing a repeatable pattern for every shared domain.

Two Platforms, One Vision

Kasha operates two distinct codebases: KashaCH (Heidi) — a full-stack Vite+Express monolith serving the Swiss CSP market — and the Kasha Platform — a 33-repo NestJS microservices architecture for the global SMB/Enterprise play. Both serve overlapping customers. Both need KYC, payments, CRM, and compliance. Building each twice is not an option.

The Challenge

  • Two separate tech stacks (Vite/Express vs NestJS microservices)
  • Different databases (Drizzle/PostgreSQL vs TypeORM/PostgreSQL)
  • Duplicated business logic across platforms
  • No shared identity for KYC, compliance, or onboarding
  • Enterprise customers span both platforms

The Pattern

  • Middleware Connector: standalone REST gateway per domain
  • Shared library extracts provider-agnostic business logic
  • TypeORM adapters bridge to shared PostgreSQL
  • Both platforms consume the same REST API
  • One truth, two consumers, zero duplication

The Middleware Connector Pattern

A Middleware Connector is a thin, standalone NestJS REST API that owns a single business domain. It sits between both platforms, providing a unified interface while the shared library encapsulates all provider logic, data models, and orchestration.

              PLATFORM UNITY — MIDDLEWARE CONNECTOR PATTERN
    ────────────────────────────────────────────────────────────────

    KashaCH (Heidi)                           Kasha Platform
    Swiss CSP Monolith                         Global Microservices
    Vite + Express + Drizzle                   NestJS + TypeORM + RabbitMQ

         company-formation.letscodenow.app         app.kasha.io
                     |                                    |
                     |        HTTP REST                  |
                     +──────────────┐  ┌──────────────────+
                                    |  |
                                    v  v
                     ┌──────────────────────────────┐
                     │    MIDDLEWARE CONNECTOR        │
                     │    Standalone REST Gateway      │
                     │                                │
                     │  NestJS  ·  Port 3001  ·  Docker │
                     │  Health checks  ·  CI/CD        │
                     └───────────────┬──────────────┘
                                    |
                           uses (npm link)
                                    |
                     ┌───────────────┴──────────────┐
                     │       SHARED LIBRARY           │
                     │  @kasha/kyc-service (GitHub)    │
                     │                                │
                     │  Orchestrator · Providers      │
                     │  Store Interfaces · DTOs        │
                     │  Events · Config · Enums        │
                     └───────────────┬──────────────┘
                                    |
                         adapters (TypeORM)
                                    |
                     ┌───────────────┴──────────────┐
                     │     SHARED POSTGRESQL          │
                     │  Database: kyc_connector       │
                     │  10 tables · UUID PKs · JSONB  │
                     │  Snake_case · Cascade deletes  │
                     └──────────────────────────────┘
                                    |
                         external API
                                    |
                     ┌───────────────┴──────────────┐
                     │    EXTERNAL PROVIDER          │
                     │  SumSub (prod) / Mock (dev)    │
                     │  Auto-detected from env vars   │
                     └──────────────────────────────┘
3
Repos
11
REST Endpoints
10
DB Entities
0
Duplicated Logic

Three Repos, Clear Boundaries

Each repo has a single responsibility. The shared library is the brain, the connector is the body, and the platform service is the existing consumer that gets upgraded.

Shared Library
kasha-kyc-service
Provider-agnostic business logic. Defines Orchestrator, Store interfaces, DTOs, Providers (SumSub + Mock), event system, and config schema. No database opinions — just contracts.
Middleware Connector
kasha-middleware-kyc-connector
Standalone NestJS REST gateway. Implements TypeORM adapters for the Store interfaces, wires up the Orchestrator, exposes 11 HTTP endpoints. Docker-deployed, CI/CD via GitHub Actions.
Platform Service
lr-kyc-service
Kasha Platform's existing KYC microservice. Will consume the shared library directly, or call the connector's REST API — same data, same rules, unified outcome.

Layered Design

The connector follows a clean layered architecture with dependency injection throughout. Each layer has a single concern and can be swapped independently.

▶
REST Controller
KycRestController — 11 endpoints, validation pipes, raw body for webhooks
↓
◉
Orchestrator
KycOrchestrator from @kasha/kyc-service — coordinates providers, stores, events
↓
▢
Store Adapters
TypeOrmApplicantStore + TypeOrmDocumentStore — implements abstract interfaces
↓
◆
Provider
SumsubProvider (production) or MockKycProvider (dev) — auto-detected from env vars
↓
■
PostgreSQL
Shared database on Docker network — 10 entities, snake_case, JSONB, cascade deletes

REST Endpoints

All endpoints are under /api/kyc. Both platforms consume the same API — KashaCH via direct HTTP calls, Kasha Platform via the internal Docker network.

Method Endpoint Purpose
POST /applicants Create verification — register applicant with provider
GET /applicants/:id Get applicant record by provider ID
POST /applicants/:id/link Generate verification link (with TTL)
POST /applicants/:id/token Get Web SDK access token for frontend embed
POST /applicants/:id/check Request verification check from provider
POST /applicants/:id/sync Sync status from provider to local database
GET /applicants/:id/documents List uploaded documents for applicant
GET /business/:businessId Get all applicants for a business entity
POST /webhook Receive provider webhooks (HMAC validated)
GET /admin/applicants List applicants (paginated, filterable)
GET /healthz/ready Database connectivity health check

Zero-Config Provider Switching

The connector auto-detects whether real SumSub credentials are present. If the token is missing or set to dev-placeholder, it seamlessly falls back to a mock provider — no code changes, no feature flags, no conditional logic in business code.

// kyc-orchestrator.provider.ts — automatic provider selection
function isRealSumsubToken(token: string | undefined): boolean {
  if (!token || token.trim() === '') return false;
  if (token === 'dev-placeholder') return false;
  return true;
}

// Result: SumsubProvider in production, MockKycProvider in dev
// MockKycProvider auto-approves, simulates latency, returns test data
const provider = useSumsub
  ? new SumsubProvider({ apiUrl, apiToken, apiSecret, webhookSecret })
  : new MockKycProvider({ latencyMs: 100, autoApproveOnCheck: true });

10-Entity Schema

The connector manages its own database (kyc_connector) on the shared PostgreSQL instance. Entities cover the full KYC lifecycle — from initial applicant creation through document uploads, risk scoring, review, and proof of address verification.

Applicant (main record — business_id indexed)
   |
   +── 1:1 ── ApplicantPersonalInfo    name, dob, nationality, id docs (JSONB)
   +── 1:1 ── ApplicantCompanyInfo     company name, reg number, beneficiaries (JSONB)
   +── 1:1 ── ApplicantReview          review status, level, priority
   |             +── 1:1 ── ApplicantReviewResult  GREEN/YELLOW/RED, reject labels
   +── 1:1 ── ApplicantRiskLabel       risk signals: email, phone, device, AML
   +── 1:1 ── ApplicantPoaResult       proof of address review outcome
   +── 1:N ── ApplicantDocument[]      28+ doc types, metadata, GPS coords (CASCADE)
   +── 1:N ── ApplicantNote[]          internal notes, created_by (CASCADE)
   +── 1:N ── ApplicantRiskMatrix[]    4 types x 13 factors, scored + blocked (CASCADE)

Docker + GitHub Actions CI/CD

The connector deploys as a standalone Docker container via GitHub Actions. Push to main triggers SSH deploy to VPS — pull, build, start, health check, clean up. Zero-downtime with automatic rollback on failure.

# docker-compose.yml — joins shared VPS network
services:
  kyc-connector:
    build: .
    ports: "127.0.0.1:3002:3001"
    networks: kasha-network (external)
    healthcheck: /healthz/ready every 15s

# deploy-dev.yml — GitHub Actions
on: push to main
steps: clone → pull → build → up -d → health check → prune

Repeatable for Every Shared Domain

KYC is the first connector. The same pattern applies to every domain that both platforms need. Each connector follows the same structure: shared library + middleware gateway + platform consumer.

■

KYC Connector

Identity verification, document uploads, risk scoring, SumSub integration. Proof of concept for the pattern.

Built
■

Payments Connector

Unified payment processing — Stripe, TWINT, PIX. Shared transaction ledger, settlement rules, refund flows.

Next Up
■

CRM Connector

Shared customer records, contact sync, interaction history. One customer view across both platforms.

Planned
■

Compliance Connector

AML screening, sanctions checks, regulatory reporting. Shared compliance engine across jurisdictions.

Planned
■

Notifications Connector

Unified email, SMS, push. Template engine, delivery tracking, preference management.

Planned
■

Billing Connector

Subscription management, invoice generation, usage metering. Shared billing across all products.

Planned

The Formula

For any shared domain: (1) Extract business logic into a provider-agnostic shared library on GitHub. (2) Build a thin NestJS middleware connector that implements store adapters and exposes REST endpoints. (3) Both platforms consume the connector's API — same data, same rules, zero duplication. (4) Deploy as a standalone Docker container on the shared network with CI/CD. Each connector is independently deployable, testable, and scalable.

Platform Unity Timeline

KYC Middleware Connector
3-repo architecture established. 11 REST endpoints, 10 DB entities, SumSub + Mock providers, Docker + CI/CD. Pattern proven.
Shared KYC Library (@kasha/kyc-service)
Provider-agnostic orchestrator, store interfaces, DTOs, event system. Consumed by connector via GitHub npm dependency.
Payments Middleware Connector
Apply same pattern: @kasha/payment-service library + kasha-middleware-payment-connector gateway. Stripe, TWINT, PIX unified.
Full Platform Convergence
All shared domains connected. Both platforms operate on unified data. Enterprise customers get seamless cross-platform experience.