From ea453ab3fc8573dbacf52e3c02d47db47d83beb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Schro=CC=88der?= Date: Tue, 27 Feb 2024 12:52:39 +0100 Subject: [PATCH] Add enhanced Clockify nodes --- .github/dependabot.yaml | 7 + .github/workflows/publish-package.yaml | 44 + .github/workflows/pull-request.yaml | 2 +- README.md | 5 + nodes/.gitkeep | 0 nodes/clockify-enhanced/.eslintrc.json | 30 + nodes/clockify-enhanced/README.md | 52 + nodes/clockify-enhanced/jest.config.ts | 11 + nodes/clockify-enhanced/package.json | 39 + nodes/clockify-enhanced/project.json | 43 + nodes/clockify-enhanced/src/api.d.ts | 12218 ++++++++++++++++ nodes/clockify-enhanced/src/index.ts | 1 + .../ClockifyEnhancedTrigger.node.json | 18 + .../ClockifyEnhancedTrigger.node.spec.ts | 870 ++ .../ClockifyEnhancedTrigger.node.ts | 351 + .../ClockifyEnhanced/clockify-enhanced.svg | 1 + nodes/clockify-enhanced/tsconfig.json | 28 + nodes/clockify-enhanced/tsconfig.lib.json | 10 + nodes/clockify-enhanced/tsconfig.spec.json | 13 + tsconfig.base.json | 3 + 20 files changed, 13745 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/publish-package.yaml delete mode 100644 nodes/.gitkeep create mode 100644 nodes/clockify-enhanced/.eslintrc.json create mode 100644 nodes/clockify-enhanced/README.md create mode 100644 nodes/clockify-enhanced/jest.config.ts create mode 100644 nodes/clockify-enhanced/package.json create mode 100644 nodes/clockify-enhanced/project.json create mode 100644 nodes/clockify-enhanced/src/api.d.ts create mode 100644 nodes/clockify-enhanced/src/index.ts create mode 100644 nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.json create mode 100644 nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.spec.ts create mode 100644 nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.ts create mode 100644 nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/clockify-enhanced.svg create mode 100644 nodes/clockify-enhanced/tsconfig.json create mode 100644 nodes/clockify-enhanced/tsconfig.lib.json create mode 100644 nodes/clockify-enhanced/tsconfig.spec.json diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 76a94917..d81d7258 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -12,3 +12,10 @@ updates: - dependency-name: '@types/*' schedule: interval: 'weekly' + + - package-ecosystem: 'npm' + directory: '/nodes/clockify-enhanced' + ignore: + - dependency-name: '@types/*' + schedule: + interval: 'weekly' diff --git a/.github/workflows/publish-package.yaml b/.github/workflows/publish-package.yaml new file mode 100644 index 00000000..8d459e68 --- /dev/null +++ b/.github/workflows/publish-package.yaml @@ -0,0 +1,44 @@ +name: Publish Package + +on: + push: + tags: + - 'clockify-enhanced-*' + +env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_VERSION: 18.18.2 + +jobs: + publish-package: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + cache: npm + node-version: ${{ env.NODE_VERSION }} + registry-url: https://registry.npmjs.org + + - name: Restore Node.js modules cache + uses: actions/cache@v4 + with: + path: node_modules + key: ${{ runner.os }}-Node-Modules-V1-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.os }}-Node-Modules-V1- + + - name: Install dependencies + run: npm ci + + - name: Get tag + uses: little-core-labs/get-tag@v3.0.2 + id: tag + with: + tagRegex: '(?.*)-(?.*)' + + - name: Publish package + run: npx nx publish n8n-nodes-${{ steps.tag.outputs.name }} --ver=${{ steps.tag.outputs.version }} --tag=latest diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index 094a11bc..282fbfff 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -47,7 +47,7 @@ jobs: run: npx nx affected --target=lint --parallel=3 - name: Test source code affected by changes - run: npx nx affected --target=test --configuration=ci --parallel=3 + run: npx nx affected --target=test --configuration=ci --exclude=n8n-nodes --parallel=3 - name: Run build of packages affected by changes run: npx nx affected --target=build --parallel=3 diff --git a/README.md b/README.md index 96ab6add..ce26c18b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@ Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation. +This is a mono repository with many different community nodes. +Please take a closer look at the detailed instructions for the individual nodes: + +- [Enhanced Clockify community nodes](nodes/clockify-enhanced/README.md) + ## Resources - [n8n community nodes documentation](https://docs.n8n.io/integrations/community-nodes/) diff --git a/nodes/.gitkeep b/nodes/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/nodes/clockify-enhanced/.eslintrc.json b/nodes/clockify-enhanced/.eslintrc.json new file mode 100644 index 00000000..b31cf71b --- /dev/null +++ b/nodes/clockify-enhanced/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../../.eslintrc.base.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredDependencies": ["express", "jest-mock-extended"] + } + ] + } + } + ] +} diff --git a/nodes/clockify-enhanced/README.md b/nodes/clockify-enhanced/README.md new file mode 100644 index 00000000..f863d247 --- /dev/null +++ b/nodes/clockify-enhanced/README.md @@ -0,0 +1,52 @@ +# @skriptfabrik/n8n-nodes-clockify-enhanced + +[![NPM Version](https://img.shields.io/npm/v/@skriptfabrik/n8n-nodes-clockify-enhanced)](https://www.npmjs.com/package/@skriptfabrik/n8n-nodes-clockify-enhanced) +[![NPM Downloads](https://img.shields.io/npm/dt/@skriptfabrik/n8n-nodes-clockify-enhanced)](https://www.npmjs.com/package/@skriptfabrik/n8n-nodes-clockify-enhanced) + +> Enhanced [Clockify](https://clockify.me/) community nodes for your [n8n](https://n8n.io/) workflows + +This is an n8n community node. It lets you use [Clockify](https://clockify.me/) webhooks as trigger nodes for your n8n workflows. + +Clockify is a time tracker and timesheet app for teams. + +[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform. + +[Installation](#installation) +[Operations](#operations) +[Credentials](#credentials) +[Compatibility](#compatibility) +[Resources](#resources) + +## Installation + +Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community +nodes documentation. + +1. Go to **Settings > Community Nodes**. +2. Select **Install**. +3. Enter `@skriptfabrik/n8n-nodes-clockify-enhanced` in **Enter npm package name**. +4. Agree to the [risks](https://docs.n8n.io/integrations/community-nodes/risks/) of using community nodes: select + **I understand the risks of installing unverified code from a public source**. +5. Select **Install**. + +After installing the node, you can use it like any other node. n8n displays the node in search results in the **Nodes** panel. + +## Operations + +It supports these operations: + +- Register a webhook in the API which will call the trigger node on configured event + +## Credentials + +You can use the built-in [Clockify credentials](https://docs.n8n.io/integrations/builtin/credentials/clockify/) to +authenticate with Clockify. + +## Compatibility + +Tested against n8n version 1.0+. + +## Resources + +- [n8n community nodes documentation](https://docs.n8n.io/integrations/community-nodes/) +- [Clockify API (v1)](https://docs.clockify.me/) diff --git a/nodes/clockify-enhanced/jest.config.ts b/nodes/clockify-enhanced/jest.config.ts new file mode 100644 index 00000000..5c7e160d --- /dev/null +++ b/nodes/clockify-enhanced/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'n8n-nodes-clockify-enhanced', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/nodes/clockify-enhanced', +}; diff --git a/nodes/clockify-enhanced/package.json b/nodes/clockify-enhanced/package.json new file mode 100644 index 00000000..3533f2fb --- /dev/null +++ b/nodes/clockify-enhanced/package.json @@ -0,0 +1,39 @@ +{ + "name": "@skriptfabrik/n8n-nodes-clockify-enhanced", + "version": "0.1.0", + "description": "Enhanced Clockify community nodes for n8n", + "keywords": [ + "clockify", + "n8n", + "n8n-community-node", + "n8n-community-node-package" + ], + "license": "MIT", + "homepage": "https://github.com/skriptfabrik/n8n-nodes/blob/main/nodes/clockify-enhanced/README.md", + "author": { + "name": "skriptfabrik", + "email": "info@skriptfabrik.com" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/skriptfabrik/n8n-nodes.git" + }, + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "type": "commonjs", + "n8n": { + "n8nNodesApiVersion": 1, + "credentials": [], + "nodes": [ + "src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.js" + ] + }, + "dependencies": { + "n8n-nodes-base": "^1.29.1", + "n8n-workflow": "^1.29.1", + "tslib": "^2.6.2" + }, + "publishConfig": { + "registry": "https://npm.pkg.github.com" + } +} diff --git a/nodes/clockify-enhanced/project.json b/nodes/clockify-enhanced/project.json new file mode 100644 index 00000000..f3ccf872 --- /dev/null +++ b/nodes/clockify-enhanced/project.json @@ -0,0 +1,43 @@ +{ + "name": "n8n-nodes-clockify-enhanced", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "nodes/clockify-enhanced/src", + "projectType": "library", + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/nodes/clockify-enhanced", + "tsConfig": "nodes/clockify-enhanced/tsconfig.lib.json", + "packageJson": "nodes/clockify-enhanced/package.json", + "main": "nodes/clockify-enhanced/src/index.ts", + "assets": [ + "nodes/clockify-enhanced/src/nodes/*/*.svg", + "nodes/clockify-enhanced/src/nodes/*/*.json", + "nodes/clockify-enhanced/*.md" + ] + } + }, + "link": { + "executor": "nx:run-commands", + "options": { + "cwd": "dist/nodes/clockify-enhanced", + "command": "npm link --no-audit" + }, + "dependsOn": ["build"] + }, + "install": { + "executor": "nx:run-commands", + "options": { + "command": "node tools/scripts/install.mjs n8n-nodes-clockify-enhanced" + }, + "dependsOn": ["link"] + }, + "publish": { + "command": "node tools/scripts/publish.mjs n8n-nodes-clockify-enhanced {args.ver} {args.tag}", + "dependsOn": ["build"] + } + }, + "tags": [] +} diff --git a/nodes/clockify-enhanced/src/api.d.ts b/nodes/clockify-enhanced/src/api.d.ts new file mode 100644 index 00000000..da26d24a --- /dev/null +++ b/nodes/clockify-enhanced/src/api.d.ts @@ -0,0 +1,12218 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + '/v1/file/image': { + /** Add photo */ + post: operations['uploadImage']; + }; + '/v1/user': { + /** Get currently logged-in user's info */ + get: operations['getLoggedUser']; + }; + '/v1/workspaces': { + /** Get all my workspaces */ + get: operations['getWorkspacesOfUser']; + /** Add workspace */ + post: operations['createWorkspace']; + }; + '/v1/workspaces/{workspaceId}': { + /** Get workspace info */ + get: operations['getWorkspaceOfUser']; + }; + '/v1/workspaces/{workspaceId}/addons/{addonId}/webhooks': { + /** Get all webhooks for addon on workspace */ + get: operations['getAddonWebhooks']; + }; + '/v1/workspaces/{workspaceId}/approval-requests': { + /** Get approval requests */ + get: operations['getApprovalGroups']; + /** Submit approval request */ + post: operations['createApprrovalRequest']; + }; + '/v1/workspaces/{workspaceId}/approval-requests/users/{userId}': { + /** Submit approval request for user */ + post: operations['createApprovalForOther']; + }; + '/v1/workspaces/{workspaceId}/approval-requests/{approvalRequestId}': { + /** Update approval request */ + patch: operations['updateApprovalStatus']; + }; + '/v1/workspaces/{workspaceId}/clients': { + /** Find clients on workspace */ + get: operations['getClients']; + /** Add a new client */ + post: operations['createClient']; + }; + '/v1/workspaces/{workspaceId}/clients/{id}': { + /** Get client by ID */ + get: operations['getClient']; + /** Update client */ + put: operations['updateClient']; + /** Delete client */ + delete: operations['deleteClient']; + }; + '/v1/workspaces/{workspaceId}/cost-rate': { + /** Update workspace cost rate */ + put: operations['setWorkspaceCostRate']; + }; + '/v1/workspaces/{workspaceId}/custom-fields': { + /** Get custom fields on workspace */ + get: operations['ofWorkspace']; + }; + '/v1/workspaces/{workspaceId}/custom-fields/{customFieldId}': { + /** Set custom field as required */ + put: operations['editCustomField']; + }; + '/v1/workspaces/{workspaceId}/expenses': { + /** Get all expenses on workspace */ + get: operations['getExpenses']; + /** Create expense */ + post: operations['createExpense']; + }; + '/v1/workspaces/{workspaceId}/expenses/categories': { + /** Get all expense categories */ + get: operations['getCategories']; + /** Add expense category */ + post: operations['createExpenseCategory']; + }; + '/v1/workspaces/{workspaceId}/expenses/categories/{categoryId}': { + /** Update expense category */ + put: operations['updateCategory']; + /** Delete expense category */ + delete: operations['deleteCategory']; + }; + '/v1/workspaces/{workspaceId}/expenses/categories/{categoryId}/status': { + /** Archive expense category */ + patch: operations['updateExpenseCategoryStatus']; + }; + '/v1/workspaces/{workspaceId}/expenses/{expenseId}': { + /** Get expense by ID */ + get: operations['getExpense']; + /** Update expense */ + put: operations['updateExpense']; + /** Delete expense */ + delete: operations['deleteExpense']; + }; + '/v1/workspaces/{workspaceId}/expenses/{expenseId}/files/{fileId}': { + /** Download receipt */ + get: operations['downloadFile']; + }; + '/v1/workspaces/{workspaceId}/hourly-rate': { + /** Update workspace billable rate */ + put: operations['setWorkspaceHourlyRate']; + }; + '/v1/workspaces/{workspaceId}/invoices': { + /** Get all invoices on workspace */ + get: operations['getInvoices']; + /** Add invoice */ + post: operations['createInvoice']; + }; + '/v1/workspaces/{workspaceId}/invoices/info': { + /** Filter out invoices */ + post: operations['getInvoicesInfo']; + }; + '/v1/workspaces/{workspaceId}/invoices/settings': { + /** Get invoice in another language */ + get: operations['getInvoiceSettings']; + /** Change invoice language */ + put: operations['updateInvoiceSettings']; + }; + '/v1/workspaces/{workspaceId}/invoices/{invoiceId}': { + /** Get invoice by ID */ + get: operations['getInvoice']; + /** Send invoice */ + put: operations['updateInvoice']; + /** Delete invoice */ + delete: operations['deleteInvoice']; + }; + '/v1/workspaces/{workspaceId}/invoices/{invoiceId}/duplicate': { + /** Duplicate invoice */ + post: operations['duplicateInvoice']; + }; + '/v1/workspaces/{workspaceId}/invoices/{invoiceId}/export': { + /** Export invoice */ + get: operations['exportInvoice']; + }; + '/v1/workspaces/{workspaceId}/invoices/{invoiceId}/payments': { + /** Get payments for invoice */ + get: operations['getPaymentsForInvoice']; + /** Add payment to invoice */ + post: operations['createInvoicePayment']; + }; + '/v1/workspaces/{workspaceId}/invoices/{invoiceId}/payments/{paymentId}': { + /** Delete payment from invoice */ + delete: operations['deletePaymentById']; + }; + '/v1/workspaces/{workspaceId}/invoices/{invoiceId}/status': { + /** Change invoice status */ + patch: operations['changeInvoiceStatus']; + }; + '/v1/workspaces/{workspaceId}/member-profile/{userId}': { + /** Get member's profile */ + get: operations['getMemberProfile']; + /** Update member's profile */ + patch: operations['updateMemberProfileWithAdditionalData']; + }; + '/v1/workspaces/{workspaceId}/member-profile/{userId}/email': { + /** Update user's email */ + put: operations['changeUserMemberEmail']; + }; + '/v1/workspaces/{workspaceId}/projects': { + /** Get all projects on workspace */ + get: operations['getProjects']; + /** Add a new project */ + post: operations['createNewProject']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}': { + /** Find project by ID */ + get: operations['getProject']; + /** Update project on workspace */ + put: operations['updateProject']; + /** Delete project from workspace */ + delete: operations['deleteProject']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/custom-fields': { + /** Get custom fields on project */ + get: operations['getCustomFieldsOfProject']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/custom-fields/{customFieldId}': { + /** Remove custom field from project */ + delete: operations['removeDefaultValueOfProject']; + /** Update custom field on project */ + patch: operations['editProjectCustomFieldDefaultValue']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/estimate': { + /** Update project estimate */ + patch: operations['updateEstimate']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/memberships': { + /** Assign/remove users to/from the project */ + post: operations['addUsersToProject']; + /** Update project memberships */ + patch: operations['updateMemberships']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/tasks': { + /** Find tasks on project */ + get: operations['getTasks']; + /** Add a new task on project */ + post: operations['createTask']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/tasks/{id}/cost-rate': { + /** Update task cost rate */ + put: operations['setTaskCostRate']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/tasks/{id}/hourly-rate': { + /** Update task billable rate */ + put: operations['setTaskHourlyRate']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/tasks/{taskId}': { + /** Get task by id */ + get: operations['getTask']; + /** Update task on project */ + put: operations['updateTask']; + /** Delete task from project */ + delete: operations['deleteTask']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/template': { + /** Update project template */ + patch: operations['updateIsProjectTemplate']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/users/{userId}/cost-rate': { + /** Update project user cost rate */ + put: operations['addUsersCostRate']; + }; + '/v1/workspaces/{workspaceId}/projects/{projectId}/users/{userId}/hourly-rate': { + /** Update project user billable rate */ + put: operations['addUsersHourlyRate']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/all': { + /** Get all assignments */ + get: operations['getAllAssignments']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/projects/totals': { + /** Get all scheduled assignments per project */ + get: operations['getProjectTotals']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/projects/totals/{projectId}': { + /** Get all scheduled assignments on project */ + get: operations['getProjectTotalsForSingleProject']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/publish': { + /** Publish assignments */ + put: operations['publishAssignments']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/recurring': { + /** Create recurring assignment */ + post: operations['createRecurring']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/recurring/{assignmentId}': { + /** Delete recurring assignment */ + delete: operations['deleteRRecurringAssignment']; + /** Update recurring assignment */ + patch: operations['editRecurring']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/series/{assignmentId}': { + /** Change recurring period */ + put: operations['editRecurringPeriod']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/user-filter/totals': { + /** Get total of users' capacity on workspace */ + post: operations['getUserTotals']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/users/{userId}/totals': { + /** Get total capacity of a user */ + get: operations['getUserTotalsForSingleUser']; + }; + '/v1/workspaces/{workspaceId}/scheduling/assignments/{assignmentId}/copy': { + /** Copy scheduled assignment */ + post: operations['copyAssignment']; + }; + '/v1/workspaces/{workspaceId}/tags': { + /** Find tags on workspace */ + get: operations['getTags']; + /** Add a new tag */ + post: operations['createNewTag']; + }; + '/v1/workspaces/{workspaceId}/tags/{id}': { + /** Get tag by ID */ + get: operations['getTag']; + /** Update tag */ + put: operations['updateTag']; + /** Delete tag */ + delete: operations['deleteTag']; + }; + '/v1/workspaces/{workspaceId}/time-entries': { + /** Add a new time entry */ + post: operations['createTimeEntry']; + }; + '/v1/workspaces/{workspaceId}/time-entries/invoiced': { + /** Mark time entries as invoiced */ + patch: operations['updateInvoicedStatus']; + }; + '/v1/workspaces/{workspaceId}/time-entries/{id}': { + /** Get a specific time entry on workspace */ + get: operations['getTimeEntry']; + /** Update time entry on workspace */ + put: operations['updateTimeEntry']; + /** Delete time entry from workspace */ + delete: operations['deleteTimeEntry']; + }; + '/v1/workspaces/{workspaceId}/user-groups': { + /** Find all groups on workspace */ + get: operations['getUserGroups']; + /** Add a new group */ + post: operations['createUserGroup']; + }; + '/v1/workspaces/{workspaceId}/user-groups/{id}': { + /** Update group */ + put: operations['updateUserGroup']; + /** Delete group */ + delete: operations['deleteUserGroup']; + }; + '/v1/workspaces/{workspaceId}/user-groups/{userGroupId}/users': { + /** Add users to group */ + post: operations['addUser']; + }; + '/v1/workspaces/{workspaceId}/user-groups/{userGroupId}/users/{userId}': { + /** Remove user from group */ + delete: operations['deleteUser']; + }; + '/v1/workspaces/{workspaceId}/user/{userId}/time-entries': { + /** Get time entries for a user on workspace */ + get: operations['getTimeEntries']; + /** Bulk edit time entries */ + put: operations['replaceMany']; + /** Add a new time entry for another user on workspace */ + post: operations['createForOthers']; + /** Delete all time entries for user on workspace */ + delete: operations['deleteMany']; + /** Stop currently running timer on workspace for user */ + patch: operations['stopRunningTimeEntry']; + }; + '/v1/workspaces/{workspaceId}/user/{userId}/time-entries/{id}/duplicate': { + /** Duplicate time entry */ + post: operations['duplicateTimeEntry']; + }; + '/v1/workspaces/{workspaceId}/users': { + /** Find all users on workspace */ + get: operations['getUsersOfWorkspace']; + /** + * Add user + * @description You can add users to a workspace via API only if that workspace has a paid subscription. If the workspace has a paid subscription, you can add as many users as you want but you are limited by the number of paid user seats on that workspace. + */ + post: operations['addUsers']; + }; + '/v1/workspaces/{workspaceId}/users/info': { + /** Filter workspace users */ + post: operations['filterUsersOfWorkspace']; + }; + '/v1/workspaces/{workspaceId}/users/{userId}': { + /** Update user's status */ + put: operations['updateUserStatus']; + /** Remove user from workspace */ + delete: operations['removeMember']; + }; + '/v1/workspaces/{workspaceId}/users/{userId}/cost-rate': { + /** Update user's cost rate */ + put: operations['setCostRateForUser']; + }; + '/v1/workspaces/{workspaceId}/users/{userId}/custom-field/{customFieldId}/value': { + /** Update user's custom field */ + put: operations['upsertUserCustomFieldValue']; + }; + '/v1/workspaces/{workspaceId}/users/{userId}/hourly-rate': { + /** Update user's hourly rate */ + put: operations['setHourlyRateForUser']; + }; + '/v1/workspaces/{workspaceId}/users/{userId}/managers': { + /** Find user's team manager */ + get: operations['getManagersOfUser']; + }; + '/v1/workspaces/{workspaceId}/users/{userId}/roles': { + /** Give user manager role */ + post: operations['createUserRole']; + /** Remove user's manager role */ + delete: operations['deleteUserRole']; + }; + '/v1/workspaces/{workspaceId}/webhooks': { + /** Get all webhooks on workspace */ + get: operations['getWebhooks']; + /** + * Create webhooks + * @description Creating a webhook generates a new token which can be used to verify that the webhook being sent was sent by Clockify, as it will always be present in the header. + */ + post: operations['createWebhook']; + }; + '/v1/workspaces/{workspaceId}/webhooks/{webhookId}': { + /** Get a specific webhook by id */ + get: operations['getWebhook']; + /** Update a webhook */ + put: operations['updateWebhook']; + /** Delete webhook */ + delete: operations['deleteWebhook']; + }; + '/v1/workspaces/{workspaceId}/webhooks/{webhookId}/logs': { + /** Get logs for a webhook */ + post: operations['getLogsForWebhook']; + }; + '/v1/workspaces/{workspaceId}/webhooks/{webhookId}/token': { + /** + * Generate new token + * @description Generates a new webhook token and invalidates previous one + */ + patch: operations['generateNewToken']; + }; + '/v1/workspaces/{workspaceId}/balance/policy/{policyId}': { + /** Get balance by policy */ + get: operations['getBalancesForPolicy']; + /** Update balance */ + patch: operations['updateBalancesForUsers']; + }; + '/v1/workspaces/{workspaceId}/balance/user/{userId}': { + /** Get balance by user */ + get: operations['getBalancesForUser']; + }; + '/v1/workspaces/{workspaceId}/holidays': { + /** Get holidays on workspace */ + get: operations['getHolidays']; + /** Create holiday */ + post: operations['createHoliday']; + }; + '/v1/workspaces/{workspaceId}/holidays/in-period': { + /** Get holiday in specific period */ + get: operations['getHolidaysInPeriod']; + }; + '/v1/workspaces/{workspaceId}/holidays/{holidayId}': { + /** Update holiday */ + put: operations['updateHoliday']; + /** Delete holiday */ + delete: operations['deleteHoliday']; + }; + '/v1/workspaces/{workspaceId}/policies': { + /** Get policies on workspace */ + get: operations['findPoliciesForWorkspace']; + /** Create time off policy */ + post: operations['createPolicy']; + }; + '/v1/workspaces/{workspaceId}/policies/{id}': { + /** Get time off policy */ + get: operations['getPolicy']; + /** Update policy */ + put: operations['updatePolicy']; + /** Delete policy */ + delete: operations['deletePolicy']; + /** Change policy status */ + patch: operations['updatePolicyStatus']; + }; + '/v1/workspaces/{workspaceId}/policies/{policyId}/requests': { + /** Create time off request (for day policies) */ + post: operations['createTimeOffRequest']; + }; + '/v1/workspaces/{workspaceId}/policies/{policyId}/requests/{requestId}': { + /** Delete request */ + delete: operations['deleteTimeOffRequest']; + /** Change time off request status */ + patch: operations['changeTimeOffRequestStatus']; + }; + '/v1/workspaces/{workspaceId}/policies/{policyId}/users/{userId}/requests': { + /** Create time off request */ + post: operations['createTimeOffRequestForOther']; + }; + '/v1/workspaces/{workspaceId}/requests': { + /** Get all time off requests on workspace */ + post: operations['getTimeOffRequests']; + }; + '/v1/shared-reports/{id}': { + /** + * Generate shared report by ID + * @description Response depends on report type and export type. Given example is for SUMMARY report and JSON exportType. + */ + get: operations['generateSharedReportV1']; + }; + '/v1/workspaces/{workspaceId}/reports/attendance': { + /** Generate attendance report */ + post: operations['generateAttendanceReport']; + }; + '/v1/workspaces/{workspaceId}/reports/detailed': { + /** Detailed report */ + post: operations['generateDetailedReport']; + }; + '/v1/workspaces/{workspaceId}/reports/expenses/detailed': { + /** Generate expense report */ + post: operations['generateDetailedReportV1']; + }; + '/v1/workspaces/{workspaceId}/reports/summary': { + /** Summary report */ + post: operations['generateSummaryReport']; + }; + '/v1/workspaces/{workspaceId}/reports/weekly': { + /** Weekly report */ + post: operations['generateWeeklyReport']; + }; + '/v1/workspaces/{workspaceId}/shared-reports': { + /** + * Get all my shared reports + * @description Gets all shared reports for current user on given workspace + */ + get: operations['getSharedReportsV1']; + /** + * Create shared report + * @description Saves shared report with name, options and report filter + */ + post: operations['saveSharedReportV1']; + }; + '/v1/workspaces/{workspaceId}/shared-reports/{id}': { + /** + * Update shared report + * @description Updates shared report name and/or options + */ + put: operations['updateSharedReportV1']; + /** Delete shared report */ + delete: operations['deleteSharedReportV1']; + }; +} + +export type webhooks = Record; + +export interface components { + schemas: { + /** + * @description Represents account status enum. + * @example ACTIVE + */ + AccountStatus: { + limitedAccount?: boolean; + } & ( + | 'ACTIVE' + | 'PENDING_EMAIL_VERIFICATION' + | 'DELETED' + | 'NOT_REGISTERED' + | 'LIMITED' + | 'LIMITED_DELETED' + ); + AddUserToWorkspaceRequest: { + /** + * @description Represents email address of the user. + * @example johndoe@example.com + */ + email: string; + }; + AddUsersToProjectRequestV1: { + /** @default false */ + remove?: boolean; + userIds?: string[]; + }; + ApprovalDetailsDtoV1: { + approvalRequest?: components['schemas']['ApprovalRequestDtoV1']; + /** + * @description Represents a time duration. + * @example PT1H30M + */ + approvedTime?: string; + /** + * Format: double + * @example 2500 + */ + billableAmount?: number; + /** + * @description Represents a time duration. + * @example PT1H30M + */ + billableTime?: string; + /** + * @description Represents a time duration. + * @example PT1H30M + */ + breakTime?: string; + /** + * Format: double + * @description Represents an amount. + * @example 5000 + */ + costAmount?: number; + /** @description Represents a list of time entry info data transfer objects. */ + entries?: components['schemas']['TimeEntryInfoDto'][]; + /** + * Format: double + * @description Represents an amount. + * @example 7500 + */ + expenseTotal?: number; + /** @description Represents a list of expense hydrated data transfer objects. */ + expenses?: components['schemas']['ExpenseHydratedDto'][]; + /** + * @description Represents a time duration. + * @example PT1H30M + */ + pendingTime?: string; + /** + * @description Represents a time duration. + * @example PT1H30M + */ + trackedTime?: string; + }; + /** @description Represents approval request creator object. */ + ApprovalRequestCreatorDtoV1: { + /** + * @description Represents user email. + * @example johhndoe@example.com + */ + userEmail?: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + /** + * @description Represents user name. + * @example johhndoe + */ + userName?: string; + }; + ApprovalRequestDtoV1: { + creator?: components['schemas']['ApprovalRequestCreatorDtoV1']; + dateRange?: components['schemas']['DateRangeDto']; + /** + * @description Represents approval request identifier across the workspace. + * @example 567687e29ae1f428e7ebf564 + */ + id?: string; + owner?: components['schemas']['ApprovalRequestOwnerDtoV1']; + status?: components['schemas']['ApprovalRequestStatusDtoV1']; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + /** @description Represents approval request owner object. */ + ApprovalRequestOwnerDtoV1: { + /** + * @description Represents a day of the week. + * @example MONDAY + * @enum {string} + */ + startOfWeek?: + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY'; + /** + * @description Represents time zone. + * @example Europe/Budapest + */ + timeZone?: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + /** + * @description Represents user name. + * @example johndoe + */ + userName?: string; + }; + /** @description Represents approval request status object. */ + ApprovalRequestStatusDtoV1: { + /** + * @description Represents an approval requesst note. + * @example This is a sample approval request note. + */ + note?: string; + /** + * @description Represents approval state enum. + * @example APPROVED + * @enum {string} + */ + state?: + | 'PENDING' + | 'APPROVED' + | 'WITHDRAWN_SUBMISSION' + | 'WITHDRAWN_APPROVAL' + | 'REJECTED'; + /** + * Format: date-time + * @description Represents a date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + updatedAt?: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + updatedBy?: string; + /** + * @description Represents user name. + * @example juandelacruz + */ + updatedByUserName?: string; + }; + AssignmentCreateRequestV1: { + /** @description Indicates whether assignment is billable or not. */ + billable?: boolean; + end?: string; + /** + * Format: double + * @description Represents assignment total hours per day. + * @example 7.5 + */ + hoursPerDay?: number; + /** @description Indicates whether to include non-working days or not. */ + includeNonWorkingDays?: boolean; + /** + * @description Represents assignment note. + * @example This is a sample note for an assignment. + */ + note?: string; + period?: components['schemas']['DateRange']; + /** + * @description Represents project identifier across the system. + * @example 56b687e29ae1f428e7ebe504 + */ + projectId: string; + recurring?: components['schemas']['RecurringAssignmentRequestV1']; + recurringAssignment?: components['schemas']['RecurringAssignmentRequestV1']; + regularRecurringAssignment?: components['schemas']['RecurringAssignmentRequest']; + start?: string; + /** + * @description Represents start time in hh:mm:ss format. + * @example 10:00:00 + */ + startTime?: string; + /** + * @description Represents task identifier across the system. + * @example 56b687e29ae1f428e7ebe505 + */ + taskId?: string; + /** + * @description Represents user identifier across the system. + * @example 72k687e29ae1f428e7ebe109 + */ + userId: string; + }; + AssignmentDtoV1: { + /** @description Indicates whether assignment is billable or not. */ + billable?: boolean; + /** @description Represents a list of excluded days objects */ + excludeDays?: components['schemas']['SchedulingExcludeDay'][]; + /** + * Format: double + * @description Represents assignment total hours per day. + * @example 7.5 + */ + hoursPerDay?: number; + /** + * @description Represents assignment identifier across the system. + * @example 74a687e29ae1f428e7ebe505 + */ + id?: string; + /** @description Indicates whether assignment should include non-working days or not. */ + includeNonWorkingDays?: boolean; + /** + * @description Represents assignment note. + * @example This is a sample note for an assignment. + */ + note?: string; + period?: components['schemas']['DateRangeDto']; + /** + * @description Represents project identifier across the system. + * @example 56b687e29ae1f428e7ebe504 + */ + projectId?: string; + /** @description Indicates whether assignment is published or not. */ + published?: boolean; + recurring?: components['schemas']['RecurringAssignmentDto']; + /** + * @description Represents start time in hh:mm:ss format. + * @example 10:00:00 + */ + startTime?: string; + /** + * @description Represents user identifier across the system. + * @example 72k687e29ae1f428e7ebe109 + */ + userId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + AssignmentHydratedDtoV1: { + /** @description Indicates whether assignment is billable or not. */ + billable?: boolean; + /** + * @description Represents client identifier across the system. + * @example 36b687e29ae1f428e7ebe109 + */ + clientId?: string; + /** + * @description Represents project name. + * @example Software Development + */ + clientName?: string; + /** + * Format: double + * @description Represents number of hours per day as double. + * @example 7.5 + */ + hoursPerDay?: number; + /** + * @description Represents assignment identifier across the system. + * @example 74a687e29ae1f428e7ebe505 + */ + id?: string; + /** + * @description Represents assignment note. + * @example This is a sample note for an assignment. + */ + note?: string; + period?: components['schemas']['DateRangeDto']; + projectArchived?: boolean; + projectBillable?: boolean; + /** + * @description Color format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #000000 + */ + projectColor?: string; + /** + * @description Represents project identifier across the system. + * @example 56b687e29ae1f428e7ebe504 + */ + projectId?: string; + /** + * @description Represents project name. + * @example Software Development + */ + projectName?: string; + /** + * @description Represents start time in hh:mm:ss format. + * @example 10:00:00 + */ + startTime?: string; + /** + * @description Represents user identifier across the system. + * @example 72k687e29ae1f428e7ebe109 + */ + userId?: string; + /** + * @description Represents user name. + * @example John Doe + */ + userName?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + /** @description Represents a list of assignment per day objects. */ + AssignmentPerDayDto: { + /** Format: date-time */ + date?: string; + hasAssignment?: boolean; + }; + AssignmentUpdateRequestV1: { + /** @description Indicates whether assignment is billable or not. */ + billable?: boolean; + end?: string; + /** + * Format: double + * @description Represents assignment total hours per day. + * @example 7.5 + */ + hoursPerDay?: number; + /** @description Indicates whether to include non-working days or not. */ + includeNonWorkingDays?: boolean; + /** + * @description Represents assignment note. + * @example This is a sample note for an assignment. + */ + note?: string; + period?: components['schemas']['DateRange']; + /** + * @description Valid series option + * @example THIS_ONE + * @enum {string} + */ + seriesUpdateOption?: 'THIS_ONE' | 'THIS_AND_FOLLOWING' | 'ALL'; + start?: string; + /** + * @description Represents start time in hh:mm:ss format. + * @example 10:00:00 + */ + startTime?: string; + /** + * @description Represents task identifier across the system. + * @example 56b687e29ae1f428e7ebe505 + */ + taskId?: string; + }; + /** @description Represents an authorization data transfer object. */ + AuthorizationSourceDtoV1: { + /** + * @description Represents authorization source identifier across the system. + * @example 5b715612b079875110791234 + */ + id?: string; + /** + * @description Represents a valid authorization source type. + * @example USER_GROUP + * @enum {string} + */ + type?: 'USER_GROUP'; + }; + /** @description Represents an automatic lock object. */ + AutomaticLockDtoV1: { + /** + * @description Represents a day of the week. + * @example FRIDAY + * @enum {string} + */ + changeDay?: + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY'; + /** + * Format: int32 + * @description Represents a day of month as integer. + * @example 15 + */ + dayOfMonth?: number; + /** + * @description Represents a day of the week. + * @example MONDAY + * @enum {string} + */ + firstDay?: + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY'; + /** + * @description Represents a time entry automatic lock period enum. + * @example DAYS + * @enum {string} + */ + olderThanPeriod?: 'DAYS' | 'WEEKS' | 'MONTHS'; + /** + * Format: int32 + * @description Represents an integer as the criteria for locking time entries. + * @example 5 + */ + olderThanValue?: number; + /** + * @description Represents a time entry automatic lock type enum. + * @example WEEKLY + * @enum {string} + */ + type?: 'WEEKLY' | 'MONTHLY' | 'OLDER_THAN'; + }; + ChangeEmailRequest: { + /** + * @description Represents email address of the user. + * @example johndoe@example.com + */ + email?: string; + }; + ChangeInvoiceStatusRequestV1: { + /** + * @description Represents the invoice status to be set. + * @example PAID + * @enum {string} + */ + invoiceStatus?: + | 'UNSENT' + | 'SENT' + | 'PAID' + | 'PARTIALLY_PAID' + | 'VOID' + | 'OVERDUE'; + }; + ClientDtoV1: { + /** + * @description Represents client's address. + * @example Ground Floor, ABC Bldg., Palo Alto, California, USA 94020 + */ + address?: string; + /** @description Represents whether a client is archived or not. */ + archived?: boolean; + /** + * @description Represents currency identifier across the system. + * @example 33t687e29ae1f428e7ebe505 + */ + currencyId?: string; + /** + * @description Represents client email. + * @example clientx@example.com + */ + email?: string; + /** + * @description Represents client identifier across the system. + * @example 44a687e29ae1f428e7ebe305 + */ + id?: string; + /** + * @description Represents client name. + * @example Client X + */ + name?: string; + /** + * @description Represents saved notes for the client. + * @example This is a sample note for the client. + */ + note?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + ClientWithCurrencyDtoV1: { + /** + * @description Represents client's address. + * @example Ground Floor, ABC Bldg., Palo Alto, California, USA 94020 + */ + address?: string; + /** @description Represents whether a client is archived or not. */ + archived?: boolean; + /** + * @description Represents client currency code. + * @example USD + */ + currencyCode?: string; + /** + * @description Represents currency identifier across the system. + * @example 33t687e29ae1f428e7ebe505 + */ + currencyId?: string; + /** + * @description Represents client email. + * @example clientx@example.com + */ + email?: string; + /** + * @description Represents client identifier across the system. + * @example 44a687e29ae1f428e7ebe305 + */ + id?: string; + /** + * @description Represents client name. + * @example Client X + */ + name?: string; + /** + * @description Represents saved notes for the client. + * @example This is a sample note for the client. + */ + note?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + ContainsClientsFilterRequest: { + /** + * @description Filter type + * @example CONTAINS + * @enum {string} + */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Represents a list of filter identifiers. + * @example [ + * "5a0ab5acb07987125438b60f", + * "64c777ddd3fcab07cfbb210c" + * ] + */ + ids?: string[]; + /** + * @description Represents a filter for status. + * @example ACTIVE + */ + status?: string; + }; + ContainsCompaniesFilterRequest: { + /** + * @description Filter type + * @example CONTAINS + * @enum {string} + */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Represents a list of filter identifiers. + * @example [ + * "5a0ab5acb07987125438b60f", + * "64c777ddd3fcab07cfbb210c" + * ] + */ + ids?: string[]; + /** + * @description Represents a filter for status. + * @example ACTIVE + */ + status?: string; + }; + ContainsUserGroupFilterRequest: { + /** + * @description Filter type + * @example CONTAINS + * @enum {string} + */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Represents a list of filter identifiers. + * @example [ + * "5a0ab5acb07987125438b60f", + * "64c777ddd3fcab07cfbb210c" + * ] + */ + ids?: string[]; + /** + * @description Represents a filter for status. + * @example ACTIVE + */ + status?: string; + }; + /** @description Represents a user group filter request object. */ + ContainsUserGroupFilterRequestV1: { + /** + * @description Filter type + * @example CONTAINS + * @enum {string} + */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Represents a list of filter identifiers. + * @example [ + * "5a0ab5acb07987125438b60f", + * "64c777ddd3fcab07cfbb210c" + * ] + */ + ids?: string[]; + /** + * @description Represents a filter for status. + * @example ACTIVE + */ + status?: string; + }; + ContainsUsersFilterRequest: { + archivedFilterValue?: boolean; + /** + * @description Filter type + * @example CONTAINS + * @enum {string} + */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Represents a list of filter identifiers. + * @example [ + * "5a0ab5acb07987125438b60f", + * "64c777ddd3fcab07cfbb210c" + * ] + */ + ids?: string[]; + /** @enum {string} */ + sourceType?: 'USER_GROUP'; + /** + * @description Represents a filter for status. + * @example ACTIVE + */ + status?: string; + statuses?: ('PENDING' | 'ACTIVE' | 'DECLINED' | 'INACTIVE' | 'ALL')[]; + }; + /** @description Represents a user filter request object. */ + ContainsUsersFilterRequestV1: { + /** + * @description Filter type + * @example CONTAINS + * @enum {string} + */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Represents a list of filter identifiers. + * @example [ + * "5a0ab5acb07987125438b60f", + * "64c777ddd3fcab07cfbb210c" + * ] + */ + ids?: string[]; + /** + * @description Valid authorization source type + * @example USER_GROUP + * @enum {string} + */ + sourceType?: 'USER_GROUP'; + /** + * @description Represents a filter for status. + * @example ACTIVE + */ + status?: string; + /** + * @description Valid array of membership status. Possible values: PENDING, ACTIVE, DECLINED, INACTIVE, ALL + * @example PENDING + */ + statuses?: ('PENDING' | 'ACTIVE' | 'DECLINED' | 'INACTIVE' | 'ALL')[]; + }; + CopyAssignmentRequestV1: { + /** + * @description Represents a series option enum. + * @example THIS_ONE + * @enum {string} + */ + seriesUpdateOption?: 'THIS_ONE' | 'THIS_AND_FOLLOWING' | 'ALL'; + /** + * @description Represents user identifier across the system. + * @example 72k687e29ae1f428e7ebe109 + */ + userId: string; + }; + /** @description Represents a cost rate request object. */ + CostRateRequest: { + /** + * Format: int32 + * @description Represents an amount as integer. + * @example 2000 + */ + amount?: number; + /** + * @description Represents a datetime in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + since?: string; + /** Format: date-time */ + sinceAsInstant?: string; + }; + CostRateRequestV1: { + /** + * Format: int32 + * @description Represents an amount as integer. + * @example 20000 + */ + amount?: number; + /** + * @description Represents a datetime in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + since?: string; + }; + CreateApprovalRequest: { + /** + * @description Specifies the approval period. + * @example MONTHLY + * @enum {string} + */ + period?: 'WEEKLY' | 'SEMI_MONTHLY' | 'MONTHLY'; + /** + * @description Valid yyyy-MM-dd datetime format. + * @example 2020-01-01 + */ + weekTime?: string; + /** + * Format: int32 + * @description Valid number of weeks ago as integer. Default value = 0 + * @example 1 + */ + weeksAgo?: number; + }; + CreateClientRequestV1: { + /** + * @description Represents client's address. + * @example Ground Floor, ABC Bldg., Palo Alto, California, USA 94020 + */ + address?: string; + /** + * @description Represents client email. + * @example clientx@example.com + */ + email?: string; + /** + * @description Represents client name. + * @example Client X + */ + name: string; + /** + * @description Represents additional notes for the client. + * @example This is a sample note for the client. + */ + note?: string; + }; + CreateCustomAttributeRequest: { + /** + * @description Represents custom attribute name. + * @example race + */ + name: string; + /** + * @description Represents custom attribute namespace. + * @example user_info + */ + namespace: string; + /** + * @description Represents custom attribute value. + * @example Asian + */ + value: string; + }; + CreateExpenseV1Request: { + /** + * Format: double + * @description Represents expense amount as double data type. + * @example 99.5 + */ + amount?: number; + /** @description Indicates whether expense is billable or not. */ + billable?: boolean; + /** + * @description Represents category identifier across the system. + * @example 45y687e29ae1f428e7ebe890 + */ + categoryId?: string; + /** + * Format: date-time + * @description Provides a valid yyyy-MM-ddThh:mm:ssZ format date. + * @example 2020-01-01T00:00:00Z + */ + date?: string; + /** Format: binary */ + file?: string; + /** + * @description Represents notes for an expense. + * @example This is a sample note for this expense. + */ + notes?: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId?: string; + }; + CreateInvoiceDtoV1: { + /** + * @description Represents to whom the invoice should be billed from. + * @example Business X + */ + billFrom?: string; + /** + * @description Represents client identifier across the system. + * @example 34p687e29ae1f428e7ebe562 + */ + clientId?: string; + /** + * @description Represents the currency used by the invoice. + * @example USD + */ + currency?: string; + /** + * Format: date-time + * @description Represents an invoice due date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-06-01T08:00:00Z + */ + dueDate?: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * Format: date-time + * @description Represents an invoice issued date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + issuedDate?: string; + /** + * @description Represents an invoice number. + * @example 202306121129 + */ + number?: string; + }; + CreateInvoicePaymentRequest: { + /** + * Format: int64 + * @description Represents an invoice payment amount as long. + * @example 100 + */ + amount?: number; + /** + * @description Represents an invoice payment note. + * @example This is a sample note for this invoice payment. + */ + note?: string; + /** + * @description Represents an invoice payment date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T12:00:00Z + */ + paymentDate?: string; + }; + CreateInvoiceRequest: { + /** + * @description Represents client identifier across the system. + * @example 98h687e29ae1f428e7ebe707 + */ + clientId: string; + /** + * @description Represents the currency used by the invoice. + * @example USD + */ + currency: string; + /** + * Format: date-time + * @description Represents an invoice due date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-06-01T08:00:00Z + */ + dueDate?: string; + /** + * Format: date-time + * @description Represents an invoice issued date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + issuedDate?: string; + /** + * @description Represents an invoice number. + * @example 202306121129 + */ + number: string; + }; + CreateTimeEntryRequest: { + /** @description Indicates whether a time entry is billable or not. */ + billable?: boolean; + customAttributes?: components['schemas']['CreateCustomAttributeRequest'][]; + customFields?: components['schemas']['UpdateCustomFieldRequest'][]; + /** + * @description Represents time entry description. + * @example This is a sample time entry description. + */ + description?: string; + /** + * Format: date-time + * @description Represents an end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + /** + * Format: date-time + * @description Represents a start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + /** + * @description Represents a list of tag ids. + * @example [ + * "321r77ddd3fcab07cfbb567y", + * "44x777ddd3fcab07cfbb88f" + * ] + */ + tagIds?: string[]; + /** + * @description Represents task identifier across the system. + * @example 54m377ddd3fcab07cfbb432w + */ + taskId?: string; + /** + * @description Valid time entry type + * @enum {string} + */ + type?: 'REGULAR' | 'BREAK' | 'HOLIDAY' | 'TIME_OFF'; + }; + CreateWebhookRequestV1: { + /** + * @description Represents webhook name. + * @example stripe + */ + name?: string; + /** + * @description Represents a list of trigger sources. + * @example [ + * "54a687e29ae1f428e7ebe909", + * "87p187e29ae1f428e7ebej56" + * ] + */ + triggerSource: string[]; + /** + * @description Represents a webhook event trigger source type enum. + * @example PROJECT_ID + * @enum {string} + */ + triggerSourceType?: + | 'PROJECT_ID' + | 'USER_ID' + | 'TAG_ID' + | 'TASK_ID' + | 'WORKSPACE_ID' + | 'USER_GROUP_ID' + | 'INVOICE_ID'; + /** + * @description Represents workspace identifier across the system. + * @example https://example-clockify.com/stripeEndpoint + */ + url: string; + /** @enum {string} */ + webhookEvent?: + | 'NEW_PROJECT' + | 'NEW_TASK' + | 'NEW_CLIENT' + | 'NEW_TIMER_STARTED' + | 'TIMER_STOPPED' + | 'TIME_ENTRY_UPDATED' + | 'TIME_ENTRY_DELETED' + | 'NEW_TIME_ENTRY' + | 'NEW_TAG' + | 'USER_DELETED_FROM_WORKSPACE' + | 'USER_JOINED_WORKSPACE' + | 'USER_DEACTIVATED_ON_WORKSPACE' + | 'USER_ACTIVATED_ON_WORKSPACE' + | 'USER_EMAIL_CHANGED' + | 'USER_UPDATED' + | 'NEW_INVOICE' + | 'INVOICE_UPDATED' + | 'NEW_APPROVAL_REQUEST' + | 'APPROVAL_REQUEST_STATUS_UPDATED' + | 'TIME_OFF_REQUESTED' + | 'TIME_OFF_REQUEST_APPROVED' + | 'TIME_OFF_REQUEST_REJECTED' + | 'TIME_OFF_REQUEST_WITHDRAWN' + | 'BALANCE_UPDATED'; + }; + /** @description Represents currency with default info object. */ + CurrencyWithDefaultInfoDtoV1: { + /** + * @description Represents currency code. + * @example USD + */ + code?: string; + /** + * @description Represents currency identifier across the system. + * @example 5b641568b07987035750505e + */ + id?: string; + /** + * @description Indicates whether curency should be set as default. + * @example true + */ + isDefault?: boolean; + }; + /** @description Represents a list of custom field default values data transfer objects. */ + CustomFieldDefaultValuesDtoV1: { + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId?: string; + /** + * @description Represents custom field status + * @example VISIBLE + */ + status?: string; + /** + * @description Represents a custom field's default value + * @example NA + */ + value?: Record; + }; + CustomFieldDtoV1: { + /** + * @description Represents a list of custom field's allowed values. + * @example [ + * "NA", + * "White", + * "Black", + * "Asian", + * "Hispanic" + * ] + */ + allowedValues?: string[]; + /** + * @description Represents custom field description. + * @example This field contains a user's race. + */ + description?: string; + /** + * @description Represents custom field entity type + * @example USER + */ + entityType?: string; + /** + * @description Represents custom field identifier across the system. + * @example 44a687e29ae1f428e7ebe305 + */ + id?: string; + /** + * @description Represents custom field name. + * @example race + */ + name?: string; + /** @description Flag to set whether custom field is modifiable only by admin users. */ + onlyAdminCanEdit?: boolean; + /** + * @description Represents custom field placeholder value. + * @example Race/ethnicity + */ + placeholder?: string; + /** @description Represents a list of custom field default values data transfer objects. */ + projectDefaultValues?: components['schemas']['CustomFieldDefaultValuesDtoV1'][]; + /** @description Flag to set whether custom field is mandatory or not. */ + required?: boolean; + /** + * @description Represents custom field status + * @example VISIBLE + */ + status?: string; + /** + * @description Represents custom field type. + * @example DROPDOWN_MULTIPLE + */ + type?: string; + /** + * @description Represents a custom field's default value in the workspace. + * @example NA + */ + workspaceDefaultValue?: Record; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + CustomFieldProjectDefaultValuesRequest: { + /** + * @description Represents a custom field's default value. + * @example NA + */ + defaultValue?: Record; + /** + * @description Represents custom field status. + * @example VISIBLE + * @enum {string} + */ + status?: 'INACTIVE' | 'VISIBLE' | 'INVISIBLE'; + }; + /** + * @description Represents custom field type. + * @example TXT + */ + CustomFieldType: + | 'TXT' + | 'NUMBER' + | 'DROPDOWN_SINGLE' + | 'DROPDOWN_MULTIPLE' + | 'CHECKBOX' + | 'LINK'; + /** @description Represents a list of custom field value objects. */ + CustomFieldValueDto: { + /** + * @description Represents custom field identifier across the system. + * @example 44a687e29ae1f428e7ebe305 + */ + customFieldId?: string; + /** + * @description Represents a custom field value source type enum. + * @example WORKSPACE + * @enum {string} + */ + sourceType?: 'WORKSPACE' | 'PROJECT' | 'TIMEENTRY'; + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + timeEntryId?: string; + /** + * @description Represents custom field value. + * @example 20231211-12345 + */ + value?: Record; + }; + CustomFieldValueDtoV1: { + /** + * @description Represents custom field identifier across the system. + * @example 5e4117fe8c625f38930d57b7 + */ + customFieldId?: string; + /** + * @description Represents custom field name. + * @example TIN + */ + name?: string; + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + timeEntryId?: string; + /** + * @description Represents a custom field value source type. + * @example WORKSPACE + */ + type?: string; + /** + * @description Represents custom field value. + * @example 20231211-12345 + */ + value?: Record; + }; + DateRange: { + /** Format: date-time */ + end?: string; + /** Format: date-time */ + start?: string; + }; + /** @description Represents a date range object. */ + DateRangeDto: { + /** Format: date-time */ + end?: string; + /** Format: date-time */ + start?: string; + }; + /** @description Represents project estimate object. */ + EstimateDtoV1: { + /** + * @description Represents a task duration estimate. + * @example PT1H30M + */ + estimate?: string; + /** + * @description Represents an estimate type enum. + * @example AUTO + * @enum {string} + */ + type?: 'AUTO' | 'MANUAL'; + }; + /** @description Represents an estimate request object. */ + EstimateRequest: { + /** + * @description Represents a time duration. + * @example PT1H30M + */ + estimate?: { + /** Format: int32 */ + nano?: number; + negative?: boolean; + /** Format: int64 */ + seconds?: number; + units?: { + dateBased?: boolean; + duration?: { + /** Format: int32 */ + nano?: number; + negative?: boolean; + /** Format: int64 */ + seconds?: number; + zero?: boolean; + }; + durationEstimated?: boolean; + timeBased?: boolean; + }[]; + zero?: boolean; + }; + /** + * @description Represents an estimate type enum. + * @example AUTO + * @enum {string} + */ + type?: 'AUTO' | 'MANUAL'; + }; + /** @description Represents estimate reset request object. */ + EstimateResetRequest: { + /** + * Format: int32 + * @description Represents a day of the month. + * @example 20 + */ + dayOfMonth?: number; + /** + * @description Represents a day of the week. + * @example MONDAY + * @enum {string} + */ + dayOfWeek?: + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY'; + /** + * Format: int32 + * @description Represents an hour of the day in 24-hhour time format. + * @example 12 + */ + hour?: number; + /** + * @description Represents a reset option enum. + * @example MONTHLY + * @enum {string} + */ + interval?: 'WEEKLY' | 'MONTHLY' | 'YEARLY'; + /** + * @description Represents a month enum. + * @example FEBRUARY + * @enum {string} + */ + month?: + | 'JANUARY' + | 'FEBRUARY' + | 'MARCH' + | 'APRIL' + | 'MAY' + | 'JUNE' + | 'JULY' + | 'AUGUST' + | 'SEPTEMBER' + | 'OCTOBER' + | 'NOVEMBER' + | 'DECEMBER'; + }; + /** @description Represents project budget estimate object. */ + EstimateWithOptionsDto: { + active?: boolean; + /** + * Format: int64 + * @description Represents an estimate as long. + * @example 600000 + */ + estimate?: number; + /** @description Indicates whether estimate includes non-billable or not. */ + includeExpenses?: boolean; + /** + * @description Represents a reset option enum. + * @example WEEKLY + * @enum {string} + */ + resetOption?: 'WEEKLY' | 'MONTHLY' | 'YEARLY'; + /** + * @description Represents an estimate type enum. + * @example AUTO + * @enum {string} + */ + type?: 'AUTO' | 'MANUAL'; + }; + /** @description Represents estimate with options request object. */ + EstimateWithOptionsRequest: { + active?: boolean; + /** + * Format: int64 + * @description Represents an estimate as long. + * @example 10000 + */ + estimate?: number; + includeExpenses?: boolean; + /** @description Flag whether to include billable expenses. */ + includesBillableExpenses?: boolean; + /** + * @description Represents a reset option enum. + * @example MONTHLY + * @enum {string} + */ + resetOption?: 'WEEKLY' | 'MONTHLY' | 'YEARLY'; + /** + * @description Represents an estimate type enum. + * @example AUTO + * @enum {string} + */ + type?: 'AUTO' | 'MANUAL'; + }; + ExpenseCategoriesWithCountDtoV1: { + /** @description Represents a list of expense categories data transfer object. */ + categories?: components['schemas']['ExpenseCategoryDtoV1'][]; + /** + * Format: int32 + * @description Indicates the number of expense categories returned. + * @example 20 + */ + count?: number; + }; + ExpenseCategoryArchiveV1Request: { + /** @description Flag whether to archive the expense category or not. */ + archived?: boolean; + }; + /** @description Represents expense category object. */ + ExpenseCategoryDto: { + /** @description Flag that indicates whether the expense category is archived or not. */ + archived?: boolean; + /** @description Represents whether expense category has unit price or none. */ + hasUnitPrice?: boolean; + /** + * @description Represents expense category identifier across the system. + * @example 89a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * @description Represents expense category name. + * @example Procurement + */ + name?: string; + /** + * Format: int32 + * @description Represents price in centavos as integer. + * @example 1000 + */ + priceInCents?: number; + /** + * @description Represents expense category unit. + * @example piece + */ + unit?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + ExpenseCategoryDtoV1: { + /** @description Flag that indicates whether the expense category is archived or not. */ + archived?: boolean; + /** @description Represents whether expense category has unit price or none. */ + hasUnitPrice?: boolean; + /** + * @description Represents expense category identifier across the system. + * @example 89a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * @description Represents expense category name. + * @example Procurement + */ + name?: string; + /** + * Format: int32 + * @description Represents price in centavos as integer. + * @example 1000 + */ + priceInCents?: number; + /** + * @description Represents expense category unit. + * @example piece + */ + unit?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + ExpenseCategoryV1Request: { + hasUnitPrice?: boolean; + /** + * @description Represents a valid expense category name. + * @example Procurement + */ + name: string; + /** + * Format: int32 + * @description Represents price in centavos as integer. + * @example 1000 + */ + priceInCents?: number; + /** + * @description Represents a valid expense category unit. + * @example piece + */ + unit?: string; + }; + /** @description Represents a list of expense daily total data transfer objects. */ + ExpenseDailyTotalsDtoV1: { + /** + * @description Represents a date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + date?: string; + /** Format: date-time */ + dateAsInstant?: string; + /** + * Format: double + * @description Represents expense total. + * @example 1500.75 + */ + total?: number; + }; + ExpenseDtoV1: { + /** @description Indicates whether expense is billable or not. */ + billable?: boolean; + /** + * @description Represents category identifier across the system. + * @example 45y687e29ae1f428e7ebe890 + */ + categoryId?: string; + /** + * @description Represents a date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + date?: string; + /** + * @description Represents file identifier across the system. + * @example 745687e29ae1f428e7ebe890 + */ + fileId?: string; + /** + * @description Represents expense identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id?: string; + isLocked?: boolean; + locked?: boolean; + /** + * @description Represents notes for an expense. + * @example This is a sample note for this expense. + */ + notes?: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + /** + * Format: double + * @description Represents expense quantity as double data type. + */ + quantity?: number; + /** + * Format: double + * @description Represents expense total as double data type. + * @example 10500.5 + */ + total?: number; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + /** @description Represents a list of expense hydrated data transfer objects. */ + ExpenseHydratedDto: { + /** + * @description Represents approval request identifier across the system. + * @example 445687e29ae1f428e7ebe893 + */ + approvalRequestId?: string; + /** @description Indicates whether expense is billable or not. */ + billable?: boolean; + category?: components['schemas']['ExpenseCategoryDto']; + /** + * @description Represents a currency. + * @example USD + */ + currency?: string; + /** + * @description Represents a date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + date?: string; + /** + * @description Represents file identifier across the system. + * @example 745687e29ae1f428e7ebe890 + */ + fileId?: string; + /** + * @description Represents file name. + * @example file_12345.csv + */ + fileName?: string; + /** + * @description Represents expense identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id?: string; + isLocked?: boolean; + locked?: boolean; + /** + * @description Represents notes for an expense. + * @example This is a sample note for this expense. + */ + notes?: string; + project?: components['schemas']['ProjectInfoDto']; + /** + * Format: double + * @description Represents expense quantity as double data type. + */ + quantity?: number; + /** + * Format: double + * @description Represents expense total as double data type. + * @example 10500.5 + */ + total?: number; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + /** @description Represent a list of hydrated expense objects. */ + ExpenseHydratedDtoV1: { + /** @description Indicates whether expense is billable or not. */ + billable?: boolean; + category?: components['schemas']['ExpenseCategoryDto']; + /** + * @description Represents a date in yyyy-MM-dd format. + * @example 89b687e29ae1f428e7ebe912 + */ + date?: string; + /** + * @description Represents file identifier across the system. + * @example 745687e29ae1f428e7ebe890 + */ + fileId?: string; + /** + * @description Represents file name. + * @example expense_20200101 + */ + fileName?: string; + /** + * @description Represents expense identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id?: string; + isLocked?: boolean; + locked?: boolean; + /** + * @description Represents notes for an expense. + * @example This is a sample note for this expense. + */ + notes?: string; + project?: components['schemas']['ProjectInfoDto']; + /** + * Format: double + * @description Represents expense quantity as double data type. + */ + quantity?: number; + /** + * Format: double + * @description Represents expense total as double data type. + * @example 10500.5 + */ + total?: number; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + /** @description Represents a list of expense weekly total data transfer objects. */ + ExpenseWeeklyTotalsDtoV1: { + /** + * @description Represents a date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + date?: string; + /** + * Format: double + * @description Represents expense total. + * @example 20000.75 + */ + total?: number; + }; + ExpensesAndTotalsDtoV1: { + /** @description Represents a list of expense daily total data transfer objects. */ + dailyTotals?: components['schemas']['ExpenseDailyTotalsDtoV1'][]; + expenses?: components['schemas']['ExpensesWithCountDtoV1']; + /** @description Represents a list of expense weekly total data transfer objects. */ + weeklyTotals?: components['schemas']['ExpenseWeeklyTotalsDtoV1'][]; + }; + /** @description Represents an expense with count data transfer object. */ + ExpensesWithCountDtoV1: { + /** + * Format: int32 + * @description Represent result count. + * @example 25 + */ + count?: number; + /** @description Represent a list of hydrated expense objects. */ + expenses?: components['schemas']['ExpenseHydratedDtoV1'][]; + }; + /** + * @description Represents a list of features. + * @example [ + * "ADD_TIME_FOR_OTHERS", + * "ADMIN_PANEL", + * "ALERTS", + * "APPROVAL" + * ] + */ + Feature: + | 'ADD_TIME_FOR_OTHERS' + | 'ADMIN_PANEL' + | 'ALERTS' + | 'APPROVAL' + | 'AUDIT_LOG' + | 'AUTOMATIC_LOCK' + | 'BRANDED_REPORTS' + | 'BULK_EDIT' + | 'CUSTOM_FIELDS' + | 'CUSTOM_REPORTING' + | 'CUSTOM_SUBDOMAIN' + | 'DECIMAL_FORMAT' + | 'DISABLE_MANUAL_MODE' + | 'EDIT_MEMBER_PROFILE' + | 'EXCLUDE_NON_BILLABLE_FROM_ESTIMATE' + | 'EXPENSES' + | 'FILE_IMPORT' + | 'HIDE_PAGES' + | 'HISTORIC_RATES' + | 'INVOICING' + | 'INVOICE_EMAILS' + | 'LABOR_COST' + | 'LOCATIONS' + | 'MANAGER_ROLE' + | 'MULTI_FACTOR_AUTHENTICATION' + | 'PROJECT_BUDGET' + | 'PROJECT_TEMPLATES' + | 'QUICKBOOKS_INTEGRATION' + | 'RECURRING_ESTIMATES' + | 'REQUIRED_FIELDS' + | 'SCHEDULED_REPORTS' + | 'SCHEDULING' + | 'SCREENSHOTS' + | 'SSO' + | 'SUMMARY_ESTIMATE' + | 'TARGETS_AND_REMINDERS' + | 'TASK_RATES' + | 'TIME_OFF' + | 'UNLIMITED_REPORTS' + | 'USER_CUSTOM_FIELDS' + | 'WHO_CAN_CHANGE_TIMEENTRY_BILLABILITY' + | 'BREAKS' + | 'KIOSK_SESSION_DURATION' + | 'KIOSK_PIN_REQUIRED' + | 'WHO_CAN_SEE_ALL_TIME_ENTRIES' + | 'WHO_CAN_SEE_PROJECT_STATUS' + | 'WHO_CAN_SEE_PUBLIC_PROJECTS_ENTRIES' + | 'WHO_CAN_SEE_TEAMS_DASHBOARD' + | 'WORKSPACE_LOCK_TIMEENTRIES' + | 'WORKSPACE_TIME_AUDIT' + | 'WORKSPACE_TIME_ROUNDING' + | 'KIOSK' + | 'FORECASTING' + | 'TIME_TRACKING' + | 'ATTENDANCE_REPORT' + | 'CLIENT_CURRENCY'; + /** + * @description Represents a feature subscription type enum. + * @example PREMIUM + */ + FeatureSubscriptionType: { + featurePermissions?: ( + | 'ADD_TIME_FOR_OTHERS' + | 'ADMIN_PANEL' + | 'ALERTS' + | 'APPROVAL' + | 'AUDIT_LOG' + | 'AUTOMATIC_LOCK' + | 'BRANDED_REPORTS' + | 'BULK_EDIT' + | 'CUSTOM_FIELDS' + | 'CUSTOM_REPORTING' + | 'CUSTOM_SUBDOMAIN' + | 'DECIMAL_FORMAT' + | 'DISABLE_MANUAL_MODE' + | 'EDIT_MEMBER_PROFILE' + | 'EXCLUDE_NON_BILLABLE_FROM_ESTIMATE' + | 'EXPENSES' + | 'FILE_IMPORT' + | 'HIDE_PAGES' + | 'HISTORIC_RATES' + | 'INVOICING' + | 'INVOICE_EMAILS' + | 'LABOR_COST' + | 'LOCATIONS' + | 'MANAGER_ROLE' + | 'MULTI_FACTOR_AUTHENTICATION' + | 'PROJECT_BUDGET' + | 'PROJECT_TEMPLATES' + | 'QUICKBOOKS_INTEGRATION' + | 'RECURRING_ESTIMATES' + | 'REQUIRED_FIELDS' + | 'SCHEDULED_REPORTS' + | 'SCHEDULING' + | 'SCREENSHOTS' + | 'SSO' + | 'SUMMARY_ESTIMATE' + | 'TARGETS_AND_REMINDERS' + | 'TASK_RATES' + | 'TIME_OFF' + | 'UNLIMITED_REPORTS' + | 'USER_CUSTOM_FIELDS' + | 'WHO_CAN_CHANGE_TIMEENTRY_BILLABILITY' + | 'BREAKS' + | 'KIOSK_SESSION_DURATION' + | 'KIOSK_PIN_REQUIRED' + | 'WHO_CAN_SEE_ALL_TIME_ENTRIES' + | 'WHO_CAN_SEE_PROJECT_STATUS' + | 'WHO_CAN_SEE_PUBLIC_PROJECTS_ENTRIES' + | 'WHO_CAN_SEE_TEAMS_DASHBOARD' + | 'WORKSPACE_LOCK_TIMEENTRIES' + | 'WORKSPACE_TIME_AUDIT' + | 'WORKSPACE_TIME_ROUNDING' + | 'KIOSK' + | 'FORECASTING' + | 'TIME_TRACKING' + | 'ATTENDANCE_REPORT' + | 'CLIENT_CURRENCY' + )[]; + legacy?: boolean; + regionalAllowed?: boolean; + /** Format: int32 */ + weight?: number; + } & ( + | 'PREMIUM' + | 'PREMIUM_YEAR' + | 'SPECIAL' + | 'SPECIAL_YEAR' + | 'TRIAL' + | 'ENTERPRISE' + | 'ENTERPRISE_YEAR' + | 'BASIC_2021' + | 'BASIC_YEAR_2021' + | 'STANDARD_2021' + | 'STANDARD_YEAR_2021' + | 'PRO_2021' + | 'PRO_YEAR_2021' + | 'ENTERPRISE_2021' + | 'ENTERPRISE_YEAR_2021' + | 'SELF_HOSTED' + | 'FREE' + ); + GetUserTotalsRequestV1: { + /** + * Format: date-time + * @description Represents end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** + * Format: int32 + * @description page + * @example 1 + */ + page?: number; + /** Format: int32 */ + 'page-size'?: number; + /** + * Format: int32 + * @description page size + * @example 50 + */ + pageSize?: number; + regularUserFilter?: components['schemas']['ContainsUsersFilterRequest']; + regularUserGroupFilter?: components['schemas']['ContainsUserGroupFilterRequest']; + /** + * @description Represents search keyword + * @example keyword + */ + search?: string; + /** + * Format: date-time + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + userFilter?: components['schemas']['ContainsUsersFilterRequestV1']; + userGroupFilter?: components['schemas']['ContainsUserGroupFilterRequestV1']; + }; + GetUsersRequestV1: { + /** + * @description If provided, you'll get a filtered list of users that contain the provided string in their email address. + * @example mail@example.com + */ + email?: string; + /** @description If you pass along includeRoles=true, you'll get each user's detailed manager role (including projects and members for whom they're managers) */ + includeRoles?: boolean; + /** + * @description If provided, you'll get all users along with what workspaces, groups, or projects they have access to. Possible values: WORKSPACE, PROJECT, USERGROUP, NONE (default), ALL (only get basic data about users on the workpace) + * @example NONE + */ + memberships?: string; + /** + * @description If provided, you'll get a filtered list of users that contain the provided string in their name. + * @example John + */ + name?: string; + /** + * Format: int32 + * @description page + * @example 1 + */ + page?: number; + /** + * Format: int32 + * @description page size + * @example 50 + */ + pageSize?: number; + /** + * @description If provided, you'll get a list of users that have access to the project. + * @example 21a687e29ae1f428e7ebe606 + */ + projectId?: string; + /** + * @description If provided, you'll get a filtered list of users that have any of the specified roles. Owners are counted as admins when filtering. + * @example [ + * "WORKSPACE_ADMIN", + * "OWNER" + * ] + */ + roles?: ( + | 'WORKSPACE_ADMIN' + | 'OWNER' + | 'TEAM_MANAGER' + | 'PROJECT_MANAGER' + )[]; + /** + * @description Sorting criteria + * @example ID + * @enum {string} + */ + sortColumn?: + | 'ID' + | 'EMAIL' + | 'NAME' + | 'NAME_LOWERCASE' + | 'ACCESS' + | 'HOURLYRATE' + | 'COSTRATE'; + /** + * @description Sorting mode + * @example ASCENDING + * @enum {string} + */ + sortOrder?: 'ASCENDING' | 'DESCENDING'; + /** + * @description If provided, you'll get a filtered list of users with the corresponding status. + * @example ACTIVE + * @enum {string} + */ + status?: 'PENDING' | 'ACTIVE' | 'DECLINED' | 'INACTIVE' | 'ALL'; + /** + * @description If provided, you'll get a list of users that belong to the specified user group IDs. + * @example [ + * "5a0ab5acb07987125438b60f", + * "72wab5acb07987125438b564" + * ] + */ + userGroups?: string[]; + }; + /** @description Represents an hourly rate object. */ + HourlyRateDtoV1: { + /** + * Format: int32 + * @description Represents an amount as integer. + * @example 10500 + */ + amount?: number; + /** + * @description Represents a currency. + * @example USD + */ + currency?: string; + }; + /** @description Represents an hourly rate request object. */ + HourlyRateRequest: { + /** + * Format: int32 + * @description Represents a cost rate amount as integer. + * @example 20000 + */ + amount: number; + /** + * @description Represents a datetime in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + since?: string; + }; + HourlyRateRequestV1: { + /** + * Format: int32 + * @description Represents a cost rate amount as integer. + * @example 20000 + */ + amount: number; + /** + * @description Represents a datetime in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + since?: string; + }; + /** @description Represents an invoice default settings object. */ + InvoiceDefaultSettingsDto: { + /** + * @description Represents company identifier across the system. + * @example 34a687e29ae1f428e7ebe101 + */ + companyId?: string; + /** + * @description Represents item type identifier across the system. + * @example 88a687e29ae1f428e7ebe303 + */ + defaultImportExpenseItemTypeId?: string; + /** + * @description Represents item type identifier across the system. + * @example 18a687e29ae1f428e7ebe303 + */ + defaultImportTimeItemTypeId?: string; + /** + * Format: int32 + * @description Represents an invoice number of due days. + * @example 2 + */ + dueDays?: number; + itemType?: string; + /** + * @description Represents item type identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + itemTypeId?: string; + /** + * @description Represents an invoice note. + * @example This is a sample note for this invoice. + */ + notes?: string; + /** + * @description Represents an invoice subject. + * @example January salary + */ + subject?: string; + /** + * Format: int64 + * @deprecated + */ + tax?: number; + /** + * Format: int64 + * @deprecated + */ + tax2?: number; + /** + * Format: double + * @description Represents a tax amount in percentage. + * @example 1 + */ + tax2Percent?: number; + /** + * Format: double + * @description Represents a tax amount in percentage. + * @example 5 + */ + taxPercent?: number; + /** + * @description Represents a tax type. + * @example COMPOUND + * @enum {string} + */ + taxType?: 'COMPOUND' | 'SIMPLE' | 'NONE'; + }; + /** @description Represents an invoice default settings object. */ + InvoiceDefaultSettingsRequestV1: { + /** + * @description Represents company identifier across the system. + * @example 34a687e29ae1f428e7ebe101 + */ + companyId?: string; + /** + * Format: int32 + * @description Represents an invoice number of due days. + * @example 2 + */ + dueDays?: number; + /** + * @description Represents item type identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + itemTypeId?: string; + /** + * @description Represents an invoice note. + * @example This is a sample note for this invoice. + */ + notes: string; + /** + * @description Represents an invoice subject. + * @example January salary + */ + subject: string; + /** + * Format: double + * @description Represents a tax amount in percentage. + * @example 5 + */ + tax2Percent?: number; + /** + * Format: double + * @description Represents a tax amount in percentage. + * @example 5 + */ + taxPercent?: number; + /** + * @description Represents a tax type. + * @example COMPOUND + * @enum {string} + */ + taxType?: 'COMPOUND' | 'SIMPLE' | 'NONE'; + }; + /** @description Represents a list of invoices. */ + InvoiceDtoV1: { + /** + * Format: int64 + * @description Represents an invoice amount as long. + * @example 100 + */ + amount?: number; + /** + * Format: int64 + * @description Represents an invoice balance amount as long. + * @example 50 + */ + balance?: number; + /** + * @description Represents client identifier across the system. + * @example 98h687e29ae1f428e7ebe707 + */ + clientId?: string; + /** + * @description Represents client name for an invoice. + * @example Client X + */ + clientName?: string; + /** + * @description Represents the currency used by the invoice. + * @example USD + */ + currency?: string; + /** + * Format: date-time + * @description Represents an invoice due date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-06-01T08:00:00Z + */ + dueDate?: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * Format: date-time + * @description Represents an invoice issued date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + issuedDate?: string; + /** + * @description Represents an invoice number. + * @example 202306121129 + */ + number?: string; + /** + * Format: int64 + * @description Represents an invoice paid amount as long. + * @example 50 + */ + paid?: number; + /** + * @description Represents the status of an invoice. + * @example PAID + * @enum {string} + */ + status?: + | 'UNSENT' + | 'SENT' + | 'PAID' + | 'PARTIALLY_PAID' + | 'VOID' + | 'OVERDUE'; + }; + /** @description Represents an invoice export fields object. */ + InvoiceExportFields: { + RTL?: boolean; + itemType?: boolean; + quantity?: boolean; + rtl?: boolean; + unitPrice?: boolean; + }; + /** @description Represents an invoice export fields object. */ + InvoiceExportFieldsRequest: { + RTL?: boolean; + /** @description Indicates whether to export item type. */ + itemType?: boolean; + /** @description Indicates whether to export quantity. */ + quantity?: boolean; + rtl?: boolean; + /** @description Indicates whether to export unit price. */ + unitPrice?: boolean; + }; + InvoiceFilterRequestV1: { + clients?: components['schemas']['ContainsClientsFilterRequest']; + companies?: components['schemas']['ContainsCompaniesFilterRequest']; + /** Format: int64 */ + 'exact-amount'?: number; + /** Format: int64 */ + 'exact-balance'?: number; + /** + * Format: int64 + * @description Represents an invoice balance. If provided, you'll get a filtered list of invoices that has the equal balance as specified. + * @example 1000 + */ + exactBalance?: number; + /** Format: int64 */ + 'greater-than-amount'?: number; + /** Format: int64 */ + 'greater-than-balance'?: number; + /** + * Format: int64 + * @description Represents an invoice balance. If provided, you'll get a filtered list of invoices that has balance greater than specified. + * @example 500 + */ + greaterThanBalance?: number; + 'invoice-number'?: string; + 'issue-date'?: components['schemas']['TimeRangeRequest']; + /** Format: int64 */ + 'less-than-amount'?: number; + /** Format: int64 */ + 'less-than-balance'?: number; + /** + * Format: int64 + * @description Represents an invoice balance. If provided, you'll get a filtered list of invoices that has balance less than specified. + * @example 500 + */ + lessThanBalance?: number; + /** + * Format: int32 + * @description page + * @example 1 + */ + page: number; + /** Format: int32 */ + 'page-size'?: number; + 'sort-column'?: string; + 'sort-order'?: string; + statuses?: components['schemas']['InvoiceStatus']; + 'strict-id-search'?: boolean; + }; + InvoiceInfoResponseDtoV1: { + /** @description Represents a list of invoice info. */ + invoices?: components['schemas']['InvoiceInfoV1'][]; + /** + * Format: int64 + * @description Represents the total invoice count. + * @example 100 + */ + total?: number; + }; + /** @description Represents a list of invoice info. */ + InvoiceInfoV1: { + /** + * Format: int64 + * @description Represents an invoice amount as long. + * @example 100 + */ + amount?: number; + /** + * Format: int64 + * @description Represents an invoice balance amount as long. + * @example 50 + */ + balance?: number; + /** + * @description Represents to whom an invoice is billed from. + * @example Company XYZ + */ + billFrom?: string; + /** + * @description Represents client identifier across the system. + * @example 98h687e29ae1f428e7ebe707 + */ + clientId?: string; + /** + * @description Represents client name for an invoice. + * @example Client X + */ + clientName?: string; + /** + * @description Represents the currency used by the invoice. + * @example USD + */ + currency?: string; + /** + * Format: int64 + * @description Represents the number of days an invoice is overdue. + * @example 10 + */ + daysOverdue?: number; + /** + * Format: date-time + * @description Represents an invoice due date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-06-01T08:00:00Z + */ + dueDate?: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * Format: date-time + * @description Represents an invoice issued date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + issuedDate?: string; + /** + * @description Represents an invoice number. + * @example 202306121129 + */ + number?: string; + /** + * Format: int64 + * @description Represents an invoice paid amount as long. + * @example 50 + */ + paid?: number; + /** + * @description Represents the status of an invoice. + * @example PAID + * @enum {string} + */ + status?: + | 'UNSENT' + | 'SENT' + | 'PAID' + | 'PARTIALLY_PAID' + | 'VOID' + | 'OVERDUE'; + visibleZeroFields?: components['schemas']['VisibleZeroFieldsInvoice']; + }; + /** @description Represents a list of invoice item datatransfer objects. */ + InvoiceItemDto: { + /** + * Format: int64 + * @description Represents item amount. + * @example 5000 + */ + amount?: number; + /** + * @description Represents an invoice item description. + * @example This is a description of an invoice item. + */ + description?: string; + /** + * @description Represents item type. + * @example Goods + */ + itemType?: string; + /** + * Format: int32 + * @description Represents an integer. + * @example 100 + */ + order?: number; + /** + * Format: int64 + * @description Represents item quantity. + * @example 10 + */ + quantity?: number; + /** + * @description Represents a list of time entrry IDs. + * @example [ + * "5b715448b0798751107918ab", + * "5b641568b07987035750505e" + * ] + */ + timeEntryIds?: string[]; + /** + * Format: int64 + * @description Represents item unit price. + * @example 500 + */ + unitPrice?: number; + }; + InvoiceOverviewDtoV1: { + /** + * Format: int64 + * @description Represents an invoice amount as long. + * @example 100 + */ + amount?: number; + /** + * Format: int64 + * @description Represents an invoice balance amount as long. + * @example 50 + */ + balance?: number; + /** + * @description Represents to whom the invoice should be billed from. + * @example Business X + */ + billFrom?: string; + /** + * @description Represents client address. + * @example Ground Floor, ABC Bldg., Palo Alto, California, USA 94020 + */ + clientAddress?: string; + /** + * @description Represents client identifier across the system. + * @example 98h687e29ae1f428e7ebe707 + */ + clientId?: string; + /** + * @description Represents client name for an invoice. + * @example Client X + */ + clientName?: string; + /** + * @description Represents company identifier across the system. + * @example 04g687e29ae1f428e7ebe123 + */ + companyId?: string; + /** @description Indicates whether invoice contains imported expenses. */ + containsImportedExpenses?: boolean; + /** @description Indicates whether invoice contains imported items. */ + containsImportedTimes?: boolean; + /** + * @description Represents the currency used by the invoice. + * @example USD + */ + currency?: string; + /** + * Format: double + * @description Represents an invoice discount amount as double. + * @example 10.5 + */ + discount?: number; + /** + * Format: int64 + * @description Represents an invoice discount amount as long. + * @example 11 + */ + discountAmount?: number; + /** + * Format: date-time + * @description Represents an invoice due date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-06-01T08:00:00Z + */ + dueDate?: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * Format: date-time + * @description Represents an invoice issued date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + issuedDate?: string; + /** @description Represents a list of invoice item datatransfer objects. */ + items?: components['schemas']['InvoiceItemDto'][]; + /** + * @description Represents an invoice note. + * @example This is a sample note for this invoice. + */ + note?: string; + /** + * @description Represents an invoice number. + * @example 202306121129 + */ + number?: string; + /** + * Format: int64 + * @description Represents an invoice paid amount as long. + * @example 50 + */ + paid?: number; + /** + * @description Represents the status of an invoice. + * @example PAID + * @enum {string} + */ + status?: + | 'UNSENT' + | 'SENT' + | 'PAID' + | 'PARTIALLY_PAID' + | 'VOID' + | 'OVERDUE'; + /** + * @description Represents an invoice subject. + * @example January salary + */ + subject?: string; + /** + * Format: int64 + * @description Represents an invoice subtotal as long. + * @example 5000 + */ + subtotal?: number; + /** + * Format: double + * @description Represents an invoice tax amount as double. + * @example 1.5 + */ + tax?: number; + /** + * Format: double + * @description Represents an invoice tax amount as double. + * @example 0 + */ + tax2?: number; + /** + * Format: int64 + * @description Represents an invoice tax amount as long. + * @example 0 + */ + tax2Amount?: number; + /** + * Format: int64 + * @description Represents an invoice tax amount as long. + * @example 1 + */ + taxAmount?: number; + /** + * @description Represents user identifier across the system. + * @example 12t687e29ae1f428e7ebe202 + */ + userId?: string; + visibleZeroFields?: components['schemas']['VisibleZeroFieldsInvoice']; + }; + InvoicePaymentDtoV1: { + /** + * Format: int64 + * @description Represents an invoice payment amount as long. + * @example 100 + */ + amount?: number; + /** + * @description Represents an invoice payment author. + * @example John Doe + */ + author?: string; + /** + * Format: date-time + * @description Represents an invoice payment date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T12:00:00Z + */ + date?: string; + /** + * @description Represents invoice payment identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * @description Represents an invoice payment note. + * @example This is a sample note for this invoice payment. + */ + note?: string; + }; + InvoiceSettingsDtoV1: { + defaults?: components['schemas']['InvoiceDefaultSettingsDto']; + exportFields?: components['schemas']['InvoiceExportFields']; + labels?: components['schemas']['LabelsCustomization']; + }; + /** + * @description Represents a list of invoice statuses. If provided, you'll get a filtered list of invoices that matches any of the invoice status provided. + * @example [ + * "SENT", + * "PAID", + * "PARTIALLY_PAID" + * ] + */ + InvoiceStatus: { + sent?: boolean; + unsent?: boolean; + void?: boolean; + } & ('UNSENT' | 'SENT' | 'PAID' | 'PARTIALLY_PAID' | 'VOID' | 'OVERDUE'); + InvoicesListDtoV1: { + /** @description Represents a list of invoices. */ + invoices?: components['schemas']['InvoiceDtoV1'][]; + /** + * Format: int64 + * @description Represents the total invoice count. + * @example 100 + */ + total?: number; + }; + /** @description Represents a label customization object. */ + LabelsCustomization: { + /** + * @description Represents invoice amount. + * @example 1000 + */ + amount?: string; + /** + * @description Represents a string an invoice is billed from. + * @example Entity A + */ + billFrom?: string; + /** + * @description Represents a string an invoice is billed to. + * @example Entity B + */ + billTo?: string; + /** + * @description Represents a description of an invoice. + * @example This is a sample description for this invoice. + */ + description?: string; + /** + * @description Represents invoice discount amount. + * @example 0 + */ + discount?: string; + /** + * @description Represents a due date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + dueDate?: string; + /** + * @description Represents an issue date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + issueDate?: string; + /** + * @description Represents an item type. + * @example Service + */ + itemType?: string; + /** + * @description Represents notes for an invoice. + * @example This is a sample note for this invoice. + */ + notes?: string; + /** + * @description Represents invoice paid amount. + * @example 1000 + */ + paid?: string; + /** + * @description Represents quantity. + * @example 10 + */ + quantity?: string; + /** + * @description Represents invoice subtotal. + * @example 1000 + */ + subtotal?: string; + /** + * @description Represents invoice tax amount. + * @example 10 + */ + tax?: string; + /** + * @description Represents invoice tax amount. + * @example 0 + */ + tax2?: string; + /** + * @description Represents invoice total amount. + * @example 1010 + */ + total?: string; + /** + * @description Represents invoice total amount. + * @example 1010 + */ + totalAmount?: string; + /** + * @description Represents unit price. + * @example 100 + */ + unitPrice?: string; + }; + /** @description Represents a label customization object. */ + LabelsCustomizationRequest: { + /** + * @description Represents invoice amount. + * @example 1000 + */ + amount?: string; + /** + * @description Represents a string an invoice is billed from. + * @example Entity A + */ + billFrom?: string; + /** + * @description Represents a string an invoice is billed to. + * @example Entity B + */ + billTo?: string; + /** + * @description Represents a description of an invoice. + * @example This is a sample description for this invoice. + */ + description?: string; + /** + * @description Represents invoice discount amount. + * @example 0 + */ + discount?: string; + /** + * @description Represents a due date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + dueDate?: string; + /** + * @description Represents an issue date in yyyy-MM-dd format. + * @example 2020-01-01 + */ + issueDate?: string; + /** + * @description Represents an item type. + * @example Service + */ + itemType?: string; + /** + * @description Represents notes for an invoice. + * @example This is a sample note for this invoice. + */ + notes?: string; + /** + * @description Represents invoice paid amount. + * @example 1000 + */ + paid?: string; + /** + * @description Represents quantity. + * @example 10 + */ + quantity?: string; + /** + * @description Represents invoice subtotal. + * @example 1000 + */ + subtotal?: string; + /** + * @description Represents invoice tax amount. + * @example 10 + */ + tax?: string; + /** + * @description Represents invoice tax amount. + * @example 0 + */ + tax2?: string; + total?: string; + /** + * @description Represents invoice total amount. + * @example 1010 + */ + totalAmount?: string; + /** + * @description Represents invoice total amount due. + * @example 10 + */ + totalAmountDue?: string; + /** + * @description Represents unit price. + * @example 100 + */ + unitPrice?: string; + }; + MemberProfileDtoV1: { + /** + * @description Represents email address of the user. + * @example johndoe@example.com + */ + email?: string; + /** @description Indicates whether user has password or none. */ + hasPassword?: boolean; + /** @description Indicates whether user has pending approval request. */ + hasPendingApprovalRequest?: boolean; + /** + * @description Represents an image url. + * @example https://www.url.com/imageurl-1234567890.jpg + */ + imageUrl?: string; + /** + * @description Represents name of the user. + * @example John Doe + */ + name?: string; + /** @description Represents a list of user custom field value objects. */ + userCustomFieldValues?: components['schemas']['UserCustomFieldValueFullDtoV1'][]; + /** + * @description Represents a day of the week. + * @example MONDAY + */ + weekStart?: { + /** Format: int32 */ + value?: number; + } & ( + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY' + ); + workCapacity?: string; + /** + * @description Represents a list of days of the week. + * @example [ + * "MONDAY", + * "TUESDAY", + * "WEDNESDAY", + * "THURSDAY", + * "FRIDAY" + * ] + */ + workingDays?: { + /** Format: int32 */ + value?: number; + } & ( + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY' + ); + /** + * Format: int32 + * @description Represents the number of workspace(s) the user is associated to. + * @example 3 + */ + workspaceNumber?: number; + }; + MemberProfileFullRequestV1: { + /** + * @description Represents an image url. + * @example https://www.url.com/imageurl-1234567890.jpg + */ + imageUrl?: string; + /** + * @description Represents name of the user. + * @example John Doe + */ + name?: string; + /** @description Indicates whether to remove profile image or not. */ + removeProfileImage?: boolean; + /** @description Represents a list of upsert user custom field objects. */ + userCustomFields?: components['schemas']['UpsertUserCustomFieldRequest'][]; + /** + * @description Represents a day of the week. + * @example MONDAY + * @enum {string} + */ + weekStart?: + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY'; + /** + * @description Represents work capacity as duration. + * @example 50000 + */ + workCapacity?: string; + /** + * @description Represents a list of days of the week. + * @example [ + * "MONDAY", + * "TUESDAY", + * "WEDNESDAY", + * "THURSDAY", + * "FRIDAY" + * ] + */ + workingDays?: { + /** Format: int32 */ + value?: number; + } & ( + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY' + ); + }; + /** @description Represents a list of membership objects. */ + MembershipDtoV1: { + costRate?: components['schemas']['RateDtoV1']; + hourlyRate?: components['schemas']['HourlyRateDtoV1']; + /** + * @description Represents a membership status enum. + * @example PENDING + * @enum {string} + */ + membershipStatus?: 'PENDING' | 'ACTIVE' | 'DECLINED' | 'INACTIVE' | 'ALL'; + /** + * @description Represents membership type enum. + * @example PROJECT + * @enum {string} + */ + membershipType?: 'WORKSPACE' | 'PROJECT' | 'USERGROUP'; + /** + * @description Represents target identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + targetId?: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + }; + /** @description Represents a list of membership request objects. */ + MembershipRequest: { + hourlyRate?: components['schemas']['HourlyRateRequest']; + /** + * @description Represents a membership status enum. + * @example PENDING + * @enum {string} + */ + membershipStatus?: 'PENDING' | 'ACTIVE' | 'DECLINED' | 'INACTIVE' | 'ALL'; + /** + * @description Represents membership type enum. + * @example PROJECT + * @enum {string} + */ + membershipType?: 'WORKSPACE' | 'PROJECT' | 'USERGROUP'; + /** + * @description Represents target identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + targetId?: string; + /** + * @description Represents user identifier across the system. + * @example 12t687e29ae1f428e7ebe202 + */ + userId?: string; + }; + /** @description Represents a list of milestone objects. */ + MilestoneDto: { + /** + * Format: date-time + * @description Represents a date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + date?: string; + /** + * @description Represents milestone identifier across the system. + * @example 34a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * @description Represents milestone name. + * @example Q3 + */ + name?: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + PatchProjectTemplateRequest: { + /** @description Indicates whether project is a template or not. */ + isTemplate?: boolean; + template?: boolean; + }; + ProjectDtoImplV1: { + /** @description Indicates whether project is archived or not. */ + archived?: boolean; + /** @description Indicates whether project is billable or not. */ + billable?: boolean; + budgetEstimate?: components['schemas']['EstimateWithOptionsDto']; + /** + * @description Represents client identifier across the system. + * @example 9t641568b07987035750704 + */ + clientId?: string; + /** + * @description Represents client name. + * @example Client X + */ + clientName?: string; + /** + * @description Color format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #000000 + */ + color?: string; + costRate?: components['schemas']['RateDtoV1']; + /** + * @description Represents project duration in milliseconds. + * @example 60000 + */ + duration?: string; + estimate?: components['schemas']['EstimateDtoV1']; + hourlyRate?: components['schemas']['RateDtoV1']; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + id?: string; + isPublic?: boolean; + isTemplate?: boolean; + /** @description Represents a list of membership objects. */ + memberships?: components['schemas']['MembershipDtoV1'][]; + /** + * @description Represents a project name. + * @example Software Development + */ + name?: string; + /** + * @description Represents project note. + * @example This is a sample note for the project. + */ + note?: string; + /** @description Indicates whether project is public or not. */ + public?: boolean; + template?: boolean; + timeEstimate?: components['schemas']['TimeEstimateDto']; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + ProjectDtoV1: { + /** + * @description Color format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #000000 + */ + color?: string; + /** + * @description Represents project duration in milliseconds. + * @example 60000 + */ + duration?: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + id?: string; + /** @description Represents a list of membership objects. */ + memberships?: components['schemas']['MembershipDtoV1'][]; + /** + * @description Represents a project name. + * @example Software Development + */ + name?: string; + /** + * @description Represents project note. + * @example This is a sample note for the project. + */ + note?: string; + /** @description Indicates whether project is public or not. */ + public?: boolean; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + ProjectEstimateRequest: { + budgetEstimate?: components['schemas']['EstimateWithOptionsRequest']; + estimateReset?: components['schemas']['EstimateResetRequest']; + timeEstimate?: components['schemas']['TimeEstimateRequest']; + }; + /** @description Represents project info object. */ + ProjectInfoDto: { + /** + * @description Represents client identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + clientId?: string; + /** + * @description Represents client name. + * @example Client X + */ + clientName?: string; + /** + * @description Color format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #000000 + */ + color?: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + id?: string; + /** + * @description Represents a project name. + * @example Software Development + */ + name?: string; + }; + ProjectRequest: { + /** @description Indicates whether project is billable or not. */ + billable?: boolean; + /** + * @description Represents client identifier across the system. + * @example 9t641568b07987035750704 + */ + clientId?: string; + /** + * @description Color format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #000000 + */ + color?: string; + estimate?: components['schemas']['EstimateRequest']; + hourlyRate?: components['schemas']['HourlyRateRequestV1']; + /** @description Indicates whether project is public or not. */ + isPublic?: boolean; + /** @description Represents a list of membership request objects. */ + memberships?: components['schemas']['MembershipRequest'][]; + /** + * @description Represents a project name. + * @example Software Development + */ + name: string; + /** + * @description Represents project note. + * @example This is a sample note for the project. + */ + note?: string; + /** @description Represents a list of task request objects. */ + tasks?: components['schemas']['TaskRequest'][]; + }; + PublishAssignmentsRequestV1: { + /** + * @description Represents end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** @description Indicates whether to notify users when assignment is published. */ + notifyUsers?: boolean; + regularUserFilter?: components['schemas']['ContainsUsersFilterRequest']; + regularUserGroupFilter?: components['schemas']['ContainsUserGroupFilterRequest']; + /** + * @description Represents a search string. + * @example search keyword + */ + search?: string; + /** + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + userFilter?: components['schemas']['ContainsUsersFilterRequestV1']; + userGroupFilter?: components['schemas']['ContainsUserGroupFilterRequestV1']; + /** + * @description Represents a view type enum. + * @example PROJECTS + * @enum {string} + */ + viewType?: 'PROJECTS' | 'TEAM' | 'ALL'; + }; + /** @description Represents cost rate object. */ + RateDto: { + /** + * Format: int32 + * @description Represents an amount as integer. + * @example 10500 + */ + amount?: number; + /** + * @description Represents a currency. + * @example USD + */ + currency?: string; + }; + /** @description Represents a cost rate object. */ + RateDtoV1: { + /** + * Format: int32 + * @description Represents an amount as integer. + * @example 10500 + */ + amount?: number; + /** + * @description Represents a currency. + * @example USD + */ + currency?: string; + }; + RateWithCurrencyRequestV1: { + /** + * Format: int32 + * @description Represents an amount as integer. + * @example 2000 + */ + amount: number; + /** + * @description Represents a currency. Default value is "USD". + * @example USD + */ + currency: string; + /** + * @description Represents a datetime in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + since?: string; + }; + /** @description Represents recurring assignment object. */ + RecurringAssignmentDto: { + /** @description Indicates whether assignment is recurring or not. */ + repeat?: boolean; + /** + * @description Represents series identifier. + * @example 64c777ddd3fcab07cfbb210c + */ + seriesId?: string; + /** + * Format: int32 + * @description Represents number of weeks for thhis assignment. + * @example 5 + */ + weeks?: number; + }; + RecurringAssignmentRequest: { + /** @description Indicates whether assignment is recurring or not. */ + repeat?: boolean; + /** + * Format: int32 + * @description Indicates number of weeks for assignment. + * @example 5 + */ + weeks?: number; + }; + RecurringAssignmentRequestV1: { + /** @description Indicates whether assignment is recurring or not. */ + repeat?: boolean; + /** + * Format: int32 + * @description Indicates number of weeks for assignment. + * @example 5 + */ + weeks?: number; + }; + RoleDetailsDtoV1: { + role?: components['schemas']['RoleDtoV1']; + /** + * @description Represents workspace identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + /** @description Represents a role data transfer object. */ + RoleDtoV1: { + /** + * @description Represents role identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + id?: string; + /** + * @description Represents a role name. + * @example Administrator + */ + name?: string; + source?: components['schemas']['AuthorizationSourceDtoV1']; + }; + RoleRequestV1: { + /** + * @description Represents entity identifier across the system. + * @example 60f924bafdaf031696ec6218 + */ + entityId: string; + /** + * @description Represents a valid role enum. + * @example WORKSPACE_ADMIN + * @enum {string} + */ + role?: 'WORKSPACE_ADMIN' | 'TEAM_MANAGER' | 'PROJECT_MANAGER'; + /** @enum {string} */ + sourceType?: 'USER_GROUP'; + }; + /** @description Represents a time rounding object. */ + RoundDto: { + minutes?: string; + round?: string; + }; + /** @description Represents a list of excluded days objects */ + SchedulingExcludeDay: { + /** + * Format: date-time + * @description Represents a datetimr in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + date?: string; + /** + * @description Represents the scheduling exclude day enum. + * @example WEEKEND + * @enum {string} + */ + type?: 'WEEKEND' | 'HOLIDAY' | 'TIME_OFF'; + }; + SchedulingProjectsTotalsDtoV1: { + /** @description Represents a list of assignment per day objects. */ + assignments?: components['schemas']['AssignmentPerDayDto'][]; + /** + * @description Represents project name. + * @example Software Development + */ + clientName?: string; + /** @description Represents a list of milestone objects. */ + milestones?: components['schemas']['MilestoneDto'][]; + /** @description Indicates whether project is archived or not. */ + projectArchived?: boolean; + /** @description Indicates whether project is billable or not. */ + projectBillable?: boolean; + /** + * @description Color format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #000000 + */ + projectColor?: string; + /** + * @description Represents project identifier across the system. + * @example 56b687e29ae1f428e7ebe504 + */ + projectId?: string; + /** + * @description Represents project name. + * @example Software Development + */ + projectName?: string; + /** + * Format: double + * @description Represents project total hours as double. + * @example 490.5 + */ + totalHours?: number; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + SchedulingUsersTotalsDtoV1: { + /** + * Format: double + * @description Represents capacity per day in hours. + * @example 7.5 + */ + capacityPerDay?: number; + /** @description Represents total hours per day object. */ + totalHoursPerDay?: components['schemas']['TotalHoursPerDayDto'][]; + /** + * @description Represents user identifier across the system. + * @example 72k687e29ae1f428e7ebe109 + */ + userId?: string; + /** @description Represents url path to user image. */ + userImage?: string; + /** + * @description Represents user name. + * @example John Doe + */ + userName?: string; + /** + * @description Represents user status. + * @example ACTIVE + */ + userStatus?: string; + /** + * @description Represents list of days of the week. + * @example [ + * "MONDAY", + * "TUESDAY", + * "WEDNESDAY", + * "THURSDAY", + * "FRIDAY" + * ] + */ + workingDays?: { + /** Format: int32 */ + value?: number; + } & ( + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY' + ); + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + StopTimeEntryRequest: { + /** + * Format: date-time + * @description Represents an end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + }; + /** @description Represents a summary report settings object. */ + SummaryReportSettingsDtoV1: { + /** @example PROJECT */ + group: string; + /** @example CLIENT */ + subgroup: string; + }; + /** @description Represents a list of tag objects. */ + TagDto: { + /** @description Indicates whether tag is archived or not. */ + archived?: boolean; + /** + * @description Represents tag identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id?: string; + /** + * @description Represents tag name. + * @example Sprint1 + */ + name?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + TagDtoV1: { + /** @description Indicates whether a tag is archived or not. */ + archived?: boolean; + /** + * @description Represents tag identifier across the system. + * @example 21s687e29ae1f428e7ebe404 + */ + id?: string; + /** + * @description Represents tag name. + * @example Sprint1 + */ + name?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + TagRequest: { + /** + * @description Represents tag name. + * @example Sprint1 + */ + name: string; + }; + TaskDtoV1: { + /** @deprecated */ + assigneeId?: string; + /** + * @description Represents list of assignee ids for the task. + * @example [ + * "45b687e29ae1f428e7ebe123", + * "67s687e29ae1f428e7ebe678" + * ] + */ + assigneeIds?: string[]; + /** @description Indicates whether a task is billable or not. */ + billable?: boolean; + /** + * Format: int64 + * @description Represents a task budget estimate as long. + * @example 10000 + */ + budgetEstimate?: number; + costRate?: components['schemas']['RateDtoV1']; + /** + * @description Represents a task duration. + * @example PT1H30M + */ + duration?: string; + /** + * @description Represents a task duration estimate. + * @example PT1H30M + */ + estimate?: string; + hourlyRate?: components['schemas']['RateDtoV1']; + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + id?: string; + /** + * @description Represents task name. + * @example Bugfixing + */ + name?: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + status?: components['schemas']['TaskStatus']; + /** + * @description Represents list of user group ids for the task. + * @example [ + * "67b687e29ae1f428e7ebe123", + * "12s687e29ae1f428e7ebe678" + * ] + */ + userGroupIds?: string[]; + }; + /** @description Represents a task object. */ + TaskInfoDto: { + /** + * @description Represents task identifier across the system. + * @example 5b715448b0798751107918ab + */ + id?: string; + /** + * @description Represents task name. + * @example Bugfixing + */ + name?: string; + }; + /** @description Represents a list of task request objects. */ + TaskRequest: { + assigneeId?: string; + /** + * @description Represents list of assignee ids for the task. + * @example [ + * "45b687e29ae1f428e7ebe123", + * "67s687e29ae1f428e7ebe678" + * ] + */ + assigneeIds?: string[]; + /** @description Flag to set whether task is billable or not */ + billable?: boolean; + /** + * Format: int64 + * @example 10000 + */ + budgetEstimate?: number; + costRate?: components['schemas']['CostRateRequest']; + /** + * @description Represents a task duration estimate. + * @example PT1H30M + */ + estimate?: string; + hourlyRate?: components['schemas']['HourlyRateRequest']; + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + id?: string; + /** + * @description Represents task name. + * @example Bugfixing + */ + name: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId?: string; + /** @example DONE */ + status?: string; + /** + * @description Represents list of user group ids for the task. + * @example [ + * "67b687e29ae1f428e7ebe123", + * "12s687e29ae1f428e7ebe678" + * ] + */ + userGroupIds?: string[]; + }; + TaskRequestV1: { + assigneeId?: string; + /** + * @description Represents list of assignee ids for the task. + * @example [ + * "45b687e29ae1f428e7ebe123", + * "67s687e29ae1f428e7ebe678" + * ] + */ + assigneeIds?: string[]; + /** + * Format: int64 + * @example 10000 + */ + budgetEstimate?: number; + /** + * @description Represents a task duration estimate. + * @example PT1H30M + */ + estimate?: string; + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + id?: string; + /** + * @description Represents task name. + * @example Bugfixing + */ + name: string; + /** @example DONE */ + status?: string; + /** @enum {string} */ + statusEnum?: 'ACTIVE' | 'DONE' | 'ALL'; + /** + * @description Represents list of user group ids for the task. + * @example [ + * "67b687e29ae1f428e7ebe123", + * "12s687e29ae1f428e7ebe678" + * ] + */ + userGroupIds?: string[]; + }; + /** + * @description Represents task status enum. + * @example DONE + */ + TaskStatus: { + active?: boolean; + } & ('ACTIVE' | 'DONE' | 'ALL'); + TimeEntryDtoImplV1: { + /** @description Indicates whether a time entry is billable or not. */ + billable?: boolean; + /** @description Represents a list of custom field value objects. */ + customFieldValues?: components['schemas']['CustomFieldValueDtoV1'][]; + /** + * @description Represents time entry description. + * @example This is a sample time entry description. + */ + description?: string; + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id?: string; + isLocked?: boolean; + /** + * @description Represents a kiosk identifier across the system. + * @example 94c777ddd3fcab07cfbb210d + */ + kioskId?: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + /** + * @description Represents a list of tag ids. + * @example [ + * "321r77ddd3fcab07cfbb567y", + * "44x777ddd3fcab07cfbb88f" + * ] + */ + tagIds?: string[]; + /** + * @description Represents task identifier across the system. + * @example 54m377ddd3fcab07cfbb432w + */ + taskId?: string; + timeInterval?: components['schemas']['TimeIntervalDtoV1']; + /** + * @description Represents a time entry type enum. + * @example BREAK + * @enum {string} + */ + type?: 'REGULAR' | 'BREAK' | 'HOLIDAY' | 'TIME_OFF'; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + TimeEntryDtoV1: { + billable?: boolean; + customFieldValues?: components['schemas']['CustomFieldValueDtoV1'][]; + description?: string; + id?: string; + isLocked?: boolean; + kioskId?: string; + projectId?: string; + tagIds?: string[]; + taskId?: string; + timeInterval?: components['schemas']['TimeIntervalDtoV1']; + type?: string; + userId?: string; + workspaceId?: string; + }; + /** + * @description Represents a list of invoiced time entry ids + * @example [ + * "54m377ddd3fcab07cfbb432w", + * "25b687e29ae1f428e7ebe123" + * ] + */ + TimeEntryId: { + id?: string; + }; + /** @description Represents a list of time entry info data transfer objects. */ + TimeEntryInfoDto: { + /** + * @description Represents approval identifier across the system. + * @example 5e4117fe8c625f38930d57b7 + */ + approvalRequestId?: string; + /** @description Indicates whether time entry is billable or not. */ + billable?: boolean; + costRate?: components['schemas']['RateDto']; + /** @description Represents a list of custom field value objects. */ + customFieldValues?: components['schemas']['CustomFieldValueDto'][]; + /** + * @description Represents a time entry description. + * @example This is a sample time entry description. + */ + description?: string; + hourlyRate?: components['schemas']['RateDto']; + /** + * @description Represents time entry identifier across the system. + * @example 5b715448b0798751107918ab + */ + id?: string; + /** @description Indicates whether time entry is locked or not. */ + isLocked?: boolean; + project?: components['schemas']['ProjectInfoDto']; + /** @description Represents a list of tag objects. */ + tags?: components['schemas']['TagDto'][]; + task?: components['schemas']['TaskInfoDto']; + timeInterval?: components['schemas']['TimeIntervalDto']; + /** + * @description Represents a time entry type enum. + * @example REGULAR + * @enum {string} + */ + type?: 'REGULAR' | 'BREAK' | 'HOLIDAY' | 'TIME_OFF'; + }; + TimeEntryWithRatesDtoV1: { + billable?: boolean; + costRate?: components['schemas']['RateDtoV1']; + customFieldValues?: components['schemas']['CustomFieldValueDtoV1'][]; + description?: string; + hourlyRate?: components['schemas']['RateDtoV1']; + id?: string; + isLocked?: boolean; + kioskId?: string; + projectId?: string; + tagIds?: string[]; + taskId?: string; + timeInterval?: components['schemas']['TimeIntervalDtoV1']; + type?: string; + userId?: string; + workspaceId?: string; + }; + /** @description Represents project time estimate object. */ + TimeEstimateDto: { + active?: boolean; + /** + * @description Represents project duration in milliseconds. + * @example 60000 + */ + estimate?: string; + includeNonBillable?: boolean; + /** + * @description Represents a reset option enum. + * @example WEEKLY + * @enum {string} + */ + resetOption?: 'WEEKLY' | 'MONTHLY' | 'YEARLY'; + /** + * @description Represents an estimate type enum. + * @example AUTO + * @enum {string} + */ + type?: 'AUTO' | 'MANUAL'; + }; + /** @description Represents project time estimate request object. */ + TimeEstimateRequest: { + active?: boolean; + /** + * Format: int64 + * @description Represents a time duration. + */ + estimate?: number; + includeNonBillable?: boolean; + /** + * @description Represents a reset option enum. + * @example MONTHLY + * @enum {string} + */ + resetOption?: 'WEEKLY' | 'MONTHLY' | 'YEARLY'; + /** + * @description Represents an estimate type enum. + * @example AUTO + * @enum {string} + */ + type?: 'AUTO' | 'MANUAL'; + }; + /** @description Represents a time interval object. */ + TimeIntervalDto: { + /** + * @description Represents a time duration. + * @example PT1H30M + */ + duration?: string; + /** Format: date-time */ + end?: string; + /** Format: date-time */ + start?: string; + }; + TimeIntervalDtoV1: { + /** + * @description Represents a time duration. + * @example 8000 + */ + duration?: string; + /** + * Format: date-time + * @description Represents an end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** + * Format: date-time + * @description Represents a start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + }; + TimeRangeRequest: { + 'issue-date-end'?: string; + 'issue-date-start'?: string; + }; + /** @description Represents total hours per day object. */ + TotalHoursPerDayDto: { + /** Format: date-time */ + date?: string; + /** Format: double */ + totalHours?: number; + }; + UpdateApprovalRequest: { + /** + * @description Additional notes for the approval request. + * @example This is a sample note. + */ + note?: string; + /** + * @description Specifies the approval state to set. + * @example PENDING + * @enum {string} + */ + state?: + | 'PENDING' + | 'APPROVED' + | 'WITHDRAWN_SUBMISSION' + | 'WITHDRAWN_APPROVAL' + | 'REJECTED'; + }; + UpdateClientRequestV1: { + /** + * @description Represents client's address. + * @example Ground Floor, ABC Bldg., Palo Alto, California, USA 94020 + */ + address?: string; + /** @description Indicates if client will be archived or not. */ + archived?: boolean; + /** + * @description Represents currency identifier across the system.a record in the database. + * @example 53a687e29ae1f428e7ebe888 + */ + currencyId?: string; + /** + * @description Represents client email. + * @example clientx@example.com + */ + email?: string; + /** + * @description Represents client name. + * @example Client X + */ + name: string; + /** + * @description Represents additional notes for the client. + * @example This is a sample note for the client. + */ + note?: string; + }; + UpdateCustomFieldRequest: { + /** + * @description Represents custom field identifier across the system. + * @example 5e4117fe8c625f38930d57b7 + */ + customFieldId: string; + /** + * @description Represents a custom field value source type enum. + * @example WORKSPACE + * @enum {string} + */ + sourceType?: 'WORKSPACE' | 'PROJECT' | 'TIMEENTRY'; + /** + * @description Represents a custom field's value. + * @example new value + */ + value?: Record; + }; + UpdateCustomFieldRequestV1: { + /** + * @description Represents a list of custom field's allowed values. + * @example [ + * "NA", + * "White", + * "Black", + * "Asian", + * "Hispanic" + * ] + */ + allowedValues?: string[]; + /** + * @description Represents custom field description. + * @example This field contains a user's race. + */ + description?: string; + /** + * @description Represents custom field name. + * @example race + */ + name: string; + /** @description Flag to set whether custom field is modifiable only by admin users. */ + onlyAdminCanEdit?: boolean; + /** + * @description Represents a custom field placeholder value. + * @example This is a sample placeholder. + */ + placeholder?: string; + /** @description Flag to set whether custom field is mandatory or not. */ + required?: boolean; + /** + * @description Represents custom field status + * @example VISIBLE + * @enum {string} + */ + status?: 'INACTIVE' | 'VISIBLE' | 'INVISIBLE'; + /** + * @description Represents custom field type. + * @example DROPDOWN_MULTIPLE + * @enum {string} + */ + type?: + | 'TXT' + | 'NUMBER' + | 'DROPDOWN_SINGLE' + | 'DROPDOWN_MULTIPLE' + | 'CHECKBOX' + | 'LINK'; + /** + * @description Represents a custom field's default value in the workspace. + * @example NA + */ + workspaceDefaultValue?: Record; + }; + UpdateExpenseV1Request: { + /** + * Format: double + * @description Represents expense amount as double data type. + * @example 99.5 + */ + amount?: number; + /** @description Indicates whether expense is billable or not. */ + billable?: boolean; + /** + * @description Represents category identifier across the system. + * @example 45y687e29ae1f428e7ebe890 + */ + categoryId?: string; + /** + * @description Represents a list of expense change fields. + * @example [ + * "USER", + * "DATE", + * "PROJECT" + * ] + */ + changeFields?: ( + | 'USER' + | 'DATE' + | 'PROJECT' + | 'CATEGORY' + | 'NOTES' + | 'AMOUNT' + | 'BILLABLE' + | 'FILE' + )[]; + /** + * Format: date-time + * @description Provides a valid yyyy-MM-ddThh:mm:ssZ format date. + * @example 2020-01-01T00:00:00Z + */ + date?: string; + /** Format: binary */ + file?: string; + /** + * @description Represents notes for an expense. + * @example This is a sample note for this expense. + */ + notes?: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId?: string; + }; + UpdateInvoiceRequestV1: { + /** + * @description Represents client identifier across the system. + * @example 98h687e29ae1f428e7ebe707 + */ + clientId?: string; + /** + * @description Represents company identifier across the system. + * @example 04g687e29ae1f428e7ebe123 + */ + companyId?: string; + /** + * @description Represents the currency used by the invoice. + * @example USD + */ + currency: string; + /** + * Format: double + * @description Represents an invoice discount percent as double. + * @example 1.5 + */ + discountPercent?: number; + /** + * Format: date-time + * @description Represents an invoice due date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-06-01T08:00:00Z + */ + dueDate?: string; + /** + * Format: date-time + * @description Represents an invoice issued date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T08:00:00Z + */ + issuedDate?: string; + /** + * @description Represents an invoice note. + * @example This is a sample note for this invoice. + */ + note?: string; + /** + * @description Represents an invoice number. + * @example 202306121129 + */ + number: string; + /** + * @description Represents an invoice subject. + * @example January salary + */ + subject?: string; + /** + * Format: double + * @description Represents an invoice tax percent as double. + * @example 0 + */ + tax2Percent?: number; + /** + * Format: double + * @description Represents an invoice tax percent as double. + * @example 0.5 + */ + taxPercent?: number; + visibleZeroFields?: components['schemas']['VisibleZeroFieldsInvoice']; + }; + UpdateInvoiceSettingsRequestV1: { + defaults?: components['schemas']['InvoiceDefaultSettingsRequestV1']; + exportFields?: components['schemas']['InvoiceExportFieldsRequest']; + labels: components['schemas']['LabelsCustomizationRequest']; + }; + UpdateInvoicedStatusRequest: { + /** @description Indicates whether time entry is invoiced or not. */ + invoiced: boolean; + /** + * @description Represents a list of invoiced time entry ids + * @example [ + * "54m377ddd3fcab07cfbb432w", + * "25b687e29ae1f428e7ebe123" + * ] + */ + timeEntryIds: components['schemas']['TimeEntryId'][]; + }; + UpdateProjectMembershipsRequest: { + /** @description Represents a list of user with id hourly rate request objects. */ + memberships: components['schemas']['UserIdWithHourlyRateRequest'][]; + }; + UpdateProjectRequest: { + /** @description Indicates whether project is archived or not. */ + archived?: boolean; + /** @description Indicates whether project is billable or not. */ + billable?: boolean; + /** + * @description Represents client identifier across the system. + * @example 9t641568b07987035750704 + */ + clientId?: string; + /** + * @description Color format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #000000 + */ + color?: string; + costRate?: components['schemas']['CostRateRequestV1']; + hourlyRate?: components['schemas']['HourlyRateRequestV1']; + /** @description Indicates whether project is public or not. */ + isPublic?: boolean; + /** + * @description Represents a project name. + * @example Software Development + */ + name?: string; + /** + * @description Represents project note. + * @example This is a sample note for the project. + */ + note?: string; + }; + UpdateTagRequest: { + /** @description Indicates whether a tag will be archived or not. */ + archived?: boolean; + /** + * @description Represents tag name. + * @example Sprint1 + */ + name: string; + }; + UpdateTaskRequest: { + assigneeId?: string; + /** + * @description Represents list of assignee ids for the task. + * @example [ + * "45b687e29ae1f428e7ebe123", + * "67s687e29ae1f428e7ebe678" + * ] + */ + assigneeIds?: string[]; + /** @description Indicates whether a task is billable or not. */ + billable?: boolean; + /** + * Format: int64 + * @example 10000 + */ + budgetEstimate?: number; + /** + * @description Represents a task duration estimate. + * @example PT1H30M + */ + estimate?: string; + /** + * @description Represents task name. + * @example Bugfixing + */ + name: string; + /** + * @example DONE + * @enum {string} + */ + status?: 'ACTIVE' | 'DONE' | 'ALL'; + /** + * @description Represents list of user group ids for the task. + * @example [ + * "67b687e29ae1f428e7ebe123", + * "12s687e29ae1f428e7ebe678" + * ] + */ + userGroupIds?: string[]; + }; + UpdateTimeEntryBulkRequest: { + /** @description Indicates whether a time entry is billable or not. */ + billable?: boolean; + customFields?: components['schemas']['UpdateCustomFieldRequest'][]; + /** + * @description Represents time entry description. + * @example This is a sample time entry description. + */ + description?: string; + /** + * Format: date-time + * @description Represents an end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + /** + * Format: date-time + * @description Represents a start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + /** + * @description Represents a list of tag ids. + * @example [ + * "321r77ddd3fcab07cfbb567y", + * "44x777ddd3fcab07cfbb88f" + * ] + */ + tagIds?: string[]; + /** + * @description Represents task identifier across the system. + * @example 54m377ddd3fcab07cfbb432w + */ + taskId?: string; + /** @enum {string} */ + type?: 'REGULAR' | 'BREAK'; + }; + UpdateTimeEntryRequest: { + /** @description Indicates whether a time entry is billable or not. */ + billable?: boolean; + /** @description Represents a list of update custom field request objects. */ + customFields?: components['schemas']['UpdateCustomFieldRequest'][]; + /** + * @description Represents time entry description. + * @example This is a sample time entry description. + */ + description?: string; + /** + * Format: date-time + * @description Represents an end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId?: string; + /** + * Format: date-time + * @description Represents a start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + /** + * @description Represents a list of tag ids. + * @example [ + * "321r77ddd3fcab07cfbb567y", + * "44x777ddd3fcab07cfbb88f" + * ] + */ + tagIds?: string[]; + /** + * @description Represents task identifier across the system. + * @example 54m377ddd3fcab07cfbb432w + */ + taskId?: string; + /** @enum {string} */ + type?: 'REGULAR' | 'BREAK'; + }; + UpdateUserGroupRequest: { + /** + * @description Represents user group name. + * @example development_team + */ + name: string; + }; + UpdateUserStatusRequest: { + /** + * @description Represents membership status enum. + * @example ACTIVE + * @enum {string} + */ + status: 'ACTIVE' | 'INACTIVE'; + }; + UpdateWebhookRequestV1: { + name?: string; + triggerSource: string[]; + /** @enum {string} */ + triggerSourceType?: + | 'PROJECT_ID' + | 'USER_ID' + | 'TAG_ID' + | 'TASK_ID' + | 'WORKSPACE_ID' + | 'USER_GROUP_ID' + | 'INVOICE_ID'; + url: string; + /** @enum {string} */ + webhookEvent?: 'NEW_PROJECT,NEW_TASK,NEW_CLIENT,NEW_TIMER_STARTED, TIMER_STOPPED, TIME_ENTRY_UPDATED, TIME_ENTRY_DELETED,NEW_TIME_ENTRY, NEW_TAG, USER_DELETED_FROM_WORKSPACE, USER_JOINED_WORKSPACE,USER_DEACTIVATED_ON_WORKSPACE, USER_ACTIVATED_ON_WORKSPACE, USER_EMAIL_CHANGED,USER_UPDATED, NEW_INVOICE, INVOICE_UPDATED, NEW_APPROVAL_REQUEST,APPROVAL_REQUEST_STATUS_UPDATED, TIME_OFF_REQUESTED, TIME_OFF_REQUEST_APPROVED,TIME_OFF_REQUEST_REJECTED, TIME_OFF_REQUEST_WITHDRAWN, BALANCE_UPDATED'; + }; + UploadFileResponseV1: { + /** + * @description File name of the uploaded image + * @example image-01234567.jpg + */ + name?: string; + /** + * @description The URL of the uploaded image in the server + * @example https://clockify.com/image-01234567.jpg + */ + url?: string; + }; + /** @description Represents a list of upsert user custom field objects. */ + UpsertUserCustomFieldRequest: { + /** + * @description Represents custom field identifier across the system. + * @example 5e4117fe8c625f38930d57b7 + */ + customFieldId: string; + /** + * @description Represents custom field value. + * @example 20231211-12345 + */ + value?: Record; + }; + UpsertUserCustomFieldRequestV1: { + /** + * @description Represents custom field value. + * @example 20231211-12345 + */ + value?: Record; + }; + UserCustomFieldValueDtoV1: { + /** + * @description Represents custom field identifier across the system. + * @example 5e4117fe8c625f38930d57b7 + */ + customFieldId?: string; + /** + * @description Represents custom field name. + * @example TIN + */ + customFieldName?: string; + customFieldType?: components['schemas']['CustomFieldType']; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + /** + * @description Represents custom field value. + * @example 20231211-12345 + */ + value?: Record; + }; + /** @description Represents a list of user custom field value objects. */ + UserCustomFieldValueFullDtoV1: { + customField?: components['schemas']['CustomFieldDtoV1']; + /** + * @description Represents custom field identifier across the system. + * @example 5e4117fe8c625f38930d57b7 + */ + customFieldId?: string; + /** + * @description Represents user custom field name. + * @example race + */ + name?: string; + /** + * @description Represents user custom field source type enum. + * @example WORKSPACE + * @enum {string} + */ + sourceType?: 'WORKSPACE' | 'USER'; + /** + * @description Represents custom field type. + * @example DROPDOWN_MULTIPLE + */ + type?: string; + /** + * @description Represents a user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + /** + * @description Represents user custom field value. + * @example Asian + */ + value?: Record; + }; + UserDtoV1: { + /** + * @description Represents user active workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + activeWorkspace?: string; + /** @description Represents a list of user custom field value objects. */ + customFields?: components['schemas']['UserCustomFieldValueDtoV1'][]; + /** + * @description Represents user default workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + defaultWorkspace?: string; + /** + * @description Represents email address of the user. + * @example johndoe@example.com + */ + email?: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + id?: string; + /** @description Represents a list of membership objects. */ + memberships?: components['schemas']['MembershipDtoV1'][]; + /** + * @description Represents name of the user. + * @example John Doe + */ + name?: string; + /** + * @description Represents profile image path of the user. + * @example https://www.url.com/profile-picture1234567890.png + */ + profilePicture?: string; + settings?: components['schemas']['UserSettingsDtoV1']; + status?: components['schemas']['AccountStatus']; + }; + UserGroupDtoV1: { + /** + * @description Represents user group identifier across the system. + * @example 76a687e29ae1f428e7ebe101 + */ + id?: string; + /** + * @description Represents user group name. + * @example development_team + */ + name?: string; + /** + * @description Represents a list of user ids. + * @example [ + * "5a0ab5acb07987125438b60f", + * "98j4b5acb07987125437y32" + * ] + */ + userIds?: string[]; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + UserGroupRequest: { + /** + * @description Represents user group name. + * @example development_team + */ + name: string; + }; + UserGroupUserRequest: { + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + }; + /** @description Represents a list of user with id hourly rate request objects. */ + UserIdWithHourlyRateRequest: { + hourlyRate?: components['schemas']['HourlyRateRequestV1']; + /** + * @description Represents user identifier across the system. + * @example 12t687e29ae1f428e7ebe202 + */ + userId: string; + }; + /** @description Represents user settings object. */ + UserSettingsDtoV1: { + /** @example true */ + alerts?: boolean; + /** @example false */ + approval?: boolean; + /** @example true */ + collapseAllProjectLists?: boolean; + /** @example true */ + dashboardPinToTop?: boolean; + /** + * @example ME + * @enum {string} + */ + dashboardSelection?: 'ME' | 'TEAM'; + /** + * @example BILLABILITY + * @enum {string} + */ + dashboardViewType?: 'PROJECT' | 'BILLABILITY'; + /** + * @description Represents a date format. + * @example MM/DD/YYYY + */ + dateFormat: string; + /** @example true */ + groupSimilarEntriesDisabled?: boolean; + /** @example false */ + isCompactViewOn?: boolean; + /** @example en */ + lang?: string; + /** @example true */ + longRunning?: boolean; + /** @example true */ + multiFactorEnabled?: boolean; + /** @example 09:00 */ + myStartOfDay?: string; + /** @example false */ + onboarding?: boolean; + /** + * Format: int32 + * @example 15 + */ + projectListCollapse?: number; + /** @example false */ + projectPickerTaskFilter?: boolean; + /** @example true */ + pto?: boolean; + /** @example false */ + reminders?: boolean; + /** @example true */ + scheduledReports?: boolean; + /** @example false */ + scheduling?: boolean; + /** @example false */ + sendNewsletter?: boolean; + /** @example false */ + showOnlyWorkingDays?: boolean; + summaryReportSettings?: components['schemas']['SummaryReportSettingsDtoV1']; + /** + * @example DARK + * @enum {string} + */ + theme?: 'DARK' | 'DEFAULT'; + /** + * @description Represents a time format enum. + * @example HOUR24 + * @enum {string} + */ + timeFormat: 'HOUR12' | 'HOUR24'; + /** @example true */ + timeTrackingManual?: boolean; + /** + * @description Represents a valid timezone ID + * @example Asia/Aden + */ + timeZone: string; + /** + * @description Represents a day of the week. + * @example MONDAY + */ + weekStart?: { + /** Format: int32 */ + value?: number; + } & ( + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY' + ); + /** @example false */ + weeklyUpdates?: boolean; + }; + /** + * @description Represents a list of zero value invoice fields that will be visible. + * @example [ + * "TAX", + * "TAX_2", + * "DISCOUNT" + * ] + */ + VisibleZeroFieldsInvoice: 'TAX' | 'TAX_2' | 'DISCOUNT'; + WebhookDtoV1: { + /** + * @description Represents an authentication token. + * @example eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE + */ + authToken?: string; + /** @description Indicates whether webhook is enabled or not. */ + enabled?: boolean; + /** + * @description Represents webhook identifier across the system. + * @example 76a687e29ae1f428e7ebe101 + */ + id?: string; + /** + * @description Represents webhook name. + * @example stripe + */ + name?: string; + /** + * @description Represents a list of trigger sources. + * @example [ + * "54a687e29ae1f428e7ebe909", + * "87p187e29ae1f428e7ebej56" + * ] + */ + triggerSource?: string[]; + triggerSourceType?: components['schemas']['WebhookEventTriggerSourceType']; + /** + * @description Represents workspace identifier across the system. + * @example https://example-clockify.com/stripeEndpoint + */ + url?: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + webhookEvent?: components['schemas']['WebhookEventType']; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId?: string; + }; + /** + * @description Represents a webhook event trigger source type enum. + * @example PROJECT_ID + */ + WebhookEventTriggerSourceType: { + /** @enum {string} */ + entityType?: + | 'AUTH' + | 'ALERT' + | 'APPROVAL_REQUEST' + | 'CLIENT' + | 'EXPENSE' + | 'EXPENSE_CATEGORY' + | 'EXPORT_SETTINGS' + | 'INVOICE' + | 'INVOICE_ITEM_TYPE' + | 'PASSWORD_RESET_TOKEN' + | 'PROJECT' + | 'PROJECT_FAVORITE' + | 'REMINDER' + | 'REPORT' + | 'ORGANIZATION' + | 'TEMPLATE' + | 'TIMEENTRY' + | 'TAG' + | 'TASK' + | 'TASK_FAVORITES' + | 'USER' + | 'USER_GROUP' + | 'WEBHOOK' + | 'WORKSPACE' + | 'CUSTOM_FIELD' + | 'WEBHOOK_LOG' + | 'SCHEDULE_ASSIGNMENT' + | 'SCHEDULE_MILESTONE' + | 'COMPANY' + | 'CURRENCY' + | 'KIOSK_PIN_CODE' + | 'KIOSK' + | 'KIOSK_SESSION' + | 'MARKETPLACE_ADDON' + | 'INVOICE_PAYMENT' + | 'HOLIDAY' + | 'EMAIL_KEY_REQUEST' + | 'EMAIL_SESSION_REQUEST'; + } & ( + | 'PROJECT_ID' + | 'USER_ID' + | 'TAG_ID' + | 'TASK_ID' + | 'WORKSPACE_ID' + | 'USER_GROUP_ID' + | 'INVOICE_ID' + ); + /** + * @description Represents a webhook event type enum. + * @example NEW_PROJECT + */ + WebhookEventType: { + /** @enum {string} */ + payloadType?: + | 'PROJECT' + | 'TIME_ENTRY' + | 'CLIENT' + | 'TAG' + | 'TASK' + | 'WEBHOOK' + | 'WEBHOOK_LOG' + | 'NO_PAYLOAD' + | 'WORKSPACE_PAYMENT_DETAILS' + | 'DOMAIN_DETAILS' + | 'WORKSPACE_DELETED_DETAILS' + | 'USER' + | 'USER_GROUP' + | 'FILE_IMPORT_RESULTS' + | 'APPROVAL_REQUEST' + | 'INVOICE' + | 'TIME_OFF_REQUEST' + | 'BALANCE_UPDATED' + | 'ASSIGNMENT' + | 'ADDITIONAL_WORKSPACE'; + validSourceTypes?: ( + | 'PROJECT_ID' + | 'USER_ID' + | 'TAG_ID' + | 'TASK_ID' + | 'WORKSPACE_ID' + | 'USER_GROUP_ID' + | 'INVOICE_ID' + )[]; + } & ( + | 'NEW_PROJECT' + | 'NEW_TASK' + | 'NEW_CLIENT' + | 'NEW_TIMER_STARTED' + | 'TIMER_STOPPED' + | 'TIME_ENTRY_UPDATED' + | 'TIME_ENTRY_DELETED' + | 'NEW_TIME_ENTRY' + | 'NEW_TAG' + | 'USER_DELETED_FROM_WORKSPACE' + | 'USER_JOINED_WORKSPACE' + | 'USER_DEACTIVATED_ON_WORKSPACE' + | 'USER_ACTIVATED_ON_WORKSPACE' + | 'USER_EMAIL_CHANGED' + | 'USER_UPDATED' + | 'TEST' + | 'RESEND' + | 'NEW_INVOICE' + | 'INVOICE_UPDATED' + | 'NEW_APPROVAL_REQUEST' + | 'APPROVAL_REQUEST_STATUS_UPDATED' + | 'TIME_OFF_REQUESTED' + | 'TIME_OFF_REQUEST_APPROVED' + | 'TIME_OFF_REQUEST_REJECTED' + | 'TIME_OFF_REQUEST_WITHDRAWN' + | 'BALANCE_UPDATED' + | 'TAG_UPDATED' + | 'TAG_DELETED' + | 'TASK_UPDATED' + | 'CLIENT_UPDATED' + | 'TASK_DELETED' + | 'CLIENT_DELETED' + ); + WebhookLogDtoV1: { + id?: string; + requestBody?: string; + respondedAt?: string; + responseBody?: string; + /** Format: int32 */ + statusCode?: number; + webhookId?: string; + }; + WebhookLogSearchRequestV1: { + /** + * Format: date-time + * @example 2023-02-01T13:00:46Z + */ + from?: string; + newest?: boolean; + sortByNewest?: boolean; + /** @enum {string} */ + status?: 'ALL' | 'SUCCEEDED' | 'FAILED'; + /** + * Format: date-time + * @example 2023-05-01T13:00:46Z + */ + to?: string; + }; + WebhooksDtoV1: { + /** @description Represents a list of webhook objects for the workspace. */ + webhooks?: components['schemas']['WebhookDtoV1'][]; + /** + * Format: int32 + * @description Represents number of webhooks for the workspace. + * @example 5 + */ + workspaceWebhookCount?: number; + }; + WorkspaceDtoV1: { + costRate?: components['schemas']['RateDtoV1']; + /** @description Represents currency with default info object. */ + currencies?: components['schemas']['CurrencyWithDefaultInfoDtoV1'][]; + featureSubscriptionType?: components['schemas']['FeatureSubscriptionType']; + features?: components['schemas']['Feature']; + hourlyRate?: components['schemas']['HourlyRateDtoV1']; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + id?: string; + /** + * @description Represents an image url. + * @example https://www.url.com/imageurl-1234567890.jpg + */ + imageUrl?: string; + /** @description Represents a list of membership objects. */ + memberships?: components['schemas']['MembershipDtoV1'][]; + /** + * @description Represents workspace name. + * @example Cool Company + */ + name?: string; + workspaceSettings?: components['schemas']['WorkspaceSettingsDtoV1']; + }; + WorkspaceRequest: { + /** + * @description Represents a workspace name. + * @example Cool Company + */ + name: string; + }; + /** @description Represents workspace settings object. */ + WorkspaceSettingsDtoV1: { + /** + * @description Represents a unique list of protected page enums. + * @example ["PROJECT","TEAM","REPORTS"] + * @enum {string} + */ + adminOnlyPages?: 'PROJECT' | 'TEAM' | 'REPORTS'; + automaticLock?: components['schemas']['AutomaticLockDtoV1']; + /** @description Indicates whether timesheets are visible or not. */ + canSeeTimeSheet?: boolean; + /** @description Indicates whether time trackers are visible or not. */ + canSeeTracker?: boolean; + /** + * @description Represents a clockify currency format enum. + * @example CURRENCY_SPACE_VALUE + * @enum {string} + */ + currencyFormat?: + | 'CURRENCY_SPACE_VALUE' + | 'VALUE_SPACE_CURRENCY' + | 'CURRENCY_VALUE' + | 'VALUE_CURRENCY'; + /** @description Indicates whether projects are billable by default. */ + defaultBillableProjects?: boolean; + /** @description Indicates whether description are forced or not. */ + forceDescription?: boolean; + /** @description Indicates whether projects are forced or not. */ + forceProjects?: boolean; + /** @description Indicates whether tags are forced or not. */ + forceTags?: boolean; + /** @description Indicates whether tasks are forced or not. */ + forceTasks?: boolean; + isProjectPublicByDefault?: boolean; + lockTimeEntries?: string; + lockTimeZone?: string; + /** @description Indicates whether two-factor authentication is enabled or not. */ + multiFactorEnabled?: boolean; + /** + * @description Represents a clockify number format enum. + * @example COMMA_PERIOD + * @enum {string} + */ + numberFormat?: + | 'COMMA_PERIOD' + | 'PERIOD_COMMA' + | 'QUOTATION_MARK_PERIOD' + | 'SPACE_COMMA'; + /** @description Indicates whether only admins can create projects. */ + onlyAdminsCreateProject?: boolean; + /** @description Indicates whether only admins can create tags. */ + onlyAdminsCreateTag?: boolean; + /** @description Indicates whether only admins can create task. */ + onlyAdminsCreateTask?: boolean; + /** @description Indicates whether only admins can see all time entries. */ + onlyAdminsSeeAllTimeEntries?: boolean; + /** @description Indicates whether only admins can see billable rates. */ + onlyAdminsSeeBillableRates?: boolean; + /** @description Indicates whether only admins can see dashboard. */ + onlyAdminsSeeDashboard?: boolean; + /** @description Indicates whether only admins can see public project entries. */ + onlyAdminsSeePublicProjectsEntries?: boolean; + /** @description Indicates whether project favorites are allowed. */ + projectFavorites?: boolean; + /** + * @description Represents a project grouping label. + * @example Project Label + */ + projectGroupingLabel?: string; + /** @description Indicates whether project picker special filter is enabled. */ + projectPickerSpecialFilter?: boolean; + round?: components['schemas']['RoundDto']; + /** @description Indicates whether time rounding is enabled in reports. */ + timeRoundingInReports?: boolean; + /** + * @description Represents a time tracking mode enum. + * @example DEFAULT + * @enum {string} + */ + timeTrackingMode?: 'DEFAULT' | 'STOPWATCH_ONLY'; + /** @description Indicates whether time tracking is seconds-accurate. */ + trackTimeDownToSecond?: boolean; + }; + Approve: { + /** + * @description Indicates whether it requires approval + * @example true + */ + requiresApproval?: boolean; + /** + * @description Indicates whether it requires specific members + * @example false + */ + specificMembers?: boolean; + /** + * @description Indicates whether it requires team manager's approval + * @example false + */ + teamManagers?: boolean; + /** + * @description Represents set of user's identifier across the system + * @example [ + * "6579d126c2fe3b25f20ea001", + * "6579d126c2fe3b25f20ea002" + * ] + */ + userIds?: string[]; + }; + AutomaticAccrual: { + /** + * Format: double + * @description Represents automatic accrual's amount + * @example 20 + */ + amount?: number; + /** + * @description Represents automatic accrual's period + * @example YEAR + * @enum {string} + */ + period?: 'MONTH' | 'YEAR'; + /** + * @description Represents automatic accrual's time unit + * @example DAYS + * @enum {string} + */ + timeUnit?: 'DAYS' | 'HOURS'; + }; + AutomaticAccrualRequest: { + /** + * Format: double + * @description Represents amount of automatic accrual. + * @example 2 + */ + amount: number; + amountValidForTimeUnit?: boolean; + /** + * @description Represents automatic accrual period. + * @example MONTH + * @enum {string} + */ + period?: 'MONTH' | 'YEAR'; + /** + * @description Represents automatic accrual time unit. + * @example DAYS + * @enum {string} + */ + timeUnit?: 'DAYS' | 'HOURS'; + }; + /** @description Represent the list of balances. */ + BalanceDtoV1: { + /** + * Format: double + * @description Represents the balance amount of the time unit + * @example 20 + */ + balance?: number; + /** + * @description Represent balance identifier across the system. + * @example 5b715448b079875110792222 + */ + id?: string; + /** + * Format: double + * @description Represent negative balance amount. + * @example 2 + */ + negativeBalanceAmount?: number; + /** + * @description Indicates whether the negative balance limit is allowed. + * @example true + */ + negativeBalanceLimit?: boolean; + /** + * @description Indicates whether the policy is archived. + * @example false + */ + policyArchived?: boolean; + /** + * @description Represent policy identifier across the system. + * @example 5b715448b079875110793333 + */ + policyId?: string; + /** + * @description Represent policy name. + * @example Days + */ + policyName?: string; + /** + * @description Represent policy time unit. + * @example DAYS + * @enum {string} + */ + policyTimeUnit?: 'DAYS' | 'HOURS'; + /** + * Format: double + * @description Represents the total amount + * @example 18 + */ + total?: number; + /** + * Format: double + * @description Represents the balance used amount + * @example 2 + */ + used?: number; + /** + * @description Represent user identifier across the system. + * @example 5b715448b079875110791234 + */ + userId?: string; + /** + * @description Represent user's username. + * @example nicholas + */ + userName?: string; + /** + * @description Represent workspace identifier across the system. + * @example 5b715448b079875110791111 + */ + workspaceId?: string; + }; + BalancesWithCountDtoV1: { + balances?: components['schemas']['BalanceDtoV1'][]; + /** + * Format: int32 + * @description Represents the count of balances. + * @example 2 + */ + count?: number; + }; + ChangeBalanceRequestV1: { + /** + * @description Provide the note you would like to use for changing the balance. + * @example Change Balance Request Note + */ + note?: string; + /** + * @description Provide user ids for whom you want to change the balance. + * @example [ + * "5b715448b079875110792222", + * "5b715448b079875110791111" + * ] + */ + userIds: string[]; + /** + * Format: double + * @description Provide the value you would like to use for changing the balance. + * @example 22 + */ + value: number; + }; + ChangePolicyStatusRequest: { + /** + * @description Provide the status you would like to use for changing the policy. + * @example ACTIVE + * @enum {string} + */ + status: 'ACTIVE' | 'ARCHIVED' | 'ALL'; + }; + ContainsFilter: { + /** + * @example CONTAINS + * @enum {string} + */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN'; + /** + * @description Represents ids upon which filtering is performed. + * @example [ + * "5b715612b079875110791111", + * "5b715612b079875110791222" + * ] + */ + ids?: string[]; + /** + * @description Represents user status. + * @example ALL + * @enum {string} + */ + status?: 'ALL' | 'ACTIVE' | 'INACTIVE'; + }; + CreateHolidayRequestV1: { + /** + * @description Provide color in format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #8BC34A + */ + color?: string; + datePeriod: components['schemas']['DatePeriodRequest']; + /** + * @description Indicates whether the holiday is shown to new users. + * @example true + */ + everyoneIncludingNew?: boolean; + /** + * @description Provide the name of the holiday. + * @example Labour Day + */ + name: string; + /** + * @description Indicates whether the holiday occurs annually. + * @example true + */ + occursAnnually?: boolean; + userGroups?: components['schemas']['ContainsFilter']; + users?: components['schemas']['ContainsFilter']; + }; + CreatePolicyRequestV1: { + /** + * @description Indicates whether policy allows half day. + * @example false + */ + allowHalfDay?: boolean; + /** + * @description Indicates whether policy allows negative balance. + * @example true + */ + allowNegativeBalance?: boolean; + approve: components['schemas']['Approve']; + /** + * @description Indicates whether policy is archived. + * @example true + */ + archived?: boolean; + automaticAccrual?: components['schemas']['AutomaticAccrualRequest']; + /** + * @description Provide color in format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #8BC34A + */ + color?: string; + /** + * @description Indicates whether the holiday is shown to new users. + * @example false + */ + everyoneIncludingNew?: boolean; + /** + * @description Provide the name you would like to use for creating the policy. + * @example Days + */ + name: string; + negativeBalance?: components['schemas']['NegativeBalanceRequest']; + /** + * @description Indicates time unit of the policy. + * @example DAYS + * @enum {string} + */ + timeUnit?: 'DAYS' | 'HOURS'; + userGroups?: components['schemas']['ContainsFilter']; + users?: components['schemas']['ContainsFilter']; + }; + CreateTimeOffRequestV1Request: { + /** + * @description Provide the note you would like to use for creating the time off request. + * @example Create Time Off Note + */ + note?: string; + timeOffPeriod: components['schemas']['TimeOffRequestPeriodV1Request']; + }; + /** @description Represents startDate and endDate of the holiday. Date is in format yyyy-mm-dd */ + DatePeriod: { + /** Format: date */ + end?: string; + /** Format: date */ + endDate?: string; + /** Format: date */ + start?: string; + /** Format: date */ + startDate?: string; + }; + /** @description Provide startDate and endDate for the holiday. */ + DatePeriodRequest: { + /** + * @description Provide endDate in format yyyy-MM-dd + * @example 2023-02-16 + */ + endDate: string; + /** + * @description Provide startDate in format yyyy-MM-dd + * @example 2023-02-14 + */ + startDate: string; + }; + GetTimeOffRequestsV1Request: { + /** + * Format: date-time + * @description Return time off requests created before. Provide end in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T23:55:06.281873Z + */ + end?: string; + /** + * Format: int32 + * @example 1 + */ + page?: number; + /** + * Format: int32 + * @example 50 + */ + 'page-size'?: number; + /** + * Format: date-time + * @description Return time off requests created after. Provide start in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T08:00:06.281873Z + */ + start?: string; + /** + * @example [APPROVED, PENDING] + * @enum {string} + */ + statuses?: 'PENDING' | 'APPROVED' | 'REJECTED' | 'ALL'; + /** + * @description Provide the user group ids of time off requests. + * @example [ + * "5b715612b079875110791342", + * "5b715612b079875110791324", + * "5b715612b079875110793142" + * ] + */ + userGroups?: string[]; + /** + * @description Provide the user ids of time off requests. + * @example [ + * "5b715612b079875110791432", + * "b715612b079875110791234" + * ] + */ + users?: string[]; + }; + HolidayDto: { + /** + * @description Provide color in format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #8BC34A + */ + color?: string; + datePeriod?: components['schemas']['DatePeriod']; + /** + * @description Indicates whether the holiday is shown to new users. + * @example false + */ + everyoneIncludingNew?: boolean; + /** + * @description Represents holiday identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents the name of the holiday. + * @example New Year's Day + */ + name?: string; + /** + * @description Indicates whether the holiday occurs annually. + * @example true + */ + occursAnnually?: boolean; + /** + * @description Indicates which user groups are included. + * @example [ + * "5b715612b079875110791342", + * "5b715612b079875110791324", + * "5b715612b079875110793142" + * ] + */ + userGroupIds?: string[]; + /** + * @description Indicates which users are included. + * @example [ + * "5b715612b079875110791432", + * "5b715612b079875110791234" + * ] + */ + userIds?: string[]; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110792222 + */ + workspaceId?: string; + }; + HolidayDtoV1: { + datePeriod?: components['schemas']['DatePeriod']; + /** + * @description Indicates whether the holiday is shown to new users. + * @example false + */ + everyoneIncludingNew?: boolean; + /** + * @description Represents holiday identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents the name of the holiday. + * @example New Year's Day + */ + name?: string; + /** + * @description Indicates whether the holiday occurs annually. + * @example true + */ + occursAnnually?: boolean; + /** + * @description Indicates which user groups are included. + * @example [ + * "5b715612b079875110791342", + * "5b715612b079875110791324", + * "5b715612b079875110793142" + * ] + */ + userGroupIds?: string[]; + /** + * @description Indicates which users are included. + * @example [ + * "5b715612b079875110791432", + * "5b715612b079875110791234" + * ] + */ + userIds?: string[]; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110792222 + */ + workspaceId?: string; + }; + /** @description Represents the data about negative balance including amount, time unit and period. */ + NegativeBalance: { + /** Format: double */ + amount?: number; + /** @enum {string} */ + period?: 'MONTH' | 'YEAR'; + /** @enum {string} */ + timeUnit?: 'DAYS' | 'HOURS'; + }; + /** @description Provide the negative balance data you would like to use for updating the policy. */ + NegativeBalanceRequest: { + /** + * Format: double + * @description Represents negative balance amount. + * @example 2 + */ + amount: number; + amountValidForTimeUnit?: boolean; + /** + * @description Represents negative balance period. + * @example MONTH + * @enum {string} + */ + period?: 'MONTH' | 'YEAR'; + /** + * @description Represents negative balance time unit. + * @example DAYS + * @enum {string} + */ + timeUnit?: 'DAYS' | 'HOURS'; + }; + /** @description Indicates half day hours period of time off. */ + Period: { + /** + * Format: date-time + * @description Provide end in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T21:59:59.999Z + */ + end?: string; + /** + * Format: date-time + * @description Provide start in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-25T22:00:00Z + */ + start?: string; + }; + /** @description Represents period of time off request including start and end date. */ + PeriodV1Request: { + /** + * Format: int32 + * @example 3 + */ + days?: number; + /** + * @description Provide end date in format YYYY-MM-DD + * @example 2021-12-25 + */ + end?: string; + /** + * @description Provide start date in format YYYY-MM-DD + * @example 2021-12-23 + */ + start?: string; + }; + PolicyDtoV1: { + /** + * @description Indicates whether the half day is allowed. + * @example false + */ + allowHalfDay?: boolean; + /** + * @description Indicates whether the negative balance is allowed. + * @example true + */ + allowNegativeBalance?: boolean; + approve?: components['schemas']['Approve']; + /** + * @description Indicates whether the policy is archived. + * @example true + */ + archived?: boolean; + automaticAccrual?: components['schemas']['AutomaticAccrual']; + /** + * @description Indicates whether the policy is shown to new users. + * @example false + */ + everyoneIncludingNew?: boolean; + /** + * @description Represents policy identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents the name of the policy. + * @example Days + */ + name?: string; + negativeBalance?: components['schemas']['NegativeBalance']; + /** + * @description Represents the time unit of the policy. + * @example DAYS + * @enum {string} + */ + timeUnit?: 'DAYS' | 'HOURS'; + /** + * @description Indicates which user groups are included. + * @example [ + * "5b715612b079875110791342", + * "5b715612b079875110791324", + * "5b715612b079875110793142" + * ] + */ + userGroupIds?: string[]; + /** + * @description Indicates which users are included. + * @example [ + * "5b715612b079875110791432", + * "5b715612b079875110791234" + * ] + */ + userIds?: string[]; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110792222 + */ + workspaceId?: string; + }; + StatusTimeOffRequestRequestV1: { + /** + * @description Provide the note you would like to use for changing the time off request. + * @example Time Off Request Note + */ + note?: string; + /** + * @description Provide the status you would like to use for changing the time off request. + * @example APPROVED + * @enum {string} + */ + status?: 'APPROVED' | 'REJECTED'; + }; + TimeOffRequestDtoV1: { + /** + * Format: double + * @description Represents the balance difference + * @example 1 + */ + balanceDiff?: number; + /** + * Format: date-time + * @description Represents the date when time off request is created. Date is in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T08:32:01.640708Z + */ + createdAt?: string; + /** + * @description Represents time off requester identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents the note of the time off request. + * @example Time Off Request Note + */ + note?: string; + /** + * @description Represents policy identifier across the system. + * @example 5b715612b079875110792333 + */ + policyId?: string; + status?: components['schemas']['TimeOffRequestStatus']; + timeOffPeriod?: components['schemas']['TimeOffRequestPeriod']; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110794444 + */ + userId?: string; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110792222 + */ + workspaceId?: string; + }; + TimeOffRequestFullDtoNewV1: { + /** + * Format: double + * @description Represents the time off balance. + * @example 1 + */ + balance?: number; + /** + * Format: double + * @description Represents the balance difference + * @example 1 + */ + balanceDiff?: number; + /** + * Format: date-time + * @description Represents the date when time off request is created. It is in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T08:32:01.640708Z + */ + createdAt?: string; + /** + * @description Represents time off requester identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents the note of the time off request. + * @example Time Off Request Note + */ + note?: string; + /** + * @description Represents policy identifier across the system. + * @example 5b715612b079875110792333 + */ + policyId?: string; + /** + * @description Represents the policy name of the time off request. + * @example Days + */ + policyName?: string; + /** + * @description Represents requester user's id. + * @example 5b715612b0798751107925555 + */ + requesterUserId?: string; + /** + * @description Represents requester user's username. + * @example John + */ + requesterUserName?: string; + status?: components['schemas']['TimeOffRequestStatus']; + timeOffPeriod?: components['schemas']['TimeOffRequestPeriod']; + /** + * @description Represents the policy name of the time off request. + * @example DAYS + * @enum {string} + */ + timeUnit?: 'DAYS' | 'HOURS'; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110794444 + */ + userId?: string; + /** + * @description Represents user's username. + * @example Nicholas + */ + userName?: string; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110792222 + */ + workspaceId?: string; + }; + /** @description Represents the array of time off requests. */ + TimeOffRequestFullDtoV1: { + /** + * Format: double + * @description Represents the time off balance. + * @example 10 + */ + balance?: number; + /** + * Format: double + * @description Represents the balance difference. + * @example 1 + */ + balanceDiff?: number; + /** + * Format: date-time + * @description Represents the date when time off request is created. It is in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T08:32:01.640708Z + */ + createdAt?: string; + /** + * @description Represents time off requester identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents the note of the time off request. + * @example Time Off Request Note + */ + note?: string; + /** + * @description Represents policy identifier across the system. + * @example 5b715612b079875110792333 + */ + policyId?: string; + /** + * @description Represents the policy name of the time off request. + * @example Days + */ + policyName?: string; + /** + * @description Represents requester user's id. + * @example 5b715612b0798751107925555 + */ + requesterUserId?: string; + /** + * @description Represents requester user's username. + * @example John + */ + requesterUserName?: string; + status?: components['schemas']['TimeOffRequestStatus']; + timeOffPeriod?: components['schemas']['TimeOffRequestPeriod']; + /** + * @description Represents the time unit of the time off request. + * @example DAYS + * @enum {string} + */ + timeUnit?: 'DAYS' | 'HOURS'; + /** + * @description Represents user's email + * @example nicholas@clockify.com + */ + userEmail?: string; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110794444 + */ + userId?: string; + /** + * @description Represents user's username. + * @example Nicholas + */ + userName?: string; + /** + * @description Represents user's time zone + * @example Europe/Budapest + */ + userTimeZone?: string; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110792222 + */ + workspaceId?: string; + }; + /** @description Represents the period the time off request. */ + TimeOffRequestPeriod: { + halfDay?: boolean; + halfDayHours?: components['schemas']['Period']; + /** @description Indicates half day period of time off. */ + halfDayPeriod?: string; + period?: components['schemas']['Period']; + }; + /** @description Provide the period you would like to use for creating the time off request. */ + TimeOffRequestPeriodV1Request: { + /** + * @description Represents the half day period. + * @example NOT_DEFINED + * @enum {string} + */ + halfDayPeriod?: 'FIRST_HALF' | 'SECOND_HALF' | 'NOT_DEFINED'; + /** + * @description Indicates whether time off is half day. + * @example false + */ + isHalfDay?: boolean; + period: components['schemas']['PeriodV1Request']; + }; + /** @description Represents the status the time off request. */ + TimeOffRequestStatus: { + /** + * Format: date-time + * @description Provide in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T08:32:06.281873Z + */ + changedAt?: string; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110799999 + */ + changedByUserId?: string; + /** + * @description Represents username of user who changed time off request status. + * @example Sara + */ + changedByUserName?: string; + /** + * @description Represents time off request status note. + * @example Time Off Request Status Note + */ + note?: string; + /** + * @description Represents time off request status type. + * @example APPROVED + * @enum {string} + */ + statusType?: 'PENDING' | 'APPROVED' | 'REJECTED' | 'ALL'; + }; + TimeOffRequestsWithCountDtoV1: { + /** + * Format: int32 + * @description Represents the count of time off requests. + * @example 1 + */ + count?: number; + requests?: components['schemas']['TimeOffRequestFullDtoV1'][]; + }; + UpdateHolidayRequestV1: { + /** + * @description Provide color in format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #8BC34A + */ + color?: string; + datePeriod: components['schemas']['DatePeriodRequest']; + /** + * @description Indicates whether the holiday is shown to new users. + * @example false + */ + everyoneIncludingNew?: boolean; + /** + * @description Provide the name you would like to use for updating the holiday. + * @example New Year's Day + */ + name: string; + /** + * @description Indicates whether the holiday occurs annually. + * @example true + */ + occursAnnually: boolean; + userGroups?: components['schemas']['ContainsFilter']; + users?: components['schemas']['ContainsFilter']; + }; + UpdatePolicyRequestV1: { + /** + * @description Indicates whether policy allows half day. + * @example true + */ + allowHalfDay: boolean; + /** + * @description Indicates whether policy allows negative balance. + * @example false + */ + allowNegativeBalance: boolean; + approve: components['schemas']['Approve']; + /** + * @description Indicates whether policy is archived. + * @example false + */ + archived: boolean; + automaticAccrual?: components['schemas']['AutomaticAccrualRequest']; + /** + * @description Provide color in format ^#(?:[0-9a-fA-F]{6}){1}$. Explanation: A valid color code should start with '#' and consist of six hexadecimal characters, representing a color in hexadecimal format. Color value is in standard RGB hexadecimal format. + * @example #8BC34A + */ + color?: string; + /** + * @description Indicates whether the policy is shown to new users. + * @example false + */ + everyoneIncludingNew: boolean; + /** + * @description Provide the name you would like to use for updating the policy. + * @example Days + */ + name: string; + negativeBalance?: components['schemas']['NegativeBalanceRequest']; + userGroups: components['schemas']['ContainsFilter']; + users: components['schemas']['ContainsFilter']; + }; + /** @description List of amounts */ + AmountDto: { + /** + * @description Represents amount type + * @example PROFIT + * @enum {string} + */ + type?: 'EARNED' | 'COST' | 'PROFIT' | 'HIDE_AMOUNT' | 'EXPORT'; + /** + * @description Represents amount value + * @example 1000 + */ + value?: number; + }; + AttendanceFilterV1: { + breakFilters?: components['schemas']['CompareBreakFilter'][]; + capacityFilters?: components['schemas']['CompareCapacityFilter'][]; + endFilters?: components['schemas']['CompareEndFilter'][]; + hasTimeOff?: boolean; + overtimeFilters?: components['schemas']['CompareOvertimeFilter'][]; + /** Format: int32 */ + page?: number; + /** Format: int32 */ + pageSize?: number; + sortColumn?: string; + startFilters?: components['schemas']['CompareStartFilter'][]; + workFilters?: components['schemas']['CompareWorkFilter'][]; + }; + /** @description report */ + AttendanceReportDtoV1: { + /** @description List of entities */ + entities?: { + /** Format: int64 */ + break?: number; + /** Format: int32 */ + capacity?: number; + date?: string; + endTime?: string; + hasRunningEntry?: boolean; + imageUrl?: string; + /** Format: int64 */ + overtime?: number; + startTime?: string; + /** Format: int64 */ + timeOff?: number; + /** Format: int64 */ + totalDuration?: number; + userId?: string; + userName?: string; + }; + }; + AuditFilterV1: { + /** + * Format: int32 + * @description Represent audit duration. + * @example 2 + */ + duration?: number; + /** + * @description Represent audit duration shorter. + * @example false + */ + durationShorter?: boolean; + /** + * @description Indicates whether to filter without a project. + * @example false + */ + withoutProject?: boolean; + /** + * @description Indicates whether to filter without a task. + * @example true + */ + withoutTask?: boolean; + }; + CompareBreakFilter: { + filtrationType?: string; + value?: string; + }; + CompareCapacityFilter: { + filtrationType?: string; + value?: string; + }; + CompareEndFilter: { + filtrationType?: string; + value?: string; + }; + CompareOvertimeFilter: { + filtrationType?: string; + value?: string; + }; + CompareStartFilter: { + filtrationType?: string; + value?: string; + }; + CompareWorkFilter: { + filtrationType?: string; + value?: string; + }; + ContainsArchivedFilterV1: { + /** @example CONTAINS */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Filter includes provided list of ids. + * @example [ + * "5b715448b079875110792222", + * "5b715448b079875110791111" + * ] + */ + ids?: string[]; + /** + * @description The status of the task, project, and other filters. + * @example ACTIVE + * @enum {string} + */ + status?: 'ACTIVE' | 'ARCHIVED' | 'ALL'; + }; + ContainsTagFilterV1: { + /** + * @description If provided, you'll get result filtered by value of contained in time entry. + * @example CONTAINS_ONLY + * @enum {string} + */ + containedInTimeentry?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** @example CONTAINS */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Filter includes provided list of ids. + * @example [ + * "5b715448b079875110792222", + * "5b715448b079875110791111" + * ] + */ + ids?: string[]; + /** + * @description The status of the task, project, and other filters. + * @example ACTIVE + * @enum {string} + */ + status?: 'ACTIVE' | 'ARCHIVED' | 'ALL'; + }; + ContainsTaskFilterV1: { + /** @example CONTAINS */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Filter includes provided list of ids. + * @example [ + * "5b715448b079875110792222", + * "5b715448b079875110791111" + * ] + */ + ids?: string[]; + /** + * @description The status of the task, project, and other filters. + * @example ACTIVE + * @enum {string} + */ + status?: 'ACTIVE' | 'ARCHIVED' | 'ALL'; + }; + ContainsUsersFilterV1: { + /** @example CONTAINS */ + contains?: 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'CONTAINS_ONLY'; + /** + * @description Filter includes provided list of ids. + * @example [ + * "5b715448b079875110792222", + * "5b715448b079875110791111" + * ] + */ + ids?: string[]; + /** + * @description The status of the task, project, and other filters. + * @example ACTIVE + * @enum {string} + */ + status?: 'ACTIVE' | 'ARCHIVED' | 'ALL'; + }; + CustomFieldFilterV1: { + empty?: boolean; + /** + * @description Represents custom field identifier across the system. + * @example 5b71544ab0798751107918b3 + */ + id?: string; + isEmpty?: boolean; + /** + * @description Represents custom field number condition. + * @example EQUAL + * @enum {string} + */ + numberCondition?: 'EQUAL' | 'GREATER_THAN' | 'LESS_THAN'; + /** + * @description Represents type of custom field. + * @example NUMBER + * @enum {string} + */ + type?: + | 'TXT' + | 'NUMBER' + | 'DROPDOWN_SINGLE' + | 'DROPDOWN_MULTIPLE' + | 'CHECKBOX' + | 'LINK'; + /** + * @description Represents custom field value. + * @example 2000 + */ + value?: Record; + }; + /** @description Represents list of days */ + DailyTotalDto: { + amount?: number; + date?: string; + duration?: number; + }; + DetailedFilterV1: { + auditFilter?: components['schemas']['AuditFilterV1']; + options?: components['schemas']['DetailedOptionsV1']; + /** + * Format: int32 + * @example 1 + */ + page?: number; + /** + * Format: int32 + * @example 20 + */ + pageSize?: number; + /** + * @description If provided, you'll get sorted result by sort column. + * @example ID + * @enum {string} + */ + sortColumn?: + | 'ID' + | 'DESCRIPTION' + | 'USER' + | 'DURATION' + | 'DATE' + | 'NATURAL' + | 'USER_DATE'; + }; + DetailedOptionsV1: { + /** + * @example CALCULATE + * @enum {string} + */ + totals?: 'CALCULATE' | 'EXCLUDE'; + }; + EntityName: { + id?: string; + name?: string; + }; + /** @description report */ + ExpenseDetailedReportDtoV1: { + /** @description List of expenses */ + expenses?: components['schemas']['ExpenseReportDtoV1'][]; + totals?: components['schemas']['ExpenseTotalsDtoV1']; + }; + /** @description List of expenses */ + ExpenseReportDtoV1: { + /** + * Format: double + * @description Represents expenses amount + */ + amount?: number; + /** + * @description Represents approval request identifier across the system. + * @example 5b715612b079875110791336 + */ + approvalRequestId?: string; + /** @description Indicates whether the expenses is billable */ + billable?: boolean; + /** @description Represents category's hash unit price */ + categoryHasUnitPrice?: boolean; + /** + * @description Represents category identifier across the system. + * @example 5b715612b079875110791334 + */ + categoryId?: string; + /** @description Represents category's name */ + categoryName?: string; + /** @description Represents category's unit */ + categoryUnit?: string; + /** + * @description Represents expenses date. Date is in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2021-10-27T00:00:00Z + */ + date?: string; + exportFields?: ( + | 'PROJECT' + | 'CLIENT' + | 'TASK' + | 'DESCRIPTION' + | 'USER' + | 'TAGS' + | 'START_DATE' + | 'START_TIME' + | 'END_TIME' + | 'DURATION' + | 'BILLABLE_AMOUNT' + | 'COST_AMOUNT' + | 'PROFIT' + | 'EMAIL' + | 'BILLABLE' + | 'BILLABLE_H' + | 'NON_BILLABLE_H' + | 'END_DATE' + | 'DECIMAL_DURATION' + | 'BILLABLE_RATE' + | 'COST_RATE' + | 'APPROVAL' + | 'BAR_CHART' + | 'PIE_CHART_1' + | 'PIE_CHART_2' + | 'PIE_CHART_3' + | 'RTL' + | 'TOTAL' + | 'SUBGROUP' + | 'GROUP' + | 'DATE' + | 'TIME' + | 'CATEGORY' + | 'NOTE' + | 'AMOUNT' + | 'INVOICED' + | 'INVOICE_ID' + | 'CATEGORY_NO_OF_UNITS' + | 'CATEGORY_UNIT' + | 'KIOSK' + | 'BREAK' + | 'NOTES' + | 'BILLABLE_TOTAL' + | 'RECEIPTS' + | 'EXPENSE_TOTAL' + | 'NAME' + | 'STATUS' + | 'VISIBILITY' + | 'BILLABILITY' + | 'TASKS' + | 'TRACKED_H' + | 'ESTIMATED_H' + | 'REMAINING_H' + | 'OVERAGE_H' + | 'TRACKED_BUDGET' + | 'ESTIMATED_BUDGET' + | 'REMAINING_BUDGET' + | 'OVERAGE_BUDGET' + | 'PROGRESS' + | 'RECURRING_ESTIMATE' + | 'EXPENSES' + | 'BILLABLE_EXPENSES' + | 'NON_BILLABLE_EXPENSES' + | 'ADDITIONAL_FIELDS' + | 'PROJECT_MEMBERS' + | 'PROJECT_MANAGER' + | 'APPROVED_BY' + | 'DATE_OF_CREATION' + | 'DATE_OF_APPROVAL' + | 'ISSUE_DATE' + | 'DUE_ON' + | 'BALANCE' + )[]; + /** + * @description Represents file identifier across the system. + * @example 5b715612b079875110791335 + */ + fileId?: string; + /** @description Represents expenses file name */ + fileName?: string; + id?: string; + invoicingInfo?: components['schemas']['invoicingInfo']; + locked?: boolean; + /** + * @description Represents expenses note. + * @example Expenses Note + */ + notes?: string; + /** @description Represents project's color */ + projectColor?: string; + /** + * @description Represents project identifier across the system. + * @example 5b715612b079875110791333 + */ + projectId?: string; + /** @description Represents project's name */ + projectName?: string; + /** + * Format: double + * @description Represents expenses quantity + * @example 10 + */ + quantity?: number; + reportName?: string; + time?: string; + /** @description Represents user's email */ + userEmail?: string; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110791121 + */ + userId?: string; + /** @description Represents user's name */ + userName?: string; + /** @description Represents user's status */ + userStatus?: string; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110791121 + */ + workspaceId?: string; + }; + ExpenseReportFilterV1: { + approvalState?: string; + billable?: boolean; + categories?: components['schemas']['ContainsArchivedFilterV1']; + clients?: components['schemas']['ContainsArchivedFilterV1']; + currency?: components['schemas']['ContainsArchivedFilterV1']; + dateRangeEnd?: string; + dateRangeStart?: string; + dateRangeType?: string; + exportType?: string; + invoicingState?: string; + /** + * @description Represents expense report filter's note + * @example Expense Report Note + */ + note?: string; + /** Format: int32 */ + page?: number; + /** + * Format: int32 + * @example 50 + */ + pageSize?: number; + projects?: components['schemas']['ContainsArchivedFilterV1']; + /** + * @description Represents expenses sort column + * @example ID + * @enum {string} + */ + sortColumn?: 'ID' | 'PROJECT' | 'USER' | 'CATEGORY' | 'DATE' | 'AMOUNT'; + sortOrder?: string; + timeZone?: string; + userGroups?: components['schemas']['ContainsUsersFilterV1']; + userLocale?: string; + users?: components['schemas']['ContainsUsersFilterV1']; + weekStart?: string; + withoutDescription?: boolean; + withoutNote?: boolean; + zoomLevel?: string; + }; + /** @description Expense Totals */ + ExpenseTotalsDtoV1: { + /** + * Format: int32 + * @description Represents expenses count + * @example 2 + */ + expensesCount?: number; + /** + * Format: double + * @description Represents total amount of expenses + * @example 20 + */ + totalAmount?: number; + /** + * Format: double + * @description Represents total billable amount of expenses + * @example 20 + */ + totalAmountBillable?: number; + }; + /** @description List of groups */ + GroupOneDto: { + /** + * @description Represents group one amount + * @example 100 + */ + amount?: number; + /** @description Represents list of children groups */ + children?: components['schemas']['GroupOneDto'][]; + /** + * @description Represents client name + * @example Cake.com + */ + clientName?: string; + /** @description Represents list of days */ + days?: components['schemas']['DailyTotalDto'][]; + /** + * @description Represents duration + * @example 10 + */ + duration?: number; + /** + * @description Represents group one identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents name + * @example Name + */ + name?: string; + /** + * @description Represents lower case name + * @example name + */ + nameLowerCase?: string; + }; + ReportFilterV1: { + /** + * @description If provided, you'll get filtered result including reports with provided amount shown. + * @example COST + * @enum {string} + */ + amountShown?: 'EARNED' | 'COST' | 'PROFIT' | 'HIDE_AMOUNT' | 'EXPORT'; + amounts?: ('EARNED' | 'COST' | 'PROFIT' | 'HIDE_AMOUNT' | 'EXPORT')[]; + approvalState?: string; + /** + * @description Indicates whether the report is archived + * @example false + */ + archived?: boolean; + attendanceFilter?: components['schemas']['AttendanceFilterV1']; + /** + * @description Indicates whether the report is billable + * @example true + */ + billable?: boolean; + clients?: components['schemas']['ContainsArchivedFilterV1']; + currency?: components['schemas']['ContainsArchivedFilterV1']; + customFields?: components['schemas']['CustomFieldFilterV1'][]; + /** + * @description Provide date in format YYYY-MM-DD + * @example 2018-11-01 + */ + dateFormat?: string; + /** + * @description Provide date in format format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2018-11-30T23:59:59.999Z + */ + dateRangeEnd: string; + /** + * @description Provide date in format format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2018-11-01T00:00:00Z + */ + dateRangeStart: string; + /** + * @description Provide date range type + * @example LAST_MONTH + * @enum {string} + */ + dateRangeType?: + | 'ABSOLUTE' + | 'TODAY' + | 'YESTERDAY' + | 'THIS_WEEK' + | 'LAST_WEEK' + | 'PAST_TWO_WEEKS' + | 'THIS_MONTH' + | 'LAST_MONTH' + | 'THIS_YEAR' + | 'LAST_YEAR'; + /** + * @description Represents report's description + * @example Report Description + */ + description?: string; + detailedFilter?: components['schemas']['DetailedFilterV1']; + /** + * @description If provided, you'll get filtered result including reports with provided export type. + * @example JSON + * @enum {string} + */ + exportType?: 'JSON' | 'JSON_V1' | 'PDF' | 'CSV' | 'XLSX' | 'ZIP'; + invoicingState?: string; + projects?: components['schemas']['ContainsArchivedFilterV1']; + /** + * @description Indicates whether the report filter is rounding + * @example false + */ + rounding?: boolean; + /** + * @description If provided, you'll get sorted result by provided sort order. + * @example ASCENDING + * @enum {string} + */ + sortOrder?: 'ASCENDING' | 'DESCENDING'; + summaryFilter?: components['schemas']['SummaryFilterV1']; + tags?: components['schemas']['ContainsTagFilterV1']; + tasks?: components['schemas']['ContainsTaskFilterV1']; + /** + * @description Provide time in format THH:MM:SS.ssssss + * @example T00:00:00 + */ + timeFormat?: string; + /** + * @description If provided, you'll get filtered result including reports with provided time zone. + * @example Europe/Belgrade + */ + timeZone?: string; + userGroups?: components['schemas']['ContainsUsersFilterV1']; + /** + * @description If provided, you'll get filtered result including reports with provided user locale. + * @example en + */ + userLocale?: string; + users?: components['schemas']['ContainsUsersFilterV1']; + /** + * @description If provided, you'll get filtered result including reports with provided week start. + * @example MONDAY + * @enum {string} + */ + weekStart?: + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY'; + weeklyFilter?: components['schemas']['WeeklyFilterV1']; + /** + * @description Indicates whether the report is billable + * @example false + */ + withoutDescription?: boolean; + /** + * @description If provided, you'll get filtered result including reports with provided zoom level. + * @example WEEK + * @enum {string} + */ + zoomLevel?: 'WEEK' | 'MONTH' | 'YEAR'; + }; + /** @description List of tags */ + ReportTagDto: { + /** + * @description Represents tag identifier across the system. + * @example 5b715612b079875110791136 + */ + id?: string; + /** + * @description Represents tag name. + * @example tagname + */ + name?: string; + }; + /** @description Represents time interval */ + ReportTimeIntervalDto: { + /** + * Format: int32 + * @description Represents the duration of interval. + */ + duration?: number; + /** + * @description Represents the end datetime. Date is in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-27T08:32:01.640708Z + */ + end?: string; + /** + * @description Represents the start datetime. Date is in format YYYY-MM-DDTHH:MM:SS.ssssssZ + * @example 2022-08-26T08:32:01.640708Z + */ + start?: string; + }; + /** @description Represents the array of reports. */ + SharedReportDtoV1: { + /** + * @description Indicates whether the shared report is fixed date + * @example true + */ + fixedDate?: boolean; + /** + * @description Represents shared report identifier across the system. + * @example 60f91b3ffdaf031696ecxx11 + */ + id?: string; + isPublic?: boolean; + /** + * Format: uri + * @description Represents URI link of shared report. + */ + link?: string; + /** + * @description Represents shared report's name. + * @example Weekly 1 + */ + name?: string; + /** + * @description Represents report author (user) identifier across the system. + * @example 60f91b3ffdaf031696ecxxxx + */ + reportAuthor?: string; + /** + * @description Represents shared report type + * @example WEEKLY + * @enum {string} + */ + type?: + | 'DETAILED' + | 'WEEKLY' + | 'SUMMARY' + | 'SCHEDULED' + | 'EXPENSE_DETAILED' + | 'EXPENSE_RECEIPT' + | 'PTO_REQUESTS' + | 'PTO_BALANCE' + | 'ATTENDANCE' + | 'INVOICE_EXPENSE' + | 'PROJECT' + | 'INVOICES'; + visibleToUserGroups?: components['schemas']['EntityName'][]; + /** + * @description Represents ids of user to whom are visible shared report. + * @example [userId1, userId2, userId3] + */ + visibleToUsers?: components['schemas']['EntityName'][]; + }; + SharedReportRequestV1: { + filter?: components['schemas']['ReportFilterV1']; + /** + * @description Indicates whether the shared reports is fixed date. + * @example true + */ + fixedDate?: boolean; + isPublic?: boolean; + /** + * @description Represents shared report's name + * @example Weekly 1 + */ + name?: string; + public?: boolean; + /** + * @description Represent the type of shared report. + * @example WEEKLY + * @enum {string} + */ + type?: + | 'DETAILED' + | 'WEEKLY' + | 'SUMMARY' + | 'SCHEDULED' + | 'EXPENSE_DETAILED' + | 'EXPENSE_RECEIPT' + | 'PTO_REQUESTS' + | 'PTO_BALANCE' + | 'ATTENDANCE' + | 'INVOICE_EXPENSE' + | 'PROJECT' + | 'INVOICES'; + /** + * @description Represents user group ids + * @example "[5b715448b079875110792222", "5b715448b079875110791111"] + */ + visibleToUserGroups?: string[]; + /** + * @description Represents user ids + * @example [ + * "5b715448b079875110791234", + * "5b715448b079875110791432", + * "5b715448b079875110791324" + * ] + */ + visibleToUsers?: string[]; + }; + SharedReportV1: { + filter?: components['schemas']['ReportFilterV1']; + /** + * @description Indicates whether the shared report is fixed date + * @example true + */ + fixedDate?: boolean; + /** + * @description Represents shared report identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + isPublic?: boolean; + /** + * @description Represents shared report name + * @example Weekly 1 + */ + name?: string; + /** + * @example WEEKLY + * @enum {string} + */ + type?: + | 'DETAILED' + | 'WEEKLY' + | 'SUMMARY' + | 'SCHEDULED' + | 'EXPENSE_DETAILED' + | 'EXPENSE_RECEIPT' + | 'PTO_REQUESTS' + | 'PTO_BALANCE' + | 'ATTENDANCE' + | 'INVOICE_EXPENSE' + | 'PROJECT' + | 'INVOICES'; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110791113 + */ + userId?: string; + /** + * @description Indicates to which user groups are visible shared report + * @example [ + * "5b715612b079875110791342", + * "5b715612b079875110791324", + * "5b715612b079875110793142" + * ] + */ + visibleToUserGroups?: string[]; + /** + * @description Indicates to whom users are visible shared report + * @example [ + * "5b715612b079875110791432", + * "5b715612b079875110791234" + * ] + */ + visibleToUsers?: string[]; + /** + * @description Represents workspace identifier across the system. + * @example 5b715612b079875110791112 + */ + workspaceId?: string; + }; + SharedReportsAndCountDtoV1: { + /** + * Format: int32 + * @description Represents the count of reports. + * @example 2 + */ + count?: number; + reports?: components['schemas']['SharedReportDtoV1'][]; + }; + SummaryFilterV1: { + /** + * @description Represents group ids + * @example "[5b715448b07987511071111", "5b715448b079875110792222"] + */ + groups?: string[]; + /** + * @description If provided, you'll get sorted result by provided sort column. + * @example GROUP + * @enum {string} + */ + sortColumn?: + | 'GROUP' + | 'DURATION' + | 'AMOUNT' + | 'EARNED' + | 'COST' + | 'PROFIT'; + /** + * @description If provided, you'll get sorted result by provided summary chart type. + * @example PROJECT + * @enum {string} + */ + summaryChartType?: 'BILLABILITY' | 'PROJECT'; + }; + /** @description List of summary report charts */ + SummaryReportChartDto: { + /** + * @description Represents how much is earned + * @example 1000 + */ + earned?: number; + /** + * @description Represents summary report identifier across the system. + * @example 5b715612b079875110791111 + */ + id?: string; + /** + * @description Represents total amount + * @example 11000 + */ + totalAmount?: number; + /** + * @description Represents total billable time + * @example 19000 + */ + totalBillableTime?: number; + /** + * @description Represents total time + * @example 20000 + */ + totalTime?: number; + }; + /** @description report */ + TimeEntryDetailedReportDto: { + /** @description time entry */ + timeEntries?: { + /** + * @description Represents approval request identifier across the system. + * @example 5b715612b079875110791222 + */ + approvalRequestId?: string; + /** + * @description Indicates whether the time entry is billable + * @example true + */ + billable?: boolean; + /** + * @description Represents client identifier across the system. + * @example 5b715612b079875110791112 + */ + clientId?: string; + /** + * @description Represents client name + * @example Cake.com + */ + clientName?: string; + /** + * @description Represents time entry description + * @example Time Entry Description + */ + description?: string; + /** + * @description Represents time entry identifier across the system. + * @example 5b715612b079875110791111 + */ + get_id?: string; + locked?: boolean; + /** @description Represents project color */ + projectColor?: string; + /** + * @description Represents project identifier across the system. + * @example 5b715612b079875110791133 + */ + projectId?: string; + /** + * @description Represents project name. + * @example Clockify + */ + projectName?: string; + /** @description List of tags */ + tags?: components['schemas']['ReportTagDto'][]; + /** + * @description Represents task identifier across the system. + * @example 5b715612b079875110791134 + */ + taskId?: string; + /** + * @description Represents task name. + * @example Task name + */ + taskName?: string; + timeInterval?: components['schemas']['ReportTimeIntervalDto']; + /** + * @description Represents user email. + * @example user@cake.com + */ + userEmail?: string; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110791135 + */ + userId?: string; + /** + * @description Represents user's name + * @example john + */ + userName?: string; + }; + /** @description List of totals */ + totals?: { + /** @description List of amounts */ + amounts?: components['schemas']['AmountDto'][]; + /** + * Format: int32 + * @description Represents entries count + * @example 1 + */ + entriesCount?: number; + /** + * @description Represents time entry report identifier across the system. + * @example 5b715612b079875110791122 + */ + id?: string; + /** + * @description Represents total billable time + * @example 1000 + */ + totalBillableTime?: number; + /** + * @description Represents total time + * @example 1200 + */ + totalTime?: number; + }; + }; + /** @description report */ + TimeEntrySummaryReportDto: { + /** @description List of summary report charts */ + chart?: components['schemas']['SummaryReportChartDto'][]; + /** @description List of groups */ + groupOne?: components['schemas']['GroupOneDto'][]; + /** @description List of totals */ + totals?: { + /** @description List of amounts */ + amounts?: components['schemas']['AmountDto'][]; + /** + * Format: int32 + * @description Represents entries count + * @example 1 + */ + entriesCount?: number; + /** + * @description Represents time entry report identifier across the system. + * @example 5b715612b079875110791122 + */ + id?: string; + /** + * @description Represents total billable time + * @example 1000 + */ + totalBillableTime?: number; + /** + * @description Represents total time + * @example 1200 + */ + totalTime?: number; + }; + }; + /** @description report */ + TimeEntryWeeklyReportDto: { + /** + * @description Indicates whether time entry report is in decimal format. + * @example false + */ + decimalFormat?: boolean; + /** @description List of groups */ + groupOne?: components['schemas']['GroupOneDto'][]; + /** + * @description Indicates whether time entry report includes users without time. + * @example false + */ + includeUsersWithoutTime?: boolean; + /** @description List of totals */ + totals?: { + /** @description List of amounts */ + amounts?: components['schemas']['AmountDto'][]; + /** + * Format: int32 + * @description Represents entries count + * @example 1 + */ + entriesCount?: number; + /** + * @description Represents time entry report identifier across the system. + * @example 5b715612b079875110791122 + */ + id?: string; + /** + * @description Represents total billable time + * @example 1000 + */ + totalBillableTime?: number; + /** + * @description Represents total time + * @example 1200 + */ + totalTime?: number; + }; + totalsByDay?: components['schemas']['DailyTotalDto'][]; + trackTimeDownToSeconds?: boolean; + usersWithoutTime?: components['schemas']['UserDto'][]; + }; + UpdateSharedReportRequestV1: { + /** + * @description Indicates whether the shared report is fixed date + * @example false + */ + fixedDate?: boolean; + isPublic?: boolean; + /** + * @description Represents shared reports name + * @example Weekly Updated Report + */ + name: string; + public?: boolean; + /** + * @description Provide user groups ids to which the shared report is visible + * @example "[5b715448b079875110792222", "5b715448b079875110791111"] + */ + visibleToUserGroups?: string[]; + /** + * @description Provide user groups ids to which the shared report is visible + * @example [ + * "5b715448b079875110791234", + * "5b715448b079875110791432", + * "5b715448b079875110791324" + * ] + */ + visibleToUsers?: string[]; + }; + UserDto: { + dateFormat?: string; + email?: string; + id?: string; + name?: string; + timeFormat?: string; + timeZone?: string; + weekStart?: string; + }; + WeeklyFilterV1: { + /** + * @description Weekly filter will include group identifier. + * @example 5b715448b079875110791111 + */ + group?: string; + /** + * @description Weekly filter will include subgroup identifier. + * @example 5b715448b079875110792222 + */ + subgroup?: string; + }; + /** @description List of entities */ + entities: { + /** Format: int64 */ + break?: number; + /** Format: int32 */ + capacity?: number; + date?: string; + endTime?: string; + hasRunningEntry?: boolean; + imageUrl?: string; + /** Format: int64 */ + overtime?: number; + startTime?: string; + /** Format: int64 */ + timeOff?: number; + /** Format: int64 */ + totalDuration?: number; + userId?: string; + userName?: string; + }; + /** @description Expense's invoicing info */ + invoicingInfo: { + invoiceId?: string; + manuallyInvoiced?: boolean; + }; + /** @description time entry */ + timeEntries: { + /** + * @description Represents approval request identifier across the system. + * @example 5b715612b079875110791222 + */ + approvalRequestId?: string; + /** + * @description Indicates whether the time entry is billable + * @example true + */ + billable?: boolean; + /** + * @description Represents client identifier across the system. + * @example 5b715612b079875110791112 + */ + clientId?: string; + /** + * @description Represents client name + * @example Cake.com + */ + clientName?: string; + /** + * @description Represents time entry description + * @example Time Entry Description + */ + description?: string; + /** + * @description Represents time entry identifier across the system. + * @example 5b715612b079875110791111 + */ + get_id?: string; + locked?: boolean; + /** @description Represents project color */ + projectColor?: string; + /** + * @description Represents project identifier across the system. + * @example 5b715612b079875110791133 + */ + projectId?: string; + /** + * @description Represents project name. + * @example Clockify + */ + projectName?: string; + /** @description List of tags */ + tags?: components['schemas']['ReportTagDto'][]; + /** + * @description Represents task identifier across the system. + * @example 5b715612b079875110791134 + */ + taskId?: string; + /** + * @description Represents task name. + * @example Task name + */ + taskName?: string; + timeInterval?: components['schemas']['ReportTimeIntervalDto']; + /** + * @description Represents user email. + * @example user@cake.com + */ + userEmail?: string; + /** + * @description Represents user identifier across the system. + * @example 5b715612b079875110791135 + */ + userId?: string; + /** + * @description Represents user's name + * @example john + */ + userName?: string; + }; + /** @description List of totals */ + totals: { + /** @description List of amounts */ + amounts?: components['schemas']['AmountDto'][]; + /** + * Format: int32 + * @description Represents entries count + * @example 1 + */ + entriesCount?: number; + /** + * @description Represents time entry report identifier across the system. + * @example 5b715612b079875110791122 + */ + id?: string; + /** + * @description Represents total billable time + * @example 1000 + */ + totalBillableTime?: number; + /** + * @description Represents total time + * @example 1200 + */ + totalTime?: number; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} + +export type $defs = Record; + +export type external = Record; + +export interface operations { + /** Add photo */ + uploadImage: { + requestBody?: { + content: { + 'multipart/form-data': { + /** + * Format: binary + * @description Image to be uploaded + */ + file: string; + }; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UploadFileResponseV1']; + }; + }; + }; + }; + /** Get currently logged-in user's info */ + getLoggedUser: { + parameters: { + query?: { + /** + * @description If set to true, memberships will be included, otherwise memberships will not be included. + * @example true + */ + 'include-memberships'?: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserDtoV1']; + }; + }; + }; + }; + /** Get all my workspaces */ + getWorkspacesOfUser: { + parameters: { + query?: { + /** + * @description If provided, you'll get a filtered list of workspaces where you have any of the specified roles. Owners are not counted as admins when filtering. + * @example [ + * "WORKSPACE_ADMIN", + * "OWNER" + * ] + */ + roles?: + | 'WORKSPACE_ADMIN' + | 'OWNER' + | 'TEAM_MANAGER' + | 'PROJECT_MANAGER'; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1'][]; + }; + }; + }; + }; + /** Add workspace */ + createWorkspace: { + requestBody: { + content: { + 'application/json': components['schemas']['WorkspaceRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Get workspace info */ + getWorkspaceOfUser: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Get all webhooks for addon on workspace */ + getAddonWebhooks: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents addon identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + addonId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WebhooksDtoV1']; + }; + }; + }; + }; + /** Get approval requests */ + getApprovalGroups: { + parameters: { + query?: { + /** + * @description Filters results based from the provided approval state. + * @example PENDING + */ + status?: + | 'PENDING' + | 'APPROVED' + | 'WITHDRAWN_SUBMISSION' + | 'WITHDRAWN_APPROVAL' + | 'REJECTED'; + /** + * @description Represents the column name to be used as sorting criteria. + * @example START + */ + 'sort-column'?: 'ID' | 'USER_ID' | 'START' | 'UPDATED_AT'; + /** + * @description Represents the sorting order. + * @example ASCENDING + */ + 'sort-order'?: 'ASCENDING' | 'DESCENDING'; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description max page-size 200 + * @example 50 + */ + 'page-size'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ApprovalDetailsDtoV1'][]; + }; + }; + }; + }; + /** Submit approval request */ + createApprrovalRequest: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateApprovalRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['ApprovalRequestDtoV1']; + }; + }; + }; + }; + /** Submit approval request for user */ + createApprovalForOther: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateApprovalRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['ApprovalRequestDtoV1']; + }; + }; + }; + }; + /** Update approval request */ + updateApprovalStatus: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents approval request identifier across the system. + * @example 940ab5acb07987125438b65y + */ + approvalRequestId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateApprovalRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ApprovalRequestDtoV1']; + }; + }; + }; + }; + /** Find clients on workspace */ + getClients: { + parameters: { + query?: { + /** + * @description Filters client results that matches with the string provided in their client name. + * @example Client X + */ + name?: string; + /** + * @description Column name that will be used as criteria for sorting results. + * @example NAME + */ + 'sort-column'?: string; + /** + * @description Sorting mode + * @example ASCENDING + */ + 'sort-order'?: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + /** + * @description Filter whether to include archived clients or not. + * @example false + */ + archived?: boolean; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ClientWithCurrencyDtoV1'][]; + }; + }; + }; + }; + /** Add a new client */ + createClient: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateClientRequestV1']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['ClientWithCurrencyDtoV1']; + }; + }; + }; + }; + /** Get client by ID */ + getClient: { + parameters: { + path: { + /** + * @description Represents client identifier across the system. + * @example 44a687e29ae1f428e7ebe305 + */ + id: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ClientWithCurrencyDtoV1']; + }; + }; + }; + }; + /** Update client */ + updateClient: { + parameters: { + query?: { + 'archive-projects'?: boolean; + 'mark-tasks-as-done'?: boolean; + }; + path: { + /** + * @description Represents client identifier across the system. + * @example 44a687e29ae1f428e7ebe305 + */ + id: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateClientRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ClientDtoV1']; + }; + }; + }; + }; + /** Delete client */ + deleteClient: { + parameters: { + path: { + /** + * @description Represents client identifier across the system. + * @example 44a687e29ae1f428e7ebe305 + */ + id: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ClientDtoV1']; + }; + }; + }; + }; + /** Update workspace cost rate */ + setWorkspaceCostRate: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CostRateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Get custom fields on workspace */ + ofWorkspace: { + parameters: { + query?: { + /** + * @description If provided, you'll get a filtered list of custom fields that contain the provided string in their name. + * @example nationality + */ + name?: string; + /** + * @description If provided, you'll get a filtered list of custom fields that matches the provided string with the custom field status. + * @example VISIBLE + */ + status?: 'INACTIVE' | 'VISIBLE' | 'INVISIBLE'; + /** + * @description If provided, you'll get a filtered list of custom fields that matches the provided string with the custom field entity type. + * @example [ + * "TIMEENTRY", + * "USER" + * ] + */ + entityType?: 'TIMEENTRY' | 'USER'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['CustomFieldDtoV1'][]; + }; + }; + }; + }; + /** Set custom field as required */ + editCustomField: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents custom field identifier across the system. + * @example 26a687e29ae1f428e7ebe101 + */ + customFieldId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateCustomFieldRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['CustomFieldDtoV1']; + }; + }; + }; + }; + /** Get all expenses on workspace */ + getExpenses: { + parameters: { + query?: { + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page-size + * @example 50 + */ + 'page-size'?: string; + /** + * @description If provided, you'll get a filtered result of expenses that matchesthe provided string in the user ID linked to the expense. + * @example 5a0ab5acb07987125438b60f + */ + userId?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ExpensesAndTotalsDtoV1']; + }; + }; + }; + }; + /** Create expense */ + createExpense: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody?: { + content: { + 'multipart/form-data': components['schemas']['CreateExpenseV1Request']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['ExpenseDtoV1']; + }; + }; + }; + }; + /** Get all expense categories */ + getCategories: { + parameters: { + query?: { + /** + * @description Represents the column name to be used as sorting criteria. + * @example NAME + */ + 'sort-column'?: string; + /** + * @description Represents the sorting order. Possible values: ASCENDING, DESCENDING + * @example ASCENDING + */ + 'sort-order'?: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + /** + * @description Flag to filter results based on whether category is archived or not. + * @example true + */ + archived?: string; + /** + * @description If provided, you'll get a filtered list of expense categoriesthat matches the provided string in their name. + * @example procurement + */ + name?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ExpenseCategoriesWithCountDtoV1']; + }; + }; + }; + }; + /** Add expense category */ + createExpenseCategory: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ExpenseCategoryV1Request']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['ExpenseCategoryDtoV1']; + }; + }; + }; + }; + /** Update expense category */ + updateCategory: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents category identifier across the system. + * @example 89a687e29ae1f428e7ebe567 + */ + categoryId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ExpenseCategoryV1Request']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ExpenseCategoryDtoV1']; + }; + }; + }; + }; + /** Delete expense category */ + deleteCategory: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents category identifier across the system. + * @example 89a687e29ae1f428e7ebe567 + */ + categoryId: string; + }; + }; + responses: { + /** @description No Content */ + 204: { + content: never; + }; + }; + }; + /** Archive expense category */ + updateExpenseCategoryStatus: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents category identifier across the system. + * @example 89a687e29ae1f428e7ebe567 + */ + categoryId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ExpenseCategoryArchiveV1Request']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ExpenseCategoryDtoV1']; + }; + }; + }; + }; + /** Get expense by ID */ + getExpense: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents expense identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + expenseId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ExpenseDtoV1']; + }; + }; + }; + }; + /** Update expense */ + updateExpense: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents expense identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + expenseId: string; + }; + }; + requestBody?: { + content: { + 'multipart/form-data': components['schemas']['UpdateExpenseV1Request']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ExpenseDtoV1']; + }; + }; + }; + }; + /** Delete expense */ + deleteExpense: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents expense identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + expenseId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Download receipt */ + downloadFile: { + parameters: { + path: { + /** + * @description Represents file identifier across the system. + * @example 745687e29ae1f428e7ebe890 + */ + fileId: string; + /** + * @description Represents expense identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + expenseId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': string[]; + }; + }; + }; + }; + /** Update workspace billable rate */ + setWorkspaceHourlyRate: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['RateWithCurrencyRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Get all invoices on workspace */ + getInvoices: { + parameters: { + query?: { + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + /** + * @description If provided, you'll get a filtered result of invoices that matches the provided string in the user ID linked to the expense. + * @example UNSENT + */ + statuses?: + | 'UNSENT' + | 'SENT' + | 'PAID' + | 'PARTIALLY_PAID' + | 'VOID' + | 'OVERDUE'; + /** + * @description Valid column name as sorting criteria. Possible values: ID, CLIENT, DUE_ON, ISSUE_DATE, AMOUNT, BALANCE + * @example CLIENT + */ + 'sort-column'?: string; + /** + * @description Possible values: ASCENDING, DESCENDING + * @example ASCENDING + */ + 'sort-order'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['InvoicesListDtoV1']; + }; + }; + }; + }; + /** Add invoice */ + createInvoice: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateInvoiceRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['CreateInvoiceDtoV1']; + }; + }; + }; + }; + /** Filter out invoices */ + getInvoicesInfo: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['InvoiceFilterRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['InvoiceInfoResponseDtoV1']; + }; + }; + }; + }; + /** Get invoice in another language */ + getInvoiceSettings: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['InvoiceSettingsDtoV1']; + }; + }; + }; + }; + /** Change invoice language */ + updateInvoiceSettings: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateInvoiceSettingsRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Get invoice by ID */ + getInvoice: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents invoice identifier across the system. + * @example 83q687e29ae1f428e7ebe195 + */ + invoiceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['InvoiceOverviewDtoV1']; + }; + }; + }; + }; + /** Send invoice */ + updateInvoice: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateInvoiceRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['InvoiceOverviewDtoV1']; + }; + }; + }; + }; + /** Delete invoice */ + deleteInvoice: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Duplicate invoice */ + duplicateInvoice: { + parameters: { + path: { + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['InvoiceOverviewDtoV1']; + }; + }; + }; + }; + /** Export invoice */ + exportInvoice: { + parameters: { + query: { + /** + * @description Represents a locale. + * @example en + */ + userLocale: string; + }; + path: { + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': string[]; + }; + }; + }; + }; + /** Get payments for invoice */ + getPaymentsForInvoice: { + parameters: { + query?: { + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['InvoicePaymentDtoV1'][]; + }; + }; + }; + }; + /** Add payment to invoice */ + createInvoicePayment: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateInvoicePaymentRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['InvoiceOverviewDtoV1']; + }; + }; + }; + }; + /** Delete payment from invoice */ + deletePaymentById: { + parameters: { + path: { + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents payment identifier across the system. + * @example 56p687e29ae1f428e7ebe456 + */ + paymentId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['InvoiceOverviewDtoV1']; + }; + }; + }; + }; + /** Change invoice status */ + changeInvoiceStatus: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents invoice identifier across the system. + * @example 78a687e29ae1f428e7ebe303 + */ + invoiceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ChangeInvoiceStatusRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Get member's profile */ + getMemberProfile: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['MemberProfileDtoV1']; + }; + }; + }; + }; + /** Update member's profile */ + updateMemberProfileWithAdditionalData: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['MemberProfileFullRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['MemberProfileDtoV1']; + }; + }; + }; + }; + /** Update user's email */ + changeUserMemberEmail: { + parameters: { + header?: { + /** + * @description Represents a subdomain name. + * @example coolestcompany + */ + 'Sub-Domain-Name'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ChangeEmailRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Get all projects on workspace */ + getProjects: { + parameters: { + query?: { + /** + * @description If provided, you'll get a filtered list of projects that contains the provided string in the project name. + * @example Software Development + */ + name?: string; + /** @description Flag to toggle on/off strict search mode. */ + 'strict-name-search'?: string; + /** @description If provided, you'll get a filtered list of projects that matches the boolean whether a project is archived or not. */ + archived?: string; + /** @description If provided, you'll get a filtered list of projects that contains the boolean whether a project is billable or not. */ + billable?: string; + /** + * @description If provided, you'll get a filtered list of projects that matches any of the client names provided in the project client. + * @example [ + * "Client X", + * "Client Y" + * ] + */ + clients?: string; + /** @description If set to true, you'll get a filtered list of projects that contains the provided string(s) in the clients. */ + 'contains-client'?: string; + /** + * @description Filters projects based on client status provided. + * @example ACTIVE + */ + 'client-status'?: string; + /** + * @description Valid array of string(s). + * @example [ + * "5a0ab5acb07987125438b60f", + * "64c777ddd3fcab07cfbb210c" + * ] + */ + users?: string; + /** @description If set to true, you'll get a filtered list of projects that contains the provided string(s) in the users. */ + 'contains-user'?: string; + /** + * @description Filters projects based on client status provided. + * @example ALL + */ + 'user-status'?: string; + /** @description Filters projects whether it is used as template or not. */ + 'is-template'?: string; + /** + * @description Sorts the results by the given column/field + * @example NAME + */ + 'sort-column'?: string; + /** + * @description Sorting mode. Possible values: ASCENDING, DESCENDING + * @example ASCENDING + */ + 'sort-order'?: string; + /** @description If set to true, results will contain additional information about the project. */ + hydrated?: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + /** + * @description Valid set of string(s). If provided, you'll get a filtered list of projects that matches the provided access. + * @example PUBLIC + */ + access?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoV1'][]; + }; + }; + }; + }; + /** Add a new project */ + createNewProject: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ProjectRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Find project by ID */ + getProject: { + parameters: { + query?: { + /** @description If set to true, results will contain additional information about the project */ + hydrated?: string; + /** + * @description If provided, you'll get a filtered list of custom fields that matches the provided string with the custom field entity type. + * @example TIMEENTRY + */ + customFieldEntityType?: 'TIMEENTRY' | 'USER'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoV1']; + }; + }; + }; + }; + /** Update project on workspace */ + updateProject: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateProjectRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Delete project from workspace */ + deleteProject: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Get custom fields on project */ + getCustomFieldsOfProject: { + parameters: { + query: { + /** + * @description If provided, you'll get a filtered list of custom fields that matches the provided string with the custom field status. + * @example INACTIVE + */ + status: 'INACTIVE' | 'VISIBLE' | 'INVISIBLE'; + /** @example TIMEENTRY */ + entityType?: 'TIMEENTRY' | 'USER'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['CustomFieldDtoV1'][]; + }; + }; + }; + }; + /** Remove custom field from project */ + removeDefaultValueOfProject: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + projectId: string; + /** + * @description Represents custom field identifier across the system. + * @example 26a687e29ae1f428e7ebe101 + */ + customFieldId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['CustomFieldDtoV1']; + }; + }; + }; + }; + /** Update custom field on project */ + editProjectCustomFieldDefaultValue: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + projectId: string; + /** + * @description Represents custom field identifier across the system. + * @example 26a687e29ae1f428e7ebe101 + */ + customFieldId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CustomFieldProjectDefaultValuesRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['CustomFieldDtoV1']; + }; + }; + }; + }; + /** Update project estimate */ + updateEstimate: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ProjectEstimateRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Assign/remove users to/from the project */ + addUsersToProject: { + parameters: { + path: { + workspaceId: string; + projectId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['AddUsersToProjectRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Update project memberships */ + updateMemberships: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateProjectMembershipsRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Find tasks on project */ + getTasks: { + parameters: { + query?: { + /** + * @description If provided, you'll get a filtered list of tasks that matchesthe provided string in their name. + * @example Bugfixing + */ + name?: string; + /** @description Flag to toggle on/off strict name search mode. */ + 'strict-name-search'?: string; + /** @description Filters search results whether task is active or not. */ + 'is-active'?: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page + * @example 1 + */ + 'page-size'?: string; + /** + * @description Represents the column as criteria for sorting tasks. + * @example ID + */ + 'sort-column'?: string; + /** + * @description Sorting mode. Possible values: ASCENDING, DESCENDING + * @example ASCENDING + */ + 'sort-order'?: string; + }; + path: { + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TaskDtoV1'][]; + }; + }; + }; + }; + /** Add a new task on project */ + createTask: { + parameters: { + query?: { + /** @description Flag to set whetherr task will have assignee or none. Default value is true. */ + 'contains-assignee'?: string; + }; + path: { + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['TaskRequestV1']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['TaskDtoV1']; + }; + }; + }; + }; + /** Update task cost rate */ + setTaskCostRate: { + parameters: { + path: { + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + id: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CostRateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TaskDtoV1']; + }; + }; + }; + }; + /** Update task billable rate */ + setTaskHourlyRate: { + parameters: { + path: { + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + id: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['HourlyRateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TaskDtoV1']; + }; + }; + }; + }; + /** Get task by id */ + getTask: { + parameters: { + path: { + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + taskId: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TaskDtoV1']; + }; + }; + }; + }; + /** Update task on project */ + updateTask: { + parameters: { + query?: { + /** @description Flag to set whetherr task will have assignee or none. Default value is true. */ + 'contains-assignee'?: string; + /** + * @description Represents a membership status. + * @example ACTIVE + */ + 'membership-status'?: + | 'PENDING' + | 'ACTIVE' + | 'DECLINED' + | 'INACTIVE' + | 'ALL'; + }; + path: { + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + taskId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTaskRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TaskDtoV1']; + }; + }; + }; + }; + /** Delete task from project */ + deleteTask: { + parameters: { + path: { + /** + * @description Represents task identifier across the system. + * @example 57a687e29ae1f428e7ebe107 + */ + taskId: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 25b687e29ae1f428e7ebe123 + */ + projectId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TaskDtoV1']; + }; + }; + }; + }; + /** Update project template */ + updateIsProjectTemplate: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['PatchProjectTemplateRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Update project user cost rate */ + addUsersCostRate: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + /** + * @description Represents user identifier across the system. + * @example 4a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CostRateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Update project user billable rate */ + addUsersHourlyRate: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 5b641568b07987035750505e + */ + projectId: string; + /** + * @description Represents user identifier across the system. + * @example 4a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CostRateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ProjectDtoImplV1']; + }; + }; + }; + }; + /** Get all assignments */ + getAllAssignments: { + parameters: { + query?: { + /** + * @description If provided, assignments will be filtered by name + * @example Bugfixing + */ + name?: string; + /** + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + /** + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** + * @description Represents the column as the sorting criteria. + * @example USER + */ + 'sort-column'?: 'PROJECT' | 'USER' | 'ID'; + /** + * @description Represents the sorting mode. + * @example ASCENDING + */ + 'sort-order'?: 'ASCENDING' | 'DESCENDING'; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description max page-size 5000 + * @example 50 + */ + 'page-size'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['AssignmentHydratedDtoV1'][]; + }; + }; + }; + }; + /** Get all scheduled assignments per project */ + getProjectTotals: { + parameters: { + query: { + /** + * @description Represents search keyword + * @example keyword + */ + search?: string; + /** + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start: string; + /** + * @description Represents end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description max page-size 200 + * @example 50 + */ + 'page-size'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['SchedulingProjectsTotalsDtoV1'][]; + }; + }; + }; + }; + /** Get all scheduled assignments on project */ + getProjectTotalsForSingleProject: { + parameters: { + query: { + /** + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start: string; + /** + * @description Represents end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents project identifier across the system. + * @example 56b687e29ae1f428e7ebe504 + */ + projectId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['SchedulingProjectsTotalsDtoV1']; + }; + }; + }; + }; + /** Publish assignments */ + publishAssignments: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['PublishAssignmentsRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Create recurring assignment */ + createRecurring: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['AssignmentCreateRequestV1']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['AssignmentDtoV1'][]; + }; + }; + }; + }; + /** Delete recurring assignment */ + deleteRRecurringAssignment: { + parameters: { + query?: { + /** + * @description Represents a series option. + * @example ALL + */ + seriesUpdateOption?: 'THIS_ONE' | 'THIS_AND_FOLLOWING' | 'ALL'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents assignment identifier across the system. + * @example 5b641568b07987035750505e + */ + assignmentId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['AssignmentDtoV1'][]; + }; + }; + }; + }; + /** Update recurring assignment */ + editRecurring: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents assignment identifier across the system. + * @example 5b641568b07987035750505e + */ + assignmentId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['AssignmentUpdateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['AssignmentDtoV1'][]; + }; + }; + }; + }; + /** Change recurring period */ + editRecurringPeriod: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents assignment identifier across the system. + * @example 5b641568b07987035750505e + */ + assignmentId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['RecurringAssignmentRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['AssignmentDtoV1'][]; + }; + }; + }; + }; + /** Get total of users' capacity on workspace */ + getUserTotals: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['GetUserTotalsRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['SchedulingUsersTotalsDtoV1'][]; + }; + }; + }; + }; + /** Get total capacity of a user */ + getUserTotalsForSingleUser: { + parameters: { + query: { + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page + * @example 50 + */ + 'page-size'?: string; + /** + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start: string; + /** + * @description Represents end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['SchedulingUsersTotalsDtoV1']; + }; + }; + }; + }; + /** Copy scheduled assignment */ + copyAssignment: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents assignment identifier across the system. + * @example 5b641568b07987035750505e + */ + assignmentId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CopyAssignmentRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['AssignmentDtoV1'][]; + }; + }; + }; + }; + /** Find tags on workspace */ + getTags: { + parameters: { + query?: { + /** + * @description If provided, you'll get a filtered list of tags that matches the provided string in their name. + * @example feature_X + */ + name?: string; + /** + * @description Flag to toggle on/off strict search mode. + * @example true + */ + 'strict-name-search'?: string; + /** + * @description Represents a list of excluded ids + * @example [ + * "90p687e29ae1f428e7ebe657", + * "3r8687e29ae1f428e7eg567y" + * ] + */ + excludedIds?: string; + /** + * @description Represents column to be used as sorting criteria. + * @example NAME + */ + 'sort-column'?: string; + /** + * @description Represents sorting mode. Possible values: ASCENDING, DESCENDING + * @example ASCENDING + */ + 'sort-order'?: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + /** + * @description Filters the result whether tags are archived or not. + * @example false + */ + archived?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TagDtoV1'][]; + }; + }; + }; + }; + /** Add a new tag */ + createNewTag: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['TagRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['TagDtoV1']; + }; + }; + }; + }; + /** Get tag by ID */ + getTag: { + parameters: { + path: { + /** + * @description Represents tag identifier across the system. + * @example 21s687e29ae1f428e7ebe404 + */ + id: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TagDtoV1']; + }; + }; + }; + }; + /** Update tag */ + updateTag: { + parameters: { + path: { + /** + * @description Represents tag identifier across the system. + * @example 21s687e29ae1f428e7ebe404 + */ + id: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTagRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TagDtoV1']; + }; + }; + }; + }; + /** Delete tag */ + deleteTag: { + parameters: { + path: { + /** + * @description Represents tag identifier across the system. + * @example 21s687e29ae1f428e7ebe404 + */ + id: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TagDtoV1']; + }; + }; + }; + }; + /** Add a new time entry */ + createTimeEntry: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateTimeEntryRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['TimeEntryDtoImplV1']; + }; + }; + }; + }; + /** Mark time entries as invoiced */ + updateInvoicedStatus: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateInvoicedStatusRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Get a specific time entry on workspace */ + getTimeEntry: { + parameters: { + query?: { + /** @description Flag to set whether to include additional information of a time entry or not. */ + hydrated?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeEntryWithRatesDtoV1']; + }; + }; + }; + }; + /** Update time entry on workspace */ + updateTimeEntry: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTimeEntryRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeEntryDtoImplV1']; + }; + }; + }; + }; + /** Delete time entry from workspace */ + deleteTimeEntry: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + id: string; + }; + }; + responses: { + /** @description No Content */ + 204: { + content: never; + }; + }; + }; + /** Find all groups on workspace */ + getUserGroups: { + parameters: { + query?: { + /** + * @description If provided, you'lll get a filtered list of groups that matches the string provided in their project id. + * @example 5a0ab5acb07987125438b60f + */ + projectId?: string; + /** + * @description If provided, you'lll get a filtered list of groups that matches the string provided in their name. + * @example development_team + */ + name?: string; + /** + * @description Column to be used as the sorting criteria. + * @example NAME + */ + 'sort-column'?: string; + /** + * @description Sorting mode. Possible values: ASCENDING, DESCENDING + * @example ASCENDING + */ + 'sort-order'?: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserGroupDtoV1'][]; + }; + }; + }; + }; + /** Add a new group */ + createUserGroup: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UserGroupRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['UserGroupDtoV1']; + }; + }; + }; + }; + /** Update group */ + updateUserGroup: { + parameters: { + path: { + /** + * @description Represents user group identifier across the system. + * @example 76a687e29ae1f428e7ebe101 + */ + id: string; + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateUserGroupRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserGroupDtoV1']; + }; + }; + }; + }; + /** Delete group */ + deleteUserGroup: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user group identifier across the system. + * @example 76a687e29ae1f428e7ebe101 + */ + id: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserGroupDtoV1']; + }; + }; + }; + }; + /** Add users to group */ + addUser: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user group identifier across the system. + * @example 76a687e29ae1f428e7ebe101 + */ + userGroupId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UserGroupUserRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserGroupDtoV1']; + }; + }; + }; + }; + /** Remove user from group */ + deleteUser: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user group identifier across the system. + * @example 76a687e29ae1f428e7ebe101 + */ + userGroupId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserGroupDtoV1']; + }; + }; + }; + }; + /** Get time entries for a user on workspace */ + getTimeEntries: { + parameters: { + query?: { + /** + * @description Represents a time entry description. + * @example This is a sample time entry description. + */ + description?: string; + /** + * @description Represents start date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2020-01-01T00:00:00Z + */ + start?: string; + /** + * @description Represents end date in yyyy-MM-ddThh:mm:ssZ format. + * @example 2021-01-01T00:00:00Z + */ + end?: string; + /** + * @description If provided, you'll get a filtered list of time entries that matches the provided string in their project id. + * @example 5b641568b07987035750505e + */ + project?: string; + /** + * @description If provided, you'll get a filtered list of time entries that matches the provided string in their task id. + * @example 64c777ddd3fcab07cfbb210c + */ + task?: string; + /** + * @description If provided, you'll get a filtered list of time entries that matches the provided string(s) in their tag id. + * @example [ + * "5e4117fe8c625f38930d57b7", + * "7e4117fe8c625f38930d57b8" + * ] + */ + tags?: string; + /** @description Flag to set whether to require project or not. */ + 'project-required'?: string; + /** @description Flag to set whether to require task or not. */ + 'task-required'?: string; + /** @description Flag to set whether to include additional information on time entries or not. */ + hydrated?: string; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description page size + * @example 50 + */ + 'page-size'?: string; + /** @description Flag to set whether to filter in progress time entries only or not. */ + 'in-progress'?: boolean; + /** + * @description Valid yyyy-MM-ddThh:mm:ssZ format date. If provided, filters results only within the week before the datetime provided. + * @example 2020-01-01T00:00:00Z + */ + 'get-week-before'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeEntryWithRatesDtoV1'][]; + }; + }; + }; + }; + /** Bulk edit time entries */ + replaceMany: { + parameters: { + query?: { + /** @description If set to true, results will contain additional information about the time entry. */ + hydrated?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTimeEntryBulkRequest'][]; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeEntryDtoV1'][]; + }; + }; + }; + }; + /** Add a new time entry for another user on workspace */ + createForOthers: { + parameters: { + query?: { + /** + * @description Represents time entry identifier across the system. + * @example 64c777ddd3fcab07cfbb210c + */ + 'from-entry'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateTimeEntryRequest']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['TimeEntryDtoImplV1']; + }; + }; + }; + }; + /** Delete all time entries for user on workspace */ + deleteMany: { + parameters: { + query: { + /** + * @description Represents a list of time entry ids to delete. + * @example 5a0ab5acb07987125438b60f + */ + 'time-entry-ids': string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeEntryDtoImplV1'][]; + }; + }; + }; + }; + /** Stop currently running timer on workspace for user */ + stopRunningTimeEntry: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['StopTimeEntryRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeEntryDtoImplV1']; + }; + }; + }; + }; + /** Duplicate time entry */ + duplicateTimeEntry: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + id: string; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['TimeEntryDtoImplV1']; + }; + }; + }; + }; + /** Find all users on workspace */ + getUsersOfWorkspace: { + parameters: { + query?: { + /** + * @description If provided, you'll get a filtered list of users that contain the provided string in their email address. + * @example mail@example.com + */ + email?: string; + /** + * @description If provided, you'll get a list of users that have access to the project. + * @example 21a687e29ae1f428e7ebe606 + */ + projectId?: string; + /** + * @description If provided, you'll get a filtered list of users with the corresponding status. + * @example ACTIVE + */ + status?: 'PENDING' | 'ACTIVE' | 'DECLINED' | 'INACTIVE' | 'ALL'; + /** + * @description If provided, you'll get a filtered list of users that contain the provided string in their name + * @example John + */ + name?: string; + /** + * @description Sorting column criteria. Default value is EMAIL. + * @example ID + */ + 'sort-column'?: + | 'ID' + | 'EMAIL' + | 'NAME' + | 'NAME_LOWERCASE' + | 'ACCESS' + | 'HOURLYRATE' + | 'COSTRATE'; + /** + * @description Sorting mode. Default value is ASCENDING. + * @example ASCENDING + */ + 'sort-order'?: 'ASCENDING' | 'DESCENDING'; + /** + * @description Specifies the current page. Default value is 1 + * @example 1 + */ + page?: string; + /** + * @description Specifies the page size. Default value is 50 and max page-size is 5000 + * @example 50 + */ + 'page-size'?: string; + /** + * @description If provided, you'll get all users along with what workspaces, groups, or projects they have access to. Default value is NONE. + * @example WORKSPACE + */ + memberships?: 'ALL' | 'NONE' | 'WORKSPACE' | 'PROJECT' | 'USERGROUP'; + /** @description If you pass along includeRoles=true, you'll get each user's detailed manager role (including projects and members for whome they're managers) */ + includeRoles?: boolean; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserDtoV1'][]; + }; + }; + }; + }; + /** + * Add user + * @description You can add users to a workspace via API only if that workspace has a paid subscription. If the workspace has a paid subscription, you can add as many users as you want but you are limited by the number of paid user seats on that workspace. + */ + addUsers: { + parameters: { + query?: { + /** @description Indicates whether to send an email when user is added to the workspace. */ + sendEmail?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['AddUserToWorkspaceRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Filter workspace users */ + filterUsersOfWorkspace: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['GetUsersRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserDtoV1'][]; + }; + }; + }; + }; + /** Update user's status */ + updateUserStatus: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateUserStatusRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Remove user from workspace */ + removeMember: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Update user's cost rate */ + setCostRateForUser: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CostRateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Update user's custom field */ + upsertUserCustomFieldValue: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + /** + * @description Represents custom field identifier across the system. + * @example 5e4117fe8c625f38930d57b7 + */ + customFieldId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpsertUserCustomFieldRequestV1']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['UserCustomFieldValueDtoV1']; + }; + }; + }; + }; + /** Update user's hourly rate */ + setHourlyRateForUser: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 89b687e29ae1f428e7ebe912 + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['HourlyRateRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WorkspaceDtoV1']; + }; + }; + }; + }; + /** Find user's team manager */ + getManagersOfUser: { + parameters: { + query?: { + /** + * @description Sorting column criteria + * @example ID + */ + 'sort-column'?: + | 'ID' + | 'EMAIL' + | 'NAME' + | 'NAME_LOWERCASE' + | 'ACCESS' + | 'HOURLYRATE' + | 'COSTRATE'; + /** + * @description Sorting mode + * @example ASCENDING + */ + 'sort-order'?: 'ASCENDING' | 'DESCENDING'; + /** + * @description page + * @example 1 + */ + page?: string; + /** + * @description max page-size 5000 + * @example 50 + */ + 'page-size'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['UserDtoV1'][]; + }; + }; + }; + }; + /** Give user manager role */ + createUserRole: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['RoleRequestV1']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['RoleDetailsDtoV1'][]; + }; + }; + }; + }; + /** Remove user's manager role */ + deleteUserRole: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 5a0ab5acb07987125438b60f + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['RoleRequestV1']; + }; + }; + responses: { + /** @description No Content */ + 204: { + content: never; + }; + }; + }; + /** Get all webhooks on workspace */ + getWebhooks: { + parameters: { + query?: { + /** + * @description Represents a webhook type enum. + * @example USER_CREATED + */ + type?: 'USER_CREATED' | 'SYSTEM' | 'ADDON'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WebhooksDtoV1']; + }; + }; + }; + }; + /** + * Create webhooks + * @description Creating a webhook generates a new token which can be used to verify that the webhook being sent was sent by Clockify, as it will always be present in the header. + */ + createWebhook: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateWebhookRequestV1']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['WebhookDtoV1']; + }; + }; + }; + }; + /** Get a specific webhook by id */ + getWebhook: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents webhook identifier across the system. + * @example 5b715448b0798751107918ab + */ + webhookId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WebhookDtoV1']; + }; + }; + }; + }; + /** Update a webhook */ + updateWebhook: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents webhook identifier across the system. + * @example 5b715448b0798751107918ab + */ + webhookId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateWebhookRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WebhookDtoV1']; + }; + }; + }; + }; + /** Delete webhook */ + deleteWebhook: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents webhook identifier across the system. + * @example 5b715448b0798751107918ab + */ + webhookId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Get logs for a webhook */ + getLogsForWebhook: { + parameters: { + query?: { + page?: number; + size?: number; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + webhookId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['WebhookLogSearchRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['WebhookLogDtoV1'][]; + }; + }; + }; + }; + /** + * Generate new token + * @description Generates a new webhook token and invalidates previous one + */ + generateNewToken: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 64a687e29ae1f428e7ebe303 + */ + workspaceId: string; + /** + * @description Represents webhook identifier across the system. + * @example 5b715448b0798751107918ab + */ + webhookId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['WebhookDtoV1']; + }; + }; + }; + }; + /** Get balance by policy */ + getBalancesForPolicy: { + parameters: { + query?: { + /** @example 1 */ + page?: string; + /** @example 50 */ + 'page-size'?: string; + /** + * @description If provided, you'll get result sorted by sort column. + * @example USER + */ + sort?: 'USER' | 'POLICY' | 'USED' | 'BALANCE' | 'TOTAL'; + /** + * @description Sort result in ascending or descending order + * @example ASCENDING + */ + 'sort-order'?: 'ASCENDING' | 'DESCENDING'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + policyId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['BalancesWithCountDtoV1']; + }; + }; + }; + }; + /** Update balance */ + updateBalancesForUsers: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + policyId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ChangeBalanceRequestV1']; + }; + }; + responses: { + /** @description No Content */ + 204: { + content: never; + }; + }; + }; + /** Get balance by user */ + getBalancesForUser: { + parameters: { + query?: { + /** @description page */ + page?: number; + /** @description max page-size 200 */ + 'page-size'?: number; + /** + * @description Sort result based on given criteria + * @example POLICY + */ + sort?: 'USER' | 'POLICY' | 'USED' | 'BALANCE' | 'TOTAL'; + /** + * @description Sort result by providing sort order. + * @example ASCENDING + */ + 'sort-order'?: 'ASCENDING' | 'DESCENDING'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents user identifier across the system. + * @example 60f924bafdaf031696ec6218 + */ + userId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['BalancesWithCountDtoV1']; + }; + }; + }; + }; + /** Get holidays on workspace */ + getHolidays: { + parameters: { + query?: { + /** + * @description If provided, you'll get a filtered list of holidays assigned to user. + * @example 60f924bafdaf031696ec6218 + */ + 'assigned-to'?: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['HolidayDtoV1'][]; + }; + }; + }; + }; + /** Create holiday */ + createHoliday: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateHolidayRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['HolidayDtoV1']; + }; + }; + }; + }; + /** Get holiday in specific period */ + getHolidaysInPeriod: { + parameters: { + query: { + /** + * @description If provided, you'll get a filtered list of holidays assigned to user. + * @example 60f924bafdaf031696ec6218 + */ + 'assigned-to': string; + /** + * @description If provided, you'll get a filtered list of holidays starting from start date. Expected date format yyyy-mm-dd + * @example 2022-12-03 + */ + start: string; + /** + * @description If provided, you'll get a filtered list of holidays ending by end date. Expected date format yyyy-mm-dd + * @example 2022-12-05 + */ + end: string; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['HolidayDtoV1'][]; + }; + }; + }; + }; + /** Update holiday */ + updateHoliday: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents holiday identifier across the system. + * @example 60f927920658241e3cf35e02 + */ + holidayId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateHolidayRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['HolidayDtoV1']; + }; + }; + }; + }; + /** Delete holiday */ + deleteHoliday: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents holiday identifier across the system. + * @example 60f927920658241e3cf35e02 + */ + holidayId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['HolidayDto']; + }; + }; + }; + }; + /** Get policies on workspace */ + findPoliciesForWorkspace: { + parameters: { + query?: { + /** @description page */ + page?: number; + /** @example 50 */ + 'page-size'?: string; + /** @description Filter resulting policies by name */ + name?: string; + /** + * @description If provided, you'll get a filtered list of policies with the corresponding status. + * @example ACTIVE + */ + status?: 'ACTIVE' | 'ARCHIVED' | 'ALL'; + }; + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['PolicyDtoV1'][]; + }; + }; + }; + }; + /** Create time off policy */ + createPolicy: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreatePolicyRequestV1']; + }; + }; + responses: { + /** @description Created */ + 201: { + content: { + 'application/json': components['schemas']['PolicyDtoV1']; + }; + }; + }; + }; + /** Get time off policy */ + getPolicy: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + id: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['PolicyDtoV1']; + }; + }; + }; + }; + /** Update policy */ + updatePolicy: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + id: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdatePolicyRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['PolicyDtoV1']; + }; + }; + }; + }; + /** Delete policy */ + deletePolicy: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + id: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: never; + }; + }; + }; + /** Change policy status */ + updatePolicyStatus: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + id: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ChangePolicyStatusRequest']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['PolicyDtoV1']; + }; + }; + }; + }; + /** Create time off request (for day policies) */ + createTimeOffRequest: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + policyId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateTimeOffRequestV1Request']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeOffRequestFullDtoNewV1']; + }; + }; + }; + }; + /** Delete request */ + deleteTimeOffRequest: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + policyId: string; + /** + * @description Represents time off request identifier across the system. + * @example 6308850156b7d75ea8fd3fbd + */ + requestId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeOffRequestDtoV1']; + }; + }; + }; + }; + /** Change time off request status */ + changeTimeOffRequestStatus: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + policyId: string; + /** + * @description Represents time off request identifier across the system. + * @example 6308850156b7d75ea8fd3fbd + */ + requestId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['StatusTimeOffRequestRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeOffRequestDtoV1']; + }; + }; + }; + }; + /** Create time off request */ + createTimeOffRequestForOther: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + /** + * @description Represents policy identifier across the system. + * @example 63034cd0cb0fb876a57e93ad + */ + policyId: string; + /** + * @description Represents user identifier across the system. + * @example 60f924bafdaf031696ec6218 + */ + userId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateTimeOffRequestV1Request']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeOffRequestFullDtoNewV1']; + }; + }; + }; + }; + /** Get all time off requests on workspace */ + getTimeOffRequests: { + parameters: { + path: { + /** + * @description Represents workspace identifier across the system. + * @example 60f91b3ffdaf031696ec61a8 + */ + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['GetTimeOffRequestsV1Request']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['TimeOffRequestsWithCountDtoV1']; + }; + }; + }; + }; + /** + * Generate shared report by ID + * @description Response depends on report type and export type. Given example is for SUMMARY report and JSON exportType. + */ + generateSharedReportV1: { + parameters: { + query?: { + dateRangeStart?: string; + dateRangeEnd?: string; + sortOrder?: string; + sortColumn?: string; + exportType?: string; + page?: number; + pageSize?: number; + }; + path: { + id: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['TimeEntrySummaryReportDto']; + }; + }; + }; + }; + /** Generate attendance report */ + generateAttendanceReport: { + parameters: { + path: { + workspaceId: string; + }; + }; + requestBody?: { + content: { + 'application/json': components['schemas']['ReportFilterV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['AttendanceReportDtoV1']; + }; + }; + }; + }; + /** Detailed report */ + generateDetailedReport: { + parameters: { + path: { + workspaceId: string; + }; + }; + requestBody?: { + content: { + 'application/json': components['schemas']['ReportFilterV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['TimeEntryDetailedReportDto']; + }; + }; + }; + }; + /** Generate expense report */ + generateDetailedReportV1: { + parameters: { + path: { + workspaceId: string; + }; + }; + requestBody?: { + content: { + 'application/json': components['schemas']['ExpenseReportFilterV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + 'application/json': components['schemas']['ExpenseDetailedReportDtoV1']; + }; + }; + }; + }; + /** Summary report */ + generateSummaryReport: { + parameters: { + path: { + workspaceId: string; + }; + }; + requestBody?: { + content: { + 'application/json': components['schemas']['ReportFilterV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['TimeEntrySummaryReportDto']; + }; + }; + }; + }; + /** Weekly report */ + generateWeeklyReport: { + parameters: { + path: { + workspaceId: string; + }; + }; + requestBody?: { + content: { + 'application/json': components['schemas']['ReportFilterV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['TimeEntryWeeklyReportDto']; + }; + }; + }; + }; + /** + * Get all my shared reports + * @description Gets all shared reports for current user on given workspace + */ + getSharedReportsV1: { + parameters: { + query?: { + page?: number; + pageSize?: number; + sharedReportsFilter?: 'ALL' | 'CREATED_BY_ME' | 'SHARED_WITH_ME'; + }; + path: { + workspaceId: string; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['SharedReportsAndCountDtoV1']; + }; + }; + }; + }; + /** + * Create shared report + * @description Saves shared report with name, options and report filter + */ + saveSharedReportV1: { + parameters: { + path: { + workspaceId: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['SharedReportRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['SharedReportV1']; + }; + }; + }; + }; + /** + * Update shared report + * @description Updates shared report name and/or options + */ + updateSharedReportV1: { + parameters: { + path: { + workspaceId: string; + id: string; + }; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateSharedReportRequestV1']; + }; + }; + responses: { + /** @description OK */ + 200: { + content: { + '*/*': components['schemas']['SharedReportV1']; + }; + }; + }; + }; + /** Delete shared report */ + deleteSharedReportV1: { + parameters: { + path: { + id: string; + workspaceId: string; + }; + }; + responses: { + /** @description Success */ + 204: { + content: never; + }; + }; + }; +} diff --git a/nodes/clockify-enhanced/src/index.ts b/nodes/clockify-enhanced/src/index.ts new file mode 100644 index 00000000..6153763a --- /dev/null +++ b/nodes/clockify-enhanced/src/index.ts @@ -0,0 +1 @@ +export * from './nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node'; diff --git a/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.json b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.json new file mode 100644 index 00000000..2149d865 --- /dev/null +++ b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.json @@ -0,0 +1,18 @@ +{ + "node": "n8n-nodes-base.clockifyEnhancedTrigger", + "nodeVersion": "1.0", + "codexVersion": "1.0", + "categories": ["Productivity"], + "resources": { + "credentialDocumentation": [ + { + "url": "https://github.com/skriptfabrik/n8n-nodes/blob/main/nodes/clockify-enhanced/README.md" + } + ], + "primaryDocumentation": [ + { + "url": "https://github.com/skriptfabrik/n8n-nodes/blob/main/nodes/clockify-enhanced/README.md" + } + ] + } +} diff --git a/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.spec.ts b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.spec.ts new file mode 100644 index 00000000..cd45446c --- /dev/null +++ b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.spec.ts @@ -0,0 +1,870 @@ +import type { Request } from 'express'; +import { mock, mockClear, mockDeep } from 'jest-mock-extended'; +import { clockifyApiRequest } from 'n8n-nodes-base/dist/nodes/Clockify/GenericFunctions'; +import type { + IHookFunctions, + ILoadOptionsFunctions, + IWebhookFunctions, +} from 'n8n-workflow'; +import { ClockifyEnhancedTrigger } from './ClockifyEnhancedTrigger.node'; + +jest.mock('n8n-nodes-base/dist/nodes/Clockify/GenericFunctions'); + +describe('ClockifyEnhancedTrigger', () => { + const hookFunctions = mockDeep(); + const loadOptionsFunctions = mockDeep(); + const webhookFunctions = mockDeep(); + + let trigger: ClockifyEnhancedTrigger; + + beforeEach(() => { + trigger = new ClockifyEnhancedTrigger(); + }); + + afterEach(() => { + mockClear(hookFunctions); + mockClear(loadOptionsFunctions); + mockClear(webhookFunctions); + }); + + it('should be defined', () => { + expect(trigger).toBeDefined(); + }); + + it('should load workspaces', () => { + jest.mocked(clockifyApiRequest).mockResolvedValue([ + { + costRate: { + amount: 10500, + currency: 'USD', + }, + currencies: [ + { + code: 'USD', + id: '5b641568b07987035750505e', + isDefault: true, + }, + ], + featureSubscriptionType: 'PREMIUM', + features: ['ADD_TIME_FOR_OTHERS', 'ADMIN_PANEL', 'ALERTS', 'APPROVAL'], + hourlyRate: { + amount: 10500, + currency: 'USD', + }, + id: '64a687e29ae1f428e7ebe303', + imageUrl: 'https://www.url.com/imageurl-1234567890.jpg', + memberships: [ + { + costRate: { + amount: 10500, + currency: 'USD', + }, + hourlyRate: { + amount: 10500, + currency: 'USD', + }, + membershipStatus: 'PENDING', + membershipType: 'PROJECT', + targetId: '64c777ddd3fcab07cfbb210c', + userId: '5a0ab5acb07987125438b60f', + }, + ], + name: 'Cool Company', + workspaceSettings: { + adminOnlyPages: '["PROJECT","TEAM","REPORTS"]', + automaticLock: { + changeDay: 'FRIDAY', + dayOfMonth: 15, + firstDay: 'MONDAY', + olderThanPeriod: 'DAYS', + olderThanValue: 5, + type: 'WEEKLY', + }, + canSeeTimeSheet: true, + canSeeTracker: true, + currencyFormat: 'CURRENCY_SPACE_VALUE', + defaultBillableProjects: true, + forceDescription: true, + forceProjects: true, + forceTags: true, + forceTasks: true, + isProjectPublicByDefault: true, + lockTimeEntries: 'string', + lockTimeZone: 'string', + multiFactorEnabled: true, + numberFormat: 'COMMA_PERIOD', + onlyAdminsCreateProject: true, + onlyAdminsCreateTag: true, + onlyAdminsCreateTask: true, + onlyAdminsSeeAllTimeEntries: true, + onlyAdminsSeeBillableRates: true, + onlyAdminsSeeDashboard: true, + onlyAdminsSeePublicProjectsEntries: true, + projectFavorites: true, + projectGroupingLabel: 'Project Label', + projectPickerSpecialFilter: true, + round: { + minutes: 'string', + round: 'string', + }, + timeRoundingInReports: true, + timeTrackingMode: 'DEFAULT', + trackTimeDownToSecond: true, + }, + }, + ]); + + expect( + trigger.methods.loadOptions.listWorkspaces.call(loadOptionsFunctions), + ).resolves.toEqual([ + { + name: 'Cool Company', + value: '64a687e29ae1f428e7ebe303', + }, + ]); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'GET', + 'workspaces', + ); + }); + + it('should not load workspaces because of undefined name', () => { + jest.mocked(clockifyApiRequest).mockResolvedValue([ + { + costRate: { + amount: 10500, + currency: 'USD', + }, + currencies: [ + { + code: 'USD', + id: '5b641568b07987035750505e', + isDefault: true, + }, + ], + featureSubscriptionType: 'PREMIUM', + features: ['ADD_TIME_FOR_OTHERS', 'ADMIN_PANEL', 'ALERTS', 'APPROVAL'], + hourlyRate: { + amount: 10500, + currency: 'USD', + }, + id: '64a687e29ae1f428e7ebe303', + imageUrl: 'https://www.url.com/imageurl-1234567890.jpg', + memberships: [ + { + costRate: { + amount: 10500, + currency: 'USD', + }, + hourlyRate: { + amount: 10500, + currency: 'USD', + }, + membershipStatus: 'PENDING', + membershipType: 'PROJECT', + targetId: '64c777ddd3fcab07cfbb210c', + userId: '5a0ab5acb07987125438b60f', + }, + ], + name: undefined, + workspaceSettings: { + adminOnlyPages: '["PROJECT","TEAM","REPORTS"]', + automaticLock: { + changeDay: 'FRIDAY', + dayOfMonth: 15, + firstDay: 'MONDAY', + olderThanPeriod: 'DAYS', + olderThanValue: 5, + type: 'WEEKLY', + }, + canSeeTimeSheet: true, + canSeeTracker: true, + currencyFormat: 'CURRENCY_SPACE_VALUE', + defaultBillableProjects: true, + forceDescription: true, + forceProjects: true, + forceTags: true, + forceTasks: true, + isProjectPublicByDefault: true, + lockTimeEntries: 'string', + lockTimeZone: 'string', + multiFactorEnabled: true, + numberFormat: 'COMMA_PERIOD', + onlyAdminsCreateProject: true, + onlyAdminsCreateTag: true, + onlyAdminsCreateTask: true, + onlyAdminsSeeAllTimeEntries: true, + onlyAdminsSeeBillableRates: true, + onlyAdminsSeeDashboard: true, + onlyAdminsSeePublicProjectsEntries: true, + projectFavorites: true, + projectGroupingLabel: 'Project Label', + projectPickerSpecialFilter: true, + round: { + minutes: 'string', + round: 'string', + }, + timeRoundingInReports: true, + timeTrackingMode: 'DEFAULT', + trackTimeDownToSecond: true, + }, + }, + ]); + + expect( + trigger.methods.loadOptions.listWorkspaces.call(loadOptionsFunctions), + ).resolves.toEqual([]); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'GET', + 'workspaces', + ); + }); + + it('should not load workspaces because of undefined id', () => { + jest.mocked(clockifyApiRequest).mockResolvedValue([ + { + costRate: { + amount: 10500, + currency: 'USD', + }, + currencies: [ + { + code: 'USD', + id: '5b641568b07987035750505e', + isDefault: true, + }, + ], + featureSubscriptionType: 'PREMIUM', + features: ['ADD_TIME_FOR_OTHERS', 'ADMIN_PANEL', 'ALERTS', 'APPROVAL'], + hourlyRate: { + amount: 10500, + currency: 'USD', + }, + id: undefined, + imageUrl: 'https://www.url.com/imageurl-1234567890.jpg', + memberships: [ + { + costRate: { + amount: 10500, + currency: 'USD', + }, + hourlyRate: { + amount: 10500, + currency: 'USD', + }, + membershipStatus: 'PENDING', + membershipType: 'PROJECT', + targetId: '64c777ddd3fcab07cfbb210c', + userId: '5a0ab5acb07987125438b60f', + }, + ], + name: 'Cool Company', + workspaceSettings: { + adminOnlyPages: '["PROJECT","TEAM","REPORTS"]', + automaticLock: { + changeDay: 'FRIDAY', + dayOfMonth: 15, + firstDay: 'MONDAY', + olderThanPeriod: 'DAYS', + olderThanValue: 5, + type: 'WEEKLY', + }, + canSeeTimeSheet: true, + canSeeTracker: true, + currencyFormat: 'CURRENCY_SPACE_VALUE', + defaultBillableProjects: true, + forceDescription: true, + forceProjects: true, + forceTags: true, + forceTasks: true, + isProjectPublicByDefault: true, + lockTimeEntries: 'string', + lockTimeZone: 'string', + multiFactorEnabled: true, + numberFormat: 'COMMA_PERIOD', + onlyAdminsCreateProject: true, + onlyAdminsCreateTag: true, + onlyAdminsCreateTask: true, + onlyAdminsSeeAllTimeEntries: true, + onlyAdminsSeeBillableRates: true, + onlyAdminsSeeDashboard: true, + onlyAdminsSeePublicProjectsEntries: true, + projectFavorites: true, + projectGroupingLabel: 'Project Label', + projectPickerSpecialFilter: true, + round: { + minutes: 'string', + round: 'string', + }, + timeRoundingInReports: true, + timeTrackingMode: 'DEFAULT', + trackTimeDownToSecond: true, + }, + }, + ]); + + expect( + trigger.methods.loadOptions.listWorkspaces.call(loadOptionsFunctions), + ).resolves.toEqual([]); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'GET', + 'workspaces', + ); + }); + + it('should check that a webhook exists', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const webhookAuthToken = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE'; + const webhookId = '76a687e29ae1f428e7ebe101'; + const webhookUrl = + 'http://localhost:5678/webhook/c940f948-0c2e-4cba-9d47-1b38790d77bb'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken: undefined, + webhookId: undefined, + }; + + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + jest.mocked(clockifyApiRequest).mockResolvedValue({ + webhooks: [ + { + authToken: webhookAuthToken, + enabled: true, + id: webhookId, + name: 'stripe', + triggerSource: [ + '54a687e29ae1f428e7ebe909', + '87p187e29ae1f428e7ebej56', + ], + triggerSourceType: 'PROJECT_ID', + url: 'http://localhost:5678/webhook/c940f948-0c2e-4cba-9d47-1b38790d77bb', + userId: '5a0ab5acb07987125438b60f', + webhookEvent: 'NEW_PROJECT', + workspaceId: '64a687e29ae1f428e7ebe303', + }, + ], + workspaceWebhookCount: 5, + }); + hookFunctions.getNodeWebhookUrl + .calledWith('default') + .mockReturnValue(webhookUrl); + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + + expect( + trigger.webhookMethods.default.checkExists.call(hookFunctions), + ).resolves.toBe(true); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'GET', + `workspaces/${workspaceId}/webhooks`, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBe(webhookAuthToken); + expect(staticData.webhookId).toBe(webhookId); + }); + + it('should check that a webhook does not exist because of invalid response', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken: undefined, + webhookId: undefined, + }; + + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + jest.mocked(clockifyApiRequest).mockResolvedValue({ + webhooks: undefined, + }); + + expect( + trigger.webhookMethods.default.checkExists.call(hookFunctions), + ).resolves.toBe(false); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'GET', + `workspaces/${workspaceId}/webhooks`, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBeUndefined(); + expect(staticData.webhookId).toBeUndefined(); + }); + + it('should check that a webhook does not exist', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const webhookAuthToken = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE'; + const webhookId = '76a687e29ae1f428e7ebe101'; + const webhookUrl = + 'http://localhost:5678/webhook/985dc3e9-b382-4dd0-922e-0ceee97023e9'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken: undefined, + webhookId: undefined, + }; + + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + jest.mocked(clockifyApiRequest).mockResolvedValue({ + webhooks: [ + { + authToken: webhookAuthToken, + enabled: true, + id: webhookId, + name: 'stripe', + triggerSource: [ + '54a687e29ae1f428e7ebe909', + '87p187e29ae1f428e7ebej56', + ], + triggerSourceType: 'PROJECT_ID', + url: 'http://localhost:5678/webhook/c940f948-0c2e-4cba-9d47-1b38790d77bb', + userId: '5a0ab5acb07987125438b60f', + webhookEvent: 'NEW_PROJECT', + workspaceId: '64a687e29ae1f428e7ebe303', + }, + ], + workspaceWebhookCount: 5, + }); + hookFunctions.getNodeWebhookUrl + .calledWith('default') + .mockReturnValue(webhookUrl); + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + + expect( + trigger.webhookMethods.default.checkExists.call(hookFunctions), + ).resolves.toBe(false); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'GET', + `workspaces/${workspaceId}/webhooks`, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBeUndefined(); + expect(staticData.webhookId).toBeUndefined(); + }); + + it('should create webhook', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const name = 'stripe'; + const webhookUrl = + 'http://localhost:5678/webhook/985dc3e9-b382-4dd0-922e-0ceee97023e9'; + const webhookEvent = 'NEW_PROJECT'; + const webhookAuthToken = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE'; + const webhookId = '76a687e29ae1f428e7ebe101'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken: undefined, + webhookId: undefined, + }; + + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + hookFunctions.getNodeParameter.calledWith('name').mockReturnValue(name); + hookFunctions.getNodeWebhookUrl + .calledWith('default') + .mockReturnValue(webhookUrl); + hookFunctions.getNodeParameter + .calledWith('webhookEvent') + .mockReturnValue(webhookEvent); + jest.mocked(clockifyApiRequest).mockResolvedValue({ + authToken: webhookAuthToken, + enabled: true, + id: webhookId, + name: 'stripe', + triggerSource: ['54a687e29ae1f428e7ebe909', '87p187e29ae1f428e7ebej56'], + triggerSourceType: 'PROJECT_ID', + url: 'http://localhost:5678/webhook/c940f948-0c2e-4cba-9d47-1b38790d77bb', + userId: '5a0ab5acb07987125438b60f', + webhookEvent: 'NEW_PROJECT', + workspaceId: '64a687e29ae1f428e7ebe303', + }); + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + + expect( + trigger.webhookMethods.default.create.call(hookFunctions), + ).resolves.toBe(true); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'POST', + `workspaces/${workspaceId}/webhooks`, + { + name, + triggerSource: [], + triggerSourceType: 'WORKSPACE_ID', + url: webhookUrl, + webhookEvent, + }, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBe(webhookAuthToken); + expect(staticData.webhookId).toBe(webhookId); + }); + + it('should not create webhook because of undefined auth token', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const name = 'stripe'; + const webhookUrl = + 'http://localhost:5678/webhook/985dc3e9-b382-4dd0-922e-0ceee97023e9'; + const webhookEvent = 'NEW_PROJECT'; + const webhookAuthToken = undefined; + const webhookId = '76a687e29ae1f428e7ebe101'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken: undefined, + webhookId: undefined, + }; + + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + hookFunctions.getNodeParameter.calledWith('name').mockReturnValue(name); + hookFunctions.getNodeWebhookUrl + .calledWith('default') + .mockReturnValue(webhookUrl); + hookFunctions.getNodeParameter + .calledWith('webhookEvent') + .mockReturnValue(webhookEvent); + jest.mocked(clockifyApiRequest).mockResolvedValue({ + authToken: webhookAuthToken, + enabled: true, + id: webhookId, + name: 'stripe', + triggerSource: ['54a687e29ae1f428e7ebe909', '87p187e29ae1f428e7ebej56'], + triggerSourceType: 'PROJECT_ID', + url: 'http://localhost:5678/webhook/c940f948-0c2e-4cba-9d47-1b38790d77bb', + userId: '5a0ab5acb07987125438b60f', + webhookEvent: 'NEW_PROJECT', + workspaceId: '64a687e29ae1f428e7ebe303', + }); + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + + expect( + trigger.webhookMethods.default.create.call(hookFunctions), + ).resolves.toBe(false); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'POST', + `workspaces/${workspaceId}/webhooks`, + { + name, + triggerSource: [], + triggerSourceType: 'WORKSPACE_ID', + url: webhookUrl, + webhookEvent, + }, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBeUndefined(); + expect(staticData.webhookId).toBeUndefined(); + }); + + it('should not create webhook because of undefined id', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const name = 'stripe'; + const webhookUrl = + 'http://localhost:5678/webhook/985dc3e9-b382-4dd0-922e-0ceee97023e9'; + const webhookEvent = 'NEW_PROJECT'; + const webhookAuthToken = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE'; + const webhookId = undefined; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken: undefined, + webhookId: undefined, + }; + + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + hookFunctions.getNodeParameter.calledWith('name').mockReturnValue(name); + hookFunctions.getNodeWebhookUrl + .calledWith('default') + .mockReturnValue(webhookUrl); + hookFunctions.getNodeParameter + .calledWith('webhookEvent') + .mockReturnValue(webhookEvent); + jest.mocked(clockifyApiRequest).mockResolvedValue({ + authToken: webhookAuthToken, + enabled: true, + id: webhookId, + name: 'stripe', + triggerSource: ['54a687e29ae1f428e7ebe909', '87p187e29ae1f428e7ebej56'], + triggerSourceType: 'PROJECT_ID', + url: 'http://localhost:5678/webhook/c940f948-0c2e-4cba-9d47-1b38790d77bb', + userId: '5a0ab5acb07987125438b60f', + webhookEvent: 'NEW_PROJECT', + workspaceId: '64a687e29ae1f428e7ebe303', + }); + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + + expect( + trigger.webhookMethods.default.create.call(hookFunctions), + ).resolves.toBe(false); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'POST', + `workspaces/${workspaceId}/webhooks`, + { + name, + triggerSource: [], + triggerSourceType: 'WORKSPACE_ID', + url: webhookUrl, + webhookEvent, + }, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBeUndefined(); + expect(staticData.webhookId).toBeUndefined(); + }); + + it('should delete webhook', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const webhookAuthToken = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE'; + const webhookId = '76a687e29ae1f428e7ebe101'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken, + webhookId, + }; + + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + jest.mocked(clockifyApiRequest).mockResolvedValue({}); + + expect( + trigger.webhookMethods.default.delete.call(hookFunctions), + ).resolves.toBe(true); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'DELETE', + `workspaces/${workspaceId}/webhooks/${webhookId}`, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBeUndefined(); + expect(staticData.webhookId).toBeUndefined(); + }); + + it('should not delete webhook because of undefined id', async () => { + const webhookAuthToken = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken, + webhookId: undefined, + }; + + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + + expect( + trigger.webhookMethods.default.delete.call(hookFunctions), + ).resolves.toBe(true); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBe(webhookAuthToken); + expect(staticData.webhookId).toBeUndefined(); + }); + + it('should not delete webhook because of api exception', async () => { + const workspaceId = '64a687e29ae1f428e7ebe303'; + const webhookAuthToken = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI2NGI3YmU3YmUwODM1Yjc2ZDYzOTY5YTciLCJtdWx0aUZhY3RvciI6dHJ1ZSwiaXNzIjoiY2xvY2tpZnkiLCJuYW1lIjoiTWFydGluIExsb3lkIiwiZXhwIjoxNjkzMzY5MzEwLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNjkzMzI2MTEwLCJqdGkiOiJZVGcxT0Raak9XTXRPRGRsWVMwME5qZ3hMVGxpTlRndE5UQmlOVEprTmpOaE'; + const webhookId = '76a687e29ae1f428e7ebe101'; + const staticData: { webhookAuthToken?: string; webhookId?: string } = { + webhookAuthToken, + webhookId, + }; + + hookFunctions.getWorkflowStaticData + .calledWith('node') + .mockReturnValue(staticData); + hookFunctions.getNodeParameter + .calledWith('workspaceId') + .mockReturnValue(workspaceId); + jest.mocked(clockifyApiRequest).mockRejectedValue(new Error()); + + expect( + trigger.webhookMethods.default.delete.call(hookFunctions), + ).resolves.toBe(false); + + expect(jest.mocked(clockifyApiRequest)).toHaveBeenCalledWith( + 'DELETE', + `workspaces/${workspaceId}/webhooks/${webhookId}`, + ); + + await new Promise(process.nextTick); + + expect(staticData.webhookAuthToken).toBe(webhookAuthToken); + expect(staticData.webhookId).toBe(webhookId); + }); + + it('should provide workflow data', () => { + const body = { + id: '_id_', + description: '_description_', + userId: '_user_id_', + billable: false, + projectId: '_project_id_', + timeInterval: { + start: '2024-02-15T00:00:00Z', + end: '2024-02-15T00:30:00Z', + duration: 'PT30M', + }, + workspaceId: '_workspace_id_', + isLocked: false, + hourlyRate: null, + costRate: null, + customFieldValues: [], + type: 'REGULAR', + kioskId: null, + projectCurrency: null, + currentlyRunning: false, + project: { + name: '_project_name_', + clientId: '_client_id_', + workspaceId: '_workspace_id_', + billable: false, + estimate: { + estimate: 'PT0S', + type: 'AUTO', + }, + color: '#000000', + archived: false, + clientName: '_client_name_', + duration: 'PT10H30M', + note: null, + budgetEstimate: null, + timeEstimate: { + estimate: 0, + type: 'AUTO', + resetOption: null, + }, + activeEstimate: 'NONE', + id: '_project_id_', + public: true, + template: false, + }, + task: { + name: '_task_name_', + projectId: '_project_id_', + assigneeId: '', + assigneeIds: [], + estimate: 'PT0S', + status: 'ACTIVE', + workspaceId: '_workspace_id_', + duration: 'PT10H30M30S', + budgetEstimate: 0, + billable: false, + hourlyRate: null, + costRate: null, + id: '_task_id_', + }, + user: { + id: '_user_id_', + name: '_user_name_', + status: 'ACTIVE', + }, + tags: [], + }; + + webhookFunctions.getHeaderData.mockReturnValue({ + 'clockify-signature': '_signature_', + 'clockify-webhook-event-type': '_event_type_', + }); + + webhookFunctions.getWorkflowStaticData.calledWith('node').mockReturnValue({ + webhookAuthToken: '_signature_', + }); + + webhookFunctions.getNodeParameter + .calledWith('webhookEvent') + .mockReturnValueOnce('_event_type_'); + + webhookFunctions.getRequestObject.mockReturnValue(mock({ body })); + + webhookFunctions.helpers.returnJsonArray.mockReturnValue([{ json: body }]); + + expect(trigger.webhook.call(webhookFunctions)).resolves.toEqual({ + workflowData: [[{ json: body }]], + }); + }); + + it('should not provide workflow data because of missing signature header', () => { + webhookFunctions.getHeaderData.mockReturnValue({ + 'clockify-webhook-event-type': '_event_type_', + }); + + expect(trigger.webhook.call(webhookFunctions)).resolves.toEqual({}); + }); + + it('should not provide workflow data because of missing webhook event type header', () => { + webhookFunctions.getHeaderData.mockReturnValue({ + 'clockify-signature': '_signature_', + }); + + expect(trigger.webhook.call(webhookFunctions)).resolves.toEqual({}); + }); + + it('should not provide workflow data because of signature missmatch', () => { + webhookFunctions.getHeaderData.mockReturnValue({ + 'clockify-signature': '_signature_', + 'clockify-webhook-event-type': '_event_type_', + }); + + webhookFunctions.getWorkflowStaticData.calledWith('node').mockReturnValue({ + webhookAuthToken: '_other_signature_', + }); + + expect(trigger.webhook.call(webhookFunctions)).resolves.toEqual({}); + }); + + it('should not provide workflow data because of webhook event type missmatch', () => { + webhookFunctions.getHeaderData.mockReturnValue({ + 'clockify-signature': '_signature_', + 'clockify-webhook-event-type': '_event_type_', + }); + + webhookFunctions.getWorkflowStaticData.calledWith('node').mockReturnValue({ + webhookAuthToken: '_signature_', + }); + + webhookFunctions.getNodeParameter + .calledWith('webhookEvent') + .mockReturnValueOnce('_other_event_type_'); + + expect(trigger.webhook.call(webhookFunctions)).resolves.toEqual({}); + }); +}); diff --git a/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.ts b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.ts new file mode 100644 index 00000000..ff6ea1db --- /dev/null +++ b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/ClockifyEnhancedTrigger.node.ts @@ -0,0 +1,351 @@ +import { clockifyApiRequest } from 'n8n-nodes-base/dist/nodes/Clockify/GenericFunctions'; +import type { + IDataObject, + IHookFunctions, + ILoadOptionsFunctions, + INodePropertyOptions, + INodeType, + INodeTypeDescription, + IWebhookFunctions, + IWebhookResponseData, +} from 'n8n-workflow'; +import { components } from '../../api'; + +export type Workspace = components['schemas']['WorkspaceDtoV1']; +export type Webhook = components['schemas']['WebhookDtoV1']; +export type WebhookCreate = components['schemas']['CreateWebhookRequestV1']; +export type Webhooks = components['schemas']['WebhooksDtoV1']; + +export interface StaticData extends IDataObject { + webhookAuthToken?: string; + webhookId?: string; +} + +export enum WebhookEvent { + APPROVAL_REQUEST_STATUS_UPDATED = 'APPROVAL_REQUEST_STATUS_UPDATED', + BALANCE_UPDATED = 'BALANCE_UPDATED', + INVOICE_UPDATED = 'INVOICE_UPDATED', + NEW_APPROVAL_REQUEST = 'NEW_APPROVAL_REQUEST', + NEW_CLIENT = 'NEW_CLIENT', + NEW_PROJECT = 'NEW_PROJECT', + NEW_TAG = 'NEW_TAG', + NEW_TASK = 'NEW_TASK', + NEW_TIME_ENTRY = 'NEW_TIME_ENTRY', + NEW_TIMER_STARTED = 'NEW_TIMER_STARTED', + TIME_ENTRY_DELETED = 'TIME_ENTRY_DELETED', + TIME_ENTRY_UPDATED = 'TIME_ENTRY_UPDATED', + TIME_OFF_REQUEST_APPROVED = 'TIME_OFF_REQUEST_APPROVED', + TIME_OFF_REQUEST_REJECTED = 'TIME_OFF_REQUEST_REJECTED', + TIME_OFF_REQUEST_WITHDRAWN = 'TIME_OFF_REQUEST_WITHDRAWN', + TIME_OFF_REQUESTED = 'TIME_OFF_REQUESTED', + TIMER_STOPPED = 'TIMER_STOPPED', + USER_ACTIVATED_ON_WORKSPACE = 'USER_ACTIVATED_ON_WORKSPACE', + USER_DEACTIVATED_ON_WORKSPACE = 'USER_DEACTIVATED_ON_WORKSPACE', + USER_DELETED_FROM_WORKSPACE = 'USER_DELETED_FROM_WORKSPACE', + USER_EMAIL_CHANGED = 'USER_EMAIL_CHANGED', + USER_JOINED_WORKSPACE = 'USER_JOINED_WORKSPACE', + USER_UPDATED = 'USER_UPDATED', +} + +export class ClockifyEnhancedTrigger implements INodeType { + description: INodeTypeDescription = { + displayName: 'Clockify Enhanced Trigger', + name: 'clockifyEnhancedTrigger', + icon: 'file:clockify-enhanced.svg', + group: ['trigger'], + version: 1, + subtitle: '={{$parameter["name"]}}', + description: 'Listen to Clockify events', + defaults: { + name: 'Clockify Enhanced Trigger', + }, + inputs: [], + outputs: ['main'], + credentials: [ + { + name: 'clockifyApi', + required: true, + }, + ], + webhooks: [ + { + name: 'default', + httpMethod: 'POST', + responseMode: 'onReceived', + path: 'webhook', + }, + ], + properties: [ + { + displayName: 'Workspace Name or ID', + name: 'workspaceId', + type: 'options', + description: + 'Choose from the list, or specify an ID using an expression', + typeOptions: { + loadOptionsMethod: 'listWorkspaces', + }, + required: true, + default: '', + }, + { + displayName: 'Webhook Name', + name: 'name', + type: 'string', + required: true, + default: '', + }, + { + displayName: 'Webhook Event', + name: 'webhookEvent', + type: 'options', + options: [ + { + name: 'Approval Request Status Updated', + value: WebhookEvent.APPROVAL_REQUEST_STATUS_UPDATED, + }, + { + name: 'Balance Updated', + value: WebhookEvent.BALANCE_UPDATED, + }, + { + name: 'Client Created', + value: WebhookEvent.NEW_CLIENT, + }, + { + name: 'Invoice Created', + value: WebhookEvent.INVOICE_UPDATED, + }, + { + name: 'New Approval Request', + value: WebhookEvent.NEW_APPROVAL_REQUEST, + }, + { + name: 'Project Created', + value: WebhookEvent.NEW_PROJECT, + }, + { + name: 'Tag Created', + value: WebhookEvent.NEW_TAG, + }, + { + name: 'Task Created', + value: WebhookEvent.NEW_TASK, + }, + { + name: 'Time Entry Created', + value: WebhookEvent.NEW_TIME_ENTRY, + }, + { + name: 'Time Entry Deleted', + value: WebhookEvent.TIME_ENTRY_DELETED, + }, + { + name: 'Time Entry Updated', + value: WebhookEvent.TIME_ENTRY_UPDATED, + }, + { + name: 'Time Off Request Approved', + value: WebhookEvent.TIME_OFF_REQUEST_APPROVED, + }, + { + name: 'Time Off Request Rejected', + value: WebhookEvent.TIME_OFF_REQUEST_REJECTED, + }, + { + name: 'Time Off Request Withdrawn', + value: WebhookEvent.TIME_OFF_REQUEST_WITHDRAWN, + }, + { + name: 'Time Off Requested', + value: WebhookEvent.TIME_OFF_REQUESTED, + }, + { + name: 'Timer Started', + value: WebhookEvent.NEW_TIMER_STARTED, + }, + { + name: 'Timer Stopped', + value: WebhookEvent.TIMER_STOPPED, + }, + { + name: 'User Activated On Workspace', + value: WebhookEvent.USER_ACTIVATED_ON_WORKSPACE, + }, + { + name: 'User Deactivated On Workspace', + value: WebhookEvent.USER_DEACTIVATED_ON_WORKSPACE, + }, + { + name: 'User Deleted From Workspace', + value: WebhookEvent.USER_DELETED_FROM_WORKSPACE, + }, + { + name: 'User Email Changed', + value: WebhookEvent.USER_EMAIL_CHANGED, + }, + { + name: 'User Joined Workspace', + value: WebhookEvent.USER_JOINED_WORKSPACE, + }, + { + name: 'User Updated', + value: WebhookEvent.USER_UPDATED, + }, + ], + required: true, + default: `${WebhookEvent.APPROVAL_REQUEST_STATUS_UPDATED}`, + }, + ], + }; + + methods = { + loadOptions: { + async listWorkspaces( + this: ILoadOptionsFunctions, + ): Promise { + const returnData: INodePropertyOptions[] = []; + + const workspaces: Workspace[] = await clockifyApiRequest.call( + this, + 'GET', + 'workspaces', + ); + + for (const workspace of workspaces) { + if (workspace.name === undefined || workspace.id === undefined) { + continue; + } + + returnData.push({ + name: workspace.name, + value: workspace.id, + }); + } + + return returnData; + }, + }, + }; + + webhookMethods = { + default: { + async checkExists(this: IHookFunctions): Promise { + const workspaceId = this.getNodeParameter('workspaceId'); + + const responseData: Webhooks = await clockifyApiRequest.call( + this, + 'GET', + `workspaces/${workspaceId}/webhooks`, + ); + + if (responseData.webhooks === undefined) { + return false; + } + + const webhookUrl = this.getNodeWebhookUrl('default'); + const webhookData: StaticData = this.getWorkflowStaticData('node'); + + for (const webhook of responseData.webhooks) { + if (webhook.url === webhookUrl) { + webhookData.webhookAuthToken = webhook.authToken; + webhookData.webhookId = webhook.id; + return true; + } + } + + return false; + }, + async create(this: IHookFunctions): Promise { + const workspaceId = this.getNodeParameter('workspaceId'); + const name = this.getNodeParameter('name') as string; + const webhookUrl = this.getNodeWebhookUrl('default') as string; + const webhookEvent = this.getNodeParameter( + 'webhookEvent', + ) as WebhookEvent; + + const body: WebhookCreate = { + name, + triggerSource: [], + triggerSourceType: 'WORKSPACE_ID', + url: webhookUrl, + webhookEvent, + }; + + const responseData: Webhook = await clockifyApiRequest.call( + this, + 'POST', + `workspaces/${workspaceId}/webhooks`, + body, + ); + + if ( + responseData.authToken === undefined || + responseData.id === undefined + ) { + return false; + } + + const webhookData: StaticData = this.getWorkflowStaticData('node'); + + webhookData.webhookAuthToken = responseData.authToken; + webhookData.webhookId = responseData.id; + + return true; + }, + async delete(this: IHookFunctions): Promise { + const webhookData: StaticData = this.getWorkflowStaticData('node'); + + if (webhookData.webhookId === undefined) { + return true; + } + + const workspaceId = this.getNodeParameter('workspaceId'); + + try { + await clockifyApiRequest.call( + this, + 'DELETE', + `workspaces/${workspaceId}/webhooks/${webhookData.webhookId}`, + ); + } catch (error) { + return false; + } + + delete webhookData.webhookAuthToken; + delete webhookData.webhookId; + + return true; + }, + }, + }; + + async webhook(this: IWebhookFunctions): Promise { + const headerData = this.getHeaderData(); + + if ( + headerData['clockify-signature'] === undefined || + headerData['clockify-webhook-event-type'] === undefined + ) { + return {}; + } + + const webhookData: StaticData = this.getWorkflowStaticData('node'); + + if (headerData['clockify-signature'] !== webhookData.webhookAuthToken) { + return {}; + } + + const webhookEvent = this.getNodeParameter('webhookEvent'); + + if (headerData['clockify-webhook-event-type'] !== webhookEvent) { + return {}; + } + + const req = this.getRequestObject(); + + return { + workflowData: [this.helpers.returnJsonArray(req.body)], + }; + } +} diff --git a/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/clockify-enhanced.svg b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/clockify-enhanced.svg new file mode 100644 index 00000000..0f174170 --- /dev/null +++ b/nodes/clockify-enhanced/src/nodes/ClockifyEnhanced/clockify-enhanced.svg @@ -0,0 +1 @@ + diff --git a/nodes/clockify-enhanced/tsconfig.json b/nodes/clockify-enhanced/tsconfig.json new file mode 100644 index 00000000..ad777cc6 --- /dev/null +++ b/nodes/clockify-enhanced/tsconfig.json @@ -0,0 +1,28 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "strictBindCallApply": false, + "strictFunctionTypes": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "noImplicitAny": true, + "noImplicitThis": true, + "useUnknownInCatchVariables": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/nodes/clockify-enhanced/tsconfig.lib.json b/nodes/clockify-enhanced/tsconfig.lib.json new file mode 100644 index 00000000..ef03d40e --- /dev/null +++ b/nodes/clockify-enhanced/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/nodes/clockify-enhanced/tsconfig.spec.json b/nodes/clockify-enhanced/tsconfig.spec.json new file mode 100644 index 00000000..d41aea47 --- /dev/null +++ b/nodes/clockify-enhanced/tsconfig.spec.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index e49408a9..74e0b5e4 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -15,6 +15,9 @@ "skipDefaultLibCheck": true, "baseUrl": ".", "paths": { + "@skriptfabrik/n8n-nodes-clockify-enhanced": [ + "nodes/clockify-enhanced/src/index.ts" + ] } }, "exclude": ["node_modules", "tmp"]