Self-hosting
Make targets
Every documented target in the repository Makefile (the ones with a ## description), grouped by the section of the Makefile they live in. Run them from the repository root, for example make test or make docs-check. The page is generated from those lines, so it always matches the Makefile.
Targets that talk to the stack expect the development services to be running (make up); database-backed targets read DT_PG_DB and the other variables on the environment variables page.
Core: stack, generation, fixtures and replays
| Target | What it does |
|---|---|
make up | infra (compose, waits healthy) + placeholder services |
make test-db | WP-65: create + migrate the dtrackier_test databases Go tests use; prints the env exports |
make dev-purge-test-tenants | WP-65: remove throwaway Go-test tenants (+ every PG/ClickHouse/Redis row they own) and orphan ClickHouse tenant rows from the SHARED dev stack; WP-67: then archive test-run leftovers in tenant-basic (demo-clean); dry run unless CONFIRM=1; report in .run/ |
make lint-go | WP-69: the Go half of make lint (dockerfile workspace check, go vet + gofmt per module) |
make replay | feed fixtures/$(FIXTURE) through running services and diff expected |
make gen-openapi | rebuild packages/contracts/openapi.yaml from docs/05 + entity tables |
make gen-check | fails if generation changed tracked files |
make ch-apply | apply ClickHouse schema + MVs to compose clickhouse |
make ch-roundtrip | reset db, apply, reset, apply |
make migrate-roundtrip | up-down-up against compose postgres (no-op until WP-01b adds migrations) |
make fixtures | regenerate fixtures/tenant-basic (deterministic, seed 42) |
make fixtures-check | determinism: regenerate into a temp dir and diff against committed fixtures |
make fixtures-edge | regenerate fixtures/edge-redirect (WP-02 replay: snapshot + 64 links across all styles + independent expectations) |
make replay-edge | WP-02 gate: restart edge-redirect (clean snapshot store), replay fixture, assert click events in NATS |
make fixtures-smartlinks | regenerate fixtures/smartlinks (WP-13 replay: 9 smartlinks + 17 steps with independent expectations) |
make replay-smartlinks | WP-13 gate: replay smartlink routing fixture against a running edge-redirect (events counted in NATS) |
make fixtures-ingest | regenerate fixtures/ingest (WP-03 replay: snapshot + clicks + 34 postback/pixel steps with independent expectations) |
make replay-ingest | WP-03 gate: restart ingest (clean in-memory state), replay fixture, assert conversion events in NATS |
make fixtures-calls | regenerate fixtures/calls (WP-33 replay: DNI pool assignment + call->conversion endpoint with independent expectations) |
make replay-calls | WP-33 gate: build ingest from this checkout, start a private instance (DNI on compose Redis), replay fixtures/calls |
make fixtures-mobile | regenerate fixtures/tenant-mobile (WP-26: apps, clicks, SAN claims + 43 install/session/event steps with hand-written expectations) |
make replay-mobile | WP-26 gate: restart ingest, replay tenant-mobile (resets its own in-memory mobile state + fixed clock), assert install events in NATS |
make fixtures-ch-check | load tenant-basic into a dedicated ClickHouse DB (dtrackier_oracle; never the live dtrackier) and diff v_agg_hourly against expected/ |
Web workspace
| Target | What it does |
|---|---|
make web-e2e | Playwright journeys vs compose stack (make up; needs chromium: pnpm --filter @dtrackier/admin exec playwright install chromium) |
make sdk-build | build dtk.js + enforce < 6 kB gz |
make sdk-e2e | Playwright click->conversion vs mock ingest (needs chromium) |
make ledger-oracle | WP-07 gate: fixture conversions → ledger == expected/ledger_balances.csv; statements, carryover, payout run, invoices (needs make up) |
make reporting-oracle | WP-06 gate: load tenant-basic, then the report engine must reproduce expected/*.csv to the cent (+ restatement, partner parity) |
iGaming
| Target | What it does |
|---|---|
make fixtures-igaming | regenerate fixtures/tenant-igaming (deterministic, seed 31, independent Python oracle) |
make replay-igaming | WP-31 gate: fixture determinism + replay tenant-igaming through the API (needs DT_TEST_PG_DSN / DT_API_DATABASE_URL, see scripts/wp-db.sh) |
Lead distribution
| Target | What it does |
|---|---|
make fixtures-leadgen | regenerate fixtures/tenant-leadgen (WP-32: 3 verticals, 11 buyer campaigns, 41 leads, returns + independent expectations) |
make fixtures-leadgen-check | determinism: regenerate into a temp dir and diff against the committed fixture |
make replay-leadgen | WP-32 gate: replay fixtures/tenant-leadgen through the API handlers (fake buyer endpoints served by the test); needs the wp DB env (scripts/wp-db.sh) |
make replays | run every replay gate, then put edge/ingest back into fully wired (Postgres/Redis/CH) mode |
make live-e2e | drive the running stack like a customer: core leg + WP-54X lifecycle (apply/approve, deep link, smartlink, pixel, 3-portal reports, cap, fraud, automation, mail, statement, payout, dispute, invoice); DT_LIVE_PHASES=core,lifecycle |
make api-audit | WP-54X black-box API audit on the running stack (tenant-basic): permission matrix, error shape, paging, idempotency, live GET stub/5xx probe |
make mcp-e2e | WP-60 MCP server end to end with the official TypeScript MCP client on the running stack (tenant-basic): three audiences, run_report = /v1/reports/query, masking, link through the edge, write round trip; DT_MCP_E2E_API for a private API build |
make ingest-chaos-load | WP-74: the ingest chaos tests (Redis outage mid postback burst, replay answers) N times (default 20) under CPU starvation (2x nproc busy loops; DT_CPU_LOAD_QUOTA= confines burners+tests to one cgroup on a shared box) |
make chaos-accuracy | WP-74 fault-and-load accuracy harness on a PRIVATE stack (scripts/wp74-chaos.sh: own Redis/NATS/CH db, fault proxy): kills, outages, slowness, CPU starvation, clock skew, sustained load; zero lost/duplicated clicks, conversions, status changes, postbacks, webhooks, ledger entries, cap counters; DT_ACC_PROFILE=quick|full, DT_ACC_SCENARIOS=a,b; needs your wp-db.sh env (or .run/wp74-env.sh); docs/17-qa/FINDINGS-74.md |
make reconcile | WP-55R labelled stream through the live stack, expected value asserted at every layer (redirect, dt.* events, ClickHouse raw + aggregates, reports, portals, logs, caps, ledger) + concurrency + redirect matrix; DT_RECON_PHASES/N/SEED, DT_RECON_EDGE/INGEST/API for private builds; docs/17-qa/RECONCILIATION.md |
make oracle | WP-73 differential oracle: seeded scenario (4 tenant zones, every payout model, FX changes, caps, rules, late/restated traffic) through the live edge+ingest, compared in full with every surface; DT_ORACLE_PROFILE=small|large, DT_RECON_SEED; private stack: scripts/wp73-stack.sh oracle; docs/17-qa/ORACLE.md |
iOS SDK
| Target | What it does |
|---|---|
make sdk-ios-test | iOS SDK core + facade tests on Linux (docker, swift 5.10.1); shares sdks/test-vectors |
make sdk-test | all SDK container tests (not part of make test) |
make sdk-ios-e2e | iOS SDK -> real ingest round trip (in-memory mobile store, signed requests); builds ingest, runs swift test in docker on the host network |
Android SDK
| Target | What it does |
|---|---|
make sdk-android-test | Android SDK JVM unit tests (signing vectors, queue, referrer, consent, engine) + AAR, sample and androidTest compile, in docker |
make sdk-android-e2e | Android SDK -> real ingest round trip (private ingest, signed requests, referrer attribution, deferred link) |
make sdk-android-build | publishable artifacts into sdks/android/*/build/repo (Maven layout; signing/Central need credentials, see README) |
Deep links / SKAN / AdAttributionKit
| Target | What it does |
|---|---|
make fixtures-skan | regenerate fixtures/tenant-mobile-skan (deterministic Go generators; seeded test keys, RFC 6979 signatures) |
make fixtures-skan-check | determinism: regenerate and fail if the committed fixture changed |
make replay-skan | WP-27 gate: private in-memory ingest + edge (own ports, shared NATS), replay tenant-mobile-skan (+ edge/), assert dt.mobile.skan_postback.v1 events |
SDK wrappers
| Target | What it does |
|---|---|
make sdk-rn-js | React Native: typecheck + Jest (mocked native module, contract vectors, Expo plugin) + build, in a pinned node image |
make sdk-rn-android | React Native Android bridge: compiles against the real AAR and runs the mapper unit tests (Android image) |
make sdk-rn-ios-mapper | React Native iOS wire-map -> iOS SDK mapper unit tests on Linux (swift image); the RN module itself builds in macOS CI |
make sdk-rn-test | all React Native checks that run without macOS |
make sdk-flutter-test | Flutter plugin: analyze + Dart tests (mocked channel, contract vectors) + pub publish dry-run + example debug APK against the real AAR (Flutter image) |
make sdk-unity-ios-shim | Unity iOS Swift shim (Plugins/iOS) compiled against the iOS SDK and its C entry points tested on Linux (swift image) |
make sdk-unity-dotnet | Unity package: .meta check + NUnit tests of the Unity-free C# 9 logic (pinned dotnet image): wire vectors, Android JNI mapping, ad-revenue adapters, build patchers |
make sdk-unity-test | all Unity checks that run without the Unity Editor |
make test-workers-isolated | run the DB/NATS-bound worker tests that skip while live workers run (stops workers, restarts after) |
Marketing site
| Target | What it does |
|---|---|
make www-build | static export to apps/www/out (OG images + WebP renditions generated at build) |
make www-check | tsc + unit tests + export checks (routes, SEO files, no third-party resources, OG images); part of make lint |
make www-a11y | axe-core on every route, light + dark (needs chromium: pnpm --filter @dtrackier/www exec playwright install chromium) |
make www-lighthouse | Lighthouse 12.6.1 on the home page, mobile preset, all categories >= 95 (needs Chrome: CHROME_PATH) |
make www-screens | recapture product screenshots from a seeded admin dev server (DT_ADMIN_URL, default http://localhost:3190) |
Docs site
| Target | What it does |
|---|---|
make docs-build | build the documentation site to apps/docs/out |
make docs-check | docs-build + check every internal link and anchor in the static export |
Security gate
| Target | What it does |
|---|---|
make security-static | WP-35: gosec, govulncheck, pnpm audit --prod, gitleaks (full history), trivy fs + built service images (pinned tools) |
make security-tests | WP-35: authz matrix, RLS/tenancy, cross-tenant ids, portal masking, secrets at rest, web/CSRF, SSRF guard, prod guard, internal auth, edge redirects |
make security | WP-35 security gate (ZAP baseline is opt-in: make zap) |
make zap | WP-35: ZAP baseline (pinned image) vs the API + 3 portals built from this checkout on private ports (needs DB env; rebuilds portals) |
Load & chaos
| Target | What it does |
|---|---|
make perf | WP-34: benchmarks + budget asserts (redirect/ingest handler histograms, postback dispatcher on a private NATS) |
make load | WP-34: k6 (docker grafana/k6) against PRIVATE edge/ingest/reporting + 10M-click ClickHouse fixture; writes tools/load/results/.{json,md}. DT_LOAD_TOOL=gen uses the pure-Go generator |
make anomaly-check | WP-55Q: inject labelled anomalies (29 days, isolated advertiser/offers/partners in tenant-basic, cleaned up) and assert the admin/partner/advertiser anomaly cards name entity, direction and report link (API built from this checkout on :19682 unless DT_E2E_API is set) |
make fraud-accuracy | WP-55Q: labelled fraud stream through a private trust-proxy edge (+ DT_FA_PRIVATE_INGEST=1: private ingest) on the dev stack; per-signal precision/recall vs the corpus labels (tenant-basic, cleaned up); DT_FA_OUT= |
make perf-fixture | WP-34: deterministic 10M-click fixture in ClickHouse database dtrackier_perf (idempotent; FORCE=1 rebuilds) |
make chaos | WP-34: toxiproxy chaos suite (infra/docker-compose.chaos.yml up -> scenarios -> down -v, even on failure); needs the compose stack; uses its own empty Postgres DB dtrackier_wp34chaos (unit tests seed tenants into dtrackier_wp34, which would collide with the fixture snapshot) |
make ci-stack | fresh stack exactly as CI builds it: compose (healthy) → migrations to HEAD → ClickHouse schema → services (wired) → seed logins |
Rolling demo data
| Target | What it does |
|---|---|
make demo-data | keep tenant-basic populated for the last 90 days (deterministic, idempotent, safe to re-run daily); DT_PG_DB / DT_CH_DB pick the databases |
Showcase workspace + test-data hygiene
| Target | What it does |
|---|---|
make demo-showcase | the owner's showcase workspace acme-network (catalogue, 90 rolling days, logins, portal hosts); idempotent; prints the logins (docs/LOGINS.md) |
make demo-clean | archive test leftovers (E2E…/WP50…/Live…) in tenant-basic; keeps fixtures and rows younger than DEMO_CLEAN_MIN_AGE (30 minutes) |
Reporting completeness
| Target | What it does |
|---|---|
make reporting-oracle-59r | WP-59R gate: fixtures/wp59r-reporting deterministic, then iGaming / calls / mobile / lead-gen / merged queries through /reports/query match the independent Python oracle to the cent (needs DT_TEST_PG_DSN, ClickHouse) |
make reporting-gap | WP-59R: docs/06 fields vs the three live report catalogues -> docs/15-overhaul/REPORTING-GAP.md (DT_REPORTING_URL for a private build) |
make saas-e2e | WP-59S: www signup -> Mailpit verify -> admin onboarding -> partner + advertiser invites -> portals -> operator (TOTP) suspends -> logins refused; needs your wp-db.sh env |
make superadmin-e2e | WP-63: operator (TOTP) -> org + 2 networks -> org admin (TOTP) -> network admins -> partner + advertiser in 3 portals x 2 -> org rollup = sum of network reports -> isolation 403/401 -> suspend -> search -> read-only impersonation; on the running shared dev stack (from main; entities purged) |
make superadmin-e2e-private | WP-63: same journey on a private stack (own NATS/Redis, API + workers + reporting + portal builds on spare ports); needs your wp-db.sh env |
Production deploy profile
| Target | What it does |
|---|---|
make deploy-lint | WP-59O: static checks of deploy/production (compose renders with generated secrets, every prodguard/loopback-default variable set per service, no data-store ports) + promtool on the alert rules |
make deploy-build | WP-59O: production images dtrackier/<svc|portal>:$${TAG:-local} (portals: standalone next build under node-guard; overwrites apps/*/.next) |
make deploy-verify | WP-59O: boot the production profile on its own compose project + spare ports (471xx), check prodguard/wiring/TLS/api->reporting->ClickHouse, run the backup/restore drill, tear down (needs deploy-build) |
make rotate-secrets | WP-70: re-seal every stored secret with the current DT_SECRETS_KEY (old keys in DT_SECRETS_KEY_PREVIOUS; ARGS=-dry-run|-json|-batch N); DB from DT_WORKERS_DATABASE_URL |
Docs + marketing site e2e
| Target | What it does |
|---|---|
make docs-e2e | docs site build-and-crawl: every page and internal link 200, no console errors, no horizontal scroll at 375 px, Aurora styling (Playwright chromium, port DT_DOCS_E2E_PORT=3106) |
make www-e2e | marketing site build-and-crawl (same checks, sitemap parity, Aurora styling; port DT_WWW_E2E_PORT=3181) |
make www-demo-e2e | demo form against the live public lead intake: provisions the form in tenant-basic (scripts/demo-intake.mjs), builds with DT_WWW_LEAD_FORM_URL, submits in a browser and finds the lead (needs the API at DT_API_URL, default :18082) |
make docs-quickstart | run the docs "First offer in 10 minutes" guide step by step against the live stack (tenant-basic) and check every documented answer (DT_API_URL, DT_EDGE_URL, DT_INGEST_URL) |
Transactional email audit
| Target | What it does |
|---|---|
make email-audit | render every transactional email kind (en,de,ar) through the notifier + Mailpit and check branding, locale, links (portal routes), plain text, unsubscribe; tenant-basic; DT_PG_DB / DT_E2E_API pick the database and the API that answers unsubscribe links |