This document summarizes the completed implementation of comprehensive request/response logging with correlation IDs and a feature flags system for Nestera.
Backend (NestJS):
-
Correlation ID Middleware (
src/common/middleware/correlation-id.middleware.ts)- ✅ Generates or accepts
X-Correlation-IDheaders - ✅ Attaches to
req.correlationIdfor downstream use - ✅ Echoes back in response headers for distributed tracing
- ✅ Records request start time for duration calculation
- ✅ Generates or accepts
-
Correlation ID Interceptor (
src/common/interceptors/correlation-id.interceptor.ts)- ✅ Safety net ensuring correlation IDs exist
- ✅ Augments pino logger context
-
Request Logging Interceptor (
src/common/interceptors/request-logging.interceptor.ts)- ✅ Logs incoming requests: method, URL, IP, user agent, user ID, masked wallet address
- ✅ Logs outgoing responses: status code, duration, content length
- ✅ Logs errors: stack traces (server errors only), error name, message
- ✅ Skips noisy paths:
/api/health,/api/metrics,/favicon.ico - ✅ Uses pino for structured JSON logs
- ✅ Integrated with APM service: tracks HTTP requests and errors
-
Log Sanitizer Service (
src/common/services/log-sanitizer.service.ts)- ✅ Redacts sensitive headers:
Authorization,Cookie,X-API-Key - ✅ Redacts sensitive body fields:
password,secret,token,privateKey,mnemonic,seedPhrase - ✅ Detects and redacts Stellar secret keys:
S[A-Z2-7]{55} - ✅ Truncates long values to 500 chars
- ✅ Masks wallet addresses to first 6 + last 4 chars
- ✅ Redacts sensitive headers:
-
Pino Configuration (
src/app.module.ts)- ✅ Correlation ID injection via
customProps - ✅ Automatic redaction of sensitive fields
- ✅ Structured serializers for req/res/err
- ✅ Pretty printing in dev with
pino-pretty - ✅ JSON logs in production
- ✅ File-based log retention: configurable via
LOG_DIRandLOG_RETENTION_DAYSenv vars
- ✅ Correlation ID injection via
-
APM Integration (
src/modules/apm/)- ✅
ApmService: tracks HTTP requests, errors, database queries, user events - ✅
MetricsService: Prometheus-compatible metrics (counters, histograms, gauges) - ✅
DistributedTracingService: W3C Trace Context support, span tracking - ✅
ApmInterceptor: distributed tracing withtraceparentheaders - ✅ Wired into
RequestLoggingInterceptorfor automatic tracking
- ✅
Frontend (Next.js):
-
Monitoring Library (
app/lib/monitoring.ts)- ✅ Lightweight wrapper around Sentry (CDN-loaded)
- ✅ Privacy-compliant: never captures passwords, private keys, raw addresses
- ✅ Tracks breadcrumbs, user context, API errors, wallet errors
- ✅ Gracefully no-ops when Sentry DSN not configured
-
MonitoringProvider (
app/components/MonitoringProvider.tsx)- ✅ Injects Sentry via
Scriptcomponent - ✅ Initializes global error and unhandled rejection handlers
- ✅ Tracks navigation as breadcrumbs
- ✅ Attaches privacy-safe wallet user context (truncated address + network)
- ✅ Injects Sentry via
Backend logs:
{
"msg": "→ POST /api/v2/auth/login",
"type": "REQUEST",
"correlationId": "a1b2c3d4-...",
"method": "POST",
"url": "/api/v2/auth/login",
"ip": "192.168.1.100",
"timestamp": "2026-06-02T10:15:30.123Z"
}APM dashboard:
- Visit
/api/apm/dashboard(authenticated) for metrics, errors, traces - Visit
/api/apm/metricsfor Prometheus-compatible metrics
Frontend error tracking:
import { captureApiError, trackUserAction } from "@/lib/monitoring";
// Track API errors
captureApiError(error, "/api/v2/savings/goals", 500, "POST");
// Track user actions
trackUserAction("savings_goal_created", { amount: 1000, currency: "USDC" });Backend .env:
LOG_DIR=/var/log/nestera # Optional: file-based logging
LOG_RETENTION_DAYS=30 # Log retention policy
APM_SAMPLING_RATE=1.0 # Distributed tracing sampling (0.0-1.0)Frontend .env:
NEXT_PUBLIC_SENTRY_DSN=https://...@sentry.io/...
NEXT_PUBLIC_SENTRY_ENVIRONMENT=production
NEXT_PUBLIC_SENTRY_RELEASE=v1.2.3Backend (NestJS):
-
Feature Flag Module (
src/modules/feature-flags/)- ✅ Entity (
entities/feature-flag.entity.ts): TypeORM entity with full flag config - ✅ Service (
feature-flags.service.ts): CRUD operations + evaluation logic - ✅ Controller (
feature-flags.controller.ts): REST API endpoints - ✅ DTOs (
dto/create-flag.dto.ts,dto/update-flag.dto.ts): validation schemas - ✅ Migration (
migrations/1775300000000-CreateFeatureFlagsTable.ts): database schema
- ✅ Entity (
-
API Endpoints:
- ✅
GET /api/v2/feature-flags— fetch all flags (public) - ✅
GET /api/v2/feature-flags/:key/evaluate— evaluate flag for user context (public) - ✅
GET /api/v2/feature-flags/:key— get single flag (admin) - ✅
POST /api/v2/feature-flags— create flag (admin) - ✅
PUT /api/v2/feature-flags/:key— update flag (admin) - ✅
PATCH /api/v2/feature-flags/:key/toggle— toggle flag (admin) - ✅
DELETE /api/v2/feature-flags/:key— delete flag (admin)
- ✅
-
Evaluation Logic:
- ✅ Kill switches (force disable)
- ✅ User targeting (wallet address)
- ✅ Network targeting (public/testnet)
- ✅ Segment targeting (beta_tester, internal)
- ✅ Percentage rollout (consistent hashing)
Frontend (Next.js):
-
Feature Flag Engine (
app/lib/feature-flags.ts)- ✅ Flag types: boolean, string, number, rollout
- ✅ Targeting rules: users, networks, segments, rollout percentage
- ✅ Kill switches
- ✅ LocalStorage cache + API sync
- ✅ Privacy-safe hashing for A/B bucketing
- ✅ Tracks flag evaluations as monitoring breadcrumbs
-
Configuration (
app/lib/flags.config.ts)- ✅ Default flags seeded on first load
- ✅ 10+ predefined flags (dashboard, charts, wallet, A/B tests, kill switches, beta features)
-
Context Provider (
app/context/FeatureFlagContext.tsx)- ✅ State management for flags and loading state
- ✅ Admin functions: toggle, update, create, delete
- ✅ User context syncing for targeting (wallet address, network)
- ✅ Automatic merging of defaults with API-loaded and cached flags
-
Hooks (
app/hooks/useFeatureFlag.ts)- ✅
useFeatureFlag(key)— boolean flags - ✅
useFeatureFlagValue<T>(key)— multivariate flags - ✅
useFeatureFlagMany(keys)— batch check
- ✅
-
Admin UI (
app/components/FeatureFlagAdmin.tsx)- ✅ Slide-in panel accessible via TopNav flag icon (dev mode only)
- ✅ Search, filter by tag (all/enabled/disabled/kill_switch/experiment/beta)
- ✅ Live toggle, rollout percentage slider, kill switch controls
- ✅ Create/delete flags at runtime
Component usage:
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
export default function Dashboard() {
const { isEnabled, isLoading } = useFeatureFlag("new-dashboard-layout");
if (isLoading) return <Skeleton />;
if (isEnabled) return <NewDashboard />;
return <OldDashboard />;
}Multivariate flags:
const { value } = useFeatureFlagValue<string>("ab-cta-button-color");
// value === "teal" | "green"Admin UI:
- Open dashboard → Click flag icon in TopNav (dev mode)
- Toggle flags, adjust rollout percentages, create new flags
Backend .env:
# No additional config required.
# Flags are stored in the database.Frontend .env:
NEXT_PUBLIC_API_URL=https://api.nestera.io # For flag API syncRun the migration to create the feature_flags table:
cd backend
npm run typeorm migration:run- ✅ Correlation ID middleware implemented
- ✅ All incoming requests logged with metadata
- ✅ All outgoing responses logged
- ✅ Integrated with APM service
- ✅ Log retention policies configurable
- ✅ Log sanitization for sensitive data
- ✅ Feature flag system implemented
- ✅ Flags can be toggled without deployment
- ✅ User-based targeting works
- ✅ Flag state persists correctly
- ✅ Admin UI for managing flags
- ✅ Flag analytics tracked
- ✅ Documentation for developers
- ✅ No performance impact (caching, efficient evaluation)
- Logging: See
LOGGING_IMPLEMENTATION.mdfor detailed backend logging architecture - Feature Flags: See
FEATURE_FLAGS_IMPLEMENTATION.mdfor frontend flag system - APM: Visit
/api/v2/docsand look for the "APM" tag - Feature Flags API: Visit
/api/v2/docsand look for the "Feature Flags" tag
-
Logging:
- All sensitive fields automatically redacted before logging
- Wallet addresses masked to first 6 + last 4 chars
- Stack traces only logged for server errors (not client errors)
- Correlation IDs are UUIDs, not predictable
-
Feature Flags:
- Public endpoints (
GET /feature-flags) return non-sensitive config only - Admin endpoints (
POST,PUT,DELETE) require JWT authentication - User targeting uses truncated wallet addresses (first 10 chars) for privacy
- Rollout bucketing uses one-way hashing (consistent but not reversible)
- Public endpoints (
Backend:
cd backend
# Test correlation IDs
curl -H "X-Correlation-ID: test-123" http://localhost:3001/api/health
# Response includes: X-Correlation-ID: test-123
# Fetch feature flags
curl http://localhost:3001/api/v2/feature-flags
# Evaluate a flag
curl "http://localhost:3001/api/v2/feature-flags/new-dashboard-layout/evaluate?address=GABCD...&network=public"Frontend:
- Open dashboard
- Click flag icon in TopNav (dev mode)
- Toggle a flag → see changes reflected immediately
- Check browser console → Sentry breadcrumbs logged
Logging:
- ✅ Full distributed tracing with correlation IDs
- ✅ Structured JSON logs with automatic sanitization
- ✅ APM integration with metrics, errors, and traces
- ✅ File-based log retention configurable
- ✅ Sentry monitoring on frontend
Feature Flags:
- ✅ Runtime toggles without deployment
- ✅ User-based, network-based, segment-based targeting
- ✅ A/B testing with percentage rollouts
- ✅ Kill switches for emergency disabling
- ✅ LocalStorage + API sync for persistence
- ✅ Admin UI for flag management
- ✅ Complete API for backend flag control
Both systems are production-ready, privacy-compliant, and fully integrated with the existing Nestera architecture.