Increase price as demand increases.
- User management (create, update, login)
- Rule management (threshold, request pairs)
- Price coefficient calculation
- Go - an open source programming language that makes it easy to build simple, reliable, and efficient software.
- Gin - a web framework written in Go (Golang).
- Gorm - The fantastic ORM library for Golang.
- OpenStreetMap - OpenStreetMap is the free wiki world map.
- PostgreSQL - PostgreSQL is a powerful, open source object-relational database system.
- PostGIS - PostGIS is a spatial database extender for PostgreSQL.
- Docker - for containerization.
- Logrus - Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger.
- JWT - JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
- Swagger - Simplify API development for users, teams, and enterprises with the Swagger open source and professional toolset.
Surge requires Docker and docker-compose to run.
$ git clone https://github.com/mhmd-bb/snapp-surge.git
$ cd snapp-surge
$ cp sample.env .env
$ cp ./osm-export/sample.env ./osm-export/.env
$ docker-compose up -d --build
If you have timeout problem while downloading project dependencies use a VPN. (Sanctions...)
- After all services are up and running you can open http://localhost:8080/docs/index.html to see Swagger documentation.
- A Default user is created for you on application startup (you can change the user pass in .env file) so you can login.
- Don't forget to create rules (threshold, coefficient pairs).
You can easily use the Swagger Documentation; But I'm providing some curl commands as well:
Login:
$ curl -X POST "http://localhost:8080/users/login" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"password\": \"admin\", \"username\": \"admin\"}"
Update Password:
$ curl -X PATCH "http://localhost:8080/users/password" -H "accept: application/json" -H "Authorization: Bearer {Your Token}" -H "Content-Type: application/json" -d "{ \"password\": \"admin\"}"
Create New User:
$ curl -X POST "http://localhost:8080/users/register" -H "accept: application/json" -H "Authorization: Bearer {Your Token}" -H "Content-Type: application/json" -d "{ \"password\": \"mohammad\", \"username\": \"mohamamd\"}"
Get All Rules:
$ curl -X GET "http://localhost:8080/rules" -H "accept: application/json" -H "Authorization: Bearer {Your Token}"
Create New Rule:
$ curl -X POST "http://localhost:8080/rules" -H "accept: application/json" -H "Authorization: Bearer {Your Token}" -H "Content-Type: application/json" -d "{ \"coefficient\": 1.1, \"threshold\": 10}"
Delete Rule:
$ curl -X DELETE "http://localhost:8080/rules/1" -H "accept: application/json" -H "Authorization: Bearer {Your Token}"
Ride Request which returns coefficient and increases district request counter:
$ curl -X POST "http://localhost:8080/surge/ride" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"lat\": 51.13199462890625, \"lon\": 35.73425097869431}"
- District Polygons of Tehran city are exported using overpass-turbo with geojson format and stored in osm-export folder.
- As you start the services using docker-compose, the gdal service exports the geojson file to PostGIS.
This way i can do spatial queries on the database and find the requested location's district.
Instead of reseting the counter of a district every two hours and losing data on each reset i used the idea below:
The overal idea is that we have a moving window on small buckets (like a 2 hour Moving window on 10 minute Buckets).
Each Bucket has:
- counter
- expiration time (10 minutes for example)
- creation date
- district id
When a district's Bucket expires a new Bucket is created with counter value of 1.
The Moving window sums all Bucket counters of a district (in last 2 hours for example). This way we can have count of requests in the last two hours with +-10 minute accuracy.