diff options
author | Maxime Quandalle <maxime@quandalle.com> | 2015-09-08 20:19:42 +0200 |
---|---|---|
committer | Maxime Quandalle <maxime@quandalle.com> | 2015-09-08 20:19:42 +0200 |
commit | 45b662a1ddb46a0f17fab7b2383c82aa1e1620ef (patch) | |
tree | cc7be215c7e7ebffd2597df70cf271b3dd435e1a /models/lists.js | |
parent | c04341f1ea5efe082bf7318cf9eb0e99b9b8374a (diff) | |
download | wekan-45b662a1ddb46a0f17fab7b2383c82aa1e1620ef.tar.gz wekan-45b662a1ddb46a0f17fab7b2383c82aa1e1620ef.tar.bz2 wekan-45b662a1ddb46a0f17fab7b2383c82aa1e1620ef.zip |
Centralize all mutations at the model level
This commit uses a new package that I need to document. It tries to
solve the long-standing debate in the Meteor community about
allow/deny rules versus methods (RPC).
This approach gives us both the centralized security rules of
allow/deny and the white-list of allowed mutations similarly to Meteor
methods. The idea to have static mutation descriptions is also
inspired by Facebook's Relay/GraphQL.
This will allow the development of a REST API using the high-level
methods instead of the MongoDB queries to do the mapping between the
HTTP requests and our collections.
Diffstat (limited to 'models/lists.js')
-rw-r--r-- | models/lists.js | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/models/lists.js b/models/lists.js new file mode 100644 index 00000000..4e4a1134 --- /dev/null +++ b/models/lists.js @@ -0,0 +1,110 @@ +Lists = new Mongo.Collection('lists'); + +Lists.attachSchema(new SimpleSchema({ + title: { + type: String, + }, + archived: { + type: Boolean, + }, + boardId: { + type: String, + }, + createdAt: { + type: Date, + denyUpdate: true, + }, + sort: { + type: Number, + decimal: true, + // XXX We should probably provide a default + optional: true, + }, + updatedAt: { + type: Date, + denyInsert: true, + optional: true, + }, +})); + +Lists.allow({ + insert(userId, doc) { + return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + }, + update(userId, doc) { + return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + }, + remove(userId, doc) { + return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + }, + fetch: ['boardId'], +}); + +Lists.helpers({ + cards() { + return Cards.find(Filter.mongoSelector({ + listId: this._id, + archived: false, + }), { sort: ['sort'] }); + }, + + allCards() { + return Cards.find({ listId: this._id }); + }, + + board() { + return Boards.findOne(this.boardId); + }, +}); + +Lists.mutations({ + rename(title) { + return { $set: { title }}; + }, + + archive() { + return { $set: { archived: true }}; + }, + + restore() { + return { $set: { archived: false }}; + }, +}); + +Lists.hookOptions.after.update = { fetchPrevious: false }; + +Lists.before.insert((userId, doc) => { + doc.createdAt = new Date(); + doc.archived = false; + if (!doc.userId) + doc.userId = userId; +}); + +Lists.before.update((userId, doc, fieldNames, modifier) => { + modifier.$set = modifier.$set || {}; + modifier.$set.modifiedAt = new Date(); +}); + +if (Meteor.isServer) { + Lists.after.insert((userId, doc) => { + Activities.insert({ + userId, + type: 'list', + activityType: 'createList', + boardId: doc.boardId, + listId: doc._id, + }); + }); + + Lists.after.update((userId, doc) => { + if (doc.archived) { + Activities.insert({ + userId, + type: 'list', + activityType: 'archivedList', + listId: doc._id, + boardId: doc.boardId, + }); + } + }); +} |