Smart Transport Operations Platform — a full-stack fleet management system for tracking vehicles, drivers, trips, maintenance, fuel, and operational costs in real time.
Built for Odoo Hackathon 2026.
- App: https://transitops-production-5c4c.up.railway.app
- API Docs (Swagger): https://transitops-production-5c4c.up.railway.app/swagger-ui/index.html
| Password | Role | |
|---|---|---|
demo.admin@transitops.test |
DemoPass456! |
Admin |
Or register your own account at /pages/register.html.
Backend
- Java 21, Spring Boot 3.5
- Spring Security + JWT (stateless authentication)
- Spring Data JPA / Hibernate
- PostgreSQL (hosted on Neon)
Frontend
- Vanilla HTML/CSS/JS
- Bootstrap 5 (dark theme)
- Chart.js (analytics visualizations)
- Served as static files directly from the Spring Boot backend (same-origin, no CORS needed)
Deployment
- Railway (backend + static frontend, single service)
- Neon Postgres (serverless database)
- Authentication & RBAC — JWT-based login/register with five roles:
ADMIN,FLEET_MANAGER,DISPATCHER,SAFETY_OFFICER,FINANCIAL_ANALYST. Endpoints are protected with@PreAuthorizebased on role. - Fleet Management — Register, view, and filter vehicles by type/status; track odometer, capacity, and acquisition cost.
- Driver Management — Register and track drivers, license expiry, safety scores, and duty status.
- Trip Dispatch — Create trips with live cargo-capacity validation against the selected vehicle; auto-updates vehicle/driver availability.
- Maintenance Logging — Log service records per vehicle, mark them complete, and track cost history.
- Fuel & Expense Tracking — Log fuel fill-ups and trip-linked expenses (tolls, parking, misc); auto-calculates total operational cost.
- Analytics Dashboard — Real-time KPIs (fuel efficiency, fleet utilization, operational cost, vehicle ROI) computed from live data, with revenue and cost charts. CSV export included.
## Project Structure
```text
TransitOps/
│
├── backend/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/
│ │ │ │ └── com/transitops/backend/
│ │ │ │ ├── config/
│ │ │ │ ├── controller/
│ │ │ │ ├── dto/
│ │ │ │ │ └── auth/
│ │ │ │ ├── entity/
│ │ │ │ ├── enums/
│ │ │ │ ├── exception/
│ │ │ │ ├── repository/
│ │ │ │ ├── security/
│ │ │ │ │ └── jwt/
│ │ │ │ ├── service/
│ │ │ │ └── BackendApplication.java
│ │ │ │
│ │ │ └── resources/
│ │ │ └── application.properties
│ │ │
│ │ └── test/
│ │
│ ├── pom.xml
│ ├── mvnw
│ └── mvnw.cmd
│
├── frontend/
│ ├── css/
│ │ ├── dashboard.css
│ │ └── style.css
│ │
│ ├── js/
│ │ ├── api.js
│ │ ├── auth.js
│ │ ├── dashboard.js
│ │ ├── drivers.js
│ │ ├── fuel.js
│ │ ├── maintenance.js
│ │ ├── reports.js
│ │ ├── trips.js
│ │ └── vehicles.js
│ │
│ ├── pages/
│ │ ├── dashboard.html
│ │ ├── drivers.html
│ │ ├── fuel.html
│ │ ├── login.html
│ │ ├── maintenance.html
│ │ ├── reports.html
│ │ ├── settings.html
│ │ ├── trips.html
│ │ └── vehicles.html
│ │
│ └── index.html
│
├── README.md
└── .gitignore
POST /api/auth/register— create an account (name, email, password, role)POST /api/auth/login— returns a JWT- Frontend stores the JWT in
localStorageand attaches it asAuthorization: Bearer <token>on every subsequent request JwtAuthenticationFiltervalidates the token on each request;SecurityConfigenforces role-based access per endpoint
Static pages (/, /index.html, /css/**, /js/**, /pages/**) and /api/auth/** are public. Everything else requires a valid token.
| Endpoint | Methods | Roles |
|---|---|---|
/api/auth/register, /api/auth/login |
POST | Public |
/api/vehicles |
GET, POST, PUT, DELETE | ADMIN, FLEET_MANAGER (write); + FINANCIAL_ANALYST (read) |
/api/drivers |
GET, POST, PUT, DELETE | ADMIN, FLEET_MANAGER (write); + FINANCIAL_ANALYST (read) |
/api/trips |
GET, POST, PUT, DELETE | ADMIN, FLEET_MANAGER, DISPATCHER (write); + FINANCIAL_ANALYST (read) |
/api/maintenance |
GET, POST, PUT, DELETE | ADMIN, SAFETY_OFFICER (write); + FLEET_MANAGER, FINANCIAL_ANALYST (read) |
/api/fuel |
GET, POST, PUT, DELETE | ADMIN, FLEET_MANAGER (write); + FINANCIAL_ANALYST (read) |
/api/expenses |
GET, POST, PUT, DELETE | ADMIN, FINANCIAL_ANALYST (write); + FLEET_MANAGER (read) |
Full interactive docs available via Swagger UI at /swagger-ui/index.html once deployed.
- Java 21+
- Maven
- A PostgreSQL database (local or Neon free tier)
git clone https://github.com/your-username/transitops.git
cd transitopsSet the following (either as actual env vars, or in a local application-local.properties — do not commit real credentials):
DB_URL=jdbc:postgresql://<host>/<database>?sslmode=require
DB_USERNAME=<your-db-username>
DB_PASSWORD=<your-db-password>
JWT_SECRET=<any-long-random-string>
Generate a JWT secret:
openssl rand -base64 32./mvnw spring-boot:runThe app (including the frontend, served as static files) will be available at http://localhost:8080.
Navigate to http://localhost:8080 — you'll land on the login page. Register a new account via /pages/register.html or use the Swagger UI at /swagger-ui/index.html to create one directly.
This project is deployed as a single Railway service:
- Database: Neon Postgres — grab the connection string from the Neon dashboard and split it into
DB_URL(prefixed withjdbc:, keeping?sslmode=require),DB_USERNAME, andDB_PASSWORD. - Backend + Frontend: Both are deployed together on Railway. The frontend lives in
src/main/resources/static/and is served automatically by Spring Boot — no separate hosting or CORS configuration needed, since everything is same-origin. - Environment variables (
DB_URL,DB_USERNAME,DB_PASSWORD,JWT_SECRET) are set in Railway's Variables tab. server.forward-headers-strategy=frameworkis set inapplication.propertiesso Spring correctly recognizes HTTPS behind Railway's proxy (required for Swagger UI and any absolute URL generation to work correctly).
The fastest way to test endpoints directly is via Swagger UI:
https://transitops-production-5c4c.up.railway.app/swagger-ui/index.html
Expand any endpoint → Try it out → fill in the request body → Execute.
Example register payload:
{
"name": "Test User",
"email": "test@test.com",
"password": "password123",
"role": "ADMIN"
}- Settings page is currently UI-only (no backend persistence for depot name, currency, or distance unit preferences).
- The "Maint. Linked" column on the Fuel & Expenses page is not yet computed —
Expenserecords link toTrip, notMaintenanceLog, so this figure is not auto-populated. - No password reset / forgot-password flow yet.
- RBAC permissions on the Settings page's matrix are illustrative; actual enforcement happens via
@PreAuthorizeon the backend, not frontend role-gating.
JaidityaSinha madhavcodes25
MIT