Skip to content

feat: structured logging, rate limiting, RPC resilience & mutation testing - #1070

Merged
Smartdevs17 merged 1 commit into
Smartdevs17:mainfrom
Lekan101:feat/logging-ratelimit-circuitbreaker-mutation-testing
Aug 28, 2026
Merged

feat: structured logging, rate limiting, RPC resilience & mutation testing#1070
Smartdevs17 merged 1 commit into
Smartdevs17:mainfrom
Lekan101:feat/logging-ratelimit-circuitbreaker-mutation-testing

Conversation

@Lekan101

@Lekan101 Lekan101 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

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.py

  • backend/services/shared/logging.ts — full rewrite:
    • AsyncLocalStorage-based correlation ID propagation that survives async/await boundaries
    • Module-scoped child loggers via logger.child('payments')
    • Per-module log-level overrides via BACKEND_LOG_LEVELS=payments:debug,auth:warn env var
    • PII field redaction through piiClassifier
    • In-memory ring buffer with queryLogs() / clearLogBuffer() for tests and dashboard
    • Elasticsearch remote sink + optional HTTP endpoint (LOG_REMOTE_ENDPOINT)
    • runWithLogContext() helper for request-scoped correlation ID injection in middleware
  • backend/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), added StructuredLogger with JSON output, correlation ID middleware using ContextVar, typed all endpoints

Issue #912 — Timeout and circuit breaker for external blockchain RPC calls

Files changed: backend/services/shared/rpcTimeout.ts, backend/services/shared/rpcResilienceMiddleware.ts

  • Updated issue references to #912 in both files
  • rpcTimeout.ts: withRpcTimeout() (signal-aware factory) + wrapWithTimeout() (wraps existing promises), RpcCallTimeoutError / RpcCallCancelledError, defaultTimeoutForChain() per EVM chain, jitter support
  • rpcResilienceMiddleware.ts: ResilientEthersProvider wiring 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

  • Updated issue reference to #913
  • Added RATE_LIMIT_HEADERS named constants (no more magic strings)
  • Added RateLimitRequest / RateLimitResponse type aliases for cleaner consumer imports
  • Added createRateLimitStatusMiddleware() — attaches X-RateLimit-* headers read-only without enforcing limits (useful on public endpoints)
  • Existing createRateLimitMiddleware() already enforces both per-key and per-user limits; createIpRateLimitMiddleware() covers unauthenticated paths

Issue #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.md

  • stryker.conf.json: added json reporter, structured HTML output path (reports/mutation/frontend/), timeoutFactor: 2, maxTestRunnerReuse: 50, ignorePatterns, exclude index.ts / animations / i18n from mutation targets
  • stryker.backend.conf.json: matching improvements, excludes migrations/ and server.ts from mutation
  • jest.config.js: added coverageThreshold (60 % branches, 70 % lines/functions/statements), coverageReporters: ['text','lcov','json-summary'], refined collectCoverageFrom
  • jest.backend.config.js: added collectCoverageFrom, coverageThreshold (50 % break, aligned with Stryker), coverageReporters
  • package.json: added mutation:test:backend, mutation:test:ci, mutation:test:backend:ci scripts
  • reports/mutation/README.md: usage docs, threshold table, output path reference

Testing

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 filtering
  • backend/services/shared/__tests__/rateLimiting.test.ts — validates per-key and per-user rate limiting, bypass, custom limits, analytics
  • backend/services/shared/__tests__/rpcTimeout.test.ts — validates timeout, cancellation, jitter, error types
  • backend/services/shared/__tests__/rpcResilienceMiddleware.test.ts — validates provider creation, send delegation, health snapshot
  • ml-service/tests/test_structured_logging.py — validates JSON log format, correlation ID injection, middleware echo behaviour

…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
@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@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! 🚀

Learn more about application limits

@Smartdevs17
Smartdevs17 merged commit b204565 into Smartdevs17:main Aug 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants