ParkIntel is an end-to-end intelligent illegal parking hotspot prediction and enforcement dispatch system. It consists of a high-fidelity Next.js command center frontend, a high-performance Go REST API backend serving live-inferred ML model predictions (using ONNX models), and a PostgreSQL database.
graph TD
User([Browser Client]) -->|Port 3000| Frontend[Next.js Command Center]
User -->|Port 8080| Backend[Go REST API]
Backend -->|Go ONNX Runtime| MLModels[LightGBM, XGBoost, RandomForest]
Backend -->|Port 5432| DB[(PostgreSQL)]
ParkIntel/
├── docker-compose.yml # Coordinates all Docker services (Frontend, Backend, DB)
├── README.md # System-wide guide (this file)
├── backend/ # Go REST API backend
│ ├── Dockerfile # Docker recipe for Go service with ONNX C-library
│ ├── main.go # App entry point
│ ├── schema.sql # Database schema script
│ └── README.md # Backend developer guide
├── frontend/ # Next.js App Router frontend
│ ├── Dockerfile # Docker recipe for Next.js app
│ ├── app/ # Next.js pages & styling
│ ├── components/ # Reusable UI widgets & command center panels
│ └── README.md # Frontend developer guide
├── models/ # ML Model storage
│ └── onnx/ # ONNX binaries (LGB, XGB, RF) & class metadata
└── ml-python/ # Python notebooks, preprocessing & training scripts
Running the entire stack with Docker Compose handles database initialization, data ingestion, ONNX shared library bindings, and Next.js building out-of-the-box.
- Docker installed and running on your system.
- Docker Compose installed (typically bundled with Docker Desktop).
Run the following command from the root directory of the project:
docker compose up --build -dThis single command will:
- Initialize a PostgreSQL 16 database container.
- Build the Go API container, download the prebuilt ONNX Runtime C library (
libonnxruntime.so.1.27.0), and compile the Go code. - Build the Next.js frontend container.
- Mount the models and training CSV datasets into the containers to seed the database and load ONNX sessions at startup.
Run the following to check if all services are healthy and running:
docker compose psYou should see:
- parkintel-db: Up and healthy (port
5432). - parkintel-backend: Up (port
8080). - parkintel-frontend: Up (port
3000).
- Frontend Dashboard: Open http://localhost:3000 in your browser.
- Backend Health Check: Run
curl http://localhost:8080/health(should return a healthy status JSON).
To stop and clean up the container stack without losing database volume data:
docker compose downTo remove the volume data as well, run docker compose down -v.
If you prefer to run services manually for debugging or active development:
Start a PostgreSQL container:
docker run --name parkintel-postgres -e POSTGRES_DB=parkintel -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:16-alpineEnsure you have Go installed (1.25+) and set ONNX_RUNTIME_LIB_PATH to an installed libonnxruntime shared library. Production containers bake this library into /usr/lib; local development can point at the Python venv copy if you have installed ml-python/requirements.txt.
Navigate to backend/ and run:
# Create local .env file
cp .env.example .env
# Run tests
go test -v ./...
# Run backend service
go run main.goThe backend will boot on port 8080 and run migrations & CSV data ingestion.
Ensure you have Node.js 18+ installed.
Navigate to frontend/ and run:
# Create local .env.local file
cp .env.local.example .env.local
# Install dependencies
npm install
# Run next.js in dev mode
npm run devOpen http://localhost:3000 to view the dashboard.
Since ONNX models are large binary files (~82MB uncompressed), Git pushes may sometimes fail over HTTPS due to network limits. Run these commands locally to optimize Git configuration:
git config http.postBuffer 524288000
git config http.lowSpeedLimit 0
git config http.lowSpeedTime 999999
git config http.version HTTP/1.1
git config core.compression 0If teammates experience difficulties or branch mismatches when pulling code updates from the remote repository, they can perform a hard reset and force-align with the remote main branch:
git fetch origin main
git reset --hard origin/main(Warning: This will discard any uncommitted local changes.)