Demo available at CarMax.io.
This package includes:
- Data collection engine for gathering CarMax inventory data
- Database setup queries for incoming inventory data
- Node back-end to accept HTTP requests and run system workers
- React front-end with price range visualization tool
- (Optional) Reverse proxy virtual host setup for Linux + Apache + Node stacks
- (Optional) Alternate OOP-based PHP back-end for those who aren't running Node
In essence, the entire system process is quite simple.
- Collect inventory data from CarMax
- Sanitize and sort data from CarMax
- Compare and store data from CarMax
- Routine data check-ups to detect sales
CarMax grants access to their semi-public API through api.carmax.com
, which this software utilizes for its data gathering.
In the case of this software, we alter the storage method for the Miles
column. Originally, mileage is stored in the database as 100k
or 10k
and so forth. To allow for easier aggregate calculations, this software stores them as their integer counterpart, 100000
or 10000
respectively.
This implementation forgoes certain available fields, but check the raw data returned from api.carmax.com
and alter your data storage as needed.
When new inventory data is collected, each resulting vehicle is examined in individually. Here is a basic decision list that is used.
- Is this vehicle is not in the database, insert it and return
- If this vehicle already exists in
Vehicles
, compare theStoreId
of this result and the previously stored record to detect moves - If this vehicle already exists in
Vehicles
and exists inSales
, remove the sales record and mark it inReturns
To detect sales, CarMax's return period of 7 days is taken into consideration. Once a vehicle has stopped appearing in CarMax's inventory for 7 days, it has the potential to be marked as sold.
If for some reason the vehicle reappears in CarMax's inventory, the sales record is removed and a vehicle return is logged instead.
Setup is as easy as running a couple queries and changing a few variables.
MySQL v5.7+
NodeJS v7.6+
ReactJS v16.0+
Run queries in mysql
directory to create database(s) and tables
mysql> use DealerData_CarMax;
mysql> source DealerData_CarMax.sql;
mysql> use DealerData_CronJob;
mysql> source DealerData_CronJob.sql;
The only table with data is DealerData_CarMax.Dealerships
which contains all current CarMax franchise locations so your local installation of the app has the data collection points necessary to begin.
- Set
ORIGIN
innode/src/config.js
to the same value asthis.host
inreact/App.js
- Set
PORT
innode/index.js
(optional)
- Extract the
react
folder to a location of your choosing, we'll usec:/dev
cd c:/dev
- Use
npm install
to install all applicable dependenciesnpm install
- Use
npm start
to initiate the test server for your new React appnpm start
- Change
host
inreact/App.js
to your domainthis.host = https://my-app-domain.com
- Use
npm run build
to create an optimized build for your front-end appnpm run build
It is recommended to run the newer Node version of this software, but the PHP version is still functional if you need it instead.
- Import files from
import
- originally used Able - Change MySQL settings in
php/import/config.mysql.php
- Use the default path (
/
) to access the HTTP(S) API - Run
cron/inventory
,cron/sales
, andcron/returns
repeatedly
If using PHP, the ProxyRequests
and ProxyPass
settings in the vhost
configuration are no longer needed.
Feel free to use this vhost
boilerplate if you're running on Apache (created on Ubuntu 16.04).
# domain: api.example.com
# public: /home/user/apps/example.com/api
<VirtualHost *:80>
# Admin email, Server Name (domain name), and any aliases
ServerAdmin admin@example.com
ServerName api.example.com
ServerAlias www.api.example.com
# Index file and Document Root (where the public files are located)
DirectoryIndex index.php index.html
DocumentRoot /home/user/apps/example.com/api
# Setup proxy for Node server
ProxyRequests on
ProxyPass / http://localhost:8080/
# If you only want to forward one directory to NodeJS, use this
# ProxyPass /api http://localhost:8080/
# Log file locatapins
LogLevel warn
ErrorLog /home/user/apps/carmax.io/log/error.log
CustomLog /home/user/apps/carmax.io/log/access.log combined
</VirtualHost>
Files available in node/src/api
POST /get/price
- used to performPriceCheck.exec({...formData})
GET /worker/inventory
- used to performInventory.exec()
GET /worker/sales
- used to performSales.exec()
GET /worker/returns
- used to performReturns.exec()
File located in node/src/workers/sales.js
exec()
- main worker used to log new sales
File located in node/src/workers/returns.js
exec()
- main worker used to log new returns
File located in node/src/workers/inventory.js
exec()
- main worker used to refresh inventory data
url()
- gets the next applicable URL for the CarMax APIinventory()
- uses url() to fetch JSON from the CarMax APIpage()
- returns the next worker page number for the CarMax APIdealership()
- returns the next dealership zip + id for the CarMax APIincrement()
- increments the worker page for the CarMax APIreset()
- resets the worker page and dealership (if applicable) for the CarMax API
react/API.js
- contains wrapper for posting data to the Node serverreact/App.js
- contains config settings and high-level app logic and importsreact/App/Page.js
- basic template for all default pages to followreact/App/Pages/PriceCheck
- main page with the price visualization tool
Only icomoon
and font-awesome-4
are included by default, but there are other icon packages ready to be used after a simple inclusion; otherwise they stay unused.
-
react/src/__gfx__/fonts/icomoon
-
react/src/__gfx__/fonts/elegants-icons
-
react/src/__gfx__/fonts/font-awesome-4
-
react/src/__gfx__/fonts/font-awesome-5
-
react/src/__gfx__/fonts/simple-line-icons
react/import/NewWindow
- component to preventtarget="_blank"
warningsreact/import/AnchorScroll
- component for smoothly scroll to an anchor on the pagexhrFields: { withCredentials: true }
- unused but available inreact/API.js
andnode/index.js
to allow the client to maintain cookies/sessions on an alternative domain via ajax requests
- Dan Lindsey - Initial work - Adom.co
This project is licensed under the GPLv3 License - see the LICENSE.md file for details.