ββββββββββ βββ ββββββ βββββββ βββββββ ββββββββββββ ββββββββββββββββββββ
βββββββββββ βββββββββββββββββββββββββββ βββββββββββββ ββββββββββββββββββββ
βββ βββββββββββββββββββββββββββ ββββββββββ ββββββ βββββββββ βββ
βββ βββββββββββββββββββββββββββ βββββββββ ββββββββββββββββ βββ
βββββββββββ ββββββ ββββββ βββββββββββββββββββββββ ββββββββββββββ βββ
ββββββββββ ββββββ ββββββ βββ ββββββββββββββββββ βββββββββββββ βββ
India's EV Charging Station Network
Find. Book. Charge.
ChargeNet is a full-stack web application that connects EV drivers with a network of 80+ charging stations across India. The platform provides real-time charger availability, slot booking, weather and AQI data at each station, community reviews, and AI-powered station tagging β all accessible through a clean, map-first interface.
The backend is built with a production-grade Express.js architecture: modular MVC structure, Zod schema validation, Pino structured logging, per-route rate limiting, Helmet security headers, and Supabase JWT authentication.
A high-performance AI Character Generator integrated into the ChargeNet ecosystem.
- Stable Diffusion v1.5: State-of-the-art character generation.
- CPU Optimized: 20s inference on Vercel CPU using optimized diffusers pipeline.
- Supabase Integration: Automatically saves generated images to Supabase Storage.
- Premium Gradio UI: Responsive design with sharing capabilities.
To enable cloud storage, add the following to your Vercel deployment or .env:
SUPABASE_URL: Your Supabase project URL.SUPABASE_KEY: Your Supabase service role or anon key.
vercel --prod- Features
- Architecture
- Tech Stack
- Project Structure
- Database Schema
- API Reference
- Getting Started
- Environment Variables
- Development Scripts
- Security
- Contributing
| Feature | Description |
|---|---|
| Station Discovery | Browse 80+ stations on an interactive Leaflet map |
| Real-time Availability | Live charger status per station |
| Slot Booking | Book and cancel EV charging sessions |
| Weather and AQI | On-site environmental data via Open-Meteo |
| Reviews and Ratings | Community-sourced station feedback |
| AI Tagging | Anthropic Claude-powered station tag generation |
| Shareable URLs | Public slug-based station pages |
| Payments | Razorpay integration |
CLIENT (React + Vite)
|
HTTP / REST (JSON)
|
ββββββββββββββββββββββββΌβββββββββββββββββββββββ
β EXPRESS API SERVER β
β β
β requestLogger β helmet β cors β bodyParser β
β β rateLimit β requireAuth β
β β
β /api/v1/stations β stationRoutes β
β /api/v1/chargers β chargerRoutes β
β /api/v1/bookings β bookingRoutes β
β /api/v1/reviews β reviewRoutes β
β β
β notFoundHandler β errorHandler β
ββββββββββββββββ¬βββββββββββββββββββββββββββββββ
|
ββββββββββββββ΄βββββββββββββ
| |
ββββββββΌβββββββ ββββββββββΌβββββββββ
β SUPABASE β β EXTERNAL APIs β
β PostgreSQL β β β
β + Auth β β Open-Meteo β
β + RLS β β Anthropic AI β
βββββββββββββββ β Razorpay β
βββββββββββββββββββ
| Technology | Version | Purpose |
|---|---|---|
| Node.js | >= 18 | Runtime |
| Express.js | 4.x | HTTP framework |
| Supabase JS | 2.x | Database client and JWT verification |
| Zod | 3.x | Request schema validation |
| Pino | Latest | Structured JSON logging |
| Helmet | Latest | HTTP security headers |
| express-rate-limit | Latest | Per-route rate limiting |
| Vitest | Latest | Unit and integration testing |
| Technology | Version | Purpose |
|---|---|---|
| React | 18.2 | UI framework |
| Vite | 5.x | Build tool and dev server |
| Tailwind CSS | 3.4 | Utility-first styling |
| React Router | v6 | Client-side routing |
| Zustand | 4.4 | Global state management |
| TanStack Query | 5.x | Server state and caching |
| React Leaflet | 4.2 | Interactive maps |
| Framer Motion | 11.x | Animations |
| React Hook Form | 7.x | Form handling |
| API | Purpose | Cost |
|---|---|---|
| Open-Meteo | Weather and AQI data | Free |
| OpenStreetMap / Leaflet | Map tiles | Free |
| Nominatim | Geocoding | Free |
| Anthropic Claude | AI station tagging | Usage-based |
| Razorpay | Payment processing | Transaction fee |
chargenet/
βββ .github/
β βββ workflows/
β βββ ci.yml # GitHub Actions CI pipeline
β
βββ server/ # Express API server
β βββ controllers/
β β βββ bookingsController.js
β β βββ chargersController.js
β β βββ reviewsController.js
β β βββ stationsController.js
β βββ lib/
β β βββ logger.js # Pino logger instance
β β βββ response.js # Standardised response helpers
β β βββ supabase.js # Supabase client (service role)
β βββ middleware/
β β βββ asyncHandler.js # Async error wrapper
β β βββ auth.js # Supabase JWT verification
β β βββ errorHandler.js # Global error and 404 handler
β β βββ logger.js # pino-http request logger
β β βββ rateLimit.js # Per-route rate limiters
β β βββ security.js # Helmet and CORS configuration
β β βββ validate.js # Zod schema validator middleware
β βββ routes/
β β βββ bookings.js
β β βββ chargers.js
β β βββ reviews.js
β β βββ stations.js
β βββ schemas/
β β βββ auth.schema.js
β β βββ booking.schema.js
β β βββ review.schema.js
β β βββ station.schema.js
β βββ services/
β β βββ ai.js # Anthropic Claude integration
β β βββ booking.service.js
β β βββ charger.service.js
β β βββ review.service.js
β β βββ station.service.js
β β βββ supabase.js
β βββ tests/ # Vitest test suite
β βββ index.js # Application entry point
β βββ vitest.config.js
β βββ package.json
β
βββ sql/
β βββ schema.sql # Full database schema
β βββ seed-stations.sql # Station seed data
β βββ database-design-fix.sql
β βββ public-rls-fix.sql # Row Level Security policies
β
βββ src/ # React frontend
β βββ components/
β βββ context/
β βββ hooks/
β βββ lib/ # Supabase client (anon key)
β βββ mock/
β βββ pages/
β βββ routes/
β βββ services/ # Frontend API service layer
β βββ store/ # Zustand stores
β βββ utils/
β
βββ .env.example
βββ SECURITY.md
βββ package.json
βββ vite.config.js
βββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β stations βββββββ<β chargers β β bookings β
βββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β id β β id β β id β
β name β β station_id β β user_id β
β slug β β type β β charger_id β
β location β β power_kw β β station_id β
β latitude β β status β β start_time β
β longitude β β connector β β end_time β
β address β ββββββββββββββββ β status β
β amenities β ββββββββββββββββ
ββββββββ¬βββββββ
β ββββββββββββββββ ββββββββββββββββ
ββββββββββββββββ<β reviews β β profiles β
β ββββββββββββββββ ββββββββββββββββ
β β id β β id β
β β station_id β β user_id β
β β user_id β β full_name β
β β rating β β vehicle_type β
β β comment β ββββββββββββββββ
β ββββββββββββββββ
β
β ββββββββββββββββ ββββββββββββββββ
βββββββββ<β station_tags β>βββββ tags β
ββββββββββββββββ ββββββββββββββββ
Base URL: http://localhost:3001/api/v1
All write endpoints require an Authorization: Bearer <token> header.
All responses follow the envelope: { success, data | error, timestamp }.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /health |
Public | Server status, uptime, version |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /stations |
Public | List all stations |
| GET | /stations/:id |
Public | Get station by ID |
| GET | /stations/slug/:slug |
Public | Get station by public slug |
| POST | /stations |
Required | Create a station |
| PUT | /stations/:id |
Required | Update a station |
| DELETE | /stations/:id |
Required | Delete a station |
| GET | /stations/:id/chargers |
Public | List chargers at a station |
| GET | /stations/:id/reviews |
Public | List reviews for a station |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| PATCH | /chargers/:id/status |
Required | Update charger availability |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /bookings |
Required | List current user's bookings |
| POST | /bookings |
Required | Create a booking |
| PATCH | /bookings/:id/cancel |
Required | Cancel a booking |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /reviews |
Required | Submit a station review |
// Success
{
"success": true,
"data": { ... },
"timestamp": "2025-01-01T00:00:00.000Z"
}
// Error
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [{ "field": "rating", "message": "Expected number" }]
},
"timestamp": "2025-01-01T00:00:00.000Z"
}| Code | HTTP Status | Cause |
|---|---|---|
VALIDATION_ERROR |
400 | Zod schema validation failed |
UNAUTHORIZED |
401 | Missing or invalid JWT |
FORBIDDEN |
403 | Authenticated but not permitted |
NOT_FOUND |
404 | Resource does not exist |
CONFLICT |
409 | Duplicate resource (DB constraint) |
SERVER_ERROR |
500 | Unhandled internal error |
- Node.js >= 18
- npm >= 9
- A Supabase project
- Razorpay test account (optional, for payment flows)
git clone https://github.com/annanyaa03/CHARGENET.git
cd CHARGENET
# Frontend dependencies
npm install
# Server dependencies
cd server && npm install && cd ..cp .env.example .env
cp server/.env.example server/.env
# Edit both files and populate all required valuesIn your Supabase SQL editor, run the files in this order:
sql/schema.sql
sql/public-rls-fix.sql
sql/seed-stations.sql # optional: seeds 80+ stations
# Frontend only β http://localhost:5173
npm run dev
# Backend only β http://localhost:3001
npm run dev:server
# Both together
npm run dev:all| Variable | Description |
|---|---|
VITE_SUPABASE_URL |
Supabase project URL |
VITE_SUPABASE_ANON_KEY |
Supabase anonymous (publishable) key |
VITE_API_URL |
Express API base URL |
VITE_RAZORPAY_KEY_ID |
Razorpay publishable key |
| Variable | Description |
|---|---|
PORT |
Server port (default: 3001) |
NODE_ENV |
development or production |
FRONTEND_URL |
Allowed CORS origin in production |
SUPABASE_URL |
Supabase project URL |
SUPABASE_PUBLISHABLE_KEY |
Supabase anonymous key |
SUPABASE_SECRET_KEY |
Supabase service role key β privileged |
SUPABASE_JWT_SECRET |
JWT secret for token verification |
RAZORPAY_KEY_ID |
Razorpay key ID |
RAZORPAY_KEY_SECRET |
Razorpay secret key β server only |
SMTP_HOST |
SMTP server hostname |
SMTP_PORT |
SMTP port (typically 587) |
SMTP_USER |
SMTP authentication username |
SMTP_PASS |
SMTP authentication password |
SMTP_FROM |
Sender address for transactional email |
VITE_prefixed variables are bundled into the client and visible to all users.
Never assign privileged credentials β service role keys, payment secrets, SMTP passwords β toVITE_variables.
| Script | Description |
|---|---|
npm run dev |
Start Vite frontend dev server |
npm run dev:server |
Start Express API with nodemon |
npm run dev:all |
Start frontend and backend concurrently |
npm run build |
Production build of the frontend |
npm run preview |
Preview production build locally |
npm run lint |
Run ESLint across all JS and JSX files |
cd server && npm test |
Run Vitest test suite |
The backend implements a layered security model across every request.
HTTP Headers β Helmet enforces Content Security Policy, HSTS with a one-year max-age and preload, X-Frame-Options deny, X-Content-Type-Options nosniff, and Referrer-Policy strict-origin-when-cross-origin.
CORS β Strict origin whitelist. Requests from unlisted origins are rejected at the middleware level. Access-Control-Allow-Credentials is enabled for authenticated flows.
Authentication β All non-GET routes require a valid Supabase JWT as Authorization: Bearer <token>. Tokens are verified server-side via the Supabase service role client and the authenticated user is attached to req.user for all downstream handlers.
Rate Limiting β Four independent limiters protect distinct surfaces:
| Limiter | Window | Limit |
|---|---|---|
| General API | 15 minutes | 100 requests |
| Authentication | 15 minutes | 10 requests |
| Bookings | 1 hour | 20 requests |
| Reviews | 1 hour | 5 requests |
Validation β All incoming request bodies are validated against Zod schemas before reaching controllers. Invalid payloads return structured 400 responses with per-field error details.
Database β Row Level Security policies are applied at the Supabase layer, ensuring users can only access their own data regardless of API-level checks.
To report a vulnerability, see SECURITY.md.
- Fork the repository.
- Create a feature branch:
git checkout -b feature/your-feature-name - Write tests for any new behaviour.
- Ensure all tests pass:
cd server && npm test - Commit using Conventional Commits.
- Open a pull request against
mainwith a clear description of changes.
MIT License. See LICENSE for details.