MotorX is a full-stack used car marketplace built for the Jordanian market. Users can list and browse used vehicles, get AI-powered fair-market price estimates, and request emergency roadside assistance. Built as a graduation project at World Islamic Sciences and Education University (WISE University), Amman, Jordan.
Live: motorx.app
- Browse and list vehicles — post car listings with photos, specs, and features, then browse and filter thousands of listings
- AI price evaluation — a machine learning model trained on real Jordanian car listings estimates a fair market price for any car; every new listing is automatically rated on creation
- Emergency assistance — a real-time SOS system using WebSockets (SignalR) connects stranded drivers with nearby tow trucks and service providers
- Car services marketplace — discover workshops, find service providers by location (Leaflet.js maps), and submit service requests
- Auth system — JWT-based authentication with refresh tokens, Google OAuth, email verification, password reset, and per-request rate limiting
- Bilingual UI — full Arabic/English support with RTL layout switching, no framework required
Three services wired together with Docker Compose, behind an Nginx reverse proxy:
Browser ──HTTPS:443──► Nginx (host)
│
HTTP:7000 (internal)
▼
ASP.NET Core 8 API
├── Serves frontend (wwwroot/)
├── All /api/ routes
└── SignalR hub (/hubs/emergency)
│
HTTP:8000 (internal)
▼
FastAPI ML microservice
└── LightGBM + ExtraTrees price prediction
│
TCP:1433 (internal)
▼
SQL Server 2022 Express
Only Nginx is publicly reachable. The API, ML service, and database are all internal to the Docker network.
├── MOTORX.Api/ # ASP.NET Core 8 backend — API, auth, business logic
├── motorx_ai/ # Python FastAPI ML microservice — price prediction
├── frontend/ # Vanilla HTML/CSS/JS frontend (served as static files)
├── docker-compose.yml # Wires all three services together
├── Dockerfile.api # Multi-stage build for the .NET backend
├── motorx_clean_schema.sql
├── .env.example
├── README.md # you are here
├── MOTORX.Api/README.md # Backend deep-dive
├── frontend/README.md # Frontend architecture
├── motorx_ai/README.md # ML pipeline and AI service
└── DEPLOYMENT.md # Production deployment guide
| Layer | Technology |
|---|---|
| Backend API | ASP.NET Core 8, Entity Framework Core, SQL Server |
| ML Service | Python 3.11, FastAPI, LightGBM, ExtraTrees, scikit-learn |
| Frontend | Vanilla HTML/CSS/JS, Leaflet.js, SignalR JS client |
| Real-time | Microsoft SignalR (WebSockets) |
| Auth | JWT (access + HttpOnly refresh cookies), Google OAuth 2.0 |
| SendGrid + MailKit/Gmail SMTP fallback | |
| Deployment | Docker, Docker Compose, Nginx, Let's Encrypt, DigitalOcean |
The price prediction model went through multiple iterations. The final architecture (v8) is a two-stage pipeline:
- Stage 1 — a lookup table that finds the median market price for a car's Brand + Model + Year + Inspection grade combination, with a 9-level fallback chain for sparse data
- Stage 2 — a stacked residual ensemble (LightGBM + ExtraTrees base models, Ridge meta-learner) trained on the delta between Stage 1's estimate and actual sale prices
| Version | Approach | CV MAE | R² |
|---|---|---|---|
| v4 (baseline) | Global LightGBM, target-encoded brand/model | ~1,760 JOD | 0.819 |
| v8 (deployed) | Lookup table + residual stacked ensemble | ~470 JOD | 0.976 |
Prerequisites: Docker Desktop, Git
git clone https://github.com/SuhaibSmadis/MotorX.git
cd MotorX
# Copy the example env file and fill in your secrets
cp .env.example .env
# Place your trained model artifacts (not in repo — too large for GitHub)
# motorx_ai/pipeline/artifacts_v8/base_price_lookup.pkl
# motorx_ai/pipeline/artifacts_v8/residual_model.pkl
docker compose up --buildThe app will be available at http://localhost:7000.
The
.pklML model artifacts are not committed to this repository because of their size. Seemotorx_ai/README.mdfor instructions on training the model locally or obtaining the artifacts.
All secrets live in .env (never committed). Copy .env.example and fill in:
| Variable | Purpose |
|---|---|
DB_PASSWORD |
SQL Server SA password |
JWT_KEY |
Secret used to sign JWT tokens |
AI_API_KEY |
Internal key the .NET backend sends to the FastAPI service |
EMAIL_FROM |
Gmail address for system emails |
EMAIL_PASSWORD |
Gmail App Password (not your account password) |
EMAILSETTINGS__SENDGRIDAPIKEY |
SendGrid API key for transactional emails |
GOOGLE_CLIENT_ID |
OAuth 2.0 Client ID from Google Cloud Console |
ADMIN_SEED_PASSWORD |
Password for the auto-seeded admin account |
Built by Suhaib Smadi, Mosab Qaddoumi, Nancy Semreen, and Mohammad Lebzo, supervised by Dr. Moath Al-Tarawneh.
- Backend README — controllers, services, auth, SignalR, EF migrations
- Frontend README — JS architecture, i18n, theming, component system
- AI Service README — ML pipeline, feature engineering, training, prediction
- Deployment Guide — step-by-step production setup on DigitalOcean