Tooling — Daily Drivers¶
Per-tool reference: what it is, where its config lives, daily commands. Targeted at developers who need to know the right invocation, not first-time users (for that read
../onboarding/day-one.md).
The list below is in roughly the order you encounter them on a typical workday.
Doppler — secrets management¶
What: Cloud-hosted secrets manager. Replaces .env files in staging / prod / perf. Local dev still uses .env for speed.
Workspace: ebit-devops (slug 4d59619bf8c6f858715b). Three projects: ebit-api, ebit-fe, ebit-admin-fe. See env.md §Doppler.
Config / state:
- Personal admin token: ~/.config/doppler/token (chmod 600), loaded by ~/.bashrc.
- Service tokens (container runtime): terraform/perf/secrets/doppler-token-* (gitignored).
- run_local.sh in each repo expects DOPPLER_TOKEN exported.
Daily commands:
doppler secrets --project ebit-api --config dev_perf
doppler secrets set KEY="value" --project ebit-api --config dev_perf
doppler run --token <service-token> -- node main.js # container-style
More: reference_doppler_workspace memory; ../audits/doppler-perf-audit.md.
Terraform — infra-as-code¶
What: Provisions AWS infra for the perf rig (eu-north-1). Modules at terraform/modules/ (monitoring + app); rig-level wiring at terraform/perf/.
Config / state:
- terraform/perf/main.tf, variables.tf, outputs.tf, versions.tf, providers.tf.
- terraform/perf/terraform.tfvars — populate from .tfvars.example before apply.
- State stored locally at terraform/perf/terraform.tfstate (note: not S3-backed today; a single-engineer setup).
- terraform/perf/loadgen-user-data.sh — cloud-init for the loadgen VM.
Daily commands:
cd terraform/perf
terraform init
terraform plan # expect ~58 adds before first apply
terraform apply -auto-approve
terraform output -json > /tmp/perf-outputs.json # save URLs / IPs
terraform destroy # after the perf retention window
Docker Compose — local stack¶
What: Glues the three repos + observability stack for local dev. Single root docker-compose.yml.
Config / state:
- /home/ubuntu/ebit/docker-compose.yml — services, ports, env, volumes.
- Per-repo Dockerfiles inside ebit-api/, ebit-fe/, ebit-admin-fe/.
- ebit-api/docker-compose.local.yml — backend-only infra (Postgres + 2 Redis + RabbitMQ). Used when you only need the data tier locally and run NestJS apps on the host.
Daily commands:
docker compose up -d # full stack from /home/ubuntu/ebit/
docker compose logs -f ebit-api # tail one service
cd ebit-api && npm run dockers:infra # backend infra only (Postgres / Redis / RMQ)
Ports: see stack.md §"Five NestJS apps" + architecture.md.
Prisma — DB schema + migrations¶
What: Type-safe Postgres client. Schema is split across three files (api.prisma, blackjack.prisma, speed_roulette.prisma) — see data-model.md.
Config / state:
- ebit-api/libs/_prisma/src/schema/*.prisma — schemas.
- ebit-api/package.json "prisma.schema" field — points at the schema folder.
- ebit-api/libs/_prisma/src/seed/index.ts — seed entrypoint.
Daily commands (from ebit-api/):
npm run db:migrate:dev # generate + apply migration vs .env DB
npm run db:seed # run seed/index.ts
npm run db:reset # drop, re-migrate, re-seed
npm run prisma:test:reset # same vs .env.test DB
Always use the npm scripts — they wrap prisma with env-cmd -f .env. Calling npx prisma directly skips the env file.
k6 — load generation¶
What: Synthetic HTTP + WS load. Native Prometheus remote-write integration.
Config / state:
- tests-perf/k6/scenarios/*.js — per-scenario scripts.
- tests-perf/k6/lib/*.js — shared helpers.
- tests-perf/k6/smoke.js — 50-VU pre-flight.
- tests-perf/profiles/ — ramp profile definitions.
Daily commands (from tests-perf/):
k6 run k6/smoke.js # 50 VU pre-flight
k6 run -e BASE_URL=http://sut:4000 k6/scenarios/signin-storm.js
k6 run --out experimental-prometheus-rw=... k6/scenarios/bet-place-storm.js
More: performance.md, ../performance-testing.md, ../../tests-perf/README.md.
Playwright — E2E + canary¶
What: Browser-driven E2E (tests-e2e/) and real-browser canary during perf runs (tests-perf/playwright-canary/).
Config / state:
- tests-e2e/playwright.config.ts, tests-perf/playwright-canary/playwright.config.ts.
- Per-spec *.spec.ts files. Auth helpers + Jaeger trace assertions live in shared utils.
Daily commands:
cd tests-e2e && pnpm playwright test # full E2E suite
cd tests-e2e && pnpm playwright test tests/dropbet-signin.spec.ts # one test
cd tests-perf/playwright-canary && pnpm exec playwright install chromium # first-time
cd tests-perf/playwright-canary && DURATION=600 LOAD_STAGE=ramp10k pnpm canary
Vitest — unit + integration tests (ebit-api)¶
What: Test runner for ebit-api. Matches *.test.ts and *.spec.ts.
Config / state:
- ebit-api/vitest.config.ts (or per-app override).
- Test DB env in ebit-api/.env.test; npm run prisma:test:reset seeds it.
Daily commands (from ebit-api/):
npm test # all
npm test -- path/to/file.test.ts # single file
npm test -- -t "pattern" # single test by name
ESLint + Prettier¶
What: Linting + formatting. All three repos use Husky + lint-staged so commits auto-run.
Daily commands:
# ebit-api
cd ebit-api && npm run lint # eslint --fix on {src,apps,libs,test}/**/*.ts
# ebit-fe / ebit-admin-fe
cd ebit-fe && pnpm lint # next lint --max-warnings=0 + tsc --noEmit (both must pass)
cd ebit-fe && pnpm tsc # type-check only
cd ebit-fe && pnpm prettier-fix # ebit-fe only
pnpm lint exits non-zero on any warning — treat warnings as build breakers.
Sentry — error monitoring¶
What: Production error aggregation for all three apps + browser-side ebit-fe.
Config / state:
- sentry.*.config.ts in each repo (server, client, edge configs for Next.js).
- @sentry/nestjs in ebit-api; @sentry/nextjs in the FEs.
- DSN per app: SENTRY_DSN_* env vars (5 in ebit-api).
- Source maps uploaded at build time via SENTRY_AUTH_TOKEN + SENTRY_ORG + SENTRY_PROJECT_*.
Daily commands: errors land in the Sentry dashboard; nothing to run. To verify locally, NODE_ENV=production is required (Sentry is disabled in local).
Grafana — observability UI¶
What: Unified UI for traces (Jaeger datasource), metrics (Prometheus), logs (Loki).
Access: http://localhost:3003 (admin / grafana).
Config / state:
- Datasources: observability/grafana/provisioning/datasources/datasources.yml.
- Dashboards: observability/grafana/provisioning/dashboards/*.json (9 dashboards, see observability.md).
Daily use: Explore tab for ad-hoc queries; dashboards for routine reads. Trace pivot from a Loki log line via provisioned derivedFields.
Recipe: ../recipes/add-grafana-dashboard.md.
Jaeger UI — trace viewer¶
What: Trace search + waterfall view. Authoritative for every flow-doc trace ID.
Access: http://localhost:16686.
Daily use:
- Search by service + operation: pick ebit-api → POST /casino/games/house/dice/bet → click a trace.
- Search by trace ID: paste from a log line or browser devtools.
- Compare traces side-by-side from the search results page.
Storage: Jaeger v2 + Badger on local EBS (50 GB gp3, ttl.spans: 72h). See ../audits/jaeger-storage-research.md.
Loki — log queries¶
What: LogQL log store. Two ingestion paths (OTLP-bridged pino, filelog/docker for EvoLogger).
Access: http://localhost:3100 (HTTP API); usually queried through Grafana.
Daily use:
# trace-correlated logs across all services
{service_name="ebit-api"} |= "<trace_id>"
# EvoLogger / winston records (filelog path)
{source="docker_filelog"} |= "EvoLogger"
# error-level only
{service_name="ebit-api"} | json | level="error"
Prometheus — metric queries¶
What: Metrics TSDB. Includes spanmetrics-derived RED metrics from the OTel Collector.
Access: http://localhost:9090.
Daily PromQL:
# Span-derived rate
rate(traces_spanmetrics_calls_total{span_name=~"prisma:.*"}[5m])
# Span-derived p95
histogram_quantile(0.95,
sum by (le, span_name) (rate(traces_spanmetrics_duration_milliseconds_bucket{span_name=~"prisma:.*"}[5m])))
# k6 load
rate(k6_http_reqs_total{scenario=~"$scenario"}[1m])
k6_vus{scenario=~"$scenario"}
# BullMQ queue depth
bullmq_queue_jobs{state="wait"}
Husky + lint-staged¶
What: Pre-commit hook runner. Auto-runs ESLint + Prettier on staged files.
Config / state: .husky/ in each repo; lint-staged config in each package.json.
Daily use: invisible. Commits auto-format and lint; failing commits surface a non-zero exit.
See also¶
stack.md— versions and rationale for each of these tools.env.md— Doppler / env-var details.observability.md— Grafana / Jaeger / Loki / Prometheus deep dive.performance.md— k6 / Playwright daily commands within the perf workflow.../recipes/— copy-paste recipes for adding endpoints, models, queues, spans, dashboards, tests.