A production-ready authentication and post scheduling system built with Node.js, TypeScript, Express, MongoDB, and Bull job queues. Features enterprise-grade rate limiting, API versioning, queue monitoring, analytics tracking, and comprehensive documentation.
This project follows a layered architecture with clear separation of concerns:
routes β controllers β services β models β database
- Thin Controllers: Controllers only handle HTTP concerns (request/response)
- Service Layer: All business logic lives in services
- Model Layer: Database operations and schema definitions
- Middleware Pipeline: Authentication, validation, rate limiting, and error handling
- Dependency Direction: Unidirectional flow prevents circular dependencies
- Type Safety: Strict TypeScript with no
anytypes
production-auth-api/
βββ src/
β βββ config/ # Configuration and environment validation
β β βββ database.ts
β β βββ env.ts
β β βββ redis.ts
β β βββ swagger.ts
β βββ models/ # Mongoose schemas and data models
β β βββ User.model.ts
β β βββ Post.model.ts
β β βββ ApiUsage.model.ts
β βββ services/ # Business logic layer
β β βββ auth.service.ts
β β βββ post.service.ts
β β βββ queue.service.ts
β β βββ analytics.service.ts
β β βββ rateLimit.service.ts
β βββ controllers/ # HTTP request handlers (thin)
β β βββ auth.controller.ts
β β βββ post.controller.ts
β β βββ queue.controller.ts
β β βββ analytics.controller.ts
β βββ routes/ # Route definitions
β β βββ v1/
β β β βββ auth.routes.ts
β β β βββ post.routes.ts
β β β βββ index.ts
β β βββ v2/
β β β βββ index.ts
β β βββ admin.routes.ts
β β βββ index.ts
β βββ middleware/ # Reusable middleware
β β βββ auth.middleware.ts
β β βββ authorize.middleware.ts
β β βββ validate.middleware.ts
β β βββ errorHandler.middleware.ts
β β βββ rateLimit.middleware.ts
β β βββ analytics.middleware.ts
β β βββ apiVersion.middleware.ts
β βββ queues/ # Bull queue setup
β β βββ post.queue.ts
β βββ workers/ # Background job processors
β β βββ post.worker.ts
β βββ utils/ # Framework-agnostic utilities
β β βββ asyncHandler.util.ts
β β βββ errors.util.ts
β β βββ jwt.util.ts
β β βββ logger.util.ts
β β βββ rateLimitStore.util.ts
β βββ types/ # TypeScript type definitions
β β βββ express.d.ts
β β βββ post.types.ts
β β βββ analytics.types.ts
β βββ app.ts # Express application setup
β βββ server.ts # API server entry point
β βββ worker.ts # Worker process entry point
βββ tests/ # Integration tests
β βββ auth.test.ts
β βββ post.test.ts
β βββ rateLimit.test.ts
β βββ versioning.test.ts
β βββ admin.test.ts
β βββ analytics.test.ts
β βββ setup.ts
βββ .env.example
βββ .eslintrc.js
βββ .gitignore
βββ .prettierrc
βββ jest.config.js
βββ package.json
βββ tsconfig.json
βββ README.md
- User Registration with email validation and password strength requirements
- User Login with secure credential verification
- JWT Authentication with Bearer token support
- Role-Based Authorization (user/admin roles)
- Timing attack prevention
- No account enumeration
- Create Posts as draft or scheduled for future publishing
- Schedule Posts with automatic publishing via job queue
- Update Posts with intelligent rescheduling
- Delete Posts with automatic job cleanup
- Multi-Platform Support (Twitter, LinkedIn, Facebook)
- Background Worker processes scheduled posts automatically
- Redis-backed rate limiting (distributed, survives restart)
- API Limiter: 100 requests/hour per IP
- User Limiter: 100 requests/hour per authenticated user
- Auth Limiter: 5 attempts/15min (brute force protection)
- Strict Limiter: 10 requests/hour for admin operations
- Rate limit headers in all responses
- Graceful degradation (fails open if Redis unavailable)
- Clean v1/v2 route structure
- v1: Stable, production API
- v2: Placeholder (returns 501 Not Implemented)
- Backward compatibility guaranteed
- View queue statistics (waiting, active, completed, failed, delayed)
- List jobs by status
- Pause/resume queue processing
- Clean old completed jobs
- Retry failed jobs
- Persistent analytics storage (MongoDB with 90-day TTL)
- Response time tracking for every request
- System-wide statistics
- Per-endpoint metrics
- Per-user analytics
- Error rate analysis
- Performance percentiles (p50, p95, p99)
- Date range filtering
- Bull Job Queue with Redis for reliable background processing
- Retry Logic with exponential backoff (3 attempts)
- Job Persistence survives server restarts
- Global Error Handling with custom error classes
- Request ID Tracking using UUID for debugging
- Structured Logging with Winston
- Input Validation using express-validator
- Security Headers with Helmet
- API Documentation with Swagger/OpenAPI
- Runtime: Node.js 18+
- Language: TypeScript (strict mode)
- Framework: Express.js
- Database: MongoDB with Mongoose
- Cache/Queue: Redis with Bull
- Authentication: JWT (jsonwebtoken)
- Validation: express-validator, Zod
- Security: bcryptjs, helmet, cors
- Rate Limiting: express-rate-limit
- Logging: Winston
- Documentation: Swagger UI, swagger-jsdoc
- Date Utilities: date-fns
- Testing: Jest, Supertest, MongoDB Memory Server
- Clone the repository:
git clone https://github.com/27manavgandhi/buffer-api-demo.git
cd buffer-api-demo- Install dependencies:
npm install- Create environment file:
cp .env.example .env-
Configure environment variables (see Configuration section)
-
Start MongoDB (if running locally):
mongod- Start Redis (if running locally):
redis-serverCreate a .env file with the following variables:
PORT=3000
MONGODB_URI=mongodb://localhost:27017/auth_db
JWT_SECRET=your-super-secret-jwt-key-minimum-32-characters-long
JWT_EXPIRES_IN=7d
NODE_ENV=development
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=PORT: Server port numberMONGODB_URI: MongoDB connection string (must be valid URL)JWT_SECRET: Minimum 32 characters for securityJWT_EXPIRES_IN: Token expiration (e.g., "7d", "24h", "30m")NODE_ENV: Environment mode (development/production/test)REDIS_HOST: Redis server hostREDIS_PORT: Redis server portREDIS_PASSWORD: Redis password (optional)
Note: The application validates all environment variables at startup and fails fast if any are missing or invalid.
Terminal 1 - API Server:
npm run devTerminal 2 - Worker Process:
npm run dev:workernpm run build
# Terminal 1
npm start
# Terminal 2
npm run start:workernpm testnpm run lint
npm run lint:fixnpm run formathttp://localhost:3000/api
GET /healthResponse:
{
"status": "healthy",
"timestamp": "2025-01-14T10:30:00.000Z"
}GET /api-docsVisit this URL in your browser for interactive Swagger UI documentation.
POST /api/v1/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "Password123"
}Requirements:
- Email: Valid email format
- Password: Min 8 chars, at least one uppercase, one lowercase, one number
Success Response (201):
{
"success": true,
"data": {
"user": {
"id": "507f1f77bcf86cd799439011",
"email": "user@example.com",
"role": "user",
"createdAt": "2025-01-14T10:30:00.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}Rate Limit: 5 requests per 15 minutes
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "Password123"
}Rate Limit: 5 requests per 15 minutes
GET /api/v1/auth/me
Authorization: Bearer <token>Rate Limit: 100 requests per hour (per user)
POST /api/v1/posts
Authorization: Bearer <token>
Content-Type: application/json
{
"content": "Hello world! This is my first scheduled post.",
"platform": "twitter",
"scheduledAt": "2025-01-15T15:00:00.000Z"
}Platforms: twitter, linkedin, facebook
Status Values: draft, scheduled, published, failed
Rate Limit: 100 requests per hour (per user)
GET /api/v1/posts?page=1&limit=10
Authorization: Bearer <token>GET /api/v1/posts/:id
Authorization: Bearer <token>PUT /api/v1/posts/:id
Authorization: Bearer <token>
Content-Type: application/json
{
"content": "Updated content",
"scheduledAt": "2025-01-16T12:00:00.000Z"
}Note: Cannot update published posts
DELETE /api/v1/posts/:id
Authorization: Bearer <token>GET /api/admin/queue/stats
Authorization: Bearer <admin-token>Response:
{
"success": true,
"data": {
"waiting": 5,
"active": 2,
"completed": 150,
"failed": 3,
"delayed": 10,
"paused": false,
"total": 170
}
}GET /api/admin/queue/jobs?status=waiting&limit=10
Authorization: Bearer <admin-token>Valid statuses: waiting, active, completed, failed, delayed
POST /api/admin/queue/pause
Authorization: Bearer <admin-token>POST /api/admin/queue/resume
Authorization: Bearer <admin-token>POST /api/admin/queue/clean?grace=0&limit=1000
Authorization: Bearer <admin-token>POST /api/admin/queue/retry-failed
Authorization: Bearer <admin-token>Rate Limit: 10 requests per hour (admin operations)
GET /api/admin/analytics/overview?startDate=2025-01-01T00:00:00Z&endDate=2025-01-14T23:59:59Z
Authorization: Bearer <admin-token>Response:
{
"success": true,
"data": {
"totalRequests": 1250,
"avgResponseTime": 45.23,
"errorRate": 2.5,
"topEndpoints": [
{ "endpoint": "/api/v1/posts", "count": 500 },
{ "endpoint": "/api/v1/auth/login", "count": 250 }
]
}
}GET /api/admin/analytics/users/:userId
Authorization: Bearer <admin-token>GET /api/admin/analytics/endpoints
Authorization: Bearer <admin-token>GET /api/admin/analytics/errors
Authorization: Bearer <admin-token>GET /api/admin/analytics/performance
Authorization: Bearer <admin-token>Date Range Parameters (optional for all analytics endpoints):
startDate: ISO 8601 date-timeendDate: ISO 8601 date-time
| Endpoint Type | Limit | Window | Key |
|---|---|---|---|
| General API | 100 req | 1 hour | IP address |
| Auth (login/register) | 5 req | 15 min | IP address |
| User endpoints | 100 req | 1 hour | User ID |
| Admin endpoints | 10 req | 1 hour | User ID |
All responses include:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Requests remainingX-RateLimit-Reset: Time when limit resets
{
"success": false,
"message": "Too many requests, please try again later"
}- v1: Stable production API (fully functional)
- v2: Not yet implemented (returns 501)
/api/v1/auth/* β Auth endpoints (working)
/api/v1/posts/* β Post endpoints (working)
/api/v2/* β Returns 501 Not Implemented
{
"success": false,
"error": {
"message": "API v2 not yet implemented",
"availableVersions": ["v1"]
}
}v1 behavior is guaranteed to remain stable. Future versions (v2, v3) will never break v1 compatibility.
Analytics data is automatically deleted after 90 days (GDPR compliance via MongoDB TTL index).
- Request count
- Response time
- Status codes
- Error rates
- Endpoint popularity
- User activity
- Performance percentiles
Every API request is logged to:
- Winston logger (immediate, structured logging)
- MongoDB (persistent analytics, fire-and-forget)
Analytics writes are non-blocking and never slow down API responses.
npm testnpm test -- auth.test.ts
npm test -- post.test.ts
npm test -- rateLimit.test.ts
npm test -- versioning.test.ts
npm test -- admin.test.ts
npm test -- analytics.test.tsnpm test -- --coverageCoverage Thresholds:
- Statements: 50%
- Branches: 50%
- Functions: 50%
- Lines: 50%
tests/auth.test.ts- Authentication teststests/post.test.ts- Post scheduling teststests/rateLimit.test.ts- Rate limiting teststests/versioning.test.ts- API versioning teststests/admin.test.ts- Admin endpoint teststests/analytics.test.ts- Analytics tests
All tests use:
- MongoDB Memory Server (in-memory database)
- Mocked Redis client
- Mocked Bull queues
- Supertest for HTTP testing
-
Password Security
- Bcrypt hashing with 10 salt rounds
- Password strength validation
- Passwords never returned in responses
-
JWT Security
- Secure secret key (min 32 chars)
- Configurable expiration
- Bearer token authentication
-
Rate Limiting
- Brute force protection (auth endpoints)
- DDoS protection (API-wide)
- Distributed rate limiting (Redis-backed)
- Fail-open strategy (availability over strict limiting)
-
Input Validation
- express-validator on all inputs
- MongoDB ObjectId validation
- Date range validation
- Email format validation
-
Security Headers
- Helmet.js for HTTP security headers
- CORS configuration
-
Error Handling
- No stack traces in production
- Sanitized error messages
- Request ID tracking
- Proper HTTP status codes
-
Authorization
- Role-based access control
- Users can only access their own posts
- Admin-only routes protected
- Cannot update published posts
Services contain all business logic, making them:
- Framework-agnostic (no Express dependencies)
- Easily testable with unit tests
- Reusable across different contexts
- Single responsibility principle
The asyncHandler utility wraps async functions, eliminating repetitive try-catch blocks while maintaining proper error handling.
Custom error hierarchy provides:
- Type-safe error handling
- Consistent HTTP status codes
- Operational vs programming error distinction
- Better error logging
Strict mode catches errors at compile time:
- No implicit
any - Null safety checks
- Unused variable detection
- Type-safe middleware
Using Zod for environment validation:
- Fail-fast on startup
- Clear error messages
- Type inference
- No runtime surprises
Bull provides:
- Redis-backed persistence
- Retry logic with backoff
- Job prioritization
- Horizontal scaling (multiple workers)
- Event monitoring
- Independent scaling (scale workers separately from API)
- Fault isolation (worker crashes don't affect API)
- Resource allocation (different CPU/memory needs)
- Clear separation of concerns
- Multiple API Servers: Stateless design allows load balancing
- Multiple Workers: Bull supports concurrent job processing
- Redis Clustering: For high-availability queues
- MongoDB Replica Sets: For database redundancy
- Indexed email field for fast lookups
- Compound indexes on userId + status
- Compound indexes on userId + scheduledAt
- TTL index for automatic data cleanup
- Pagination for list endpoints
- Job deduplication via jobId
- Configurable retry strategies
- Automatic job cleanup
- Event-driven monitoring
- Redis connection pooling
The architecture supports:
- Refresh tokens (minimal refactor)
- Email verification (new service methods)
- Password reset (additional routes)
- OAuth integration (service abstraction)
- Actual platform APIs (replace simulation)
- Webhook notifications (post-publish callbacks)
- Real-time notifications (WebSocket support)
Solution: Redis not running
redis-serverSolution: MongoDB not running
mongodSolution: Worker not running
npm run dev:workerSolution: Rebuild
npm run buildSolution: Tests mock Redis (check jest.mock in test files)
Solution:
- Check Redis is running:
redis-cli ping - Check rate limit headers in responses
- Verify RedisStore is properly initialized
Solution: Make sure user has admin role
mongosh
use auth_db
db.users.updateOne(
{ email: "your-email@example.com" },
{ $set: { role: "admin" } }
)Before deploying to production:
- Update JWT_SECRET (min 32 characters)
- Set NODE_ENV=production
- Configure production MongoDB URI
- Configure production Redis credentials
- Enable MongoDB authentication
- Enable Redis password
- Setup HTTPS/SSL
- Configure CORS for frontend domain
- Setup monitoring (Uptime Robot, DataDog, etc.)
- Setup error tracking (Sentry)
- Configure log aggregation
- Setup database backups
- Configure firewall rules
- Setup CI/CD pipeline
- Create production .env file
- Test all endpoints in staging
- Load test with realistic traffic
- Setup process manager (PM2)
- Configure reverse proxy (Nginx)
- Setup auto-scaling rules
- Document runbook procedures
This is a portfolio project demonstrating production-grade patterns. Feel free to use it as a reference or starting point for your own projects.
MIT
Repository: https://github.com/27manavgandhi/buffer-api-demo
Built with attention to production-quality patterns and senior-level engineering practices. Architecture inspired by Buffer's engineering team.
β Star this repo if you find it useful!