{"id":22533490,"url":"https://github.com/vectormike/probable-engine","last_synced_at":"2025-06-30T09:36:50.340Z","repository":{"id":155403777,"uuid":"632558416","full_name":"Vectormike/probable-engine","owner":"Vectormike","description":null,"archived":false,"fork":false,"pushed_at":"2023-04-26T06:06:44.000Z","size":299,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T05:43:03.086Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/Vectormike.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-25T16:52:16.000Z","updated_at":"2023-04-25T18:56:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"44a308af-1394-41eb-8da3-c7e0564ea7ec","html_url":"https://github.com/Vectormike/probable-engine","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Vectormike/probable-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vectormike%2Fprobable-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vectormike%2Fprobable-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vectormike%2Fprobable-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vectormike%2Fprobable-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Vectormike","download_url":"https://codeload.github.com/Vectormike/probable-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vectormike%2Fprobable-engine/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262748641,"owners_count":23358240,"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":[],"created_at":"2024-12-07T09:08:29.852Z","updated_at":"2025-06-30T09:36:50.317Z","avatar_url":"https://github.com/Vectormike.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# **Backend Developer Assessment**\n\n![Meek](https://res.cloudinary.com/dangqctnm/image/upload/v1682447079/meekfi_ljmlaq.png)\n\n## Manual Installation\n\nIf you would still prefer to do the installation manually, follow these steps:\n\nClone the repo:\n\n```bash\ngit clone --depth 1 https://github.com/Vectormike/probable-engine meekfi-assessment\ncd meekfi-assessment\n```\n\nInstall the dependencies:\n\n```bash\nyarn install\n```\n\nSet the environment variables:\n\n```bash\ncp .env.example .env\n\n# open .env and modify the environment variables (if needed)\n```\n\n## Commands\n\nRunning locally:\n\n```bash\nyarn dev\n```\n\nRunning in production:\n\n```bash\nyarn start\n```\n\nTesting:\n\n```bash\n# run all tests\nyarn test\n\n# run all tests in watch mode\nyarn test:watch\n\n# run test coverage\nyarn coverage\n```\n\nDocker:\n\n```bash\ndocker-compose -up -d\n```\n\n## Environment Variables\n\nThe environment variables can be found and modified in the `.env` file. They come with these default values:\n\n```bash\n# Port number\nPORT=5222\n\n# URL of the Mongo DB\nMONGODB_URL=mongodb://127.0.0.1:27017/meekfi\n\n# JWT\n# JWT secret key\nJWT_SECRET=thisisasamplesecret\n# Number of minutes after which an access token expires\nJWT_ACCESS_EXPIRATION_MINUTES=30\n# Number of days after which a refresh token expires\nJWT_REFRESH_EXPIRATION_DAYS=30\n\n```\n\n## API Documentation\n\nTo view the list of available APIs and their specifications, run the server and go to [Postman Doc](https://documenter.getpostman.com/view/5622145/2s93Y6tf4C) in your browser.\n\n### API Endpoints\n\nList of available routes:\n\n**Auth routes**:\\\n`POST /v1/auth/register` - register\\\n`POST /v1/auth/login` - login\\\n`POST /v1/auth/refresh-tokens` - refresh auth tokens\\\n`POST /v1/auth/forgot-password` - send reset password email\\\n`POST /v1/auth/reset-password` - reset password\\\n`POST /v1/auth/send-verification-email` - send verification email\\\n`POST /v1/auth/verify-email` - verify email\n\n**User routes**:\\\n`POST /v1/users` - create a user\\\n`GET /v1/users` - get all users\\\n`GET /v1/users/:userId` - get user\\\n`PATCH /v1/users/:userId` - update user\\\n`DELETE /v1/users/:userId` - delete user\n\n---\n\n## **High Level System Design**\n\nThis documnet provides information about my solution to the MeekFi Backend Developer Assessment\nwhich required that I build an API in that allow it's users perform the following actions:\n\n- create an account\n- login account\n- update account\n- delete account\n\nThe following sections give more details into the API and the various design choices that were made.\n\nThe diagram below shows the various components of the system as can be infered from its requirements.\n\n![high level diagram](https://d2uusema5elisf.cloudfront.net/books/web-developers-field-guide/images/8-fevsbe/recap-server-side.png)\n\n# **Design Assumptions**\n\nBelow are some of the assumptions made while designing the features and functionality of this API:\n\n## Data Models\n\n### User:\n\n- Name (string)\n- Email address (string)\n- Date of birth (date)\n- Password (string)\n\n## API Endpoints\n\n## Create User\n\n- URL: /register\n- Method: POST\n- Request body:\n\n  - Name (string)\n  - Email address (string)\n  - Date of birth (date)\n  - Password (string)\n\n- Response body:\n  - User (object)\n  - Tokens (object)\n\n#### Login\n\n- URL: /login\n- Method: POST\n\n- Request body:\n  - Email address (string)\n  - Password (string)\n- Response body:\n  - User (object)\n  - Tokens (object)\n\n### Get User\n\n- URL: /users/{userId}\n- Method: GET\n- Request headers:\n  - Authorization: Bearer {access_token}\n- Response body:\n  - Name (string)\n  - Email address (string)\n  - Date of birth (date)\n\n### Update User\n\n- URL: /users/{userId}\n- Method: PUT\n- Request headers:\n- Authorization: Bearer {access_token}\n- Request body:\n  - Name (string)\n  - Email address (string)\n  - Date of birth (date)\n  - Password (string)\n- Response body:\n  - User ID (string)\n\n### Delete User\n\n- URL: /users/{userId}\n- Method: DELETE\n- Request headers:\n  - Authorization: Bearer {access_token}\n- Response body:\n  - User ID (string)\n\nAuthentication and Authorization:\nTo authenticate users, we can use the email address and password combination provided during login. Upon successful authentication, the server will generate an access token that is required for all subsequent requests to the API.\n\nWe can use JWT (JSON Web Token) to create access tokens that contain user ID and expiration date. We can store the secret key used to sign the tokens on the server-side, and include it in the access token when it is generated.\n\nWe can also include authorization logic in each endpoint to ensure that only authenticated and authorized users can access and modify their own user information.\n\n**Generating Access Tokens**:\n\nAn access token can be generated by making a successful call to the register (`POST /v1/auth/register`) or login (`POST /v1/auth/login`) endpoints. The response of these endpoints also contains refresh tokens (explained below).\n\nAn access token is valid for 30 minutes. You can modify this expiration time by changing the `JWT_ACCESS_EXPIRATION_MINUTES` environment variable in the .env file.\n\n**Refreshing Access Tokens**:\n\nAfter the access token expires, a new access token can be generated, by making a call to the refresh token endpoint (`POST /v1/auth/refresh-tokens`) and sending along a valid refresh token in the request body. This call returns a new access token and a new refresh token.\n\nA refresh token is valid for 30 days. You can modify this expiration time by changing the `JWT_REFRESH_EXPIRATION_DAYS` environment variable in the .env file.\n\n### Additional Considerations\n\nWe included validation checks for all incoming requests to ensure that the request body is in the correct format and that all required fields are present.\n\nWe included error handling to return meaningful error messages to the client when something goes wrong.\n\nWe included rate limiting to prevent abuse of the API by limiting the number of requests a client can make within a certain timeframe.\n\nWe can include logging and monitoring to help us diagnose and fix issues that may arise with the system.\n\n### Project Folder Structure\n\nThis section describes the structure of the files/folders which hold the project code.\n\n![](https://res.cloudinary.com/dangqctnm/image/upload/v1682447425/Screen_Shot_2023-04-25_at_7.30.06_PM_epfikb.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvectormike%2Fprobable-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvectormike%2Fprobable-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvectormike%2Fprobable-engine/lists"}