{"id":30420738,"url":"https://github.com/macabeus/casafari-challenge","last_synced_at":"2026-04-10T13:32:09.274Z","repository":{"id":47584395,"uuid":"186514936","full_name":"macabeus/casafari-challenge","owner":"macabeus","description":"📝 A simple, but powerful, CRUD app, using Hapi.js + Mongo + React Hooks + Bootstrap + Docker!","archived":false,"fork":false,"pushed_at":"2021-08-23T08:58:56.000Z","size":161,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-22T08:26:39.605Z","etag":null,"topics":["bootstrap","docker","hapijs","mongoose","monorepo","react"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/macabeus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-14T00:29:46.000Z","updated_at":"2021-08-23T08:58:30.000Z","dependencies_parsed_at":"2022-09-02T20:51:12.414Z","dependency_job_id":null,"html_url":"https://github.com/macabeus/casafari-challenge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/macabeus/casafari-challenge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macabeus%2Fcasafari-challenge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macabeus%2Fcasafari-challenge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macabeus%2Fcasafari-challenge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macabeus%2Fcasafari-challenge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/macabeus","download_url":"https://codeload.github.com/macabeus/casafari-challenge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macabeus%2Fcasafari-challenge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31645284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["bootstrap","docker","hapijs","mongoose","monorepo","react"],"created_at":"2025-08-22T08:20:02.493Z","updated_at":"2026-04-10T13:32:09.233Z","avatar_url":"https://github.com/macabeus.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://d1qb2nb5cznatu.cloudfront.net/startups/i/834564-b37cb0b04f07235c820a59111fe22961-medium_jpg.jpg\" width=\"127px\" height=\"127px\" align=\"left\"/\u003e\n\n# casafari-challenge\n\n\u003e Node.js Developer challenge solution\u003cbr\u003e\n\u003e A simple yet powerful CRUD app using Hapi.js + Mongo + React Hooks + Bootstrap + Docker!\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/dLyj2jZ.png\" width=780\u003e\n\u003c/p\u003e\n\n## What does it do?\n\nIt is a Contact list app, where you can create, read, edit and delete a contact using the browser – or just the API.\n\n## How it works?\n\nDespite being a simple CRUD app, I opted for two core decisions:\n\n### Dockerize the entire application\n\nThe main reason why I'm using Docker is to have an easier setup. Installing Mongo might be an error-prone and boring task, and we can ensure that everyone is using the same Mongo and Node version. Also, using Docker will provide an easy way to run the server application on a container that will communicate with the database on another container.\u003cbr\u003e\nThat is a simpler setup on a new environment.\n\n### Use a single repo\n\nYeah, we could build the entire application on a single project, but I chose to build two: `contract_server` and `contract_front`. The first application is responsible for providing an API that the second application uses to render a web app. We could have `contract_server` using Hapi to provide static content, but it would result in extra coupling between the front and the back-end - which can become something critical at scale.\n\nThese two decisions are also handy when deploying: we could write a `Dockerfile` focused to deploy the `contract_server` project on something like AWS Fargate, and then deploy the `contract_front` on a static content provider, such as AWS S3.\n\n### Other decisions\n\nOn the back-end, I picked mongoose instead of just using plain mongodb because, with mongoose, we can write better code for models. \n\nOn the front-end, since one of the requirements of the challenge is to use bootstrap, I used reactstrap, because it allowed me to write a simpler and more declarative JSX code.\n\n## How to run?\n\nFirst, you need to have Docker and Docker Compose on your machine. If you don't, check [this page](https://docs.docker.com/install/) to install Docker and [this one](https://docs.docker.com/compose/install/) to install Docker Compose.\n\nThen, run the following command to start the MongoDB container:\n\n```\n\u003e docker-compose up database\n```\n\nAfter Mongo is initialized (it takes a few seconds), you need to run the back-end project:\n\n```\n\u003e cd contact_server\n\u003e npm i\n\u003e docker-compose up contact_server\n```\n\nThen, the API will be running at [`http://localhost:3000`](http://localhost:3000). You can check if everything is fine using the API [`GET http://localhost:3000/status`](http://localhost:3000/status); if you see `\"ok\"`, then the server is running.\n\nNow, to run the front-end start the following service:\n\n```\n\u003e cd contact_front\n\u003e npm i\n\u003e docker-compose up contact_front\n```\n\nFinally, just head to [`http://localhost:8080`](http://localhost:8080) to see the application running!\n\n### Tests \u0026 Linting\n\nYou can run the tests using:\n\n```\ndocker-compose run --rm contact_tests\n```\n\nAnd the lint using:\n\n```\ndocker-compose run --rm contact_front_lint\ndocker-compose run --rm contact_lint\n```\n\n### Restart database\n\nIf you want to restart your database, you can do it by running:\n\n```\nrm -rf database_data/\n```\n\nThen, restart the `database` service.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacabeus%2Fcasafari-challenge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmacabeus%2Fcasafari-challenge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacabeus%2Fcasafari-challenge/lists"}