Skip to content

The whole system on one page

2 min read · main part only; folded sections are optional

After this you can answer: What are the main parts of MiniTickets, and which of them run in AWS?

flowchart TB
B[Browser] --> ALB[ALB]
ALB -->|"pages"| W["Web app<br/>Next.js on ECS"]
ALB -->|"/trpc/*"| A["API<br/>Fastify on ECS"]
W -->|"http://api:4000"| A
A --> PG[(RDS Postgres)]
A --> V[(ElastiCache Valkey)]
A -->|"events"| S["SNS → SQS"]
S --> L["Lambda: email, tickets"]

Learn this picture first. Every later chapter zooms into one box or one arrow.

  1. The browser loads pages and calls the API on the same address. It never talks to a database.
  2. The ALB (Application Load Balancer) is the one way in. It sends /trpc/* to the API and everything else to the web app.
  3. The web app renders pages. To render /events on the server, it calls the API on a private name, http://api:4000, that never leaves AWS.
  4. The API holds all the business logic and is the only code that reads or writes Postgres and Valkey.
  5. Background work starts from an SNS topic: queues feed one Lambda that sends emails and one that makes QR tickets, stored in DynamoDB and S3.
PartWhere it runsCode
Web app (Next.js)ECS Fargate, port 3000apps/web
API (Fastify + tRPC)ECS Fargate, port 4000apps/api
Worker and tickets functionsLambda, one arm64 imageapps/worker
InfrastructurePulumi, TypeScriptinfra
DNSCloudflare, outside AWSrecords printed by Pulumi
CI and CDGitHub Actions, outside AWS.github/workflows

Four switches in the committed infra/Pulumi.dev.yaml decide what exists: dataEnabled, computeEnabled and entryEnabled are on; cdnEnabled is off, so CloudFront is built in code but not running. The map grows the system in 25 stages, from the account (stage 0) to the alarms (stage 24).

Open the full map →

Resource Groups → Tag Editor, region us-east-1: every resource of the stack has a name that starts with minitickets-dev.

SymptomCauseWhere to look
Pages load, every /trpc/* call failsThe API has no healthy taskECS → minitickets-dev-api → Events
/events shows an error, the rest worksThe web server cannot reach http://api:4000The /minitickets/dev/web log group
The domain does not open at allDNS points at an old ALBCloudflare record vs the ALB’s DNS name
Why does the web app call the API instead of the database?

One rule, one place: every check (who may book, how many seats) lives in the API. If the web app read Postgres too, those rules would have to exist twice and could drift apart.

What is the single point of failure here?

Several: one api task, one web task, one Valkey node and a single-AZ database. That is a cost choice for a dev environment. Production would run at least two tasks and a Multi-AZ database.

Why are DNS and CI outside AWS?

The domain was already at Cloudflare, and the code is on GitHub. AWS trusts GitHub through OIDC, so no AWS key is stored there. The cost is that a person adds the DNS records by hand.

Advanced: Where the pieces are created

infra/index.ts calls the layers in build order: network, security groups, budget and certificate, data (Postgres, Valkey, secrets), registry, release and CI/CD roles, the always-on queues and ticket storage, then compute (cluster, IAM roles, entry, api), the two Lambda functions, the web service and finally observability. Each layer file starts with a header that lists what it NEEDS, what it CREATES and what it GIVES to later layers. The web app’s own server-side client is apps/web/src/lib/trpc/server.ts → makeServerTrpcClient.

Answer these without scrolling up. If one feels hard, reread that section.

  1. Which part is the only one that touches Postgres and Valkey?
  2. How does the ALB decide between the web app and the API?
  3. How does the web server reach the API while it renders /events?
  4. Which parts live outside AWS?
  5. Which switch is off in the committed config, and what does that turn off?

Redraw it from memory: the eight boxes: browser, ALB, web app, API, Postgres, Valkey, SNS to SQS, the Lambda functions

Try this: on the map, drag the stage slider to 9, then 13, then 24, and say what each stage added

Read this book online: https://book.theversehub.in/