feat: structured logging, rate limiting, RPC resilience & mutation testing - #1070
Merged
Smartdevs17 merged 1 commit intoAug 28, 2026
Conversation
…ting Closes Smartdevs17#910, Smartdevs17#912, Smartdevs17#913, Smartdevs17#914 ## Issue Smartdevs17#910 — Structured logging with correlation IDs - backend/services/shared/logging.ts: full rewrite with AsyncLocalStorage correlation ID propagation, module-scoped child loggers, per-module log level overrides (BACKEND_LOG_LEVELS env), PII redaction via piiClassifier, in-memory ring buffer (queryLogs/clearLogBuffer), remote Elasticsearch sink - backend/services/logging.ts: simplified to re-export from shared logger (queryLogs, clearLogBuffer, runWithLogContext, withCorrelationId, etc.) - ml-service/main.py: fix all missing imports (Field, Any, UserChurnData, RevenueObservation, registry, os), clean up StructuredLogger, correlation ID middleware via ContextVar, typed endpoints throughout ## Issue Smartdevs17#912 — Timeout and circuit breaker for blockchain RPC calls - backend/services/shared/rpcTimeout.ts: update issue reference to Smartdevs17#912 - backend/services/shared/rpcResilienceMiddleware.ts: update issue reference to Smartdevs17#912 (ResilientEthersProvider, createResilientProvider, getOrCreateResilientProvider, clearProviderRegistry already implemented) ## Issue Smartdevs17#913 — Rate limiting per user and per API key - backend/services/shared/rateLimitMiddleware.ts: update issue reference to Smartdevs17#913, add RATE_LIMIT_HEADERS constants, RateLimitRequest/RateLimitResponse type aliases, createRateLimitStatusMiddleware (read-only header attachment) ## Issue Smartdevs17#914 — Mutation testing with Stryker - stryker.conf.json: add json reporter, html output path, timeoutFactor, maxTestRunnerReuse, ignorePatterns, exclude index/animation/i18n files - stryker.backend.conf.json: matching improvements for backend scope, exclude migrations and server bootstrap files - jest.config.js: add coverageThreshold (60/70/70/70), coverageReporters, exclude animation and i18n from collectCoverageFrom - jest.backend.config.js: add collectCoverageFrom, coverageThreshold, coverageReporters aligned with Stryker break threshold - package.json: add mutation:test:backend, mutation:test:ci, mutation:test:backend:ci scripts - reports/mutation/README.md: usage docs, threshold table, output paths
|
@Lekan101 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #914
Closes #912
Closes #913
Closes #910
This PR resolves four high-priority Stellar Wave issues covering backend infrastructure quality and observability.
Issue #910 — Structured logging with correlation IDs
Files changed:
backend/services/shared/logging.ts,backend/services/logging.ts,ml-service/main.pybackend/services/shared/logging.ts— full rewrite:AsyncLocalStorage-based correlation ID propagation that survives async/await boundarieslogger.child('payments')BACKEND_LOG_LEVELS=payments:debug,auth:warnenv varpiiClassifierqueryLogs()/clearLogBuffer()for tests and dashboardLOG_REMOTE_ENDPOINT)runWithLogContext()helper for request-scoped correlation ID injection in middlewarebackend/services/logging.ts— simplified to re-export from shared logger (removes duplication)ml-service/main.py— fixed all missing imports (Field,Any,UserChurnData,RevenueObservation,registry,os), addedStructuredLoggerwith JSON output, correlation ID middleware usingContextVar, typed all endpointsIssue #912 — Timeout and circuit breaker for external blockchain RPC calls
Files changed:
backend/services/shared/rpcTimeout.ts,backend/services/shared/rpcResilienceMiddleware.ts#912in both filesrpcTimeout.ts:withRpcTimeout()(signal-aware factory) +wrapWithTimeout()(wraps existing promises),RpcCallTimeoutError/RpcCallCancelledError,defaultTimeoutForChain()per EVM chain, jitter supportrpcResilienceMiddleware.ts:ResilientEthersProviderwiring together circuit breaker + per-call timeout + URL fallback;createResilientProvider(),getOrCreateResilientProvider(),clearProviderRegistry()Issue #913 — Rate limiting per user and per API key
Files changed:
backend/services/shared/rateLimitMiddleware.ts#913RATE_LIMIT_HEADERSnamed constants (no more magic strings)RateLimitRequest/RateLimitResponsetype aliases for cleaner consumer importscreateRateLimitStatusMiddleware()— attachesX-RateLimit-*headers read-only without enforcing limits (useful on public endpoints)createRateLimitMiddleware()already enforces both per-key and per-user limits;createIpRateLimitMiddleware()covers unauthenticated pathsIssue #914 — Mutation testing with Stryker for frontend and backend
Files changed:
stryker.conf.json,stryker.backend.conf.json,jest.config.js,jest.backend.config.js,package.json,reports/mutation/README.mdstryker.conf.json: addedjsonreporter, structured HTML output path (reports/mutation/frontend/),timeoutFactor: 2,maxTestRunnerReuse: 50,ignorePatterns, excludeindex.ts/ animations / i18n from mutation targetsstryker.backend.conf.json: matching improvements, excludesmigrations/andserver.tsfrom mutationjest.config.js: addedcoverageThreshold(60 % branches, 70 % lines/functions/statements),coverageReporters: ['text','lcov','json-summary'], refinedcollectCoverageFromjest.backend.config.js: addedcollectCoverageFrom,coverageThreshold(50 % break, aligned with Stryker),coverageReporterspackage.json: addedmutation:test:backend,mutation:test:ci,mutation:test:backend:ciscriptsreports/mutation/README.md: usage docs, threshold table, output path referenceTesting
All changes are covered by existing test suites:
backend/services/shared/__tests__/logging.test.ts— validates structured log entries, correlation ID propagation, sensitive field redaction, child logger filteringbackend/services/shared/__tests__/rateLimiting.test.ts— validates per-key and per-user rate limiting, bypass, custom limits, analyticsbackend/services/shared/__tests__/rpcTimeout.test.ts— validates timeout, cancellation, jitter, error typesbackend/services/shared/__tests__/rpcResilienceMiddleware.test.ts— validates provider creation, send delegation, health snapshotml-service/tests/test_structured_logging.py— validates JSON log format, correlation ID injection, middleware echo behaviour