A production-ready Node.js/Express REST API backend for the EVzone private EV charging platform.
- JWT authentication (register, login, refresh tokens)
- Complete CRUD for chargers, sites, sessions, pricing, and access control
- PostgreSQL with migrations and seed data
- CORS-enabled for frontend integration
- Structured error handling and logging
- Docker support for local development
Prerequisites:
- Docker & Docker Compose installed
- Or Node.js 18+, npm 9+, and PostgreSQL 13+
Option A: Docker (Recommended)
# Clone and navigate to backend
cd private-charge-backend
# Copy environment template
cp .env.example .env
# Start services (PostgreSQL + backend)
docker-compose up -d
# Run migrations
docker exec evzone-backend npm run migrate
# Seed sample data
docker exec evzone-backend npm run seed
# Check logs
docker-compose logs -f backendBackend will be available at http://localhost:8000
PostgreSQL at localhost:5432
Option B: Local Setup
# Install dependencies
npm install
# Copy environment
cp .env.example .env
# Update .env with local PostgreSQL credentials
# Then run migrations
npm run migrate
# Seed database
npm run seed
# Start dev server
npm run devsrc/
├── app.js — Express app setup
├── config/
│ ├── database.js — PostgreSQL connection pool
│ └── constants.js — Constants (roles, statuses, etc)
├── controllers/ — Request handlers
│ ├── auth.js — Register, login, refresh token
│ ├── users.js — User profile CRUD
│ ├── sites.js — Site (location) management
│ ├── chargers.js — Charger onboarding & management
│ └── sessions.js — Charging session lifecycle
├── middleware/
│ └── auth.js — JWT authentication & error handling
├── routes/ — Route definitions
│ ├── auth.js
│ ├── users.js
│ ├── sites.js
│ ├── chargers.js
│ └── sessions.js
├── services/
│ └── jwt.js — JWT token generation/verification
migrations/ — Database schema & seed scripts
See .env.example for defaults. Key variables:
NODE_ENV=development
PORT=8000
DB_HOST=localhost
DB_PORT=5432
DB_NAME=evzone_private_charge
DB_USER=postgres
DB_PASSWORD=your_secure_password
JWT_SECRET=your_super_secret_jwt_key
JWT_EXPIRE=7d
CORS_ORIGIN=http://localhost:3000
POST /api/auth/register — Register new user
POST /api/auth/login — Login & get JWT token
POST /api/auth/refresh — Refresh token (requires auth)
GET /api/users/profile — Get current user profile
PUT /api/users/profile — Update profile
GET /api/sites — List user's sites
POST /api/sites — Create site
GET /api/sites/:id — Get site details
PUT /api/sites/:id — Update site
DELETE /api/sites/:id — Delete site
GET /api/chargers — List chargers
POST /api/chargers — Create charger (onboarding)
GET /api/chargers/:id — Get charger details
GET /api/chargers/:id/status — Get live status
PUT /api/chargers/:id — Update charger
DELETE /api/chargers/:id — Delete charger
GET /api/sessions — List sessions
POST /api/sessions/start — Start charging session
GET /api/sessions/:id — Get session details
POST /api/sessions/:id/stop — Stop session
GET /api/health — Server status check
Core Tables:
users— User accounts with password hashingsites— Charging locations (address, lat/long)chargers— EV charging hardware (model, serial, connectors)connectors— Individual charger connectorssessions— Charging sessions (start/stop, energy, cost)pricing_plans— Pricing tiers (fixed, hourly, TOU)tariffs— Time-of-use ratesaccess_permissions— User access to chargersguest_passes— Temporary QR access codesbookings— Charger reservationsschedules— Recurring schedulespayments— Payment transactionsinvoices— Billing recordsfaults— Charger diagnosticsaudit_logs— Action history
npm start # Start production server
npm run dev # Start with nodemon (auto-reload)
npm run migrate # Run database migrations
npm run seed # Seed sample data
npm test # Run tests
npm run lint # Lint codeRegister:
curl -X POST http://localhost:8000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe"
}'Login:
curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'Get Profile (with token):
curl -X GET http://localhost:8000/api/users/profile \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Create Site:
curl -X POST http://localhost:8000/api/sites \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Downtown Hub",
"address": "123 Main St",
"city": "Washington",
"country": "DC",
"latitude": 38.9072,
"longitude": -77.0369
}'Once running, import the Postman collection (coming soon) or use curl/VS Code REST Client to test endpoints.
Quick health check:
curl http://localhost:8000/api/health- Add more controllers (pricing, access, payments, analytics)
- Implement OCPP WebSocket handler for charger communication
- Add input validation and request schemas
- Write unit and integration tests
- Set up CI/CD (GitHub Actions)
- Deploy to staging/production (Heroku, Railway, AWS)
- Generate OpenAPI/Swagger documentation
Proprietary — EVzone. Not for public redistribution.
For questions or issues, open a GitHub issue or contact the team.