Skip to content

n-ithesh/acquisitions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Acquisitions API

A secure and scalable Node.js REST API with authentication, built with Express.js, Drizzle ORM, and Neon Database. Features comprehensive security middleware, JWT authentication, and Docker-based development workflow.

πŸ“‹ Table of Contents

✨ Features

  • πŸ” JWT Authentication - Secure user authentication with bcrypt password hashing
  • πŸ›‘οΈ Security First - Helmet, CORS, Arcjet security middleware
  • 🐘 Neon Database - Serverless PostgreSQL with Neon Local for development
  • πŸ”„ Hot Reload - Auto-restart on file changes in development
  • πŸ“ Structured Logging - Winston logger with Morgan HTTP logging
  • 🐳 Docker Ready - Separate dev/prod Docker configurations
  • 🎯 Modern ES Modules - Full ESM support with import path aliases
  • βœ… Input Validation - Zod schema validation for requests
  • 🧩 Modular Architecture - Clean separation of concerns (MVC pattern)

πŸ›  Tech Stack

  • Runtime: Node.js 22
  • Framework: Express.js 5
  • Database: Neon PostgreSQL
  • ORM: Drizzle ORM
  • Authentication: JWT + bcrypt
  • Security: Helmet, CORS, Arcjet
  • Logging: Winston + Morgan
  • Validation: Zod
  • Dev Tools: ESLint, Prettier, Docker

πŸ“ Project Structure

acquisitions/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ config/           # Configuration files
β”‚   β”‚   β”œβ”€β”€ arject.js     # Arcjet security config
β”‚   β”‚   β”œβ”€β”€ database.js   # Database connection
β”‚   β”‚   └── logger.js     # Winston logger setup
β”‚   β”œβ”€β”€ controllers/      # Request handlers
β”‚   β”‚   β”œβ”€β”€ auth.controller.js
β”‚   β”‚   └── user.controller.js
β”‚   β”œβ”€β”€ middleware/       # Custom middleware
β”‚   β”‚   └── security.middleware.js
β”‚   β”œβ”€β”€ models/           # Database schemas
β”‚   β”‚   └── user.model.js
β”‚   β”œβ”€β”€ routes/           # API routes
β”‚   β”‚   β”œβ”€β”€ auth.routes.js
β”‚   β”‚   └── user.route.js
β”‚   β”œβ”€β”€ services/         # Business logic
β”‚   β”‚   β”œβ”€β”€ auth.service.js
β”‚   β”‚   └── user.service.js
β”‚   β”œβ”€β”€ utils/            # Utility functions
β”‚   β”‚   β”œβ”€β”€ cookies.js
β”‚   β”‚   β”œβ”€β”€ format.js
β”‚   β”‚   └── jwt.js
β”‚   β”œβ”€β”€ validations/      # Zod schemas
β”‚   β”‚   β”œβ”€β”€ auth.validation.js
β”‚   β”‚   └── user.validation.js
β”‚   β”œβ”€β”€ app.js            # Express app setup
β”‚   β”œβ”€β”€ index.js          # Entry point
β”‚   └── server.js         # Server configuration
β”œβ”€β”€ drizzle/              # Database migrations
β”œβ”€β”€ scripts/              # Helper scripts
β”‚   β”œβ”€β”€ dev.sh            # Development startup
β”‚   └── prod.sh           # Production startup
β”œβ”€β”€ logs/                 # Application logs
β”œβ”€β”€ Dockerfile            # Production container
β”œβ”€β”€ docker-compose.dev.yml   # Development setup
β”œβ”€β”€ docker-compose.prod.yml  # Production setup
β”œβ”€β”€ drizzle.config.js     # Drizzle ORM config
└── package.json

πŸš€ Getting Started

Prerequisites

  • Node.js 22 or higher
  • Docker and Docker Compose (for containerized setup)
  • Neon Account (sign up at neon.tech)
  • Git

Environment Setup

  1. Clone the repository

    git clone https://github.com/n-ithesh/acquisitions.git
    cd acquisitions
  2. Install dependencies

    npm install
  3. Set up Neon Database

    • Go to console.neon.tech
    • Create a new project
    • Get your API Key from Settings β†’ API Keys
    • Copy your Project ID from Project Settings
    • Copy your Branch ID from Branches tab
  4. Configure environment files

    Development (.env.development):

    # Neon Configuration
    NEON_API_KEY=your_api_key_here
    NEON_PROJECT_ID=your_project_id_here
    PARENT_BRANCH_ID=your_main_branch_id_here
    
    # Database URL (for Neon Local)
    DB_URL=postgres://neon:npg@neon-local:5432/neondb
    
    # Application
    NODE_ENV=development
    PORT=3000
    
    # JWT
    JWT_SECRET=your_jwt_secret_here
    JWT_EXPIRES_IN=7d
    
    # Arcjet (optional)
    ARCJET_KEY=your_arcjet_key_here

    Production (.env.production):

    # Database URL (from Neon Console)
    DB_URL=postgres://user:pass@ep-xxx.aws.neon.tech/neondb?sslmode=require
    
    # Application
    NODE_ENV=production
    PORT=3000
    
    # JWT
    JWT_SECRET=your_secure_jwt_secret_here
    JWT_EXPIRES_IN=7d
    
    # Arcjet
    ARCJET_KEY=your_arcjet_key_here

Development Mode

Using Docker (Recommended):

# Start with Neon Local proxy
docker compose -f docker-compose.dev.yml up --build

# Or use the helper script
npm run dev:docker

Local Development (without Docker):

# Ensure DB_URL points to a valid database
npm run dev

Your API will be available at http://localhost:3000

Production Mode

Using Docker:

docker compose -f docker-compose.prod.yml up --build

# Or use the helper script
npm run prod:docker

Direct deployment:

npm start

πŸ“‘ API Documentation

Base URL

http://localhost:3000/api

Endpoints

Health Check

GET /health

Returns server health status

Authentication

Sign Up

POST /api/auth/sign-up
Content-Type: application/json

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "securePassword123"
}

Sign In

POST /api/auth/sign-in
Content-Type: application/json

{
  "email": "john@example.com",
  "password": "securePassword123"
}

Sign Out

POST /api/auth/sign-out

Users

Get Users (Protected)

GET /api/users
Authorization: Bearer <token>

πŸ—„οΈ Database Management

Migrations

Generate migrations (after schema changes):

npm run db:generate

Apply migrations:

Development:

docker compose -f docker-compose.dev.yml exec app npm run db:migrate

Production:

DB_URL="your_prod_connection_string" npm run db:migrate

Database Studio

Access Drizzle Studio to manage your database:

npm run db:studio

Opens at https://local.drizzle.studio

Schema

Current schema includes:

  • users table with authentication fields
    • id (serial, primary key)
    • name (varchar)
    • email (varchar, unique)
    • password (varchar, hashed)
    • role (varchar, default: 'user')
    • created_at (timestamp)
    • updated_at (timestamp)

πŸ’» Development

Code Quality

Linting:

npm run lint        # Check for issues
npm run lint:fix    # Auto-fix issues

Formatting:

npm run format:check  # Check formatting
npm run format        # Auto-format code

Import Aliases

The project uses import aliases for cleaner imports:

import User from '#models/user.model.js';
import { db } from '#config/database.js';
import { validateAuth } from '#validations/auth.validation.js';

Available aliases:

  • #models/ β†’ ./src/models/
  • #config/ β†’ ./src/config/
  • #controllers/ β†’ ./src/controllers/
  • #routes/ β†’ ./src/routes/
  • #utils/ β†’ ./src/utils/
  • #middlewares/ β†’ ./src/middlewares/
  • #services/ β†’ ./src/services/
  • #validations/ β†’ ./src/validations/

πŸ“œ Scripts

Script Description
npm run dev Start development server with watch mode
npm start Start production server
npm run lint Run ESLint
npm run lint:fix Fix ESLint issues
npm run format Format code with Prettier
npm run format:check Check code formatting
npm run db:generate Generate Drizzle migrations
npm run db:migrate Apply Drizzle migrations
npm run db:studio Open Drizzle Studio
npm run dev:docker Start development with Docker
npm run prod:docker Start production with Docker

🐳 Docker

Development Setup

Uses Neon Local proxy for ephemeral database branches:

  • Fresh database branch per container start
  • Hot-reload enabled
  • Database accessible at localhost:5432
  • Auto-cleanup on container stop
docker compose -f docker-compose.dev.yml up --build

Production Setup

Connects directly to Neon Cloud Database:

  • No local proxy
  • Optimized Node.js image
  • Non-root user execution
  • Health checks included
docker compose -f docker-compose.prod.yml up --build

Docker Commands

# View logs
docker compose -f docker-compose.dev.yml logs -f app

# Shell into container
docker compose -f docker-compose.dev.yml exec app sh

# Stop and remove volumes
docker compose -f docker-compose.dev.yml down -v

# Rebuild from scratch
docker compose -f docker-compose.dev.yml up --build --force-recreate

For detailed Docker documentation, see DOCKER.md and QUICKSTART.md

πŸ”’ Security

Implemented Security Measures

  • Helmet.js - Sets secure HTTP headers
  • CORS - Cross-origin resource sharing
  • Arcjet - Advanced security middleware
  • bcrypt - Password hashing (salt rounds: 10)
  • JWT - Token-based authentication
  • Cookie Security - HttpOnly, Secure, SameSite cookies
  • Input Validation - Zod schema validation
  • Rate Limiting - Via Arcjet
  • SQL Injection Protection - Via Drizzle ORM parameterized queries

Security Best Practices

  1. Never commit .env* files (except .env.example)
  2. Use strong JWT secrets in production
  3. Enable SSL/TLS for production database connections
  4. Rotate API keys regularly
  5. Use environment variables for all secrets
  6. Keep dependencies updated
  7. Enable 2FA on Neon account

πŸ› Troubleshooting

Port 5432 Already in Use

Stop local PostgreSQL or change the port:

# Windows
net stop postgresql-x64-14

# Or change port in docker-compose.dev.yml
ports:
  - "54320:5432"

Can't Connect to Database

  1. Check if containers are running:

    docker compose -f docker-compose.dev.yml ps
  2. View container logs:

    docker compose -f docker-compose.dev.yml logs -f
  3. Verify environment variables:

    docker compose -f docker-compose.dev.yml config

Authentication Failed

  • Verify Neon credentials in .env.development
  • Check API key hasn't expired
  • Ensure Project ID and Branch ID are correct

Migration Issues

# Reset local database
docker compose -f docker-compose.dev.yml down -v
docker compose -f docker-compose.dev.yml up --build

# Regenerate migrations
npm run db:generate
npm run db:migrate

General Issues

# Clean rebuild
docker compose down -v
docker system prune -a
npm run dev:docker

πŸ“š Additional Resources

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

ISC

πŸ‘€ Author

n-ithesh

πŸ™ Acknowledgments


Happy coding! πŸŽ‰

For quick setup instructions, see QUICKSTART.md

About

A secure and scalable Node.js REST API with authentication, built with Express.js, Drizzle ORM, and Neon Database. Features comprehensive security middleware, JWT authentication, and Docker-based development workflow.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors