diff --git a/server/api/controllers/access-tokens/accept-terms.js b/server/api/controllers/access-tokens/accept-terms.js index 3b616c4a..5e927468 100644 --- a/server/api/controllers/access-tokens/accept-terms.js +++ b/server/api/controllers/access-tokens/accept-terms.js @@ -3,6 +3,92 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/access-tokens/accept-terms: + * post: + * summary: Accept terms and conditions + * description: Accept terms during the authentication flow. Converts the pending token to an access token. + * tags: + * - Access Tokens + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - pendingToken + * - signature + * properties: + * pendingToken: + * type: string + * maxLength: 1024 + * description: Pending token received from the authentication flow + * example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4... + * signature: + * type: string + * minLength: 64 + * maxLength: 64 + * description: Terms signature hash based on user role + * example: 940226c4c41f51afe3980ceb63704e752636526f4c52a4ea579e85b247493d94 + * responses: + * 200: + * description: Terms accepted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * type: string + * description: Access token for API authentication + * example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ5... + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * description: Invalid pending token + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNAUTHORIZED + * message: + * type: string + * description: Error message + * example: Invalid pending token + * 403: + * description: Authentication restriction + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_FORBIDDEN + * message: + * type: string + * enum: + * - Invalid signature + * - Admin login required to initialize instance + * description: Specific error message + * example: Invalid signature + */ + const { getRemoteAddress } = require('../../../utils/remote-address'); const { AccessTokenSteps } = require('../../../constants'); diff --git a/server/api/controllers/access-tokens/create.js b/server/api/controllers/access-tokens/create.js index 397c1e10..8e98cce0 100755 --- a/server/api/controllers/access-tokens/create.js +++ b/server/api/controllers/access-tokens/create.js @@ -3,6 +3,106 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/access-tokens: + * post: + * summary: User login + * description: Authenticates a user using email/username and password. Returns an access token for API authentication. + * tags: + * - Access Tokens + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - emailOrUsername + * - password + * properties: + * emailOrUsername: + * type: string + * maxLength: 256 + * description: Email address or username of the user + * example: john.doe@example.com + * password: + * type: string + * maxLength: 256 + * description: Password of the user + * example: SecurePassword123! + * withHttpOnlyToken: + * type: boolean + * description: Whether to include an HTTP-only authentication cookie + * example: true + * responses: + * 200: + * description: Login successful + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * type: string + * description: Access token for API authentication + * example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4... + * headers: + * Set-Cookie: + * description: HTTP-only authentication cookie (if withHttpOnlyToken is true) + * schema: + * type: string + * example: httpOnlyToken=29aa3e38-8d24-4029-9743-9cbcf0a0dd5c; HttpOnly; Secure; SameSite=Strict + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * description: Invalid credentials + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNAUTHORIZED + * message: + * type: string + * enum: + * - Invalid credentials + * - Invalid email or username + * - Invalid password + * description: Specific error message + * example: Invalid credentials + * 403: + * description: Authentication restriction + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_FORBIDDEN + * message: + * type: string + * enum: + * - Use single sign-on + * - Terms acceptance required + * - Admin login required to initialize instance + * description: Specific error message + * example: Use single sign-on + */ + const bcrypt = require('bcrypt'); const { isEmailOrUsername } = require('../../../utils/validators'); diff --git a/server/api/controllers/access-tokens/delete.js b/server/api/controllers/access-tokens/delete.js index 9e15d16d..1e7a36b5 100644 --- a/server/api/controllers/access-tokens/delete.js +++ b/server/api/controllers/access-tokens/delete.js @@ -3,6 +3,32 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/access-tokens: + * delete: + * summary: User logout + * description: Logs out the current user by deleting the session and access token. Clears HTTP-only cookies if present. + * tags: + * - Access Tokens + * responses: + * 200: + * description: Logout successful + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * type: string + * description: Revoked access token + * example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4... + * 401: + * $ref: '#/components/responses/Unauthorized' + */ + module.exports = { async fn() { const { currentSession } = this.req; diff --git a/server/api/controllers/access-tokens/exchange-with-oidc.js b/server/api/controllers/access-tokens/exchange-with-oidc.js index 92101877..32f21921 100644 --- a/server/api/controllers/access-tokens/exchange-with-oidc.js +++ b/server/api/controllers/access-tokens/exchange-with-oidc.js @@ -3,6 +3,156 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/access-tokens/exchange-with-oidc: + * post: + * summary: Exchange OIDC code for access token + * description: Exchanges an OIDC authorization code for an access token. Creates a user if they do not exist. + * tags: + * - Access Tokens + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - nonce + * properties: + * code: + * type: string + * maxLength: 2048 + * description: Authorization code from OIDC provider + * example: abc123def456ghi789 + * nonce: + * type: string + * maxLength: 1024 + * description: Nonce value for OIDC security + * example: random-nonce-123456 + * withHttpOnlyToken: + * type: boolean + * description: Whether to include HTTP-only authentication cookie + * example: true + * responses: + * 200: + * description: OIDC exchange successful + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * type: string + * description: Access token for API authentication + * example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4... + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * description: OIDC authentication error + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNAUTHORIZED + * message: + * type: string + * enum: + * - Invalid code or nonce + * - Invalid userinfo configuration + * description: Specific error message + * example: Invalid code or nonce + * 403: + * description: Authentication restriction + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_FORBIDDEN + * message: + * type: string + * enum: + * - Terms acceptance required + * - Admin login required to initialize instance + * description: Specific error message + * example: Terms acceptance required + * 409: + * description: Conflict error + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_CONFLICT + * message: + * type: string + * enum: + * - Email already in use + * - Username already in use + * - Active users limit reached + * description: Specific error message + * example: Email already in use + * 422: + * description: Missing required values + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNPROCESSABLE_ENTITY + * message: + * type: string + * description: Error message + * example: Unable to retrieve required values (email, name) + * 500: + * description: OIDC configuration error + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_INTERNAL_SERVER_ERROR + * message: + * type: string + * description: Error message + * example: Invalid OIDC configuration + */ + const { getRemoteAddress } = require('../../../utils/remote-address'); const Errors = { diff --git a/server/api/controllers/access-tokens/revoke-pending-token.js b/server/api/controllers/access-tokens/revoke-pending-token.js index 206acc09..0348358f 100644 --- a/server/api/controllers/access-tokens/revoke-pending-token.js +++ b/server/api/controllers/access-tokens/revoke-pending-token.js @@ -3,6 +3,46 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/access-tokens/revoke-pending-token: + * post: + * summary: Revoke pending token + * description: Revokes a pending authentication token and cancels the authentication flow. + * tags: + * - Access Tokens + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - pendingToken + * properties: + * pendingToken: + * type: string + * maxLength: 1024 + * description: Pending token to revoke + * example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4... + * responses: + * 200: + * description: Pending token revoked successfully + * content: + * application/json: + * schema: + * type: object + * properties: + * item: + * type: null + * description: No data returned + * example: null + * 400: + * $ref: '#/components/responses/ValidationError' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const Errors = { PENDING_TOKEN_NOT_FOUND: { pendingTokenNotFound: 'Pending token not found', diff --git a/server/api/controllers/actions/index-in-board.js b/server/api/controllers/actions/index-in-board.js index 91312bd8..e52e3358 100755 --- a/server/api/controllers/actions/index-in-board.js +++ b/server/api/controllers/actions/index-in-board.js @@ -3,6 +3,62 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{boardId}/actions: + * get: + * summary: Get board actions + * description: Retrieves a list of actions (activity history) for a specific board, with pagination support. + * tags: + * - Actions + * parameters: + * - name: boardId + * in: path + * required: true + * description: ID of the board to get actions for + * schema: + * type: string + * example: 1357158568008091264 + * - name: beforeId + * in: query + * required: false + * description: ID to get actions before (for pagination) + * schema: + * type: string + * example: 1357158568008091265 + * responses: + * 200: + * description: Board actions retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * - included + * properties: + * items: + * type: array + * items: + * $ref: '#/components/schemas/Action' + * included: + * type: object + * required: + * - users + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/actions/index-in-card.js b/server/api/controllers/actions/index-in-card.js index 6e1a5358..1b3d4555 100755 --- a/server/api/controllers/actions/index-in-card.js +++ b/server/api/controllers/actions/index-in-card.js @@ -3,6 +3,62 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/actions: + * get: + * summary: Get card actions + * description: Retrieves a list of actions (activity history) for a specific card, with pagination support. + * tags: + * - Actions + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to get actions for + * schema: + * type: string + * example: 1357158568008091264 + * - name: beforeId + * in: query + * required: false + * description: ID to get actions before (for pagination) + * schema: + * type: string + * example: 1357158568008091265 + * responses: + * 200: + * description: Card actions retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * - included + * properties: + * items: + * type: array + * items: + * $ref: '#/components/schemas/Action' + * included: + * type: object + * required: + * - users + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/attachments/create.js b/server/api/controllers/attachments/create.js index eee4ea53..8589939e 100644 --- a/server/api/controllers/attachments/create.js +++ b/server/api/controllers/attachments/create.js @@ -3,6 +3,118 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/attachments: + * post: + * summary: Create attachment + * description: Creates an attachment on a card. Requires board editor permissions. + * tags: + * - Attachments + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to create the attachment on + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - type + * - url + * - name + * properties: + * type: + * type: string + * enum: [link] + * description: Type of the attachment + * example: link + * url: + * type: string + * maxLength: 2048 + * description: URL for the link attachment + * example: https://google.com/search?q=planka + * name: + * type: string + * maxLength: 128 + * description: Name/title of the attachment + * example: Google Link + * multipart/form-data: + * schema: + * type: object + * required: + * - type + * - file + * - name + * properties: + * type: + * type: string + * enum: [file] + * description: Type of the attachment + * example: file + * file: + * type: string + * format: binary + * description: File to upload + * name: + * type: string + * maxLength: 128 + * description: Name/title of the attachment + * example: Important Document + * requestId: + * type: string + * maxLength: 128 + * description: Request ID for tracking + * example: req_123456 + * responses: + * 200: + * description: Attachment created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Attachment' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * description: Upload or validation error + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNPROCESSABLE_ENTITY + * message: + * type: string + * enum: + * - No file was uploaded + * - Url must be present + * description: Specific error message + * example: No file was uploaded + */ + const { isUrl } = require('../../../utils/validators'); const { idInput } = require('../../../utils/inputs'); diff --git a/server/api/controllers/attachments/delete.js b/server/api/controllers/attachments/delete.js index 0bdb288f..6dac01fa 100755 --- a/server/api/controllers/attachments/delete.js +++ b/server/api/controllers/attachments/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/attachments/{id}: + * delete: + * summary: Delete attachment + * description: Deletes an attachment. Requires board editor permissions. + * tags: + * - Attachments + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the attachment to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Attachment deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Attachment' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/attachments/update.js b/server/api/controllers/attachments/update.js index 779cd76c..7423e3b3 100755 --- a/server/api/controllers/attachments/update.js +++ b/server/api/controllers/attachments/update.js @@ -3,6 +3,56 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/attachments/{id}: + * patch: + * summary: Update attachment + * description: Updates an attachment. Requires board editor permissions. + * tags: + * - Attachments + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the attachment to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * name: + * type: string + * maxLength: 128 + * description: Name/title of the attachment + * example: Google Link + * responses: + * 200: + * description: Attachment updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Attachment' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/background-images/create.js b/server/api/controllers/background-images/create.js index 547758a6..21ff056c 100644 --- a/server/api/controllers/background-images/create.js +++ b/server/api/controllers/background-images/create.js @@ -3,6 +3,83 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects/{projectId}/background-images: + * post: + * summary: Upload background image + * description: Uploads a background image for a project. Requires project manager permissions. + * tags: + * - Background Images + * parameters: + * - name: projectId + * in: path + * required: true + * description: ID of the project to upload background image for + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * multipart/form-data: + * schema: + * type: object + * required: + * - file + * properties: + * file: + * type: string + * format: binary + * description: Background image file (must be an image format) + * requestId: + * type: string + * maxLength: 128 + * description: Request ID for tracking + * example: req_123456 + * responses: + * 200: + * description: Background image uploaded successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BackgroundImage' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * description: File upload error + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNPROCESSABLE_ENTITY + * message: + * type: string + * enum: + * - No file was uploaded + * - File is not image + * description: Specific error message + * example: No file was uploaded + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/background-images/delete.js b/server/api/controllers/background-images/delete.js index 6f528ee0..e2cd5c3d 100755 --- a/server/api/controllers/background-images/delete.js +++ b/server/api/controllers/background-images/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/background-images/{id}: + * delete: + * summary: Delete background image + * description: Deletes a background image. Requires project manager permissions. + * tags: + * - Background Images + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the background image to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Background image deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BackgroundImage' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/base-custom-field-groups/create.js b/server/api/controllers/base-custom-field-groups/create.js index 8dbdafd7..9771500f 100644 --- a/server/api/controllers/base-custom-field-groups/create.js +++ b/server/api/controllers/base-custom-field-groups/create.js @@ -3,6 +3,58 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects/{projectId}/base-custom-field-groups: + * post: + * summary: Create base custom field group + * description: Creates a base custom field group within a project. Requires project manager permissions. + * tags: + * - Base Custom Field Groups + * parameters: + * - name: projectId + * in: path + * required: true + * description: ID of the project to create the base custom field group in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - name + * properties: + * name: + * type: string + * maxLength: 128 + * description: Name/title of the base custom field group + * example: Base Properties + * responses: + * 200: + * description: Base custom field group created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BaseCustomFieldGroup' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/base-custom-field-groups/delete.js b/server/api/controllers/base-custom-field-groups/delete.js index 526c7a4b..062e6dc5 100644 --- a/server/api/controllers/base-custom-field-groups/delete.js +++ b/server/api/controllers/base-custom-field-groups/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/base-custom-field-groups/{id}: + * delete: + * summary: Delete base custom field group + * description: Deletes a base custom field group. Requires project manager permissions. + * tags: + * - Base Custom Field Groups + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the base custom field group to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Base custom field group deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BaseCustomFieldGroup' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/base-custom-field-groups/update.js b/server/api/controllers/base-custom-field-groups/update.js index fe244719..50f6f8da 100644 --- a/server/api/controllers/base-custom-field-groups/update.js +++ b/server/api/controllers/base-custom-field-groups/update.js @@ -3,6 +3,56 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/base-custom-field-groups/{id}: + * patch: + * summary: Update base custom field group + * description: Updates a base custom field group. Requires project manager permissions. + * tags: + * - Base Custom Field Groups + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the base custom field group to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * name: + * type: string + * maxLength: 128 + * description: Name/title of the base custom field group + * example: Base Properties + * responses: + * 200: + * description: Base custom field group updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BaseCustomFieldGroup' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/board-memberships/create.js b/server/api/controllers/board-memberships/create.js index d23d1d71..ab8fb366 100755 --- a/server/api/controllers/board-memberships/create.js +++ b/server/api/controllers/board-memberships/create.js @@ -3,6 +3,70 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{boardId}/memberships: + * post: + * summary: Add user to board + * description: Adds a user to a board. Requires project manager permissions. + * tags: + * - Board Memberships + * parameters: + * - name: boardId + * in: path + * required: true + * description: ID of the board to add the user to + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - userId + * - role + * properties: + * userId: + * type: string + * description: ID of the user to add to the board + * example: 1357158568008091265 + * role: + * type: string + * enum: [editor, viewer] + * description: Role of the user in the board + * example: editor + * canComment: + * type: boolean + * nullable: true + * description: Whether the user can comment on cards (applies only to viewers) + * example: true + * responses: + * 200: + * description: User added to board successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BoardMembership' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/board-memberships/delete.js b/server/api/controllers/board-memberships/delete.js index f0438bbc..0bdf7869 100755 --- a/server/api/controllers/board-memberships/delete.js +++ b/server/api/controllers/board-memberships/delete.js @@ -3,6 +3,42 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/board-memberships/{id}: + * delete: + * summary: Remove user from board + * description: Removes a user from a board. Users can remove themselves, or project managers can remove any user. + * tags: + * - Board Memberships + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the board membership to remove + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: User removed from board successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BoardMembership' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/board-memberships/update.js b/server/api/controllers/board-memberships/update.js index c0881e1f..d7f85e76 100644 --- a/server/api/controllers/board-memberships/update.js +++ b/server/api/controllers/board-memberships/update.js @@ -3,6 +3,59 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/board-memberships/{id}: + * patch: + * summary: Update board membership + * description: Updates a board membership. Requires project manager permissions. + * tags: + * - Board Memberships + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the board membership to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * role: + * type: string + * enum: [editor, viewer] + * description: Role of the user in the board + * example: editor + * canComment: + * type: boolean + * nullable: true + * description: Whether the user can comment on cards (applies only to viewers) + * example: true + * responses: + * 200: + * description: Board membership updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/BoardMembership' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/boards/create.js b/server/api/controllers/boards/create.js index 7a733e08..28fe7bb2 100755 --- a/server/api/controllers/boards/create.js +++ b/server/api/controllers/boards/create.js @@ -3,6 +3,178 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects/{projectId}/boards: + * post: + * summary: Create board + * description: Creates a board within a project. Supports importing from Trello. Requires project manager permissions. + * tags: + * - Boards + * parameters: + * - name: projectId + * in: path + * required: true + * description: ID of the project to create the board in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * - name + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the board within the project + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the board + * example: Development Board + * defaultView: + * type: string + * enum: [kanban, grid, list] + * default: kanban + * description: Default view for the board + * example: kanban + * defaultCardType: + * type: string + * enum: [project, story] + * default: project + * description: Default card type for new cards + * example: project + * limitCardTypesToDefaultOne: + * type: boolean + * default: false + * description: Whether to limit card types to default one + * example: false + * alwaysDisplayCardCreator: + * type: boolean + * default: false + * description: Whether to always display the card creator + * example: false + * expandTaskListsByDefault: + * type: boolean + * default: false + * description: Whether to expand task lists by default + * example: false + * multipart/form-data: + * schema: + * type: object + * required: + * - position + * - name + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the board within the project + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the board + * example: Development Board + * defaultView: + * type: string + * enum: [kanban, grid, list] + * default: kanban + * description: Default view for the board + * example: kanban + * defaultCardType: + * type: string + * enum: [project, story] + * default: project + * description: Default card type for new cards + * example: project + * limitCardTypesToDefaultOne: + * type: boolean + * default: false + * description: Whether to limit card types to default one + * example: false + * alwaysDisplayCardCreator: + * type: boolean + * default: false + * description: Whether to always display the card creator + * example: false + * expandTaskListsByDefault: + * type: boolean + * default: false + * description: Whether to expand task lists by default + * example: false + * importType: + * type: string + * enum: [trello] + * description: Type of import + * example: trello + * importFile: + * type: string + * format: binary + * description: Import file + * requestId: + * type: string + * maxLength: 128 + * description: Request ID for tracking + * example: req_123456 + * responses: + * 200: + * description: Board created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/Board' + * included: + * type: object + * required: + * - boardMemberships + * properties: + * boardMemberships: + * type: array + * items: + * $ref: '#/components/schemas/BoardMembership' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * description: Import file upload error + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNPROCESSABLE_ENTITY + * message: + * type: string + * enum: + * - No import file was uploaded + * - Invalid import file + * description: Specific error message + * example: No import file was uploaded + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/boards/delete.js b/server/api/controllers/boards/delete.js index af46ef52..39e61586 100755 --- a/server/api/controllers/boards/delete.js +++ b/server/api/controllers/boards/delete.js @@ -3,6 +3,42 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{id}: + * delete: + * summary: Delete board + * description: Deletes a board and all its contents (lists, cards, etc.). Requires project manager permissions. + * tags: + * - Boards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the board to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Board deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Board' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/boards/show.js b/server/api/controllers/boards/show.js index ca351616..1cbd3036 100755 --- a/server/api/controllers/boards/show.js +++ b/server/api/controllers/boards/show.js @@ -3,6 +3,152 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{id}: + * get: + * summary: Get board details + * description: Retrieves comprehensive board information, including lists, cards, and other related data. + * tags: + * - Boards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the board to retrieve + * schema: + * type: string + * example: 1357158568008091264 + * - name: subscribe + * in: query + * required: false + * description: Whether to subscribe to real-time updates for this board (only for socket connections) + * schema: + * type: boolean + * example: true + * responses: + * 200: + * description: Board details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * allOf: + * - $ref: '#/components/schemas/Board' + * - type: object + * properties: + * isSubscribed: + * type: boolean + * description: Whether the current user is subscribed to the board + * example: true + * included: + * type: object + * required: + * - users + * - projects + * - boardMemberships + * - labels + * - lists + * - cards + * - cardMemberships + * - cardLabels + * - taskLists + * - tasks + * - attachments + * - customFieldGroups + * - customFields + * - customFieldValues + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * projects: + * type: array + * description: Parent project + * items: + * $ref: '#/components/schemas/Project' + * boardMemberships: + * type: array + * description: Related board memberships + * items: + * $ref: '#/components/schemas/BoardMembership' + * labels: + * type: array + * description: Related labels + * items: + * $ref: '#/components/schemas/Label' + * lists: + * type: array + * description: Related lists + * items: + * $ref: '#/components/schemas/List' + * cards: + * type: array + * description: Related cards + * items: + * allOf: + * - $ref: '#/components/schemas/Card' + * - type: object + * properties: + * isSubscribed: + * type: boolean + * description: Whether the current user is subscribed to the card + * example: true + * cardMemberships: + * type: array + * description: Related card-membership associations + * items: + * $ref: '#/components/schemas/CardMembership' + * cardLabels: + * type: array + * description: Related card-label associations + * items: + * $ref: '#/components/schemas/CardLabel' + * taskLists: + * type: array + * description: Related task lists + * items: + * $ref: '#/components/schemas/TaskList' + * tasks: + * type: array + * description: Related tasks + * items: + * $ref: '#/components/schemas/Task' + * attachments: + * type: array + * description: Related attachments + * items: + * $ref: '#/components/schemas/Attachment' + * customFieldGroups: + * type: array + * description: Related custom field groups + * items: + * $ref: '#/components/schemas/CustomFieldGroup' + * customFields: + * type: array + * description: Related custom fields + * items: + * $ref: '#/components/schemas/CustomField' + * customFieldValues: + * type: array + * description: Related custom field values + * items: + * $ref: '#/components/schemas/CustomFieldValue' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/boards/update.js b/server/api/controllers/boards/update.js index 86c4971a..9c75c620 100755 --- a/server/api/controllers/boards/update.js +++ b/server/api/controllers/boards/update.js @@ -3,6 +3,84 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{id}: + * patch: + * summary: Update board + * description: Updates a board. Project managers can update all fields, board members can only subscribe/unsubscribe. + * tags: + * - Boards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the board to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the board within the project + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the board + * example: Development Board + * defaultView: + * type: string + * enum: [kanban, grid, list] + * description: Default view for the board + * example: kanban + * defaultCardType: + * type: string + * enum: [project, story] + * description: Default card type for new cards + * example: project + * limitCardTypesToDefaultOne: + * type: boolean + * description: Whether to limit card types to default one + * alwaysDisplayCardCreator: + * type: boolean + * description: Whether to limit card types to default one + * example: false + * expandTaskListsByDefault: + * type: boolean + * description: Whether to always display the card creator + * example: false + * isSubscribed: + * type: boolean + * description: Whether the current user is subscribed to the board + * example: true + * responses: + * 200: + * description: Board updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Board' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/card-labels/create.js b/server/api/controllers/card-labels/create.js index 76e76e00..498e75c1 100755 --- a/server/api/controllers/card-labels/create.js +++ b/server/api/controllers/card-labels/create.js @@ -3,6 +3,59 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/labels: + * post: + * summary: Add label to card + * description: Adds a label to a card. Requires board editor permissions. + * tags: + * - Card Labels + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to add the label to + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - labelId + * properties: + * labelId: + * type: string + * description: ID of the label to add to the card + * example: 1357158568008091265 + * responses: + * 200: + * description: Label added to card successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CardLabel' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/card-labels/delete.js b/server/api/controllers/card-labels/delete.js index 89c201f1..5daabd7d 100755 --- a/server/api/controllers/card-labels/delete.js +++ b/server/api/controllers/card-labels/delete.js @@ -3,6 +3,51 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/labels/{labelId}: + * delete: + * summary: Remove label from card + * description: Removes a label from a card. Requires board editor permissions. + * tags: + * - Card Labels + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to remove the label from + * schema: + * type: string + * example: 1357158568008091264 + * - name: labelId + * in: path + * required: true + * description: ID of the label to remove from the card + * schema: + * type: string + * example: 1357158568008091265 + * responses: + * 200: + * description: Label removed from card successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CardLabel' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/card-memberships/create.js b/server/api/controllers/card-memberships/create.js index e0199150..f5ba01df 100755 --- a/server/api/controllers/card-memberships/create.js +++ b/server/api/controllers/card-memberships/create.js @@ -3,6 +3,59 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/memberships: + * post: + * summary: Add user to card + * description: Adds a user to a card. Requires board editor permissions. + * tags: + * - Card Memberships + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to add the user to + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - userId + * properties: + * userId: + * type: string + * description: ID of the card to add the user to + * example: 1357158568008091265 + * responses: + * 200: + * description: User added to card successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CardMembership' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/card-memberships/delete.js b/server/api/controllers/card-memberships/delete.js index ec70c435..5eef131d 100755 --- a/server/api/controllers/card-memberships/delete.js +++ b/server/api/controllers/card-memberships/delete.js @@ -3,6 +3,51 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/memberships/{userId}: + * delete: + * summary: Remove user from card + * description: Removes a user from a card. Requires board editor permissions. + * tags: + * - Card Memberships + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to remove the user from + * schema: + * type: string + * example: 1357158568008091264 + * - name: userId + * in: path + * required: true + * description: ID of the user to remove from the card + * schema: + * type: string + * example: 1357158568008091265 + * responses: + * 200: + * description: User removed from card successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CardMembership' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/cards/create.js b/server/api/controllers/cards/create.js index 10ee39cb..50f32180 100755 --- a/server/api/controllers/cards/create.js +++ b/server/api/controllers/cards/create.js @@ -3,6 +3,106 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{listId}/cards: + * post: + * summary: Create card + * description: Creates a card within a list. Requires board editor permissions. + * tags: + * - Cards + * parameters: + * - name: listId + * in: path + * required: true + * description: ID of the list to create the card in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - type + * - name + * properties: + * type: + * type: string + * enum: [project, story] + * description: Type of the card + * example: project + * position: + * type: number + * minimum: 0 + * nullable: true + * description: Position of the card within the list + * example: 65536 + * name: + * type: string + * maxLength: 1024 + * description: Name/title of the card + * example: Implement user authentication + * description: + * type: string + * maxLength: 1048576 + * nullable: true + * description: Detailed description of the card + * example: Add JWT-based authentication system... + * dueDate: + * type: string + * format: date-time + * nullable: true + * description: Due date for the card + * example: 2024-01-01T00:00:00.000Z + * isDueCompleted: + * type: boolean + * nullable: true + * description: Whether the due date is completed + * example: false + * stopwatch: + * type: object + * required: + * - startedAt + * - total + * nullable: true + * description: Stopwatch data for time tracking + * properties: + * startedAt: + * type: string + * format: date-time + * description: When the stopwatch was started + * example: 2024-01-01T00:00:00.000Z + * total: + * type: number + * description: Total time in seconds + * example: 3600 + * responses: + * 200: + * description: Card created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Card' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { isDueDate, isStopwatch } = require('../../../utils/validators'); const { idInput } = require('../../../utils/inputs'); diff --git a/server/api/controllers/cards/delete.js b/server/api/controllers/cards/delete.js index 600ea84a..208159a5 100755 --- a/server/api/controllers/cards/delete.js +++ b/server/api/controllers/cards/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{id}: + * delete: + * summary: Delete card + * description: Deletes a card and all its contents (tasks, attachments, etc.). Requires board editor permissions. + * tags: + * - Cards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the card to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Card deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Card' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/cards/duplicate.js b/server/api/controllers/cards/duplicate.js index 906cb49f..3e672d80 100644 --- a/server/api/controllers/cards/duplicate.js +++ b/server/api/controllers/cards/duplicate.js @@ -3,6 +3,117 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{id}/duplicate: + * post: + * summary: Duplicate card + * description: Creates a duplicate of a card with all its contents (tasks, attachments, etc.). Requires board editor permissions. + * tags: + * - Cards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the card to duplicate + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * - name + * properties: + * position: + * type: number + * minimum: 0 + * description: Position for the duplicated card within the list + * example: 65536 + * name: + * type: string + * maxLength: 1024 + * description: Name/title for the duplicated card + * example: Implement user authentication (copy) + * responses: + * 200: + * description: Card duplicated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/Card' + * included: + * type: object + * required: + * - cardMemberships + * - cardLabels + * - taskLists + * - tasks + * - attachments + * - customFieldGroups + * - customFields + * - customFieldValues + * properties: + * cardMemberships: + * type: array + * description: Related card-membership associations + * items: + * $ref: '#/components/schemas/CardMembership' + * cardLabels: + * type: array + * description: Related card-label associations + * items: + * $ref: '#/components/schemas/CardLabel' + * taskLists: + * type: array + * description: Related task lists + * items: + * $ref: '#/components/schemas/TaskList' + * tasks: + * type: array + * description: Related tasks + * items: + * $ref: '#/components/schemas/Task' + * attachments: + * type: array + * description: Related attachments + * items: + * $ref: '#/components/schemas/Attachment' + * customFieldGroups: + * type: array + * description: Related custom field groups + * items: + * $ref: '#/components/schemas/CustomFieldGroup' + * customFields: + * type: array + * description: Related custom fields + * items: + * $ref: '#/components/schemas/CustomField' + * customFieldValues: + * type: array + * description: Related custom field values + * items: + * $ref: '#/components/schemas/CustomFieldValue' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/cards/index.js b/server/api/controllers/cards/index.js index b2add4ab..af6f5240 100644 --- a/server/api/controllers/cards/index.js +++ b/server/api/controllers/cards/index.js @@ -3,6 +3,139 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{listId}/cards: + * get: + * summary: Get cards in list + * description: Retrieves cards from an endless list with filtering, search, and pagination support. + * tags: + * - Cards + * parameters: + * - name: listId + * in: path + * required: true + * description: ID of the list to get cards from (must be an endless list) + * schema: + * type: string + * example: 1357158568008091264 + * - name: before + * in: query + * required: false + * description: Pagination cursor (JSON object with id and listChangedAt) + * schema: + * type: string + * example: '{"id": "1357158568008091269", "listChangedAt": "2024-01-01T00:00:00.000Z"}' + * - name: search + * in: query + * required: false + * description: Search term to filter cards + * schema: + * type: string + * maxLength: 128 + * example: bug fix + * - name: filterUserIds + * in: query + * required: false + * description: Comma-separated user IDs to filter by members + * schema: + * type: string + * example: 1357158568008091265,1357158568008091266 + * - name: filterLabelIds + * in: query + * required: false + * description: Comma-separated label IDs to filter by labels + * schema: + * type: string + * example: 1357158568008091267,1357158568008091268 + * responses: + * 200: + * description: Cards retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * - included + * properties: + * items: + * type: array + * items: + * allOf: + * - $ref: '#/components/schemas/Card' + * - type: object + * properties: + * isSubscribed: + * type: boolean + * description: Whether the current user is subscribed to the card + * example: true + * included: + * type: object + * required: + * - users + * - cardMemberships + * - cardLabels + * - taskLists + * - tasks + * - attachments + * - customFieldGroups + * - customFields + * - customFieldValues + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * cardMemberships: + * type: array + * description: Related card-membership associations + * items: + * $ref: '#/components/schemas/CardMembership' + * cardLabels: + * type: array + * description: Related card-label associations + * items: + * $ref: '#/components/schemas/CardLabel' + * taskLists: + * type: array + * description: Realted Task lists + * items: + * $ref: '#/components/schemas/TaskList' + * tasks: + * type: array + * description: Related tasks + * items: + * $ref: '#/components/schemas/Task' + * attachments: + * type: array + * description: Related attachments + * items: + * $ref: '#/components/schemas/Attachment' + * customFieldGroups: + * type: array + * description: Related custom field groups + * items: + * $ref: '#/components/schemas/CustomFieldGroup' + * customFields: + * type: array + * description: Related custom fields + * items: + * $ref: '#/components/schemas/CustomField' + * customFieldValues: + * type: array + * description: Related custom field values + * items: + * $ref: '#/components/schemas/CustomFieldValue' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const moment = require('moment'); const { isId } = require('../../../utils/validators'); diff --git a/server/api/controllers/cards/read-notifications.js b/server/api/controllers/cards/read-notifications.js index e5143658..c28c21cb 100644 --- a/server/api/controllers/cards/read-notifications.js +++ b/server/api/controllers/cards/read-notifications.js @@ -3,6 +3,53 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{id}/read-notifications: + * post: + * summary: Mark card notifications as read + * description: Marks all notifications for a specific card as read for the current user. Requires access to the card. + * tags: + * - Cards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the card to mark notifications as read for + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Notifications marked as read successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/Card' + * included: + * type: object + * required: + * - notifications + * properties: + * notifications: + * type: array + * description: Related notifications + * items: + * $ref: '#/components/schemas/Notification' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/cards/show.js b/server/api/controllers/cards/show.js index ee56f26a..fd801bd0 100755 --- a/server/api/controllers/cards/show.js +++ b/server/api/controllers/cards/show.js @@ -3,6 +3,108 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{id}: + * get: + * summary: Get card details + * description: Retrieves comprehensive card information, including tasks, attachments, and other related data. + * tags: + * - Cards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the card to retrieve + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Card details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * allOf: + * - $ref: '#/components/schemas/Card' + * - type: object + * properties: + * isSubscribed: + * type: boolean + * description: Whether the current user is subscribed to the card + * example: true + * included: + * type: object + * required: + * - users + * - cardMemberships + * - cardLabels + * - taskLists + * - tasks + * - attachments + * - customFieldGroups + * - customFields + * - customFieldValues + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * cardMemberships: + * type: array + * description: Related card-membership associations + * items: + * $ref: '#/components/schemas/CardMembership' + * cardLabels: + * type: array + * description: Related card-label associations + * items: + * $ref: '#/components/schemas/CardLabel' + * taskLists: + * type: array + * description: Related task lists + * items: + * $ref: '#/components/schemas/TaskList' + * tasks: + * type: array + * description: Related tasks + * items: + * $ref: '#/components/schemas/Task' + * attachments: + * type: array + * description: Related attachments + * items: + * $ref: '#/components/schemas/Attachment' + * customFieldGroups: + * type: array + * description: Related custom field groups + * items: + * $ref: '#/components/schemas/CustomFieldGroup' + * customFields: + * type: array + * description: Related custom fields + * items: + * $ref: '#/components/schemas/CustomField' + * customFieldValues: + * type: array + * description: Related custom field values + * items: + * $ref: '#/components/schemas/CustomFieldValue' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/cards/update.js b/server/api/controllers/cards/update.js index 1b3be1c6..a0965dc6 100755 --- a/server/api/controllers/cards/update.js +++ b/server/api/controllers/cards/update.js @@ -3,6 +3,119 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{id}: + * patch: + * summary: Update card + * description: Updates a card. Board editors can update all fields, viewers can only subscribe/unsubscribe. + * tags: + * - Cards + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the card to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * boardId: + * type: string + * description: ID of the board to move the card to + * example: 1357158568008091265 + * listId: + * type: string + * description: ID of the list to move the card to + * example: 1357158568008091266 + * coverAttachmentId: + * type: string + * nullable: true + * description: ID of the attachment used as cover + * example: 1357158568008091267 + * type: + * type: string + * enum: [project, story] + * description: Type of the card + * example: project + * position: + * type: number + * minimum: 0 + * nullable: true + * description: Position of the card within the list + * example: 65536 + * name: + * type: string + * maxLength: 1024 + * description: Name/title of the card + * example: Implement user authentication + * description: + * type: string + * maxLength: 1048576 + * nullable: true + * description: Detailed description of the card + * example: Add JWT-based authentication system... + * dueDate: + * type: string + * format: date-time + * nullable: true + * description: Due date for the card + * example: 2024-01-01T00:00:00.000Z + * isDueCompleted: + * type: boolean + * nullable: true + * description: Whether the due date is completed + * example: false + * stopwatch: + * type: object + * required: + * - startedAt + * - total + * nullable: true + * description: Stopwatch data for time tracking + * properties: + * startedAt: + * type: string + * format: date-time + * description: When the stopwatch was started + * example: 2024-01-01T00:00:00.000Z + * total: + * type: number + * description: Total time in seconds + * example: 3600 + * isSubscribed: + * type: boolean + * description: Whether the current user is subscribed to the card + * responses: + * 200: + * description: Card updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Card' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { isDueDate, isStopwatch } = require('../../../utils/validators'); const { idInput } = require('../../../utils/inputs'); diff --git a/server/api/controllers/comments/create.js b/server/api/controllers/comments/create.js index cc6c6446..0cbab4b6 100755 --- a/server/api/controllers/comments/create.js +++ b/server/api/controllers/comments/create.js @@ -3,6 +3,58 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/comments: + * post: + * summary: Create comment + * description: Creates a new comment on a card. Requires board editor permissions or comment permissions. + * tags: + * - Comments + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to create the comment on + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - text + * properties: + * text: + * type: string + * maxLength: 1048576 + * description: Content of the comment + * example: This task is almost complete... + * responses: + * 200: + * description: Comment created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Comment' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/comments/delete.js b/server/api/controllers/comments/delete.js index c591abc7..ae8f6a37 100755 --- a/server/api/controllers/comments/delete.js +++ b/server/api/controllers/comments/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/comments/{id}: + * delete: + * summary: Delete comment + * description: Deletes a comment. Can be deleted by the comment author (with comment permissions) or project manager. + * tags: + * - Comments + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the comment to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Comment deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Comment' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/comments/index.js b/server/api/controllers/comments/index.js index 1f68faa5..7801591d 100644 --- a/server/api/controllers/comments/index.js +++ b/server/api/controllers/comments/index.js @@ -3,6 +3,62 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/comments: + * get: + * summary: Get card comments + * description: Retrieves comments for a card with pagination support. Requires access to the card. + * tags: + * - Comments + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to retrieve comments for + * schema: + * type: string + * example: 1357158568008091264 + * - name: beforeId + * in: query + * required: false + * description: ID to get comments before (for pagination) + * schema: + * type: string + * example: 1357158568008091265 + * responses: + * 200: + * description: Comments retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * - included + * properties: + * items: + * type: array + * items: + * $ref: '#/components/schemas/Comment' + * included: + * type: object + * required: + * - users + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/comments/update.js b/server/api/controllers/comments/update.js index 3411653a..8193c97e 100755 --- a/server/api/controllers/comments/update.js +++ b/server/api/controllers/comments/update.js @@ -3,6 +3,56 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/comments/{id}: + * patch: + * summary: Update comment + * description: Updates a comment. Only the author of the comment can update it. + * tags: + * - Comments + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the comment to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * text: + * type: string + * maxLength: 1048576 + * description: Content of the comment + * example: This task is almost complete... + * responses: + * 200: + * description: Comment updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Comment' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/config/show.js b/server/api/controllers/config/show.js index 2fefbec3..79219b5e 100644 --- a/server/api/controllers/config/show.js +++ b/server/api/controllers/config/show.js @@ -3,6 +3,28 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/config: + * get: + * summary: Get application configuration + * description: Retrieves the application configuration. + * tags: + * - Config + * responses: + * 200: + * description: Configuration retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Config' + */ + module.exports = { async fn() { const { currentUser } = this.req; diff --git a/server/api/controllers/custom-field-groups/create-in-board.js b/server/api/controllers/custom-field-groups/create-in-board.js index 9f9fca29..f500d9bf 100644 --- a/server/api/controllers/custom-field-groups/create-in-board.js +++ b/server/api/controllers/custom-field-groups/create-in-board.js @@ -3,6 +3,70 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{boardId}/custom-field-groups: + * post: + * summary: Create custom field group in board + * description: Creates a custom field group within a board. Either `baseCustomFieldGroupId` or `name` must be provided. Requires board editor permissions. + * tags: + * - Custom Field Groups + * parameters: + * - name: boardId + * in: path + * required: true + * description: ID of the board to create the custom field group in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * properties: + * baseCustomFieldGroupId: + * type: string + * description: ID of the base custom field group used as a template + * example: 1357158568008091265 + * position: + * type: number + * minimum: 0 + * description: Position of the custom field group within the board + * example: 65536 + * name: + * type: string + * maxLength: 128 + * nullable: true + * description: Name/title of the custom field group (required if `baseCustomFieldGroupId` is not provided) + * example: Properties + * responses: + * 200: + * description: Custom field group created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomFieldGroup' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-field-groups/create-in-card.js b/server/api/controllers/custom-field-groups/create-in-card.js index 51ebb72f..25fb98c5 100644 --- a/server/api/controllers/custom-field-groups/create-in-card.js +++ b/server/api/controllers/custom-field-groups/create-in-card.js @@ -3,6 +3,70 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/custom-field-groups: + * post: + * summary: Create custom field group in card + * description: Creates a custom field group within a card. Either `baseCustomFieldGroupId` or `name` must be provided. Requires board editor permissions. + * tags: + * - Custom Field Groups + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to create the custom field group in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * properties: + * baseCustomFieldGroupId: + * type: string + * description: ID of the base custom field group used as a template + * example: 1357158568008091265 + * position: + * type: number + * minimum: 0 + * description: Position of the custom field group within the card + * example: 65536 + * name: + * type: string + * maxLength: 128 + * nullable: true + * description: Name/title of the custom field group (required if `baseCustomFieldGroupId` is not provided) + * example: Properties + * responses: + * 200: + * description: Custom field group created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomFieldGroup' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-field-groups/delete.js b/server/api/controllers/custom-field-groups/delete.js index 8ae77312..9bbef3f7 100755 --- a/server/api/controllers/custom-field-groups/delete.js +++ b/server/api/controllers/custom-field-groups/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/custom-field-groups/{id}: + * delete: + * summary: Delete custom field group + * description: Deletes a custom field group. Requires board editor permissions. + * tags: + * - Custom Field Groups + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the custom field group to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Custom field group deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomFieldGroup' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-field-groups/show.js b/server/api/controllers/custom-field-groups/show.js index 1081a50a..a4d6070b 100644 --- a/server/api/controllers/custom-field-groups/show.js +++ b/server/api/controllers/custom-field-groups/show.js @@ -3,6 +3,59 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/custom-field-groups/{id}: + * get: + * summary: Get custom field group details + * description: Retrieves comprehensive custom field group information, including fields and values. Requires access to the board/card. + * tags: + * - Custom Field Groups + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the custom field group to retrieve + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Custom field group details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/CustomFieldGroup' + * included: + * type: object + * required: + * - customFields + * - customFieldValues + * properties: + * customFields: + * type: array + * items: + * $ref: '#/components/schemas/CustomField' + * description: Related custom fields + * customFieldValues: + * type: array + * items: + * $ref: '#/components/schemas/CustomFieldValue' + * description: Related custom field values (for card-specific groups) + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-field-groups/update.js b/server/api/controllers/custom-field-groups/update.js index b4911d68..96382b35 100755 --- a/server/api/controllers/custom-field-groups/update.js +++ b/server/api/controllers/custom-field-groups/update.js @@ -3,6 +3,64 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/custom-field-groups/{id}: + * patch: + * summary: Update custom field group + * description: Updates a custom field group. Supports both board-wide and card-specific groups. Requires board editor permissions. + * tags: + * - Custom Field Groups + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the custom field group to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the custom field group within the board/card + * example: 65536 + * name: + * type: string + * maxLength: 128 + * nullable: true + * description: Name/title of the custom field group + * example: Properties + * responses: + * 200: + * description: Custom field group updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomFieldGroup' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-field-values/create-or-update.js b/server/api/controllers/custom-field-values/create-or-update.js index 401a6461..051c398d 100644 --- a/server/api/controllers/custom-field-values/create-or-update.js +++ b/server/api/controllers/custom-field-values/create-or-update.js @@ -3,6 +3,68 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/custom-field-values: + * post: + * summary: Create or update custom field value + * description: Creates or updates a custom field value for a card. Requires board editor permissions. + * tags: + * - Custom Field Values + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to set the custom field value for + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - customFieldGroupId + * - customFieldId + * - content + * properties: + * customFieldGroupId: + * type: string + * description: ID of the custom field group the value belongs to + * example: 1357158568008091265 + * customFieldId: + * type: string + * description: ID of the custom field the value belongs to + * example: 1357158568008091266 + * content: + * type: string + * maxLength: 512 + * description: Content/value of the custom field + * example: High Priority + * responses: + * 200: + * description: Custom field value created or updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomFieldValue' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-field-values/delete.js b/server/api/controllers/custom-field-values/delete.js index c634cbff..4f8ac186 100644 --- a/server/api/controllers/custom-field-values/delete.js +++ b/server/api/controllers/custom-field-values/delete.js @@ -3,6 +3,58 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/custom-field-groups/{customFieldGroupId}/custom-fields/{customFieldId}/value: + * delete: + * summary: Delete custom field value + * description: Deletes a custom field value for a specific card. Requires board editor permissions. + * tags: + * - Custom Field Values + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to delete the custom field value from + * schema: + * type: string + * example: 1357158568008091264 + * - name: customFieldGroupId + * in: path + * required: true + * description: ID of the custom field group the value belongs to + * schema: + * type: string + * example: 1357158568008091265 + * - name: customFieldId + * in: path + * required: true + * description: ID of the custom field the value belongs to + * schema: + * type: string + * example: 1357158568008091266 + * responses: + * 200: + * description: Custom field value deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomFieldValue' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-fields/create-in-base-custom-field-group.js b/server/api/controllers/custom-fields/create-in-base-custom-field-group.js index c697834a..37dd4912 100644 --- a/server/api/controllers/custom-fields/create-in-base-custom-field-group.js +++ b/server/api/controllers/custom-fields/create-in-base-custom-field-group.js @@ -3,6 +3,66 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/base-custom-field-groups/{baseCustomFieldGroupId}/custom-fields: + * post: + * summary: Create custom field in base custom field group + * description: Creates a custom field within a base custom field group. Requires project manager permissions. + * tags: + * - Custom Fields + * parameters: + * - name: baseCustomFieldGroupId + * in: path + * required: true + * description: ID of the base custom field group to create the custom field in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * - name + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the custom field within the group + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the custom field + * example: Priority + * showOnFrontOfCard: + * type: boolean + * description: Whether to show the field on the front of cards + * example: true + * responses: + * 200: + * description: Custom field created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomField' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-fields/create-in-custom-field-group.js b/server/api/controllers/custom-fields/create-in-custom-field-group.js index 274a0153..38553cad 100644 --- a/server/api/controllers/custom-fields/create-in-custom-field-group.js +++ b/server/api/controllers/custom-fields/create-in-custom-field-group.js @@ -3,6 +3,68 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/custom-field-groups/{customFieldGroupId}/custom-fields: + * post: + * summary: Create custom field in custom field group + * description: Creates a custom field within a custom field group. Requires board editor permissions. + * tags: + * - Custom Fields + * parameters: + * - name: customFieldGroupId + * in: path + * required: true + * description: ID of the custom field group to create the custom field in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * - name + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the custom field within the group + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the custom field + * example: Priority + * showOnFrontOfCard: + * type: boolean + * description: Whether to show the field on the front of cards + * example: true + * responses: + * 200: + * description: Custom field created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomField' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-fields/delete.js b/server/api/controllers/custom-fields/delete.js index a1475ef8..c01fce2e 100755 --- a/server/api/controllers/custom-fields/delete.js +++ b/server/api/controllers/custom-fields/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/custom-fields/{id}: + * delete: + * summary: Delete custom field + * description: Deletes a custom field. Can delete the in base custom field group (requires project manager permissions) or the custom field group (requires board editor permissions). + * tags: + * - Custom Fields + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the custom field to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Custom field deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomField' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/custom-fields/update.js b/server/api/controllers/custom-fields/update.js index 1c8144b5..c3bad196 100755 --- a/server/api/controllers/custom-fields/update.js +++ b/server/api/controllers/custom-fields/update.js @@ -3,6 +3,65 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/custom-fields/{id}: + * patch: + * summary: Update custom field + * description: Updates a custom field. Can update in the base custom field group (requires project manager permissions) or the custom field group (requires board editor permissions). + * tags: + * - Custom Fields + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the custom field to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the custom field within the group + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the custom field + * example: Priority + * showOnFrontOfCard: + * type: boolean + * description: Whether to show the field on the front of cards + * example: false + * responses: + * 200: + * description: Custom field updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/CustomField' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/file-attachments/download-thumbnail.js b/server/api/controllers/file-attachments/download-thumbnail.js index 077bb873..433aeac7 100644 --- a/server/api/controllers/file-attachments/download-thumbnail.js +++ b/server/api/controllers/file-attachments/download-thumbnail.js @@ -3,6 +3,62 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/attachments/{id}/download/thumbnails/{fileName}.{fileExtension}: + * get: + * summary: Download file attachment thumbnail + * description: Downloads a thumbnail for a file attachment. Only available for image attachments that have thumbnails generated. Requires access to the card. + * tags: + * - File Attachments + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the file attachment to download the thumbnail for + * schema: + * type: string + * example: 1357158568008091264 + * - name: fileName + * in: path + * required: true + * description: Thumbnail size identifier + * schema: + * type: string + * enum: [outside-360, outside-720] + * example: outside-360 + * - name: fileExtension + * in: path + * required: true + * description: File extension of the thumbnail + * schema: + * type: string + * example: jpg + * responses: + * 200: + * description: Thumbnail image returned successfully + * content: + * image/*: + * schema: + * type: string + * format: binary + * headers: + * Content-Type: + * schema: + * type: string + * description: MIME type of the thumbnail image + * Cache-Control: + * schema: + * type: string + * description: Cache control header + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/file-attachments/download.js b/server/api/controllers/file-attachments/download.js index 8419bceb..b94a4c42 100644 --- a/server/api/controllers/file-attachments/download.js +++ b/server/api/controllers/file-attachments/download.js @@ -3,6 +3,51 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/attachments/{id}/download: + * get: + * summary: Download file attachment + * description: Downloads a file attachment. Requires access to the card. + * tags: + * - File Attachments + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the file attachment to download + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: File attachment content returned successfully + * content: + * application/octet-stream: + * schema: + * type: string + * format: binary + * image/*: + * schema: + * type: string + * format: binary + * headers: + * Content-Disposition: + * schema: + * type: string + * description: Attachment disposition with filename + * Content-Type: + * schema: + * type: string + * description: MIME type of the file + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/labels/create.js b/server/api/controllers/labels/create.js index 75e2047b..6a29cb04 100755 --- a/server/api/controllers/labels/create.js +++ b/server/api/controllers/labels/create.js @@ -3,6 +3,70 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{boardId}/labels: + * post: + * summary: Create label + * description: Creates a label within a board. Requires board editor permissions. + * tags: + * - Labels + * parameters: + * - name: boardId + * in: path + * required: true + * description: ID of the board to create the label in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * - color + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the label within the board + * example: 65536 + * name: + * type: string + * maxLength: 128 + * nullable: true + * description: Name/title of the label + * example: Bug + * color: + * type: string + * enum: [muddy-grey, autumn-leafs, morning-sky, antique-blue, egg-yellow, desert-sand, dark-granite, fresh-salad, lagoon-blue, midnight-blue, light-orange, pumpkin-orange, light-concrete, sunny-grass, navy-blue, lilac-eyes, apricot-red, orange-peel, silver-glint, bright-moss, deep-ocean, summer-sky, berry-red, light-cocoa, grey-stone, tank-green, coral-green, sugar-plum, pink-tulip, shady-rust, wet-rock, wet-moss, turquoise-sea, lavender-fields, piggy-red, light-mud, gun-metal, modern-green, french-coast, sweet-lilac, red-burgundy, pirate-gold] + * description: Color of the label + * example: berry-red + * responses: + * 200: + * description: Label created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Label' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/labels/delete.js b/server/api/controllers/labels/delete.js index b710c09a..75c976f7 100755 --- a/server/api/controllers/labels/delete.js +++ b/server/api/controllers/labels/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/labels/{id}: + * delete: + * summary: Delete label + * description: Deletes a label. Requires board editor permissions. + * tags: + * - Labels + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the label to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Label deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Label' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/labels/update.js b/server/api/controllers/labels/update.js index 312e4d80..df499526 100755 --- a/server/api/controllers/labels/update.js +++ b/server/api/controllers/labels/update.js @@ -3,6 +3,67 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/labels/{id}: + * patch: + * summary: Update label + * description: Updates a label. Requires board editor permissions. + * tags: + * - Labels + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the label to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the label within the board + * example: 65536 + * name: + * type: string + * maxLength: 128 + * nullable: true + * description: Name/title of the label + * example: Bug + * color: + * type: string + * enum: [muddy-grey, autumn-leafs, morning-sky, antique-blue, egg-yellow, desert-sand, dark-granite, fresh-salad, lagoon-blue, midnight-blue, light-orange, pumpkin-orange, light-concrete, sunny-grass, navy-blue, lilac-eyes, apricot-red, orange-peel, silver-glint, bright-moss, deep-ocean, summer-sky, berry-red, light-cocoa, grey-stone, tank-green, coral-green, sugar-plum, pink-tulip, shady-rust, wet-rock, wet-moss, turquoise-sea, lavender-fields, piggy-red, light-mud, gun-metal, modern-green, french-coast, sweet-lilac, red-burgundy, pirate-gold] + * description: Color of the label + * example: berry-red + * responses: + * 200: + * description: Label updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Label' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/lists/clear.js b/server/api/controllers/lists/clear.js index b217e9bd..fdbd0a48 100644 --- a/server/api/controllers/lists/clear.js +++ b/server/api/controllers/lists/clear.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{id}/clear: + * post: + * summary: Clear list + * description: Deletes all cards from a list. Only works with trash-type lists. Requires project manager or board editor permissions. + * tags: + * - Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the list to clear (must be a trash-type list) + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: List cleared successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/List' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/lists/create.js b/server/api/controllers/lists/create.js index c136ee9c..824680a1 100755 --- a/server/api/controllers/lists/create.js +++ b/server/api/controllers/lists/create.js @@ -3,6 +3,70 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{boardId}/lists: + * post: + * summary: Create list + * description: Creates a list within a board. Requires board editor permissions. + * tags: + * - Lists + * parameters: + * - name: boardId + * in: path + * required: true + * description: ID of the board to create the list in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - type + * - position + * - name + * properties: + * type: + * type: string + * enum: [active, closed] + * description: Type/status of the list + * example: active + * position: + * type: number + * minimum: 0 + * description: Position of the list within the board + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the list + * example: To Do + * responses: + * 200: + * description: List created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/List' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/lists/delete.js b/server/api/controllers/lists/delete.js index 238e46a4..c63f0f1b 100755 --- a/server/api/controllers/lists/delete.js +++ b/server/api/controllers/lists/delete.js @@ -3,6 +3,55 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{id}: + * delete: + * summary: Delete list + * description: Deletes a list and moves its cards to a trash list. Can only delete finite lists. Requires board editor permissions. + * tags: + * - Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the list to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: List deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/List' + * included: + * type: object + * required: + * - cards + * properties: + * cards: + * type: array + * description: Related cards + * items: + * $ref: '#/components/schemas/Card' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/lists/move-cards.js b/server/api/controllers/lists/move-cards.js index 45b6ac52..c37a4de4 100644 --- a/server/api/controllers/lists/move-cards.js +++ b/server/api/controllers/lists/move-cards.js @@ -3,6 +3,74 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{id}/move-cards: + * post: + * summary: Move cards + * description: Moves all cards from a closed list to an archive list. Requires board editor permissions. + * tags: + * - Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the source list (must be a closed-type list) + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - listId + * properties: + * listId: + * type: string + * description: ID of the target list (must be an archive-type list) + * example: 1357158568008091265 + * responses: + * 200: + * description: Cards moved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/List' + * included: + * type: object + * required: + * - cards + * - actions + * properties: + * cards: + * type: array + * description: Related cards + * items: + * $ref: '#/components/schemas/Card' + * actions: + * type: array + * description: Related actions + * items: + * $ref: '#/components/schemas/Action' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/lists/show.js b/server/api/controllers/lists/show.js index a53d8a39..a995dd10 100644 --- a/server/api/controllers/lists/show.js +++ b/server/api/controllers/lists/show.js @@ -3,6 +3,114 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{id}: + * get: + * summary: Get list details + * description: Retrieves comprehensive list information, including cards, attachments, and other related data. Requires access to the board. + * tags: + * - Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the list to retrieve + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: List details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/List' + * included: + * type: object + * required: + * - users + * - cards + * - cardMemberships + * - cardLabels + * - taskLists + * - tasks + * - attachments + * - customFieldGroups + * - customFields + * - customFieldValues + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * cards: + * type: array + * description: Related cards + * items: + * allOf: + * - $ref: '#/components/schemas/Card' + * - type: object + * properties: + * isSubscribed: + * type: boolean + * description: Whether the current user is subscribed to the card + * example: true + * cardMemberships: + * type: array + * description: Related card-membership associations + * items: + * $ref: '#/components/schemas/CardMembership' + * cardLabels: + * type: array + * description: Related card-label associations + * items: + * $ref: '#/components/schemas/CardLabel' + * taskLists: + * type: array + * description: Related task lists + * items: + * $ref: '#/components/schemas/TaskList' + * tasks: + * type: array + * description: Related tasks + * items: + * $ref: '#/components/schemas/Task' + * attachments: + * type: array + * description: Related attachments + * items: + * $ref: '#/components/schemas/Attachment' + * customFieldGroups: + * type: array + * description: Related custom field groups + * items: + * $ref: '#/components/schemas/CustomFieldGroup' + * customFields: + * type: array + * description: Related custom fields + * items: + * $ref: '#/components/schemas/CustomField' + * customFieldValues: + * type: array + * description: Related custom field values + * items: + * $ref: '#/components/schemas/CustomFieldValue' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/lists/sort.js b/server/api/controllers/lists/sort.js index 35c5d8d0..f72aeddb 100644 --- a/server/api/controllers/lists/sort.js +++ b/server/api/controllers/lists/sort.js @@ -3,6 +3,73 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{id}/sort: + * post: + * summary: Sort cards in list + * description: Sorts all cards within a list. Requires board editor permissions. + * tags: + * - Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the list to sort + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - fieldName + * properties: + * fieldName: + * type: string + * enum: [name, dueDate, createdAt] + * description: Field to sort cards by + * example: name + * order: + * type: string + * enum: [asc, desc] + * description: Sorting order + * example: asc + * responses: + * 200: + * description: List sorted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/List' + * included: + * type: object + * properties: + * cards: + * type: array + * description: Related cards + * items: + * $ref: '#/components/schemas/Card' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/lists/update.js b/server/api/controllers/lists/update.js index c9537f36..a93212ba 100755 --- a/server/api/controllers/lists/update.js +++ b/server/api/controllers/lists/update.js @@ -3,6 +3,76 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/lists/{id}: + * patch: + * summary: Update list + * description: Updates a list. Can move lists between boards. Requires board editor permissions. + * tags: + * - Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the list to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * boardId: + * type: string + * description: ID of the board to move list to + * example: 1357158568008091265 + * type: + * type: string + * enum: [active, closed] + * description: Type/status of the list + * example: active + * position: + * type: number + * minimum: 0 + * description: Position of the list within the board + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the list + * example: To Do + * color: + * type: string + * enum: [berry-red, pumpkin-orange, lagoon-blue, pink-tulip, light-mud, orange-peel, bright-moss, antique-blue, dark-granite, turquoise-sea] + * nullable: true + * description: Color for the list + * example: lagoon-blue + * responses: + * 200: + * description: List updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/List' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/notification-services/create-in-board.js b/server/api/controllers/notification-services/create-in-board.js index 7f8f2c07..55d862dc 100644 --- a/server/api/controllers/notification-services/create-in-board.js +++ b/server/api/controllers/notification-services/create-in-board.js @@ -3,6 +3,64 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/boards/{boardId}/notification-services: + * post: + * summary: Create notification service for board + * description: Creates a new notification service for a board. Requires project manager permissions. + * tags: + * - Notification Services + * parameters: + * - name: boardId + * in: path + * required: true + * description: ID of the board to create notification service for + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - url + * - format + * properties: + * url: + * type: string + * maxLength: 512 + * description: URL endpoint for notifications + * example: https://example.service.com/planka + * format: + * type: string + * enum: [text, markdown, html] + * description: Format for notification messages + * example: text + * responses: + * 200: + * description: Notification service created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/notification-services/create-in-user.js b/server/api/controllers/notification-services/create-in-user.js index 8f622a9a..3e15ab73 100644 --- a/server/api/controllers/notification-services/create-in-user.js +++ b/server/api/controllers/notification-services/create-in-user.js @@ -3,6 +3,64 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{userId}/notification-services: + * post: + * summary: Create notification service for user + * description: Creates a new notification service for a user. Users can only create services for themselves. + * tags: + * - Notification Services + * parameters: + * - name: userId + * in: path + * required: true + * description: ID of the user to create notification service for (must be the current user) + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - url + * - format + * properties: + * url: + * type: string + * maxLength: 512 + * description: URL endpoint for notifications + * example: https://example.service.com/planka + * format: + * type: string + * enum: [text, markdown, html] + * description: Format for notification messages + * example: text + * responses: + * 200: + * description: Notification service created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/notification-services/delete.js b/server/api/controllers/notification-services/delete.js index 65398615..ebccfbdc 100644 --- a/server/api/controllers/notification-services/delete.js +++ b/server/api/controllers/notification-services/delete.js @@ -3,6 +3,42 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/notification-services/{id}: + * delete: + * summary: Delete notification service + * description: Deletes a notification service. Users can delete their own services, project managers can delete board services. + * tags: + * - Notification Services + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the notification service to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Notification service deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/notification-services/test.js b/server/api/controllers/notification-services/test.js index 37cfb868..c5a7cec0 100644 --- a/server/api/controllers/notification-services/test.js +++ b/server/api/controllers/notification-services/test.js @@ -3,6 +3,42 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/notification-services/{id}/test: + * post: + * summary: Test notification service + * description: Sends a test notification to verify the notification service is working. Users can test their own services, project managers can test board services. + * tags: + * - Notification Services + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the notification service to test + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Test notification sent successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/notification-services/update.js b/server/api/controllers/notification-services/update.js index 05a6cb67..455bee07 100644 --- a/server/api/controllers/notification-services/update.js +++ b/server/api/controllers/notification-services/update.js @@ -3,6 +3,59 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/notification-services/{id}: + * patch: + * summary: Update notification service + * description: Updates a notification service. Users can update their own services, project managers can update board services. + * tags: + * - Notification Services + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the notification service to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * url: + * type: string + * maxLength: 512 + * description: URL endpoint for notifications + * example: https://example.service.com/planka + * format: + * type: string + * enum: [text, markdown, html] + * description: Format for notification messages + * example: text + * responses: + * 200: + * description: Notification service updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/notifications/index.js b/server/api/controllers/notifications/index.js index b1d27b87..5fd75e1f 100755 --- a/server/api/controllers/notifications/index.js +++ b/server/api/controllers/notifications/index.js @@ -3,6 +3,45 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/notifications: + * get: + * summary: Get user notifications + * description: Retrieves all unread notifications for the current user, including creator users. + * tags: + * - Notifications + * responses: + * 200: + * description: Notifications retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * - included + * properties: + * items: + * type: array + * items: + * $ref: '#/components/schemas/Notification' + * included: + * type: object + * required: + * - users + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + */ + module.exports = { async fn() { const { currentUser } = this.req; diff --git a/server/api/controllers/notifications/read-all.js b/server/api/controllers/notifications/read-all.js index 74db7aac..5a04665b 100755 --- a/server/api/controllers/notifications/read-all.js +++ b/server/api/controllers/notifications/read-all.js @@ -3,6 +3,34 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/notifications/read-all: + * post: + * summary: Mark all notifications as read + * description: Marks all notifications for the current user as read. + * tags: + * - Notifications + * responses: + * 200: + * description: Notifications marked as read successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * properties: + * items: + * type: array + * items: + * $ref: '#/components/schemas/Notification' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + */ + module.exports = { async fn() { const { currentUser } = this.req; diff --git a/server/api/controllers/notifications/show.js b/server/api/controllers/notifications/show.js index b3ed3ead..727b4895 100644 --- a/server/api/controllers/notifications/show.js +++ b/server/api/controllers/notifications/show.js @@ -3,6 +3,53 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/notifications/{id}: + * get: + * summary: Get notification details + * description: Retrieves notification, including creator users. Users can only access their own notifications. + * tags: + * - Notifications + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the notification to retrieve + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Notification details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/Notification' + * included: + * type: object + * required: + * - users + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/notifications/update.js b/server/api/controllers/notifications/update.js index f39885e3..6ff7ddf9 100644 --- a/server/api/controllers/notifications/update.js +++ b/server/api/controllers/notifications/update.js @@ -3,6 +3,53 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/notifications/{id}: + * patch: + * summary: Update notification + * description: Updates a notification. Users can only update their own notifications. + * tags: + * - Notifications + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the notification to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * isRead: + * type: boolean + * description: Whether the notification has been read + * example: true + * responses: + * 200: + * description: Notification updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Notification' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/project-managers/create.js b/server/api/controllers/project-managers/create.js index ebdc991d..733ce356 100755 --- a/server/api/controllers/project-managers/create.js +++ b/server/api/controllers/project-managers/create.js @@ -3,6 +3,61 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects/{projectId}/managers: + * post: + * summary: Add project manager + * description: Adds a user as a project manager. Requires admin privileges for shared projects or existing project manager permissions. The user must be an admin or project owner. + * tags: + * - Project Managers + * parameters: + * - name: projectId + * in: path + * required: true + * description: ID of the project to add the manager to + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - userId + * properties: + * userId: + * type: string + * description: ID of the user who is assigned as project manager + * example: 1357158568008091265 + * responses: + * 200: + * description: Project manager added successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/ProjectManager' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/project-managers/delete.js b/server/api/controllers/project-managers/delete.js index 3c406513..3887cef5 100755 --- a/server/api/controllers/project-managers/delete.js +++ b/server/api/controllers/project-managers/delete.js @@ -3,6 +3,46 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/project-managers/{id}: + * delete: + * summary: Remove project manager + * description: Removes a user from project managers. Requires admin privileges for shared projects or existing project manager permissions. Cannot remove the last project manager. + * tags: + * - Project Managers + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the project manager to remove + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Project manager removed successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/ProjectManager' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/projects/create.js b/server/api/controllers/projects/create.js index 4b35865c..dcea7264 100755 --- a/server/api/controllers/projects/create.js +++ b/server/api/controllers/projects/create.js @@ -3,6 +3,69 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects: + * post: + * summary: Create project + * description: Creates a project. The current user automatically becomes a project manager. + * tags: + * - Projects + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - type + * - name + * properties: + * type: + * type: string + * enum: [public, private] + * description: Type of the project + * example: private + * name: + * type: string + * maxLength: 128 + * description: Name/title of the project + * example: Development Project + * description: + * type: string + * maxLength: 1024 + * nullable: true + * description: Detailed description of the project + * example: A project for developing new features... + * responses: + * 200: + * description: Project created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/Project' + * included: + * type: object + * required: + * - projectManagers + * properties: + * projectManagers: + * type: array + * description: Related project managers + * items: + * $ref: '#/components/schemas/ProjectManager' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + */ + module.exports = { inputs: { type: { diff --git a/server/api/controllers/projects/delete.js b/server/api/controllers/projects/delete.js index a4c86a30..116a2cef 100755 --- a/server/api/controllers/projects/delete.js +++ b/server/api/controllers/projects/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects/{id}: + * delete: + * summary: Delete project + * description: Deletes a project. The project must not have any boards. Requires project manager permissions. + * tags: + * - Projects + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the project to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Project deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Project' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/projects/index.js b/server/api/controllers/projects/index.js index 6b330fcb..52fa2176 100755 --- a/server/api/controllers/projects/index.js +++ b/server/api/controllers/projects/index.js @@ -3,6 +3,94 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects: + * get: + * summary: Get all accessible projects + * description: Retrieves all projects the current user has access to, including managed projects, membership projects, and shared projects (for admins). + * tags: + * - Projects + * responses: + * 200: + * description: Projects retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * - included + * properties: + * items: + * type: array + * items: + * allOf: + * - $ref: '#/components/schemas/Project' + * - type: object + * properties: + * isFavorite: + * type: boolean + * description: Whether the project is marked as favorite by the current user + * example: true + * included: + * type: object + * required: + * - users + * - projectManagers + * - backgroundImages + * - baseCustomFieldGroups + * - boards + * - boardMemberships + * - customFields + * - notificationServices + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * projectManagers: + * type: array + * description: Related project managers + * items: + * $ref: '#/components/schemas/ProjectManager' + * backgroundImages: + * type: array + * description: Related background images + * items: + * $ref: '#/components/schemas/BackgroundImage' + * baseCustomFieldGroups: + * type: array + * description: Related base custom field groups + * items: + * $ref: '#/components/schemas/BaseCustomFieldGroup' + * boards: + * type: array + * description: Related boards + * items: + * $ref: '#/components/schemas/Board' + * boardMemberships: + * type: array + * description: Related board memberships (for current user) + * items: + * $ref: '#/components/schemas/BoardMembership' + * customFields: + * type: array + * description: Related custom fields + * items: + * $ref: '#/components/schemas/CustomField' + * notificationServices: + * type: array + * description: Related notification services (for managed projects) + * items: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + */ + module.exports = { async fn() { const { currentUser } = this.req; diff --git a/server/api/controllers/projects/show.js b/server/api/controllers/projects/show.js index b64c5762..fb4524e4 100644 --- a/server/api/controllers/projects/show.js +++ b/server/api/controllers/projects/show.js @@ -3,6 +3,102 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects/{id}: + * get: + * summary: Get project details + * description: Retrieves comprehensive project information, including boards, board memberships, and other related data. + * tags: + * - Projects + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the project to retrieve + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Project details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * allOf: + * - $ref: '#/components/schemas/Project' + * - type: object + * properties: + * isFavorite: + * type: boolean + * description: Whether the project is marked as favorite by the current user + * example: true + * included: + * type: object + * required: + * - users + * - projectManagers + * - backgroundImages + * - baseCustomFieldGroups + * - boards + * - boardMemberships + * - customFields + * - notificationServices + * properties: + * users: + * type: array + * description: Related users + * items: + * $ref: '#/components/schemas/User' + * projectManagers: + * type: array + * description: Related project managers + * items: + * $ref: '#/components/schemas/ProjectManager' + * backgroundImages: + * type: array + * description: Related background images + * items: + * $ref: '#/components/schemas/BackgroundImage' + * baseCustomFieldGroups: + * type: array + * description: Related base custom field groups + * items: + * $ref: '#/components/schemas/BaseCustomFieldGroup' + * boards: + * type: array + * description: Related boards + * items: + * $ref: '#/components/schemas/Board' + * boardMemberships: + * type: array + * description: Related board memberships (for current user) + * items: + * $ref: '#/components/schemas/BoardMembership' + * customFields: + * type: array + * description: Related custom fields + * items: + * $ref: '#/components/schemas/CustomField' + * notificationServices: + * type: array + * description: Related notification services (for managed projects) + * items: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/projects/update.js b/server/api/controllers/projects/update.js index 1b3a416e..add24e4d 100755 --- a/server/api/controllers/projects/update.js +++ b/server/api/controllers/projects/update.js @@ -3,6 +3,96 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/projects/{id}: + * patch: + * summary: Update project + * description: Updates a project. Accessible fields depend on user permissions. + * tags: + * - Projects + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the project to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * ownerProjectManagerId: + * type: string + * nullable: true + * description: ID of the project manager who owns the project + * example: 1357158568008091265 + * backgroundImageId: + * type: string + * nullable: true + * description: ID of the background image used as background + * example: 1357158568008091266 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the project + * example: Development Project + * description: + * type: string + * maxLength: 1024 + * nullable: true + * description: Detailed description of the project + * example: A project for developing new features... + * backgroundType: + * type: string + * enum: [gradient, image] + * nullable: true + * description: Type of background for the project + * example: gradient + * backgroundGradient: + * type: string + * enum: [old-lime, ocean-dive, tzepesch-style, jungle-mesh, strawberry-dust, purple-rose, sun-scream, warm-rust, sky-change, green-eyes, blue-xchange, blood-orange, sour-peel, green-ninja, algae-green, coral-reef, steel-grey, heat-waves, velvet-lounge, purple-rain, blue-steel, blueish-curve, prism-light, green-mist, red-curtain] + * nullable: true + * description: Gradient background for the project + * example: ocean-dive + * isHidden: + * type: boolean + * description: Whether the project is hidden + * example: false + * isFavorite: + * type: boolean + * description: Whether the project is marked as favorite by the current user + * example: true + * responses: + * 200: + * description: Project updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Project' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/task-lists/create.js b/server/api/controllers/task-lists/create.js index 288f8481..f875e0c9 100755 --- a/server/api/controllers/task-lists/create.js +++ b/server/api/controllers/task-lists/create.js @@ -3,6 +3,72 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/cards/{cardId}/task-lists: + * post: + * summary: Create task list + * description: Creates a task list within a card. Requires board editor permissions. + * tags: + * - Task Lists + * parameters: + * - name: cardId + * in: path + * required: true + * description: ID of the card to create task list in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * - name + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the task list within the card + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the task list + * example: Development Tasks + * showOnFrontOfCard: + * type: boolean + * description: Whether to show the task list on the front of the card + * example: true + * hideCompletedTasks: + * type: boolean + * description: Whether to hide completed tasks + * example: false + * responses: + * 200: + * description: Task list created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/TaskList' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/task-lists/delete.js b/server/api/controllers/task-lists/delete.js index 94226917..15c709b4 100755 --- a/server/api/controllers/task-lists/delete.js +++ b/server/api/controllers/task-lists/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/task-lists/{id}: + * delete: + * summary: Delete task list + * description: Deletes a task list and all its tasks. Requires board editor permissions. + * tags: + * - Task Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the task list to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Task list deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/TaskList' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/task-lists/show.js b/server/api/controllers/task-lists/show.js index ea27a2b1..7db47d1d 100644 --- a/server/api/controllers/task-lists/show.js +++ b/server/api/controllers/task-lists/show.js @@ -3,6 +3,53 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/task-lists/{id}: + * get: + * summary: Get task list details + * description: Retrieves task list information, including tasks. Requires access to the card. + * tags: + * - Task Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the task list to retrieve + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Task list details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/TaskList' + * included: + * type: object + * required: + * - tasks + * properties: + * tasks: + * type: array + * description: Related tasks + * items: + * $ref: '#/components/schemas/Task' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/task-lists/update.js b/server/api/controllers/task-lists/update.js index 46ec794e..b92b2691 100755 --- a/server/api/controllers/task-lists/update.js +++ b/server/api/controllers/task-lists/update.js @@ -3,6 +3,69 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/task-lists/{id}: + * patch: + * summary: Update task list + * description: Updates a task list. Requires board editor permissions. + * tags: + * - Task Lists + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the task list to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * position: + * type: number + * minimum: 0 + * description: Position of the task list within the card + * example: 65536 + * name: + * type: string + * maxLength: 128 + * description: Name/title of the task list + * example: Development Tasks + * showOnFrontOfCard: + * type: boolean + * description: Whether to show the task list on the front of the card + * example: true + * hideCompletedTasks: + * type: boolean + * description: Whether to hide completed tasks + * example: false + * responses: + * 200: + * description: Task list updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/TaskList' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/tasks/create.js b/server/api/controllers/tasks/create.js index f1b1bb78..c73e6ccf 100755 --- a/server/api/controllers/tasks/create.js +++ b/server/api/controllers/tasks/create.js @@ -3,6 +3,74 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/task-lists/{taskListId}/tasks: + * post: + * summary: Create task + * description: Creates a task within a task list. Either `linkedCardId` or `name` must be provided. Requires board editor permissions. + * tags: + * - Tasks + * parameters: + * - name: taskListId + * in: path + * required: true + * description: ID of the task list to create task in + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - position + * properties: + * linkedCardId: + * type: string + * description: ID of the card linked to the task + * example: 1357158568008091265 + * position: + * type: number + * minimum: 0 + * description: Position of the task within the task list + * example: 65536 + * name: + * type: string + * maxLength: 1024 + * nullable: true + * description: Name/title of the task (required if `linkedCardId` is not provided) + * example: Write unit tests + * isCompleted: + * type: boolean + * description: Whether the task is completed + * example: false + * responses: + * 200: + * description: Task created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Task' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/tasks/delete.js b/server/api/controllers/tasks/delete.js index c708e2e3..fbb23bb9 100755 --- a/server/api/controllers/tasks/delete.js +++ b/server/api/controllers/tasks/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/tasks/{id}: + * delete: + * summary: Delete task + * description: Deletes a task. Requires board editor permissions. + * tags: + * - Tasks + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the task to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Task deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Task' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/tasks/update.js b/server/api/controllers/tasks/update.js index 6272c0ed..10b128d5 100755 --- a/server/api/controllers/tasks/update.js +++ b/server/api/controllers/tasks/update.js @@ -3,6 +3,74 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/tasks/{id}: + * patch: + * summary: Update task + * description: Updates a task. Linked card tasks have limited update options. Requires board editor permissions. + * tags: + * - Tasks + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the task to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * taskListId: + * type: string + * description: ID of the task list to move the task to + * example: 1357158568008091265 + * assigneeUserId: + * type: string + * nullable: true + * description: ID of the user assigned to the task (null to unassign) + * example: 1357158568008091266 + * position: + * type: number + * minimum: 0 + * description: Position of the task within the task list + * example: 65536 + * name: + * type: string + * maxLength: 1024 + * description: Name/title of the task + * example: Write unit tests + * isCompleted: + * type: boolean + * description: Whether the task is completed + * example: true + * responses: + * 200: + * description: Task updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Task' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/terms/show.js b/server/api/controllers/terms/show.js index f75cb461..680b95aa 100644 --- a/server/api/controllers/terms/show.js +++ b/server/api/controllers/terms/show.js @@ -3,6 +3,75 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/terms: + * get: + * summary: Get terms and conditions + * description: Retrieves terms and conditions in the specified language. + * tags: + * - Terms + * parameters: + * - name: type + * in: query + * required: true + * description: Type of terms to retrieve + * schema: + * type: string + * enum: [general, extended] + * example: general + * - name: language + * in: query + * required: false + * description: Language code for terms localization + * schema: + * type: string + * enum: [de-DE, en-US] + * example: en-US + * responses: + * 200: + * description: Terms content retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * type: object + * required: + * - type + * - language + * - content + * - signature + * properties: + * type: + * type: string + * enum: [general, extended] + * description: Type of terms + * example: en-US + * language: + * type: string + * enum: [de-DE, en-US] + * description: Language code used + * example: en-US + * content: + * type: string + * description: Markdown content of the terms + * example: Your privacy is important to us... + * signature: + * type: string + * description: Signature hash of terms + * example: 940226c4c41f51afe3980ceb63704e752636526f4c52a4ea579e85b247493d94 + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + module.exports = { inputs: { type: { diff --git a/server/api/controllers/users/create.js b/server/api/controllers/users/create.js index 1444b01c..b76f7178 100755 --- a/server/api/controllers/users/create.js +++ b/server/api/controllers/users/create.js @@ -3,6 +3,107 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users: + * post: + * summary: Create user + * description: Creates a user account. Requires admin privileges. + * tags: + * - Users + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - email + * - password + * - role + * - name + * properties: + * email: + * type: string + * format: email + * maxLength: 256 + * description: Email address for login and notifications + * example: john.doe@example.com + * password: + * type: string + * maxLength: 256 + * description: Password for user authentication (must meet password requirements) + * example: SecurePassword123! + * role: + * type: string + * enum: [admin, projectOwner, boardUser] + * description: User role defining access permissions + * example: admin + * name: + * type: string + * maxLength: 128 + * description: Full display name of the user + * example: John Doe + * username: + * type: string + * minLength: 3 + * maxLength: 16 + * pattern: "^[a-zA-Z0-9]+((_{1}|\\.|){1}[a-zA-Z0-9])*$" + * nullable: true + * description: Unique username for user identification + * example: john_doe + * phone: + * type: string + * maxLength: 128 + * nullable: true + * description: Contact phone number + * example: +1234567890 + * organization: + * type: string + * maxLength: 128 + * nullable: true + * description: Organization or company name + * example: Acme Corporation + * language: + * type: string + * enum: [ar-YE, bg-BG, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, zh-CN, zh-TW] + * nullable: true + * description: Preferred language for user interface and notifications + * example: en-US + * subscribeToOwnCards: + * type: boolean + * description: Whether the user subscribes to their own cards + * example: false + * subscribeToCardWhenCommenting: + * type: boolean + * description: Whether the user subscribes to cards when commenting + * example: true + * turnOffRecentCardHighlighting: + * type: boolean + * description: Whether recent card highlighting is disabled + * example: false + * responses: + * 200: + * description: User created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { isPassword } = require('../../../utils/validators'); const Errors = { diff --git a/server/api/controllers/users/delete.js b/server/api/controllers/users/delete.js index ad5effdb..e82a5fff 100755 --- a/server/api/controllers/users/delete.js +++ b/server/api/controllers/users/delete.js @@ -3,6 +3,44 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{id}: + * delete: + * summary: Delete user + * description: Deletes a user account. Cannot delete the default admin user. Requires admin privileges. + * tags: + * - Users + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the user to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: User deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/users/index.js b/server/api/controllers/users/index.js index 24f91054..eca9ad9a 100755 --- a/server/api/controllers/users/index.js +++ b/server/api/controllers/users/index.js @@ -3,6 +3,36 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users: + * get: + * summary: Get all users + * description: Retrieves a list of all users. Requires admin or project owner privileges. + * tags: + * - Users + * responses: + * 200: + * description: List of users retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * properties: + * items: + * type: array + * items: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + */ + const Errors = { NOT_ENOUGH_RIGHTS: { notEnoughRights: 'Not enough rights', diff --git a/server/api/controllers/users/show.js b/server/api/controllers/users/show.js index b59c54c3..8900519d 100755 --- a/server/api/controllers/users/show.js +++ b/server/api/controllers/users/show.js @@ -3,6 +3,60 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{id}: + * get: + * summary: Get user details + * description: Retrieves a user. Use 'me' as ID to get the current user. + * tags: + * - Users + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the user or 'me' for current user + * schema: + * type: string + * example: 1357158568008091264 + * - name: subscribe + * in: query + * required: false + * description: Whether to subscribe to real-time updates for this user (only for socket connections) + * schema: + * type: boolean + * example: true + * responses: + * 200: + * description: User details retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * - included + * properties: + * item: + * $ref: '#/components/schemas/User' + * included: + * type: object + * required: + * - notificationServices + * properties: + * notificationServices: + * type: array + * description: Related notification services (for current user) + * items: + * $ref: '#/components/schemas/NotificationService' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { ID_REGEX, MAX_STRING_ID, isIdInRange } = require('../../../utils/validators'); const Errors = { diff --git a/server/api/controllers/users/update-avatar.js b/server/api/controllers/users/update-avatar.js index c6d465d0..80e835ff 100755 --- a/server/api/controllers/users/update-avatar.js +++ b/server/api/controllers/users/update-avatar.js @@ -3,6 +3,57 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{id}/avatar: + * patch: + * summary: Update user avatar + * description: Updates a user's avatar image. Users can update their own avatar, admins can update any user's avatar. + * tags: + * - Users + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the user whose avatar to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * multipart/form-data: + * schema: + * type: object + * required: + * - file + * properties: + * file: + * type: string + * format: binary + * description: Avatar image file (must be an image format) + * responses: + * 200: + * description: Avatar updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + * 422: + * $ref: '#/components/responses/UnprocessableEntity' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/users/update-email.js b/server/api/controllers/users/update-email.js index f28b6634..8f601c79 100644 --- a/server/api/controllers/users/update-email.js +++ b/server/api/controllers/users/update-email.js @@ -3,6 +3,66 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{id}/email: + * patch: + * summary: Update user email + * description: Updates a user's email address. Users must provide current password when updating their own email. Admins can update any user's email without a password. + * tags: + * - Users + * parameters: + * - in: path + * name: id + * required: true + * description: ID of the user whose email to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - email + * properties: + * email: + * type: string + * format: email + * maxLength: 256 + * description: Email address for login and notifications + * example: john.doe@example.com + * currentPassword: + * type: string + * maxLength: 256 + * description: Current password (required when updating own email) + * example: SecurePassword123! + * responses: + * 200: + * description: Email updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const bcrypt = require('bcrypt'); const { idInput } = require('../../../utils/inputs'); diff --git a/server/api/controllers/users/update-password.js b/server/api/controllers/users/update-password.js index eb7ea028..ec641c74 100644 --- a/server/api/controllers/users/update-password.js +++ b/server/api/controllers/users/update-password.js @@ -3,6 +3,74 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{id}/password: + * patch: + * summary: Update user password + * description: Updates a user's password. Users must provide a current password when updating their own password. Admins can update any user's password without the current password. Returns a new access token when updating own password. + * tags: + * - Users + * parameters: + * - in: path + * name: id + * required: true + * description: ID of the user whose password to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - password + * properties: + * password: + * type: string + * maxLength: 256 + * description: Password (must meet password requirements) + * example: SecurePassword123! + * currentPassword: + * type: string + * maxLength: 256 + * description: Current password (required when updating own password) + * example: SecurePassword456! + * responses: + * 200: + * description: Password updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/User' + * included: + * type: object + * required: + * - accessTokens + * properties: + * accessTokens: + * type: array + * description: New acces tokens (when updating own password) + * items: + * type: string + * example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ4... + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const bcrypt = require('bcrypt'); const { isPassword } = require('../../../utils/validators'); diff --git a/server/api/controllers/users/update-username.js b/server/api/controllers/users/update-username.js index 0ec6530b..63248002 100644 --- a/server/api/controllers/users/update-username.js +++ b/server/api/controllers/users/update-username.js @@ -3,6 +3,66 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{id}/username: + * patch: + * summary: Update user username + * description: Updates a user's username. Users must provide a current password when updating their own username (unless they are SSO users with `oidcIgnoreUsername` enabled). Admins can update any user's username without the current password. + * tags: + * - Users + * parameters: + * - in: path + * name: id + * required: true + * description: ID of the user whose username to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * username: + * type: string + * minLength: 3 + * maxLength: 16 + * pattern: '^[a-zA-Z0-9]+((_|\.)?[a-zA-Z0-9])*$' + * nullable: true + * description: Unique username for user identification + * example: john_doe + * currentPassword: + * type: string + * maxLength: 256 + * description: Current password (required when updating own username) + * example: SecurePassword123! + * responses: + * 200: + * description: Username updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const bcrypt = require('bcrypt'); const { idInput } = require('../../../utils/inputs'); diff --git a/server/api/controllers/users/update.js b/server/api/controllers/users/update.js index ea07d007..4232e8a2 100755 --- a/server/api/controllers/users/update.js +++ b/server/api/controllers/users/update.js @@ -3,6 +3,120 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/users/{id}: + * patch: + * summary: Update user + * description: Updates a user. Users can update their own profile, admins can update any user. + * tags: + * - Users + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the user to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * role: + * type: string + * enum: [admin, projectOwner, boardUser] + * description: User role defining access permissions + * example: admin + * name: + * type: string + * maxLength: 128 + * description: Full display name of the user + * example: John Doe + * avatar: + * type: object + * nullable: true + * description: Avatar of the user (only null value to remove avatar) + * phone: + * type: string + * maxLength: 128 + * nullable: true + * description: Contact phone number + * example: +1234567890 + * organization: + * type: string + * maxLength: 128 + * nullable: true + * description: Organization or company name + * example: Acme Corporation + * language: + * type: string + * enum: [ar-YE, bg-BG, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, zh-CN, zh-TW] + * nullable: true + * description: Preferred language for user interface and notifications + * example: en-US + * subscribeToOwnCards: + * type: boolean + * description: Whether the user subscribes to their own cards + * example: false + * subscribeToCardWhenCommenting: + * type: boolean + * description: Whether the user subscribes to cards when commenting + * example: true + * turnOffRecentCardHighlighting: + * type: boolean + * description: Whether recent card highlighting is disabled + * example: false + * enableFavoritesByDefault: + * type: boolean + * description: Whether favorites are enabled by default + * example: false + * defaultEditorMode: + * type: string + * enum: [wysiwyg, markup] + * description: Default markdown editor mode + * example: wysiwyg + * defaultHomeView: + * type: string + * enum: [gridProjects, groupedProjects] + * description: Default view mode for the home page + * example: groupedProjects + * defaultProjectsOrder: + * type: string + * enum: [byDefault, alphabetically, byCreationTime] + * description: Default sort order for projects display + * example: byDefault + * isDeactivated: + * type: boolean + * description: Whether the user account is deactivated and cannot log in (for admins) + * example: false + * responses: + * 200: + * description: User updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/User' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 403: + * $ref: '#/components/responses/Forbidden' + * 404: + * $ref: '#/components/responses/NotFound' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/webhooks/create.js b/server/api/controllers/webhooks/create.js index 9caf21d6..3e65bf0e 100644 --- a/server/api/controllers/webhooks/create.js +++ b/server/api/controllers/webhooks/create.js @@ -3,6 +3,73 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/webhooks: + * post: + * summary: Create webhook + * description: Creates a webhook. Requires admin privileges. + * tags: + * - Webhooks + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - name + * - url + * properties: + * name: + * type: string + * maxLength: 128 + * description: Name/title of the webhook + * example: Webhook Updates + * url: + * type: string + * format: url + * maxLength: 2048 + * description: URL endpoint for the webhook + * example: https://example.service.com/planka + * accessToken: + * type: string + * maxLength: 512 + * nullable: true + * description: Access token for webhook authentication + * example: secret_token_123 + * events: + * type: string + * maxLength: 2048 + * nullable: true + * description: Comma-separated list of events that trigger the webhook + * example: cardCreate,cardUpdate,cardDelete + * excludedEvents: + * type: string + * maxLength: 2048 + * nullable: true + * description: Comma-separated list of events excluded from the webhook + * example: userCreate,userUpdate,userDelete + * responses: + * 200: + * description: Webhook created successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Webhook' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 409: + * $ref: '#/components/responses/Conflict' + */ + const { isUrl } = require('../../../utils/validators'); const Errors = { diff --git a/server/api/controllers/webhooks/delete.js b/server/api/controllers/webhooks/delete.js index 1c23837e..93d34f89 100644 --- a/server/api/controllers/webhooks/delete.js +++ b/server/api/controllers/webhooks/delete.js @@ -3,6 +3,42 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/webhooks/{id}: + * delete: + * summary: Delete webhook + * description: Deletes a webhook. Requires admin privileges. + * tags: + * - Webhooks + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the webhook to delete + * schema: + * type: string + * example: 1357158568008091264 + * responses: + * 200: + * description: Webhook deleted successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Webhook' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { idInput } = require('../../../utils/inputs'); const Errors = { diff --git a/server/api/controllers/webhooks/index.js b/server/api/controllers/webhooks/index.js index 73aea6fe..f4445116 100644 --- a/server/api/controllers/webhooks/index.js +++ b/server/api/controllers/webhooks/index.js @@ -3,6 +3,34 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/webhooks: + * get: + * summary: Get all webhooks + * description: Retrieves a list of all configured webhooks. Requires admin privileges. + * tags: + * - Webhooks + * responses: + * 200: + * description: List of webhooks retrieved successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - items + * properties: + * items: + * type: array + * items: + * $ref: '#/components/schemas/Webhook' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + */ + module.exports = { async fn() { const webhooks = await Webhook.qm.getAll(); diff --git a/server/api/controllers/webhooks/update.js b/server/api/controllers/webhooks/update.js index 8eff2fd3..097244d0 100644 --- a/server/api/controllers/webhooks/update.js +++ b/server/api/controllers/webhooks/update.js @@ -3,6 +3,78 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ +/** + * @swagger + * /api/webhooks/{id}: + * patch: + * summary: Update webhook + * description: Updates a webhook. Requires admin privileges. + * tags: + * - Webhooks + * parameters: + * - name: id + * in: path + * required: true + * description: ID of the webhook to update + * schema: + * type: string + * example: 1357158568008091264 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * name: + * type: string + * maxLength: 128 + * description: Name/title of the webhook + * example: Webhook Updates + * url: + * type: string + * format: url + * maxLength: 2048 + * description: URL endpoint for the webhook + * example: https://example.service.com/planka + * accessToken: + * type: string + * maxLength: 512 + * nullable: true + * description: Access token for webhook authentication + * example: secret_token_123 + * events: + * type: string + * maxLength: 2048 + * nullable: true + * description: Comma-separated list of events that trigger the webhook + * example: cardCreate,cardUpdate,cardDelete + * excludedEvents: + * type: string + * maxLength: 2048 + * nullable: true + * description: Comma-separated list of events excluded from the webhook + * example: userCreate,userUpdate,userDelete + * responses: + * 200: + * description: Webhook updated successfully + * content: + * application/json: + * schema: + * type: object + * required: + * - item + * properties: + * item: + * $ref: '#/components/schemas/Webhook' + * 400: + * $ref: '#/components/responses/ValidationError' + * 401: + * $ref: '#/components/responses/Unauthorized' + * 404: + * $ref: '#/components/responses/NotFound' + */ + const { isUrl } = require('../../../utils/validators'); const { idInput } = require('../../../utils/inputs'); diff --git a/server/api/models/Action.js b/server/api/models/Action.js index bc742385..8b750f03 100755 --- a/server/api/models/Action.js +++ b/server/api/models/Action.js @@ -10,6 +10,58 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Action: + * type: object + * required: + * - cardId + * - type + * - data + * properties: + * id: + * type: string + * description: Unique identifier for the action + * example: 1357158568008091264 + * boardId: + * type: string + * nullable: true + * description: ID of the board where the action occurred + * example: 1357158568008091265 + * cardId: + * type: string + * description: ID of the card where the action occurred + * example: 1357158568008091266 + * userId: + * type: string + * nullable: true + * description: ID of the user who performed the action + * example: 1357158568008091267 + * type: + * type: string + * enum: [createCard, moveCard, addMemberToCard, removeMemberFromCard, completeTask, uncompleteTask] + * description: Type of the action + * example: moveCard + * data: + * type: object + * description: Action specific data (varies by type) + * example: {"card": {"name": "Implement user authentication"}, "toList": {"id": "1357158568008091268", "name": "To Do", "type": "active"}, "fromList": {"id": "1357158568008091269", "name": "Done", "type": "closed"}} + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the action was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the action was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Types = { CREATE_CARD: 'createCard', MOVE_CARD: 'moveCard', diff --git a/server/api/models/Attachment.js b/server/api/models/Attachment.js index 998aa0d2..467a380e 100644 --- a/server/api/models/Attachment.js +++ b/server/api/models/Attachment.js @@ -10,6 +10,58 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Attachment: + * type: object + * required: + * - cardId + * - type + * - data + * - name + * properties: + * id: + * type: string + * description: Unique identifier for the attachment + * example: 1357158568008091264 + * cardId: + * type: string + * description: ID of the card the attachment belongs to + * example: 1357158568008091265 + * creatorUserId: + * type: string + * nullable: true + * description: ID of the user who created the attachment + * example: 1357158568008091266 + * type: + * type: string + * enum: [file, link] + * description: Type of the attachment + * example: link + * data: + * type: object + * description: Attachment specific data (varies by type) + * example: {"url": "https://google.com/search?q=planka", "faviconUrl": "https://storage.example.com/favicons/google.com.png"} + * name: + * type: string + * description: Name/title of the attachment + * example: Google Link + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the attachment was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the attachment was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Types = { FILE: 'file', LINK: 'link', diff --git a/server/api/models/BackgroundImage.js b/server/api/models/BackgroundImage.js index a5b49397..b477bafd 100644 --- a/server/api/models/BackgroundImage.js +++ b/server/api/models/BackgroundImage.js @@ -10,6 +10,60 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * BackgroundImage: + * type: object + * required: + * - projectId + * - size + * - url + * - thumbnailUrls + * properties: + * id: + * type: string + * description: Unique identifier for the background image + * example: 1357158568008091264 + * projectId: + * type: string + * description: ID of the project the background image belongs to + * example: 1357158568008091265 + * size: + * type: string + * description: File size of the background image in bytes + * example: 1024576 + * url: + * type: string + * format: uri + * description: URL to access the full-size background image + * example: https://storage.example.com/background-images/1357158568008091264/original.jpg + * thumbnailUrls: + * type: object + * required: + * - outside360 + * description: URLs for different thumbnail sizes of the background image + * properties: + * outside360: + * type: string + * format: uri + * description: URL for 360px thumbnail version + * example: https://storage.example.com/background-images/1357158568008091264/outside-360.jpg + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the background image was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the background image was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/BaseCustomFieldGroup.js b/server/api/models/BaseCustomFieldGroup.js index 39d4e898..13759299 100755 --- a/server/api/models/BaseCustomFieldGroup.js +++ b/server/api/models/BaseCustomFieldGroup.js @@ -10,6 +10,42 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * BaseCustomFieldGroup: + * type: object + * required: + * - projectId + * - name + * properties: + * id: + * type: string + * description: Unique identifier for the base custom field group + * example: 1357158568008091264 + * projectId: + * type: string + * description: ID of the project the base custom field group belongs to + * example: 1357158568008091265 + * name: + * type: string + * description: Name/title of the base custom field group + * example: Base Properties + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the base custom field group was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the base custom field group was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/Board.js b/server/api/models/Board.js index bf51c278..2c6af619 100755 --- a/server/api/models/Board.js +++ b/server/api/models/Board.js @@ -10,6 +10,69 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Board: + * type: object + * required: + * - projectId + * - position + * - name + * properties: + * id: + * type: string + * description: Unique identifier for the board + * example: 1357158568008091264 + * projectId: + * type: string + * description: ID of the project the board belongs to + * example: 1357158568008091265 + * position: + * type: number + * description: Position of the board within the project + * example: 65536 + * name: + * type: string + * description: Name/title of the board + * example: Development Board + * defaultView: + * type: string + * enum: [kanban, grid, list] + * description: Default view for the board + * example: kanban + * defaultCardType: + * type: string + * enum: [project, story] + * description: Default card type for new cards + * example: project + * limitCardTypesToDefaultOne: + * type: boolean + * description: Whether to limit card types to default one + * example: false + * alwaysDisplayCardCreator: + * type: boolean + * description: Whether to always display the card creator + * example: false + * expandTaskListsByDefault: + * type: boolean + * description: Whether to expand task lists by default + * example: false + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the board was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the board was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Card = require('./Card'); const Views = { diff --git a/server/api/models/BoardMembership.js b/server/api/models/BoardMembership.js index c7b8a871..72850a99 100644 --- a/server/api/models/BoardMembership.js +++ b/server/api/models/BoardMembership.js @@ -10,6 +10,58 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * BoardMembership: + * type: object + * required: + * - role + * - projectId + * - boardId + * - userId + * properties: + * id: + * type: string + * description: Unique identifier for the board membership + * example: 1357158568008091264 + * projectId: + * type: string + * description: ID of the project the board membership belongs to (denormalized) + * example: 1357158568008091265 + * boardId: + * type: string + * description: ID of the board the membership is associated with + * example: 1357158568008091266 + * userId: + * type: string + * description: ID of the user who is a member of the board + * example: 1357158568008091267 + * role: + * type: string + * enum: [editor, viewer] + * description: Role of the user in the board + * example: editor + * canComment: + * type: boolean + * nullable: true + * description: Whether the user can comment on cards (applies only to viewers) + * example: true + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the board membership was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the board membership was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Roles = { EDITOR: 'editor', VIEWER: 'viewer', diff --git a/server/api/models/Card.js b/server/api/models/Card.js index 0dd09b2c..e25e0712 100755 --- a/server/api/models/Card.js +++ b/server/api/models/Card.js @@ -10,6 +10,120 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Card: + * type: object + * required: + * - boardId + * - listId + * - type + * - name + * properties: + * id: + * type: string + * description: Unique identifier for the card + * example: 1357158568008091264 + * boardId: + * type: string + * description: ID of the board the card belongs to (denormalized) + * example: 1357158568008091265 + * listId: + * type: string + * description: ID of the list the card belongs to + * example: 1357158568008091266 + * creatorUserId: + * type: string + * nullable: true + * description: ID of the user who created the card + * example: 1357158568008091267 + * prevListId: + * type: string + * nullable: true + * description: ID of the previous list the card was in (available when in archive or trash) + * example: 1357158568008091268 + * coverAttachmentId: + * type: string + * nullable: true + * description: ID of the attachment used as cover + * example: 1357158568008091269 + * type: + * type: string + * enum: [project, story] + * description: Type of the card + * example: project + * position: + * type: number + * nullable: true + * description: Position of the card within the list + * example: 65536 + * name: + * type: string + * description: Name/title of the card + * example: Implement user authentication + * description: + * type: string + * nullable: true + * description: Detailed description of the card + * example: Add JWT-based authentication system... + * dueDate: + * type: string + * format: date-time + * nullable: true + * description: Due date for the card + * example: 2024-01-01T00:00:00.000Z + * isDueCompleted: + * type: boolean + * nullable: true + * description: Whether the due date is completed + * example: false + * stopwatch: + * type: object + * required: + * - startedAt + * - total + * nullable: true + * description: Stopwatch data for time tracking + * properties: + * startedAt: + * type: string + * format: date-time + * description: When the stopwatch was started + * example: 2024-01-01T00:00:00.000Z + * total: + * type: number + * description: Total time in seconds + * example: 3600 + * commentsTotal: + * type: number + * description: Total number of comments on the card + * example: 100 + * isClosed: + * type: boolean + * description: Whether the card is closed + * example: false + * listChangedAt: + * type: string + * format: date-time + * nullable: true + * description: When the card was last moved between lists + * example: 2024-01-01T00:00:00.000Z + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the card was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the card was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Types = { PROJECT: 'project', STORY: 'story', diff --git a/server/api/models/CardLabel.js b/server/api/models/CardLabel.js index b3f43d17..4c000eec 100755 --- a/server/api/models/CardLabel.js +++ b/server/api/models/CardLabel.js @@ -10,6 +10,42 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * CardLabel: + * type: object + * required: + * - cardId + * - labelId + * properties: + * id: + * type: string + * description: Unique identifier for the card-label association + * example: 1357158568008091264 + * cardId: + * type: string + * description: ID of the card the label is associated with + * example: 1357158568008091265 + * labelId: + * type: string + * description: ID of the label associated with the card + * example: 1357158568008091266 + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the card-label association was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the card-label association was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/CardMembership.js b/server/api/models/CardMembership.js index 0f6f40d1..99ef2770 100755 --- a/server/api/models/CardMembership.js +++ b/server/api/models/CardMembership.js @@ -10,6 +10,42 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * CardMembership: + * type: object + * required: + * - cardId + * - userId + * properties: + * id: + * type: string + * description: Unique identifier for the card membership + * example: 1357158568008091264 + * cardId: + * type: string + * description: ID of the card the user is a member of + * example: 1357158568008091265 + * userId: + * type: string + * description: ID of the user who is a member of the card + * example: 1357158568008091266 + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the card membership was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the card membership was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/Comment.js b/server/api/models/Comment.js index 5e476a00..f97d8155 100644 --- a/server/api/models/Comment.js +++ b/server/api/models/Comment.js @@ -10,6 +10,47 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Comment: + * type: object + * required: + * - cardId + * - text + * properties: + * id: + * type: string + * description: Unique identifier for the comment + * example: 1357158568008091264 + * cardId: + * type: string + * description: ID of the card the comment belongs to + * example: 1357158568008091265 + * userId: + * type: string + * nullable: true + * description: ID of the user who created the comment + * example: 1357158568008091266 + * text: + * type: string + * description: Content of the comment + * example: This task is almost complete... + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the comment was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the comment was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/Config.js b/server/api/models/Config.js index db27f12c..86b26eca 100644 --- a/server/api/models/Config.js +++ b/server/api/models/Config.js @@ -10,6 +10,48 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Config: + * type: object + * required: + * - id + * - isInitialized + * - version + * properties: + * id: + * type: string + * description: Unique identifier for the config (always set to '1') + * example: 1 + * isInitialized: + * type: boolean + * description: Whether the PLANKA instance has been initialized + * example: true + * version: + * type: string + * description: Current version of the PLANKA application + * example: 2.0.0 + * activeUsersLimit: + * type: number + * nullable: true + * description: Maximum number of active users allowed (conditionally added for admins if configured) + * example: 100 + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the config was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the config was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const MAIN_ID = '1'; module.exports = { diff --git a/server/api/models/CustomField.js b/server/api/models/CustomField.js index a154837c..c6421041 100755 --- a/server/api/models/CustomField.js +++ b/server/api/models/CustomField.js @@ -10,6 +10,57 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * CustomField: + * type: object + * required: + * - position + * - name + * - showOnFrontOfCard + * properties: + * id: + * type: string + * description: Unique identifier for the custom field + * example: 1357158568008091264 + * baseCustomFieldGroupId: + * type: string + * nullable: true + * description: ID of the base custom field group the custom field belongs to + * example: 1357158568008091265 + * customFieldGroupId: + * type: string + * nullable: true + * description: ID of the custom field group the custom field belongs to + * example: 1357158568008091266 + * position: + * type: number + * description: Position of the custom field within the group + * example: 65536 + * name: + * type: string + * description: Name/title of the custom field + * example: Priority + * showOnFrontOfCard: + * type: boolean + * description: Whether to show the field on the front of cards + * example: true + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the custom field was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the custom field was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/CustomFieldGroup.js b/server/api/models/CustomFieldGroup.js index 9aeb9cb0..eeec106e 100755 --- a/server/api/models/CustomFieldGroup.js +++ b/server/api/models/CustomFieldGroup.js @@ -10,6 +10,57 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * CustomFieldGroup: + * type: object + * required: + * - position + * properties: + * id: + * type: string + * description: Unique identifier for the custom field group + * example: 1357158568008091264 + * boardId: + * type: string + * nullable: true + * description: ID of the board the custom field group belongs to + * example: 1357158568008091265 + * cardId: + * type: string + * nullable: true + * description: ID of the card the custom field group belongs to + * example: 1357158568008091266 + * baseCustomFieldGroupId: + * type: string + * nullable: true + * description: ID of the base custom field group used as a template + * example: 1357158568008091267 + * position: + * type: number + * description: Position of the custom field group within the board/card + * example: 65536 + * name: + * type: string + * nullable: true + * description: Name/title of the custom field group + * example: Properties + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the custom field group was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the custom field group was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/CustomFieldValue.js b/server/api/models/CustomFieldValue.js index 496f8fb6..63ca29ba 100644 --- a/server/api/models/CustomFieldValue.js +++ b/server/api/models/CustomFieldValue.js @@ -10,6 +10,52 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * CustomFieldValue: + * type: object + * required: + * - cardId + * - customFieldGroupId + * - customFieldId + * - content + * properties: + * id: + * type: string + * description: Unique identifier for the custom field value + * example: 1357158568008091264 + * cardId: + * type: string + * description: ID of the card the value belongs to + * example: 1357158568008091265 + * customFieldGroupId: + * type: string + * description: ID of the custom field group the value belongs to + * example: 1357158568008091266 + * customFieldId: + * type: string + * description: ID of the custom field the value belongs to + * example: 1357158568008091267 + * content: + * type: string + * description: Content/value of the custom field + * example: High Priority + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the custom field value was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the custom field value was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/Label.js b/server/api/models/Label.js index b270452a..e4a23d1e 100755 --- a/server/api/models/Label.js +++ b/server/api/models/Label.js @@ -10,6 +10,53 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Label: + * type: object + * required: + * - boardId + * - position + * - color + * properties: + * id: + * type: string + * description: Unique identifier for the label + * example: 1357158568008091264 + * boardId: + * type: string + * description: ID of the board the label belongs to + * example: 1357158568008091265 + * position: + * type: number + * description: Position of the label within the board + * example: 65536 + * name: + * type: string + * nullable: true + * description: Name/title of the label + * example: Bug + * color: + * type: string + * enum: [muddy-grey, autumn-leafs, morning-sky, antique-blue, egg-yellow, desert-sand, dark-granite, fresh-salad, lagoon-blue, midnight-blue, light-orange, pumpkin-orange, light-concrete, sunny-grass, navy-blue, lilac-eyes, apricot-red, orange-peel, silver-glint, bright-moss, deep-ocean, summer-sky, berry-red, light-cocoa, grey-stone, tank-green, coral-green, sugar-plum, pink-tulip, shady-rust, wet-rock, wet-moss, turquoise-sea, lavender-fields, piggy-red, light-mud, gun-metal, modern-green, french-coast, sweet-lilac, red-burgundy, pirate-gold] + * description: Color of the label + * example: berry-red + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the label was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the label was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const COLORS = [ 'muddy-grey', 'autumn-leafs', diff --git a/server/api/models/List.js b/server/api/models/List.js index bd3b18e7..42a5b709 100755 --- a/server/api/models/List.js +++ b/server/api/models/List.js @@ -10,6 +10,59 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * List: + * type: object + * required: + * - boardId + * - type + * properties: + * id: + * type: string + * description: Unique identifier for the list + * example: 1357158568008091264 + * boardId: + * type: string + * description: ID of the board the list belongs to + * example: 1357158568008091265 + * type: + * type: string + * enum: [active, closed, archive, trash] + * description: Type/status of the list + * example: active + * position: + * type: number + * nullable: true + * description: Position of the list within the board + * example: 65536 + * name: + * type: string + * nullable: true + * description: Name/title of the list + * example: To Do + * color: + * type: string + * enum: [berry-red, pumpkin-orange, lagoon-blue, pink-tulip, light-mud, orange-peel, bright-moss, antique-blue, dark-granite, turquoise-sea] + * nullable: true + * description: Color for the list + * example: lagoon-blue + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the list was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the list was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Types = { ACTIVE: 'active', CLOSED: 'closed', diff --git a/server/api/models/Notification.js b/server/api/models/Notification.js index 2d9763a6..e79d28d7 100755 --- a/server/api/models/Notification.js +++ b/server/api/models/Notification.js @@ -10,6 +10,79 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Notification: + * type: object + * required: + * - id + * - userId + * - boardId + * - cardId + * - type + * - data + * - isRead + * properties: + * id: + * type: string + * description: Unique identifier for the notification + * example: 1357158568008091264 + * userId: + * type: string + * description: ID of the user who receives the notification + * example: 1357158568008091265 + * creatorUserId: + * type: string + * nullable: true + * description: ID of the user who created the notification + * example: 1357158568008091266 + * boardId: + * type: string + * description: ID of the board associated with the notification (denormalized) + * example: 1357158568008091267 + * cardId: + * type: string + * description: ID of the card associated with the notification + * example: 1357158568008091268 + * commentId: + * type: string + * nullable: true + * description: ID of the comment associated with the notification + * example: 1357158568008091269 + * actionId: + * type: string + * nullable: true + * description: ID of the action associated with the notification + * example: 1357158568008091270 + * type: + * type: string + * enum: [moveCard, commentCard, addMemberToCard, mentionInComment] + * description: Type of the notification + * example: commentCard + * data: + * type: object + * description: Notification payload specific to the type + * example: {"card": {"name": "Implement user authentication"}, "text": "This task is almost complete..."} + * isRead: + * type: boolean + * description: Whether the notification has been read + * example: false + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the notification was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the notification was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Types = { MOVE_CARD: 'moveCard', COMMENT_CARD: 'commentCard', diff --git a/server/api/models/NotificationService.js b/server/api/models/NotificationService.js index ccf9a897..20407c53 100644 --- a/server/api/models/NotificationService.js +++ b/server/api/models/NotificationService.js @@ -10,6 +10,53 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * NotificationService: + * type: object + * required: + * - url + * - format + * properties: + * id: + * type: string + * description: Unique identifier for the notification service + * example: 1357158568008091264 + * userId: + * type: string + * nullable: true + * description: ID of the user the service is associated with + * example: 1357158568008091265 + * boardId: + * type: string + * nullable: true + * description: ID of the board the service is associated with + * example: 1357158568008091266 + * url: + * type: string + * description: URL endpoint for notifications + * example: https://example.service.com/planka + * format: + * type: string + * enum: [text, markdown, html] + * description: Format for notification messages + * example: text + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the notification service was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the notification service was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Formats = { TEXT: 'text', MARKDOWN: 'markdown', diff --git a/server/api/models/Project.js b/server/api/models/Project.js index 8a889a8e..d463e4c7 100755 --- a/server/api/models/Project.js +++ b/server/api/models/Project.js @@ -10,6 +10,69 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Project: + * type: object + * required: + * - name + * properties: + * id: + * type: string + * description: Unique identifier for the project + * example: 1357158568008091264 + * ownerProjectManagerId: + * type: string + * nullable: true + * description: ID of the project manager who owns the project + * example: 1357158568008091265 + * backgroundImageId: + * type: string + * nullable: true + * description: ID of the background image used as background + * example: 1357158568008091266 + * name: + * type: string + * description: Name/title of the project + * example: Development Project + * description: + * type: string + * nullable: true + * description: Detailed description of the project + * example: A project for developing new features... + * backgroundType: + * type: string + * enum: [gradient, image] + * nullable: true + * description: Type of background for the project + * example: gradient + * backgroundGradient: + * type: string + * enum: [old-lime, ocean-dive, tzepesch-style, jungle-mesh, strawberry-dust, purple-rose, sun-scream, warm-rust, sky-change, green-eyes, blue-xchange, blood-orange, sour-peel, green-ninja, algae-green, coral-reef, steel-grey, heat-waves, velvet-lounge, purple-rain, blue-steel, blueish-curve, prism-light, green-mist, red-curtain] + * nullable: true + * description: Gradient background for the project + * example: ocean-dive + * isHidden: + * type: boolean + * default: false + * description: Whether the project is hidden + * example: false + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the project was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the project was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Types = { PRIVATE: 'private', SHARED: 'shared', diff --git a/server/api/models/ProjectManager.js b/server/api/models/ProjectManager.js index 9730ee4c..370ca68b 100644 --- a/server/api/models/ProjectManager.js +++ b/server/api/models/ProjectManager.js @@ -10,6 +10,42 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * ProjectManager: + * type: object + * required: + * - projectId + * - userId + * properties: + * id: + * type: string + * description: Unique identifier for the project manager + * example: 1357158568008091264 + * projectId: + * type: string + * description: ID of the project the manager is associated with + * example: 1357158568008091265 + * userId: + * type: string + * description: ID of the user who is assigned as project manager + * example: 1357158568008091266 + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the project manager was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the project manager was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/Task.js b/server/api/models/Task.js index 6b52d286..49381362 100755 --- a/server/api/models/Task.js +++ b/server/api/models/Task.js @@ -10,6 +10,62 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Task: + * type: object + * required: + * - taskListId + * - position + * - name + * properties: + * id: + * type: string + * description: Unique identifier for the task + * example: 1357158568008091264 + * taskListId: + * type: string + * description: ID of the task list the task belongs to + * example: 1357158568008091265 + * linkedCardId: + * type: string + * nullable: true + * description: ID of the card linked to the task + * example: 1357158568008091266 + * assigneeUserId: + * type: string + * nullable: true + * description: ID of the user assigned to the task + * example: 1357158568008091267 + * position: + * type: number + * description: Position of the task within the task list + * example: 65536 + * name: + * type: string + * description: Name/title of the task + * example: Write unit tests + * isCompleted: + * type: boolean + * default: false + * description: Whether the task is completed + * example: false + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the task was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the task was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/TaskList.js b/server/api/models/TaskList.js index f810d7d5..570a1041 100644 --- a/server/api/models/TaskList.js +++ b/server/api/models/TaskList.js @@ -10,6 +10,57 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * TaskList: + * type: object + * required: + * - cardId + * - position + * - name + * properties: + * id: + * type: string + * description: Unique identifier for the task list + * example: 1357158568008091264 + * cardId: + * type: string + * description: ID of the card the task list belongs to + * example: 1357158568008091265 + * position: + * type: number + * description: Position of the task list within the card + * example: 65536 + * name: + * type: string + * description: Name/title of the task list + * example: Development Tasks + * showOnFrontOfCard: + * type: boolean + * default: true + * description: Whether to show the task list on the front of the card + * example: true + * hideCompletedTasks: + * type: boolean + * default: false + * description: Whether to hide completed tasks + * example: false + * createdAt: + * type: string + * format: date-time + * nullable: true + * description: When the task list was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * nullable: true + * description: When the task list was last updated + * example: 2024-01-01T00:00:00.000Z + */ + module.exports = { attributes: { // ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗ diff --git a/server/api/models/User.js b/server/api/models/User.js index 7dc59941..99dc68d3 100755 --- a/server/api/models/User.js +++ b/server/api/models/User.js @@ -10,6 +10,167 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * User: + * type: object + * required: + * - id + * - email + * - role + * - name + * - termsType + * properties: + * id: + * type: string + * description: Unique identifier for the user + * example: 1357158568008091264 + * email: + * type: string + * format: email + * description: Email address for login and notifications (private field) + * example: john.doe@example.com + * role: + * type: string + * enum: [admin, projectOwner, boardUser] + * description: User role defining access permissions + * example: admin + * name: + * type: string + * description: Full display name of the user + * example: John Doe + * username: + * type: string + * minLength: 3 + * maxLength: 32 + * pattern: "^[a-zA-Z0-9]+((_{1}|\\.|){1}[a-zA-Z0-9])*$" + * nullable: true + * description: Unique username for user identification + * example: john_doe + * avatar: + * type: object + * required: + * - url + * - thumbnailUrls + * nullable: true + * description: Avatar information for the user with generated URLs + * properties: + * url: + * type: string + * format: uri + * description: URL to the full-size avatar image + * example: https://storage.example.com/user-avatars/1357158568008091264/original.jpg + * thumbnailUrls: + * type: object + * required: + * - cover180 + * description: URLs for different thumbnail sizes + * properties: + * cover180: + * type: string + * format: uri + * description: URL for 180px cover thumbnail + * example: https://storage.example.com/user-avatars/1357158568008091264/cover-180.jpg + * gravatarUrl: + * type: string + * format: uri + * nullable: true + * description: Gravatar URL for the user (conditionally added if configured) + * example: https://www.gravatar.com/avatar/abc123 + * phone: + * type: string + * nullable: true + * description: Contact phone number + * example: +1234567890 + * organization: + * type: string + * nullable: true + * description: Organization or company name + * example: Acme Corporation + * language: + * type: string + * enum: [ar-YE, bg-BG, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, zh-CN, zh-TW] + * nullable: true + * description: Preferred language for user interface and notifications (personal field) + * example: en-US + * subscribeToOwnCards: + * type: boolean + * default: false + * description: Whether the user subscribes to their own cards (personal field) + * example: false + * subscribeToCardWhenCommenting: + * type: boolean + * default: true + * description: Whether the user subscribes to cards when commenting (personal field) + * example: true + * turnOffRecentCardHighlighting: + * type: boolean + * default: false + * description: Whether recent card highlighting is disabled (personal field) + * example: false + * enableFavoritesByDefault: + * type: boolean + * default: false + * description: Whether favorites are enabled by default (personal field) + * example: false + * defaultEditorMode: + * type: string + * enum: [wysiwyg, markup] + * default: wysiwyg + * description: Default markdown editor mode (personal field) + * example: wysiwyg + * defaultHomeView: + * type: string + * enum: [gridProjects, groupedProjects] + * default: groupedProjects + * description: Default view mode for the home page (personal field) + * example: groupedProjects + * defaultProjectsOrder: + * type: string + * enum: [byDefault, alphabetically, byCreationTime] + * default: byDefault + * description: Default sort order for projects display (personal field) + * example: byDefault + * termsType: + * type: string + * description: Type of terms applicable to the user based on role + * example: general + * isSsoUser: + * type: boolean + * default: false + * description: Whether the user is SSO user (private field) + * example: false + * isDeactivated: + * type: boolean + * default: false + * description: Whether the user account is deactivated and cannot log in + * example: false + * isDefaultAdmin: + * type: boolean + * nullable: true + * description: Whether the user is the default admin (visible only to current user or admin) + * example: false + * lockedFieldNames: + * type: array + * items: + * type: string + * nullable: true + * description: List of fields locked from editing (visible only to current user or admin) + * example: [email, password, name] + * createdAt: + * type: string + * format: date-time + * description: When the user was created + * example: 2024-01-01T00:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * description: When the user was last updated + * example: 2024-01-01T00:00:00.000Z + */ + const Roles = { ADMIN: 'admin', PROJECT_OWNER: 'projectOwner', diff --git a/server/api/models/Webhook.js b/server/api/models/Webhook.js index f63b18ad..e03407c9 100644 --- a/server/api/models/Webhook.js +++ b/server/api/models/Webhook.js @@ -10,6 +10,57 @@ * @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models */ +/** + * @swagger + * components: + * schemas: + * Webhook: + * type: object + * required: + * - name + * - url + * properties: + * id: + * type: string + * description: Unique identifier for the webhook + * example: 1357158568008091264 + * name: + * type: string + * description: Name/title of the webhook + * example: Webhook Updates + * url: + * type: string + * description: URL endpoint for the webhook + * example: https://example.service.com/planka + * accessToken: + * type: string + * nullable: true + * description: Access token for webhook authentication + * example: secret_token_123 + * events: + * type: array + * items: + * type: string + * description: List of events that trigger the webhook + * example: [cardCreate, cardUpdate, cardDelete] + * excludedEvents: + * type: array + * items: + * type: string + * description: List of events excluded from the webhook + * example: [userCreate, userUpdate, userDelete] + * createdAt: + * type: string + * format: date-time + * description: When the webhook was created + * example: 2024-03-01T12:00:00.000Z + * updatedAt: + * type: string + * format: date-time + * description: When the webhook was last updated + * example: 2024-03-02T15:30:00.000Z + */ + const Events = { ACTION_CREATE: 'actionCreate', diff --git a/server/api/responses/conflict.js b/server/api/responses/conflict.js index c5aa2bbe..95a86229 100755 --- a/server/api/responses/conflict.js +++ b/server/api/responses/conflict.js @@ -31,6 +31,30 @@ * ``` */ +/** + * @swagger + * components: + * responses: + * Conflict: + * description: Request conflicts with current state of the resource + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_CONFLICT + * message: + * type: string + * description: Error message + * example: Resource already exists + */ + module.exports = function conflict(message) { const { res } = this; diff --git a/server/api/responses/forbidden.js b/server/api/responses/forbidden.js index 3bd32838..da8a353e 100644 --- a/server/api/responses/forbidden.js +++ b/server/api/responses/forbidden.js @@ -31,6 +31,30 @@ * ``` */ +/** + * @swagger + * components: + * responses: + * Forbidden: + * description: Access forbidden - insufficient permissions + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_FORBIDDEN + * message: + * type: string + * description: Error message + * example: Not enough rights + */ + module.exports = function forbidden(message) { const { res } = this; diff --git a/server/api/responses/notFound.js b/server/api/responses/notFound.js index 5b068df4..d737e9a5 100755 --- a/server/api/responses/notFound.js +++ b/server/api/responses/notFound.js @@ -31,6 +31,30 @@ * ``` */ +/** + * @swagger + * components: + * responses: + * NotFound: + * description: Resource not found + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_NOT_FOUND + * message: + * type: string + * description: Error message + * example: Resource not found + */ + module.exports = function notFound(message) { const { res } = this; diff --git a/server/api/responses/unauthorized.js b/server/api/responses/unauthorized.js index d3a9d081..a0752dd9 100755 --- a/server/api/responses/unauthorized.js +++ b/server/api/responses/unauthorized.js @@ -31,6 +31,30 @@ * ``` */ +/** + * @swagger + * components: + * responses: + * Unauthorized: + * description: Authentication required or invalid credentials + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNAUTHORIZED + * message: + * type: string + * description: Error message + * example: Access token is missing, invalid or expired + */ + module.exports = function unauthorized(message) { const { res } = this; diff --git a/server/api/responses/unprocessableEntity.js b/server/api/responses/unprocessableEntity.js index e2470474..0a4fde2c 100644 --- a/server/api/responses/unprocessableEntity.js +++ b/server/api/responses/unprocessableEntity.js @@ -31,6 +31,30 @@ * ``` */ +/** + * @swagger + * components: + * responses: + * UnprocessableEntity: + * description: Request contains semantic errors or validation failures + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_UNPROCESSABLE_ENTITY + * message: + * type: string + * description: Error message + * example: Validation failed + */ + module.exports = function unprocessableEntity(message) { const { res } = this; diff --git a/server/api/responses/validationError.js b/server/api/responses/validationError.js new file mode 100644 index 00000000..7a67b056 --- /dev/null +++ b/server/api/responses/validationError.js @@ -0,0 +1,68 @@ +/*! + * Copyright (c) 2024 PLANKA Software GmbH + * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md + */ + +/** + * validationError.js + * + * A custom response. + * + * Example usage: + * ``` + * return res.validationError(); + * // -or- + * return res.validationError(optionalData); + * ``` + * + * Or with actions2: + * ``` + * exits: { + * somethingHappened: { + * responseType: 'validationError' + * } + * } + * ``` + * + * ``` + * throw 'somethingHappened'; + * // -or- + * throw { somethingHappened: optionalData } + * ``` + */ + +/** + * @swagger + * components: + * responses: + * ValidationError: + * description: Request validation failed due to missing or invalid parameters + * content: + * application/json: + * schema: + * type: object + * required: + * - code + * - problems + * - message + * properties: + * code: + * type: string + * description: Error code + * example: E_MISSING_OR_INVALID_PARAMS + * problems: + * type: array + * description: Array of specific validation error messages + * items: + * type: string + * example: [ + * "\"emailOrUsername\" is required, but it was not defined.", + * "\"password\" is required, but it was not defined." + * ] + * message: + * type: string + * description: Error message + * example: The server could not fulfill this request (`POST /api/access-tokens`) due to 2 missing or invalid parameters. + */ + +module.exports = function validationError() {};