starts fixing default tasks and use discriminator

This commit is contained in:
Matteo Pagliazzi
2015-11-27 21:18:37 +01:00
parent 7d53a4fd54
commit cfa776fff3
3 changed files with 52 additions and 47 deletions

View File

@@ -10,10 +10,10 @@ var ChallengeSchema = new Schema({
shortName: String,
description: String,
official: {type: Boolean,'default':false},
habits: [TaskSchemas.HabitSchema],
dailys: [TaskSchemas.DailySchema],
todos: [TaskSchemas.TodoSchema],
rewards: [TaskSchemas.RewardSchema],
//habits: [TaskSchemas.HabitSchema],
//dailys: [TaskSchemas.DailySchema],
//todos: [TaskSchemas.TodoSchema],
//rewards: [TaskSchemas.RewardSchema],
leader: {type: String, ref: 'User'},
group: {type: String, ref: 'Group'},
timestamp: {type: Date, 'default': Date.now},

View File

@@ -5,9 +5,10 @@ import baseModel from '../libs/api-v3/baseModel';
import _ from 'lodash';
let Schema = mongoose.Schema;
let discriminatorOptions = () => {
return {discriminatorKey: 'type'}; // the key that distinguishes task types
let discriminatorOptions = {
discriminatorKey: 'type', // the key that distinguishes task types
};
let subDiscriminatorOptions = _.defaults(_.cloneDeep(discriminatorOptions), {_id: false});
// TODO make sure a task can only update the fields belonging to its type
// We could use discriminators but it looks like when loading from the parent
@@ -29,10 +30,10 @@ export let TaskSchema = new Schema({
broken: String, // CHALLENGE_DELETED, TASK_DELETED, UNSUBSCRIBED, CHALLENGE_CLOSED TODO enum
winner: String, // user.profile.name TODO necessary?
},
}, _.default({
}, _.defaults({
minimize: true, // So empty objects are returned
strict: true,
}, discriminatorOptions()));
}, discriminatorOptions));
TaskSchema.plugin(baseModel, {
noSet: [],
@@ -66,7 +67,7 @@ let dailyTodoSchema = () => {
export let Habit = Task.discriminator('Habit', new Schema(_.defaults({
up: {type: Boolean, default: true},
down: {type: Boolean, default: true},
}, habitDailySchema())), discriminatorOptions());
}, habitDailySchema()), subDiscriminatorOptions));
export let Daily = Task.discriminator('Daily', new Schema(_.defaults({
frequency: {type: String, default: 'weekly', enum: ['daily', 'weekly']},
@@ -87,13 +88,13 @@ export let Daily = Task.discriminator('Daily', new Schema(_.defaults({
su: {type: Boolean, default: true},
},
streak: {type: Number, default: 0},
}, habitDailySchema(), dailyTodoSchema())), discriminatorOptions());
}, habitDailySchema(), dailyTodoSchema()), subDiscriminatorOptions));
export let Todo = Task.discriminator('Todo', new Schema(_.defaults({
dateCompleted: Date,
// FIXME we're getting parse errors, people have stored as "today" and "3/13". Need to run a migration & put this back to type: Date
// TODO change field name
date: String, // due date for todos
}, dailyTodoSchema())), discriminatorOptions());
}, dailyTodoSchema()), subDiscriminatorOptions));
export let Reward = Task.discriminator('Reward', new Schema({}), discriminatorOptions());
export let Reward = Task.discriminator('Reward', new Schema({}, subDiscriminatorOptions));

View File

@@ -3,6 +3,7 @@ import shared from '../../../common';
import _ from 'lodash';
import validator from 'validator';
import moment from 'moment';
import Q from 'q';
import { model as Task } from './task';
import baseModel from '../libs/api-v3/baseModel';
// import {model as Challenge} from './challenge';
@@ -491,36 +492,37 @@ schema.post('init', function postInitUser (doc) {
});
function _populateDefaultTasks (user, taskTypes) {
_.each(taskTypes, (taskType) => {
// TODO save in own documents
user[taskType] = _.map(shared.content.userDefaults[taskType], (taskDefaults) => {
let newTask;
if ('tags' in taskTypes) {
user.tags = _.map(shared.content.userDefaults.tags, function(tag){
let newTag = _.cloneDeep(tag);
// Render task's text and notes in user's language
if (taskType === 'tags') {
newTask = _.cloneDeep(taskDefaults);
// tasks automatically get id=helpers.uuid() from TaskSchema id.default, but tags are Schema.Types.Mixed - so we need to manually invoke here
newTask.id = shared.uuid();
newTask.name = newTask.name(user.preferences.language);
} else {
newTask = new Task(taskDefaults);
newTask.userId = user._id;
newTask.text = newTask.text(user.preferences.language);
if (newTask.notes) {
newTask.notes = newTask.notes(user.preferences.language);
}
if (newTask.checklist) {
newTask.checklist = _.map(newTask.checklist, (checklistItem) => {
checklistItem.text = checklistItem.text(user.preferences.language);
return checklistItem;
});
}
}
return newTask;
// tasks automatically get _id=helpers.uuid() from TaskSchema id.default, but tags are Schema.Types.Mixed - so we need to manually invoke here
newTag.id = shared.uuid();
// Render tag's name in user's language
newTag.name = newTag.name(user.preferences.language);
return newTag;
});
}
let tasksToCreate = [];
_.each(taskTypes, (taskType) => {
let tasksOfType = _.map(shared.content.userDefaults[taskType], (taskDefaults) => {
let newTask = new Task(taskDefaults);
newTask.userId = user._id;
newTask.text = newTask.text(user.preferences.language);
if (newTask.notes) newTask.notes = newTask.notes(user.preferences.language);
if (newTask.checklist) {
newTask.checklist = _.map(newTask.checklist, (checklistItem) => {
checklistItem.text = checklistItem.text(user.preferences.language);
return checklistItem;
});
}
});
tasksToCreate.push(...tasksOfType);
});
return Task.create(tasksToCreate);
}
function _populateDefaultsForNewUser (user) {
@@ -543,7 +545,7 @@ function _populateDefaultsForNewUser (user) {
});
}
_populateDefaultTasks(user, taskTypes);
return _populateDefaultTasks(user, taskTypes);
}
function _setProfileName (user) {
@@ -556,13 +558,10 @@ function _setProfileName (user) {
return localUsername || facebookUsername || anonymous;
}
schema.pre('save', function postSaveUser (next) {
// Populate new users with default content
if (this.isNew) {
_populateDefaultsForNewUser(this);
}
schema.pre('save', function postSaveUser (next, done) {
next();
// this.markModified('tasks');
// TODO remove all unnecessary checks
if (_.isNaN(this.preferences.dayStart) || this.preferences.dayStart < 0 || this.preferences.dayStart > 23) {
this.preferences.dayStart = 0;
}
@@ -611,7 +610,12 @@ schema.pre('save', function postSaveUser (next) {
if (_.isNaN(this._v) || !_.isNumber(this._v)) this._v = 0;
this._v++;
next();
// Populate new users with default content
if (this.isNew) {
_populateDefaultsForNewUser(this)
.then((tasks) => done())
.catch(done);
}
});
schema.methods.unlink = function unlink (options, cb) {