A NestJS-based e-commerce backend with feature flags, dual database support, and OpenTelemetry monitoring.
npm install
npm run build
npm run dev
The API will be available at http://localhost:3001/api
Copy env.example
to .env
and configure:
# Database
DATABASE_URL=./database.sqlite
# JWT
JWT_SECRET=your-jwt-secret
# Feature Flags
DEVCYCLE_SERVER_SDK_KEY=your-devcycle-server-key
DEVCYCLE_CLIENT_SDK_KEY=your-devcycle-client-key
# OpenTelemetry (Optional)
DYNATRACE_ENV_URL=your-dynatrace-url
DYNATRACE_API_TOKEN=your-dynatrace-token
USE_LOCAL_OTLP=false
LOCAL_OTLP_PORT=14499
The system comes with pre-configured test users:
Username | Password | Role | |
---|---|---|---|
admin |
admin@shopper.com | password |
admin |
user |
user@shopper.com | password |
user |
src/
βββ main.ts # Application bootstrap
βββ app.module.ts # Root module
βββ otelSetup.ts # OpenTelemetry configuration
βββ dynatraceOtelLogHook.ts # Feature flag tracing
βββ auth/ # Authentication & authorization
βββ users/ # User management
βββ products/ # Product catalog
βββ cart/ # Shopping cart
βββ orders/ # Order processing
βββ admin/ # Admin operations
βββ feature-flags/ # Feature flag service
βββ database/ # Database configuration & seeding
βββ entities/ # TypeORM entities
- Authentication: JWT-based auth with role guards
- Database: Dual SQLite/PostgreSQL support with TypeORM
- Feature Flags: DevCycle integration with OpenFeature
- Monitoring: OpenTelemetry with Dynatrace support
- API: RESTful endpoints with validation
The app uses DevCycle with OpenFeature for feature management:
- Setup: Configure
DEVCYCLE_SERVER_SDK_KEY
in environment - Usage: Inject
FeatureFlagService
into controllers/services - Methods:
getBooleanValue(userId, key, defaultValue)
getStringValue(userId, key, defaultValue)
getNumberValue(userId, key, defaultValue)
getObjectValue(userId, key, defaultValue)
Flag Key | Type | Purpose | Default | Usage |
---|---|---|---|---|
use-neon |
Boolean | Controls database routing - when true , reads from PostgreSQL (Neon), when false reads from SQLite |
false |
Database abstraction layer for gradual migration |
new-flow |
Boolean | Enables intentional error generation for metric tracking - throws 500 error in 10% of product API calls | false |
Error monitoring and alerting system validation |
// Database routing flag (currently implemented)
const useNeon = await this.featureFlagService.getBooleanValue(
userId,
"use-neon",
false
)
// Error tracking flag (currently implemented)
const isNewFlowEnabled = await this.featureFlagService.getBooleanValue(
userId,
"new-flow",
false
)
// Generic pattern for new flags
const isFeatureEnabled = await this.featureFlagService.getBooleanValue(
userId,
"feature-flag-key",
false
)
The use-neon
flag enables a dual-database architecture:
- Write Operations: Always write to both SQLite AND PostgreSQL
- Read Operations: Route based on feature flag per user
false
(default): Read from SQLite (existing users)true
: Read from PostgreSQL/Neon (migrated users)
- Benefits: Zero-downtime database migration, A/B testing database performance
The new-flow
flag enables intentional error generation for monitoring validation:
- Purpose: Validates that error tracking, monitoring, and alerting systems are working correctly
- Behavior: When enabled, throws HTTP 500 errors randomly in 10% of GET /api/products calls
- Error Details:
- Error Type:
InternalServerErrorException
- Message: "Service temporarily unavailable - new flow processing error"
- Logging: Includes user ID and random value for debugging
- Error Type:
- API Documentation: Swagger/OpenAPI docs show potential 500 responses
- Benefits: Ensures observability tools capture and alert on real production errors
# Standard development
npm run dev
# With OpenTelemetry (Dynatrace)
npm run dev:otel
# With local OTLP collector
npm run dev:local-otlp
# Standard production
npm run start:prod
# With OpenTelemetry
npm run start:prod:otel
npm run start:prod:local-otlp
- Standard Backend (No OpenTelemetry)
- Backend with OpenTelemetry (Dynatrace)
- Backend with Local OTLP
# Start standard backend
pm2 start ecosystem.config.js --only shopper-backend
# Start with OpenTelemetry (Dynatrace)
pm2 start ecosystem.config.js --only shopper-backend-otel
# Start with local OTLP collector
pm2 start ecosystem.config.js --only shopper-backend-local-otlp
# View logs
pm2 logs shopper-backend
pm2 logs shopper-backend-otel
# Monitor
pm2 monit
# Restart
pm2 restart shopper-backend
# Stop
pm2 stop shopper-backend
# View all processes
pm2 list
Before deployment, update ecosystem.config.js
:
- Set correct
cwd
path - Configure environment variables
- Update database URLs
- Set proper API keys
POST /api/auth/register
- User registrationPOST /api/auth/login
- User login
GET /api/products
- List all productsGET /api/products/:id
- Get product detailsPOST /api/products
- Create product (admin)PUT /api/products/:id
- Update product (admin)
GET /api/cart
- Get user cartPOST /api/cart/add
- Add item to cartPUT /api/cart/update/:id
- Update cart itemDELETE /api/cart/remove/:id
- Remove from cart
GET /api/orders
- Get user ordersPOST /api/orders
- Create orderGET /api/orders/:id
- Get order details
GET /api/admin/users
- List all users (admin)GET /api/admin/orders
- List all orders (admin)
# Install dependencies
npm install
# Run in development mode
npm run dev
# Run with file watching
npm run start:debug
# Type checking
npm run type-check
# Linting
npm run lint
npm run lint:fix
# Formatting
npm run format
npm run format:check
# Run all checks
npm run check-all
# Unit tests
npm run test
# Test with coverage
npm run test:cov
# Watch mode
npm run test:watch
# E2E tests
npm run test:e2e
PM2 logs are organized by service:
- Standard:
logs/out.log
,logs/err.log
- OpenTelemetry:
logs/otel-out.log
,logs/otel-err.log
- Local OTLP:
logs/local-otlp-out.log
,logs/local-otlp-err.log
The app supports dual database configuration:
- SQLite: For development and testing
- PostgreSQL: For production
Database is automatically seeded with sample data on startup.
- Module not found: Run
npm install
- Database errors: Check
DATABASE_URL
in.env
- Port conflicts: Change
PORT
in environment - Feature flag errors: Verify
DEVCYCLE_SERVER_SDK_KEY
- OpenTelemetry issues: Check OTLP collector status
npm run start:debug
Access debugger at chrome://inspect
in Chrome.