GithubHelp home page GithubHelp logo

makemek / line-liff Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 1.0 951 KB

Pub/sub coffee shop (a coding test for LINE company)

Home Page: https://docs.google.com/document/d/1TmPiojL_HRk8T09NDkPAXx_ZshSKT_VieREeblsJAU8/edit?usp=sharing

TypeScript 57.57% HTML 24.41% CSS 5.16% JavaScript 11.82% Dockerfile 1.04%

line-liff's Introduction

To run the project

docker-compose up -d

Then, open a browser and navigate to

localhost:3000

Pre-assumptions I made

To simplify the use case and to make coding less complicated, I assumes that

  • When placing orders, customer is already authenticated.

No matter how many orders placed, it will come from the same customer. So that I can push notification to the customer without having to do authentication just to differentiate each customer's request.

Answer

I pick javascript (Nodejs) because the project doesn't require doing any performance intensive operations on the backend. Tasks are about handling HTTP requests, responding to events, and communicating with external services. Nodejs is excellent at dealing with asynchronous tasks.

C# (.NET) is also a good alternative for handling asynchronous tasks. It is a compiled language that offers strongly typed OOP. The performance is on par with Nodejs. Unlike .NET, Nodejs doesn't have type-checking feature. Typescript, an extension language to javascript, offers a type-checking and can run inside Nodejs by transpiling the code to javascript.

Both of these languages are suitable for the project. Though, .NET is a little more cumbersome to deploy than Nodejs because supports on linux container are limited.

Nodejs is what I am comfortable with. Therefore, it is the language that I choose to implement in this project.

What about database ?

From a specification that I read, there are two entities.

  • Product
  • Order

Order can contain product(s). However the product is not a Product entity. It is a snapshot of Product. If products are updated or deleted, orders that have those products shouldn't be updated along with. Order should contain the history of products ordered, not the Product entity itself. Product and Order have no relationship with each other.

There are two choices when it comes to choosing a database

  • Relational database

Suitable for data that have simple relationships, table-like structure, requires integrity, and strict validation.

  • Non-relational database

Suitable for data with little to no relationships with other entities, soft validation, and having a predefined schema upfront is not necessary.

Graph database is also a part of Non-relational database. It is suitable for data with complex relationships between entities. Relationships have main priority over entity.

As stated about Product and Order entities, there is no relationship between them. A non-relational database is suitable for the project. Order that can contain product snapshots means that I need a database which is suitable for embedding object-like data into the entity. I found that MongoDB is what I am looking for. MongoDB represents stored data in JSON. Because of flexible schema, I can insert any extra product information to Order without having to define a model about it. They are rarely updated anyway so it shouldn't be a problem in long term.

How might you improve this system?

Frontend needs more styling

I just want to have a simple interface to interact with the backend. I applied little styling to them.

Makes frontend more scaleable

In its current state, they are implemented using plain HTML and unoptimized javascript with Vuejs running as a framework. The frontend should be in a separate repository with its own code base structure and with more proper bundling tool. It should run on its own server so that it doesn't depend on backend building configuration.

Even what customer interacts on the frontend and what admin interacts on back office can also be split to a different repository as web and backoffice respectively.

Time is limited, even too short for me, I plan to do it in one project anyway so that it is easy to install and deploy. The question emphasizes more on how things should work, not appearances.

Are there any design flaws?

Customer can place one product per order

The specification doesn't define about it, so I chose an easiest route. That is once the customer clicks on product, an order is sent to back office where admin can serve the order.

Server doesn't close connection when it becomes stale

Because I use server-sent event (SSE) to have server push event notification to client. The server doesn't close a connection when it becomes idle for a long time. The server may consumes a lot of memory or even cause a memory leak if lots of clients are connected to the SSE route at the same time.

The reason I pick SSE over websocket is because it is simple to implement. Clients only reads from event that server sent. So it is unidirectional, not bidirectional in websocket.

Using websocket is overkill in my opinion as client doesn't have to talk on the same channel. Client doesn't talk back to server frequently, so HTTP overhead is not a problem to the point that I have to use websocket over SSE.

Customer may not be there to receive a notification

If customer explicitly close a connection to the server such as closing a tab on their browser, order message event published by Redis is lost forever. If notifications have to be preserved, we can use AWS SQS or RabbitMQ to queue messages and consume when needed.

Usage of mongo object _id as an identifier

Mongo's generated ids are not human readable. It is difficult to communicate among teams or stakeholders. It is more preferable to use custom id based on business requirements. For example, Product can use SKU as an identifier. Order can use custom id like LIF-000001.

Are there any additional features that could be added to this system?

  • Customer can choose multiple products before making an order
  • An authentication to customer when making an order
  • Ability to upload image file from back office to a cloud provider such as Cloudinary, AWS S3, or Google Cloud Storage

line-liff's People

Contributors

makemek avatar

Watchers

James Cloos avatar  avatar

Forkers

piyapong-nake

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.