diff --git a/common/script/api-v3/preenHistory.js b/common/script/api-v3/preenHistory.js index 50ffb1518f..64ae4e4715 100644 --- a/common/script/api-v3/preenHistory.js +++ b/common/script/api-v3/preenHistory.js @@ -62,7 +62,7 @@ export function preenHistory (history) { } export function preenUserHistory (user, tasksByType, minHistLen = 7) { - tasksByType.habits.concat(user.dailys).forEach((task) => { + tasksByType.habits.concat(tasksByType.dailys).forEach((task) => { if (task.history.length > minHistLen) { task.history = preenHistory(user, task.history); task.markModified('history'); diff --git a/website/src/controllers/api-v3/tasks.js b/website/src/controllers/api-v3/tasks.js index ef7180088e..be77c97d70 100644 --- a/website/src/controllers/api-v3/tasks.js +++ b/website/src/controllers/api-v3/tasks.js @@ -7,10 +7,12 @@ import { NotAuthorized, BadRequest, } from '../../libs/api-v3/errors'; +import { model as Challenge } from '../../models/challenge'; import shared from '../../../../common'; import Q from 'q'; import _ from 'lodash'; import scoreTask from '../../../../common/script/api-v3/scoreTask'; +import { preenHistory } from '../../../../common/script/api-v3/preenHistory'; let api = {}; @@ -292,7 +294,24 @@ api.scoreTask = { sendTaskWebhook(user.preferences.webhooks, _generateWebhookTaskData(task, direction, delta, userStats, user)); - // TODO sync challenge + // TODO test? + if (task.challenge.id && task.challenge.taskId && !task.challenge.broken && task.type !== 'reward') { + Tasks.Task.findOne({ + _id: task.challenge.taskId + }).exec() + .then(chalTask => { + chalTask.value += delta; + if (t.type == 'habit' || t.type == 'daily') { + chalTask.history.push({value: chalTask.value, date: Number(new Date())}); + // TODO 1. treat challenges as subscribed users for preening 2. it's expensive to do it at every score - how to have it happen once like for cron? + chalTask.history = preenHistory(user, chalTask.history); + chalTask.markModified('history'); + } + + return chalTask.save(); + }); + //.catch(next) TODO what to do here + } }); }) .catch(next); diff --git a/website/src/models/task.js b/website/src/models/task.js index 74f8d07c53..b31676da10 100644 --- a/website/src/models/task.js +++ b/website/src/models/task.js @@ -21,13 +21,13 @@ export let TaskSchema = new Schema({ type: String, validate: [validator.isUUID, 'Invalid uuid.'], }], - value: {type: Number, default: 0}, // redness or cost for rewards + value: {type: Number, default: 0, required: true}, // redness or cost for rewards Required because it must be settable (for rewards) priority: {type: Number, default: 1, required: true}, // TODO enum? attribute: {type: String, default: 'str', enum: ['str', 'con', 'int', 'per']}, userId: {type: String, ref: 'User', validate: [validator.isUUID, 'Invalid uuid.']}, // When not set it belongs to a challenge challenge: { - id: {type: String, ref: 'Challenge', validate: [validator.isUUID, 'Invalid uuid.']}, + id: {type: String, ref: 'Challenge', validate: [validator.isUUID, 'Invalid uuid.']}, // When set (and userId not set) it's the original task taskId: {type: String, ref: 'Task', validate: [validator.isUUID, 'Invalid uuid.']}, // When not set but challenge.id defined it's the original task broken: {type: String, enum: ['CHALLENGE_DELETED', 'TASK_DELETED', 'UNSUBSCRIBED', 'CHALLENGE_CLOSED']}, winner: String, // user.profile.name TODO necessary?