{"_id":"@ankit18193/routex-gateway","_rev":"3-57745042e83cdea46d9419585bc8e40d","name":"@ankit18193/routex-gateway","dist-tags":{"latest":"1.2.1"},"versions":{"1.1.0":{"name":"@ankit18193/routex-gateway","version":"1.1.0","keywords":["api-gateway","reverse-proxy","fastify","typescript","redis","rate-limiting","streaming"],"author":"","license":"MIT","_id":"@ankit18193/routex-gateway@1.1.0","maintainers":[{"name":"ankit18193","email":"ankityadav18193@gmail.com"}],"bin":{"routex":"dist/src/bin/gateway.js"},"dist":{"shasum":"15c2fd05e16d7263519e419cba1d121fcd191929","tarball":"https://registry.npmjs.org/@ankit18193/routex-gateway/-/routex-gateway-1.1.0.tgz","fileCount":219,"integrity":"sha512-OzM4t5QRKE2SlFpH3UXvrVKw9FW34WxfB0TMgPZpDKjED1GVG78mnMekphifgJtIAbGtt4Pl6lWDCcaL/67fVQ==","signatures":[{"sig":"MEYCIQD7Rf0p/o1LI+4dVNYJDje8V+pGyZPGYjrO/pwJicxREQIhANQ71Px8pi/8c37xROxZVfw/bKNFcojHLizLWVF0Aexa","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":553789},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./auth":{"types":"./dist/src/auth/index.d.ts","import":"./dist/src/auth/index.js"},"./cache":{"types":"./dist/src/cache/index.d.ts","import":"./dist/src/cache/index.js"},"./proxy":{"types":"./dist/src/proxy/index.d.ts","import":"./dist/src/proxy/index.js"},"./types":{"types":"./dist/src/types/index.d.ts","import":"./dist/src/types/index.js"},"./utils":{"types":"./dist/src/utils/index.d.ts","import":"./dist/src/utils/index.js"},"./config":{"types":"./dist/src/config/index.d.ts","import":"./dist/src/config/index.js"},"./errors":{"types":"./dist/src/errors/index.d.ts","import":"./dist/src/errors/index.js"},"./logger":{"types":"./dist/src/logger/index.d.ts","import":"./dist/src/logger/index.js"},"./server":{"types":"./dist/src/server/index.d.ts","import":"./dist/src/server/index.js"},"./rate-limit":{"types":"./dist/src/rate-limit/index.d.ts","import":"./dist/src/rate-limit/index.js"},"./package.json":"./package.json","./circuit-breaker":{"types":"./dist/src/circuit-breaker/index.d.ts","import":"./dist/src/circuit-breaker/index.js"}},"gitHead":"3072fa0b5d3dee774a49e3e6f032de0d5fb88fed","scripts":{"dev":"tsc && node dist/src/bin/gateway.js","test":"vitest run","build":"tsc","start":"node dist/src/bin/gateway.js","prepack":"npm run build","typecheck":"tsc --noEmit","start:chat":"node dist/src/bin/mock-chat.js","start:user":"node dist/src/bin/mock-user.js","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"ankit18193","email":"ankityadav18193@gmail.com"},"_npmVersion":"11.16.0","description":"Production-grade API Gateway and Reverse Proxy built with Node.js and TypeScript","directories":{},"_nodeVersion":"24.18.0","dependencies":{"zod":"^3.24.2","pino":"^9.6.0","yaml":"^2.7.0","dotenv":"^16.4.7","undici":"^7.4.0","fastify":"^5.2.1","ioredis":"^5.6.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.8","typescript":"^5.8.2","@types/node":"^22.13.9","pino-pretty":"^13.0.0","@vitest/coverage-v8":"^3.0.8"},"_npmOperationalInternal":{"tmp":"tmp/routex-gateway_1.1.0_1788854357939_0.09491401781549302","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@ankit18193/routex-gateway","version":"1.2.0","keywords":["api-gateway","reverse-proxy","fastify","typescript","redis","rate-limiting","streaming"],"author":"","license":"MIT","_id":"@ankit18193/routex-gateway@1.2.0","maintainers":[{"name":"ankit18193","email":"ankityadav18193@gmail.com"}],"bin":{"routex":"dist/src/bin/gateway.js"},"dist":{"shasum":"5182794bd3916502072cdb9ce7ecf3fc5d6f92e0","tarball":"https://registry.npmjs.org/@ankit18193/routex-gateway/-/routex-gateway-1.2.0.tgz","fileCount":219,"integrity":"sha512-ZqkHXi2NpeVLOR3Hn6So3h6w/RuUXeGBoncj4H5xyBr7xpYbJOUePGexySPGQTEnPsJGvFakHDvOmdSfLL0PHg==","signatures":[{"sig":"MEUCIQDRlxbysHbNG//nGl4LHfbKZEVQc4EQt8B2c+3V4fejugIgOJe4mgFAtTTSPzs969dFO6fUFkeEAOxCjQlq6caKNac=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":562525},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./auth":{"types":"./dist/src/auth/index.d.ts","import":"./dist/src/auth/index.js"},"./cache":{"types":"./dist/src/cache/index.d.ts","import":"./dist/src/cache/index.js"},"./proxy":{"types":"./dist/src/proxy/index.d.ts","import":"./dist/src/proxy/index.js"},"./types":{"types":"./dist/src/types/index.d.ts","import":"./dist/src/types/index.js"},"./utils":{"types":"./dist/src/utils/index.d.ts","import":"./dist/src/utils/index.js"},"./config":{"types":"./dist/src/config/index.d.ts","import":"./dist/src/config/index.js"},"./errors":{"types":"./dist/src/errors/index.d.ts","import":"./dist/src/errors/index.js"},"./logger":{"types":"./dist/src/logger/index.d.ts","import":"./dist/src/logger/index.js"},"./server":{"types":"./dist/src/server/index.d.ts","import":"./dist/src/server/index.js"},"./rate-limit":{"types":"./dist/src/rate-limit/index.d.ts","import":"./dist/src/rate-limit/index.js"},"./package.json":"./package.json","./circuit-breaker":{"types":"./dist/src/circuit-breaker/index.d.ts","import":"./dist/src/circuit-breaker/index.js"}},"gitHead":"5b1d7633eb85110c02248caa55d16b848b5ea0cf","scripts":{"dev":"tsc && node dist/src/bin/gateway.js","test":"vitest run","build":"tsc","start":"node dist/src/bin/gateway.js","prepack":"npm run build","typecheck":"tsc --noEmit","start:chat":"node dist/src/bin/mock-chat.js","start:user":"node dist/src/bin/mock-user.js","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"ankit18193","email":"ankityadav18193@gmail.com"},"_npmVersion":"11.16.0","description":"Production-grade API Gateway and Reverse Proxy built with Node.js and TypeScript","directories":{},"_nodeVersion":"24.18.0","dependencies":{"zod":"^3.24.2","pino":"^9.6.0","yaml":"^2.7.0","dotenv":"^16.4.7","undici":"^7.4.0","fastify":"^5.2.1","ioredis":"^5.6.0","@ankit18193/pulse":"^0.4.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.8","typescript":"^5.8.2","@types/node":"^22.13.9","pino-pretty":"^13.0.0","@vitest/coverage-v8":"^3.0.8"},"_npmOperationalInternal":{"tmp":"tmp/routex-gateway_1.2.0_1788966497349_0.8785218702648512","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@ankit18193/routex-gateway","version":"1.2.1","description":"Production-grade API Gateway and Reverse Proxy built with Node.js and TypeScript","type":"module","main":"dist/src/index.js","types":"dist/src/index.d.ts","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./config":{"types":"./dist/src/config/index.d.ts","import":"./dist/src/config/index.js"},"./server":{"types":"./dist/src/server/index.d.ts","import":"./dist/src/server/index.js"},"./types":{"types":"./dist/src/types/index.d.ts","import":"./dist/src/types/index.js"},"./errors":{"types":"./dist/src/errors/index.d.ts","import":"./dist/src/errors/index.js"},"./auth":{"types":"./dist/src/auth/index.d.ts","import":"./dist/src/auth/index.js"},"./rate-limit":{"types":"./dist/src/rate-limit/index.d.ts","import":"./dist/src/rate-limit/index.js"},"./cache":{"types":"./dist/src/cache/index.d.ts","import":"./dist/src/cache/index.js"},"./circuit-breaker":{"types":"./dist/src/circuit-breaker/index.d.ts","import":"./dist/src/circuit-breaker/index.js"},"./proxy":{"types":"./dist/src/proxy/index.d.ts","import":"./dist/src/proxy/index.js"},"./logger":{"types":"./dist/src/logger/index.d.ts","import":"./dist/src/logger/index.js"},"./utils":{"types":"./dist/src/utils/index.d.ts","import":"./dist/src/utils/index.js"},"./package.json":"./package.json"},"bin":{"routex":"dist/src/bin/gateway.js"},"scripts":{"dev":"tsc && node dist/src/bin/gateway.js","start":"node dist/src/bin/gateway.js","start:user":"node dist/src/bin/mock-user.js","start:chat":"node dist/src/bin/mock-chat.js","build":"tsc","prepack":"npm run build","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},"keywords":["api-gateway","reverse-proxy","fastify","typescript","redis","rate-limiting","streaming"],"author":"","license":"MIT","dependencies":{"dotenv":"^16.4.7","fastify":"^5.2.1","ioredis":"^5.6.0","pino":"^9.6.0","undici":"^7.4.0","yaml":"^2.7.0","zod":"^3.24.2"},"devDependencies":{"@types/node":"^22.13.9","@vitest/coverage-v8":"^3.0.8","pino-pretty":"^13.0.0","typescript":"^5.8.2","vitest":"^3.0.8"},"engines":{"node":">=20.0.0"},"gitHead":"5b1d7633eb85110c02248caa55d16b848b5ea0cf","_id":"@ankit18193/routex-gateway@1.2.1","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-7m2ZY5LAfUiAMervIRBJOjRH7s0M5c/tyJ/mKmCaj6TAZqnYjeYFoh8J9KOsgx7AfeuvgVRnCSsB3t4W8AJarQ==","shasum":"982519c8ecbbccdc869ba38fe13e16c63154a91b","tarball":"https://registry.npmjs.org/@ankit18193/routex-gateway/-/routex-gateway-1.2.1.tgz","fileCount":219,"unpackedSize":562490,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHGtQYBeSueLT8qAWvdYxX/3XJqX+sDH4QR4Sa/s2DlgAiEAjQuHm37kf47Wu5fGSr/CYTet3rUJnUPSGzDzhUWnlro="}]},"_npmUser":{"name":"ankit18193","email":"ankityadav18193@gmail.com"},"directories":{},"maintainers":[{"name":"ankit18193","email":"ankityadav18193@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/routex-gateway_1.2.1_1788967137779_0.9895050711471016"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-08T07:59:17.649Z","modified":"2026-09-09T15:18:58.165Z","1.1.0":"2026-09-08T07:59:18.100Z","1.2.0":"2026-09-09T15:08:17.513Z","1.2.1":"2026-09-09T15:18:57.930Z"},"license":"MIT","keywords":["api-gateway","reverse-proxy","fastify","typescript","redis","rate-limiting","streaming"],"description":"Production-grade API Gateway and Reverse Proxy built with Node.js and TypeScript","maintainers":[{"name":"ankit18193","email":"ankityadav18193@gmail.com"}],"readme":"# RouteX — High-Performance Edge API Gateway & Reverse Proxy\r\n\r\n> Production-quality, resilient, zero-buffer streaming API Gateway built with Node.js, TypeScript, Fastify, Undici, Redis, and Docker.\r\n\r\n---\r\n\r\n## Table of Contents\r\n1. [Architecture Overview](#architecture-overview)\r\n2. [Integrating RouteX Into Your Application](#integrating-routex-into-your-application)\r\n   - [The Integration Mental Model](#the-integration-mental-model)\r\n   - [The Three Integration Models](#the-three-integration-models)\r\n   - [Zero-to-Working Integration Guide (10 Steps)](#zero-to-working-integration-guide-10-steps)\r\n   - [Real Worked Example Application](#real-worked-example-application)\r\n   - [What the Developer Modifies vs What Stays Untouched](#what-the-developer-modifies-vs-what-stays-untouched)\r\n   - [Docker Compose Integration: Same Stack vs External Services](#docker-compose-integration-same-stack-vs-external-services)\r\n   - [Development vs Production Deployment](#development-vs-production-deployment)\r\n   - [What Happens When My Application Sends a Request?](#what-happens-when-my-application-sends-a-request)\r\n   - [Common Integration Mistakes & Gotchas](#common-integration-mistakes--gotchas)\r\n   - [How to Add Another Backend Service](#how-to-add-another-backend-service)\r\n   - [Client URLs vs Internal Upstream URLs](#client-urls-vs-internal-upstream-urls)\r\n   - [Authentication & Identity Integration](#authentication--identity-integration)\r\n   - [Practical Guide: Rate Limiting, Caching & Circuit Breaking](#practical-guide-rate-limiting-caching--circuit-breaking)\r\n   - [RouteX Integration Checklist](#routex-integration-checklist)\r\n   - [What You Don't Need to Change](#what-you-dont-need-to-change)\r\n3. [Feature Matrix](#feature-matrix)\r\n4. [Request Lifecycle Pipeline](#request-lifecycle-pipeline)\r\n5. [Quickstart Guide](#quickstart-guide)\r\n   - [Local Development](#local-development)\r\n   - [Docker & Docker Compose](#docker--docker-compose)\r\n6. [Configuration Reference](#configuration-reference)\r\n7. [Operational Runbook](#operational-runbook)\r\n   - [Health & Readiness Probes](#health--readiness-probes)\r\n   - [Graceful Shutdown & Socket Draining](#graceful-shutdown--socket-draining)\r\n   - [Structured Logging & Correlation](#structured-logging--correlation)\r\n   - [Redis Fault Tolerance & Fail-Open Behavior](#redis-fault-tolerance--fail-open-behavior)\r\n8. [Security Model](#security-model)\r\n9. [Performance & Streaming Memory Profiling](#performance--streaming-memory-profiling)\r\n10. [Troubleshooting Guide](#troubleshooting-guide)\r\n11. [Automated Verification Suite](#automated-verification-suite)\r\n\r\n---\r\n\r\n## Architecture Overview\r\n\r\n```mermaid\r\nflowchart TD\r\n    Client[HTTP/HTTPS Clients / Web / Mobile] -->|Ingress Traffic :8080| Gateway[RouteX Gateway Engine]\r\n    \r\n    subgraph RouteX Pipeline\r\n        Gateway --> P1[1. Correlation & UUID Engine]\r\n        P1 --> P2[2. Tier-1 IP Rate Limiter]\r\n        P2 --> P3[3. Edge Auth JWT / API Keys]\r\n        P3 --> P4[4. RBAC Authorization]\r\n        P4 --> P5[5. Tier-2 Identity Rate Limiter]\r\n        P5 --> P6{6. Response Cache?}\r\n        \r\n        P6 -- HIT --> CacheReturn[Return Cached Response + Age Header]\r\n        P6 -- MISS / BYPASS --> P7{7. Circuit Breaker OPEN?}\r\n        \r\n        P7 -- YES (OPEN) --> FastFail[503 UPSTREAM_CIRCUIT_OPEN]\r\n        P7 -- NO (CLOSED/HALF_OPEN) --> P8[8. SingleFlight Collapsing]\r\n        P8 --> P9[9. Header Sanitization RFC 7230/9110]\r\n        P9 --> P10[10. Undici Stream Connection Pool]\r\n    end\r\n\r\n    P10 -->|Zero-Buffer Stream| US1[User Service :4001]\r\n    P10 -->|Zero-Buffer Stream| US2[Chat Service :4002]\r\n    P10 -->|Zero-Buffer Stream| US3[Payment Service :4003]\r\n    P2 -.->|Sliding Window Lua| Redis[(Redis 7 :6379)]\r\n    P5 -.->|Sliding Window Lua| Redis\r\n    P6 -.->|SHA-256 Key Cache| Redis\r\n```\r\n\r\n---\r\n\r\n## Integrating RouteX Into Your Application\r\n\r\nThis section is a step-by-step, practical guide for developers who want to connect RouteX to their existing backend services and direct frontend/client traffic through the gateway.\r\n\r\n### The Integration Mental Model\r\n\r\nRouteX is an **Edge API Gateway and Reverse Proxy**. It acts as a single, hardened entry point in front of your backend microservices:\r\n\r\n```\r\nBEFORE ROUTEX:\r\nClient / Frontend ───> Directly calls User Service (:4001)\r\n                  ───> Directly calls Chat Service (:4002)\r\n                  ───> Directly calls Payment Service (:4003)\r\n\r\nAFTER ROUTEX:\r\nClient / Frontend ───> RouteX Gateway (:8080)\r\n                              │\r\n                              ├───> User Service (:4001)\r\n                              ├───> Chat Service (:4002)\r\n                              └───> Payment Service (:4003)\r\n```\r\n\r\n- **Your backend services stay untouched**: Your services continue to execute business logic, query databases, and return responses. You **do not** rewrite your APIs to use RouteX.\r\n- **RouteX handles cross-cutting concerns**: RouteX centralizes routing, authentication (JWT/API-keys), role-based access control (RBAC), distributed sliding-window rate limiting, HTTP response caching, circuit breaking, zero-buffer streaming, and RFC 7230/9110 header hygiene.\r\n- **Trusted identity propagation**: Once RouteX authenticates a user, it injects verified HTTP headers (`x-user-id`, `x-user-roles`, `x-auth-type`) into the upstream request. Your downstream services can trust these headers and avoid redundant JWT decoding.\r\n\r\n---\r\n\r\n### The Three Integration Models\r\n\r\nDepending on your organization's repository structure, choose the model that fits your architecture:\r\n\r\n#### Option A: Dedicated Gateway Service (Recommended for Microservices)\r\n\r\nRouteX runs as an independent repository and containerized service in your infrastructure, sitting in front of your application services:\r\n\r\n```\r\nmy-application/\r\n  ├── frontend/\r\n  ├── user-service/\r\n  ├── chat-service/\r\n  └── payment-service/\r\n\r\nRouteX/ (Separate repo / container)\r\n  ├── config/\r\n  │   ├── gateway.docker.yaml\r\n  │   └── routes.docker.yaml\r\n  └── docker-compose.yml\r\n```\r\n\r\n#### Option B: Monorepo / Unified Deployment\r\n\r\nIf your team maintains a monorepo, RouteX lives in an `api-gateway/` or `routex/` directory and is orchestrated alongside your services in a shared `docker-compose.yml` or Kubernetes manifest.\r\n\r\n#### Option C: Reusable npm Package / Programmatic Library\r\n\r\nInstall and import RouteX directly into any Node.js / TypeScript application:\r\n\r\n```bash\r\nnpm install routex\r\n```\r\n\r\n```typescript\r\nimport { createGatewayServer } from 'routex';\r\n\r\n// Initialize RouteX Gateway programmatically in code\r\nconst gateway = createGatewayServer({\r\n  server: {\r\n    port: 8080,\r\n    host: '0.0.0.0',\r\n    logLevel: 'info',\r\n  },\r\n  routes: [\r\n    {\r\n      id: 'user-service-route',\r\n      pathPrefix: '/api/v1/users',\r\n      upstream: 'http://localhost:4001',\r\n      methods: ['GET', 'POST', 'PUT', 'DELETE'],\r\n    },\r\n    {\r\n      id: 'chat-service-route',\r\n      pathPrefix: '/api/v1/chats',\r\n      upstream: 'http://localhost:4002',\r\n      websocket: true,\r\n    },\r\n  ],\r\n});\r\n\r\n// Start listening\r\nconst address = await gateway.listen();\r\nconsole.log(`RouteX Gateway running on ${address}`);\r\n\r\n// Access underlying Fastify instance if needed:\r\n// gateway.fastifyInstance.get('/custom', ...)\r\n\r\n// Gracefully drain sockets and close connection pools on shutdown:\r\n// await gateway.close();\r\n```\r\n\r\n##### Modular Subpath Imports\r\n\r\nRouteX exports clean, tree-shakeable ESM submodules:\r\n\r\n```typescript\r\nimport { RouteXGatewayServer, createGatewayServer } from 'routex/server';\r\nimport { GatewayConfigSchema, loadGatewayConfig } from 'routex/config';\r\nimport { GatewayError, createErrorEnvelope } from 'routex/errors';\r\nimport { AuthManager, createAuthManager } from 'routex/auth';\r\nimport { RateLimitManager, RedisClient } from 'routex/rate-limit';\r\nimport { CacheManager } from 'routex/cache';\r\nimport { CircuitManager } from 'routex/circuit-breaker';\r\nimport { ProxyRouter, WebSocketProxyHandler } from 'routex/proxy';\r\nimport { createLogger, logAccess } from 'routex/logger';\r\n```\r\n\r\n---\r\n\r\n### Zero-to-Working Integration Guide (10 Steps)\r\n\r\nFollow these 10 steps to connect RouteX to your backend services:\r\n\r\n#### Step 1 — Get RouteX\r\n\r\nClone the RouteX repository:\r\n\r\n```bash\r\ngit clone https://github.com/ankit18193/RouteX.git\r\ncd RouteX\r\n```\r\n\r\nYou do **not** copy RouteX TypeScript source files into your backend application. RouteX is a standalone service packaged via Docker.\r\n\r\n#### Step 2 — Identify Your Backend Services\r\n\r\nList the URLs and ports of the backend services you want to place behind RouteX:\r\n\r\n| Service Name | Internal Host & Port | Example Routes |\r\n|---|---|---|\r\n| **User Service** | `http://user-service:4001` | `/api/v1/users/*`, `/api/v1/auth/*` |\r\n| **Chat Service** | `http://chat-service:4002` | `/api/v1/chats/*`, `/api/v1/messages/*` |\r\n| **Payment Service** | `http://payment-service:4003` | `/api/v1/payments/*` |\r\n\r\n*(Replace these with your actual container names/hostnames and ports).*\r\n\r\n#### Step 3 — Configure Routes in `config/routes.docker.yaml`\r\n\r\nEdit [`config/routes.docker.yaml`](file:///d:/RouteX/RouteX/config/routes.docker.yaml) to register your routes and upstream targets:\r\n\r\n```yaml\r\nroutes:\r\n  # 1. Public Authentication Route\r\n  - id: auth_service_api\r\n    pathPrefix: /api/v1/auth\r\n    upstream: http://user-service:4001\r\n    stripPrefix: false\r\n    methods: [POST]\r\n    auth:\r\n      mode: public\r\n    rateLimit:\r\n      enabled: true\r\n      windowSec: 60\r\n      limit: 30\r\n      failurePolicy: fail-open\r\n    timeouts:\r\n      connectTimeoutMs: 2000\r\n      responseTimeoutMs: 3000\r\n\r\n  # 2. Protected User Management Route\r\n  - id: user_service_api\r\n    pathPrefix: /api/v1/users\r\n    upstream: http://user-service:4001\r\n    stripPrefix: false\r\n    methods: [GET, POST, PUT, PATCH, DELETE]\r\n    auth:\r\n      mode: jwt\r\n      requiredRoles: []\r\n    rateLimit:\r\n      enabled: true\r\n      windowSec: 60\r\n      limit: 100\r\n      tiers:\r\n        free: 60\r\n        premium: 500\r\n    cache:\r\n      enabled: true\r\n      ttlSec: 30\r\n      allowAuthenticated: true\r\n    circuitBreaker:\r\n      enabled: true\r\n      failureThreshold: 5\r\n      resetTimeoutMs: 10000\r\n    timeouts:\r\n      connectTimeoutMs: 2000\r\n      responseTimeoutMs: 5000\r\n\r\n  # 3. Chat & Messaging Route\r\n  - id: chat_service_api\r\n    pathPrefix: /api/v1/chats\r\n    upstream: http://chat-service:4002\r\n    stripPrefix: false\r\n    methods: [GET, POST, PUT, DELETE]\r\n    auth:\r\n      mode: any\r\n    rateLimit:\r\n      enabled: true\r\n      windowSec: 60\r\n      limit: 120\r\n    timeouts:\r\n      connectTimeoutMs: 2000\r\n      responseTimeoutMs: 5000\r\n```\r\n\r\n##### Field Reference for `routes.docker.yaml`:\r\n\r\n| Field | Type | Description |\r\n|---|---|---|\r\n| `id` | `string` | Unique identifier for the route (e.g. `user_service_api`). |\r\n| `pathPrefix` | `string` | URL prefix matched using longest-prefix matching (e.g. `/api/v1/users`). |\r\n| `upstream` | `string` | Internal upstream URL (e.g. `http://user-service:4001`). Must include protocol. |\r\n| `stripPrefix` | `boolean` | `false` preserves `pathPrefix` when proxying; `true` strips it before dispatching. |\r\n| `methods` | `string[]` | HTTP methods allowed (e.g. `[GET, POST, PUT, DELETE]`). Unmatched methods return 405. |\r\n| `auth.mode` | `enum` | `'public'` (no auth), `'jwt'` (Bearer token), `'api-key'` (`x-api-key`), `'any'` (JWT or API key). |\r\n| `auth.requiredRoles` | `string[]` | RBAC roles required to access route (e.g. `['admin']`). |\r\n| `rateLimit.enabled` | `boolean` | Activates Redis atomic sliding-window rate limiting. |\r\n| `rateLimit.windowSec` | `number` | Rate limit window in seconds (default: `60`). |\r\n| `rateLimit.limit` | `number` | Allowed request quota per window (default: `100`). |\r\n| `rateLimit.tiers` | `record` | Tier-based quotas based on user/API-key tier (e.g. `free: 60`, `premium: 500`). |\r\n| `cache.enabled` | `boolean` | Activates Redis response caching for safe GET requests. |\r\n| `cache.ttlSec` | `number` | Time-to-live for cached responses in seconds. |\r\n| `circuitBreaker.enabled` | `boolean` | Activates per-upstream circuit breaker protection. |\r\n| `circuitBreaker.failureThreshold` | `number` | Consecutive 5xx failures required to trip breaker to `OPEN`. |\r\n| `timeouts.responseTimeoutMs` | `number` | Maximum time to wait for upstream response before returning 504. |\r\n\r\n#### Step 4 — Configure Gateway Settings in `config/gateway.docker.yaml`\r\n\r\nReview [`config/gateway.docker.yaml`](file:///d:/RouteX/RouteX/config/gateway.docker.yaml):\r\n\r\n```yaml\r\nserver:\r\n  port: 8080\r\n  host: 0.0.0.0\r\n  requestTimeoutMs: 10000\r\n  headersTimeoutMs: 11000\r\n  maxHeaderSize: 16384\r\n  trustedProxies:\r\n    - 127.0.0.1\r\n    - ::1\r\n    - 172.16.0.0/12\r\n    - 10.0.0.0/8\r\n  logLevel: info\r\n  logFormat: json\r\n\r\nredis:\r\n  host: redis\r\n  port: 6379\r\n  db: 0\r\n  connectTimeoutMs: 3000\r\n  keyPrefix: \"routex:\"\r\n\r\nauth:\r\n  jwt:\r\n    enabled: true\r\n    hs256Secret: \"routex-dev-super-secret-key-for-testing-at-least-32-chars-long!\"\r\n  apiKey:\r\n    enabled: true\r\n    headerName: \"x-api-key\"\r\n    cacheTtlSec: 300\r\n```\r\n\r\n#### Step 5 — Configure Environment Variables in `.env`\r\n\r\nCopy `.env.example` to `.env`:\r\n\r\n```bash\r\ncp .env.example .env\r\n```\r\n\r\nReview `.env`:\r\n\r\n```ini\r\n# Server configuration\r\nPORT=8080\r\nHOST=0.0.0.0\r\nLOG_LEVEL=info\r\nLOG_FORMAT=json\r\n\r\n# Configuration file paths (points to Docker configuration)\r\nROUTEX_CONFIG_PATH=config/gateway.docker.yaml\r\nROUTEX_ROUTES_PATH=config/routes.docker.yaml\r\n\r\n# Redis configuration (inside Docker Compose, host is the service name 'redis')\r\nREDIS_HOST=redis\r\nREDIS_PORT=6379\r\nREDIS_PASSWORD=\r\n\r\n# Authentication secrets (Replace with your production secrets)\r\nJWT_HS256_SECRET=your-32-character-or-longer-production-jwt-secret-key-here!\r\nJWT_SECRET=your-32-character-or-longer-production-jwt-secret-key-here!\r\n```\r\n\r\n> [!IMPORTANT]\r\n> Never commit `.env` to version control. The repository `.gitignore` automatically ignores `.env`. Use `.env.example` as a template.\r\n\r\n#### Step 6 — Configure Docker Networking (`service-name` vs `localhost`)\r\n\r\nWhen running inside Docker Compose:\r\n- **CORRECT**: `upstream: http://user-service:4001` (Uses Docker internal DNS to resolve the container name).\r\n- **INCORRECT**: `upstream: http://localhost:4001` (Resolves to the `routex-gateway` container itself, causing connection refused `502 BAD_GATEWAY`).\r\n\r\nEnsure your services share a Docker network with RouteX (e.g. `routex-net`).\r\n\r\n#### Step 7 — Start RouteX with Docker Compose\r\n\r\nBuild and launch the stack:\r\n\r\n```bash\r\n# Build the production Docker image\r\ndocker compose build\r\n\r\n# Start the stack in background\r\ndocker compose up -d\r\n\r\n# Check running container health\r\ndocker compose ps\r\n```\r\n\r\nExpected output:\r\n```text\r\nNAME                  SERVICE          STATUS                    PORTS\r\nroutex-gateway        routex-gateway   Up 2 minutes (healthy)    0.0.0.0:8080->8080/tcp\r\nroutex-redis          redis            Up 2 minutes (healthy)    0.0.0.0:6379->6379/tcp\r\nroutex-user-service   user-service     Up 2 minutes (healthy)    0.0.0.0:4001->4001/tcp\r\nroutex-chat-service   chat-service     Up 2 minutes (healthy)    0.0.0.0:4002->4002/tcp\r\n```\r\n\r\n#### Step 8 — Verify the Gateway Probes\r\n\r\nVerify that RouteX and its dependencies are running and healthy:\r\n\r\n```bash\r\n# Liveness Probe (process health, memory usage)\r\ncurl -i http://localhost:8080/livez\r\n\r\n# Readiness Probe (router, poolManager, Redis connectivity)\r\ncurl -i http://localhost:8080/readyz\r\n```\r\n\r\nExpected response for `/readyz`:\r\n```json\r\n{\r\n  \"status\": \"ok\",\r\n  \"gateway\": \"RouteX\",\r\n  \"checks\": {\r\n    \"router\": \"ok\",\r\n    \"poolManager\": \"ok\",\r\n    \"redis\": \"ok\"\r\n  },\r\n  \"uptimeSec\": 120\r\n}\r\n```\r\n\r\n#### Step 9 — Change Your Client / Frontend Base URL\r\n\r\nUpdate your frontend application (React, Vue, iOS, Android, etc.) or API client to send traffic through RouteX at port `8080`:\r\n\r\n```javascript\r\n// BEFORE: Directly contacting microservices\r\nconst USER_API = \"http://localhost:4001/api/v1/users\";\r\nconst CHAT_API = \"http://localhost:4002/api/v1/chats\";\r\n\r\n// AFTER: All ingress traffic routes through RouteX Gateway\r\nconst API_BASE_URL = \"http://localhost:8080\";\r\n\r\n// Fetch current user\r\nconst userRes = await fetch(`${API_BASE_URL}/api/v1/users/me`, {\r\n  headers: { \"Authorization\": `Bearer ${token}` }\r\n});\r\n\r\n// Fetch chats\r\nconst chatRes = await fetch(`${API_BASE_URL}/api/v1/chats`, {\r\n  headers: { \"Authorization\": `Bearer ${token}` }\r\n});\r\n```\r\n\r\n#### Step 10 — Test Authentication & Trusted Identity Propagation\r\n\r\nSend an authenticated request through RouteX:\r\n\r\n```bash\r\n# 1. Obtain a JWT token\r\nTOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/token \\\r\n  -H \"Content-Type: application/json\" \\\r\n  -d '{\"sub\":\"usr_prod_101\",\"roles\":[\"user\"]}' | jq -r .token)\r\n\r\n# 2. Call protected user route through RouteX Gateway\r\ncurl -i -H \"Authorization: Bearer $TOKEN\" http://localhost:8080/api/v1/users/me\r\n```\r\n\r\nRouteX validates the JWT, enforces rate limits, checks RBAC, and injects verified identity headers before forwarding to `user-service`:\r\n- `x-user-id: usr_prod_101`\r\n- `x-user-roles: user`\r\n- `x-auth-type: jwt`\r\n- `x-gateway-auth-status: authenticated`\r\n\r\n---\r\n\r\n### Real Worked Example Application\r\n\r\nLet's look at an end-to-end request flow for a realistic 3-service architecture:\r\n\r\n```mermaid\r\nsequenceDiagram\r\n    autonumber\r\n    actor Client as Frontend Client\r\n    participant GW as RouteX Gateway (:8080)\r\n    participant Redis as Redis 7 (:6379)\r\n    participant US as User Service (:4001)\r\n\r\n    Client->>GW: GET /api/v1/users/me (Authorization: Bearer <JWT>)\r\n    GW->>GW: 1. Generate x-request-id: req_a1b2\r\n    GW->>GW: 2. Match route: user_service_api (/api/v1/users)\r\n    GW->>Redis: 3. Check Tier-1 IP rate limit\r\n    Redis-->>GW: IP Limit OK (Remaining: 99)\r\n    GW->>GW: 4. Verify JWT signature & expiration\r\n    GW->>GW: 5. Verify RBAC roles\r\n    GW->>Redis: 6. Check Tier-2 Identity rate limit\r\n    Redis-->>GW: Identity Limit OK\r\n    GW->>Redis: 7. Check Response Cache (GET hash)\r\n    Redis-->>GW: Cache MISS\r\n    GW->>GW: 8. Check Circuit Breaker (Origin: user-service:4001 -> CLOSED)\r\n    GW->>US: 9. Proxy Stream + Injected Headers (x-user-id, x-request-id)\r\n    US-->>GW: 10. HTTP 200 OK (User Profile JSON)\r\n    GW->>Redis: 11. Store Response Cache (TTL: 30s)\r\n    GW-->>Client: 12. HTTP 200 OK + x-cache: MISS + x-request-id\r\n```\r\n\r\n---\r\n\r\n### What the Developer Modifies vs What Stays Untouched\r\n\r\n| File / Component | Modification Required? | Purpose & Developer Responsibility |\r\n|---|:---:|---|\r\n| [`config/routes.docker.yaml`](file:///d:/RouteX/RouteX/config/routes.docker.yaml) | **REQUIRED** | Declare your backend services, URL paths, auth requirements, rate limits, caching, and timeouts. |\r\n| [`.env`](file:///d:/RouteX/RouteX/.env) | **REQUIRED** | Set environment-specific secrets (`JWT_HS256_SECRET`, `REDIS_HOST`, `PORT`). |\r\n| [`config/gateway.docker.yaml`](file:///d:/RouteX/RouteX/config/gateway.docker.yaml) | **OPTIONAL** | Adjust global server timeouts, trusted proxy CIDRs, and logging level/format. |\r\n| [`docker-compose.yml`](file:///d:/RouteX/RouteX/docker-compose.yml) | **OPTIONAL** | Replace mock services with your actual application containers or attach external networks. |\r\n| [`Dockerfile`](file:///d:/RouteX/RouteX/Dockerfile) | **DO NOT TOUCH** | Production multi-stage Alpine build already configured and optimized. |\r\n| `src/**` (All source code) | **DO NOT TOUCH** | Core gateway routing, streaming, crypto, and Redis Lua engines. |\r\n| [`.env.example`](file:///d:/RouteX/RouteX/.env.example) | **REFERENCE ONLY** | Template for `.env`. Keep in sync if new environment variables are introduced. |\r\n\r\n---\r\n\r\n### Docker Compose Integration: Same Stack vs External Services\r\n\r\n#### Case 1: Services in the Same `docker-compose.yml`\r\n\r\nIf your backend services run in the same Compose stack as RouteX:\r\n\r\n```yaml\r\nservices:\r\n  routex-gateway:\r\n    build: .\r\n    container_name: routex-gateway\r\n    ports:\r\n      - \"8080:8080\"\r\n    environment:\r\n      - REDIS_HOST=redis\r\n      - ROUTEX_CONFIG_PATH=config/gateway.docker.yaml\r\n      - ROUTEX_ROUTES_PATH=config/routes.docker.yaml\r\n    networks:\r\n      - app-net\r\n\r\n  redis:\r\n    image: redis:7-alpine\r\n    container_name: routex-redis\r\n    networks:\r\n      - app-net\r\n\r\n  my-user-service:\r\n    image: my-org/user-service:latest\r\n    container_name: my-user-service\r\n    networks:\r\n      - app-net\r\n```\r\n\r\nIn `config/routes.docker.yaml`, set:\r\n```yaml\r\nupstream: http://my-user-service:4001\r\n```\r\n\r\n#### Case 2: Services on an External Docker Network or Host\r\n\r\nIf your backend services are running in a separate Compose project or on the host machine:\r\n\r\n1. **Connect to an external Docker network**:\r\n   ```yaml\r\n   networks:\r\n     routex-net:\r\n       external: true\r\n       name: my-existing-backend-network\r\n   ```\r\n2. **Or access the host machine from Docker (Development only)**:\r\n   ```yaml\r\n   # In routes.docker.yaml (Windows / macOS Docker Desktop):\r\n   upstream: http://host.docker.internal:4001\r\n   ```\r\n\r\n---\r\n\r\n### Development vs Production Deployment\r\n\r\n| Consideration | Local Development | Cloud Production (Kubernetes / AWS ECS / VMs) |\r\n|---|---|---|\r\n| **Orchestration** | `docker compose up -d` | Kubernetes Deployment / ECS Task Definition / Docker Swarm |\r\n| **Ingress Point** | `http://localhost:8080` | Cloud Load Balancer (AWS ALB, Cloudflare, NGINX Ingress) |\r\n| **Redis** | Local container (`redis:7-alpine`) | Managed Redis Cluster (AWS ElastiCache, Redis Enterprise) |\r\n| **Secrets** | Local `.env` file | AWS Secrets Manager, HashiCorp Vault, Kubernetes Secrets |\r\n| **Health Checks** | Compose `healthcheck` on `/livez` | K8s Liveness (`/livez`) & Readiness (`/readyz`) probes |\r\n\r\n---\r\n\r\n### What Happens When My Application Sends a Request?\r\n\r\nWhen a client makes a request to `GET http://localhost:8080/api/v1/users/me`:\r\n\r\n1. **Correlation**: RouteX reads or generates `x-request-id` (e.g. `req_70b57b88-e765-406a...`) and initializes high-resolution nanosecond timers.\r\n2. **Route Resolution**: Matches `/api/v1/users/me` to the `user_service_api` route definition.\r\n3. **Tier-1 IP Rate Limiting**: Evaluates client IP quota in Redis. Rejects with 429 if the IP exceeded its limit.\r\n4. **Edge Authentication**: Validates the `Authorization: Bearer <JWT>` header using cryptographic signature verification (HS256/RS256). Rejects with 401 if missing, expired, or tampered.\r\n5. **RBAC Authorization**: Checks if user's roles satisfy the route's `requiredRoles`. Rejects with 403 if unauthorized.\r\n6. **Tier-2 Identity Rate Limiting**: Evaluates the authenticated user's tier (`free`, `premium`) in Redis.\r\n7. **Cache Check**: Computes SHA-256 cache key. If found in Redis, immediately returns cached payload with `x-cache: HIT`.\r\n8. **Circuit Breaker Check**: Verifies that the upstream `http://user-service:4001` circuit is `CLOSED`. If `OPEN`, fast-fails with 503 (`UPSTREAM_CIRCUIT_OPEN`).\r\n9. **SingleFlight Collapsing**: If multiple clients request the same uncached URL simultaneously, RouteX collapses them into a single upstream request.\r\n10. **Header Sanitization**: Strips client-forged headers (`x-user-id`, `x-user-roles`) and hop-by-hop headers (`Connection`, `Keep-Alive`). Injects verified identity headers.\r\n11. **Zero-Buffer Proxy Streaming**: Directly pipes response stream from upstream `user-service:4001` back to client without accumulating chunks in Node.js heap.\r\n12. **Observability & Caching**: Emits structured JSON access log with latency breakdown (`gatewayOverheadMs`, `upstreamLatencyMs`) and asynchronously caches response if eligible.\r\n\r\n---\r\n\r\n### Common Integration Mistakes & Gotchas\r\n\r\n1. **Using `localhost` instead of container service names**: Inside Docker, `http://localhost:4001` targets the gateway container itself. Always use `http://user-service:4001`.\r\n2. **Missing `stripPrefix` setting**: If your upstream expects `/users/me` instead of `/api/v1/users/me`, set `stripPrefix: true`.\r\n3. **Frontend calling microservices directly**: Ensure your frontend client base URL points to `http://localhost:8080` (RouteX) rather than direct backend ports.\r\n4. **Committing `.env` with secrets**: Keep `.env` gitignored; use environment injection in CI/CD.\r\n5. **Short JWT secrets**: RouteX requires HS256 secrets to be at least 32 characters long for cryptographic security.\r\n6. **Mismatched Docker networks**: If RouteX cannot reach your services, verify with `docker network inspect routex_routex-net` that all containers share the network.\r\n7. **Trusting client identity headers in backend services**: Backend services should read `x-user-id` injected by RouteX, but must ensure ingress from the gateway is protected.\r\n8. **Forgetting to rebuild after YAML changes**: If running in Docker, restart RouteX with `docker compose restart routex-gateway` to reload configuration.\r\n9. **Redis connectivity failure**: If Redis is unreachable and `failurePolicy: fail-closed`, rate limiting will reject requests. Set `failurePolicy: fail-open` if you prefer resilient pass-through during Redis degradation.\r\n10. **Unmatched HTTP methods**: If a route specifies `methods: [GET]`, a `POST` request will receive `405 Method Not Allowed` with an `Allow: GET` header.\r\n11. **Trailing slash in `pathPrefix`**: `pathPrefix` must not have a trailing slash (e.g. use `/api/v1/users`, not `/api/v1/users/`).\r\n12. **Assuming RouteX handles database business logic**: RouteX is an edge gateway and reverse proxy; your backend services continue to handle database transactions and application state.\r\n\r\n---\r\n\r\n### How to Add Another Backend Service\r\n\r\nTo add a new backend service (e.g. `Order Service` on port `4004`):\r\n\r\n#### 1. Add Route in `config/routes.docker.yaml`:\r\n```yaml\r\n  - id: order_service_api\r\n    pathPrefix: /api/v1/orders\r\n    upstream: http://order-service:4004\r\n    stripPrefix: false\r\n    methods: [GET, POST, PUT, DELETE]\r\n    auth:\r\n      mode: jwt\r\n      requiredRoles: [\"user\", \"admin\"]\r\n    rateLimit:\r\n      enabled: true\r\n      windowSec: 60\r\n      limit: 100\r\n    circuitBreaker:\r\n      enabled: true\r\n      failureThreshold: 5\r\n      resetTimeoutMs: 10000\r\n    timeouts:\r\n      connectTimeoutMs: 2000\r\n      responseTimeoutMs: 5000\r\n```\r\n\r\n#### 2. Add Service to `docker-compose.yml` (if managed locally):\r\n```yaml\r\n  order-service:\r\n    image: my-org/order-service:latest\r\n    container_name: routex-order-service\r\n    ports:\r\n      - \"4004:4004\"\r\n    networks:\r\n      - routex-net\r\n```\r\n\r\n#### 3. Restart RouteX:\r\n```bash\r\ndocker compose up -d\r\n```\r\n\r\n---\r\n\r\n### Client URLs vs Internal Upstream URLs\r\n\r\n```\r\n+─────────────────────────────────────────────────────────────────────────────+\r\n| CLIENT / PUBLIC FACING URL (Calls RouteX Port 8080)                         |\r\n|   https://api.yourdomain.com/api/v1/users/profile                           |\r\n|   http://localhost:8080/api/v1/users/profile                                |\r\n+──────────────────────────────────────┬──────────────────────────────────────+\r\n                                       │ (RouteX evaluates pathPrefix: /api/v1/users)\r\n                                       ▼\r\n+─────────────────────────────────────────────────────────────────────────────+\r\n| INTERNAL UPSTREAM URL (Dispatched by RouteX to Backend Service)             |\r\n|   http://user-service:4001/api/v1/users/profile                             |\r\n+─────────────────────────────────────────────────────────────────────────────+\r\n```\r\n\r\nClients never need to know internal hostnames, internal ports, or microservice topology.\r\n\r\n---\r\n\r\n### Authentication & Identity Integration\r\n\r\nRouteX supports four declarative route authentication modes:\r\n\r\n#### 1. `mode: public`\r\nNo authentication required. Ingress requests pass directly to upstream with Tier-1 IP rate limiting:\r\n```yaml\r\nauth:\r\n  mode: public\r\n```\r\n\r\n#### 2. `mode: jwt`\r\nRequires a valid `Authorization: Bearer <token>` header. RouteX verifies the cryptographic signature (HS256/RS256), expiration (`exp`), issuer (`iss`), and audience (`aud`):\r\n```yaml\r\nauth:\r\n  mode: jwt\r\n  requiredRoles: [\"admin\"]\r\n```\r\n\r\n#### 3. `mode: api-key`\r\nRequires a valid API key passed via `x-api-key` header:\r\n```yaml\r\nauth:\r\n  mode: api-key\r\n```\r\n\r\n#### 4. `mode: any`\r\nPermits access if either a valid JWT Bearer token or a valid API key is supplied:\r\n```yaml\r\nauth:\r\n  mode: any\r\n```\r\n\r\n##### Downstream Injected Headers\r\nUpon successful authentication, RouteX injects trusted headers:\r\n- `x-user-id`: Authenticated user ID (e.g. `usr_123`).\r\n- `x-user-roles`: Comma-separated list of roles (e.g. `admin,billing`).\r\n- `x-auth-type`: Authentication type (`jwt` or `api-key`).\r\n- `x-gateway-auth-status`: `authenticated`.\r\n\r\n---\r\n\r\n### Practical Guide: Rate Limiting, Caching & Circuit Breaking\r\n\r\n```\r\n+─────────────────────────────────────────────────────────────────────────────+\r\n|                        FEATURE SELECTION MATRIX                             |\r\n+────────────────────┬─────────────────────────────┬──────────────────────────+\r\n| Feature            | When to Enable              | Configuration Target     |\r\n+────────────────────┼─────────────────────────────┼──────────────────────────+\r\n| Rate Limiting      | Protect login endpoints,    | rateLimit:               |\r\n|                    | public APIs, and prevent    |   windowSec: 60          |\r\n|                    | abuse / DoS.                |   limit: 100             |\r\n+────────────────────┼─────────────────────────────┼──────────────────────────+\r\n| Response Caching   | Safe, idempotent GET APIs   | cache:                   |\r\n|                    | with high read volume and   |   enabled: true          |\r\n|                    | low change frequency.       |   ttlSec: 30             |\r\n+────────────────────┼─────────────────────────────┼──────────────────────────+\r\n| Circuit Breaker    | Protect gateway and healthy | circuitBreaker:          |\r\n|                    | services when an upstream   |   enabled: true          |\r\n|                    | encounters cascade failures.|   failureThreshold: 5    |\r\n+────────────────────┴─────────────────────────────┴──────────────────────────+\r\n```\r\n\r\n---\r\n\r\n### RouteX Integration Checklist\r\n\r\nBefore deploying your integrated application to production, verify:\r\n\r\n- [ ] RouteX repository cloned and built (`docker compose build`).\r\n- [ ] Backend service container names and ports verified.\r\n- [ ] `config/routes.docker.yaml` updated with all required route prefixes.\r\n- [ ] `config/gateway.docker.yaml` reviewed for timeouts and proxy CIDRs.\r\n- [ ] `.env` created from `.env.example` with strong production secrets.\r\n- [ ] `.env` is ignored by Git and not committed.\r\n- [ ] Docker network configured and shared across containers.\r\n- [ ] `/livez` probe returns `200 OK`.\r\n- [ ] `/readyz` probe returns `200 OK` (`router: ok`, `poolManager: ok`, `redis: ok`).\r\n- [ ] Public routes verified (`mode: public`).\r\n- [ ] Protected routes verified with valid JWT (`mode: jwt`).\r\n- [ ] Tampered/expired JWT verified to return `401 UNAUTHORIZED`.\r\n- [ ] Header spoofing verified (malicious client headers stripped).\r\n- [ ] Client/frontend base URL updated to RouteX port `8080`.\r\n\r\n---\r\n\r\n### What You Don't Need to Change\r\n\r\nWhen integrating RouteX into your stack, you do **NOT** need to write code for or modify:\r\n- Fastify server configuration or routing plugins.\r\n- Undici stream connection pool managers.\r\n- Cryptographic JWT verifiers or API-key constant-time comparison algorithms.\r\n- Redis Sliding Window Lua scripts.\r\n- SingleFlight mutex coalescing engine.\r\n- Circuit breaker state machines (`CLOSED` $\\rightarrow$ `OPEN` $\\rightarrow$ `HALF_OPEN`).\r\n- Header sanitization pipelines.\r\n\r\nAll functionality is driven declaratively through [`config/routes.docker.yaml`](file:///d:/RouteX/RouteX/config/routes.docker.yaml) and environment variables.\r\n\r\n---\r\n\r\n## Feature Matrix\r\n\r\n| Phase | Engine Area | Implementation Highlights |\r\n|---|---|---|\r\n| **Phase 1** | **Core Foundation** | Strict Zod configuration validation, standard JSON error envelopes, high-resolution nanosecond timing (`hrtime.bigint`), structured Pino logging, UUIDv4 request correlation. |\r\n| **Phase 2** | **Mock Ecosystem** | Mock User Service (port 4001) & Mock Chat Service (port 4002) supporting cryptographic JWT generation, chunked streaming payloads, delay injection, and fault simulations. |\r\n| **Phase 3** | **Zero-Buffer Proxy** | `ProxyRouter` longest-prefix route matching, `UpstreamPoolManager` Undici connection pooling with keep-alive, RFC 7230/9110 hop-by-hop header stripping, zero-buffer duplex streaming. |\r\n| **Phase 4** | **Auth & Identity** | Multi-mode route security (`public`, `jwt`, `api-key`, `any`), RS256/HS256 cryptographic JWT verification, constant-time API-key hash matching (`timingSafeEqual`), bounded LRU key cache, RBAC authorization, identity header propagation. |\r\n| **Phase 5** | **Distributed Rate Limiting** | Two-tier atomic Redis Sliding Window Log via custom Lua scripts (`EVALSHA` / `NOSCRIPT` fallback), Tier-1 IP protection, Tier-2 authenticated Identity limits, per-route subscription tiers (`free`, `premium`), `X-RateLimit-*` & `Retry-After` RFC-compliant headers. |\r\n| **Phase 6** | **Cache & Circuit Breaker** | Distributed Redis HTTP response caching, deterministic query-sorted cache keys, SingleFlight cache stampede protection (coalescing 50+ concurrent requests into 1 upstream fetch), per-origin Circuit Breaker state machine (`CLOSED` $\\rightarrow$ `OPEN` $\\rightarrow$ `HALF_OPEN`) with origin isolation. |\r\n| **Phase 7** | **Production Delivery** | Multi-stage production `Dockerfile`, `docker-compose.yml`, health probes (`/healthz`, `/livez`, `/readyz`), graceful socket draining, 15MB+ streaming memory verification (< 35MB growth), 300+ automated end-to-end acceptance tests. |\r\n| **Phase 8** | **Realtime Edge Integration** | Full RFC 6455 bidirectional WebSocket proxying, pre-101 connect-time failover across multi-node upstreams, active upstream /readyz health tracking & round-robin routing, edge rate limiting & JWT verification on upgrade, protocol/extension negotiation preservation, and half-duplex graceful connection draining. |\r\n\r\n---\r\n\r\n## Request Lifecycle Pipeline\r\n\r\nEvery request traversing RouteX undergoes a strict deterministic 10-step lifecycle:\r\n\r\n1. **Correlation & Timing**: A unique `x-request-id` is assigned or normalized, and a high-resolution timer (`startTime`) is initialized.\r\n2. **Route Resolution**: `ProxyRouter` evaluates the request URL against configured routes using longest-prefix matching. Returns 404 (`ROUTE_NOT_FOUND`) if unmatched, or 405 (`METHOD_NOT_ALLOWED`) with `Allow` header if method mismatch.\r\n3. **Tier-1 IP Rate Limiting**: Redis atomic sliding-window evaluates client IP limit. If exhausted, returns 429 (`TOO_MANY_REQUESTS`) with `Retry-After`.\r\n4. **Edge Authentication**: Validates credentials (JWT signature/expiration or API key hash). Populates trusted `AuthContext`.\r\n5. **RBAC Authorization**: Verifies `AuthContext.roles` satisfy route's `requiredRoles`. Rejects with 403 (`FORBIDDEN`) on mismatch.\r\n6. **Tier-2 Identity Rate Limiting**: Evaluates authenticated user ID or API key against tier quotas (`free`, `premium`, `enterprise`).\r\n7. **Response Cache Lookup**: For safe GET requests on cacheable routes, checks Redis for deterministic hashed key. On `HIT`, serves immediately with `age` and `x-cache: HIT`.\r\n8. **Upstream Circuit Breaker Check**: Verifies origin circuit breaker state. If `OPEN`, fast-fails immediately with 503 (`UPSTREAM_CIRCUIT_OPEN`) and `Retry-After`.\r\n9. **SingleFlight Stampede Protection & Forwarding**: Coalesces concurrent cache misses into a single upstream request. Sanitizes hop-by-hop headers and injects verified identity headers (`x-user-id`, `x-user-roles`, `x-auth-type`, `x-forwarded-*`).\r\n10. **Zero-Buffer Duplex Streaming**: Streams response body directly from Undici pool back to client socket without buffering in Node.js heap. Records circuit breaker latency and status codes.\r\n\r\n---\r\n\r\n## Quickstart Guide\r\n\r\n### Prerequisites\r\n- Node.js >= 20.0.0\r\n- Redis >= 6.2 (or Docker)\r\n\r\n### Local Development\r\n\r\n1. **Install Dependencies**:\r\n   ```bash\r\n   npm install\r\n   ```\r\n\r\n2. **Start Background Services (Redis & Mock Upstreams)**:\r\n   ```bash\r\n   # Terminal 1: Redis (if local)\r\n   redis-server\r\n\r\n   # Terminal 2: Mock User Service (Port 4001)\r\n   npm run start:user\r\n\r\n   # Terminal 3: Mock Chat Service (Port 4002)\r\n   npm run start:chat\r\n   ```\r\n\r\n3. **Start RouteX Gateway**:\r\n   ```bash\r\n   # Development mode (compiles TypeScript and runs standalone gateway)\r\n   npm run dev\r\n\r\n   # Or production mode (runs pre-compiled dist/src/bin/gateway.js)\r\n   npm start\r\n   ```\r\n   Gateway listens on `http://127.0.0.1:8080`.\r\n\r\n4. **Verify Liveness & Readiness**:\r\n   ```bash\r\n   curl http://127.0.0.1:8080/healthz\r\n   curl http://127.0.0.1:8080/readyz\r\n   ```\r\n\r\n---\r\n\r\n### Docker & Docker Compose\r\n\r\nDeploy the complete multi-container production topology with a single command:\r\n\r\n```bash\r\ndocker compose up --build -d\r\n```\r\n\r\nThe stack orchestrates:\r\n- `redis`: Redis 7 alpine container with persistent healthcheck probe.\r\n- `user-service`: Mock User Service on internal port 4001.\r\n- `chat-service`: Mock Chat Service on internal port 4002.\r\n- `routex-gateway`: Production-hardened Node.js Alpine container on port 8080 running as non-root user `node`.\r\n\r\n---\r\n\r\n## Configuration Reference\r\n\r\nRouteX is configured via declarative YAML (`config/gateway.config.yaml` or `config/gateway.docker.yaml`).\r\n\r\n```yaml\r\nserver:\r\n  port: 8080\r\n  host: 0.0.0.0\r\n  requestTimeoutMs: 10000\r\n  headersTimeoutMs: 11000\r\n  maxHeaderSize: 16384\r\n  logLevel: info\r\n  logFormat: json\r\n  trustedProxies:\r\n    - 127.0.0.1\r\n    - 10.0.0.0/8\r\n\r\nredis:\r\n  enabled: true\r\n  host: redis\r\n  port: 6379\r\n  db: 0\r\n  connectTimeoutMs: 3000\r\n  commandTimeoutMs: 2000\r\n  keyPrefix: \"routex:\"\r\n\r\nauth:\r\n  jwt:\r\n    enabled: true\r\n    algorithms: [\"HS256\", \"RS256\"]\r\n    hs256SecretEnv: JWT_SECRET\r\n  apiKeys:\r\n    enabled: true\r\n    cacheTtlMs: 60000\r\n    cacheMaxEntries: 1000\r\n    keys:\r\n      - id: key_prod_01\r\n        key: rx_live_9f83b2a1c4e7d0f2a6b8c9d1e3f5a7b9\r\n        userId: usr_enterprise_corp\r\n        roles: [\"admin\", \"api:write\"]\r\n        tier: premium\r\n\r\nroutes:\r\n  - id: users_service\r\n    pathPrefix: /api/v1/users\r\n    upstream: http://user-service:4001\r\n    stripPrefix: false\r\n    methods: [GET, POST, PUT, DELETE]\r\n    auth:\r\n      mode: jwt\r\n      requiredRoles: []\r\n    rateLimit:\r\n      enabled: true\r\n      windowSec: 60\r\n      limit: 100\r\n      ipLimit: 20\r\n      tiers:\r\n        free: 60\r\n        premium: 300\r\n    cache:\r\n      enabled: true\r\n      ttlSec: 60\r\n      maxBodyBytes: 1048576\r\n    circuitBreaker:\r\n      enabled: true\r\n      failureThreshold: 5\r\n      resetTimeoutMs: 10000\r\n      failureStatusCodes: [500, 502, 503, 504]\r\n    timeouts:\r\n      connectTimeoutMs: 1000\r\n      responseTimeoutMs: 5000\r\n```\r\n\r\n---\r\n\r\n## Operational Runbook\r\n\r\n### Health & Readiness Probes\r\n\r\nRouteX provides three dedicated endpoints for container orchestrators (Kubernetes, Docker, Nomad):\r\n\r\n| Endpoint | Probe Type | Verification Performed | Status Codes |\r\n|---|---|---|---|\r\n| `/livez` | **Liveness** | Verifies Gateway event loop is responsive, Node process uptime, and memory statistics. | `200 OK` |\r\n| `/readyz` | **Readiness** | Pings Redis connection, validates router & pool manager, checks shutdown state (`isShuttingDown`). | `200 OK` (Healthy) / `503 Service Unavailable` |\r\n| `/healthz` | **General** | Aggregated health overview including version and gateway state. | `200 OK` |\r\n\r\n### Graceful Shutdown & Socket Draining\r\n\r\nWhen receiving `SIGTERM` or `SIGINT`:\r\n1. `isShuttingDown` flag is flipped to `true`.\r\n2. `/readyz` immediately returns `503 Service Unavailable`, prompting load balancers to route new traffic away.\r\n3. Idle HTTP keep-alive connections are severed via `server.closeIdleConnections()`.\r\n4. In-flight requests are permitted to finish streaming within their timeout budget.\r\n5. Undici upstream pools and Redis connections are closed cleanly.\r\n\r\n### Structured Logging & Correlation\r\n\r\nAll ingress requests produce structured JSON logs with high-resolution latency breakdown:\r\n\r\n```json\r\n{\r\n  \"level\": \"info\",\r\n  \"time\": \"2026-08-30T13:11:19.460Z\",\r\n  \"name\": \"routex-gateway\",\r\n  \"type\": \"ACCESS_LOG\",\r\n  \"requestId\": \"req_38df0886-fa10-4b96-b67d-b7a93fe83254\",\r\n  \"method\": \"GET\",\r\n  \"url\": \"/api/v1/chats\",\r\n  \"statusCode\": 200,\r\n  \"routeId\": \"chat_service_api\",\r\n  \"totalDurationMs\": 9.779,\r\n  \"upstreamLatencyMs\": 5.11,\r\n  \"gatewayOverheadMs\": 4.669,\r\n  \"clientIp\": \"172.18.0.1\",\r\n  \"userAgent\": \"curl/8.21.0\",\r\n  \"cache_status\": \"BYPASS\",\r\n  \"circuit_state\": \"CLOSED\",\r\n  \"circuit_rejected\": false\r\n}\r\n```\r\n\r\n### Redis Fault Tolerance & Fail-Open Behavior\r\n\r\nWhen Redis encounters network partitions or connectivity loss:\r\n- `failurePolicy: \"fail-open\"` (default): Rate limiting permits traffic with a logged warning, preventing gateway outages caused by cache layer issues.\r\n- `failurePolicy: \"fail-closed\"`: Rate limiting rejects incoming traffic with 429 when strict financial quotas must be enforced.\r\n- Redis client implements bounded exponential reconnect backoff with error suppression to prevent unhandled process crashes.\r\n\r\n---\r\n\r\n## Security Model\r\n\r\n1. **Header Spoofing Prevention**: Downstream requests attempting to forge internal identity headers (`x-user-id`, `x-user-roles`, `x-auth-type`, `x-auth-claims`, `x-gateway-*`, `x-internal-*`) are unconditionally stripped.\r\n2. **RFC 7230/9110 Header Hygiene**: Standard and dynamic `Connection` nominated hop-by-hop headers are removed before upstream proxy dispatch.\r\n3. **CRLF Injection Neutralization**: All request and response header values are sanitized against carriage return (`\\r`) and newline (`\\n`) characters.\r\n4. **Constant-Time Key Matching**: API keys are hashed with SHA-256 and compared using `crypto.timingSafeEqual` to prevent side-channel timing attacks.\r\n5. **Cryptographic Algorithm Validation**: Rejects tokens using `alg: \"none\"` or unapproved algorithms.\r\n\r\n---\r\n\r\n## Performance & Streaming Memory Profiling\r\n\r\nRouteX enforces zero-buffer streaming across request upload and response download pipelines:\r\n\r\n- **Low Overhead**: Sub-millisecond median routing overhead (+0.04 ms p50 overhead).\r\n- **High Concurrency**: 700+ requests/sec at 50 concurrent connections in local benchmarks.\r\n- **Download Streaming Benchmark**: Streaming large payloads (15MB+) through RouteX yields less than **35MB** peak heap growth, proving that memory does not scale linearly with payload size.\r\n- **Upload Streaming Benchmark**: Multi-chunk request bodies are piped directly to upstream HTTP sockets via chunked transfer encoding.\r\n- **SingleFlight Stampede Coalescing**: 50 concurrent requests for an uncached URL collapse into exactly 1 upstream dispatch, eliminating backend database spikes.\r\n\r\n---\r\n\r\n## Troubleshooting Guide\r\n\r\n| Symptom | Probable Cause | Diagnostic & Resolution |\r\n|---|---|---|\r\n| `502 BAD_GATEWAY` | Upstream service down, wrong port, or `localhost` used in Docker. | Verify upstream service is running and listening. Inside Docker, use `http://service-name:port` instead of `localhost`. |\r\n| `504 GATEWAY_TIMEOUT` | Upstream latency exceeded `responseTimeoutMs`. | Check upstream performance or increase `timeouts.responseTimeoutMs` in `routes.docker.yaml`. |\r\n| `503 UPSTREAM_CIRCUIT_OPEN` | Consecutive failures exceeded `failureThreshold`. | Upstream has failed repeatedly. Inspect upstream logs. Breaker will automatically probe in `HALF_OPEN` after `resetTimeoutMs`. |\r\n| `429 TOO_MANY_REQUESTS` | IP or Identity rate limit window exhausted. | Inspect `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `Retry-After` headers. |\r\n| `401 UNAUTHORIZED` | Invalid JWT signature, expired token, or invalid API key. | Verify JWT secret/public key configuration or ensure API key format matches `rx_live_*`. |\r\n| `403 FORBIDDEN` | Authenticated identity lacks required RBAC roles. | Verify `authContext.roles` contains roles specified in `route.auth.requiredRoles`. |\r\n| `404 ROUTE_NOT_FOUND` | Path does not match any configured `pathPrefix`. | Verify route entry in `routes.docker.yaml` matches the incoming request path. |\r\n| `405 METHOD_NOT_ALLOWED` | HTTP method not declared in route's `methods` array. | Add the method (e.g. `POST`, `PUT`, `DELETE`) to the route's `methods` array. |\r\n\r\n---\r\n\r\n## Automated Verification Suite\r\n\r\nTo run the complete automated test suite (unit, integration, and E2E acceptance tests):\r\n\r\n```bash\r\n# Run all unit, integration, and E2E tests (42 suites, 321 tests)\r\nnpm test\r\n\r\n# Run tests with V8 code coverage report (>91.8% coverage)\r\nnpm run test:coverage\r\n\r\n# Run TypeScript strict type verification\r\nnpm run typecheck\r\n\r\n# Build production distribution bundle in dist/\r\nnpm run build\r\n```\r\n\r\n---\r\n\r\n## License\r\nMIT\r\n","readmeFilename":"README.md"}