- Based on relationships every entity e.g. User, Team, Stock or any other should have their own defined “wallet” to which we could transfer money or withdraw
- Every request for credit/debit (deposit or withdraw) should be based on records in database for given model
- Every instance of a single transaction should have proper validations against required fields and their source and target wallet, e.g. from who we are taking money and transferring to whom? (Credits == source wallet == nil, Debits == target wallet == nil)
- Each record should be created in database transactions to comply with ACID standards
- Balance for given entity (User, Team, Stock) should be calculated by summing records
- Architect generic wallet solution (money manipulation) between entities (User, Stock, Team or any other)
- Create model relationships and validations for achieving proper calculations of every wallet, transactions
- Use STI (or any other design pattern) for proper money manipulation
- Back-end (preferably Rails) + tests of business logic: validations, operations, edge-cases (preferably RSpec)
- Front-end (any framework)
┌─────────────────────────────────────────────────┐
│ User (Devise) │
│─────────────────────────────────────────────────│
│ PK id integer NOT NULL │
│ email char(100) NOT NULL, UNIQUE CONSTRAINT │
│ role = person | team | stock - integer NOT NULL │
└─────────────────┬───────────────────────────────┘
│
│ 1:1
▼
┌───────────────────────────────────────────────────┐
│ Wallet │
│───────────────────────────────────────────────────│
│ PK id integer NOT NULL │
│ FK user_id integer NOT NULL │
│ balance float (cumulative after each transaction) │
└─────────────────┬─────────────────────────────────┘
│
│ 1 mandatory:many optional
▼
┌───────────────────────────────────────────────────┐
│ Transaction │
│───────────────────────────────────────────────────│
│ PK id integer NOT NULL │
│ FK1 source_wallet_id integer NOT NULL │
│ FK2 target_wallet_id integer NOT NULL │
│ amount float NOT NULL │
│ created_at datetimez NOT NULL │
└───────────────────────────────────────────────────┘
- Puma as simple, fast, multi-threaded server for Ruby/Rack applications
- Rake – Ruby Make, make-like build utility for Ruby
- All required gems installed with Bundler gem manager
- Devise - Flexible authentication solution for Rails with Warden.
- Letter Opener - Preview mail in the browser instead of sending.
- Testing:
- RSpec - testing tool for TDD/BDD
- rspec-rails - RSpec testing framework for Ruby on Rails
- Fuubar - instafailing RSpec formatter that uses a progress bar instead of a string of letters and dots as feedback.
- factory_bot, factory_bot_rails - fixtures replacement with a straightforward definition
syntax, support for multiple build strategies (saved instances, unsaved
instances, attribute hashes, and stubbed objects), and support for multiple
factories for the same class (
user
,admin_user
, and so on), including factory inheritance + provides Rails integration. - Faker - A library for generating fake data such as names, addresses, and phone numbers.
- Shoulda Matchers - Simple one-liner tests for common Rails functionality.
- Debug: Awesome Print - Pretty print your Ruby objects with style -- in full color and with proper indentation
- Code style is provided via RuboCop
- TODO: add more
- System: Linux, Mac
- Git
- SQLite3
- Node.js
- Yarn
- Ruby version manager (
rbenv
orRVM
) - Ruby 3.0.2
- Bundler
- Gems installed via Bundler Gemfile
Clone with SSH (or HTTPS):
$ git clone git@github.com:alex-petr/internal-wallet-transactional-system.git internal_wallet_transactional_system
$ cd internal_wallet_transactional_system/ && brew update && brew upgrade ; brew cleanup
$ brew install rbenv
$ rbenv install 3.0.2
$ gem install bundler && bundle
$ yarn install
$ rails db:migrate && rails db:migrate RAILS_ENV=test
$ rails db:seed
# On default 3000 port:
$ rails s
# With customized port (-p, --port PORT):
$ rails s -p 5000
# Default: Run all spec files (i.e., those matching spec/**/*_spec.rb)
$ rspec
# Run all spec files in a single directory (recursively)
$ rspec spec/services
# Run a single spec file
$ rspec spec/services/some_service_spec.rb
- Migrate to MySQL or PostgreSQL
- Add Brakeman, RubyCritic
- Add annotate, dotenv-rails, pry-byebug
- Improve Readme
- Move transaction operations to Sidekiq background workers
- Add CI (Drone.io, Circle CI etc): RuboCop, RSpec, Brakeman
- Add errors monitoring system (Rollbar, Sentry, Airbrake etc)
- Add Cucumber/Capybara feature tests
- Migrate to Rails JSON API and remove views to separated repo
- Migrate from custom Rails API to Grape API / Swagger
- Add RailsMoney gem