- Ruby 2.6 >
- Yarn 1.22 >
- SQLite
> git clone [email protected]:ggstroligo/sales.git
> bundle install
> yarn
> bin/webpack
> rails s -p 3000
Access on browser localhost:3000 You have example of .tab files on /docs/examples to upload on the application.
You've received a text file (tab separated) with data describing the company sales. We need a way for this data to be imported to a database to be analyzed later.
Your job is to create a web interface that accepts file uploads, normalizes the data and stores it in a relational database.
Your application MUST:
- Accept (via HTML form) file uploads of TAB-separated files, with the following columns:
purchaser name
,item description
,item price
,purchase count
,merchant address
,merchant name
. You can assume the columns will always be in that order, and that there will always be some value in each column, and that there will always be a header row. An example file calledexample_input.tab
is included on this repo. - Interpret (parse) the received file, normalize the data, and save the data correctly in a relational database. Don't forget to model the entities imported from the file data, considering their relationships.
- Show the total gross income represented by the sales data after each file upload, and also the total all-time gross income.
- Be written in Ruby 2.5 or greater (or, in the language solicited by the job description, if any).
- Have good automated tests coverage.
- Be simple to configure and execute, running on a Unix-compatible environment (Linux or macOS).
- Use only free / open-source language and libraries.
I chose to do this challenge using a use-case based architecture, which is a bit of what I've been studying recently. It wasn't exactly as I would have liked due to the lack of time I had to complete it, but I liked the final result.
With that said, let's cut to the chase.
At the first, I made an entity relationship diagram (ERD) to have a well-defined path.
About the DBMS I chose SQLite, cause of it practicity
Then, I start thinking about the architecture, and as I said, I chose to use a use-case based architecture, instead of bloated services.
At the first I thought a file structure like:
models/
..customer.rb
..merchant.rb
..order.rb
..product.rb
..sale.rb
..order/
....item.rb
use_cases/ (hold all complex use case flow logics)
..sales_report/
....collect.rb
....step/
......parse_entry.rb
......persist_data.rb
services/
..presenters/ (prepare view data based on controller#action)
....sales/
......index.rb
......show.rb
- Abstract queries steps into a base class
- Add helper/delegator methods to models
- Improve serialization base
- Improve front-end with any modern reactive framework (hotwire, react)
- Improve error handler