From f6b6478313b6e5c877f579e34c84b3f8ca1f37e2 Mon Sep 17 00:00:00 2001 From: ravendevhub Date: Sat, 29 Aug 2026 12:07:39 +0630 Subject: [PATCH] feat(api): add request id middleware with client header validation and tracing (#686) - Validate client-supplied X-Request-ID and X-Correlation-ID headers (alphanumeric/hyphens <= 64 chars) - Fallback to cryptographically random UUID generation on invalid/missing headers - Expose X-Request-ID and X-Correlation-ID in HTTP response headers - Attach validated IDs to request context for structured logging - Add unit test coverage and specification in docs/REQUEST_ID_MIDDLEWARE.md --- docs/REQUEST_ID_MIDDLEWARE.md | 35 ++++++ listener/src/middleware/request-id.test.ts | 69 +++++++++++ listener/src/middleware/request-id.ts | 60 +++++++++ listener/src/utils/request-id.test.ts | 134 +++++++++------------ listener/src/utils/request-id.ts | 58 ++++++--- 5 files changed, 263 insertions(+), 93 deletions(-) create mode 100644 docs/REQUEST_ID_MIDDLEWARE.md create mode 100644 listener/src/middleware/request-id.test.ts create mode 100644 listener/src/middleware/request-id.ts diff --git a/docs/REQUEST_ID_MIDDLEWARE.md b/docs/REQUEST_ID_MIDDLEWARE.md new file mode 100644 index 00000000..eafe3810 --- /dev/null +++ b/docs/REQUEST_ID_MIDDLEWARE.md @@ -0,0 +1,35 @@ +# 🆔 Request ID & Correlation Tracing Middleware + +This document specifies the Request ID tracing middleware for NotifyChain's API services (Issue #686). + +--- + +## 1. Overview + +To make requests traceable across distributed logs and debugging sessions: +1. Every incoming HTTP request resolves a validated `X-Request-ID`. +2. Client-provided `X-Request-ID` and `X-Correlation-ID` headers are validated against strict alphanumeric/hyphen constraints (`^[a-zA-Z0-9_-]{1,64}$`). +3. If valid, the client-provided ID is preserved; if missing or invalid, a secure unique ID is minted. +4. Both IDs are attached to the request context for logging and echoed in HTTP response headers. + +--- + +## 2. Header Contract + +| Header Name | Required | Behavior | +|---|---|---| +| `X-Request-ID` | Optional on Request | Validated client ID or minted UUID, echoed on response | +| `X-Correlation-ID` | Optional on Request | Multi-service trace ID, echoed on response | + +--- + +## 3. Usage & Integration + +```typescript +import { applyRequestContext } from '../utils/request-id'; + +export function handleHttpRequest(req: IncomingMessage, res: ServerResponse) { + const { requestId, correlationId } = applyRequestContext(req, res); + logger.info(`Received request`, { requestId, correlationId, url: req.url }); +} +``` diff --git a/listener/src/middleware/request-id.test.ts b/listener/src/middleware/request-id.test.ts new file mode 100644 index 00000000..aa3f7b57 --- /dev/null +++ b/listener/src/middleware/request-id.test.ts @@ -0,0 +1,69 @@ +import { IncomingMessage, ServerResponse } from 'http'; +import { attachRequestId, isValidRequestId, resolveRequestId } from './request-id'; + +describe('Request ID Middleware (Issue #686)', () => { + describe('isValidRequestId', () => { + test('accepts valid UUIDs and alphanumeric tokens', () => { + expect(isValidRequestId('c9bf9e57-1685-4c89-bafb-ff5af830be8a')).toBe(true); + expect(isValidRequestId('req-123456_abc')).toBe(true); + expect(isValidRequestId('simpleid')).toBe(true); + }); + + test('rejects empty, invalid characters or oversized IDs', () => { + expect(isValidRequestId('')).toBe(false); + expect(isValidRequestId(' ')).toBe(false); + expect(isValidRequestId('req