Skip to content

gabrielanhaia/bitcoin

Repository files navigation

CircleCI License

Transactions - Test

Author: Gabriel Anhaia
Email: Anhaia.gabriel@gmail.com

API Documentation

Running the project without docker

  1. For some reason the Guzzle Http can't access the same server when we are using (PHP built in / php artisan serve). So I recommend that you install in you machine Apache or Nginx and clone the folder inside your web directory. The index should be the folder public.

  2. Copy the file .env.example to .env and change the variables bellow with your database options: DB_CONNECTION=mysql DB_HOST=mysql DB_DATABASE=default DB_USERNAME=default DB_PASSWORD=secret DB_PORT=3306

  3. Run the command composer install

  4. Run php artisan key:generate

  5. Run php artisan migrate

  6. Run :exchange_rates:manual_import

  7. Enjoy :)

Running the project by Docker

  1. Access the folder laradock and run:
    docker-compose up -d nginx mysql

  2. Copy the file .env.example to .env and change the variables bellow with this values: DB_CONNECTION=mysql DB_HOST=mysql DB_DATABASE=default DB_USERNAME=default DB_PASSWORD=secret DB_PORT=3306

  3. Run the command composer install

  4. Run php artisan key:generate

  5. Run php artisan migrate

  6. Run :exchange_rates:manual_import

  7. Enjoy :)

About the Project

Important points about my test that I tried to follow (always):

  1. To write a clear code easily to maintain (any developer)
  2. Try to use Design Patterns (Only in situations that really make sense).
  3. to follow the SOLID principles
  4. Cover the project with Unit tests as much as possible (I wrote a few tests, It's not 100% covered).
  5. PHP and developing without a framework (on the integration packages to get the exchange rates)
  6. Organization (I used the Trello for controlling all tasks, I can share it with you if you would like).
  7. PSRs.
  8. Use different layers to organize the project when it grows (Repositories and Services)
  9. Micro commits with clear messages.

DONT FORGET TO LOOK AT THIS PACKAGE (It should be part of the test as an extra, unfortunatelly I didn't have enough time to finish)
https://github.com/gabrielanhaia/integration-api-bitcoin-rates

Important things implemented by me

  1. The transactions (Transfers) are stored at the database with a status 'PENDING', then, the transaction is send to a queue to be processed. The result can be two new status PROCESSED or NOT_PROCESSED (When something wrong happens).
  2. Transaction types: There are 4 types TRANSFER_DEBIT (The wallet that sends the money), TRANSFER_CREDIT (The wallet that receives the money), DEBIT (When the account receive money from another source, it could be a deposit, first wallet, etc), CREDIT (It could be when someone use a debit card or cash the money).
  3. Repository layer: It implemented it to encapsulate the ORM (eloquent/data sources). Who knows if in the future we will change the things.
  4. My repositories are receiving and returning Entities. I try to use this patter in big projects because it's much better the arrays that can't guarantee the data passed to the methods. Besides that, with Entities (DTO), We can easily change the data source in the repositories (if it is necessary).
  5. I am using the Service Layer to put the logic, on this way it's easier for the developers to maintain the project. Besides that, it is easier to test.
  6. The repositories, services and models are all being injected by the Container (DI Laravel).
  7. I am versioning the API, if we have APPs, web platforms and/or external integrations consuming our API, it will be easier to change/improve the endpoints.
  8. The API token is really simple (as the required), it's just a api_token on the user table, in a real project we would think about a JWT token and maybe user OAuth...
  9. I put all the models in an especific directory (I do not know why the Laravel don't change it, it is a mess).
  10. The database was projected with index to speed up the queries (You can see the model on database/, there are a few files there.
  11. I am getting the properties by the objects and you can see that in some layers I am not getting the object in the return (just using the normal behavior of the objects), for sure I agree it would be defined at the beginning of the project. I think it is an important thing to be defined, new developers can get confused with the object references.
  12. To be sure that the last amount is correct I am getting by the transaction order (processed_at) (status = PROCESSED)
  13. There are maybe 2 comments inside the methods (to explain something). I would never put a comment inside a method. I follow the principle that any developer should look at a method and understand it by himself.
  14. In a real application, I would create an account (Company Account/Pa...l) to store the company bitcoins to transfer the initial amount (debit) and earn the profit (credit)
  15. I created a table to store settings (You can see there the "Maximum of wallets per user", "Bonus of bitcoins for new users" and "Profit per transfers between different users")
  16. I created a manual importer (app/Console/Commands/ManualImportExchangeRates.php) for the exchange rates. I created it just to import all the rates quickly, so I can test my endpoints. My goal is to start the official importer (integration with the API) if I don't have enough time to do everything I am planning for the project.
  17. The transactions are processed in a Queue (centralized), in production environment we could use REDIS and have different machines running our webserver. All of then would send the jobs to be processed in the same queue.

The problems founded and observations

I have found different problems to solve in this project, a few of them were:

  1. The security (It is working with money).
  2. Don't lose transactions (never).
  3. Keep the transactions/balance organized.
  4. Loads of validations to don't duplicate or allow the users earn bitcoins.

Technologies/Methodologies

PHP 7.3 Laravel Docker/Laradock Composer MySql 5.7 PHPUnit: CircleCi: Trello: I tried to follow the scrum principles (actually planning and using the kanban) to keep the project organized. In the cards, there are the number of the issues on GitHub. PSRs: I am following the PSR's for a clean code. ** Another technologies:** GitHub, GIT

Tests

I didn't implement all unit tests, there are more unit tests on the packages (integrations). But there are a few important tests that could be checked.

Running the tests: php vendor/bin/phpunit

Things to improve

  1. Database: I don't think mysql is a problem, but I was searching about different approaches ant technologies, I found new digital banks that have a similar structure of the transaction tables. They are using a database called Datomic (https://www.datomic.com/nubanks-story.html) It is really interesting.
  2. Security
  3. An account to store the Company Bitcoins (profit, bonus for first wallets...)
  4. Helpers.

License

It is open-sourced software licensed under the MIT license.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published