diff --git a/app/schemas/models/achievement.coffee b/app/schemas/models/achievement.coffee
index 1443d99cd..ba01f9199 100644
--- a/app/schemas/models/achievement.coffee
+++ b/app/schemas/models/achievement.coffee
@@ -10,6 +10,10 @@ module.exports =
       model: { type: 'string' }
       description: { type: 'string' }
       userField: { type: 'string' }
+<<<<<<< HEAD
+=======
+      related: c.objectId
+>>>>>>> 97602db... Refactored achievements and their endpoints as per the feedback by Scott.
       proportionalTo:
         type: 'string'
         description: 'For repeatables only. Denotes the field a repeatable achievement needs for its calculations'
diff --git a/app/schemas/models/earned_achievement.coffee b/app/schemas/models/earned_achievement.coffee
index 0a54d0e09..9b2c50c19 100644
--- a/app/schemas/models/earned_achievement.coffee
+++ b/app/schemas/models/earned_achievement.coffee
@@ -17,9 +17,11 @@ module.exports =
           [
             {
               rel: 'extra'
-              href: '/db/user/{($)}'
+              href: '/db/achievement/{($)}'
             }
           ]
+      collection:
+        type: 'string'
       achievementName:
         type: 'string'
       created:
diff --git a/app/views/kinds/SearchView.coffee b/app/views/kinds/SearchView.coffee
index 6619a71c3..7710cf484 100644
--- a/app/views/kinds/SearchView.coffee
+++ b/app/views/kinds/SearchView.coffee
@@ -4,8 +4,12 @@ forms = require('lib/forms')
 app = require('application')
 
 class SearchCollection extends Backbone.Collection
-  initialize: (modelURL, @model, @term) ->
-    @url = "#{modelURL}/search?project=true"
+  initialize: (modelURL, @model, @term, @projection) ->
+    @url = "#{modelURL}/search?project="
+    if @projection? and not @projection == []
+      @url += projection[0]
+      @url += ',' + projected for projected in projection[1..]
+    else @url += "true"
     @url += "&term=#{term}" if @term
 
 module.exports = class SearchView extends View
@@ -17,6 +21,7 @@ module.exports = class SearchView extends View
   model: null # Article
   modelURL: null # '/db/article'
   tableTemplate: null # require 'templates/editor/article/table'
+  projected: null # ['name', 'description', 'version'] or null for default
 
   events:
     'change input#search': 'runSearch'
diff --git a/server/achievements/EarnedAchievement.coffee b/server/achievements/EarnedAchievement.coffee
index c38f19a30..80eee59af 100644
--- a/server/achievements/EarnedAchievement.coffee
+++ b/server/achievements/EarnedAchievement.coffee
@@ -13,4 +13,7 @@ EarnedAchievementSchema = new mongoose.Schema({
     default: false
 }, {strict:false})
 
+# Maybe consider indexing on changed: -1 as well?
+EarnedAchievementSchema.index({user: 1, achievement: 1}, {unique: true, name: 'earned achievement index'})
+
 module.exports = EarnedAchievement = mongoose.model('EarnedAchievement', EarnedAchievementSchema)
\ No newline at end of file
diff --git a/server/achievements/achievement_handler.coffee b/server/achievements/achievement_handler.coffee
index 2a56e7f47..746cb4f2a 100644
--- a/server/achievements/achievement_handler.coffee
+++ b/server/achievements/achievement_handler.coffee
@@ -5,7 +5,7 @@ class AchievementHandler extends Handler
   modelClass: Achievement
 
   # Used to determine which properties requests may edit
-  editableProperties: ['name', 'query', 'worth', 'model', 'description', 'userField', 'proportionalTo']
+  editableProperties: ['name', 'query', 'worth', 'collection', 'description', 'userField', 'proportionalTo']
   jsonSchema = require '../../app/schemas/models/achievement.coffee'
 
   hasAccess: (req) ->
diff --git a/server/plugins/achievements.coffee b/server/plugins/achievements.coffee
index bc4bfb18b..0cc125574 100644
--- a/server/plugins/achievements.coffee
+++ b/server/plugins/achievements.coffee
@@ -11,7 +11,7 @@ loadAchievements = ->
   query = Achievement.find({})
   query.exec (err, docs) ->
     _.each docs, (achievement) ->
-      category = achievement.get 'model'
+      category = achievement.get 'collection'
       achievements[category] = [] unless category of achievements
       achievements[category].push achievement
 
@@ -49,29 +49,28 @@ module.exports = AchievablePlugin = (schema, options) ->
         userObjectID = doc.get(achievement.get('userField'))
         userID = if _.isObject userObjectID then userObjectID.toHexString() else userObjectID # Standardize! Use strings, not ObjectId's
 
-        if newlyAchieved and not alreadyAchieved
-          console.log 'Creating a new earned achievement called \'' + (achievement.get 'name') + '\' for ' + userID
-          earned = new EarnedAchievement(
+        if newlyAchieved and (not alreadyAchieved or isRepeatable)
+          earned = {
             user: userID
             achievement: achievement._id.toHexString()
             achievementName: achievement.get 'name'
-          )
-          earned.save (err, doc) ->
-            console.log err if err?
-        else if newlyAchieved and isRepeatable
-          proportionalTo = achievement.get 'proportionalTo'
-          originalValue = util.getByPath(originalDocObj, proportionalTo)
-          newValue = docObj.get proportionalTo
+          }
+          if isRepeatable
+            console.log 'Upserting repeatable achievement called \'' + (achievement.get 'name') + '\' for ' + userID
+            proportionalTo = achievement.get 'proportionalTo'
+            originalValue = util.getByPath(originalDocObj, proportionalTo)
+            newValue = docObj.get proportionalTo
 
-          if originalValue != newValue
-            upsertQuery = EarnedAchievement.findOneAndUpdate
-              user: userID
-              achievement: achievement._id.toHexString(),
-              notified: false
-              achievedAmount: newValue
-              changed: Date.now(),
-              upsert: true
-            upsertQuery.exec (err, docs) ->
+            if originalValue != newValue
+              earned.notified = false
+              earned.achievedAmount = newValue
+              earned.changed = Date.now()
+              upsertQuery = EarnedAchievement.findOneAndUpdate earned, upsert:true
+              upsertQuery.exec (err, docs) ->
+                console.log err if err?
+          else # alreadyAchieved
+            console.log 'Creating a new earned achievement called \'' + (achievement.get 'name') + '\' for ' + userID
+            (new EarnedAchievement(earned)).save (err, doc) ->
               console.log err if err?
 
 
diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee
index 6f988250e..48895ec87 100644
--- a/server/users/user_handler.coffee
+++ b/server/users/user_handler.coffee
@@ -10,7 +10,7 @@ async = require 'async'
 log = require 'winston'
 LevelSession = require('../levels/sessions/LevelSession')
 LevelSessionHandler = require '../levels/sessions/level_session_handler'
-EarnedAchievement = require '../achievements/earned_achievement_handler'
+EarnedAchievement = require '../achievements/EarnedAchievement'
 
 serverProperties = ['passwordHash', 'emailLower', 'nameLower', 'passwordReset']
 privateProperties = [