# EDR Freight — API integration stack (headless, sharded). # # Overlay on docker-compose.e2e.yaml, plus a GENERATED third file holding the # per-shard services (integration/.it-shards.yaml, written by gen-shards.mjs). # # The freight API is NOT a container here — it boots inside each vitest worker, # on the host, so a code change needs no image rebuild and a breakpoint works. # Each worker is a full shard of the topology; nothing mutable is shared: # # shard i: # freight app (in vitest worker, host :3111+i) # │ ▲ # │ └──── HTTP ─── payment-api-it-{i} :3131+i (inbound CBE bill query, # │ │ via host.docker.internal) # └── HTTP ──────────────► │ ──HTTP──> gateway-mock-it-{i} :4600+i # ▲ │ # └──── RabbitMQ vhost payment_s{i} ──┘ (outbox → payment.events → consumer) # # Shared by every shard: postgres (one container, one database per shard cloned # from a seeded template), rabbitmq (one container, one vhost per shard), minio, # and the one-shot migration. # # Its own compose project (`name:` below overrides the base) and its own host # ports, so it can run side by side with the Cypress e2e stack. # # node integration/scripts/it.mjs up|test|down|logs # # Never start it with plain `docker compose -f docker-compose.it.yaml` — it is # an OVERLAY and needs the base file first: # docker compose -f docker-compose.e2e.yaml -f docker-compose.it.yaml \ # -f integration/.it-shards.yaml ... name: edr-freight-it services: # Outbox transport. The payment API publishes payment.succeeded/failed here # and freight consumes it — the production path. Copied from the passenger # harness (e2e/docker-compose.yml). One broker, one vhost per shard # (payment_s0, payment_s1, …) created by it.mjs — a shared vhost would let one # shard's freight consumer eat another shard's settlement event. rabbitmq-it: image: rabbitmq:3-management environment: RABBITMQ_DEFAULT_USER: edr RABBITMQ_DEFAULT_PASS: edr_secret RABBITMQ_DEFAULT_VHOST: payment ports: - "${IT_RABBIT_PORT:-5772}:5672" - "${IT_RABBIT_UI_PORT:-15772}:15672" healthcheck: # check_running, NOT ping: ping only proves the Erlang node answers, and # it.mjs runs `rabbitmqctl add_vhost` the moment this goes healthy — which # on a cold boot failed with "this command requires the 'rabbit' app to be # running on the target node". check_running waits for the application. test: ["CMD", "rabbitmq-diagnostics", "-q", "check_running"] interval: 5s timeout: 10s retries: 20 # The per-shard `gateway-mock-it-{i}` and `payment-api-it-{i}` services live in # integration/.it-shards.yaml. The base file's `freight-api-e2e` is never # started — the app runs in-process (integration/src/app.ts).