Skip to content

Reputation System: How We Crowd Source Good Content

Maxim Zaslavsky edited this page Apr 26, 2014 · 4 revisions

Database Setup

Votes table

  • User ID (of voter)
  • When (when the vote was placed)
  • On (revision ID that was voted on)
  • Value (+1 or -1, i.e. upvote or downvote)

Event_Revision table changes

  • IsApproved should be an enum: Approved, Pending, or Rejected

Constants

For handling individual votes:

  • Threshold to approve a revision: +4
  • Threshold to reject a revision: -4
  • For upvoting a revision: +1 -- regardless of what happens to this revision later
  • For downvoting a revision: -1 (this is why we don't tell them the voting scheme and only update their points count once a day).

After each vote, we check for whether either threshold has been reached. If so, we approve or reject the revision.

At time of approval:

  • For having created a revision that is approved: +10
  • For having upvoted a revision that is now approved: +2
  • For having downvoted a revision that is now approved: -5

At time of rejection:

  • For having created a revision that is rejected: -15
  • For having upvoted a revision that is rejected: -1
  • For having downvoted a revision that is rejected: +5 (offsets the initial -1)

Current queries changes

  • Best_revision() should include unapproved revisions you've voted for

User Profile fields

  • Current points -- the publicly-visible count they see. Updated once a day.
  • Pending points -- points they've earned (or lost) since the last time "Current points" was updated.
  • Last point update time -- the last time we flushed pending points into current points.

New queries

Get user's point count

This method's output is cached for 5 minutes so that we don't have to hit the database after every refresh. Maybe also poll the server from client side every 5 minutes for a new point count?

Procedure:

  1. Check cache to see if we already have a cached point count for this user.
  2. Compare current date & time to "Last point update time".
  3. If difference is less than 24 hours, then return "Current points".
  4. If difference is more than 24 hours, "Current points" += "Pending points", "Pending points" -> 0, and return "Current points".
  5. Before returning anything, put it in cache with a 5 minute expiration.

Similar revisions

TBD

Get list of unapproved revisions

Fetches count (default=3) unapproved revisions for this user to vote on.

Constraints on revisions:

  • classes the user is in
  • not created by the user
  • are newer than the last approved revision
  • are unapproved, regardless of what their current vote total is
  • don't belong to an event this user hid previously

Later, perhaps add these constraints:

  • Bias towards events the user has participated in before?
  • Are future events?

Submit a vote

Handles users' votes on unapproved revisions -- checks the votes for eligibility, records them, then processes side-effects (approval, points).

Procedure:

  1. Check if voter is eligible to vote on this revision, else stop
  2. Record the vote
  3. Recompute total vote count for this revision
  4. If the revision passes the approval threshold, approve it. If it passes the rejection threshold, reject it.
  5. Award points to the voter for having submitted a vote.
  6. If we changed state to Approved or Rejected (no longer Pending), then award points to this voter, previous voters, and revision creator as explained in the "Constants" section above.