{"id":18508563,"url":"https://github.com/camilafbarcellos/apollo-techtest","last_synced_at":"2026-05-05T00:36:34.872Z","repository":{"id":203398839,"uuid":"709504703","full_name":"camilafbarcellos/apollo-techtest","owner":"camilafbarcellos","description":"Development of a frontend and a backend application for Apollo Solutions technical test (2023).","archived":false,"fork":false,"pushed_at":"2024-04-12T22:58:32.000Z","size":1543,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-17T02:23:17.298Z","etag":null,"topics":["api","crud","fullstack","mui","nestjs","react","sqlite","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/camilafbarcellos.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,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-10-24T20:21:45.000Z","updated_at":"2023-10-25T23:43:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"51732c4e-0797-4b0f-a885-e29bac99e268","html_url":"https://github.com/camilafbarcellos/apollo-techtest","commit_stats":null,"previous_names":["camilafbarcellos/apollo-techtest"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camilafbarcellos%2Fapollo-techtest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camilafbarcellos%2Fapollo-techtest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camilafbarcellos%2Fapollo-techtest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camilafbarcellos%2Fapollo-techtest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/camilafbarcellos","download_url":"https://codeload.github.com/camilafbarcellos/apollo-techtest/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254112592,"owners_count":22016803,"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":["api","crud","fullstack","mui","nestjs","react","sqlite","typescript"],"created_at":"2024-11-06T15:14:44.225Z","updated_at":"2026-05-05T00:36:29.844Z","avatar_url":"https://github.com/camilafbarcellos.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# :brain: Apollo Tech Test\n\u003cp align=\"center\"\u003eJr Web Developer • FullStack • 2023\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://apollosolutionsdev.com/wp-content/uploads/2022/06/Versoes-do-Logo.png\" width=\"500\" height=\"250\"/\u003e\n\u003c/p\u003e\n\n## :bookmark_tabs: Table of Contents\n### [Setup](#rocket-setup) • [Technologies](#gear-technologies) • [Questions](#question-questions) • [Endpoints](#door-endpoints) • [Schemas](#bricks-schemas) • [Screenshots](#camera_flash-screenshots)\n\n## :information_source: About The App\n\nFullstack application developed for the **[Apollo Solutions Dev](https://apollosolutionsdev.com/)** technical test that implements a simple product management system. The app offers the registration of new products and the listing of existing ones as the main functionality, and also provides all CRUD (Create, Read, Update, Delete) basic methods.\n\nBuilt using [TypeScript](https://www.typescriptlang.org/), the application has a **backend** powered by [Node](https://nodejs.org/en) and [NestJS](https://nestjs.com/), and employs [SQLite](https://www.sqlite.org/) for data storage. The **frontend**, on the other hand, is constructed using [React](https://react.dev/) and [MaterialUI](https://mui.com/), ensuring a great user experience with a simple and intuitive interface, along with a fast **API communication** provided by [Axios](https://axios-http.com/).\n\n### Features\n- **Product management:** Users can read, register, modify, and delete products.\n- **Automatic pricing:** The application dynamically calculates promotional prices based on the product category.\n    \u003e When a price is changed, the promotional price will be recalculated.\n    \n    \u003e When the category is changed, the promotional price will be recalculated based on it.\n- **Sorting and filtering:** Easily sort and filter the product list to find exactly what you need.\n\n## :rocket: Setup\n- Download or clone the repository\n- In the project directory, open two terminals and follow the instructions below to setup both back and frontend\n    - Both terminals must be active to correctly run the application\n\n### Backend\n- In the first terminal, access the backend directory\n```\ncd backend/\n```\n- Download all required dependencies\n```\nnpm i\n```\n- Run the API locally at [localhost:3100](http://localhost:3100)\n```\nnpm start\n```\n\n### Frontend\n- In the second terminal, access the frontend directory\n```\ncd frontend/\n```\n- Download all required dependencies\n```\nnpm i\n```\n- Run the application locally at [localhost:3000](http://localhost:3000)\n```\nnpm start\n```\n\n### SQLite Database\nThis project operates with an **SQLite database**, offering a simple and straightforward backend setup. There's no need to configure anything manually, as the **API**, constructed using **NestJS** and **TypeORM**, takes care of everything. It automatically generates a `db.sqlite` database file within the backend folder's root directory, which stores all the data managed by the application. If you need to restart the API, the database remains consistent, and it can also be deleted at anytime to a fresh restart along with the API if wanted so.\n\n\u003e **Obs.:* in some Linux environments, it may be necessary to install the `sqlite3` package!\n\n## :gear: Technologies\n![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge\u0026logo=typescript\u0026logoColor=white)\n![ReactJS](https://img.shields.io/badge/React-20232A?style=for-the-badge\u0026logo=react\u0026logoColor=61DAFB)\n![MUI](https://img.shields.io/badge/MUI-%230081CB.svg?style=for-the-badge\u0026logo=mui\u0026logoColor=white)\n![Axios](https://img.shields.io/badge/Axios-5A29E4.svg?style=for-the-badge\u0026logo=Axios\u0026logoColor=white)\n![NodeJS](https://img.shields.io/badge/Node.js-43853D?style=for-the-badge\u0026logo=node.js\u0026logoColor=white)\n![NestJS](https://img.shields.io/badge/nestjs-%23E0234E.svg?style=for-the-badge\u0026logo=nestjs\u0026logoColor=white)\n![SQLite](https://img.shields.io/badge/SQLite-07405E?style=for-the-badge\u0026logo=sqlite\u0026logoColor=white)\n\n## :question: Questions\n**1. What would be your first improvements if you had more implementation time?**\n\nI would carefully review and refactor all the code to make it cleaner and more reusable, which would allow me to easily implement the CRUD of new object types in the backend, as well as their registration and visualization screens in the frontend. Having this concrete and functional base, I could adopt other types of databases, such as PostgreSQL or MongoDB, and deploy all parts of the application in order to run it more easily.\n\n**2. Thinking about your solution, how would maintenance be in case of adding new product categories? What would need to be changed?**\n\nIn my implementation, the product categories work like `enums`. Therefore, it's easy to add or remove categories by just modifying the [ProductCategory](backend/src/util/ProductCategory.ts) file on the backend and the [productCategory](frontend/src/types/productCategory.ts) file on the frontend. In addition, you would also change the [CategoryDiscounts](backend/src/util/CategoryDiscounts.ts) file in the backend to update the category discount percentages.\n\n**3. What changes would need to be made to support updates in the product category's discount percentage so that whenever the discount percentage was changed, the new price would be reflected in all products of the same category?**\n\nIn this case, it would be interesting to create a new entity in the database that represents categories, which allows us to store the discount percentage information. By having two separate entities, we could establish a one-to-many relationship between Product and Category, since each category can have multiple products. Then, when implementing Category endpoints in the API, the update route should check if there has been any change to the discount percentage. If so, it triggers a method to recalculate the promotional price of all products belonging to that category. This can be done by retrieving all products with a specific category through a new `GET` route on the Product endpoints, using a specific method to recalculate the prices, and then sending the modified products to be updated through the Product's `PUT` route.\n\n[↑ Back to top](#brain-apollo-tech-test)\n\n## :door: Endpoints\n\n### Products Endpoints\n|       Route         |    Method    |                   Description                    |                                                                         \n|   ---------------   | :----------: |  ----------------------------------------------  |                                                                           \n|  `/products`        |    POST      |  Creates a new product                           | \n|  `/products`        |    GET       |  Gets all products                               |   \n|  `/products/:id`    |    GET       |  Gets a specific product by its ID               |   \n|  `/products/:id`    |    PUT       |  Updates a specific product by its ID            |                                                        \n|  `/products/:id`    |    DELETE    |  Deletes a specific product by its ID            |                 \n\n## :bricks: Schemas\n\n### Product Entity\n|    FieldName   |    Type   | Required |\n|----------------|:---------:|:--------:|\n| `id`           | Number    |   true   |\n| `name`         | String    |   true   |\n| `description`  | String    |   true   |\n| `color`        | String    |   true   |\n| `category`     | String    |   true   |\n| `price`        | Number    |   true   |\n| `promoPrice`   | Number    |   true   |\n\n[↑ Back to top](#brain-apollo-tech-test)\n\n## :camera_flash: Screenshots\n### List page\n![List](/github/list-table.png)\n\n- Sorting table by name, category or price\n\n![Order](/github/table-order.gif)\n\n- Filtering by name or category\n\n![Filter](/github/table-filter.gif)\n\n- Modifying a product with automatic price calculator\n\n![Modify](/github/table-modify.gif)\n\n- Removing a product\n\n![Remove](/github/table-remove.gif)\n\n### Register page\n![Register](/github/register-form.png)\n\n- Submitting an invalid form\n\n![Invalid](/github/invalid-form.gif)\n\n- Submitting a valid form\n\n![Valid](/github/valid-form.gif)\n\n[↑ Back to top](#brain-apollo-tech-test)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcamilafbarcellos%2Fapollo-techtest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcamilafbarcellos%2Fapollo-techtest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcamilafbarcellos%2Fapollo-techtest/lists"}