tulak / referrals

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Description

Ruby on Rails application implementing an API using GraphQL. The API listens on path /graphql and responds to POST requests. The /graphiql endpoint is available to explore the API using graphical tool called GraphiQL. PostgreSQL is used as database for ActiveRecord

Architecture

The application consists of 2 models User and Transaction. The User model is used for authentication using devise. It holds information about registered users and referrals. The Transaction model holds information about the account transactions of the user. The type of transaction is determined by code column. Appication implements 2 types of transactions (REFERRER_BONUS and REFERRALS_BONUS). New transaction types should be added by implementing new codes.

The application implements 2 types of rewards that can be achieved upon registration ReferredBonus and ReferralsBonus. Each reward business logic is implemented in a service object in services/user_services/.

ReferredBonus adds fixed amount to user's account if the registered user used a valid referral token.

ReferralsBonus adds fixed amount to user's account if 5 new users registered using user's referral token

Design Decisions

Ruby on Rails, PostgreSQL, RSpec and Graphql was used because of my personal preference. The devise and devise-jwt gems were used for authentication instead of implementing custom authentication method because it is battle tested by the community.

Two different rewards were identified and implemented as separate service objects. Unit and integration tests are used to maintain working functionality of these objects.

The account balance was implemented using Transaction model to support extensibility.

API Methods

The application implements following GraphQL Schema:

"""
Autogenerated return type of Login
"""
type LoginPayload {
  error: String
  jwt: String
  success: Boolean!
}

type Mutation {
  login(email: String!, password: String!): LoginPayload
  register(email: String!, password: String!, passwordConfirmation: String!, referralToken: String): RegisterPayload
}

type Query {
  currentUser: User
}

"""
Autogenerated return type of Register
"""
type RegisterPayload {
  errors: [String!]

  """
  Result of the registration process
  """
  success: Boolean!
  user: User
}

type User {
  balance: Float!
  email: String!
  id: ID!
  referralToken: String
}

It is expected for the front-end developer to understand how GraphQL API works and how to use the schema types.

Authentication

Application uses JWT based authentication implemented using battle tested gems devise and devise-jwt.

The client logs in using register mutation and receives JWT token. This token is valid ofr 12 hours and identifies authenticated request when included in the HTTP headers of the API request:

Header Name: Authorization 
Header Value: Bearer <token>

Development Setup

Clone the repository and install gems using Bundler

$ git clone https://github.com/tulak/referrals.git referrals
$ cd referrals
$ bundle

Create database and migrate the schema

$ rails db:create
$ rails db:migrate

Run tests

$ rspec spec/

About


Languages

Language:Ruby 88.5%Language:HTML 6.4%Language:JavaScript 4.3%Language:CSS 0.8%