Skip to content

fix: production outage + dependency security updates - #10

Merged
devinder-dev merged 2 commits into
mainfrom
fix/production-resilience
Sep 23, 2026
Merged

devinder-dev merged 2 commits into
mainfrom
fix/production-resilience

Conversation

@devinder-dev

Copy link
Copy Markdown
Owner

Why

The live API stopped answering on 2026-09-23. Neon paused the database after the free monthly compute quota ran out, because Render's health check called /health/ready (a SELECT 1) every few seconds and the compute never slept. With no timeouts anywhere, requests hung instead of failing.

Phase 1 — resilience (ADR 51)

  • render.yaml: healthCheckPath: /health (liveness only, no database)
  • /health exempt from the Redis-backed rate limiter
  • pg: connectionTimeoutMillis 5 s, statement_timeout 15 s
  • ioredis (app connection): connectTimeout 3 s, commandTimeout 2 s
  • Fastify requestTimeout 30 s; /health/ready capped at 3 s
  • server.ts logs a failed buildApp() clearly
  • Verified: against an unreachable DB the old code hung until killed; the new code fails in 5.0 s

Phase 2 — dependencies (ADR 52)

  • bun audit: 22 vulnerabilities (9 high) → 1
  • fastify 5.12.5 (fixes X-Forwarded-* spoofing under trustProxy), Prisma 7.10
  • same-major overrides: fast-uri, find-my-way, mysql2
  • Stripe held at ~22.5.0 — 22.6 changes the API version; that gets its own change
  • Remaining: deepmerge-ts, pinned by Prisma, input is our own config only

Tests

438 pass, 0 fail. New: tests/integration/health.test.ts, tests/unit/timeout.test.ts. Production Docker image builds.

After merge

  • UptimeRobot must ping /health, not /health/ready
  • Confirm Render picked up the new health check path

…dependency

The live API went down on 2026-09-23: Render's health check pointed at
/health/ready, which runs SELECT 1 every few seconds, so Neon's compute
never slept, the free monthly quota ran out and Neon paused the project.
With no timeouts anywhere, requests hung instead of failing.

- render.yaml: healthCheckPath /health (liveness only)
- /health exempt from the Redis-backed rate limiter
- pg: connectionTimeoutMillis 5s, statement_timeout 15s
- ioredis app connection: connectTimeout 3s, commandTimeout 2s
- Fastify requestTimeout 30s; /health/ready capped at 3s
- server.ts logs a failed buildApp() clearly instead of an unhandled rejection
- ADR 51, deployment.md warns against pinging /health/ready
…s for pinned transitives

bun audit: 22 known vulnerabilities (9 high) -> 1.

- bun update within existing ranges; majors left for their own change
- overrides, same major only: fast-uri ^3.1.6, find-my-way ^9.7.0,
  mysql2 ^3.24.4
- stripe pinned ~22.5.0: 22.6 moves the API version, which does not ride
  along with a security fix
- remaining: deepmerge-ts <8, pinned by @prisma/config, input is our own
  config file only (ADR 52)
@vercel

vercel Bot commented Sep 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
fakturly-app Ready Ready Preview Sep 23, 2026 1:11pm UTC

@devinder-dev
devinder-dev merged commit 12eb396 into main Sep 23, 2026
7 checks passed

This branch was successfully deployed

1 active deployment
Preview — 5b88c149 Deployed Sep 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant