Skip to content

Add production-readiness features: health checks, security, pagination, sanitization#125

Merged
madhavcodez merged 2 commits intomainfrom
claude/audit-production-readiness-Uc304
Mar 18, 2026
Merged

Add production-readiness features: health checks, security, pagination, sanitization#125
madhavcodez merged 2 commits intomainfrom
claude/audit-production-readiness-Uc304

Conversation

@madhavcodez
Copy link
Copy Markdown
Owner

Summary

This PR hardens the backend for production deployment by adding comprehensive health checks, security headers, API documentation, cursor-based pagination, input sanitization, and improved environment configuration validation.

Key Changes

Security & Headers

  • Added Helmet integration for security headers (X-Content-Type-Options, X-Frame-Options, etc.)
  • Implemented CORS with explicit origin allowlist from environment configuration
  • Added request ID tracking via x-request-id header for observability

Health Checks & Observability

  • Enhanced /health endpoint to perform actual database and Redis connectivity probes
  • Returns 503 Service Unavailable when services are degraded
  • Improved logging configuration with structured serializers and configurable log levels
  • Added graceful shutdown handling for SIGINT/SIGTERM signals

API Documentation

  • Integrated Fastify Swagger for OpenAPI 3.1.0 documentation
  • Exposed API docs at /docs endpoint with JSON schema at /docs/json

Pagination

  • Created pagination.ts utility with cursor-based pagination support
  • Implemented parsePaginationParams() and buildPaginatedResponse() helpers
  • Applied pagination to /v1/search, /v1/feed, and /v1/log/recently-played endpoints
  • Cursor validation prevents SQL injection with length and character checks

Input Sanitization

  • Added sanitize.ts module with stripHtml() function for plain-text fields
  • Applied HTML stripping to review bodies and list descriptions
  • Prevents XSS by encoding special characters

Database Improvements

  • Added migration 006_session_expiry_and_indexes.sql:
    • Session expiration support with expires_at column
    • Full-text search vector on albums with automatic trigger updates
    • Missing performance indexes on ratings, reviews, activity_events, listening_events, and notifications
  • Updated session queries to filter expired sessions with expires_at > NOW()

HTTP Status Codes

  • Changed signup and POST endpoints to return 201 Created instead of 200 OK
  • Updated follow, rating, review, and list creation endpoints accordingly

Environment Configuration

  • Replaced ad-hoc env parsing with Zod schema validation
  • Production mode enforces explicit DATABASE_URL and REDIS_URL (no dev defaults)
  • Added NODE_ENV, LOG_LEVEL, and ALLOWED_ORIGINS configuration
  • Validates all environment variables at startup with clear error messages

Docker & Deployment

  • Added Dockerfile with multi-stage build (builder + production)
  • Added docker-compose.prod.yml with resource limits and health checks
  • Added .dockerignore to optimize image size
  • Added backend/.dockerignore for production builds

Testing & CI

  • Added comprehensive production-readiness.test.ts covering:
    • Health check endpoint validation
    • Security headers presence
    • OpenAPI documentation availability
    • Database schema requirements (session expiry, search vectors, indexes)
    • Pagination functionality on feed and search
    • HTTP status codes (201 for creation)
    • HTML sanitization in reviews
  • Updated existing tests to expect 201 status codes
  • Added npm audit step to CI pipeline
  • Added Dependabot configuration for automated dependency updates

Dependencies

  • Added @fastify/helmet for security headers
  • Added @fastify/swagger and @fastify/swagger-ui for API documentation
  • Added Node.js version constraint (>=20.0.0) in package.json

Notable Implementation Details

  • Pagination uses cursor-based approach (not offset) for better performance at scale
  • Feed caching only applies to first page (no cursor) to maintain consistency
  • Search supports both full-text search vectors and LIKE fallback for compatibility
  • Database connection timeout set to 5 seconds for faster failure detection
  • Redis retry strategy limited to 3 attempts to fail fast
  • Session cleanup can be automated via scheduled job querying idx_sessions_expires index

https://claude.ai/code/session_01HXWnSTisXW9rizJZW4mV7X

claude added 2 commits March 18, 2026 22:18
Security: session expiry (24h TTL), CORS allowlist, helmet headers,
HTML sanitization for user content, env var validation with Zod.

Infrastructure: Dockerfile with multi-stage build, prod docker-compose,
graceful shutdown handler, real health check with DB/Redis probes.

Performance: cursor-based pagination on feed/search/recently-played,
missing DB indexes (ratings, reviews, activity_events), full-text
search with tsvector/GIN index on albums.

API: correct 201 status codes on creation, structured JSON logging
with request IDs, OpenAPI/Swagger docs at /docs.

DevOps: npm audit in CI, engines field in package.json, Dependabot
config, migration naming conflicts fixed (003_ duplicates).

Tests updated for new status codes + production readiness test suite.

https://claude.ai/code/session_01HXWnSTisXW9rizJZW4mV7X
- Env validation: restore dev defaults for DATABASE_URL/REDIS_URL so
  tests work without running services; enforce explicit values in prod
- DB client: add connection timeout (5s), Redis retry limit (3 attempts),
  robust close() that handles disconnected state
- Server: clean up DB on migration failure to prevent orphaned connections
- Pagination: guard against undefined cursor on empty result sets,
  validate cursor length (max 128 chars)
- Sanitize: encode remaining HTML entities after tag stripping
- Migration: add COALESCE for null-safe tsvector generation
- Tests: fix setup() to close app on failure (prevents ioredis retry
  loops hanging the process), tighten status code assertions (201 exact)

https://claude.ai/code/session_01HXWnSTisXW9rizJZW4mV7X
@madhavcodez madhavcodez merged commit c8bdeb8 into main Mar 18, 2026
0 of 2 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in Soundscore Mar 18, 2026
madhavcodez pushed a commit that referenced this pull request Mar 21, 2026
Merges claude/audit-production-readiness-Uc304 into main.
No conflicts — PR changes are backend-only, our recent commit was iOS + contracts.

PR contents:
- Helmet security headers, CORS allowlist, request ID tracking
- Enhanced /health endpoint with DB + Redis probes (503 on degraded)
- Fastify Swagger for OpenAPI 3.1.0 docs at /docs
- Cursor-based pagination on /v1/search, /v1/feed, /v1/log/recently-played
- HTML sanitization (stripHtml) on reviews and list descriptions
- Migration 006: session expiry, full-text search vectors, performance indexes
- Zod-validated env config (enforces explicit URLs in production)
- Multi-stage Dockerfile + docker-compose.prod.yml with resource limits
- Production-readiness test suite
- 201 Created status codes for POST endpoints
- Dependabot config for automated dependency updates
madhavcodez pushed a commit that referenced this pull request Mar 21, 2026
Merges claude/audit-production-readiness-Uc304 into main.
No conflicts — PR changes are backend-only, our recent commit was iOS + contracts.

PR contents:
- Helmet security headers, CORS allowlist, request ID tracking
- Enhanced /health endpoint with DB + Redis probes (503 on degraded)
- Fastify Swagger for OpenAPI 3.1.0 docs at /docs
- Cursor-based pagination on /v1/search, /v1/feed, /v1/log/recently-played
- HTML sanitization (stripHtml) on reviews and list descriptions
- Migration 006: session expiry, full-text search vectors, performance indexes
- Zod-validated env config (enforces explicit URLs in production)
- Multi-stage Dockerfile + docker-compose.prod.yml with resource limits
- Production-readiness test suite
- 201 Created status codes for POST endpoints
- Dependabot config for automated dependency updates
@madhavcodez madhavcodez deleted the claude/audit-production-readiness-Uc304 branch March 21, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants