Skip to content

Architecture — Index

This page is the engineering-track summary. Two canonical sources sit alongside it: - ../architecture.md — long-form C4 reference (L1 / L2 / L3, written prose). Read this first if you want to know what the system does. - ../architecture/ — runtime-topology Mermaid diagrams (service map, OTel tracing flow, sequence diagrams). Read this first if you want to know what container talks to what container.

Everything below is a pointer or a callout — no diagrams duplicated here.


Service map

The full Mermaid graph LR is in ../architecture/service-map.md. Solid edges are active; dashed edges are stubbed; red labels mark trace-propagation gaps.

Tier Components
Browser-facing ebit-fe (:3000, dropbet) · ebit-admin-fe (:3001)
Backend (NestJS monorepo) api (:4000, REST + Swagger) · rt (:4001, websocket) · bj (:4002, orphan) · bo (:4003, backoffice) · speed-roulette (internal)
Stateful Postgres (5555→5432, three schemas) · Redis cache (:6379, pwd cache) · Redis bot (:6380, pwd bot) · RabbitMQ (:5672, vhost ft, stubbed)
Observability OTel Collector (:4317/4318) · Jaeger v2 + Badger (:16686) · Prometheus (:9090) · Loki (:3100) · Grafana (:3003)

Per-port contract is in ../architecture.md §2.


Repos and their relationship

/home/ubuntu/ebit/
├── ebit-api/           ← backend monorepo (5 apps + 11 libs)
├── ebit-fe/            ← player site (dropbet)
├── ebit-admin-fe/      ← admin panel SPA
├── tests-e2e/          ← Playwright E2E across all three
├── tests-perf/         ← k6 + Playwright canary load tests
├── terraform/          ← AWS infra (modules + perf rig wiring)
├── observability/      ← OTel Collector / Loki / Prometheus configs + Grafana provisioning
└── docker-compose.yml  ← root compose glues all of the above for local dev

For per-repo framework + version detail, see the canonical stack inventory at stack.md §2. Each repo has its own .git, package.json, Dockerfile, and CI config. They ship independently. The root docker-compose.yml is the only file that knows about all three.

Inside ebit-api

Layer Path Imports as
Apps apps/{api,rt,bj,bo,speed-roulette}/ @api/*, @rt/*, @bj/*, @bo/*, @speed-roulette/*
Shared libs libs/{shared,auth,games,accounting,integrations,gateway,ws-throttler,modules,is-localhost,_prisma}/ @app/shared, @app/auth, @app/games, @app/accounting, @app/integrations, @app/gateway, @app/ws-throttler, @app/modules, @app/is-localhost, @app/_prisma

Aliases declared in ebit-api/tsconfig.json. Apps build/run separately (npm run start:dev, start:dev:rt, start:dev:bj, start:dev:bo, start:dev:speed-roulette).

Frontend ↔ backend

  • dropbet (ebit-fe) — calls ebit-api via fetch (with traceparent injected by @vercel/otel) and connects to ebit-rt via socket.io-client (websocket-only). Public auth endpoints, bet placement, leaderboard, wallet — all on api.
  • admin (ebit-admin-fe) — calls ebit-api directly (no separate admin backend). All admin endpoints live in api under /admin/* guarded by JwtGuard + PermissionGuard + (for SuperAdmin paths) RolesGuard + OtpGuard.

The ebit-bo app provides a separate Swagger surface on :4003 for backoffice operations; it is reachable from internal tooling but not from ebit-admin-fe today.


Cross-cutting concerns

Auth

JWT in cookies, bcrypt for passwords, 2FA via a temp JWT signed with JWT_MFA_TEMP_SECRET, sessions persisted in cache Redis. See ../flows/dropbet-sign-in.md, ../flows/admin-sign-in.md, and ../api-reference/auth-flow.md.

Observability

Every service runs the OTel SDK from libs/shared/src/basic/pre/pre-otel.main.ts. Traces, metrics, and logs all funnel through the OTel Collector. Spanmetrics derives RED metrics from spans without needing per-instrumentation Prometheus exporters. See observability.md and ../architecture/tracing-flow.md.

Async work

BullMQ on cache Redis for everything in production; RabbitMQ exists in compose for the Fast Track module but the producer is stubbed (disabled = true). See ADR-0003. Recipes for adding queues live in ../recipes/add-bullmq-queue.md.

Configuration

Every backend service validates env at boot via libs/shared/src/env-config/env.dto.ts. Local dev uses .env files; staging/prod use Doppler-injected envs. See env.md.


Known structural debt

These are documented in detail in ../weaknesses-register.md (architectural blind spots AF-, security findings SF-, flow failure modes FM-, workspace gaps WK-) and in the per-flow §6 sections. Listed here so you know what to expect when reading code.

# Issue Impact Pointer
1 OTel traceparent does not propagate across @ExternalControllerClient (Redis pub/sub microservice transport) Three-hop speed-roulette flow surfaces as three uncorrelated traces in Jaeger. The auto-instrumentation does not inject traceparent into the pub/sub envelope. ADR-0005 · ../audits/perf-trace-coverage-audit.md
2 ebit-bj is architecturally orphaned The blackjack server on port 4002 has its own session-token scheme and EVO-Games external-wallet RPC, but no in-repo FE calls it. dropbet hits apps/api/src/casino/house/blackjack/ instead. Disposition (delete vs wire up) is open. ../flows/dropbet-blackjack.md §6.4
3 Fast Track RabbitMQ producer stubbed apps/api/src/fast-track/rabbitmq/fast-track.rmq.module.ts:8 returns disabled = true. Broker runs but receives zero traffic. ADR-0003
4 Three stacked bugs in ebit-admin-fe block cross-service traces and silently break the dashboard (a) Cookie name mismatch — middleware reads jwt_access_token, API sets access_token; (b) middleware silently falls through on bad JWT (commented redirect); (c) instrumentation.ts doesn't fall back to @vercel/otel. Memory project_admin_fe_auth_bugs.md; will surface in ../handover/ once written
5 EvoLogger (winston) records reach Loki only via filelog/docker scrape, not OTLP — distinguishable by source=docker_filelog. Trace-correlation fields present but service.name resource attribute missing on this path. ADR-0007
6 WS / socket.io is not OTel-instrumented — neither inbound connect nor each socket message creates a span. RT-only flows are blind. ../audits/perf-trace-coverage-audit.md "Coverage matrix"
7 BullMQ job processing creates orphan traces — bet-settled consumer starts a new root span because traceparent is not in the job data. ../audits/perf-trace-coverage-audit.md

Items 1, 6, 7 are tracked in the trace-coverage audit; items 2, 4 are tracked as integration debt and not currently scheduled.


Sequence diagrams

The two flagship request flows have full Mermaid sequence diagrams plus span-by-span walkthroughs:

For the other 13 flows, see flows.md.


See also