2.3 KiB
2.3 KiB
Market: referral
Sprint: ?
Outcome:
users can invite other users.if an user sign up with another user invitation code, exchange gives inviter a bonus to encourage people to join our exchange. bonus amount is a percent of trade fee.
File destination:
{$Dena_Path}/app/jobs/referral_bonus.rb
{$Dena_Path}/app/models/bonus.rb
Commits:
What did we implement:
first of we need a table to save bonuses. we create bonus table.its columns are:
- trade_id: foreign key to trade tables.this shows that this bonus was created from which trade.
- sender_member_id: foreign key to members tables.this shows bonus was created from which member trade(invited memebr).
- bonus_member_id: foreign key to members tables.this shows bonus was sent to which member(inviter member).
- amount: amoutn of bonus
- state: state of bonus { pending: 0, payed: 1, rejected: 2 }
- we have an validation on creating bonus for avoiding duplication and double paying.
validates_uniqueness_of :trade, :scope => [:sender_member_id]
this means that can not create bonus with same trade AND same sender.
- we created a cron job that runs every 24 hour (we plan to run it in midnights to avoid putting pressure on server) This is how it works:
- select all last 24 hour revenues and process them in batch of 1000.
- get them one by one and convert them to rial and multiply them with referral bonus percent.
- create bonus, update users balance(with lock version) and create on revenue debit for accounting system(we cant lost money in system)
- all calculations and db updates that related about money(critical calculations) are in transaction so if one of them blocked or rejected all changes rollbacked .
graph TD
title:referral_job
A[loop:batch 1000] -->|1000 of last 24h| B(one of revenue)
B -->|revenue| D{has referral}
D -->|no| B
D -->|yes| F{is in rial}
F -->|yes| I
F -->|no| H[convert to irt]
H --> I[calculation bonus amount]
I --> J[changes balance]
J --> K[create bonus and accounting things]
K --> L{error happend?}
L --> |yes| M[roll back everything]
L --> |no| P
M --> O[create bonus with pending state]
O --> P{1000 ended?}
P -->|yes| A
P -->|no| B