scorecard 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 06e11f730ab8af962e70b4942175fa861d736ef4
4
- data.tar.gz: bc09ee07cb46b2ebc3de67fae7fab333166735c3
3
+ metadata.gz: 1232899ca7b26af8e4a8d8af2baaae024343a688
4
+ data.tar.gz: c3c252f4debd3424989324fa5a0b239a13f90185
5
5
  SHA512:
6
- metadata.gz: 21dd7bb81cca83651312ac334966664ec05daaf345cc576300e2ecbbc0e6a9521534ebb70cd1e71df3a324c12298ef20ed6de30e03b9b16deaa2b3f09261175b
7
- data.tar.gz: e23a940cdcd60c314ee23d555279bb912cb437244020d3b70357b2b06033a5cacb3f8f95d9e89a17cf48e33c2f6c4ce84799bd42d338ab32a004787e7ea7af08
6
+ metadata.gz: 2dee14b5121ee947bf95bd12d17ed95a08b36cbb5e6aa469871d7582129c0b48b3b3517f3332790adf72a75df7e1a134008a5f20f63b4c65f87ce9260a8eaa2e
7
+ data.tar.gz: 88d9897dd851e560050b03bfeb8b88258264ff0c580dcba90b7f7b1efda7eda10109e50b11aab721de74e39523c202fff8b1fd8718e031bf4cf36a2c17a27950
data/README.md CHANGED
@@ -8,7 +8,7 @@ For anyone who comes across this, please note this is not yet feature complete,
8
8
 
9
9
  Add this line to your application's Gemfile:
10
10
 
11
- gem 'scorecard', '0.0.2'
11
+ gem 'scorecard', '0.0.3'
12
12
 
13
13
  Don't forget to bundle:
14
14
 
@@ -23,36 +23,68 @@ Then, add the migrations to your app and update your database accordingly:
23
23
  In an initializer, define the events that points are tied to - with a unique context and the number of points:
24
24
 
25
25
  ```ruby
26
- Scorecard::PointRule.new :new_post, 50
26
+ Scorecard.configure do |config|
27
+ config.rules.add_rule :new_post, 50
28
+ end
27
29
  ```
28
30
 
29
31
  You can also provide a block with logic for whether to award the points, the maximum number of points allowed to be awarded for this rule, and the timeframe for that limit:
30
32
 
31
33
  ```ruby
32
- Scorecard::PointRule.new :new_post, 50, limit: 100, timeframe: :day,
34
+ Scorecard.configure do |config|
35
+ config.rules.add_rule :new_post, 50, limit: 100, timeframe: :day,
33
36
  if: lambda { |payload| payload[:user].posts.count <= 1 }
37
+ end
34
38
  ```
35
39
 
36
40
  The payload object contains the context plus every option you send through to `score` call (see below).
37
41
 
42
+ For levels, you can set the central piece of logic that calculates the user's current level in the initializer as well:
43
+
44
+ ```ruby
45
+ Scorecard.configure do |config|
46
+ config.levels = lambda { |user|
47
+ if user.created_at > 2.years.ago
48
+ 3
49
+ elsif user.created_at > 1.year.ago
50
+ 2
51
+ else
52
+ 1
53
+ end
54
+ }
55
+ end
56
+ ```
57
+
38
58
  ## Scoring
39
59
 
40
60
  And then, when you want to fire those events, use code much like the following:
41
61
 
42
62
  ```ruby
43
- Scorecard::Points.score :new_post, gameable: post
63
+ Scorecard::Scorer.points :new_post, gameable: post
44
64
  ```
45
65
 
46
66
  This presumes that the user the points are for is a method on the gameable object. If that's not the case, you can pass in a custom user:
47
67
 
48
68
  ```ruby
49
- Scorecard::Points.score :new_post, gameable: post, user: user
69
+ Scorecard::Scorer.points :new_post, gameable: post, user: user
50
70
  ```
51
71
 
52
72
  If you're using Sidekiq, you can push the scoring behaviour into a background worker using `score_async` instead. Make sure `scorecard` is listed below `sidekiq` in your `Gemfile`.
53
73
 
54
74
  ```ruby
55
- Scorecard::Points.score_async :new_post, gameable: post
75
+ Scorecard::Scorer.points_async :new_post, gameable: post
76
+ ```
77
+
78
+ Whenever you want to recalculate a user's level, run the following:
79
+
80
+ ```ruby
81
+ Scorecard::Scorer.level user
82
+ ```
83
+
84
+ To remove points related to a given gameable object, you can use the Scorecard::Cleaner class:
85
+
86
+ ```ruby
87
+ Scorecard::Cleaner.points post
56
88
  ```
57
89
 
58
90
  ## Results
@@ -60,7 +92,13 @@ Scorecard::Points.score_async :new_post, gameable: post
60
92
  To get the current points count for a given user:
61
93
 
62
94
  ```ruby
63
- Scorecard::Points.for user
95
+ Scorecard::Card.new(user).points
96
+ ```
97
+
98
+ And the current level:
99
+
100
+ ```ruby
101
+ Scorecard::Card.new(user).level
64
102
  ```
65
103
 
66
104
  ## Contributing
@@ -0,0 +1,17 @@
1
+ class Scorecard::Level < ActiveRecord::Base
2
+ self.table_name = 'scorecard_levels'
3
+
4
+ belongs_to :user, polymorphic: true
5
+
6
+ if Rails.version.to_s < '4.0.0'
7
+ attr_accessible :amount, :user
8
+ end
9
+
10
+ validates :amount, presence: true
11
+ validates :user, presence: true
12
+ validates :user_id, uniqueness: {scope: :user_type}
13
+
14
+ def self.for_user(user)
15
+ where(user_id: user.id, user_type: user.class.name).first
16
+ end
17
+ end
@@ -4,6 +4,10 @@ class Scorecard::Point < ActiveRecord::Base
4
4
  belongs_to :user, polymorphic: true
5
5
  belongs_to :gameable, polymorphic: true
6
6
 
7
+ if Rails.version.to_s < '4.0.0'
8
+ attr_accessible :context, :identifier, :amount, :gameable, :user
9
+ end
10
+
7
11
  validates :context, presence: true
8
12
  validates :identifier, presence: true, uniqueness: {
9
13
  scope: [:context, :user_type, :user_id]
@@ -19,6 +23,10 @@ class Scorecard::Point < ActiveRecord::Base
19
23
  where user_id: user.id, user_type: user.class.name
20
24
  end
21
25
 
26
+ def self.for_gameable(gameable)
27
+ where gameable_id: gameable.id, gameable_type: gameable.class.name
28
+ end
29
+
22
30
  def self.for_user_in_timeframe(context, user, timeframe)
23
31
  for_context(context).for_user(user).where(created_at: timeframe)
24
32
  end
@@ -0,0 +1,12 @@
1
+ class CreateLevels < ActiveRecord::Migration
2
+ def change
3
+ create_table :scorecard_levels do |table|
4
+ table.integer :amount, null: false
5
+ table.string :user_type, null: false
6
+ table.integer :user_id, null: false
7
+ table.timestamps
8
+ end
9
+
10
+ add_index :scorecard_levels, [:user_type, :user_id], unique: true
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ class Scorecard::Card
2
+ attr_reader :user
3
+
4
+ def initialize(user)
5
+ @user = user
6
+ end
7
+
8
+ def level
9
+ @level ||= begin
10
+ record = Scorecard::Level.for_user(user)
11
+ record.nil? ? Scorecard.levels.call(user) : record.amount
12
+ end
13
+ end
14
+
15
+ def points
16
+ @points ||= Scorecard::Point.for_user(user).sum(:amount)
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ class Scorecard::Cleaner
2
+ def self.points(gameable)
3
+ Scorecard::Point.for_gameable(gameable).each do |point|
4
+ point.destroy
5
+ ActiveSupport::Notifications.instrument 'scorecard', user: point.user
6
+ end
7
+ end
8
+
9
+ def self.points_async(gameable)
10
+ Scorecard::ClearWorker.perform_in 10.seconds, gameable.class.name,
11
+ gameable.id
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ class Scorecard::ClearWorker
2
+ include Sidekiq::Worker
3
+
4
+ def perform(class_name, id)
5
+ Scorecard::Cleaner.points class_name.constantize.find(id)
6
+ end
7
+ end
@@ -5,11 +5,11 @@ class Scorecard::Rules
5
5
  @point_rules = []
6
6
  end
7
7
 
8
- def add_rule_for_points(context, amount, options = {})
8
+ def add_rule(context, amount, options = {})
9
9
  point_rules << Scorecard::PointRule.new(context, amount, options)
10
10
  end
11
11
 
12
- def find_rule_for_points(context)
12
+ def find_rule(context)
13
13
  point_rules.detect { |rule| rule.context == context }
14
14
  end
15
15
 
@@ -1,4 +1,4 @@
1
- class Scorecard::Worker
1
+ class Scorecard::ScoreWorker
2
2
  include Sidekiq::Worker
3
3
 
4
4
  def perform(context, options)
@@ -9,6 +9,6 @@ class Scorecard::Worker
9
9
  options[prefix] = klass.find options.delete("#{prefix}_id")
10
10
  end
11
11
 
12
- Scorecard::Points.score context.to_sym, options.symbolize_keys
12
+ Scorecard::Scorer.points context.to_sym, options.symbolize_keys
13
13
  end
14
14
  end
@@ -0,0 +1,27 @@
1
+ class Scorecard::Scorer
2
+ def self.level(user)
3
+ level = Scorecard::Level.for_user(user) || Scorecard::Level.new(user: user)
4
+ level.amount = Scorecard.levels.call user
5
+ return unless level.amount_changed?
6
+
7
+ level.save
8
+ ActiveSupport::Notifications.instrument 'level.scorecard', user: user
9
+ end
10
+
11
+ def self.points(context, options)
12
+ ActiveSupport::Notifications.instrument 'points.scorecard',
13
+ options.merge(context: context)
14
+ end
15
+
16
+ def self.points_async(context, options)
17
+ [:gameable, :user].each do |prefix|
18
+ next unless options[prefix]
19
+
20
+ options["#{prefix}_id"] = options[prefix].id
21
+ options["#{prefix}_type"] = options[prefix].class.name
22
+ options.delete prefix
23
+ end
24
+
25
+ Scorecard::ScoreWorker.perform_async context, options.stringify_keys
26
+ end
27
+ end
@@ -14,7 +14,7 @@ class Scorecard::Subscriber
14
14
  end
15
15
 
16
16
  def points(event)
17
- rule = Scorecard.rules.find_rule_for_points event.payload[:context]
17
+ rule = Scorecard.rules.find_rule event.payload[:context]
18
18
 
19
19
  event.payload[:amount] ||= rule.amount
20
20
  event.payload[:identifier] ||= event.payload[:gameable].id
@@ -22,8 +22,11 @@ class Scorecard::Subscriber
22
22
 
23
23
  return unless rule && rule.allowed?(event.payload)
24
24
 
25
- Scorecard::Point.create(
25
+ point = Scorecard::Point.create(
26
26
  event.payload.slice(:context, :amount, :identifier, :user, :gameable)
27
27
  )
28
+ ActiveSupport::Notifications.instrument(
29
+ 'scorecard', user: event.payload[:user]
30
+ ) if point.persisted?
28
31
  end
29
32
  end
data/lib/scorecard.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Scorecard
2
+ mattr_accessor :levels
3
+
2
4
  def self.configure
3
5
  yield self
4
6
  end
@@ -8,9 +10,15 @@ module Scorecard
8
10
  end
9
11
  end
10
12
 
13
+ require 'scorecard/card'
14
+ require 'scorecard/cleaner'
11
15
  require 'scorecard/engine'
12
- require 'scorecard/points'
13
16
  require 'scorecard/point_rule'
14
17
  require 'scorecard/rules'
18
+ require 'scorecard/scorer'
15
19
  require 'scorecard/subscriber'
16
- require 'scorecard/worker' if defined?(Sidekiq)
20
+
21
+ if defined?(Sidekiq)
22
+ require 'scorecard/clear_worker'
23
+ require 'scorecard/score_worker'
24
+ end
data/scorecard.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  Gem::Specification.new do |spec|
3
3
  spec.name = 'scorecard'
4
- spec.version = '0.0.2'
4
+ spec.version = '0.0.3'
5
5
  spec.authors = ['Pat Allan']
6
6
  spec.email = ['pat@freelancing-gods.com']
7
7
  spec.summary = 'Rails Engine for common scorecard patterns'
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Clearing Points' do
4
+ let(:post) { Post.create! user: user }
5
+ let(:user) { User.create! }
6
+
7
+ before :each do
8
+ Scorecard.configure do |config|
9
+ config.rules.add_rule :new_post, 50
10
+ end
11
+
12
+ post
13
+ end
14
+
15
+ it 'removes points for a given gameable object' do
16
+ expect(Scorecard::Card.new(user).points).to eq(50)
17
+
18
+ Scorecard::Cleaner.points(post)
19
+
20
+ expect(Scorecard::Card.new(user).points).to eq(0)
21
+ end
22
+
23
+ it 'clears points via Sidekiq' do
24
+ expect(Scorecard::Card.new(user).points).to eq(50)
25
+
26
+ Scorecard::Cleaner.points_async(post)
27
+
28
+ expect(Scorecard::Card.new(user).points).to eq(0)
29
+ end
30
+
31
+ it "fires a generic notification" do
32
+ fired = false
33
+
34
+ subscriber = ActiveSupport::Notifications.subscribe 'scorecard' do |*args|
35
+ event = ActiveSupport::Notifications::Event.new(*args)
36
+ fired = (event.payload[:user] == user)
37
+ end
38
+
39
+ Scorecard::Cleaner.points_async(post)
40
+
41
+ ActiveSupport::Notifications.unsubscribe(subscriber)
42
+
43
+ expect(fired).to be_true
44
+ end
45
+ end
46
+
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levels' do
4
+ let(:user) { User.create! email: 'pat-new' }
5
+
6
+ before :each do
7
+ Scorecard.configure do |config|
8
+ config.levels = lambda { |user|
9
+ user.email[/old/] ? 2 : 1
10
+ }
11
+ end
12
+ end
13
+
14
+ it "saves the score for the user" do
15
+ Scorecard::Scorer.level user
16
+
17
+ level = Scorecard::Level.where(user_id: user.id, user_type: 'User').first
18
+ expect(level.amount).to eq(1)
19
+ end
20
+
21
+ it "fires a level notification when the level is first set" do
22
+ fired = false
23
+
24
+ subscriber = ActiveSupport::Notifications.subscribe 'level.scorecard' do |*args|
25
+ event = ActiveSupport::Notifications::Event.new(*args)
26
+ fired = (event.payload[:user] == user)
27
+ end
28
+
29
+ Scorecard::Scorer.level user
30
+
31
+ ActiveSupport::Notifications.unsubscribe(subscriber)
32
+
33
+ expect(fired).to be_true
34
+ end
35
+
36
+ it "fires a level notification when the level is changed" do
37
+ Scorecard::Scorer.level user
38
+ user.update_attributes(email: 'pat-old')
39
+
40
+ fired = false
41
+
42
+ subscriber = ActiveSupport::Notifications.subscribe 'level.scorecard' do |*args|
43
+ event = ActiveSupport::Notifications::Event.new(*args)
44
+ fired = (event.payload[:user] == user)
45
+ end
46
+
47
+ Scorecard::Scorer.level user
48
+
49
+ ActiveSupport::Notifications.unsubscribe(subscriber)
50
+
51
+ expect(fired).to be_true
52
+ end
53
+
54
+ it "does not fire a notification when the level remains the same" do
55
+ Scorecard::Scorer.level user
56
+
57
+ fired = false
58
+
59
+ subscriber = ActiveSupport::Notifications.subscribe 'level.scorecard' do |*args|
60
+ event = ActiveSupport::Notifications::Event.new(*args)
61
+ fired = (event.payload[:user] == user)
62
+ end
63
+
64
+ Scorecard::Scorer.level user
65
+
66
+ ActiveSupport::Notifications.unsubscribe(subscriber)
67
+
68
+ expect(fired).to be_false
69
+ end
70
+
71
+ it "retrieves stored level for a user" do
72
+ Scorecard::Scorer.level user
73
+
74
+ expect(Scorecard::Card.new(user).level).to eq(1)
75
+ end
76
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Reading points' do
4
+ it "returns the total points for a user" do
5
+ Scorecard.configure do |config|
6
+ config.rules.add_rule :new_user, 20
7
+ config.rules.add_rule :new_post, 30
8
+ end
9
+
10
+ user = User.create!
11
+ post = Post.create! user: user
12
+ Scorecard::Scorer.points :new_user, gameable: user, user: user
13
+
14
+ expect(Scorecard::Card.new(user).points).to eq(50)
15
+ end
16
+ end
@@ -1,19 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Scorecard' do
4
- before :each do
5
- Scorecard.rules.clear
6
- end
7
-
3
+ describe 'Scoring points' do
8
4
  it "stores points for configured behaviour" do
9
5
  Scorecard.configure do |config|
10
- config.rules.add_rule_for_points :new_post, 50
6
+ config.rules.add_rule :new_post, 50
11
7
  end
12
8
 
13
9
  user = User.create!
14
10
  post = Post.create! user: user
15
11
 
16
- Scorecard::Point.where(
12
+ points = Scorecard::Point.where(
17
13
  context: 'new_post',
18
14
  amount: 50,
19
15
  identifier: post.id.to_s,
@@ -21,12 +17,13 @@ describe 'Scorecard' do
21
17
  user_type: 'User',
22
18
  gameable_id: post.id,
23
19
  gameable_type: 'Post'
24
- ).should_not be_empty
20
+ )
21
+ expect(points).to_not be_empty
25
22
  end
26
23
 
27
24
  it "only stores points when provided logic passes" do
28
25
  Scorecard.configure do |config|
29
- config.rules.add_rule_for_points :new_post, 50,
26
+ config.rules.add_rule :new_post, 50,
30
27
  if: lambda { |payload| Post.count <= 1 }
31
28
  end
32
29
 
@@ -34,22 +31,23 @@ describe 'Scorecard' do
34
31
  post = Post.create! user: user
35
32
  post = Post.create! user: user
36
33
 
37
- Scorecard::Point.where(
34
+ count = Scorecard::Point.where(
38
35
  context: 'new_post',
39
36
  amount: 50
40
- ).count.should == 1
37
+ ).count
38
+ expect(count).to eq(1)
41
39
  end
42
40
 
43
41
  it "does not double-up on points for the same event" do
44
42
  Scorecard.configure do |config|
45
- config.rules.add_rule_for_points :new_post, 50
43
+ config.rules.add_rule :new_post, 50
46
44
  end
47
45
 
48
46
  user = User.create!
49
47
  post = Post.create! user: user
50
- Scorecard::Points.score :new_post, gameable: post
48
+ Scorecard::Scorer.points :new_post, gameable: post
51
49
 
52
- Scorecard::Point.where(
50
+ count = Scorecard::Point.where(
53
51
  context: 'new_post',
54
52
  amount: 50,
55
53
  identifier: post.id.to_s,
@@ -57,12 +55,13 @@ describe 'Scorecard' do
57
55
  user_type: 'User',
58
56
  gameable_id: post.id,
59
57
  gameable_type: 'Post'
60
- ).count.should == 1
58
+ ).count
59
+ expect(count).to eq(1)
61
60
  end
62
61
 
63
62
  it "respects limit options" do
64
63
  Scorecard.configure do |config|
65
- config.rules.add_rule_for_points :new_post, 50, limit: 100
64
+ config.rules.add_rule :new_post, 50, limit: 100
66
65
  end
67
66
 
68
67
  user = User.create!
@@ -70,36 +69,32 @@ describe 'Scorecard' do
70
69
  post = Post.create! user: user
71
70
  post = Post.create! user: user
72
71
 
73
- Scorecard::Point.where(
74
- context: 'new_post',
75
- amount: 50
76
- ).count.should == 2
72
+ count = Scorecard::Point.where(context: 'new_post', amount: 50).count
73
+ expect(count).to eq(2)
77
74
  end
78
75
 
79
76
  it "respects timeframe options" do
80
77
  Scorecard.configure do |config|
81
- config.rules.add_rule_for_points :new_post, 50, timeframe: :day
78
+ config.rules.add_rule :new_post, 50, timeframe: :day
82
79
  end
83
80
 
84
81
  user = User.create!
85
82
  post = Post.create! user: user
86
83
  post = Post.create! user: user
87
84
 
88
- Scorecard::Point.where(
89
- context: 'new_post',
90
- amount: 50
91
- ).count.should == 1
85
+ count = Scorecard::Point.where(context: 'new_post', amount: 50).count
86
+ expect(count).to eq(1)
92
87
  end
93
88
 
94
89
  it "allows for processing via Sidekiq" do
95
90
  Scorecard.configure do |config|
96
- config.rules.add_rule_for_points :new_user, 20
91
+ config.rules.add_rule :new_user, 20
97
92
  end
98
93
 
99
94
  user = User.create!
100
- Scorecard::Points.score_async :new_user, gameable: user, user: user
95
+ Scorecard::Scorer.points_async :new_user, gameable: user, user: user
101
96
 
102
- Scorecard::Point.where(
97
+ points = Scorecard::Point.where(
103
98
  context: 'new_user',
104
99
  amount: 20,
105
100
  identifier: user.id.to_s,
@@ -107,19 +102,27 @@ describe 'Scorecard' do
107
102
  user_type: 'User',
108
103
  gameable_id: user.id,
109
104
  gameable_type: 'User'
110
- ).should_not be_empty
105
+ )
106
+ expect(points).to_not be_empty
111
107
  end
112
108
 
113
- it "returns the total points for a user" do
109
+ it "fires a generic notification" do
114
110
  Scorecard.configure do |config|
115
- config.rules.add_rule_for_points :new_user, 20
116
- config.rules.add_rule_for_points :new_post, 30
111
+ config.rules.add_rule :new_post, 50
112
+ end
113
+
114
+ fired = false
115
+ user = User.create!
116
+
117
+ subscriber = ActiveSupport::Notifications.subscribe 'scorecard' do |*args|
118
+ event = ActiveSupport::Notifications::Event.new(*args)
119
+ fired = (event.payload[:user] == user)
117
120
  end
118
121
 
119
- user = User.create!
120
122
  post = Post.create! user: user
121
- Scorecard::Points.score :new_user, gameable: user, user: user
122
123
 
123
- Scorecard::Points.for(user).should == 50
124
+ ActiveSupport::Notifications.unsubscribe(subscriber)
125
+
126
+ expect(fired).to be_true
124
127
  end
125
128
  end
@@ -2,6 +2,6 @@ class Post < ActiveRecord::Base
2
2
  belongs_to :user
3
3
 
4
4
  after_create lambda { |post|
5
- Scorecard::Points.score :new_post, gameable: post
5
+ Scorecard::Scorer.points :new_post, gameable: post
6
6
  }
7
7
  end
data/spec/spec_helper.rb CHANGED
@@ -15,4 +15,7 @@ Dir["./spec/support/**/*.rb"].each { |file| require file }
15
15
 
16
16
  RSpec.configure do |config|
17
17
  config.use_transactional_fixtures = true
18
+ config.before :each do
19
+ Scorecard.rules.clear
20
+ end
18
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scorecard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Allan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-24 00:00:00.000000000 Z
11
+ date: 2013-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -93,18 +93,26 @@ files:
93
93
  - LICENSE.txt
94
94
  - README.md
95
95
  - Rakefile
96
+ - app/models/scorecard/level.rb
96
97
  - app/models/scorecard/point.rb
97
98
  - config.ru
98
99
  - db/migrate/1_create_points.rb
100
+ - db/migrate/2_create_levels.rb
99
101
  - lib/scorecard.rb
102
+ - lib/scorecard/card.rb
103
+ - lib/scorecard/cleaner.rb
104
+ - lib/scorecard/clear_worker.rb
100
105
  - lib/scorecard/engine.rb
101
106
  - lib/scorecard/point_rule.rb
102
- - lib/scorecard/points.rb
103
107
  - lib/scorecard/rules.rb
108
+ - lib/scorecard/score_worker.rb
109
+ - lib/scorecard/scorer.rb
104
110
  - lib/scorecard/subscriber.rb
105
- - lib/scorecard/worker.rb
106
111
  - scorecard.gemspec
107
- - spec/acceptance/points_spec.rb
112
+ - spec/acceptance/clearing_points_spec.rb
113
+ - spec/acceptance/levels_spec.rb
114
+ - spec/acceptance/read_points_spec.rb
115
+ - spec/acceptance/score_points_spec.rb
108
116
  - spec/internal/app/models/post.rb
109
117
  - spec/internal/app/models/user.rb
110
118
  - spec/internal/config/database.yml
@@ -138,7 +146,10 @@ signing_key:
138
146
  specification_version: 4
139
147
  summary: Rails Engine for common scorecard patterns
140
148
  test_files:
141
- - spec/acceptance/points_spec.rb
149
+ - spec/acceptance/clearing_points_spec.rb
150
+ - spec/acceptance/levels_spec.rb
151
+ - spec/acceptance/read_points_spec.rb
152
+ - spec/acceptance/score_points_spec.rb
142
153
  - spec/internal/app/models/post.rb
143
154
  - spec/internal/app/models/user.rb
144
155
  - spec/internal/config/database.yml
@@ -1,22 +0,0 @@
1
- class Scorecard::Points
2
- def self.score(context, options)
3
- ActiveSupport::Notifications.instrument 'points.scorecard',
4
- options.merge(context: context)
5
- end
6
-
7
- def self.score_async(context, options)
8
- [:gameable, :user].each do |prefix|
9
- next unless options[prefix]
10
-
11
- options["#{prefix}_id"] = options[prefix].id
12
- options["#{prefix}_type"] = options[prefix].class.name
13
- options.delete prefix
14
- end
15
-
16
- Scorecard::Worker.perform_async context, options.stringify_keys
17
- end
18
-
19
- def self.for(user)
20
- Scorecard::Point.for_user(user).sum(:amount)
21
- end
22
- end