A full-stack system that identifies flagged individuals from a live webcam feed using in-browser face recognition, backed by an admin panel for managing criminal records and a public complaint-reporting workflow with area-based crime analytics.
🔗 Live demo: https://client-seven-delta-36.vercel.app
Admin login: admin@system.com / admin123
The backend runs on a free instance, so the very first request after a period of inactivity can take 30-60 seconds to wake up — if the demo seems slow to load at first, give it a moment and it'll be fast after that.
Community policing and neighborhood watch efforts often lack a lightweight, searchable way to cross-reference a face against known records or to track recurring incidents by area. CrimDetect explores that problem end-to-end: a browser can run face detection and matching entirely client-side (no image ever needs to leave the device to run recognition), while the backend handles record-keeping, a rules-based escalation system (repeated violations → warnings → criminal classification), a claims/appeals process for disputing a flagged status, and a public complaint system with a live crime heatmap.
The React frontend talks to an Express API, which reads/writes MySQL and delegates CPU-heavy face-matching work to a pool of Node worker threads so it doesn't block the main event loop while comparing face descriptors against the criminal database.
Admin panel
- JWT-authenticated admin accounts
- Full CRUD on criminal records, with face image upload
- Claims review workflow (approve/reject appeals from flagged users)
- Dashboard with live stats and charts (risk breakdown, detection timeline)
User panel
- Registration/login, profile with current status (Normal / Under Observation / Criminal)
- Warning history timeline
- Claim submission (appeal a flagged status, with proof upload)
- Public complaint submission with geolocation, and a personal complaint history
Face detection
- Real-time webcam-based face detection, running entirely in the browser
- 128-dimension face descriptor extraction and matching
- Euclidean-distance comparison against the criminal database (match threshold < 0.6)
- Confidence-scored match alerts, with every detection logged server-side
Crime analytics
- Public complaint submissions aggregated by area/category
- Interactive heatmap of complaint density across Karachi's administrative areas (GeoJSON boundary matching)
Face detection and recognition run client-side via face-api.js, a TensorFlow.js wrapper around three pretrained models:
- SSD MobileNet v1 — face detection (locating faces in the video frame)
- 68-point Face Landmark model — facial landmark alignment
- Face Recognition model — generates the 128-D descriptor used for matching against stored criminal records
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, shadcn/ui (Radix primitives), face-api.js, Leaflet, Recharts |
| Backend | Node.js, Express, JWT auth, Multer (uploads), Worker Threads (parallel face matching) |
| Database | MySQL (MySQL-wire-compatible TiDB Serverless in production) |
| CI/CD | GitHub Actions (lint, build, test on every push/PR; automated deploy to Vercel on merge to main) |
| Piece | Host |
|---|---|
| Frontend | Vercel |
| Backend API | Render |
| Database | TiDB Serverless |
Every push to main automatically re-runs the test suite, rebuilds the
frontend, and redeploys both services — see DEPLOYMENT.md for the full
setup/redeploy process.
Warning level: 1-2 violations → LOW
3-4 violations → MEDIUM
5+ violations → HIGH
Criminal status: violation_count >= 5 AND warnings ignored → CRIMINAL
3+ violations (not yet criminal) → UNDER_OBSERVATION
Claim approval: approved claim → status reset to NORMAL, violation_count → 0
Risk score (0-100): 10 pts per violation (capped at 40)
+ 15 pts per HIGH-risk record
+ 5 pts per unacknowledged warning
→ CRITICAL (70+) / HIGH (50+) / MEDIUM (30+) / LOW
- bcrypt password hashing
- JWT-protected routes with role-based access (admin vs. user)
- express-validator input validation on all mutating endpoints
- File-type/size-restricted uploads
- CORS locked to the deployed frontend origin
Auth — POST /api/auth/register, POST /api/auth/login, GET /api/auth/me
Admin — POST /api/admin/criminal, GET /api/admin/criminals, PUT /api/admin/criminal/:id, DELETE /api/admin/criminal/:id, GET /api/admin/claims, PUT /api/admin/claim/:id/verify, GET /api/admin/dashboard
User — GET /api/user/profile, GET /api/user/warnings, POST /api/user/claim, GET /api/user/status
Detection — POST /api/detect/face, GET /api/detect/criminals, POST /api/detect/log
Complaints — POST /api/complaints/user/complaint, GET /api/complaints/complaints (role-filtered: admin sees all, user sees their own), PUT /api/complaints/admin/complaint/:id/verify (admin), GET /api/complaints/stats/area-category (heatmap data)
Prerequisites: Node.js ≥ 18, MySQL ≥ 8.0
# 1. Database - create it and load the schema
mysql -u root -p -e "CREATE DATABASE criminal_detection_db;"
mysql -u root -p criminal_detection_db < server/extras/schema.sql
mysql -u root -p criminal_detection_db < server/extras/complaints_schema.sql
mysql -u root -p criminal_detection_db < server/extras/Notification.sql
# 2. Backend
cd server
npm install
cp .env.example .env # fill in your local MySQL credentials
npm run dev # http://localhost:5000
# 3. Frontend (separate terminal)
cd client
npm install
npm run dev # http://localhost:5173Face-api.js's model weight files are already included under
client/public/models/, so no separate download is needed.
Default seeded login once the schema is loaded: admin@system.com / admin123.
CrimDetect/
├── client/ # React frontend
│ ├── public/models/ # face-api.js model weights
│ └── src/
│ ├── components/ # Reusable UI + layout components
│ ├── pages/ # Route-level pages
│ ├── services/ # API client modules
│ └── lib/ # Shared utilities
├── server/ # Express backend
│ ├── extras/ # SQL schema files
│ └── src/
│ ├── controllers/ # Route handlers
│ ├── models/ # DB access layer
│ ├── middlewares/ # Auth, error handling
│ ├── utils/ # Face matching, rule engine, geo utils
│ └── workers/ # Worker-thread pool for face matching
├── render.yaml # Render deployment blueprint
├── DEPLOYMENT.md # Deployment/redeploy guide
└── .github/workflows/ # CI/CD pipelines
ISC
