Jr Web Developer • FullStack • 2023
Setup • Technologies • Questions • Endpoints • Schemas • Screenshots
Fullstack application developed for the Apollo Solutions Dev 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.
Built using TypeScript, the application has a backend powered by Node and NestJS, and employs SQLite for data storage. The frontend, on the other hand, is constructed using React and MaterialUI, ensuring a great user experience with a simple and intuitive interface, along with a fast API communication provided by Axios.
-
Product management: Users can read, register, modify, and delete products.
-
Automatic pricing: The application dynamically calculates promotional prices based on the product category.
When a price is changed, the promotional price will be recalculated.
When the category is changed, the promotional price will be recalculated based on it.
-
Sorting and filtering: Easily sort and filter the product list to find exactly what you need.
- Download or clone the repository
- In the project directory, open two terminals and follow the instructions below to setup both back and frontend
- Both terminals must be active to correctly run the application
- In the first terminal, access the backend directory
cd backend/
- Download all required dependencies
npm i
- Run the API locally at localhost:3100
npm start
- In the second terminal, access the frontend directory
cd frontend/
- Download all required dependencies
npm i
- Run the application locally at localhost:3000
npm start
This 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.
*Obs.: in some Linux environments, it may be necessary to install the
sqlite3
package!
1. What would be your first improvements if you had more implementation time?
I 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.
2. Thinking about your solution, how would maintenance be in case of adding new product categories? What would need to be changed?
In my implementation, the product categories work like enums
. Therefore, it's easy to add or remove categories by just modifying the ProductCategory file on the backend and the productCategory file on the frontend. In addition, you would also change the CategoryDiscounts file in the backend to update the category discount percentages.
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?
In 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.
Route | Method | Description |
---|---|---|
/products |
POST | Creates a new product |
/products |
GET | Gets all products |
/products/:id |
GET | Gets a specific product by its ID |
/products/:id |
PUT | Updates a specific product by its ID |
/products/:id |
DELETE | Deletes a specific product by its ID |
FieldName | Type | Required |
---|---|---|
id |
Number | true |
name |
String | true |
description |
String | true |
color |
String | true |
category |
String | true |
price |
Number | true |
promoPrice |
Number | true |
- Sorting table by name, category or price
- Filtering by name or category
- Modifying a product with automatic price calculator
- Removing a product
- Submitting an invalid form
- Submitting a valid form