Skip to content

Latest commit

Β 

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ EstelleBright β€” Production-Ready Task Manager Backend

Node.js Express.js PostgreSQL Prisma Redis Docker Zod Jest Midtrans OpenRouter

A production-grade RESTful Task Management API built with Node.js and Express.js, engineered for high performance, scalability, and an exceptional developer experience. This project features multi-core CPU clustering via PM2, robust JWT authentication with OTP email verification, a Redis caching layer, Prisma ORM v7 with PostgreSQL, automated testing suites, Zod request validation, Midtrans payment gateway integration, OpenRouter AI chat assistant, and full Docker containerization.


πŸ“– Table of Contents


πŸ› οΈ Tech Stack & Tools

Category Technology / Tools
Runtime & Framework Node.js (v22+), Express.js (v5)
Server Management PM2 (Cluster Mode, Graceful Reload, Memory Auto-Restart)
Database & ORM PostgreSQL 17, Prisma ORM v7 (Adapter-Pg)
Caching Redis 7 (In-Memory Caching, Configurable TTL)
Authentication JWT (Access + Refresh Tokens), Bcrypt, OTP Email Verification
Input Validation Zod v4 (Runtime Schema Validation for All Endpoints)
Payment Gateway Midtrans Snap API (Sandbox / Production via Env Config)
AI Assistant OpenRouter AI (Multi-model API Gateway for Chat Completions)
File Storage Cloudinary Image Upload, Multer Middleware
Document Generation PDFKit (Dynamic PDF Reports for Task Completions)
Email Service EmailJS (Transactional Emails: OTP, Notifications)
API Documentation Swagger / OpenAPI 3.0 (Interactive Docs at /api-docs)
Testing Jest v30 + Supertest (Unit & Integration Tests, Mocked External Services)
Code Quality ESLint v10+ (Flat Config), Prettier, Husky Pre-commit Hooks
Containerization Docker (Multi-stage Build, Non-root User) + Docker Compose
Logging Winston (Daily Rotate File + Console Transport with Request ID)

✨ Key Features

Feature Description
πŸ” JWT Auth + OTP Verification Signup with email OTP verification, login, forgot/reset password with token rotation & refresh tokens.
πŸ“‹ Team Management Create teams, manage members with roles (admin / member), upload banners to Cloudinary, set capacity.
βœ… Task & Assignment Full CRUD tasks with importance levels, filtering, pagination, and user assignment/unassignment.
πŸ“„ Completion & PDF Reports Mark tasks complete with automated PDF report generation via PDFKit with download endpoint.
πŸ’³ Midtrans Payments Invoice management, payment URL generation, webhook auto-update, polling sync, merchant/buyer role control.
πŸ€– AI Chat Assistant Chat with OpenRouter AI (supports multiple LLM models) via public /api/ai/chat endpoint.
⚑ Redis Caching Configurable TTL caching on GET endpoints for sub-millisecond response times.
πŸ›‘οΈ Zod Input Validation Runtime schema validation for all request bodies, params, and queries β€” clear, type-safe error messages.
πŸ”§ Master Routes Admin endpoints protected by MASTER_KEY for database operations: clear all data & seed sample data.
πŸ“Š Interactive Swagger Docs Auto-generated API documentation from JSDoc annotations, hosted at /api-docs.
πŸ§ͺ Jest Testing Suite Comprehensive test coverage with mocked external services (Midtrans, EmailJS, Cloudinary, Redis).
🐳 Dockerized Multi-stage Docker build (310MB production image), health checks, non-root user, docker-compose ready.
πŸ“ˆ PM2 Cluster Mode Auto-scales to all CPU cores, zero-downtime reload, memory-limit restart at 1GB.
πŸ“ Winston Logging Daily rotated log files with request ID tracking.

πŸ’³ Payment Integration (Midtrans)

This project includes a fully functional payment gateway powered by Midtrans Snap API, supporting secure online transactions with both sandbox and production environments.

Payment Flow

Step Description
1. Create Invoice Merchant creates an invoice for a buyer via POST /api/payments with buyerUserId and price.
2. Get Payment URL Buyer retrieves a secure Midtrans payment URL via GET /api/payments/:id/payment-url.
3. Complete Payment Buyer completes payment on the Midtrans hosted payment page.
4. Auto-Update Status Payment status is automatically updated in the database via Midtrans Webhook or Frontend Polling.

Payment Environment Configuration

The Midtrans environment is controlled by the MIDTRANS_IS_PRODUCTION environment variable, not NODE_ENV. This allows you to run the app in production mode while still using sandbox keys for testing.

MIDTRANS_IS_PRODUCTION=false   # Uses sandbox API (Midtrans test environment)
MIDTRANS_IS_PRODUCTION=true    # Uses production API (requires live keys)

Payment Webhook & Polling Strategy

Mechanism Description When to Use
Webhook Midtrans sends real-time notification to POST /api/payments/webhook Production (reliable, automatic)
Frontend Polling Frontend calls POST /api/payments/:id/sync every 5 seconds Local Development (when webhook is unavailable)

Note: Webhook only works when the server is accessible via a public URL (e.g., using ngrok or deployed to a cloud server). For local development, frontend polling ensures status updates still work seamlessly.


πŸ€– AI Assistant (OpenRouter)

This project integrates OpenRouter AI, a unified API gateway that provides access to multiple large language models (LLMs) including GPT-4, Claude, Gemini, and many more.


πŸ›‘οΈ Zod Request Validation

All API endpoints implement Zod v4 runtime schema validation, ensuring that every request body, parameter, and query string is validated before reaching the controller logic.

Benefits:

  • βœ… Type-safe request validation
  • βœ… Clear, descriptive error messages
  • βœ… Protection against malformed or malicious input
  • βœ… Centralized schema definitions for maintainability

πŸ”§ Master Routes (Admin Tools)

Protected admin endpoints for database maintenance, secured by the MASTER_KEY environment variable.

πŸš€ Getting Started

Prerequisites

Local Development Setup

# 1. Clone the repository
git clone https://github.com/zannunakiz/TaskManagementBackend_EstelleBright.git
cd TaskManagementBackend_EstelleBright

# 2. Install dependencies
npm install

# 3. Set up environment variables
cp env.example .env
# Edit .env with your configuration (database, API keys, etc.)

# 4. Generate Prisma client
npx prisma generate

# 5. Push database schema
npx prisma db push

# 6. (Optional) Seed sample data
curl -X POST http://localhost:3001/master/seed \
  -H "Content-Type: application/json" \
  -d '{"master_key": "your_master_key"}'

# 7. Start development server with hot reload
npm run dev

βš™οΈ PM2 Process Management

This project uses PM2 as the production process manager for zero-downtime reloads, cluster mode, and automatic restarts.

PM2 Commands

Command Description
npm run pm2:start Start app in production mode (port 3001)
npm run pm2:start:staging Start app in staging mode (port 3002)
npm run pm2:stop Stop the app
npm run pm2:restart Restart the app
npm run pm2:reload Reload app with zero downtime
npm run pm2:delete Delete the app from PM2
npm run pm2:logs Tail live logs
npm run pm2:monit Open real-time monitoring dashboard
npm run pm2:status Show all running PM2 processes

PM2 Configuration (ecosystem.config.js)

  • Cluster mode with max instances (one per CPU core)
  • Max memory restart threshold at 1GB
  • Log files written to ./logs/pm2-*.log
  • Environment-specific ports: production on 3001, staging on 3002

Graceful Shutdown

The app handles SIGTERM and SIGINT signals in src/app.js to gracefully disconnect Prisma and Redis before exiting β€” no additional configuration needed.


🐳 Docker Deployment

# Build and start all services (PostgreSQL, Redis, App)
docker compose up -d --build

# Stop all services
docker compose down

# View application logs
docker compose logs -f app

# View all services logs
docker compose logs -f

Docker Configuration

  • Multi-stage build: Dependencies installed in builder stage, production image is lean (~310MB)
  • Non-root user: Runs as appuser for security
  • Health checks: Automatic container health monitoring
  • Database migrations: Auto-executed via docker-entrypoint.sh
  • Environment variables: Passed from .env file via Docker Compose variable substitution

πŸ§ͺ Testing

# Run all tests
npm test

# Run tests with watch mode
npm run test:watch

# Run tests with coverage report
npm run test:coverage

Test Coverage

The test suite uses Jest with Supertest for HTTP integration testing. External services (Midtrans, EmailJS, Cloudinary, Redis) are mocked using __mocks__/ for reliable, deterministic tests.


πŸ›‘οΈ Security Features

This project implements multiple layers of security to protect against common vulnerabilities.

Authentication & Authorization

Feature Description
JWT Access + Refresh Tokens Short-lived access tokens (30min default) with refresh token rotation
Token Versioning Invalidate all tokens for a user by incrementing tokenVersion (logout all devices)
OTP Email Verification 6-digit OTP sent via EmailJS for signup verification and password reset
Cryptographically Secure OTP OTPs generated using crypto.randomBytes() (not Math.random())
OTP Brute Force Protection Account locked for 15 minutes after 5 failed OTP attempts
Hashed OTP Storage All OTPs stored as bcrypt hashes (both verification and reset)
Role-Based Access Control Team-level roles: owner, admin, member with granular permissions

Input Validation & Sanitization

Feature Description
Zod Schema Validation All request bodies, params, and queries validated at runtime
String Length Limits Maximum character limits on all string fields (prevents resource exhaustion)
HTML Tag Stripping XSS prevention via HTML tag removal from string inputs
Type Coercion Safety Numeric IDs validated as positive integers

Rate Limiting

Endpoint Category Limit Window
General API 100 requests 15 minutes
Authentication 10 requests 15 minutes
OTP Verification 5 requests 15 minutes
AI Chat 20 requests 15 minutes
Master Routes 3 requests 15 minutes
Webhook 10 requests 1 minute

Payment Security

Feature Description
Webhook Signature Verification HMAC-SHA512 signature verification using X-Signature-Key header
Timing-Safe Comparison All secret comparisons use crypto.timingSafeEqual()
Midtrans Environment Isolation Sandbox/production controlled by MIDTRANS_IS_PRODUCTION env var

Infrastructure Security

Feature Description
Helmet.js Security headers: HSTS, X-Frame-Options, X-Content-Type-Options, etc.
CORS Strict origin control in production
Environment Validation Startup check for required secrets (exits if missing)
Docker Non-Root User Application runs as appuser (not root)
Container Resource Limits CPU and memory limits for all services
Graceful Shutdown Proper Prisma/Redis disconnection on SIGTERM/SIGINT
Request ID Tracking Every request tagged with unique ID for audit trail
Winston Logging Structured JSON logs with daily rotation

API Documentation Security

  • Swagger docs (/api-docs) are only available in non-production environments
  • All protected endpoints require Authorization: Bearer <token> header
  • Master routes require MASTER_KEY in request body + rate limiting

πŸ” Environment Variables

Variable Description Required
NODE_ENV Application environment Yes
PORT Server port (default: 3001) Yes
DATABASE_URL PostgreSQL connection string Yes
REDIS_URL Redis connection string Yes
ACCESS_TOKEN_SECRET JWT access token secret Yes
REFRESH_TOKEN_SECRET JWT refresh token secret Yes
MASTER_KEY Admin master key for seed/clear Yes
SERVER_KEY Midtrans server key Yes
CLIENT_KEY Midtrans client key Yes
MERCHANT_ID Midtrans merchant ID Yes
MIDTRANS_IS_PRODUCTION Midtrans environment (true/false) Yes
OPENROUTER_API_KEY OpenRouter AI API key Yes
EMAILJS_SERVICE_ID EmailJS service ID Yes
EMAILJS_TEMPLATE_ID EmailJS template ID Yes
EMAILJS_PUBLIC_KEY EmailJS public key Yes
EMAILJS_PRIVATE_KEY EmailJS private key Yes
CLOUDINARY_CLOUD_NAME Cloudinary cloud name Yes
CLOUDINARY_API_KEY Cloudinary API key Yes
CLOUDINARY_API_SECRET Cloudinary API secret Yes
CLOUDINARY_UPLOAD_PRESET Cloudinary upload preset Yes
TOKEN_EXPIRY JWT access token expiry (default: 30m) No
REFRESH_TOKEN_EXPIRY JWT refresh token expiry (default: 30d) No

Made with ❀️ by Richky Amogus

Releases

Packages

Contributors

Languages