{"id":26497588,"url":"https://github.com/dchicchon/colaco","last_synced_at":"2026-04-09T08:02:36.994Z","repository":{"id":45341752,"uuid":"438055538","full_name":"dchicchon/colaco","owner":"dchicchon","description":"Full Stack application utilizing React","archived":false,"fork":false,"pushed_at":"2023-06-28T23:23:22.000Z","size":1475,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2023-06-29T00:22:11.354Z","etag":null,"topics":["express","nodejs","react","sql"],"latest_commit_sha":null,"homepage":"https://dchicchon.github.io/colaco/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dchicchon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-13T23:28:13.000Z","updated_at":"2023-06-28T23:26:18.000Z","dependencies_parsed_at":"2022-09-02T00:02:12.300Z","dependency_job_id":null,"html_url":"https://github.com/dchicchon/colaco","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchicchon%2Fcolaco","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchicchon%2Fcolaco/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchicchon%2Fcolaco/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dchicchon%2Fcolaco/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dchicchon","download_url":"https://codeload.github.com/dchicchon/colaco/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244620363,"owners_count":20482599,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["express","nodejs","react","sql"],"created_at":"2025-03-20T13:43:16.134Z","updated_at":"2026-04-09T08:02:36.901Z","avatar_url":"https://github.com/dchicchon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ColaCo\n\n## Summary\nThis [monorepo](https://en.wikipedia.org/wiki/Monorepo#:~:text=In%20version%20control%20systems%2C%20a,stored%20in%20the%20same%20repository.\u0026text=Many%20attempts%20have%20been%20made,other%2C%20newer%20forms%20of%20monorepos.) hosts a full-stack application that can build a soda machine application. The client dispenses soda jsons from a virtual soda machine and the server hosts an api where an owner can manage their machine through an interface. The application utililzes the [MVC framework](https://www.tutorialspoint.com/mvc_framework/mvc_framework_introduction.htm) as its architecture.\n\nTo follow along with the below steps, be sure to use the `stack` branch. The main branch here is dedicated to the demo site running in Github Pages\n\n## Table of Contents\n1. [Installation](#installation)\n2. [Start](#start)\n3. [Client](#client)\n4. [Server](#server)\n5. [Production](#production)\n6. [Links](#links)\n\n## Photos\n\n\u003cbr/\u003e\n\n\u003cimg src='https://media.giphy.com/media/yHRPCtODZadWaeraY5/giphy.gif'/\u003e\n\u003cfigcaption align='center'\u003e\u003cb\u003eClient\u003c/b\u003e\u003c/figcaption\u003e\n\u003cbr/\u003e\n\u003cimg src='https://media.giphy.com/media/vMv1HPiaFaATeZl5qk/giphy.gif'/\u003e\n\u003cfigcaption align='center'\u003e\u003cb\u003eAPI Interface\u003c/b\u003e\u003c/figcaption\u003e\n\n## Installation\nBefore running this application, please ensure that your device has the latest version of [NodeJS](https://nodejs.org/en/)\n\n## Start\n### Quickstart\nTo start this application, run:\n```console\nnpm run quickstart\n```\nThis will install all the dependencies for the application then concurrently begin the client and api development servers. By default, the client will be hosted on http://localhost:3000, the api interface on http://localhost:3001, and the api on http://localhost:4000. The database should also be seeded by this point as well\n\n\n# Client\n## Summary \nThe `client` of this project is a [React](https://reactjs.org/) application that displays an SVG soda machine that contains a list of sodas retrieved from the `server` through an api call.\n## User Actions\n### Purchase Soda\nOn the `client`, a user can purchase sodas from the vending machine by clicking the button. Upon clicking the button, an api call will be sent to the server requesting to purchase a soda. Upon successful purchase, the browser will trigger the download of `soda.json` which will contain the `id`, `label` and `description` of the soda. In addition to the download, a message will appear on the side of the machine stating the soda label purchased.\n\n## API calls used\n- GET `/api/sodas`: retrieves the list of sodas available from the database\n- PUT `/api/sodas`: decrements the type of soda purchased then returns the soda information to download as `json`\n\n## Stretch Goals\n- Utilize polling through [useInterval](https://blog.bitsrc.io/polling-in-react-using-the-useinterval-custom-hook-e2bcefda4197) to fetch new content over time\n- Utilize React [`lazy`, `Suspense`](https://reactjs.org/docs/code-splitting.html#reactlazy) to take advantage of code splitting and allow the client to load components as needed with webpack\n- Utilize React [`Error Boundary`](https://reactjs.org/docs/error-boundaries.html) to catch JavaScript errors and display fallback UI\n- Add additional styling with SVGs or [`Three.js`](https://github.com/pmndrs/react-three-fiber) to page in order to keep users more engaged. \n\n# Server\n### Summary\nThe `server` is a NodeJS application utilizing the web framework [Express](https://expressjs.com/) to host an `API` for the `client`. To simplify the managment of the soda machine, an `interface` built with React was used to interact with the `API`. \n\n## Interface\n### Summary\nThe interface displays information to the admin that includes the `Soda listings`, `Transactions placed`, and `Revenue earned`. The admin additionally can interact with the `API` directly here.\n### User Actions\n#### Create Soda\nAn admin can create a soda by clicking on the `Add Soda` button. This will bring up a modal that will request input from the admin to create the soda. On submit, a POST request will be sent to `/api/sodas` and will respond with the soda created\n#### Update Soda\nAn admin can update a soda utilizing the same modal by clicking the `Update Soda` button. On sumbit, a PUT request will be sent to `/api/sodas/:id` and will respond with how many rows were updated.\n#### Delete Soda\nAn admin can delete a soda by clicking the `Update Soda` button then on the modal click the `Delete Soda` button. This will send a DELETE request to `/api/sodas:id` and will respond with the result of the deletion\n### API calls used\n- GET `/api/sodas` to retrieve all sodas from the database\n- GET `/api/transactions/` to retrieve all transactions from the database\n- GET `/api/revenue` to retrieve the current revenue of the soda machine\n- POST `/api/sodas` to add a soda to the database\n- PUT `/api/sodas/:id` to update a soda\n- DELETE `/api/sodas/:id` to delete a soda inthe database\n\n### Stretch Goals\n- Include authentication to only allow soda machine admins to access the API. Either through a environment variable as a password or by creating admins in the database.\n- Include a timeline of the soda machine revenue to analyze the most profitable times.\n- Include a table of most purchased sodas to anaylze which sodas were the most popular\n- Include pagination to our transaction and soda tables to allow admin to not have to request such a large amount of data from the server at one time.\n- Create more tests to ensure quality of code.\n\n\n## API\n### Summary\nThe API is built with the [Express web framework](https://expressjs.com/) and [Sequelize ORM](https://sequelize.org/). It is structured as follows\n```\n- controllers \n- db\n- models\n- routes\n- tests\n- testUtils\n- utils\napp.js\nserver.js\n```\n\nThe API is structured to modularize the code and allow testing on individual files. An example of testing an express app can be found [here](https://dev.to/mhmdlotfy96/testing-nodejs-express-api-with-jest-and-supertest-1bk0)\n\n### Available Routes\n\n\u003ctable role=table\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTitle\n\u003ctd\u003e \u003ccode\u003eGet Sodas\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMethod\n\u003ctd\u003eGET\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL\n\u003ctd\u003e\u003ccode\u003e/api/sodas\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL Parameters\n\u003ctd\u003e\u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSuccess Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 200\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e[{id: '1', label: 'Pop', description: 'A soda', price: 1.00, quantity: 100 }, ...]\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eError Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 400 BAD REQUEST \u003cbr\u003e\u003cstrong\u003eContent\u003c/strong\u003e: \u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\n\u003cstrong\u003eSample Request\n\u003ctd\u003e\n\u003ccode\u003ecurl http://localhost:4000/api/sodas\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eNotes\n\u003ctd\u003eReturns a list of sodas\n\u003c/table\u003e\n\n\u003chr\u003e\n\n\u003ctable role=table\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTitle\n\u003ctd\u003e\u003ccode\u003eGet Transactions\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMethod\n\u003ctd\u003eGET\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL\n\u003ctd\u003e\u003ccode\u003e/api/transactions\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL Parameters\n\u003ctd\u003e\u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSuccess Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 200\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e[{id: '1', label: 'Pop', price: 1.00, time: 12/18/2021, 3:02:21 PM }, ...]\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eError Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 400 BAD REQUEST ERROR\u003cbr\u003e\u003cstrong\u003eContent\u003c/strong\u003e: \u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\n\u003cstrong\u003eSample Request\n\u003ctd\u003e\n\u003ccode\u003ecurl http://localhost:4000/api/transactions\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eNotes\n\u003ctd\u003eReturns a list of transactions \n\u003c/table\u003e\n\n\u003chr\u003e\n\n\u003ctable role=table\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTitle\n\u003ctd\u003e\u003ccode\u003eGet Revenue\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMethod\n\u003ctd\u003eGET\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL\n\u003ctd\u003e\u003ccode\u003e/api/revenue\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL Parameters\n\u003ctd\u003e\u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSuccess Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 200\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e[{revenue: 9.00}]\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eError Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 400 BAD REQUEST \u003cbr\u003e\u003cstrong\u003eContent\u003c/strong\u003e: \u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\n\u003cstrong\u003eSample Request\n\u003ctd\u003e\n\u003ccode\u003ecurl http://localhost:4000/api/revenue\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eNotes\n\u003ctd\u003eReturns the revenue of the soda machine\n\u003c/table\u003e\n\n\u003chr\u003e\n\n\u003ctable role=table\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTitle\n\u003ctd\u003e\u003ccode\u003eAdd Soda\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMethod\n\u003ctd\u003ePOST\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL\n\u003ctd\u003e\u003ccode\u003e/api/sodas\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL Parameters\n\u003ctd\u003e\u003cstrong\u003eRequired:\u003cbr\u003e\u003ccode\u003e{label: [String], price: [Float], description: [String], quantity: [Integer]}\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSuccess Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 200\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e{id: 1, label: 'Pop', price: 1.00, description: 'A soda', quantity: 100}\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eError Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e400 BAD REQUEST\u003cbr\u003e\u003cstrong\u003eContent\u003c/strong\u003e: \u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\n\u003cstrong\u003eSample Request\n\u003ctd\u003e\n\u003ccode\u003ecurl -X POST -H \"Content-Type: application/json\" -d '{\"label\":\"pop\",\"price\":1.00,\"description\":\"niceSoda\", \"quantity\":100}' http://localhost:4000/api/sodas\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eNotes\n\u003ctd\u003eAdds a soda\n\u003c/table\u003e\n\n\u003chr\u003e\n\n\u003ctable role=table\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTitle\n\u003ctd\u003e\u003ccode\u003eBuy Soda\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMethod\n\u003ctd\u003ePUT\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL\n\u003ctd\u003e\u003ccode\u003e/api/sodas\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL Parameters\n\u003ctd\u003e\u003cstrong\u003eRequired:\u003cbr\u003e\u003ccode\u003e{id: [id]}\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSuccess Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 200\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e[1,0]\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eError Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 400 BAD REQUEST\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e{\"error\":\"No more soda to dispense\"}\n\u003ctr\u003e\n\u003ctd\u003e\n\u003cstrong\u003eSample Request\n\u003ctd\u003e\n\u003ccode\u003ecurl -X PUT -H \"Content-Type: application/json\" -d '{\"id\": [id]}' http://localhost:4000/api/sodas\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eNotes\n\u003ctd\u003eDecrements the soda quantity\n\u003c/table\u003e\n\n\n\u003chr\u003e\n\n\u003ctable role=table\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTitle\n\u003ctd\u003e\u003ccode\u003eUpdate Soda\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMethod\n\u003ctd\u003ePUT\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL\n\u003ctd\u003e\u003ccode\u003e/api/sodas/:id\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL Parameters\n\u003ctd\u003e\u003cstrong\u003eRequired:\u003cbr\u003e\u003ccode\u003e{id: [id], label: [String], price: [Float], description: [String], quantity: [Integer]}\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSuccess Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 200\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e[1,0]\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eError Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 400 BAD REQUEST\u003cbr\u003e\u003cstrong\u003eContent\u003c/strong\u003e: \u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\n\u003cstrong\u003eSample Request\n\u003ctd\u003e\n\u003ccode\u003ecurl -X PUT -H \"Content-Type: application/json\" -d '{\"label\":\"Poppy\",\"price\":1.50,\"description\":\"A new Soda\", \"quantity\":150\"}' http://localhost:4000/api/sodas/[id]\n\u003ctr\u003e \n\u003ctd\u003e\u003cstrong\u003eNotes\n\u003ctd\u003eUpdates a soda\n\u003c/table\u003e\n\n\u003chr\u003e\n\n\u003ctable role=table\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTitle\n\u003ctd\u003e\u003ccode\u003eDelete Soda\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMethod\n\u003ctd\u003eDELETE\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL\n\u003ctd\u003e\u003ccode\u003e/api/sodas/:id\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eURL Parameters\n\u003ctd\u003e\u003cstrong\u003eRequired:\u003cbr\u003e\u003ccode\u003e{id: [id]}\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSuccess Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 200\u003cbr\u003e\u003cstrong\u003eContent: \u003c/strong\u003e\u003ccode\u003e[1]\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eError Response\n\u003ctd\u003e\u003cstrong\u003eCode:\u003c/strong\u003e 400 BAD REQUEST\u003cbr\u003e\u003cstrong\u003eContent\u003c/strong\u003e: \u003ccode\u003eNone\n\u003ctr\u003e\n\u003ctd\u003e\n\u003cstrong\u003eSample Request\n\u003ctd\u003e\n\u003ccode\u003ecurl -X DELETE http://localhost:4000/api/sodas/[id]\n\u003ctr\u003e \n\u003ctd\u003e\u003cstrong\u003eNotes\n\u003ctd\u003eDeletes a Soda\n\u003c/table\u003e\n\n### Database  \nFor development of this application, [SQLite](https://www.sqlite.org/index.html) was used due to its flexibility as a `zero-configuration` and `self-contained` database engine.\n\nIn production, it is [recommended](https://www.sqlite.org/whentouse.html) to utilize a SQL Database engines such as MySQL, PostGreSQL, etc. For my deployment of this application, I utilized `MySQL` through the provisioning of `JAWSDB` on `Heroku`\n\n#### SQL vs NoSQL\nIn the development of this project, a SQL Database was utilized as the main platform for hosting the data. In hindsight, I believe that a NoSQL database would have been the correct choice due to the flexibility of data models and because my application does not require any relational mapping of the tables.\n\n### Models\nThis application relies on the Data Models of `Soda` and `Transaction`.\n\n```js\nSoda {\n  label: String,\n  price: Number,\n  description: String,\n  quantity: Number\n}\n\nTransaction {\n  label: String,\n  price: Number\n}\n```\n\nThe models are then created as instances via [`Sequelize`](https://sequelize.org/)\n\n\n### Stretch Goals\n- In the API for purchasing a soda, the api is sending back an object that is a representation of the soda purchased. The client then creates an `a` tag to initiate the function `downloadJSON` to download the JSON file on the client. This method utilizes more resources on the browser and may stress mobile clients. It would be more appropriate to download from the server itself utilizing the method [`res.download`](https://github.com/expressjs/express/blob/master/examples/downloads/index.js)\n- Convert database solution to utilize `mongoose` package since current application does not rely extensibly on relational mapping and it would be beneficial to have a more flexible data model.\n- Transfer application to a Docker container to make it an executable that can run in any environment\n- Configure cors options to only accept origins for `client` \n- Create more tests to ensure quality of code.\n\n\n# Production\nTo deploy this application I utilized [Heroku](https://www.heroku.com/home) since they provide add-ons for production SQL databases such as [JAWSDB](https://www.jawsdb.com/) that can easily be placed into the `API`. If no `JAWSDB`\n\n## Configuration\nThe `Client` during development utilizes the `Server` endpont `http://localhost:4000` for requests. For deployment, ensure that you set the .env variable `REACT_APP_BASE_URL` to your production server. On the Heroku application dashboard, this can be found in `settings` under the section `Config Vars`.\n\n## Deployment\nTo deploy this application, be sure to have the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) installed. Since this project is a monorepo, we will deploy the client and server individually as their own applications via [Git Subtrees](https://www.atlassian.com/git/tutorials/git-subtree)\n\n### Client\n1. Create a Heroku application\n```console\nheroku create \u003coptional-name\u003e\n```\n2. Utilizing the project endpoint, create a new git remote through this command\n```console\ngit remote add client \u003cclient-heroku-endpoint\u003e\n```\n3. Push the project the `client` remote via\n```console\nnpm run deploy-client\n```\n### Server\n1. Create a Heroku application\n```console\nheroku create \u003coptional-name\u003e\n```\n2. Utilizing the project endpoint, create a new git remote through this command\n```console\ngit remote add server \u003cserver-heroku-endpoint\u003e\n```\n3. Push the project the `server` remote via\n```console\nnpm run deploy-server\n```\n\n# Available Scripts\n```console\nnpm run quickstart    - runs install script then start script\nnpm run install       - install dependencies in application\nnpm start             - runs seed script and develop script\nnpm run develop       - starts client and api development servers\nnpm run client        - starts client development server\nnpm run server        - starts server api and interface servers\nnpm run seed          - seeds sqlite database\nnpm run deploy:client - deploys client build to heroku endpoint\nnpm run deploy:server - deploys server build to heroku endpoint\nnpm run lint          - runs linter on client and server\nnpm run test          - runs tests on client and server\nnpm run prepare       - prepares git hooks with husky\nnpm run build         - runs build scripts of client and api-interface\n```\n\n# Technologies Used\n- [React](https://reactjs.org/): JavaScript Framework for UI Interfaces\n- [Sequelize](https://sequelize.org/): Object Relational Mapper for SQL\n- [NodeJS](https://nodejs.org/en/): JavaScript Server Runtime Environment\n- [Express](https://expressjs.com/): JavaScript Web Framework\n- [Heroku](https://www.heroku.com/home): Cloud Application Platform to applications\n- [ESLint](https://eslint.org/): JavaScript Linter to identify issues and conform style\n- [Husky](https://www.npmjs.com/package/husky): NPM package to run project scripts with Git Hooks\n- [Axios](https://axios-http.com/docs/intro): promise based HTTP client for the Browser and NodeJS\n- [CORS](https://www.npmjs.com/package/cors): NPM package to enable Cross Origin Resource Sharing on the server.\n\n# Project Stretch Goals\n- Utilize [Continuous Integration](https://www.atlassian.com/continuous-delivery/continuous-integration) in the project for future codebase development.\n- Several eslint configs have rules turned off, turn them on in the future\n\n## Links\n[Client](https://soda-machine-dchicchon.herokuapp.com/)\n\u003cbr\u003e\n[Server](https://soda-machine-server-dchicchon.herokuapp.com/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdchicchon%2Fcolaco","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdchicchon%2Fcolaco","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdchicchon%2Fcolaco/lists"}