summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/boards.js176
-rw-r--r--models/cardComments.js56
-rw-r--r--models/cards.js169
-rw-r--r--models/checklistItems.js55
-rw-r--r--models/checklists.js63
-rw-r--r--models/customFields.js73
-rw-r--r--models/export.js15
-rw-r--r--models/integrations.js99
-rw-r--r--models/lists.js68
-rw-r--r--models/swimlanes.js59
-rw-r--r--models/users.js172
11 files changed, 994 insertions, 11 deletions
diff --git a/models/boards.js b/models/boards.js
index db3b1149..99480ca7 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -1,10 +1,19 @@
Boards = new Mongo.Collection('boards');
+/**
+ * This is a Board.
+ */
Boards.attachSchema(new SimpleSchema({
title: {
+ /**
+ * The title of the board
+ */
type: String,
},
slug: {
+ /**
+ * The title slugified.
+ */
type: String,
autoValue() { // eslint-disable-line consistent-return
// XXX We need to improve slug management. Only the id should be necessary
@@ -24,6 +33,9 @@ Boards.attachSchema(new SimpleSchema({
},
},
archived: {
+ /**
+ * Is the board archived?
+ */
type: Boolean,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -32,6 +44,9 @@ Boards.attachSchema(new SimpleSchema({
},
},
createdAt: {
+ /**
+ * Creation time of the board
+ */
type: Date,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert) {
@@ -43,6 +58,9 @@ Boards.attachSchema(new SimpleSchema({
},
// XXX Inconsistent field naming
modifiedAt: {
+ /**
+ * Last modification time of the board
+ */
type: Date,
optional: true,
autoValue() { // eslint-disable-line consistent-return
@@ -55,6 +73,9 @@ Boards.attachSchema(new SimpleSchema({
},
// De-normalized number of users that have starred this board
stars: {
+ /**
+ * How many stars the board has
+ */
type: Number,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert) {
@@ -64,6 +85,9 @@ Boards.attachSchema(new SimpleSchema({
},
// De-normalized label system
'labels': {
+ /**
+ * List of labels attached to a board
+ */
type: [Object],
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -78,6 +102,9 @@ Boards.attachSchema(new SimpleSchema({
},
},
'labels.$._id': {
+ /**
+ * Unique id of a label
+ */
// We don't specify that this field must be unique in the board because that
// will cause performance penalties and is not necessary since this field is
// always set on the server.
@@ -86,10 +113,22 @@ Boards.attachSchema(new SimpleSchema({
type: String,
},
'labels.$.name': {
+ /**
+ * Name of a label
+ */
type: String,
optional: true,
},
'labels.$.color': {
+ /**
+ * color of a label.
+ *
+ * Can be amongst `green`, `yellow`, `orange`, `red`, `purple`,
+ * `blue`, `sky`, `lime`, `pink`, `black`,
+ * `silver`, `peachpuff`, `crimson`, `plum`, `darkgreen`,
+ * `slateblue`, `magenta`, `gold`, `navy`, `gray`,
+ * `saddlebrown`, `paleturquoise`, `mistyrose`, `indigo`
+ */
type: String,
allowedValues: [
'green', 'yellow', 'orange', 'red', 'purple',
@@ -103,6 +142,9 @@ Boards.attachSchema(new SimpleSchema({
// documents like de-normalized meta-data (the date the member joined the
// board, the number of contributions, etc.).
'members': {
+ /**
+ * List of members of a board
+ */
type: [Object],
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -117,27 +159,48 @@ Boards.attachSchema(new SimpleSchema({
},
},
'members.$.userId': {
+ /**
+ * The uniq ID of the member
+ */
type: String,
},
'members.$.isAdmin': {
+ /**
+ * Is the member an admin of the board?
+ */
type: Boolean,
},
'members.$.isActive': {
+ /**
+ * Is the member active?
+ */
type: Boolean,
},
'members.$.isNoComments': {
+ /**
+ * Is the member not allowed to make comments
+ */
type: Boolean,
optional: true,
},
'members.$.isCommentOnly': {
+ /**
+ * Is the member only allowed to comment on the board
+ */
type: Boolean,
optional: true,
},
permission: {
+ /**
+ * visibility of the board
+ */
type: String,
allowedValues: ['public', 'private'],
},
color: {
+ /**
+ * The color of the board.
+ */
type: String,
allowedValues: [
'belize',
@@ -154,24 +217,45 @@ Boards.attachSchema(new SimpleSchema({
},
},
description: {
+ /**
+ * The description of the board
+ */
type: String,
optional: true,
},
subtasksDefaultBoardId: {
+ /**
+ * The default board ID assigned to subtasks.
+ */
type: String,
optional: true,
defaultValue: null,
},
subtasksDefaultListId: {
+ /**
+ * The default List ID assigned to subtasks.
+ */
type: String,
optional: true,
defaultValue: null,
},
allowsSubtasks: {
+ /**
+ * Does the board allows subtasks?
+ */
type: Boolean,
defaultValue: true,
},
presentParentTask: {
+ /**
+ * Controls how to present the parent task:
+ *
+ * - `prefix-with-full-path`: add a prefix with the full path
+ * - `prefix-with-parent`: add a prefisx with the parent name
+ * - `subtext-with-full-path`: add a subtext with the full path
+ * - `subtext-with-parent`: add a subtext with the parent name
+ * - `no-parent`: does not show the parent at all
+ */
type: String,
allowedValues: [
'prefix-with-full-path',
@@ -184,23 +268,38 @@ Boards.attachSchema(new SimpleSchema({
defaultValue: 'no-parent',
},
startAt: {
+ /**
+ * Starting date of the board.
+ */
type: Date,
optional: true,
},
dueAt: {
+ /**
+ * Due date of the board.
+ */
type: Date,
optional: true,
},
endAt: {
+ /**
+ * End date of the board.
+ */
type: Date,
optional: true,
},
spentTime: {
+ /**
+ * Time spent in the board.
+ */
type: Number,
decimal: true,
optional: true,
},
isOvertime: {
+ /**
+ * Is the board overtimed?
+ */
type: Boolean,
defaultValue: false,
optional: true,
@@ -774,6 +873,14 @@ if (Meteor.isServer) {
//BOARDS REST API
if (Meteor.isServer) {
+ /**
+ * @operation get_boards_from_user
+ * @summary Get all boards attached to a user
+ *
+ * @param {string} userId the ID of the user to retrieve the data
+ * @return_type [{_id: string,
+ title: string}]
+ */
JsonRoutes.add('GET', '/api/users/:userId/boards', function (req, res) {
try {
Authentication.checkLoggedIn(req.userId);
@@ -804,6 +911,13 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_public_boards
+ * @summary Get all public boards
+ *
+ * @return_type [{_id: string,
+ title: string}]
+ */
JsonRoutes.add('GET', '/api/boards', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -825,6 +939,13 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_board
+ * @summary Get the board with that particular ID
+ *
+ * @param {string} boardId the ID of the board to retrieve the data
+ * @return_type Boards
+ */
JsonRoutes.add('GET', '/api/boards/:boardId', function (req, res) {
try {
const id = req.params.boardId;
@@ -843,6 +964,31 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation new_board
+ * @summary Create a board
+ *
+ * @description This allows to create a board.
+ *
+ * The color has to be chosen between `belize`, `nephritis`, `pomegranate`,
+ * `pumpkin`, `wisteria`, `midnight`:
+ *
+ * <img src="https://wekan.github.io/board-colors.png" width="40%" alt="Wekan logo" />
+ *
+ * @param {string} title the new title of the board
+ * @param {string} owner "ABCDE12345" <= User ID in Wekan.
+ * (Not username or email)
+ * @param {boolean} [isAdmin] is the owner an admin of the board (default true)
+ * @param {boolean} [isActive] is the board active (default true)
+ * @param {boolean} [isNoComments] disable comments (default false)
+ * @param {boolean} [isCommentOnly] only enable comments (default false)
+ * @param {string} [permission] "private" board <== Set to "public" if you
+ * want public Wekan board
+ * @param {string} [color] the color of the board
+ *
+ * @return_type {_id: string,
+ defaultSwimlaneId: string}
+ */
JsonRoutes.add('POST', '/api/boards', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -880,6 +1026,12 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation delete_board
+ * @summary Delete a board
+ *
+ * @param {string} boardId the ID of the board
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -900,6 +1052,19 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation add_board_label
+ * @summary Add a label to a board
+ *
+ * @description If the board doesn't have the name/color label, this function
+ * adds the label to the board.
+ *
+ * @param {string} boardId the board
+ * @param {string} color the color of the new label
+ * @param {string} name the name of the new label
+ *
+ * @return_type string
+ */
JsonRoutes.add('PUT', '/api/boards/:boardId/labels', function (req, res) {
Authentication.checkUserId(req.userId);
const id = req.params.boardId;
@@ -929,6 +1094,17 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation set_board_member_permission
+ * @tag Users
+ * @summary Change the permission of a member of a board
+ *
+ * @param {string} boardId the ID of the board that we are changing
+ * @param {string} memberId the ID of the user to change permissions
+ * @param {boolean} isAdmin admin capability
+ * @param {boolean} isNoComments NoComments capability
+ * @param {boolean} isCommentOnly CommentsOnly capability
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/members/:memberId', function (req, res) {
try {
const boardId = req.params.boardId;
diff --git a/models/cardComments.js b/models/cardComments.js
index b6cb10fa..974c5ec9 100644
--- a/models/cardComments.js
+++ b/models/cardComments.js
@@ -1,19 +1,34 @@
CardComments = new Mongo.Collection('card_comments');
+/**
+ * A comment on a card
+ */
CardComments.attachSchema(new SimpleSchema({
boardId: {
+ /**
+ * the board ID
+ */
type: String,
},
cardId: {
+ /**
+ * the card ID
+ */
type: String,
},
// XXX Rename in `content`? `text` is a bit vague...
text: {
+ /**
+ * the text of the comment
+ */
type: String,
},
// XXX We probably don't need this information here, since we already have it
// in the associated comment creation activity
createdAt: {
+ /**
+ * when was the comment created
+ */
type: Date,
denyUpdate: false,
autoValue() { // eslint-disable-line consistent-return
@@ -26,6 +41,9 @@ CardComments.attachSchema(new SimpleSchema({
},
// XXX Should probably be called `authorId`
userId: {
+ /**
+ * the author ID of the comment
+ */
type: String,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -87,6 +105,16 @@ if (Meteor.isServer) {
//CARD COMMENT REST API
if (Meteor.isServer) {
+ /**
+ * @operation get_all_comments
+ * @summary Get all comments attached to a card
+ *
+ * @param {string} boardId the board ID of the card
+ * @param {string} cardId the ID of the card
+ * @return_type [{_id: string,
+ * comment: string,
+ * authorId: string}]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/comments', function (req, res) {
try {
Authentication.checkUserId( req.userId);
@@ -111,6 +139,15 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_comment
+ * @summary Get a comment on a card
+ *
+ * @param {string} boardId the board ID of the card
+ * @param {string} cardId the ID of the card
+ * @param {string} commentId the ID of the comment to retrieve
+ * @return_type CardComments
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/comments/:commentId', function (req, res) {
try {
Authentication.checkUserId( req.userId);
@@ -130,6 +167,16 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation new_comment
+ * @summary Add a comment on a card
+ *
+ * @param {string} boardId the board ID of the card
+ * @param {string} cardId the ID of the card
+ * @param {string} authorId the user who 'posted' the comment
+ * @param {string} text the content of the comment
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/cards/:cardId/comments', function (req, res) {
try {
Authentication.checkUserId( req.userId);
@@ -160,6 +207,15 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation delete_comment
+ * @summary Delete a comment on a card
+ *
+ * @param {string} boardId the board ID of the card
+ * @param {string} cardId the ID of the card
+ * @param {string} commentId the ID of the comment to delete
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/cards/:cardId/comments/:commentId', function (req, res) {
try {
Authentication.checkUserId( req.userId);
diff --git a/models/cards.js b/models/cards.js
index 7b05e4b5..aa0bf93e 100644
--- a/models/cards.js
+++ b/models/cards.js
@@ -5,11 +5,17 @@ Cards = new Mongo.Collection('cards');
// of comments just to display the number of them in the board view.
Cards.attachSchema(new SimpleSchema({
title: {
+ /**
+ * the title of the card
+ */
type: String,
optional: true,
defaultValue: '',
},
archived: {
+ /**
+ * is the card archived
+ */
type: Boolean,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -18,33 +24,51 @@ Cards.attachSchema(new SimpleSchema({
},
},
parentId: {
+ /**
+ * ID of the parent card
+ */
type: String,
optional: true,
defaultValue: '',
},
listId: {
+ /**
+ * List ID where the card is
+ */
type: String,
optional: true,
defaultValue: '',
},
swimlaneId: {
+ /**
+ * Swimlane ID where the card is
+ */
type: String,
},
// The system could work without this `boardId` information (we could deduce
// the board identifier from the card), but it would make the system more
// difficult to manage and less efficient.
boardId: {
+ /**
+ * Board ID of the card
+ */
type: String,
optional: true,
defaultValue: '',
},
coverId: {
+ /**
+ * Cover ID of the card
+ */
type: String,
optional: true,
defaultValue: '',
},
createdAt: {
+ /**
+ * creation date
+ */
type: Date,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert) {
@@ -55,6 +79,9 @@ Cards.attachSchema(new SimpleSchema({
},
},
customFields: {
+ /**
+ * list of custom fields
+ */
type: [Object],
optional: true,
defaultValue: [],
@@ -62,11 +89,17 @@ Cards.attachSchema(new SimpleSchema({
'customFields.$': {
type: new SimpleSchema({
_id: {
+ /**
+ * the ID of the related custom field
+ */
type: String,
optional: true,
defaultValue: '',
},
value: {
+ /**
+ * value attached to the custom field
+ */
type: Match.OneOf(String, Number, Boolean, Date),
optional: true,
defaultValue: '',
@@ -74,59 +107,95 @@ Cards.attachSchema(new SimpleSchema({
}),
},
dateLastActivity: {
+ /**
+ * Date of last activity
+ */
type: Date,
autoValue() {
return new Date();
},
},
description: {
+ /**
+ * description of the card
+ */
type: String,
optional: true,
defaultValue: '',
},
requestedBy: {
+ /**
+ * who requested the card (ID of the user)
+ */
type: String,
optional: true,
defaultValue: '',
},
assignedBy: {
+ /**
+ * who assigned the card (ID of the user)
+ */
type: String,
optional: true,
defaultValue: '',
},
labelIds: {
+ /**
+ * list of labels ID the card has
+ */
type: [String],
optional: true,
defaultValue: [],
},
members: {
+ /**
+ * list of members (user IDs)
+ */
type: [String],
optional: true,
defaultValue: [],
},
receivedAt: {
+ /**
+ * Date the card was received
+ */
type: Date,
optional: true,
},
startAt: {
+ /**
+ * Date the card was started to be worked on
+ */
type: Date,
optional: true,
},
dueAt: {
+ /**
+ * Date the card is due
+ */
type: Date,
optional: true,
},
endAt: {
+ /**
+ * Date the card ended
+ */
type: Date,
optional: true,
},
spentTime: {
+ /**
+ * How much time has been spent on this
+ */
type: Number,
decimal: true,
optional: true,
defaultValue: 0,
},
isOvertime: {
+ /**
+ * is the card over time?
+ */
type: Boolean,
defaultValue: false,
optional: true,
@@ -134,6 +203,9 @@ Cards.attachSchema(new SimpleSchema({
// XXX Should probably be called `authorId`. Is it even needed since we have
// the `members` field?
userId: {
+ /**
+ * user ID of the author of the card
+ */
type: String,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -142,21 +214,33 @@ Cards.attachSchema(new SimpleSchema({
},
},
sort: {
+ /**
+ * Sort value
+ */
type: Number,
decimal: true,
defaultValue: '',
},
subtaskSort: {
+ /**
+ * subtask sort value
+ */
type: Number,
decimal: true,
defaultValue: -1,
optional: true,
},
type: {
+ /**
+ * type of the card
+ */
type: String,
defaultValue: '',
},
linkedId: {
+ /**
+ * ID of the linked card
+ */
type: String,
optional: true,
defaultValue: '',
@@ -1309,6 +1393,17 @@ if (Meteor.isServer) {
}
//SWIMLANES REST API
if (Meteor.isServer) {
+ /**
+ * @operation get_swimlane_cards
+ * @summary get all cards attached to a swimlane
+ *
+ * @param {string} boardId the board ID
+ * @param {string} swimlaneId the swimlane ID
+ * @return_type [{_id: string,
+ * title: string,
+ * description: string,
+ * listId: string}]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/swimlanes/:swimlaneId/cards', function(req, res) {
const paramBoardId = req.params.boardId;
const paramSwimlaneId = req.params.swimlaneId;
@@ -1332,6 +1427,16 @@ if (Meteor.isServer) {
}
//LISTS REST API
if (Meteor.isServer) {
+ /**
+ * @operation get_all_cards
+ * @summary get all cards attached to a list
+ *
+ * @param {string} boardId the board ID
+ * @param {string} listId the list ID
+ * @return_type [{_id: string,
+ * title: string,
+ * description: string}]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function(req, res) {
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
@@ -1352,6 +1457,15 @@ if (Meteor.isServer) {
});
});
+ /**
+ * @operation get_card
+ * @summary get a card
+ *
+ * @param {string} boardId the board ID
+ * @param {string} listId the list ID of the card
+ * @param {string} cardId the card ID
+ * @return_type Cards
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards/:cardId', function(req, res) {
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
@@ -1368,6 +1482,19 @@ if (Meteor.isServer) {
});
});
+ /**
+ * @operation new_card
+ * @summary creates a new card
+ *
+ * @param {string} boardId the board ID of the new card
+ * @param {string} listId the list ID of the new card
+ * @param {string} authorID the user ID of the person owning the card
+ * @param {string} title the title of the new card
+ * @param {string} description the description of the new card
+ * @param {string} swimlaneId the swimlane ID of the new card
+ * @param {string} [members] the member IDs list of the new card
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function(req, res) {
Authentication.checkUserId(req.userId);
const paramBoardId = req.params.boardId;
@@ -1406,6 +1533,36 @@ if (Meteor.isServer) {
}
});
+ /*
+ * Note for the JSDoc:
+ * 'list' will be interpreted as the path parameter
+ * 'listID' will be interpreted as the body parameter
+ */
+ /**
+ * @operation edit_card
+ * @summary edit fields in a card
+ *
+ * @param {string} boardId the board ID of the card
+ * @param {string} list the list ID of the card
+ * @param {string} cardId the ID of the card
+ * @param {string} [title] the new title of the card
+ * @param {string} [listId] the new list ID of the card (move operation)
+ * @param {string} [description] the new description of the card
+ * @param {string} [authorId] change the owner of the card
+ * @param {string} [labelIds] the new list of label IDs attached to the card
+ * @param {string} [swimlaneId] the new swimlane ID of the card
+ * @param {string} [members] the new list of member IDs attached to the card
+ * @param {string} [requestedBy] the new requestedBy field of the card
+ * @param {string} [assignedBy] the new assignedBy field of the card
+ * @param {string} [receivedAt] the new receivedAt field of the card
+ * @param {string} [assignBy] the new assignBy field of the card
+ * @param {string} [startAt] the new startAt field of the card
+ * @param {string} [dueAt] the new dueAt field of the card
+ * @param {string} [endAt] the new endAt field of the card
+ * @param {string} [spentTime] the new spentTime field of the card
+ * @param {boolean} [isOverTime] the new isOverTime field of the card
+ * @param {string} [customFields] the new customFields value of the card
+ */
JsonRoutes.add('PUT', '/api/boards/:boardId/lists/:listId/cards/:cardId', function(req, res) {
Authentication.checkUserId(req.userId);
const paramBoardId = req.params.boardId;
@@ -1551,6 +1708,18 @@ if (Meteor.isServer) {
});
});
+ /**
+ * @operation delete_card
+ * @summary Delete a card from a board
+ *
+ * @description This operation **deletes** a card, and therefore the card
+ * is not put in the recycle bin.
+ *
+ * @param {string} boardId the board ID of the card
+ * @param {string} list the list ID of the card
+ * @param {string} cardId the ID of the card
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId/cards/:cardId', function(req, res) {
Authentication.checkUserId(req.userId);
const paramBoardId = req.params.boardId;
diff --git a/models/checklistItems.js b/models/checklistItems.js
index 9867dd94..35b18ed7 100644
--- a/models/checklistItems.js
+++ b/models/checklistItems.js
@@ -1,21 +1,39 @@
ChecklistItems = new Mongo.Collection('checklistItems');
+/**
+ * An item in a checklist
+ */
ChecklistItems.attachSchema(new SimpleSchema({
title: {
+ /**
+ * the text of the item
+ */
type: String,
},
sort: {
+ /**
+ * the sorting field of the item
+ */
type: Number,
decimal: true,
},
isFinished: {
+ /**
+ * Is the item checked?
+ */
type: Boolean,
defaultValue: false,
},
checklistId: {
+ /**
+ * the checklist ID the item is attached to
+ */
type: String,
},
cardId: {
+ /**
+ * the card ID the item is attached to
+ */
type: String,
},
}));
@@ -193,6 +211,17 @@ if (Meteor.isServer) {
}
if (Meteor.isServer) {
+ /**
+ * @operation get_checklist_item
+ * @tag Checklists
+ * @summary Get a checklist item
+ *
+ * @param {string} boardId the board ID
+ * @param {string} cardId the card ID
+ * @param {string} checklistId the checklist ID
+ * @param {string} itemId the ID of the item
+ * @return_type ChecklistItems
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId/items/:itemId', function (req, res) {
Authentication.checkUserId( req.userId);
const paramItemId = req.params.itemId;
@@ -209,6 +238,19 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation edit_checklist_item
+ * @tag Checklists
+ * @summary Edit a checklist item
+ *
+ * @param {string} boardId the board ID
+ * @param {string} cardId the card ID
+ * @param {string} checklistId the checklist ID
+ * @param {string} itemId the ID of the item
+ * @param {string} [isFinished] is the item checked?
+ * @param {string} [title] the new text of the item
+ * @return_type {_id: string}
+ */
JsonRoutes.add('PUT', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId/items/:itemId', function (req, res) {
Authentication.checkUserId( req.userId);
@@ -229,6 +271,19 @@ if (Meteor.isServer) {
});
});
+ /**
+ * @operation delete_checklist_item
+ * @tag Checklists
+ * @summary Delete a checklist item
+ *
+ * @description Note: this operation can't be reverted.
+ *
+ * @param {string} boardId the board ID
+ * @param {string} cardId the card ID
+ * @param {string} checklistId the checklist ID
+ * @param {string} itemId the ID of the item to be removed
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId/items/:itemId', function (req, res) {
Authentication.checkUserId( req.userId);
const paramItemId = req.params.itemId;
diff --git a/models/checklists.js b/models/checklists.js
index 425a10b2..a372fafa 100644
--- a/models/checklists.js
+++ b/models/checklists.js
@@ -1,18 +1,33 @@
Checklists = new Mongo.Collection('checklists');
+/**
+ * A Checklist
+ */
Checklists.attachSchema(new SimpleSchema({
cardId: {
+ /**
+ * The ID of the card the checklist is in
+ */
type: String,
},
title: {
+ /**
+ * the title of the checklist
+ */
type: String,
defaultValue: 'Checklist',
},
finishedAt: {
+ /**
+ * When was the checklist finished
+ */
type: Date,
optional: true,
},
createdAt: {
+ /**
+ * Creation date of the checklist
+ */
type: Date,
denyUpdate: false,
autoValue() { // eslint-disable-line consistent-return
@@ -24,6 +39,9 @@ Checklists.attachSchema(new SimpleSchema({
},
},
sort: {
+ /**
+ * sorting value of the checklist
+ */
type: Number,
decimal: true,
},
@@ -128,6 +146,15 @@ if (Meteor.isServer) {
}
if (Meteor.isServer) {
+ /**
+ * @operation get_all_checklists
+ * @summary Get the list of checklists attached to a card
+ *
+ * @param {string} boardId the board ID
+ * @param {string} cardId the card ID
+ * @return_type [{_id: string,
+ * title: string}]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/checklists', function (req, res) {
Authentication.checkUserId( req.userId);
const paramCardId = req.params.cardId;
@@ -149,6 +176,22 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_checklist
+ * @summary Get a checklist
+ *
+ * @param {string} boardId the board ID
+ * @param {string} cardId the card ID
+ * @param {string} checklistId the ID of the checklist
+ * @return_type {cardId: string,
+ * title: string,
+ * finishedAt: string,
+ * createdAt: string,
+ * sort: number,
+ * items: [{_id: string,
+ * title: string,
+ * isFinished: boolean}]}
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId', function (req, res) {
Authentication.checkUserId( req.userId);
const paramChecklistId = req.params.checklistId;
@@ -173,6 +216,15 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation new_checklist
+ * @summary create a new checklist
+ *
+ * @param {string} boardId the board ID
+ * @param {string} cardId the card ID
+ * @param {string} title the title of the new checklist
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/cards/:cardId/checklists', function (req, res) {
Authentication.checkUserId( req.userId);
@@ -204,6 +256,17 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation delete_checklist
+ * @summary Delete a checklist
+ *
+ * @description The checklist will be removed, not put in the recycle bin.
+ *
+ * @param {string} boardId the board ID
+ * @param {string} cardId the card ID
+ * @param {string} checklistId the ID of the checklist to remove
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId', function (req, res) {
Authentication.checkUserId( req.userId);
const paramChecklistId = req.params.checklistId;
diff --git a/models/customFields.js b/models/customFields.js
index 5bb5e743..3e8aa250 100644
--- a/models/customFields.js
+++ b/models/customFields.js
@@ -1,40 +1,73 @@
CustomFields = new Mongo.Collection('customFields');
+/**
+ * A custom field on a card in the board
+ */
CustomFields.attachSchema(new SimpleSchema({
boardId: {
+ /**
+ * the ID of the board
+ */
type: String,
},
name: {
+ /**
+ * name of the custom field
+ */
type: String,
},
type: {
+ /**
+ * type of the custom field
+ */
type: String,
allowedValues: ['text', 'number', 'date', 'dropdown'],
},
settings: {
+ /**
+ * settings of the custom field
+ */
type: Object,
},
'settings.dropdownItems': {
+ /**
+ * list of drop down items objects
+ */
type: [Object],
optional: true,
},
'settings.dropdownItems.$': {
type: new SimpleSchema({
_id: {
+ /**
+ * ID of the drop down item
+ */
type: String,
},
name: {
+ /**
+ * name of the drop down item
+ */
type: String,
},
}),
},
showOnCard: {
+ /**
+ * should we show on the cards this custom field
+ */
type: Boolean,
},
automaticallyOnCard: {
+ /**
+ * should the custom fields automatically be added on cards?
+ */
type: Boolean,
},
showLabelOnMiniCard: {
+ /**
+ * should the label of the custom field be shown on minicards?
+ */
type: Boolean,
},
}));
@@ -88,6 +121,15 @@ if (Meteor.isServer) {
//CUSTOM FIELD REST API
if (Meteor.isServer) {
+ /**
+ * @operation get_all_custom_fields
+ * @summary Get the list of Custom Fields attached to a board
+ *
+ * @param {string} boardID the ID of the board
+ * @return_type [{_id: string,
+ * name: string,
+ * type: string}]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/custom-fields', function (req, res) {
Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
@@ -103,6 +145,14 @@ if (Meteor.isServer) {
});
});
+ /**
+ * @operation get_custom_field
+ * @summary Get a Custom Fields attached to a board
+ *
+ * @param {string} boardID the ID of the board
+ * @param {string} customFieldId the ID of the custom field
+ * @return_type CustomFields
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/custom-fields/:customFieldId', function (req, res) {
Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
@@ -113,6 +163,19 @@ if (Meteor.isServer) {
});
});
+ /**
+ * @operation new_custom_field
+ * @summary Create a Custom Field
+ *
+ * @param {string} boardID the ID of the board
+ * @param {string} name the name of the custom field
+ * @param {string} type the type of the custom field
+ * @param {string} settings the settings object of the custom field
+ * @param {boolean} showOnCard should we show the custom field on cards?
+ * @param {boolean} automaticallyOnCard should the custom fields automatically be added on cards?
+ * @param {boolean} showLabelOnMiniCard should the label of the custom field be shown on minicards?
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/custom-fields', function (req, res) {
Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
@@ -137,6 +200,16 @@ if (Meteor.isServer) {
});
});
+ /**
+ * @operation delete_custom_field
+ * @summary Delete a Custom Fields attached to a board
+ *
+ * @description The Custom Field can't be retrieved after this operation
+ *
+ * @param {string} boardID the ID of the board
+ * @param {string} customFieldId the ID of the custom field
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/custom-fields/:customFieldId', function (req, res) {
Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
diff --git a/models/export.js b/models/export.js
index 62d2687a..fa4894d9 100644
--- a/models/export.js
+++ b/models/export.js
@@ -6,13 +6,20 @@ if (Meteor.isServer) {
// `ApiRoutes.path('boards/export', boardId)``
// on the client instead of copy/pasting the route path manually between the
// client and the server.
- /*
- * This route is used to export the board FROM THE APPLICATION.
- * If user is already logged-in, pass loginToken as param "authToken":
- * '/api/boards/:boardId/export?authToken=:token'
+ /**
+ * @operation export
+ * @tag Boards
+ *
+ * @summary This route is used to export the board **FROM THE APPLICATION**.
+ *
+ * @description If user is already logged-in, pass loginToken as param
+ * "authToken": '/api/boards/:boardId/export?authToken=:token'
*
* See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/
* for detailed explanations
+ *
+ * @param {string} boardId the ID of the board we are exporting
+ * @param {string} authToken the loginToken
*/
JsonRoutes.add('get', '/api/boards/:boardId/export', function(req, res) {
const boardId = req.params.boardId;
diff --git a/models/integrations.js b/models/integrations.js
index 1062b93b..1c473b57 100644
--- a/models/integrations.js
+++ b/models/integrations.js
@@ -1,33 +1,60 @@
Integrations = new Mongo.Collection('integrations');
+/**
+ * Integration with third-party applications
+ */
Integrations.attachSchema(new SimpleSchema({
enabled: {
+ /**
+ * is the integration enabled?
+ */
type: Boolean,
defaultValue: true,
},
title: {
+ /**
+ * name of the integration
+ */
type: String,
optional: true,
},
type: {
+ /**
+ * type of the integratation (Default to 'outgoing-webhooks')
+ */
type: String,
defaultValue: 'outgoing-webhooks',
},
activities: {
+ /**
+ * activities the integration gets triggered (list)
+ */
type: [String],
defaultValue: ['all'],
},
url: { // URL validation regex (https://mathiasbynens.be/demo/url-regex)
+ /**
+ * URL validation regex (https://mathiasbynens.be/demo/url-regex)
+ */
type: String,
},
token: {
+ /**
+ * token of the integration
+ */
type: String,
optional: true,
},
boardId: {
+ /**
+ * Board ID of the integration
+ */
type: String,
},
createdAt: {
+ /**
+ * Creation date of the integration
+ */
type: Date,
denyUpdate: false,
autoValue() { // eslint-disable-line consistent-return
@@ -39,6 +66,9 @@ Integrations.attachSchema(new SimpleSchema({
},
},
userId: {
+ /**
+ * user ID who created the interation
+ */
type: String,
},
}));
@@ -58,7 +88,13 @@ Integrations.allow({
//INTEGRATIONS REST API
if (Meteor.isServer) {
- // Get all integrations in board
+ /**
+ * @operation get_all_integrations
+ * @summary Get all integrations in board
+ *
+ * @param {string} boardId the board ID
+ * @return_type [Integrations]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/integrations', function(req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -78,7 +114,14 @@ if (Meteor.isServer) {
}
});
- // Get a single integration in board
+ /**
+ * @operation get_integration
+ * @summary Get a single integration in board
+ *
+ * @param {string} boardId the board ID
+ * @param {string} intId the integration ID
+ * @return_type Integrations
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/integrations/:intId', function(req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -98,7 +141,14 @@ if (Meteor.isServer) {
}
});
- // Create a new integration
+ /**
+ * @operation new_integration
+ * @summary Create a new integration
+ *
+ * @param {string} boardId the board ID
+ * @param {string} url the URL of the integration
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/integrations', function(req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -125,7 +175,19 @@ if (Meteor.isServer) {
}
});
- // Edit integration data
+ /**
+ * @operation edit_integration
+ * @summary Edit integration data
+ *
+ * @param {string} boardId the board ID
+ * @param {string} intId the integration ID
+ * @param {string} [enabled] is the integration enabled?
+ * @param {string} [title] new name of the integration
+ * @param {string} [url] new URL of the integration
+ * @param {string} [token] new token of the integration
+ * @param {string} [activities] new list of activities of the integration
+ * @return_type {_id: string}
+ */
JsonRoutes.add('PUT', '/api/boards/:boardId/integrations/:intId', function (req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -173,7 +235,15 @@ if (Meteor.isServer) {
}
});
- // Delete subscribed activities
+ /**
+ * @operation delete_integration_activities
+ * @summary Delete subscribed activities
+ *
+ * @param {string} boardId the board ID
+ * @param {string} intId the integration ID
+ * @param {string} newActivities the activities to remove from the integration
+ * @return_type Integrations
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/integrations/:intId/activities', function (req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -197,7 +267,15 @@ if (Meteor.isServer) {
}
});
- // Add subscribed activities
+ /**
+ * @operation new_integration_activities
+ * @summary Add subscribed activities
+ *
+ * @param {string} boardId the board ID
+ * @param {string} intId the integration ID
+ * @param {string} newActivities the activities to add to the integration
+ * @return_type Integrations
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/integrations/:intId/activities', function (req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -221,7 +299,14 @@ if (Meteor.isServer) {
}
});
- // Delete integration
+ /**
+ * @operation delete_integration
+ * @summary Delete integration
+ *
+ * @param {string} boardId the board ID
+ * @param {string} intId the integration ID
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/integrations/:intId', function (req, res) {
try {
const paramBoardId = req.params.boardId;
diff --git a/models/lists.js b/models/lists.js
index b99fe8f5..0e1ba801 100644
--- a/models/lists.js
+++ b/models/lists.js
@@ -1,10 +1,19 @@
Lists = new Mongo.Collection('lists');
+/**
+ * A list (column) in the Wekan board.
+ */
Lists.attachSchema(new SimpleSchema({
title: {
+ /**
+ * the title of the list
+ */
type: String,
},
archived: {
+ /**
+ * is the list archived
+ */
type: Boolean,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -13,9 +22,15 @@ Lists.attachSchema(new SimpleSchema({
},
},
boardId: {
+ /**
+ * the board associated to this list
+ */
type: String,
},
createdAt: {
+ /**
+ * creation date
+ */
type: Date,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert) {
@@ -26,12 +41,18 @@ Lists.attachSchema(new SimpleSchema({
},
},
sort: {
+ /**
+ * is the list sorted
+ */
type: Number,
decimal: true,
// XXX We should probably provide a default
optional: true,
},
updatedAt: {
+ /**
+ * last update of the list
+ */
type: Date,
optional: true,
autoValue() { // eslint-disable-line consistent-return
@@ -43,19 +64,31 @@ Lists.attachSchema(new SimpleSchema({
},
},
wipLimit: {
+ /**
+ * WIP object, see below
+ */
type: Object,
optional: true,
},
'wipLimit.value': {
+ /**
+ * value of the WIP
+ */
type: Number,
decimal: false,
defaultValue: 1,
},
'wipLimit.enabled': {
+ /**
+ * is the WIP enabled
+ */
type: Boolean,
defaultValue: false,
},
'wipLimit.soft': {
+ /**
+ * is the WIP a soft or hard requirement
+ */
type: Boolean,
defaultValue: false,
},
@@ -212,6 +245,14 @@ if (Meteor.isServer) {
//LISTS REST API
if (Meteor.isServer) {
+ /**
+ * @operation get_all_lists
+ * @summary Get the list of Lists attached to a board
+ *
+ * @param {string} boardId the board ID
+ * @return_type [{_id: string,
+ * title: string}]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/lists', function (req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -235,6 +276,14 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_list
+ * @summary Get a List attached to a board
+ *
+ * @param {string} boardId the board ID
+ * @param {string} listId the List ID
+ * @return_type Lists
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId', function (req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -253,6 +302,14 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation new_list
+ * @summary Add a List to a board
+ *
+ * @param {string} boardId the board ID
+ * @param {string} title the title of the List
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/lists', function (req, res) {
try {
Authentication.checkUserId( req.userId);
@@ -276,6 +333,17 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation delete_list
+ * @summary Delete a List
+ *
+ * @description This **deletes** a list from a board.
+ * The list is not put in the recycle bin.
+ *
+ * @param {string} boardId the board ID
+ * @param {string} listId the ID of the list to remove
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId', function (req, res) {
try {
Authentication.checkUserId( req.userId);
diff --git a/models/swimlanes.js b/models/swimlanes.js
index 3559bcd2..fa5245da 100644
--- a/models/swimlanes.js
+++ b/models/swimlanes.js
@@ -1,10 +1,19 @@
Swimlanes = new Mongo.Collection('swimlanes');
+/**
+ * A swimlane is an line in the kaban board.
+ */
Swimlanes.attachSchema(new SimpleSchema({
title: {
+ /**
+ * the title of the swimlane
+ */
type: String,
},
archived: {
+ /**
+ * is the swimlane archived?
+ */
type: Boolean,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert && !this.isSet) {
@@ -13,9 +22,15 @@ Swimlanes.attachSchema(new SimpleSchema({
},
},
boardId: {
+ /**
+ * the ID of the board the swimlane is attached to
+ */
type: String,
},
createdAt: {
+ /**
+ * creation date of the swimlane
+ */
type: Date,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert) {
@@ -26,12 +41,18 @@ Swimlanes.attachSchema(new SimpleSchema({
},
},
sort: {
+ /**
+ * the sort value of the swimlane
+ */
type: Number,
decimal: true,
// XXX We should probably provide a default
optional: true,
},
updatedAt: {
+ /**
+ * when was the swimlane last edited
+ */
type: Date,
optional: true,
autoValue() { // eslint-disable-line consistent-return
@@ -131,6 +152,15 @@ if (Meteor.isServer) {
//SWIMLANE REST API
if (Meteor.isServer) {
+ /**
+ * @operation get_all_swimlanes
+ *
+ * @summary Get the list of swimlanes attached to a board
+ *
+ * @param {string} boardId the ID of the board
+ * @return_type [{_id: string,
+ * title: string}]
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/swimlanes', function (req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -154,6 +184,15 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_swimlane
+ *
+ * @summary Get a swimlane
+ *
+ * @param {string} boardId the ID of the board
+ * @param {string} swimlaneId the ID of the swimlane
+ * @return_type Swimlanes
+ */
JsonRoutes.add('GET', '/api/boards/:boardId/swimlanes/:swimlaneId', function (req, res) {
try {
const paramBoardId = req.params.boardId;
@@ -172,6 +211,15 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation new_swimlane
+ *
+ * @summary Add a swimlane to a board
+ *
+ * @param {string} boardId the ID of the board
+ * @param {string} title the new title of the swimlane
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/swimlanes', function (req, res) {
try {
Authentication.checkUserId( req.userId);
@@ -195,6 +243,17 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation delete_swimlane
+ *
+ * @summary Delete a swimlane
+ *
+ * @description The swimlane will be deleted, not moved to the recycle bin
+ *
+ * @param {string} boardId the ID of the board
+ * @param {string} swimlaneId the ID of the swimlane
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/boards/:boardId/swimlanes/:swimlaneId', function (req, res) {
try {
Authentication.checkUserId( req.userId);
diff --git a/models/users.js b/models/users.js
index d4c678b7..56643848 100644
--- a/models/users.js
+++ b/models/users.js
@@ -4,8 +4,14 @@ const isSandstorm = Meteor.settings && Meteor.settings.public &&
Meteor.settings.public.sandstorm;
Users = Meteor.users;
+/**
+ * A User in wekan
+ */
Users.attachSchema(new SimpleSchema({
username: {
+ /**
+ * the username of the user
+ */
type: String,
optional: true,
autoValue() { // eslint-disable-line consistent-return
@@ -18,17 +24,29 @@ Users.attachSchema(new SimpleSchema({
},
},
emails: {
+ /**
+ * the list of emails attached to a user
+ */
type: [Object],
optional: true,
},
'emails.$.address': {
+ /**
+ * The email address
+ */
type: String,
regEx: SimpleSchema.RegEx.Email,
},
'emails.$.verified': {
+ /**
+ * Has the email been verified
+ */
type: Boolean,
},
createdAt: {
+ /**
+ * creation date of the user
+ */
type: Date,
autoValue() { // eslint-disable-line consistent-return
if (this.isInsert) {
@@ -39,6 +57,9 @@ Users.attachSchema(new SimpleSchema({
},
},
profile: {
+ /**
+ * profile settings
+ */
type: Object,
optional: true,
autoValue() { // eslint-disable-line consistent-return
@@ -50,50 +71,86 @@ Users.attachSchema(new SimpleSchema({
},
},
'profile.avatarUrl': {
+ /**
+ * URL of the avatar of the user
+ */
type: String,
optional: true,
},
'profile.emailBuffer': {
+ /**
+ * list of email buffers of the user
+ */
type: [String],
optional: true,
},
'profile.fullname': {
+ /**
+ * full name of the user
+ */
type: String,
optional: true,
},
'profile.hiddenSystemMessages': {
+ /**
+ * does the user wants to hide system messages?
+ */
type: Boolean,
optional: true,
},
'profile.initials': {
+ /**
+ * initials of the user
+ */
type: String,
optional: true,
},
'profile.invitedBoards': {
+ /**
+ * board IDs the user has been invited to
+ */
type: [String],
optional: true,
},
'profile.language': {
+ /**
+ * language of the user
+ */
type: String,
optional: true,
},
'profile.notifications': {
+ /**
+ * enabled notifications for the user
+ */
type: [String],
optional: true,
},
'profile.showCardsCountAt': {
+ /**
+ * showCardCountAt field of the user
+ */
type: Number,
optional: true,
},
'profile.starredBoards': {
+ /**
+ * list of starred board IDs
+ */
type: [String],
optional: true,
},
'profile.icode': {
+ /**
+ * icode
+ */
type: String,
optional: true,
},
'profile.boardView': {
+ /**
+ * boardView field of the user
+ */
type: String,
optional: true,
allowedValues: [
@@ -103,27 +160,45 @@ Users.attachSchema(new SimpleSchema({
],
},
services: {
+ /**
+ * services field of the user
+ */
type: Object,
optional: true,
blackbox: true,
},
heartbeat: {
+ /**
+ * last time the user has been seen
+ */
type: Date,
optional: true,
},
isAdmin: {
+ /**
+ * is the user an admin of the board?
+ */
type: Boolean,
optional: true,
},
createdThroughApi: {
+ /**
+ * was the user created through the API?
+ */
type: Boolean,
optional: true,
},
loginDisabled: {
+ /**
+ * loginDisabled field of the user
+ */
type: Boolean,
optional: true,
},
'authenticationMethod': {
+ /**
+ * authentication method of the user
+ */
type: String,
optional: false,
defaultValue: 'password',
@@ -681,6 +756,12 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_current_user
+ *
+ * @summary returns the current user
+ * @return_type Users
+ */
JsonRoutes.add('GET', '/api/user', function(req, res) {
try {
Authentication.checkLoggedIn(req.userId);
@@ -699,6 +780,15 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_all_users
+ *
+ * @summary return all the users
+ *
+ * @description Only the admin user (the first user) can call the REST API.
+ * @return_type [{ _id: string,
+ * username: string}]
+ */
JsonRoutes.add('GET', '/api/users', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -717,6 +807,16 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation get_user
+ *
+ * @summary get a given user
+ *
+ * @description Only the admin user (the first user) can call the REST API.
+ *
+ * @param {string} userId the user ID
+ * @return_type Users
+ */
JsonRoutes.add('GET', '/api/users/:userId', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -734,6 +834,23 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation edit_user
+ *
+ * @summary edit a given user
+ *
+ * @description Only the admin user (the first user) can call the REST API.
+ *
+ * Possible values for *action*:
+ * - `takeOwnership`: The admin takes the ownership of ALL boards of the user (archived and not archived) where the user is admin on.
+ * - `disableLogin`: Disable a user (the user is not allowed to login and his login tokens are purged)
+ * - `enableLogin`: Enable a user
+ *
+ * @param {string} userId the user ID
+ * @param {string} action the action
+ * @return_type {_id: string,
+ * title: string}
+ */
JsonRoutes.add('PUT', '/api/users/:userId', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -777,6 +894,25 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation add_board_member
+ * @tag Boards
+ *
+ * @summary Add New Board Member with Role
+ *
+ * @description Only the admin user (the first user) can call the REST API.
+ *
+ * **Note**: see [Boards.set_board_member_permission](#set_board_member_permission)
+ * to later change the permissions.
+ *
+ * @param {string} boardId the board ID
+ * @param {string} userId the user ID
+ * @param {boolean} isAdmin is the user an admin of the board
+ * @param {boolean} isNoComments disable comments
+ * @param {boolean} isCommentOnly only enable comments
+ * @return_type {_id: string,
+ * title: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/members/:userId/add', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -817,6 +953,20 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation remove_board_member
+ * @tag Boards
+ *
+ * @summary Remove Member from Board
+ *
+ * @description Only the admin user (the first user) can call the REST API.
+ *
+ * @param {string} boardId the board ID
+ * @param {string} userId the user ID
+ * @param {string} action the action (needs to be `remove`)
+ * @return_type {_id: string,
+ * title: string}
+ */
JsonRoutes.add('POST', '/api/boards/:boardId/members/:userId/remove', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -852,6 +1002,18 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation new_user
+ *
+ * @summary Create a new user
+ *
+ * @description Only the admin user (the first user) can call the REST API.
+ *
+ * @param {string} username the new username
+ * @param {string} email the email of the new user
+ * @param {string} password the password of the new user
+ * @return_type {_id: string}
+ */
JsonRoutes.add('POST', '/api/users/', function (req, res) {
try {
Authentication.checkUserId(req.userId);
@@ -876,6 +1038,16 @@ if (Meteor.isServer) {
}
});
+ /**
+ * @operation delete_user
+ *
+ * @summary Delete a user
+ *
+ * @description Only the admin user (the first user) can call the REST API.
+ *
+ * @param {string} userId the ID of the user to delete
+ * @return_type {_id: string}
+ */
JsonRoutes.add('DELETE', '/api/users/:userId', function (req, res) {
try {
Authentication.checkUserId(req.userId);