codecombat/codecombat — pull request #1027 by rubenvereecken (2014-05-18 18:13:21+00:00)
Title: Achievements: endpoint + mongoose basics

The following endpoints are in place:

- GET `/db/achievement/all` returns all achievements. Any other /db/*/all call results in a 404 by default.
- POST `/db/achievement/` inserts an achievement. Access is currently restricted to admins.
- GET `/db/earned_achievement/user/USER_ID` where USER_ID is a valid user id. This is a `getByRelationship` call.

Q: what's the cleanest way to simply GET the active user's earned_achievements? The level_session_handler has a `getActiveSessions`. I think it gets called by a GET to something like `/db/level/dungeon-arena/session?team=humans` even though it also gets called by its `getByRelationship`.
I propose GET `/db/earned_achievement`
I'll probably want a GET `db/achievement/model/MODEL_NAME` as well to fetch all achievements for a specific category but I'll make that one as I need it.

Next to the endpoints, achievements get detected and created once and never again. Except for repeatables of course, which get updated whenever a new 'amount' is detected. Those haven't been thoroughly tested yet.

I tested using the following fixture:

```
db.achievements.insert({
query: {'levelID':'dungeon-arena'},
name: 'Dungeon Arena started',
worth: 1,
model: 'level.session',
description: 'Started playing Dungeon Arena.',
userField: 'creator'
});
```

The achievement was successfully created upon starting dungeon-arena with no previous dungeon-arena level session in place. This means that we'll have to be careful with introducing achievements that may already have been achieved as they won't be re-added (because of the cheap client-only checks). Instead we should run a separate script that checks the db and inserts missing achievements for users that have already achieved it, every time such an achievement is introduced.