From 04db465ed136f53a6e42f3132a242a972b4b51de Mon Sep 17 00:00:00 2001 From: noevidence1017 Date: Wed, 24 Jun 2026 23:52:46 +0100 Subject: [PATCH 1/2] feat: add correlation ID middleware for request tracing --- .../middleware/correlation.js | 25 +++++++++++++++++++ stellar-payment-platform/package-lock.json | 17 ++++++++++++- stellar-payment-platform/package.json | 3 ++- stellar-payment-platform/server.js | 12 +++++++-- 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 stellar-payment-platform/middleware/correlation.js diff --git a/stellar-payment-platform/middleware/correlation.js b/stellar-payment-platform/middleware/correlation.js new file mode 100644 index 0000000..3e45be7 --- /dev/null +++ b/stellar-payment-platform/middleware/correlation.js @@ -0,0 +1,25 @@ +const { v4: uuidv4 } = require('uuid'); + +const CORRELATION_HEADER = 'X-Correlation-ID'; + +// #31 — Correlation ID middleware for end-to-end request tracing. +// Reuses an incoming X-Correlation-ID header when present, otherwise generates +// a fresh uuidv4. The ID is exposed on req.correlationId and echoed back on the +// response so callers and downstream services can stitch logs together. +const correlationId = (req, res, next) => { + const incoming = req.get(CORRELATION_HEADER); + const id = typeof incoming === 'string' && incoming.trim() ? incoming.trim() : uuidv4(); + + req.correlationId = id; + res.set(CORRELATION_HEADER, id); + + // Prefix request logs with the correlation ID so a single API call can be + // traced end-to-end across the backend's log output. + res.on('finish', () => { + console.log(`[Correlation ID: ${id}] ${req.method} ${req.originalUrl} ${res.statusCode}`); + }); + + next(); +}; + +module.exports = { correlationId, CORRELATION_HEADER }; diff --git a/stellar-payment-platform/package-lock.json b/stellar-payment-platform/package-lock.json index 7b1c84e..928c297 100644 --- a/stellar-payment-platform/package-lock.json +++ b/stellar-payment-platform/package-lock.json @@ -16,7 +16,8 @@ "generic-pool": "^3.9.0", "node-cron": "4.5.0", "pdfkit": "^0.15.2", - "sqlite3": "^5.1.7" + "sqlite3": "^5.1.7", + "uuid": "^9.0.1" }, "devDependencies": { "jest": "^29.7.0", @@ -6843,6 +6844,20 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", diff --git a/stellar-payment-platform/package.json b/stellar-payment-platform/package.json index 66b9584..1a8ce9d 100644 --- a/stellar-payment-platform/package.json +++ b/stellar-payment-platform/package.json @@ -19,7 +19,8 @@ "generic-pool": "^3.9.0", "node-cron": "4.5.0", "pdfkit": "^0.15.2", - "sqlite3": "^5.1.7" + "sqlite3": "^5.1.7", + "uuid": "^9.0.1" }, "devDependencies": { "jest": "^29.7.0", diff --git a/stellar-payment-platform/server.js b/stellar-payment-platform/server.js index d44d8c8..7906968 100644 --- a/stellar-payment-platform/server.js +++ b/stellar-payment-platform/server.js @@ -8,6 +8,7 @@ const sqlite3 = require('sqlite3').verbose(); const { Horizon } = require('@stellar/stellar-sdk'); const PDFDocument = require('pdfkit'); const { scheduleCleanupJob } = require('./src/cleanup-cron'); +const { correlationId } = require('./middleware/correlation'); const dotenv = require('dotenv'); dotenv.config(); @@ -41,6 +42,10 @@ const corsOptions = { optionsSuccessStatus: 204 }; +// #31 — Attach a correlation ID to every request before anything else runs so +// all downstream middleware, handlers and logs can reference the same trace. +app.use(correlationId); + app.use(cors(corsOptions)); app.use(express.json()); // #49 — Enforce strict 10kb JSON payload size limit to prevent DoS via oversized payloads @@ -562,11 +567,14 @@ app.use((err, req, res, next) => { if (statusCode === 500) { const errorId = crypto.randomUUID(); - console.error(`[Error ID: ${errorId}]`, err); + // #31 — Prefix error logs with the correlation ID so a single API call can + // be traced across every log line it produced. + console.error(`[Correlation ID: ${req.correlationId}] [Error ID: ${errorId}]`, err); return res.status(500).json({ success: false, error: 'Internal Server Error', - reference_id: errorId + reference_id: errorId, + correlation_id: req.correlationId }); } From e1dfd98e3eab328ed3b11345fd38b1a063ff8b71 Mon Sep 17 00:00:00 2001 From: noevidence1017 Date: Sat, 4 Jul 2026 00:46:33 +0100 Subject: [PATCH 2/2] fix: resolve merge conflicts in package.json and restore correlation import --- stellar-payment-platform/package-lock.json | 7 +------ stellar-payment-platform/package.json | 3 +-- stellar-payment-platform/server.js | 1 + 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/stellar-payment-platform/package-lock.json b/stellar-payment-platform/package-lock.json index 69a4fa9..4fe347d 100644 --- a/stellar-payment-platform/package-lock.json +++ b/stellar-payment-platform/package-lock.json @@ -25,6 +25,7 @@ "rate-limit-redis": "^4.2.0", "redis": "^4.7.0", "sqlite3": "^5.1.7", + "uuid": "^9.0.1", "xss": "^1.0.15" }, "devDependencies": { @@ -64,7 +65,6 @@ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -1154,7 +1154,6 @@ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz", "integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==", "license": "MIT", - "peer": true, "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -1962,7 +1961,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.38", "caniuse-lite": "^1.0.30001799", @@ -3248,7 +3246,6 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", "license": "MIT", - "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -3295,7 +3292,6 @@ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", "license": "MIT", - "peer": true, "engines": { "node": ">= 16" }, @@ -6256,7 +6252,6 @@ "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@prisma/config": "6.19.3", "@prisma/engines": "6.19.3" diff --git a/stellar-payment-platform/package.json b/stellar-payment-platform/package.json index d686b89..acb49fe 100644 --- a/stellar-payment-platform/package.json +++ b/stellar-payment-platform/package.json @@ -33,11 +33,10 @@ "generic-pool": "^3.9.0", "node-cron": "4.5.0", "pdfkit": "^0.15.2", - "sqlite3": "^5.1.7", - "uuid": "^9.0.1" "rate-limit-redis": "^4.2.0", "redis": "^4.7.0", "sqlite3": "^5.1.7", + "uuid": "^9.0.1", "xss": "^1.0.15" }, "devDependencies": { diff --git a/stellar-payment-platform/server.js b/stellar-payment-platform/server.js index 9b57c18..2c141d9 100644 --- a/stellar-payment-platform/server.js +++ b/stellar-payment-platform/server.js @@ -6,6 +6,7 @@ const RedisStore = require('rate-limit-redis'); const { createClient } = require('redis'); const { prisma } = require('./prismaClient'); const { scheduleCleanupJob } = require('./src/cleanup-cron'); +const { correlationId } = require('./middleware/correlation'); const Filter = require('bad-words'); const dotenv = require('dotenv'); const timeout = require('connect-timeout');