- Ruby 2.6 >
- Yarn 1.22 >
- SQLite
> git clone git@github.com:ggstroligo/sales.git
> bundle install
> yarn
> bin/webpack
> rails s -p 3000Access 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.tabis 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
