Skip to content

System Technical Overview

Dane Mackier edited this page Feb 10, 2021 · 2 revisions

In this document we will detail the technical overview of the system that was decided on based on this discussion. In this discussion we walked through the most important user scenario, Ordering and receiving food, and detailed what would be needed technically to complete this process. This document is the result of that discussion.

Technical Terms and Jargon

We want to have consistent words relating to specific actions or representations of an object. For that reason its important to align the definitions of certain terms to how we'll be using it in this project going forward.

Backend

The first thing to mention comes from Fernando in the discussion where he mentions that I called the collection of api functions groups when referring to them. He proposed using the REST convention of calling a group of endpoints a resource. So that's what we'll do. Each of the 5 "backend systems" will be a resource and their naming will match the resource recommendation from the REST convention. We'll use the multiple of the resource as the endpoint name. That will make the Order management have the resource "orders", the User Management "users" etc.

System Models

In this system we have defined quite a few models, we won't go over all of them because a lot of them are obvious. But we'll go over the ones that were commonly typed using a / with an additional description.

  • Merchant: Will be used to describe a Restaurant or any store that's selling on here. The "Manager" account in relation to the login on the "Restaurant Manager" where they can adjust their menu's as well as the term "Operator". All of those will be described by the term Merchant because they all have the same permissions and purpose.

  • User: Will be used for the user of the client application. Not the Driver (which will be a user of the Driver app), not the Merchant (which will be the user of the Restaurant Manager). Only the user of the customer application will be considered a user because the rest of the "users" are "part of" the organisation in a sense and we want to distinguish between them

Backend Insights

Following through with the entire 9 step process that was identified in the discussion allowed us to get some great insights into what we would require to build this backend. A breakdown of what we learned follows.

Backend API and Setup

We'll have different types of cloud functions which we can categorise and locate accordingly in the source code. We have:

  • Reactive functions: These functions are listening for changes and will only run whenever any of those changes occur. The common ones are listening to a new entry in a collection or listening to an update in a document. This will be used throughout the backend to keep things separate and easy to extend.

  • RESTful functions: These are functions that will run only when called explicitly from an http request or through the cloud functions SDK that is available. This is seen in the checkout request and most likely through the function that we'll use to add a payment method into our system for a user. These functions will make use of express as noted in the final comment from Rodrigo. Each of the resources will expose a single cloud function endpoint using express and we will internally split the paths and perform the intended actions.

Data models

We identified 9 models that will be required to carry out our major goals. Please keep in mind that these are not the only models that will be used in the clients. This is just to give us a guideline of what we would need in order to process one order on the backend. We'll start of with the models required on the merchant side.

  • Merchant: This model represents the entity that's providing the product the user is ordering. It will also be used as the object to refer to for the auth details when viewed from the Restaurant Managers perspective.
    • Name
    • Address
    • Opening Times
    • Menu's
  • Menu: This is the object that will represent a collection of products and their options available from the Merhants
    • Availability
    • Products
  • Products: The products represent actual things that the user can order and pay for through the app.
    • Name
    • Price
    • Description
    • Availability
    • Options
  • ProductOptions: The options that can be added to modify a Product in the cart. Additional cheese, a flavor, a drink with the meal, etc.

Next we'll look at what's required from the Users side.

  • User: This represents the entity that will be ordering the product and paying for it.
    • Name
    • Address
    • Payment Method
    • Account details

That's the only major model I can identify at this point. Of course the models used to represent things like the Address, PaymentMethod and AccountDetails will be models as well but those aren't important in carrying over the data from the client to the restaurant and back. Those can be stored as strings if we're lazy (which we are not). But that's how I determine if they're worth mentioning in this document. Next up is the meat of the process. All the models involved in connecting the User to the Merchants products.

  • Cart: This represents the current set of products that the user would like to buy from the producer.
    • Products: A list of all the products with their options that the user would like to buy
    • Total: the current total of the cart
    • UserId: the user the cart belongs too
    • RestaurantId: The restaurant the orders are from
    • DeliveryLocation: The place to where the user is ordering the food
    • Delivery instructions: Any additional instructions for delivery that will be given to the driver.
  • Order: This is the "promise" made by the system between the Merchant and the User that describes what was ordered, what its state is, and who it belongs too:
    • Id: The is of the order which will match the document id.
    • status: The status of the order to tell the user and the restaurant what state the order is in.
    • Delivery address: The address where this order must be delivered too.
    • Pick up address: The place where this address must be picked up.
    • Products: All the products that were ordered along with their options
  • Delivery: This is the model that will be used to track the driver delivery contract. The same way an order is the contract between the user and the producer. The Delivery is the contract between the Merchant, the User and the Driver that says "I'm taking this order to the user, and this is my current status". This will be updated in real time with the lat long of the driver
    • OrderId
    • DriverID
    • UserId
    • RestaurantId
    • Lattitude
    • Longitude
    • Delivery Address
    • Pickup Address
    • Time picked up
    • Time delivered
  • Driver: This represents a registered driver that can login to the Driver application and take a delivery from a Merchant location to the Users location.

That's all the major models required that we can identify based on the most important process in the entire product. Getting what the user ordered to them in a manner that keeps every party involved up to date with what's happening. These are not "The complete models" we will be adding and taking away properties as we develop but this does give us an idea of what we have and will need going forward

Firestore Collections

In this section we go over the collections we'll require to get the information from the client through the system and back to the client. We can follow the same path as what we did with the models above. We'll look at the collections the restaurants will need.

  • Restaurants: This will be a collection of documents that contains the description and details of restaurants.
    • Menus: This will be a sub collection in a restaurant document that contains the menu's for that restaurant
      • Products: This will be a sub collection in a menu document that contains all the products for that specific menu.
        • Options: This will be a sub collection in Products that contains all the options available for that product.

The structure above will allow use to apply well defined security rules from the highest level down and also allow us to easily find products / options for specific restaurants with their specific menu's. Next up is the user:

  • Users: A ****collection that will store the information of the user as a document.
    • PaymentMethods: A collection that stores all the payment methods that the user has added to their profile
    • Addresses: A collection that stores all the addresses the user has added to their profile as documents

The we can move onto the collection required for these two to communicate with each other and make their exchange.

  • Carts: A collection that houses all the carts as documents
  • Orders: A collection that keeps all the orders that has been placed through the system
  • Deliveries: A collection that keeps the delivery document for the real-time system to track it.
  • Drivers: A collection that stores all the Drivers information

That will cover all the collections for this process. With these collections we have sufficient points of interception in case we want to add additional functionality / functions to do more. It covers our scenario and if we can get away with only these collections we'll have a very lean system on our hands to maintain. Which is great for the long run.

Backend Explantion

In addition to what's mentioned above I think it's important to provide additional insights based on some questions we had in the discussions. This was around the confusion over what the Cloud Functions will actually be used for. To clear this up we'll go over how they are intended to be used to maybe shed some light for the developers not familiar with the cloud functions.

What Are The Cloud Functions For?

The cloud functions will serve as micro-services that perform specific tasks that's required for an action to be complete. It is not to abstract the user from the firestore database, it's to enhance the experience of using the Firestore database. The cloud functions will contain all the business logic of what needs to happen once the information has left the users device and moved into our database.

Will We Access the Database Through Function API calls?

No. Clients will query the database directly and also insert the appropriate data they're allowed too directly. Once the client makes their modification the reactive cloud functions will take over and perform the correct actions based on the data that was modified.

Why Not the Traditional SQL DB with Api endpoints?

I favour long term maintenance over an easier setup. I know the traditional backend infrastructure takes a lot of maintenance, initial setup and development work. Much more development work than firebase or something like Azure app services, or AWS's apps offering. So I take time for setup + time for maintenance + time for development and choose the lowest one to keep it simple. In this scenario its quite an easy win for Firebase because there's no setup or development time required. Just the continuous "maintenance" that changes as we use the product. But we don't have to develop our backend.

There's quite a lot of things to build if you don't use a backend infrastructure. About 3 times more than what we're building now. You have to think about caching, managing users data, building a socket implementation to get real-time functionality and many other things I can't think of. By cutting that out we're building a system that can be maintained by a single dedicated full-stack developer or a smaller team where each member focuses on an entire piece of the system. Maybe 3 devs where one does customer app and driver app, the other does restaurant app and restaurant manager and the last dev does all the backend work. If you were building your own backend you'd most likely need multiple developers to tackle the specific parts in the backend itself to get everything working.

The questions above comes from a good question by Taufeeq posted here check it out to see all the questions and more detailed answers in some cases.

Conclusion

We know the technical layout and setup required for us to theoretically build this system. This will be our foundation to stand on and we will work from here. This document will be modified and updated throughout the development of this product. If you feel that we can do something better, I want this to be an community influenced project so we can discuss, compare notes and make a decision together. Please consider joining the Slack and joining the boxtout channel in there. I'd be happy to have you chat a bit as we're building this.

Next up

Finally some code things, well kind of :D We're going to be setting up the firebase project and then creating the collections with some fake data to get our backend ready. We'll setup the different resources, link them to the firebase project and then hopefully, I hope we can get to this, generate fake data to work with. That'll be a big win if we can do that.