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) — callsebit-apivia fetch (with traceparent injected by@vercel/otel) and connects toebit-rtvia socket.io-client (websocket-only). Public auth endpoints, bet placement, leaderboard, wallet — all onapi. - admin (
ebit-admin-fe) — callsebit-apidirectly (no separate admin backend). All admin endpoints live inapiunder/admin/*guarded byJwtGuard+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:
- Sign-in —
../architecture/request-flow-signin.md - Place bet —
../architecture/request-flow-bet-place.md(the runnable counterpart is../e2e-trace-demo.md)
For the other 13 flows, see flows.md.
See also¶
stack.md— versions and rationale../onboarding/anatomy-of-a-bet.md— narrative tour of a single bet's spans across services../glossary.md— every domain term with file:line citation../../CLAUDE.md— workspace orientation (ports, package managers, common commands)