Scenario Questions
A customer is charged twice because the app retried a timed-out payment request. How do you fix it?
Make the endpoint idempotent. The client sends an Idempotency-Key header (a UUID per checkout attempt). An interceptor stores the key in Redis as "running" before the handler and the final response as "done" after it. A retry with the same key gets the stored response (or 409 while running) instead of charging again. Also pass the key / your order id to the payment gateway, and add a unique constraint on (userId, idempotencyKey) in the database.
Your API works locally but returns 401 for every request after deploying behind nginx with three instances. What do you check?
- Is
JWT_SECRETthe same on all instances? Different secrets mean a token signed by one instance fails on another. - Does nginx forward the
Authorizationheader? Check proxy config. - Clock skew between servers can make tokens look expired.
- Is the env actually loaded (ConfigModule validation should fail fast if missing)?
The cron job that cancels unpaid orders runs three times every 10 minutes. Why, and how do you fix it?
@Cron runs in every process; with three instances (pm2 cluster or three containers) it fires three times. Fixes: run schedulers in only one dedicated worker instance (e.g. RUN_CRON=true and register ScheduleModule conditionally), or let the cron enqueue a BullMQ job with a fixed jobId (duplicates are ignored), or take a Redis lock (SET key NX PX) before running. Also make the job itself idempotent.
A product listing endpoint takes 4 seconds with 50 products. How do you investigate?
Turn on query logging and count queries: if there are 51+ queries, it is an N+1 problem (category/seller loaded per product); fix with include/relations or a join, or DataLoader in GraphQL. Check EXPLAIN ANALYZE for missing indexes on filter/sort columns, make sure pagination has a max limit, select only needed columns, and cache the first pages in Redis with a short TTL.