Merko is a product and vendor small search engine, but instead of showing a list of matches in text, this shows the location by coordinates of the vendors that match the search for their products or directly, their business names. It is made with Laravel, VueJs and MySQL and of course, Google Maps API.
When all the confinement began due to the pandemic caused by the SARS-COV-2 virus, many people began to buy products in large quantities, fear instilled the idea of creating reserves, which caused some shortages in some regions. Due to the above, the question arose: how could we find the location of an article that we need with exact precision? Maybe a spare or medicine, something vital; Many may sell the same, but what is the closest vendor?.
With this idea in mind, a simple map-based application was built, with the ability to search in a static radius around the user's location, with filters and options to extend radius up to 50 kilometers. All code and installation instructions can be found on Github as a public repository; there is also a demo page of Merko.
In a short tutorial (Speaking in spanish), its basic operation is explained:
The project is designed on the MVC pattern, this is made up of four major models, and other minor ones:
- User: Laravel default User model.
- Location: These are the businesses that users register, including all contact information and especially the coordinates (latitude, longitude) for their location on the map.
- Order: Orders that a user can send to a seller or vendor, their negotiation is direct, the seller can confirm the availability of products, that is, confirm an order.
- Product: Products registered in each of the businesses, includes three main elements: A description, a long description and the price. The long description is used to detail additional or complementary information.
A repository pattern based on Eloquent is implemented, a pure implementation of the pattern was not made because it makes redundant the advantages offered by the ORM Eloquent, in its operation with facades it is possible to do without the injection of dependencies in the repository constructor. The methods implemented in the interface are: CREATE, GET, UPDATE and DESTROY, which are in charge of the addition, cancellation and modification operations, known as CRUD (Create, Read, Update, Destroy). This layer is hosted on the path:
Each main model has a repository that implements the Repository interface:
# Interface /app/Repositories/Repository.php # Repositories /app/Repositories/LocationRepository.php /app/Repositories/OrderRepository.php /app/Repositories/ProductRepository.php
As in the case of repositories, each model has a service, each service extends from its respective repository, uses a feature to facilitate the loading of relations (relations) and implements the Service interface:
# Interface /app/Services/Service.php # Trait to load relationships /app/Services/Relationships.php # Services /app/Services/LocationService.php /app/Services/OrderService.php /app/Services/ProductService.php
The service layer executes operations with the database, the idea when extending the repository is to simplify the code as much as possible and access the repository methods when the service is used in a controller; In this way, the controllers will maintain an order of responsibility and the non-repetition of the code is guaranteed in all of them.
In order to optimize the queries, the scopes of Eloquent were exploited, in each model they will find the scopes implemented in case of seeing their use in the service layer.
Trait of column names
The Queryable name feature, allows the selection of the specific names of the fields, columns or table headings, is located in /app/Traits/Queryable.php, in this way we avoid the use of the asterisk (*) wildcard in the queries to MySQL. This takes the contents of the $fillable property and uses by default the columns id, created_at and updated_at, so only the foreign key fields should be indicated in case it is required to load related models. Almost all models make use of this feature.
Once users have registered businesses (locations), they can create products individually or by bulk upload using a spreadsheet; To do this, they create a document with three column headings:
- Description: With a minimum length of 20 characters and a maximum of 126 characters.
- long description: With a maximum length of 400 characters.
- price: numeric field.
Loading products from a spreadsheet will be effective on the first sheet of the document, if and only if, the three necessary fields with the conditions.
Challenges in the process
The initial design contemplated the implementation of a payment gateway and images for product model. The payment gateway diverted the main idea of being a search engine, since it entails monopolizing all payments and then sending the benefits to those who have sold on the platform; This dynamic includes costs for everyone, which is why it was dismantled.
The images in the product model brought an almost impossible task, loading an image for each product is very complicated; a vendor with thousands of products would see this as a great cost of time and money, which makes the project impractical.
I release the project code with the idea of contributing to the open source world and with the purpose of finding a viable solution to the provisioning problem, from the basic to the vital elements; this crisis has shown how vulnerable we are, in fear and overload of mostly fake information, therefore, building this type of tool can open doors when many are closed.