Skip to content

Architecture

The platform is a submodule-based monorepo. Each submodule is an independent repo with its own build system, CI, and history. The parent repo owns the deploy manifests (deploy/argocd/), the cluster-wide services that live in-tree (services/), and the GitHub Actions workflows that build every service image.

Repository layout

backend/                    # Python APIs — Flask today, FastAPI during Phase 2.
  cashless-backend/         # Admin API + background jobs (Flask 2.0, gunicorn/eventlet)
  personalaccount-api/      # Personal account (Flask 2.3, gunicorn)

core/                       # Shared libraries
  cashless-core/            # Shared Python utils (crypto, payments, notifications)
  cashless-core-ui/         # Shared Angular library (@cashless-media/core)
  models/                   # SQLAlchemy 2.0 models (cashless-models v2)

frontend/                   # Web frontends — all Angular 21
  cashless-admin-ui/
  cashless-refund-ui/
  marketplace-user-ui/
  personalaccount-ui/

apps/                       # Mobile applications
  mPOS/                     # Android/Kotlin — POS terminal
  user_app_android/         # Android/Java — legacy cardholder (sunset)
  user_app_android_with_sdk/# Android/Kotlin + Compose — active cardholder
  user_app_ios/             # iOS/Swift — cardholder
  dispatch_app/             # Android/Java — dispatch workflows
  fastpass_app/             # Android/Java — fastpass scanning
  format_app/               # Android/Java — formatting tooling
  report_app/               # Android/Java — operator reporting

sdk/
  cashless-core-rs/         # Rust + UniFFI → Kotlin + Swift bindings

services/                   # Services that live inside the parent repo
  cashless-auth/            # FastAPI — identity / sessions
  cashless-cron/            # Scheduled jobs
  cashless-redis/           # In-cluster Redis
  cashless-db-backup/       # MySQL backup CronJob
  cashless-secrets/         # External-Secrets operator config
  cashless-ingress/         # Cluster-wide GCE Ingress + ManagedCertificate
  cashless-docs/            # This site
  otel-collector/           # OTLP receiver
  cluster-bootstrap/        # First-time cluster bootstrap

deploy/
  argocd/                   # ArgoCD AppProject + Application CRs

Service boundaries

  • cashless-core and models are shared Python packages consumed by backend services. Treat them as libraries — never reach into their internals from a service.
  • cashless-core-ui is the shared Angular library consumed by all four web frontends. New shared components belong here, not in any one frontend.
  • cashless-core-rs is the only mobile SDK. The legacy KMP cashless-sdk was retired on 2026-05-08 (Wave 6 strangler-fig complete). Use UniFFI bindings — Kotlin for Android, Swift for iOS.
  • cashless-backend and personalaccount-api are deployed independently via Helm + ArgoCD. They do not share a runtime; cross-service calls go over HTTP, authenticated via cashless-auth.

Data layer

  • MySQL 8.0 on Cloud SQL. Schema lives in core/models/. Migrations run as a one-shot cashless-migrate Job on every backend rollout.
  • Redis is in-cluster (cashless-redis) for cache + RQ queues. The auth-claims cache (Wave 6, G4) keys by sha256(token) with a 60s TTL.
  • No Postgres / Drizzle despite the global stack defaults — those are aspirational for new greenfield services.

Payments

The active processor set is:

Processor Notes
Stripe Primary card processor + Stripe Terminal (mPOS).
Mercado Pago Latin-America card + wallet.
Adyen Enterprise card + APMs.
Direct PayPal PayPal balance + PayPal Credit (no BrainTree wrapper).

BrainTree was dropped during the v2 modernization. It survives only on the legacy master / develop branches for reference.

Deploy flow

flowchart TD
    A([Push to cashless-v2]) --> B[GitHub Actions CI]
    B -->|docker build| C[GHCR image<br/>sha-&lt;12 hex&gt;]
    C --> D[Argo CD Image Updater]
    D -->|write-back image.tag| E[deploy/argocd/values/*.yaml]
    E --> F[ArgoCD reconcile]
    F --> G([GKE rollout])
  1. Push to cashless-v2 on the parent repo or any submodule.
  2. GitHub Actions runs per-service CI (.github/workflows/ci-*.yml) and builds a Docker image tagged sha-<12 hex> pushed to GHCR.
  3. Argo CD Image Updater detects the new tag and writes it to deploy/argocd/values/<service>.yaml, committing back to cashless-v2.
  4. ArgoCD reconciles the Application and rolls out the new image into the cashless namespace on GKE.
  5. Cluster ingress (services/cashless-ingress) fronts every host on a single static IP with a Google ManagedCertificate.

For end-to-end deploy debugging see OPERATIONS.md.

CI matrix

All Python-service CI lives in the parent monorepo at .github/workflows/:

Workflow Purpose
python-ci.yml Reusable: uv install, ruff, mypy (soft-fail), pytest.
docker-build.yml Reusable: buildx → GHCR with provenance + SBOM.
helm-lint.yml Reusable: helm lint + helm template.
ci-cashless-*.yml Per-service: chains lint → helm-lint → docker-build.
ci-marketplace-* etc. Frontend CI: lint + type-check + Jest + Playwright.

Observability

OpenTelemetry end-to-end:

  • Browser SDK in every frontend ships traces + RUM to the collector.
  • Backend services export OTLP traces + metrics.
  • otel-collector receives OTLP and fans out to Prometheus + Cloud Trace.
  • kube-prometheus-stack scrapes everything else.

Grafana dashboards live in services/cluster-bootstrap/grafana/ and are provisioned at bootstrap time.