diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..93a6f2e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +name: CI/CD Pipeline + +on: + push: + branches: [ main, master, dev ] + pull_request: + branches: [ main, master, dev ] + +jobs: + backend-lint-test-build: + name: Backend CI + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: backend/package-lock.json + + - name: Install System Dependencies + run: sudo apt-get update && sudo apt-get install -y build-essential + + - name: Install Backend Dependencies + working-directory: ./backend + run: npm ci + + - name: Generate Prisma Client + working-directory: ./backend + run: npx prisma generate + + - name: Run Eslint + working-directory: ./backend + run: npm run lint + + - name: Run Backend Tests + working-directory: ./backend + run: npm run test -- --passWithNoTests + + - name: Build Backend + working-directory: ./backend + run: npm run build + + frontend-lint-test-build: + name: Frontend CI + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install Frontend Dependencies + working-directory: ./frontend + run: npm ci + + - name: Run Eslint + working-directory: ./frontend + run: npm run lint + + - name: Run Frontend Tests + working-directory: ./frontend + run: npm run test run + + - name: Build Frontend + working-directory: ./frontend + run: npm run build diff --git a/backend/eslint.config.mjs b/backend/eslint.config.mjs index caebf6e..e0d3b19 100644 --- a/backend/eslint.config.mjs +++ b/backend/eslint.config.mjs @@ -6,7 +6,7 @@ import tseslint from 'typescript-eslint'; export default tseslint.config( { - ignores: ['eslint.config.mjs'], + ignores: ['eslint.config.mjs', '**/*.spec.ts', '**/*.test.ts'], }, eslint.configs.recommended, ...tseslint.configs.recommendedTypeChecked, @@ -28,7 +28,7 @@ export default tseslint.config( rules: { '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-floating-promises': 'warn', - '@typescript-eslint/no-unsafe-argument': 'warn' + '@typescript-eslint/no-unsafe-argument': 'warn', }, }, ); \ No newline at end of file diff --git a/backend/eslint_errors.txt b/backend/eslint_errors.txt new file mode 100644 index 0000000..b765435 --- /dev/null +++ b/backend/eslint_errors.txt @@ -0,0 +1,299 @@ + +> backend@0.1.0 lint +> eslint "{src,apps,libs,test}/**/*.ts" --fix + + +E:\Software_Development\try_ts_fullstack\backend\src\attachment\attachment.resolver.ts + 26:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 26:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 36:46 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 36:51 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\attachment\attachment.service.ts + 87:13 error Avoid referencing unbound methods which may cause unintentional scoping of `this`. +If your function does not access `this`, you can annotate it with `this: void`, or consider using an arrow function instead @typescript-eslint/unbound-method + 150:23 error Promise returned in function argument where a void return was expected @typescript-eslint/no-misused-promises + 159:24 error 'err' is defined but never used @typescript-eslint/no-unused-vars + 176:50 error Unsafe member access .projectId on an `any` value @typescript-eslint/no-unsafe-member-access + 177:52 error Unsafe member access .taskId on an `any` value @typescript-eslint/no-unsafe-member-access + 178:55 error Unsafe member access .commentId on an `any` value @typescript-eslint/no-unsafe-member-access + 180:20 error Unsafe member access .conversationId on an `any` value @typescript-eslint/no-unsafe-member-access + 183:15 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 187:13 error Expected the Promise rejection reason to be an Error @typescript-eslint/prefer-promise-reject-errors + 190:38 error Expected the Promise rejection reason to be an Error @typescript-eslint/prefer-promise-reject-errors + +E:\Software_Development\try_ts_fullstack\backend\src\auth\auth.module.ts + 20:7 error Async method 'useFactory' has no 'await' expression @typescript-eslint/require-await + +E:\Software_Development\try_ts_fullstack\backend\src\auth\auth.service.ts + 9:23 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 9:38 error Unsafe member access .email on an `any` value @typescript-eslint/no-unsafe-member-access + 9:45 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 9:55 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 12:7 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + +E:\Software_Development\try_ts_fullstack\backend\src\auth\decorators\current-user.decorator.ts + 7:5 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 7:29 error Unsafe member access .req on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\auth\guards\gql-auth.guard.ts + 9:5 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 9:29 error Unsafe member access .req on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\auth\guards\project-access.guard.ts + 31:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 31:38 error Unsafe member access .req on an `any` value @typescript-eslint/no-unsafe-member-access + 32:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 35:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 35:26 error Unsafe member access .user on an `any` value @typescript-eslint/no-unsafe-member-access + 41:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 41:28 error Unsafe member access .projectId on an `any` value @typescript-eslint/no-unsafe-member-access + 41:46 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 41:57 error Unsafe member access .input on an `any` value @typescript-eslint/no-unsafe-member-access + 51:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 51:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 52:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + +E:\Software_Development\try_ts_fullstack\backend\src\auth\guards\project-permission.guard.ts + 50:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 50:38 error Unsafe member access .req on an `any` value @typescript-eslint/no-unsafe-member-access + 51:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 54:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 54:26 error Unsafe member access .user on an `any` value @typescript-eslint/no-unsafe-member-access + 60:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 61:12 error Unsafe member access .projectId on an `any` value @typescript-eslint/no-unsafe-member-access + 62:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 63:12 error Unsafe member access .input on an `any` value @typescript-eslint/no-unsafe-member-access + 64:12 error Unsafe member access .updateProjectInput on an `any` value @typescript-eslint/no-unsafe-member-access + 71:5 error Unnecessary try/catch wrapper no-useless-catch + 73:9 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 73:14 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 74:9 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + +E:\Software_Development\try_ts_fullstack\backend\src\auth\guards\roles.guard.ts + 27:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 27:39 error Unsafe member access .req on an `any` value @typescript-eslint/no-unsafe-member-access + 33:55 error Unsafe member access .role on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\auth\guards\ws-jwt.guard.ts + 27:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 32:7 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 34:14 error 'err' is defined but never used @typescript-eslint/no-unused-vars + +E:\Software_Development\try_ts_fullstack\backend\src\auth\strategies\jwt.strategy.ts + 18:26 error Unsafe member access .cookies on an `any` value @typescript-eslint/no-unsafe-member-access + 19:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 19:25 error Unsafe member access .cookies on an `any` value @typescript-eslint/no-unsafe-member-access + 30:49 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 30:57 error Unsafe member access .sub on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\chat\chat.resolver.ts + 20:10 error 'PubSub' is defined but never used @typescript-eslint/no-unused-vars + 139:11 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 139:23 error Unsafe member access .publish on an `any` value @typescript-eslint/no-unsafe-member-access + 157:11 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 157:23 error Unsafe member access .publish on an `any` value @typescript-eslint/no-unsafe-member-access + 171:11 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 171:23 error Unsafe member access .publish on an `any` value @typescript-eslint/no-unsafe-member-access + 190:17 error Unsafe member access .messageSent on an `any` value @typescript-eslint/no-unsafe-member-access + 190:58 error Unsafe member access .conversationId on an `any` value @typescript-eslint/no-unsafe-member-access + 196:50 error 'conversationId' is defined but never used @typescript-eslint/no-unused-vars + 198:5 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 198:12 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 198:24 error Unsafe member access .asyncIterableIterator on an `any` value @typescript-eslint/no-unsafe-member-access + 204:17 error Unsafe member access .messageUpdated on an `any` value @typescript-eslint/no-unsafe-member-access + 204:61 error Unsafe member access .conversationId on an `any` value @typescript-eslint/no-unsafe-member-access + 209:50 error 'conversationId' is defined but never used @typescript-eslint/no-unused-vars + 211:5 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 211:12 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 211:24 error Unsafe member access .asyncIterableIterator on an `any` value @typescript-eslint/no-unsafe-member-access + 217:17 error Unsafe member access .messageDeleted on an `any` value @typescript-eslint/no-unsafe-member-access + 217:61 error Unsafe member access .conversationId on an `any` value @typescript-eslint/no-unsafe-member-access + 220:27 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 220:35 error Unsafe member access .messageDeleted on an `any` value @typescript-eslint/no-unsafe-member-access + 223:50 error 'conversationId' is defined but never used @typescript-eslint/no-unused-vars + 225:5 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 225:12 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 225:24 error Unsafe member access .asyncIterableIterator on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\chat\chat.service.ts + 93:34 error Unsafe member access .title on an `any` value @typescript-eslint/no-unsafe-member-access + 95:15 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 95:28 error Unsafe member access .url on an `any` value @typescript-eslint/no-unsafe-member-access + 96:15 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 96:30 error Unsafe member access .title on an `any` value @typescript-eslint/no-unsafe-member-access + 97:15 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 97:36 error Unsafe member access .description on an `any` value @typescript-eslint/no-unsafe-member-access + 98:15 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 98:30 error Unsafe member access .images on an `any` value @typescript-eslint/no-unsafe-member-access + 98:53 error Unsafe member access .favicons on an `any` value @typescript-eslint/no-unsafe-member-access + 99:15 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 99:33 error Unsafe member access .siteName on an `any` value @typescript-eslint/no-unsafe-member-access + 100:15 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 100:33 error Unsafe member access .favicons on an `any` value @typescript-eslint/no-unsafe-member-access + 105:70 error Unsafe member access .message on an `any` value @typescript-eslint/no-unsafe-member-access + 121:9 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 122:9 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + +E:\Software_Development\try_ts_fullstack\backend\src\comment\comment.resolver.ts + 33:59 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 33:64 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 39:40 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 39:45 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 48:44 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 48:49 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 60:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 60:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 70:43 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 70:48 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 84:51 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 84:56 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 92:50 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 92:55 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\common\decorators\sanitized-string.decorator.ts + 36:30 error '_args' is defined but never used @typescript-eslint/no-unused-vars + +E:\Software_Development\try_ts_fullstack\backend\src\common\filters\global-exception.filter.ts + 9:10 error 'GqlArgumentsHost' is defined but never used @typescript-eslint/no-unused-vars + 22:9 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 22:9 error A `require()` style import is forbidden @typescript-eslint/no-require-imports + 22:33 error Unsafe member access .init on an `any` value @typescript-eslint/no-unsafe-member-access + 25:16 error 'err' is defined but never used @typescript-eslint/no-unused-vars + 55:9 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 55:9 error A `require()` style import is forbidden @typescript-eslint/no-require-imports + 55:33 error Unsafe member access .captureException on an `any` value @typescript-eslint/no-unsafe-member-access + 56:16 error 'err' is defined but never used @typescript-eslint/no-unused-vars + 69:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 70:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 72:7 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 72:7 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 72:16 error Unsafe member access .status on an `any` value @typescript-eslint/no-unsafe-member-access + 72:31 error Unsafe member access .json on an `any` value @typescript-eslint/no-unsafe-member-access + 75:9 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 75:23 error Unsafe member access .url on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\common\interceptors\logging.interceptor.ts + 26:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 27:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 27:39 error Unsafe member access .req on an `any` value @typescript-eslint/no-unsafe-member-access + 29:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 29:31 error Unsafe member access .parentType on an `any` value @typescript-eslint/no-unsafe-member-access + 30:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 30:30 error Unsafe member access .fieldName on an `any` value @typescript-eslint/no-unsafe-member-access + 31:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 31:30 error Unsafe member access .operation on an `any` value @typescript-eslint/no-unsafe-member-access + 33:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 34:14 error Unsafe member access .ip on an `any` value @typescript-eslint/no-unsafe-member-access + 34:25 error Unsafe member access .headers on an `any` value @typescript-eslint/no-unsafe-member-access + 35:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 35:30 error Unsafe member access .headers on an `any` value @typescript-eslint/no-unsafe-member-access + 36:27 error Unsafe member access .user on an `any` value @typescript-eslint/no-unsafe-member-access + 36:50 error Unsafe member access .user on an `any` value @typescript-eslint/no-unsafe-member-access + 39:38 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 39:48 error Unsafe member access .toUpperCase on an `any` value @typescript-eslint/no-unsafe-member-access + 53:107 error Unsafe member access .message on an `any` value @typescript-eslint/no-unsafe-member-access + 61:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 62:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 66:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 66:26 error Unsafe member access .method on an `any` value @typescript-eslint/no-unsafe-member-access + 67:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 67:23 error Unsafe member access .originalUrl on an `any` value @typescript-eslint/no-unsafe-member-access + 67:42 error Unsafe member access .url on an `any` value @typescript-eslint/no-unsafe-member-access + 68:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 68:28 error Unsafe member access .ip on an `any` value @typescript-eslint/no-unsafe-member-access + 68:38 error Unsafe member access .headers on an `any` value @typescript-eslint/no-unsafe-member-access + 69:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 69:29 error Unsafe member access .headers on an `any` value @typescript-eslint/no-unsafe-member-access + 72:13 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 72:24 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 72:28 error Unsafe member access .includes on an `any` value @typescript-eslint/no-unsafe-member-access + 83:19 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 83:36 error Unsafe member access .statusCode on an `any` value @typescript-eslint/no-unsafe-member-access + 93:94 error Unsafe member access .message on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\health\health.controller.ts + 26:28 error Unsafe member access .database on an `any` value @typescript-eslint/no-unsafe-member-access + 30:28 error Unsafe member access .database on an `any` value @typescript-eslint/no-unsafe-member-access + 41:26 error Unsafe member access .memory on an `any` value @typescript-eslint/no-unsafe-member-access + 51:28 error Unsafe member access .memory on an `any` value @typescript-eslint/no-unsafe-member-access + 52:28 error Unsafe member access .memory on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\main.ts + 40:45 warning Unsafe argument of type `any` assigned to a parameter of type `string` @typescript-eslint/no-unsafe-argument + 40:49 error Unsafe member access .method on an `any` value @typescript-eslint/no-unsafe-member-access + 41:7 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 41:14 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 44:11 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 44:24 error Unsafe member access .headers on an `any` value @typescript-eslint/no-unsafe-member-access + 44:49 error Unsafe member access .headers on an `any` value @typescript-eslint/no-unsafe-member-access + 48:7 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 48:14 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 53:7 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 53:14 error Unsafe member access .startsWith on an `any` value @typescript-eslint/no-unsafe-member-access + 57:7 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return + 57:14 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 57:14 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + 57:18 error Unsafe member access .status on an `any` value @typescript-eslint/no-unsafe-member-access + 57:30 error Unsafe member access .json on an `any` value @typescript-eslint/no-unsafe-member-access + 60:5 error Unsafe call of a(n) `any` typed value @typescript-eslint/no-unsafe-call + +E:\Software_Development\try_ts_fullstack\backend\src\project-member\project-member.resolver.ts + 38:54 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 38:59 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 50:50 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 50:55 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 66:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 66:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 81:20 error '_user' is defined but never used @typescript-eslint/no-unused-vars + 99:20 error '_user' is defined but never used @typescript-eslint/no-unused-vars + 117:62 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 117:67 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\project\project.resolver.ts + 39:59 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 39:64 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 54:40 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 54:45 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 66:44 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 66:49 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 82:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 82:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 96:43 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 96:48 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\task\task.resolver.ts + 32:53 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 32:58 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 44:37 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 44:42 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 53:41 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 53:46 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 65:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 65:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 75:40 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 75:45 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + +E:\Software_Development\try_ts_fullstack\backend\src\task\task.service.ts + 3:3 error 'ForbiddenException' is defined but never used @typescript-eslint/no-unused-vars + +E:\Software_Development\try_ts_fullstack\backend\src\timesheet\timesheet.resolver.ts + 21:63 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 21:68 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 32:42 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 32:47 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 41:46 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 41:51 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 53:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 53:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 63:45 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 63:50 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 77:9 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment + 77:28 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 80:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 80:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + 96:7 warning Unsafe argument of type `any` assigned to a parameter of type `number` @typescript-eslint/no-unsafe-argument + 96:12 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access + +✖ 243 problems (207 errors, 36 warnings) + diff --git a/backend/package-lock.json b/backend/package-lock.json index 826d902..f21e816 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,12 +1,12 @@ { "name": "backend", - "version": "0.0.1", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "backend", - "version": "0.0.1", + "version": "0.1.0", "license": "UNLICENSED", "dependencies": { "@apollo/server": "^4.12.2", @@ -20,6 +20,7 @@ "@nestjs/passport": "^11.0.5", "@nestjs/platform-express": "^11.0.1", "@nestjs/platform-socket.io": "^11.1.12", + "@nestjs/throttler": "^6.2.1", "@nestjs/websockets": "^11.1.12", "@prisma/adapter-pg": "^7.2.0", "@prisma/client": "^7.2.0", @@ -30,14 +31,17 @@ "class-validator": "^0.14.3", "cookie-parser": "^1.4.7", "graphql": "^16.11.0", + "graphql-subscriptions": "^3.0.0", "graphql-upload-ts": "^2.1.3", + "helmet": "^8.0.0", "link-preview-js": "^4.0.0", "passport": "^0.7.0", "passport-jwt": "^4.0.1", "pg": "^8.16.3", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", - "socket.io": "^4.8.3" + "socket.io": "^4.8.3", + "xss": "^1.0.15" }, "devDependencies": { "@eslint/eslintrc": "^3.2.0", @@ -3476,6 +3480,17 @@ } } }, + "node_modules/@nestjs/throttler": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@nestjs/throttler/-/throttler-6.5.0.tgz", + "integrity": "sha512-9j0ZRfH0QE1qyrj9JjIRDz5gQLPqq9yVC2nHsrosDVAfI5HHw08/aUAWx9DZLSdQf4HDkmhTTEGLrRFHENvchQ==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", + "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", + "reflect-metadata": "^0.1.13 || ^0.2.0" + } + }, "node_modules/@nestjs/websockets": { "version": "11.1.12", "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-11.1.12.tgz", @@ -9397,6 +9412,15 @@ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, + "node_modules/graphql-subscriptions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-3.0.0.tgz", + "integrity": "sha512-kZCdevgmzDjGAOqH7GlDmQXYAkuHoKpMlJrqF40HMPhUhM5ZWSFSxCwD/nSi6AkaijmMfsFhoJRGJ27UseCvRA==", + "license": "MIT", + "peerDependencies": { + "graphql": "^15.7.2 || ^16.0.0" + } + }, "node_modules/graphql-tag": { "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", @@ -9531,6 +9555,18 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.2.0.tgz", + "integrity": "sha512-DRgTIUgnWcJ62KyarxxziuqYxKGnR6Rgg19BlbucN/dpmJbl1XOit6qvoOX0ZT+HhWe5OUVhU/a1zpGyc1xA0Q==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/EvanHahn" + } + }, "node_modules/hono": { "version": "4.10.6", "resolved": "https://registry.npmjs.org/hono/-/hono-4.10.6.tgz", diff --git a/backend/package.json b/backend/package.json index d0b81f7..388235a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -34,6 +34,7 @@ "@nestjs/passport": "^11.0.5", "@nestjs/platform-express": "^11.0.1", "@nestjs/platform-socket.io": "^11.1.12", + "@nestjs/throttler": "^6.2.1", "@nestjs/websockets": "^11.1.12", "@prisma/adapter-pg": "^7.2.0", "@prisma/client": "^7.2.0", @@ -44,14 +45,17 @@ "class-validator": "^0.14.3", "cookie-parser": "^1.4.7", "graphql": "^16.11.0", + "graphql-subscriptions": "^3.0.0", "graphql-upload-ts": "^2.1.3", + "helmet": "^8.0.0", "link-preview-js": "^4.0.0", "passport": "^0.7.0", "passport-jwt": "^4.0.1", "pg": "^8.16.3", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", - "socket.io": "^4.8.3" + "socket.io": "^4.8.3", + "xss": "^1.0.15" }, "devDependencies": { "@eslint/eslintrc": "^3.2.0", diff --git a/backend/prisma/generated/commonInputTypes.ts b/backend/prisma/generated/commonInputTypes.ts index 0da57b7..9a758e5 100644 --- a/backend/prisma/generated/commonInputTypes.ts +++ b/backend/prisma/generated/commonInputTypes.ts @@ -237,6 +237,62 @@ export type IntNullableFilter<$PrismaModel = never> = { not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null } +export type EnumProjectVisibilityFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectVisibility | Prisma.EnumProjectVisibilityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectVisibilityFilter<$PrismaModel> | $Enums.ProjectVisibility +} + +export type EnumProjectPriorityFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectPriority | Prisma.EnumProjectPriorityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectPriorityFilter<$PrismaModel> | $Enums.ProjectPriority +} + +export type FloatFilter<$PrismaModel = never> = { + equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> + lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> + gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> + not?: Prisma.NestedFloatFilter<$PrismaModel> | number +} + +export type EnumProjectMethodologyFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectMethodology | Prisma.EnumProjectMethodologyFieldRefInput<$PrismaModel> + in?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectMethodologyFilter<$PrismaModel> | $Enums.ProjectMethodology +} + +export type JsonNullableFilter<$PrismaModel = never> = +| Prisma.PatchUndefined< + Prisma.Either>, Exclude>, 'path'>>, + Required> + > +| Prisma.OptionalFlat>, 'path'>> + +export type JsonNullableFilterBase<$PrismaModel = never> = { + equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter + path?: string[] + mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> + string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> + string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> + string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> + array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter +} + export type IntNullableWithAggregatesFilter<$PrismaModel = never> = { equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null @@ -253,15 +309,24 @@ export type IntNullableWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedIntNullableFilter<$PrismaModel> } -export type FloatFilter<$PrismaModel = never> = { - equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> - in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> - notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> - lt?: number | Prisma.FloatFieldRefInput<$PrismaModel> - lte?: number | Prisma.FloatFieldRefInput<$PrismaModel> - gt?: number | Prisma.FloatFieldRefInput<$PrismaModel> - gte?: number | Prisma.FloatFieldRefInput<$PrismaModel> - not?: Prisma.NestedFloatFilter<$PrismaModel> | number +export type EnumProjectVisibilityWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectVisibility | Prisma.EnumProjectVisibilityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectVisibilityWithAggregatesFilter<$PrismaModel> | $Enums.ProjectVisibility + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumProjectVisibilityFilter<$PrismaModel> + _max?: Prisma.NestedEnumProjectVisibilityFilter<$PrismaModel> +} + +export type EnumProjectPriorityWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectPriority | Prisma.EnumProjectPriorityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectPriorityWithAggregatesFilter<$PrismaModel> | $Enums.ProjectPriority + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumProjectPriorityFilter<$PrismaModel> + _max?: Prisma.NestedEnumProjectPriorityFilter<$PrismaModel> } export type FloatWithAggregatesFilter<$PrismaModel = never> = { @@ -280,6 +345,138 @@ export type FloatWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedFloatFilter<$PrismaModel> } +export type EnumProjectMethodologyWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectMethodology | Prisma.EnumProjectMethodologyFieldRefInput<$PrismaModel> + in?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectMethodologyWithAggregatesFilter<$PrismaModel> | $Enums.ProjectMethodology + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumProjectMethodologyFilter<$PrismaModel> + _max?: Prisma.NestedEnumProjectMethodologyFilter<$PrismaModel> +} + +export type JsonNullableWithAggregatesFilter<$PrismaModel = never> = +| Prisma.PatchUndefined< + Prisma.Either>, Exclude>, 'path'>>, + Required> + > +| Prisma.OptionalFlat>, 'path'>> + +export type JsonNullableWithAggregatesFilterBase<$PrismaModel = never> = { + equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter + path?: string[] + mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> + string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> + string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> + string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> + array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _min?: Prisma.NestedJsonNullableFilter<$PrismaModel> + _max?: Prisma.NestedJsonNullableFilter<$PrismaModel> +} + +export type EnumTaskTypeFilter<$PrismaModel = never> = { + equals?: $Enums.TaskType | Prisma.EnumTaskTypeFieldRefInput<$PrismaModel> + in?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskTypeFilter<$PrismaModel> | $Enums.TaskType +} + +export type EnumTaskPriorityFilter<$PrismaModel = never> = { + equals?: $Enums.TaskPriority | Prisma.EnumTaskPriorityFieldRefInput<$PrismaModel> + in?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskPriorityFilter<$PrismaModel> | $Enums.TaskPriority +} + +export type EnumTaskTypeWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.TaskType | Prisma.EnumTaskTypeFieldRefInput<$PrismaModel> + in?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskTypeWithAggregatesFilter<$PrismaModel> | $Enums.TaskType + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumTaskTypeFilter<$PrismaModel> + _max?: Prisma.NestedEnumTaskTypeFilter<$PrismaModel> +} + +export type EnumTaskPriorityWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.TaskPriority | Prisma.EnumTaskPriorityFieldRefInput<$PrismaModel> + in?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskPriorityWithAggregatesFilter<$PrismaModel> | $Enums.TaskPriority + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumTaskPriorityFilter<$PrismaModel> + _max?: Prisma.NestedEnumTaskPriorityFilter<$PrismaModel> +} + +export type DecimalNullableFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null +} + +export type EnumTimesheetSourceFilter<$PrismaModel = never> = { + equals?: $Enums.TimesheetSource | Prisma.EnumTimesheetSourceFieldRefInput<$PrismaModel> + in?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + notIn?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTimesheetSourceFilter<$PrismaModel> | $Enums.TimesheetSource +} + +export type EnumApprovalStatusFilter<$PrismaModel = never> = { + equals?: $Enums.ApprovalStatus | Prisma.EnumApprovalStatusFieldRefInput<$PrismaModel> + in?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumApprovalStatusFilter<$PrismaModel> | $Enums.ApprovalStatus +} + +export type DecimalNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _min?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _max?: Prisma.NestedDecimalNullableFilter<$PrismaModel> +} + +export type EnumTimesheetSourceWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.TimesheetSource | Prisma.EnumTimesheetSourceFieldRefInput<$PrismaModel> + in?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + notIn?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTimesheetSourceWithAggregatesFilter<$PrismaModel> | $Enums.TimesheetSource + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumTimesheetSourceFilter<$PrismaModel> + _max?: Prisma.NestedEnumTimesheetSourceFilter<$PrismaModel> +} + +export type EnumApprovalStatusWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ApprovalStatus | Prisma.EnumApprovalStatusFieldRefInput<$PrismaModel> + in?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumApprovalStatusWithAggregatesFilter<$PrismaModel> | $Enums.ApprovalStatus + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumApprovalStatusFilter<$PrismaModel> + _max?: Prisma.NestedEnumApprovalStatusFilter<$PrismaModel> +} + export type EnumProjectRoleFilter<$PrismaModel = never> = { equals?: $Enums.ProjectRole | Prisma.EnumProjectRoleFieldRefInput<$PrismaModel> in?: $Enums.ProjectRole[] | Prisma.ListEnumProjectRoleFieldRefInput<$PrismaModel> @@ -314,30 +511,6 @@ export type EnumConversationTypeWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedEnumConversationTypeFilter<$PrismaModel> } -export type JsonNullableFilter<$PrismaModel = never> = -| Prisma.PatchUndefined< - Prisma.Either>, Exclude>, 'path'>>, - Required> - > -| Prisma.OptionalFlat>, 'path'>> - -export type JsonNullableFilterBase<$PrismaModel = never> = { - equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter - path?: string[] - mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> - string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> - string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> - string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> - array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter -} - export type EnumMessageTypeFilter<$PrismaModel = never> = { equals?: $Enums.MessageType | Prisma.EnumMessageTypeFieldRefInput<$PrismaModel> in?: $Enums.MessageType[] | Prisma.ListEnumMessageTypeFieldRefInput<$PrismaModel> @@ -345,33 +518,6 @@ export type EnumMessageTypeFilter<$PrismaModel = never> = { not?: Prisma.NestedEnumMessageTypeFilter<$PrismaModel> | $Enums.MessageType } -export type JsonNullableWithAggregatesFilter<$PrismaModel = never> = -| Prisma.PatchUndefined< - Prisma.Either>, Exclude>, 'path'>>, - Required> - > -| Prisma.OptionalFlat>, 'path'>> - -export type JsonNullableWithAggregatesFilterBase<$PrismaModel = never> = { - equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter - path?: string[] - mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> - string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> - string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> - string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> - array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter - _count?: Prisma.NestedIntNullableFilter<$PrismaModel> - _min?: Prisma.NestedJsonNullableFilter<$PrismaModel> - _max?: Prisma.NestedJsonNullableFilter<$PrismaModel> -} - export type EnumMessageTypeWithAggregatesFilter<$PrismaModel = never> = { equals?: $Enums.MessageType | Prisma.EnumMessageTypeFieldRefInput<$PrismaModel> in?: $Enums.MessageType[] | Prisma.ListEnumMessageTypeFieldRefInput<$PrismaModel> @@ -607,6 +753,27 @@ export type NestedEnumWorkspaceRoleWithAggregatesFilter<$PrismaModel = never> = _max?: Prisma.NestedEnumWorkspaceRoleFilter<$PrismaModel> } +export type NestedEnumProjectVisibilityFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectVisibility | Prisma.EnumProjectVisibilityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectVisibilityFilter<$PrismaModel> | $Enums.ProjectVisibility +} + +export type NestedEnumProjectPriorityFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectPriority | Prisma.EnumProjectPriorityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectPriorityFilter<$PrismaModel> | $Enums.ProjectPriority +} + +export type NestedEnumProjectMethodologyFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectMethodology | Prisma.EnumProjectMethodologyFieldRefInput<$PrismaModel> + in?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectMethodologyFilter<$PrismaModel> | $Enums.ProjectMethodology +} + export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = { equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null @@ -634,6 +801,26 @@ export type NestedFloatNullableFilter<$PrismaModel = never> = { not?: Prisma.NestedFloatNullableFilter<$PrismaModel> | number | null } +export type NestedEnumProjectVisibilityWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectVisibility | Prisma.EnumProjectVisibilityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectVisibility[] | Prisma.ListEnumProjectVisibilityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectVisibilityWithAggregatesFilter<$PrismaModel> | $Enums.ProjectVisibility + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumProjectVisibilityFilter<$PrismaModel> + _max?: Prisma.NestedEnumProjectVisibilityFilter<$PrismaModel> +} + +export type NestedEnumProjectPriorityWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectPriority | Prisma.EnumProjectPriorityFieldRefInput<$PrismaModel> + in?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectPriority[] | Prisma.ListEnumProjectPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectPriorityWithAggregatesFilter<$PrismaModel> | $Enums.ProjectPriority + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumProjectPriorityFilter<$PrismaModel> + _max?: Prisma.NestedEnumProjectPriorityFilter<$PrismaModel> +} + export type NestedFloatWithAggregatesFilter<$PrismaModel = never> = { equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> @@ -650,6 +837,135 @@ export type NestedFloatWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedFloatFilter<$PrismaModel> } +export type NestedEnumProjectMethodologyWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ProjectMethodology | Prisma.EnumProjectMethodologyFieldRefInput<$PrismaModel> + in?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + notIn?: $Enums.ProjectMethodology[] | Prisma.ListEnumProjectMethodologyFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumProjectMethodologyWithAggregatesFilter<$PrismaModel> | $Enums.ProjectMethodology + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumProjectMethodologyFilter<$PrismaModel> + _max?: Prisma.NestedEnumProjectMethodologyFilter<$PrismaModel> +} + +export type NestedJsonNullableFilter<$PrismaModel = never> = +| Prisma.PatchUndefined< + Prisma.Either>, Exclude>, 'path'>>, + Required> + > +| Prisma.OptionalFlat>, 'path'>> + +export type NestedJsonNullableFilterBase<$PrismaModel = never> = { + equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter + path?: string[] + mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> + string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> + string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> + string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> + array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null + lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> + not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter +} + +export type NestedEnumTaskTypeFilter<$PrismaModel = never> = { + equals?: $Enums.TaskType | Prisma.EnumTaskTypeFieldRefInput<$PrismaModel> + in?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskTypeFilter<$PrismaModel> | $Enums.TaskType +} + +export type NestedEnumTaskPriorityFilter<$PrismaModel = never> = { + equals?: $Enums.TaskPriority | Prisma.EnumTaskPriorityFieldRefInput<$PrismaModel> + in?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskPriorityFilter<$PrismaModel> | $Enums.TaskPriority +} + +export type NestedEnumTaskTypeWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.TaskType | Prisma.EnumTaskTypeFieldRefInput<$PrismaModel> + in?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskType[] | Prisma.ListEnumTaskTypeFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskTypeWithAggregatesFilter<$PrismaModel> | $Enums.TaskType + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumTaskTypeFilter<$PrismaModel> + _max?: Prisma.NestedEnumTaskTypeFilter<$PrismaModel> +} + +export type NestedEnumTaskPriorityWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.TaskPriority | Prisma.EnumTaskPriorityFieldRefInput<$PrismaModel> + in?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + notIn?: $Enums.TaskPriority[] | Prisma.ListEnumTaskPriorityFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTaskPriorityWithAggregatesFilter<$PrismaModel> | $Enums.TaskPriority + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumTaskPriorityFilter<$PrismaModel> + _max?: Prisma.NestedEnumTaskPriorityFilter<$PrismaModel> +} + +export type NestedDecimalNullableFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null +} + +export type NestedEnumTimesheetSourceFilter<$PrismaModel = never> = { + equals?: $Enums.TimesheetSource | Prisma.EnumTimesheetSourceFieldRefInput<$PrismaModel> + in?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + notIn?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTimesheetSourceFilter<$PrismaModel> | $Enums.TimesheetSource +} + +export type NestedEnumApprovalStatusFilter<$PrismaModel = never> = { + equals?: $Enums.ApprovalStatus | Prisma.EnumApprovalStatusFieldRefInput<$PrismaModel> + in?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumApprovalStatusFilter<$PrismaModel> | $Enums.ApprovalStatus +} + +export type NestedDecimalNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _min?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _max?: Prisma.NestedDecimalNullableFilter<$PrismaModel> +} + +export type NestedEnumTimesheetSourceWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.TimesheetSource | Prisma.EnumTimesheetSourceFieldRefInput<$PrismaModel> + in?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + notIn?: $Enums.TimesheetSource[] | Prisma.ListEnumTimesheetSourceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumTimesheetSourceWithAggregatesFilter<$PrismaModel> | $Enums.TimesheetSource + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumTimesheetSourceFilter<$PrismaModel> + _max?: Prisma.NestedEnumTimesheetSourceFilter<$PrismaModel> +} + +export type NestedEnumApprovalStatusWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.ApprovalStatus | Prisma.EnumApprovalStatusFieldRefInput<$PrismaModel> + in?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.ApprovalStatus[] | Prisma.ListEnumApprovalStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumApprovalStatusWithAggregatesFilter<$PrismaModel> | $Enums.ApprovalStatus + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumApprovalStatusFilter<$PrismaModel> + _max?: Prisma.NestedEnumApprovalStatusFilter<$PrismaModel> +} + export type NestedEnumProjectRoleFilter<$PrismaModel = never> = { equals?: $Enums.ProjectRole | Prisma.EnumProjectRoleFieldRefInput<$PrismaModel> in?: $Enums.ProjectRole[] | Prisma.ListEnumProjectRoleFieldRefInput<$PrismaModel> @@ -691,30 +1007,6 @@ export type NestedEnumMessageTypeFilter<$PrismaModel = never> = { not?: Prisma.NestedEnumMessageTypeFilter<$PrismaModel> | $Enums.MessageType } -export type NestedJsonNullableFilter<$PrismaModel = never> = -| Prisma.PatchUndefined< - Prisma.Either>, Exclude>, 'path'>>, - Required> - > -| Prisma.OptionalFlat>, 'path'>> - -export type NestedJsonNullableFilterBase<$PrismaModel = never> = { - equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter - path?: string[] - mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel> - string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel> - string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel> - string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel> - array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null - lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> - not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter -} - export type NestedEnumMessageTypeWithAggregatesFilter<$PrismaModel = never> = { equals?: $Enums.MessageType | Prisma.EnumMessageTypeFieldRefInput<$PrismaModel> in?: $Enums.MessageType[] | Prisma.ListEnumMessageTypeFieldRefInput<$PrismaModel> diff --git a/backend/prisma/generated/enums.ts b/backend/prisma/generated/enums.ts index 34cf7db..82ba25d 100644 --- a/backend/prisma/generated/enums.ts +++ b/backend/prisma/generated/enums.ts @@ -60,6 +60,74 @@ export const TaskStatus = { export type TaskStatus = (typeof TaskStatus)[keyof typeof TaskStatus] +export const ProjectMethodology = { + SCRUM: 'SCRUM', + WATERFALL: 'WATERFALL', + KANBAN: 'KANBAN', + AGILE: 'AGILE', + OTHER: 'OTHER' +} as const + +export type ProjectMethodology = (typeof ProjectMethodology)[keyof typeof ProjectMethodology] + + +export const ProjectVisibility = { + PRIVATE: 'PRIVATE', + TEAM: 'TEAM', + PUBLIC: 'PUBLIC' +} as const + +export type ProjectVisibility = (typeof ProjectVisibility)[keyof typeof ProjectVisibility] + + +export const ProjectPriority = { + LOW: 'LOW', + MEDIUM: 'MEDIUM', + HIGH: 'HIGH', + CRITICAL: 'CRITICAL' +} as const + +export type ProjectPriority = (typeof ProjectPriority)[keyof typeof ProjectPriority] + + +export const TaskType = { + TASK: 'TASK', + BUG: 'BUG', + STORY: 'STORY', + EPIC: 'EPIC' +} as const + +export type TaskType = (typeof TaskType)[keyof typeof TaskType] + + +export const TaskPriority = { + LOW: 'LOW', + MEDIUM: 'MEDIUM', + HIGH: 'HIGH', + URGENT: 'URGENT' +} as const + +export type TaskPriority = (typeof TaskPriority)[keyof typeof TaskPriority] + + +export const TimesheetSource = { + MANUAL: 'MANUAL', + TIMER: 'TIMER', + INTEGRATION: 'INTEGRATION' +} as const + +export type TimesheetSource = (typeof TimesheetSource)[keyof typeof TimesheetSource] + + +export const ApprovalStatus = { + PENDING: 'PENDING', + APPROVED: 'APPROVED', + REJECTED: 'REJECTED' +} as const + +export type ApprovalStatus = (typeof ApprovalStatus)[keyof typeof ApprovalStatus] + + export const ProjectRole = { OWNER: 'OWNER', ADMIN: 'ADMIN', diff --git a/backend/prisma/generated/internal/class.ts b/backend/prisma/generated/internal/class.ts index 1f474ad..045dcce 100644 --- a/backend/prisma/generated/internal/class.ts +++ b/backend/prisma/generated/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.2.0", "engineVersion": "0c8ef2ce45c83248ab3df073180d5eda9e8be7a3", "activeProvider": "postgresql", - "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"./generated\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel User {\n id Int @id @default(autoincrement())\n name String\n email String @unique\n password String\n phone String?\n mobile String?\n firstName String\n lastName String?\n status Boolean @default(true)\n address String?\n bio String?\n birthDate DateTime?\n gender Gender?\n role UserRole @default(USER)\n tasks Task[]\n projects Project[]\n timesheets Timesheet[]\n comments Comment[]\n projectMemberships ProjectMember[]\n workspaceMembers WorkspaceMember[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n conversations ConversationParticipant[]\n messages Message[]\n}\n\nmodel Workspace {\n id Int @id @default(autoincrement())\n name String\n description String?\n members WorkspaceMember[]\n projects Project[]\n projectStages ProjectStage[]\n taskStages TaskStage[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n conversations Conversation[]\n}\n\nmodel WorkspaceMember {\n id Int @id @default(autoincrement())\n workspaceId Int\n userId Int\n role WorkspaceRole @default(MEMBER)\n joinedAt DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([workspaceId, userId])\n @@index([workspaceId])\n @@index([userId])\n}\n\nenum WorkspaceRole {\n OWNER\n ADMIN\n MEMBER\n VIEWER\n}\n\nmodel ProjectStage {\n id Int @id @default(autoincrement())\n title String\n description String?\n color String @default(\"#808080\")\n sequence Int @default(5)\n isCompleted Boolean @default(false)\n isCanceled Boolean @default(false)\n workspaceId Int\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n projects Project[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel TaskStage {\n id Int @id @default(autoincrement())\n title String\n description String?\n color String @default(\"#808080\")\n sequence Int @default(5)\n isCompleted Boolean @default(false)\n isCanceled Boolean @default(false)\n workspaceId Int\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n tasks Task[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Project {\n id Int @id @default(autoincrement())\n name String\n description String?\n tasks Task[]\n responsible User? @relation(fields: [responsibleId], references: [id])\n responsibleId Int?\n stage ProjectStage? @relation(fields: [stageId], references: [id])\n stageId Int?\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n workspaceId Int\n comments Comment[]\n attachments Attachment[]\n timesheets Timesheet[]\n members ProjectMember[]\n sequence Int @default(1000)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Task {\n id Int @id @default(autoincrement())\n title String\n description String?\n user User @relation(fields: [userId], references: [id])\n project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)\n userId Int\n projectId Int\n stage TaskStage? @relation(fields: [stageId], references: [id])\n stageId Int?\n comments Comment[]\n attachments Attachment[]\n timesheets Timesheet[]\n sequence Int @default(1000)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Timesheet {\n id Int @id @default(autoincrement())\n description String\n date DateTime\n timeSpent Float\n userId Int\n projectId Int\n project Project @relation(fields: [projectId], references: [id])\n taskId Int?\n user User @relation(fields: [userId], references: [id])\n task Task? @relation(fields: [taskId], references: [id])\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Comment {\n id Int @id @default(autoincrement())\n content String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n userId Int\n projectId Int?\n taskId Int?\n parentId Int?\n user User @relation(fields: [userId], references: [id])\n project Project? @relation(fields: [projectId], references: [id])\n task Task? @relation(fields: [taskId], references: [id])\n parent Comment? @relation(\"CommentReplies\", fields: [parentId], references: [id])\n replies Comment[] @relation(\"CommentReplies\")\n}\n\nenum UserRole {\n ADMIN\n MANAGER\n USER\n}\n\nenum Gender {\n Male\n Female\n}\n\nenum ProjectStatus {\n DRAFT\n IN_PROGRESS\n IN_REVIEW\n DONE\n CANCELED\n}\n\nenum TaskStatus {\n TODO\n IN_PROGRESS\n DEPLOYED\n TESTING\n REVISION\n DONE\n CANCELED\n}\n\nmodel Attachment {\n id Int @id @default(autoincrement())\n filename String\n path String\n mimeType String\n size Int\n createdAt DateTime @default(now())\n\n projectId Int?\n project Project? @relation(fields: [projectId], references: [id])\n taskId Int?\n\n task Task? @relation(fields: [taskId], references: [id])\n message Message? @relation(fields: [messageId], references: [id])\n messageId Int?\n conversationId Int?\n conversation Conversation? @relation(fields: [conversationId], references: [id])\n}\n\nmodel ProjectMember {\n id Int @id @default(autoincrement())\n userId Int\n projectId Int\n workspaceId Int\n role ProjectRole @default(MEMBER)\n joinedAt DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)\n\n @@unique([userId, projectId])\n @@index([projectId])\n @@index([userId])\n}\n\nenum ProjectRole {\n OWNER\n ADMIN\n MEMBER\n VIEWER\n}\n\nenum ConversationType {\n CHANNEL\n DIRECT\n}\n\nmodel Conversation {\n id Int @id @default(autoincrement())\n name String?\n type ConversationType @default(DIRECT)\n workspaceId Int?\n workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n participants ConversationParticipant[]\n messages Message[]\n attachments Attachment[]\n}\n\nmodel ConversationParticipant {\n id Int @id @default(autoincrement())\n userId Int\n conversationId Int\n joinedAt DateTime @default(now())\n lastReadAt DateTime @default(now())\n\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)\n\n @@unique([userId, conversationId])\n}\n\nmodel Message {\n id Int @id @default(autoincrement())\n content String\n linkPreview Json?\n senderId Int\n conversationId Int\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n isEdited Boolean @default(false)\n type MessageType @default(TEXT)\n fileUrl String?\n fileName String?\n fileSize Int?\n mimeType String?\n metadata Json?\n attachments Attachment[]\n\n sender User @relation(fields: [senderId], references: [id], onDelete: Cascade)\n conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)\n}\n\nenum MessageType {\n TEXT\n IMAGE\n DOCUMENT\n LOCATION\n STICKER\n}\n", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"./generated\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel User {\n id Int @id @default(autoincrement())\n name String\n email String @unique\n password String\n phone String?\n mobile String?\n firstName String\n lastName String?\n status Boolean @default(true)\n address String?\n bio String?\n birthDate DateTime?\n gender Gender?\n role UserRole @default(USER)\n tasks Task[]\n projects Project[]\n timesheets Timesheet[]\n comments Comment[]\n projectMemberships ProjectMember[]\n workspaceMembers WorkspaceMember[]\n reportedTasks Task[] @relation(\"ReportedTasks\")\n approvedTimesheets Timesheet[] @relation(\"ApprovedTimesheets\")\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n conversations ConversationParticipant[]\n messages Message[]\n}\n\nmodel Workspace {\n id Int @id @default(autoincrement())\n name String\n description String?\n members WorkspaceMember[]\n projects Project[]\n projectStages ProjectStage[]\n taskStages TaskStage[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n conversations Conversation[]\n}\n\nmodel WorkspaceMember {\n id Int @id @default(autoincrement())\n workspaceId Int\n userId Int\n role WorkspaceRole @default(MEMBER)\n joinedAt DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([workspaceId, userId])\n @@index([workspaceId])\n @@index([userId])\n}\n\nenum WorkspaceRole {\n OWNER\n ADMIN\n MEMBER\n VIEWER\n}\n\nmodel ProjectStage {\n id Int @id @default(autoincrement())\n title String\n description String?\n color String @default(\"#808080\")\n sequence Int @default(5)\n isCompleted Boolean @default(false)\n isCanceled Boolean @default(false)\n workspaceId Int\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n projects Project[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([workspaceId])\n}\n\nmodel TaskStage {\n id Int @id @default(autoincrement())\n title String\n description String?\n color String @default(\"#808080\")\n sequence Int @default(5)\n isCompleted Boolean @default(false)\n isCanceled Boolean @default(false)\n workspaceId Int\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n tasks Task[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([workspaceId])\n}\n\nmodel Project {\n id Int @id @default(autoincrement())\n name String\n description String?\n tasks Task[]\n responsible User? @relation(fields: [responsibleId], references: [id])\n responsibleId Int?\n stage ProjectStage? @relation(fields: [stageId], references: [id])\n stageId Int?\n workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n workspaceId Int\n comments Comment[]\n attachments Attachment[]\n timesheets Timesheet[]\n members ProjectMember[]\n\n key String? @unique\n visibility ProjectVisibility @default(TEAM)\n priority ProjectPriority @default(MEDIUM)\n budgetPlanned Float @default(0)\n budgetActual Float @default(0)\n startDate DateTime?\n endDate DateTime?\n actualStartDate DateTime?\n actualEndDate DateTime?\n progress Float @default(0)\n currency String @default(\"USD\")\n phasesCount Int @default(1)\n methodology ProjectMethodology @default(KANBAN)\n tags String[]\n customFields Json?\n archivedAt DateTime?\n\n sequence Int @default(1000)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n deletedAt DateTime?\n\n @@index([workspaceId])\n @@index([responsibleId])\n @@index([stageId])\n}\n\nmodel Task {\n id Int @id @default(autoincrement())\n title String\n description String?\n user User @relation(fields: [userId], references: [id])\n project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)\n userId Int\n projectId Int\n stage TaskStage? @relation(fields: [stageId], references: [id])\n stageId Int?\n comments Comment[]\n attachments Attachment[]\n timesheets Timesheet[]\n\n parentTaskId Int?\n parentTask Task? @relation(\"Subtasks\", fields: [parentTaskId], references: [id])\n subtasks Task[] @relation(\"Subtasks\")\n type TaskType @default(TASK)\n reporterId Int?\n reporter User? @relation(\"ReportedTasks\", fields: [reporterId], references: [id])\n watchers Json?\n startDate DateTime?\n dueDate DateTime?\n completedAt DateTime?\n estimatedHours Float @default(0)\n remainingHours Float @default(0)\n progress Float @default(0)\n priority TaskPriority @default(MEDIUM)\n tags String[]\n checklist Json?\n dependencies Json?\n customFields Json?\n deletedAt DateTime?\n\n sequence Int @default(1000)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([projectId])\n @@index([userId])\n @@index([stageId])\n @@index([parentTaskId])\n}\n\nmodel Timesheet {\n id Int @id @default(autoincrement())\n description String\n date DateTime\n timeSpent Float\n userId Int\n projectId Int\n project Project @relation(fields: [projectId], references: [id])\n taskId Int?\n user User @relation(fields: [userId], references: [id])\n task Task? @relation(fields: [taskId], references: [id])\n\n startTime DateTime?\n endTime DateTime?\n billable Boolean @default(true)\n hourlyRate Decimal?\n cost Decimal?\n source TimesheetSource @default(MANUAL)\n approvalStatus ApprovalStatus @default(PENDING)\n approvedById Int?\n approvedBy User? @relation(\"ApprovedTimesheets\", fields: [approvedById], references: [id])\n approvedAt DateTime?\n tags String[]\n customFields Json?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n deletedAt DateTime?\n\n @@index([userId])\n @@index([projectId])\n @@index([taskId])\n}\n\nmodel Comment {\n id Int @id @default(autoincrement())\n content String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n deletedAt DateTime?\n userId Int\n projectId Int?\n taskId Int?\n parentId Int?\n user User @relation(fields: [userId], references: [id])\n project Project? @relation(fields: [projectId], references: [id])\n task Task? @relation(fields: [taskId], references: [id])\n parent Comment? @relation(\"CommentReplies\", fields: [parentId], references: [id])\n replies Comment[] @relation(\"CommentReplies\")\n\n @@index([userId])\n @@index([projectId])\n @@index([taskId])\n @@index([parentId])\n}\n\nenum UserRole {\n ADMIN\n MANAGER\n USER\n}\n\nenum Gender {\n Male\n Female\n}\n\nenum ProjectStatus {\n DRAFT\n IN_PROGRESS\n IN_REVIEW\n DONE\n CANCELED\n}\n\nenum TaskStatus {\n TODO\n IN_PROGRESS\n DEPLOYED\n TESTING\n REVISION\n DONE\n CANCELED\n}\n\nenum ProjectMethodology {\n SCRUM\n WATERFALL\n KANBAN\n AGILE\n OTHER\n}\n\nenum ProjectVisibility {\n PRIVATE\n TEAM\n PUBLIC\n}\n\nenum ProjectPriority {\n LOW\n MEDIUM\n HIGH\n CRITICAL\n}\n\nenum TaskType {\n TASK\n BUG\n STORY\n EPIC\n}\n\nenum TaskPriority {\n LOW\n MEDIUM\n HIGH\n URGENT\n}\n\nenum TimesheetSource {\n MANUAL\n TIMER\n INTEGRATION\n}\n\nenum ApprovalStatus {\n PENDING\n APPROVED\n REJECTED\n}\n\nmodel Attachment {\n id Int @id @default(autoincrement())\n filename String\n path String\n mimeType String\n size Int\n createdAt DateTime @default(now())\n\n projectId Int?\n project Project? @relation(fields: [projectId], references: [id])\n taskId Int?\n\n task Task? @relation(fields: [taskId], references: [id])\n message Message? @relation(fields: [messageId], references: [id])\n messageId Int?\n conversationId Int?\n conversation Conversation? @relation(fields: [conversationId], references: [id])\n}\n\nmodel ProjectMember {\n id Int @id @default(autoincrement())\n userId Int\n projectId Int\n workspaceId Int\n role ProjectRole @default(MEMBER)\n joinedAt DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)\n\n @@unique([userId, projectId])\n @@index([projectId])\n @@index([userId])\n}\n\nenum ProjectRole {\n OWNER\n ADMIN\n MEMBER\n VIEWER\n}\n\nenum ConversationType {\n CHANNEL\n DIRECT\n}\n\nmodel Conversation {\n id Int @id @default(autoincrement())\n name String?\n type ConversationType @default(DIRECT)\n workspaceId Int?\n workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: Cascade)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n participants ConversationParticipant[]\n messages Message[]\n attachments Attachment[]\n}\n\nmodel ConversationParticipant {\n id Int @id @default(autoincrement())\n userId Int\n conversationId Int\n joinedAt DateTime @default(now())\n lastReadAt DateTime @default(now())\n\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)\n\n @@unique([userId, conversationId])\n}\n\nmodel Message {\n id Int @id @default(autoincrement())\n content String\n linkPreview Json?\n senderId Int\n conversationId Int\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n isEdited Boolean @default(false)\n type MessageType @default(TEXT)\n fileUrl String?\n fileName String?\n fileSize Int?\n mimeType String?\n metadata Json?\n attachments Attachment[]\n\n sender User @relation(fields: [senderId], references: [id], onDelete: Cascade)\n conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)\n}\n\nenum MessageType {\n TEXT\n IMAGE\n DOCUMENT\n LOCATION\n STICKER\n}\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"phone\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"mobile\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"firstName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"lastName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"status\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"address\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"birthDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"gender\",\"kind\":\"enum\",\"type\":\"Gender\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"UserRole\"},{\"name\":\"tasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"TaskToUser\"},{\"name\":\"projects\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToUser\"},{\"name\":\"timesheets\",\"kind\":\"object\",\"type\":\"Timesheet\",\"relationName\":\"TimesheetToUser\"},{\"name\":\"comments\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentToUser\"},{\"name\":\"projectMemberships\",\"kind\":\"object\",\"type\":\"ProjectMember\",\"relationName\":\"ProjectMemberToUser\"},{\"name\":\"workspaceMembers\",\"kind\":\"object\",\"type\":\"WorkspaceMember\",\"relationName\":\"UserToWorkspaceMember\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"conversations\",\"kind\":\"object\",\"type\":\"ConversationParticipant\",\"relationName\":\"ConversationParticipantToUser\"},{\"name\":\"messages\",\"kind\":\"object\",\"type\":\"Message\",\"relationName\":\"MessageToUser\"}],\"dbName\":null},\"Workspace\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"members\",\"kind\":\"object\",\"type\":\"WorkspaceMember\",\"relationName\":\"WorkspaceToWorkspaceMember\"},{\"name\":\"projects\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToWorkspace\"},{\"name\":\"projectStages\",\"kind\":\"object\",\"type\":\"ProjectStage\",\"relationName\":\"ProjectStageToWorkspace\"},{\"name\":\"taskStages\",\"kind\":\"object\",\"type\":\"TaskStage\",\"relationName\":\"TaskStageToWorkspace\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"conversations\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"ConversationToWorkspace\"}],\"dbName\":null},\"WorkspaceMember\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"WorkspaceRole\"},{\"name\":\"joinedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"WorkspaceToWorkspaceMember\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToWorkspaceMember\"}],\"dbName\":null},\"ProjectStage\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"color\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"isCompleted\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"isCanceled\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"ProjectStageToWorkspace\"},{\"name\":\"projects\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToProjectStage\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"TaskStage\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"color\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"isCompleted\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"isCanceled\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"TaskStageToWorkspace\"},{\"name\":\"tasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"TaskToTaskStage\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Project\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"ProjectToTask\"},{\"name\":\"responsible\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ProjectToUser\"},{\"name\":\"responsibleId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"stage\",\"kind\":\"object\",\"type\":\"ProjectStage\",\"relationName\":\"ProjectToProjectStage\"},{\"name\":\"stageId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"ProjectToWorkspace\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comments\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentToProject\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToProject\"},{\"name\":\"timesheets\",\"kind\":\"object\",\"type\":\"Timesheet\",\"relationName\":\"ProjectToTimesheet\"},{\"name\":\"members\",\"kind\":\"object\",\"type\":\"ProjectMember\",\"relationName\":\"ProjectToProjectMember\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Task\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TaskToUser\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToTask\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"stage\",\"kind\":\"object\",\"type\":\"TaskStage\",\"relationName\":\"TaskToTaskStage\"},{\"name\":\"stageId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comments\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentToTask\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToTask\"},{\"name\":\"timesheets\",\"kind\":\"object\",\"type\":\"Timesheet\",\"relationName\":\"TaskToTimesheet\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Timesheet\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"date\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"timeSpent\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToTimesheet\"},{\"name\":\"taskId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TimesheetToUser\"},{\"name\":\"task\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"TaskToTimesheet\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Comment\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"taskId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"parentId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"CommentToUser\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"CommentToProject\"},{\"name\":\"task\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"CommentToTask\"},{\"name\":\"parent\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentReplies\"},{\"name\":\"replies\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentReplies\"}],\"dbName\":null},\"Attachment\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"filename\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"path\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"mimeType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"size\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"AttachmentToProject\"},{\"name\":\"taskId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"task\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"AttachmentToTask\"},{\"name\":\"message\",\"kind\":\"object\",\"type\":\"Message\",\"relationName\":\"AttachmentToMessage\"},{\"name\":\"messageId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversationId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversation\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"AttachmentToConversation\"}],\"dbName\":null},\"ProjectMember\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"ProjectRole\"},{\"name\":\"joinedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ProjectMemberToUser\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToProjectMember\"}],\"dbName\":null},\"Conversation\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"ConversationType\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"ConversationToWorkspace\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"participants\",\"kind\":\"object\",\"type\":\"ConversationParticipant\",\"relationName\":\"ConversationToConversationParticipant\"},{\"name\":\"messages\",\"kind\":\"object\",\"type\":\"Message\",\"relationName\":\"ConversationToMessage\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToConversation\"}],\"dbName\":null},\"ConversationParticipant\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversationId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"joinedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lastReadAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ConversationParticipantToUser\"},{\"name\":\"conversation\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"ConversationToConversationParticipant\"}],\"dbName\":null},\"Message\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"linkPreview\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"senderId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversationId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"isEdited\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"MessageType\"},{\"name\":\"fileUrl\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fileName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fileSize\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"mimeType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"metadata\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToMessage\"},{\"name\":\"sender\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"MessageToUser\"},{\"name\":\"conversation\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"ConversationToMessage\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"phone\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"mobile\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"firstName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"lastName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"status\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"address\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"birthDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"gender\",\"kind\":\"enum\",\"type\":\"Gender\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"UserRole\"},{\"name\":\"tasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"TaskToUser\"},{\"name\":\"projects\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToUser\"},{\"name\":\"timesheets\",\"kind\":\"object\",\"type\":\"Timesheet\",\"relationName\":\"TimesheetToUser\"},{\"name\":\"comments\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentToUser\"},{\"name\":\"projectMemberships\",\"kind\":\"object\",\"type\":\"ProjectMember\",\"relationName\":\"ProjectMemberToUser\"},{\"name\":\"workspaceMembers\",\"kind\":\"object\",\"type\":\"WorkspaceMember\",\"relationName\":\"UserToWorkspaceMember\"},{\"name\":\"reportedTasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"ReportedTasks\"},{\"name\":\"approvedTimesheets\",\"kind\":\"object\",\"type\":\"Timesheet\",\"relationName\":\"ApprovedTimesheets\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"conversations\",\"kind\":\"object\",\"type\":\"ConversationParticipant\",\"relationName\":\"ConversationParticipantToUser\"},{\"name\":\"messages\",\"kind\":\"object\",\"type\":\"Message\",\"relationName\":\"MessageToUser\"}],\"dbName\":null},\"Workspace\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"members\",\"kind\":\"object\",\"type\":\"WorkspaceMember\",\"relationName\":\"WorkspaceToWorkspaceMember\"},{\"name\":\"projects\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToWorkspace\"},{\"name\":\"projectStages\",\"kind\":\"object\",\"type\":\"ProjectStage\",\"relationName\":\"ProjectStageToWorkspace\"},{\"name\":\"taskStages\",\"kind\":\"object\",\"type\":\"TaskStage\",\"relationName\":\"TaskStageToWorkspace\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"conversations\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"ConversationToWorkspace\"}],\"dbName\":null},\"WorkspaceMember\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"WorkspaceRole\"},{\"name\":\"joinedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"WorkspaceToWorkspaceMember\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"UserToWorkspaceMember\"}],\"dbName\":null},\"ProjectStage\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"color\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"isCompleted\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"isCanceled\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"ProjectStageToWorkspace\"},{\"name\":\"projects\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToProjectStage\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"TaskStage\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"color\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"isCompleted\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"isCanceled\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"TaskStageToWorkspace\"},{\"name\":\"tasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"TaskToTaskStage\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Project\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"ProjectToTask\"},{\"name\":\"responsible\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ProjectToUser\"},{\"name\":\"responsibleId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"stage\",\"kind\":\"object\",\"type\":\"ProjectStage\",\"relationName\":\"ProjectToProjectStage\"},{\"name\":\"stageId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"ProjectToWorkspace\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comments\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentToProject\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToProject\"},{\"name\":\"timesheets\",\"kind\":\"object\",\"type\":\"Timesheet\",\"relationName\":\"ProjectToTimesheet\"},{\"name\":\"members\",\"kind\":\"object\",\"type\":\"ProjectMember\",\"relationName\":\"ProjectToProjectMember\"},{\"name\":\"key\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"visibility\",\"kind\":\"enum\",\"type\":\"ProjectVisibility\"},{\"name\":\"priority\",\"kind\":\"enum\",\"type\":\"ProjectPriority\"},{\"name\":\"budgetPlanned\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"budgetActual\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"startDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"endDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"actualStartDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"actualEndDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"progress\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"currency\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"phasesCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"methodology\",\"kind\":\"enum\",\"type\":\"ProjectMethodology\"},{\"name\":\"tags\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"customFields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"archivedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Task\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TaskToUser\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToTask\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"stage\",\"kind\":\"object\",\"type\":\"TaskStage\",\"relationName\":\"TaskToTaskStage\"},{\"name\":\"stageId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"comments\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentToTask\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToTask\"},{\"name\":\"timesheets\",\"kind\":\"object\",\"type\":\"Timesheet\",\"relationName\":\"TaskToTimesheet\"},{\"name\":\"parentTaskId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"parentTask\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"Subtasks\"},{\"name\":\"subtasks\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"Subtasks\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"TaskType\"},{\"name\":\"reporterId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"reporter\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ReportedTasks\"},{\"name\":\"watchers\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"startDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"dueDate\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"completedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"estimatedHours\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"remainingHours\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"progress\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"priority\",\"kind\":\"enum\",\"type\":\"TaskPriority\"},{\"name\":\"tags\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"checklist\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"dependencies\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"customFields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"sequence\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Timesheet\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"date\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"timeSpent\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToTimesheet\"},{\"name\":\"taskId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"TimesheetToUser\"},{\"name\":\"task\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"TaskToTimesheet\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"billable\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"hourlyRate\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"cost\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"source\",\"kind\":\"enum\",\"type\":\"TimesheetSource\"},{\"name\":\"approvalStatus\",\"kind\":\"enum\",\"type\":\"ApprovalStatus\"},{\"name\":\"approvedById\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"approvedBy\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ApprovedTimesheets\"},{\"name\":\"approvedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"tags\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"customFields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Comment\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"taskId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"parentId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"CommentToUser\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"CommentToProject\"},{\"name\":\"task\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"CommentToTask\"},{\"name\":\"parent\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentReplies\"},{\"name\":\"replies\",\"kind\":\"object\",\"type\":\"Comment\",\"relationName\":\"CommentReplies\"}],\"dbName\":null},\"Attachment\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"filename\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"path\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"mimeType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"size\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"AttachmentToProject\"},{\"name\":\"taskId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"task\",\"kind\":\"object\",\"type\":\"Task\",\"relationName\":\"AttachmentToTask\"},{\"name\":\"message\",\"kind\":\"object\",\"type\":\"Message\",\"relationName\":\"AttachmentToMessage\"},{\"name\":\"messageId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversationId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversation\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"AttachmentToConversation\"}],\"dbName\":null},\"ProjectMember\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"projectId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"ProjectRole\"},{\"name\":\"joinedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ProjectMemberToUser\"},{\"name\":\"project\",\"kind\":\"object\",\"type\":\"Project\",\"relationName\":\"ProjectToProjectMember\"}],\"dbName\":null},\"Conversation\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"ConversationType\"},{\"name\":\"workspaceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"workspace\",\"kind\":\"object\",\"type\":\"Workspace\",\"relationName\":\"ConversationToWorkspace\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"participants\",\"kind\":\"object\",\"type\":\"ConversationParticipant\",\"relationName\":\"ConversationToConversationParticipant\"},{\"name\":\"messages\",\"kind\":\"object\",\"type\":\"Message\",\"relationName\":\"ConversationToMessage\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToConversation\"}],\"dbName\":null},\"ConversationParticipant\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversationId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"joinedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lastReadAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ConversationParticipantToUser\"},{\"name\":\"conversation\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"ConversationToConversationParticipant\"}],\"dbName\":null},\"Message\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"linkPreview\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"senderId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"conversationId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"isEdited\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"MessageType\"},{\"name\":\"fileUrl\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fileName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fileSize\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"mimeType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"metadata\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"attachments\",\"kind\":\"object\",\"type\":\"Attachment\",\"relationName\":\"AttachmentToMessage\"},{\"name\":\"sender\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"MessageToUser\"},{\"name\":\"conversation\",\"kind\":\"object\",\"type\":\"Conversation\",\"relationName\":\"ConversationToMessage\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") async function decodeBase64AsWasm(wasmBase64: string): Promise { const { Buffer } = await import('node:buffer') diff --git a/backend/prisma/generated/internal/prismaNamespace.ts b/backend/prisma/generated/internal/prismaNamespace.ts index ccc444f..6d80054 100644 --- a/backend/prisma/generated/internal/prismaNamespace.ts +++ b/backend/prisma/generated/internal/prismaNamespace.ts @@ -1577,9 +1577,26 @@ export const ProjectScalarFieldEnum = { responsibleId: 'responsibleId', stageId: 'stageId', workspaceId: 'workspaceId', + key: 'key', + visibility: 'visibility', + priority: 'priority', + budgetPlanned: 'budgetPlanned', + budgetActual: 'budgetActual', + startDate: 'startDate', + endDate: 'endDate', + actualStartDate: 'actualStartDate', + actualEndDate: 'actualEndDate', + progress: 'progress', + currency: 'currency', + phasesCount: 'phasesCount', + methodology: 'methodology', + tags: 'tags', + customFields: 'customFields', + archivedAt: 'archivedAt', sequence: 'sequence', createdAt: 'createdAt', - updatedAt: 'updatedAt' + updatedAt: 'updatedAt', + deletedAt: 'deletedAt' } as const export type ProjectScalarFieldEnum = (typeof ProjectScalarFieldEnum)[keyof typeof ProjectScalarFieldEnum] @@ -1592,6 +1609,22 @@ export const TaskScalarFieldEnum = { userId: 'userId', projectId: 'projectId', stageId: 'stageId', + parentTaskId: 'parentTaskId', + type: 'type', + reporterId: 'reporterId', + watchers: 'watchers', + startDate: 'startDate', + dueDate: 'dueDate', + completedAt: 'completedAt', + estimatedHours: 'estimatedHours', + remainingHours: 'remainingHours', + progress: 'progress', + priority: 'priority', + tags: 'tags', + checklist: 'checklist', + dependencies: 'dependencies', + customFields: 'customFields', + deletedAt: 'deletedAt', sequence: 'sequence', createdAt: 'createdAt', updatedAt: 'updatedAt' @@ -1608,8 +1641,20 @@ export const TimesheetScalarFieldEnum = { userId: 'userId', projectId: 'projectId', taskId: 'taskId', + startTime: 'startTime', + endTime: 'endTime', + billable: 'billable', + hourlyRate: 'hourlyRate', + cost: 'cost', + source: 'source', + approvalStatus: 'approvalStatus', + approvedById: 'approvedById', + approvedAt: 'approvedAt', + tags: 'tags', + customFields: 'customFields', createdAt: 'createdAt', - updatedAt: 'updatedAt' + updatedAt: 'updatedAt', + deletedAt: 'deletedAt' } as const export type TimesheetScalarFieldEnum = (typeof TimesheetScalarFieldEnum)[keyof typeof TimesheetScalarFieldEnum] @@ -1620,6 +1665,7 @@ export const CommentScalarFieldEnum = { content: 'content', createdAt: 'createdAt', updatedAt: 'updatedAt', + deletedAt: 'deletedAt', userId: 'userId', projectId: 'projectId', taskId: 'taskId', @@ -1841,44 +1887,58 @@ export type ListEnumWorkspaceRoleFieldRefInput<$PrismaModel> = FieldRefInputType /** - * Reference to a field of type 'Float' + * Reference to a field of type 'ProjectVisibility' */ -export type FloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float'> +export type EnumProjectVisibilityFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectVisibility'> /** - * Reference to a field of type 'Float[]' + * Reference to a field of type 'ProjectVisibility[]' */ -export type ListFloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float[]'> +export type ListEnumProjectVisibilityFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectVisibility[]'> /** - * Reference to a field of type 'ProjectRole' + * Reference to a field of type 'ProjectPriority' */ -export type EnumProjectRoleFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectRole'> +export type EnumProjectPriorityFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectPriority'> /** - * Reference to a field of type 'ProjectRole[]' + * Reference to a field of type 'ProjectPriority[]' */ -export type ListEnumProjectRoleFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectRole[]'> +export type ListEnumProjectPriorityFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectPriority[]'> /** - * Reference to a field of type 'ConversationType' + * Reference to a field of type 'Float' */ -export type EnumConversationTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ConversationType'> +export type FloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float'> /** - * Reference to a field of type 'ConversationType[]' + * Reference to a field of type 'Float[]' */ -export type ListEnumConversationTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ConversationType[]'> +export type ListFloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float[]'> + + + +/** + * Reference to a field of type 'ProjectMethodology' + */ +export type EnumProjectMethodologyFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectMethodology'> + + + +/** + * Reference to a field of type 'ProjectMethodology[]' + */ +export type ListEnumProjectMethodologyFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectMethodology[]'> @@ -1896,6 +1956,104 @@ export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$Prisma +/** + * Reference to a field of type 'TaskType' + */ +export type EnumTaskTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TaskType'> + + + +/** + * Reference to a field of type 'TaskType[]' + */ +export type ListEnumTaskTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TaskType[]'> + + + +/** + * Reference to a field of type 'TaskPriority' + */ +export type EnumTaskPriorityFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TaskPriority'> + + + +/** + * Reference to a field of type 'TaskPriority[]' + */ +export type ListEnumTaskPriorityFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TaskPriority[]'> + + + +/** + * Reference to a field of type 'Decimal' + */ +export type DecimalFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Decimal'> + + + +/** + * Reference to a field of type 'Decimal[]' + */ +export type ListDecimalFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Decimal[]'> + + + +/** + * Reference to a field of type 'TimesheetSource' + */ +export type EnumTimesheetSourceFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TimesheetSource'> + + + +/** + * Reference to a field of type 'TimesheetSource[]' + */ +export type ListEnumTimesheetSourceFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'TimesheetSource[]'> + + + +/** + * Reference to a field of type 'ApprovalStatus' + */ +export type EnumApprovalStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ApprovalStatus'> + + + +/** + * Reference to a field of type 'ApprovalStatus[]' + */ +export type ListEnumApprovalStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ApprovalStatus[]'> + + + +/** + * Reference to a field of type 'ProjectRole' + */ +export type EnumProjectRoleFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectRole'> + + + +/** + * Reference to a field of type 'ProjectRole[]' + */ +export type ListEnumProjectRoleFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ProjectRole[]'> + + + +/** + * Reference to a field of type 'ConversationType' + */ +export type EnumConversationTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ConversationType'> + + + +/** + * Reference to a field of type 'ConversationType[]' + */ +export type ListEnumConversationTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ConversationType[]'> + + + /** * Reference to a field of type 'MessageType' */ diff --git a/backend/prisma/generated/internal/prismaNamespaceBrowser.ts b/backend/prisma/generated/internal/prismaNamespaceBrowser.ts index 5dd1e59..c346e41 100644 --- a/backend/prisma/generated/internal/prismaNamespaceBrowser.ts +++ b/backend/prisma/generated/internal/prismaNamespaceBrowser.ts @@ -168,9 +168,26 @@ export const ProjectScalarFieldEnum = { responsibleId: 'responsibleId', stageId: 'stageId', workspaceId: 'workspaceId', + key: 'key', + visibility: 'visibility', + priority: 'priority', + budgetPlanned: 'budgetPlanned', + budgetActual: 'budgetActual', + startDate: 'startDate', + endDate: 'endDate', + actualStartDate: 'actualStartDate', + actualEndDate: 'actualEndDate', + progress: 'progress', + currency: 'currency', + phasesCount: 'phasesCount', + methodology: 'methodology', + tags: 'tags', + customFields: 'customFields', + archivedAt: 'archivedAt', sequence: 'sequence', createdAt: 'createdAt', - updatedAt: 'updatedAt' + updatedAt: 'updatedAt', + deletedAt: 'deletedAt' } as const export type ProjectScalarFieldEnum = (typeof ProjectScalarFieldEnum)[keyof typeof ProjectScalarFieldEnum] @@ -183,6 +200,22 @@ export const TaskScalarFieldEnum = { userId: 'userId', projectId: 'projectId', stageId: 'stageId', + parentTaskId: 'parentTaskId', + type: 'type', + reporterId: 'reporterId', + watchers: 'watchers', + startDate: 'startDate', + dueDate: 'dueDate', + completedAt: 'completedAt', + estimatedHours: 'estimatedHours', + remainingHours: 'remainingHours', + progress: 'progress', + priority: 'priority', + tags: 'tags', + checklist: 'checklist', + dependencies: 'dependencies', + customFields: 'customFields', + deletedAt: 'deletedAt', sequence: 'sequence', createdAt: 'createdAt', updatedAt: 'updatedAt' @@ -199,8 +232,20 @@ export const TimesheetScalarFieldEnum = { userId: 'userId', projectId: 'projectId', taskId: 'taskId', + startTime: 'startTime', + endTime: 'endTime', + billable: 'billable', + hourlyRate: 'hourlyRate', + cost: 'cost', + source: 'source', + approvalStatus: 'approvalStatus', + approvedById: 'approvedById', + approvedAt: 'approvedAt', + tags: 'tags', + customFields: 'customFields', createdAt: 'createdAt', - updatedAt: 'updatedAt' + updatedAt: 'updatedAt', + deletedAt: 'deletedAt' } as const export type TimesheetScalarFieldEnum = (typeof TimesheetScalarFieldEnum)[keyof typeof TimesheetScalarFieldEnum] @@ -211,6 +256,7 @@ export const CommentScalarFieldEnum = { content: 'content', createdAt: 'createdAt', updatedAt: 'updatedAt', + deletedAt: 'deletedAt', userId: 'userId', projectId: 'projectId', taskId: 'taskId', diff --git a/backend/prisma/generated/models/Comment.ts b/backend/prisma/generated/models/Comment.ts index 3828736..b050a4c 100644 --- a/backend/prisma/generated/models/Comment.ts +++ b/backend/prisma/generated/models/Comment.ts @@ -47,6 +47,7 @@ export type CommentMinAggregateOutputType = { content: string | null createdAt: Date | null updatedAt: Date | null + deletedAt: Date | null userId: number | null projectId: number | null taskId: number | null @@ -58,6 +59,7 @@ export type CommentMaxAggregateOutputType = { content: string | null createdAt: Date | null updatedAt: Date | null + deletedAt: Date | null userId: number | null projectId: number | null taskId: number | null @@ -69,6 +71,7 @@ export type CommentCountAggregateOutputType = { content: number createdAt: number updatedAt: number + deletedAt: number userId: number projectId: number taskId: number @@ -98,6 +101,7 @@ export type CommentMinAggregateInputType = { content?: true createdAt?: true updatedAt?: true + deletedAt?: true userId?: true projectId?: true taskId?: true @@ -109,6 +113,7 @@ export type CommentMaxAggregateInputType = { content?: true createdAt?: true updatedAt?: true + deletedAt?: true userId?: true projectId?: true taskId?: true @@ -120,6 +125,7 @@ export type CommentCountAggregateInputType = { content?: true createdAt?: true updatedAt?: true + deletedAt?: true userId?: true projectId?: true taskId?: true @@ -218,6 +224,7 @@ export type CommentGroupByOutputType = { content: string createdAt: Date updatedAt: Date + deletedAt: Date | null userId: number projectId: number | null taskId: number | null @@ -252,6 +259,7 @@ export type CommentWhereInput = { content?: Prisma.StringFilter<"Comment"> | string createdAt?: Prisma.DateTimeFilter<"Comment"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Comment"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Comment"> | Date | string | null userId?: Prisma.IntFilter<"Comment"> | number projectId?: Prisma.IntNullableFilter<"Comment"> | number | null taskId?: Prisma.IntNullableFilter<"Comment"> | number | null @@ -268,6 +276,7 @@ export type CommentOrderByWithRelationInput = { content?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder userId?: Prisma.SortOrder projectId?: Prisma.SortOrderInput | Prisma.SortOrder taskId?: Prisma.SortOrderInput | Prisma.SortOrder @@ -287,6 +296,7 @@ export type CommentWhereUniqueInput = Prisma.AtLeast<{ content?: Prisma.StringFilter<"Comment"> | string createdAt?: Prisma.DateTimeFilter<"Comment"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Comment"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Comment"> | Date | string | null userId?: Prisma.IntFilter<"Comment"> | number projectId?: Prisma.IntNullableFilter<"Comment"> | number | null taskId?: Prisma.IntNullableFilter<"Comment"> | number | null @@ -303,6 +313,7 @@ export type CommentOrderByWithAggregationInput = { content?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder userId?: Prisma.SortOrder projectId?: Prisma.SortOrderInput | Prisma.SortOrder taskId?: Prisma.SortOrderInput | Prisma.SortOrder @@ -322,6 +333,7 @@ export type CommentScalarWhereWithAggregatesInput = { content?: Prisma.StringWithAggregatesFilter<"Comment"> | string createdAt?: Prisma.DateTimeWithAggregatesFilter<"Comment"> | Date | string updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Comment"> | Date | string + deletedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"Comment"> | Date | string | null userId?: Prisma.IntWithAggregatesFilter<"Comment"> | number projectId?: Prisma.IntNullableWithAggregatesFilter<"Comment"> | number | null taskId?: Prisma.IntNullableWithAggregatesFilter<"Comment"> | number | null @@ -332,6 +344,7 @@ export type CommentCreateInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null user: Prisma.UserCreateNestedOneWithoutCommentsInput project?: Prisma.ProjectCreateNestedOneWithoutCommentsInput task?: Prisma.TaskCreateNestedOneWithoutCommentsInput @@ -344,6 +357,7 @@ export type CommentUncheckedCreateInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number projectId?: number | null taskId?: number | null @@ -355,6 +369,7 @@ export type CommentUpdateInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null user?: Prisma.UserUpdateOneRequiredWithoutCommentsNestedInput project?: Prisma.ProjectUpdateOneWithoutCommentsNestedInput task?: Prisma.TaskUpdateOneWithoutCommentsNestedInput @@ -367,6 +382,7 @@ export type CommentUncheckedUpdateInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -379,6 +395,7 @@ export type CommentCreateManyInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number projectId?: number | null taskId?: number | null @@ -389,6 +406,7 @@ export type CommentUpdateManyMutationInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type CommentUncheckedUpdateManyInput = { @@ -396,6 +414,7 @@ export type CommentUncheckedUpdateManyInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -422,6 +441,7 @@ export type CommentCountOrderByAggregateInput = { content?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder @@ -441,6 +461,7 @@ export type CommentMaxOrderByAggregateInput = { content?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder @@ -452,6 +473,7 @@ export type CommentMinOrderByAggregateInput = { content?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder @@ -654,6 +676,7 @@ export type CommentCreateWithoutUserInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null project?: Prisma.ProjectCreateNestedOneWithoutCommentsInput task?: Prisma.TaskCreateNestedOneWithoutCommentsInput parent?: Prisma.CommentCreateNestedOneWithoutRepliesInput @@ -665,6 +688,7 @@ export type CommentUncheckedCreateWithoutUserInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null projectId?: number | null taskId?: number | null parentId?: number | null @@ -705,6 +729,7 @@ export type CommentScalarWhereInput = { content?: Prisma.StringFilter<"Comment"> | string createdAt?: Prisma.DateTimeFilter<"Comment"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Comment"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Comment"> | Date | string | null userId?: Prisma.IntFilter<"Comment"> | number projectId?: Prisma.IntNullableFilter<"Comment"> | number | null taskId?: Prisma.IntNullableFilter<"Comment"> | number | null @@ -715,6 +740,7 @@ export type CommentCreateWithoutProjectInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null user: Prisma.UserCreateNestedOneWithoutCommentsInput task?: Prisma.TaskCreateNestedOneWithoutCommentsInput parent?: Prisma.CommentCreateNestedOneWithoutRepliesInput @@ -726,6 +752,7 @@ export type CommentUncheckedCreateWithoutProjectInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number taskId?: number | null parentId?: number | null @@ -762,6 +789,7 @@ export type CommentCreateWithoutTaskInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null user: Prisma.UserCreateNestedOneWithoutCommentsInput project?: Prisma.ProjectCreateNestedOneWithoutCommentsInput parent?: Prisma.CommentCreateNestedOneWithoutRepliesInput @@ -773,6 +801,7 @@ export type CommentUncheckedCreateWithoutTaskInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number projectId?: number | null parentId?: number | null @@ -809,6 +838,7 @@ export type CommentCreateWithoutRepliesInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null user: Prisma.UserCreateNestedOneWithoutCommentsInput project?: Prisma.ProjectCreateNestedOneWithoutCommentsInput task?: Prisma.TaskCreateNestedOneWithoutCommentsInput @@ -820,6 +850,7 @@ export type CommentUncheckedCreateWithoutRepliesInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number projectId?: number | null taskId?: number | null @@ -835,6 +866,7 @@ export type CommentCreateWithoutParentInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null user: Prisma.UserCreateNestedOneWithoutCommentsInput project?: Prisma.ProjectCreateNestedOneWithoutCommentsInput task?: Prisma.TaskCreateNestedOneWithoutCommentsInput @@ -846,6 +878,7 @@ export type CommentUncheckedCreateWithoutParentInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number projectId?: number | null taskId?: number | null @@ -877,6 +910,7 @@ export type CommentUpdateWithoutRepliesInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null user?: Prisma.UserUpdateOneRequiredWithoutCommentsNestedInput project?: Prisma.ProjectUpdateOneWithoutCommentsNestedInput task?: Prisma.TaskUpdateOneWithoutCommentsNestedInput @@ -888,6 +922,7 @@ export type CommentUncheckedUpdateWithoutRepliesInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -915,6 +950,7 @@ export type CommentCreateManyUserInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null projectId?: number | null taskId?: number | null parentId?: number | null @@ -924,6 +960,7 @@ export type CommentUpdateWithoutUserInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null project?: Prisma.ProjectUpdateOneWithoutCommentsNestedInput task?: Prisma.TaskUpdateOneWithoutCommentsNestedInput parent?: Prisma.CommentUpdateOneWithoutRepliesNestedInput @@ -935,6 +972,7 @@ export type CommentUncheckedUpdateWithoutUserInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -946,6 +984,7 @@ export type CommentUncheckedUpdateManyWithoutUserInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -956,6 +995,7 @@ export type CommentCreateManyProjectInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number taskId?: number | null parentId?: number | null @@ -965,6 +1005,7 @@ export type CommentUpdateWithoutProjectInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null user?: Prisma.UserUpdateOneRequiredWithoutCommentsNestedInput task?: Prisma.TaskUpdateOneWithoutCommentsNestedInput parent?: Prisma.CommentUpdateOneWithoutRepliesNestedInput @@ -976,6 +1017,7 @@ export type CommentUncheckedUpdateWithoutProjectInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -987,6 +1029,7 @@ export type CommentUncheckedUpdateManyWithoutProjectInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -997,6 +1040,7 @@ export type CommentCreateManyTaskInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number projectId?: number | null parentId?: number | null @@ -1006,6 +1050,7 @@ export type CommentUpdateWithoutTaskInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null user?: Prisma.UserUpdateOneRequiredWithoutCommentsNestedInput project?: Prisma.ProjectUpdateOneWithoutCommentsNestedInput parent?: Prisma.CommentUpdateOneWithoutRepliesNestedInput @@ -1017,6 +1062,7 @@ export type CommentUncheckedUpdateWithoutTaskInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -1028,6 +1074,7 @@ export type CommentUncheckedUpdateManyWithoutTaskInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -1038,6 +1085,7 @@ export type CommentCreateManyParentInput = { content: string createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null userId: number projectId?: number | null taskId?: number | null @@ -1047,6 +1095,7 @@ export type CommentUpdateWithoutParentInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null user?: Prisma.UserUpdateOneRequiredWithoutCommentsNestedInput project?: Prisma.ProjectUpdateOneWithoutCommentsNestedInput task?: Prisma.TaskUpdateOneWithoutCommentsNestedInput @@ -1058,6 +1107,7 @@ export type CommentUncheckedUpdateWithoutParentInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -1069,6 +1119,7 @@ export type CommentUncheckedUpdateManyWithoutParentInput = { content?: Prisma.StringFieldUpdateOperationsInput | string createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null @@ -1110,6 +1161,7 @@ export type CommentSelect = runtime.Types.Extensions.GetOmit<"id" | "content" | "createdAt" | "updatedAt" | "userId" | "projectId" | "taskId" | "parentId", ExtArgs["result"]["comment"]> +export type CommentOmit = runtime.Types.Extensions.GetOmit<"id" | "content" | "createdAt" | "updatedAt" | "deletedAt" | "userId" | "projectId" | "taskId" | "parentId", ExtArgs["result"]["comment"]> export type CommentInclude = { user?: boolean | Prisma.UserDefaultArgs project?: boolean | Prisma.Comment$projectArgs @@ -1199,6 +1254,7 @@ export type $CommentPayload readonly createdAt: Prisma.FieldRef<"Comment", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"Comment", 'DateTime'> + readonly deletedAt: Prisma.FieldRef<"Comment", 'DateTime'> readonly userId: Prisma.FieldRef<"Comment", 'Int'> readonly projectId: Prisma.FieldRef<"Comment", 'Int'> readonly taskId: Prisma.FieldRef<"Comment", 'Int'> diff --git a/backend/prisma/generated/models/Project.ts b/backend/prisma/generated/models/Project.ts index da911d7..c519be7 100644 --- a/backend/prisma/generated/models/Project.ts +++ b/backend/prisma/generated/models/Project.ts @@ -31,6 +31,10 @@ export type ProjectAvgAggregateOutputType = { responsibleId: number | null stageId: number | null workspaceId: number | null + budgetPlanned: number | null + budgetActual: number | null + progress: number | null + phasesCount: number | null sequence: number | null } @@ -39,6 +43,10 @@ export type ProjectSumAggregateOutputType = { responsibleId: number | null stageId: number | null workspaceId: number | null + budgetPlanned: number | null + budgetActual: number | null + progress: number | null + phasesCount: number | null sequence: number | null } @@ -49,9 +57,24 @@ export type ProjectMinAggregateOutputType = { responsibleId: number | null stageId: number | null workspaceId: number | null + key: string | null + visibility: $Enums.ProjectVisibility | null + priority: $Enums.ProjectPriority | null + budgetPlanned: number | null + budgetActual: number | null + startDate: Date | null + endDate: Date | null + actualStartDate: Date | null + actualEndDate: Date | null + progress: number | null + currency: string | null + phasesCount: number | null + methodology: $Enums.ProjectMethodology | null + archivedAt: Date | null sequence: number | null createdAt: Date | null updatedAt: Date | null + deletedAt: Date | null } export type ProjectMaxAggregateOutputType = { @@ -61,9 +84,24 @@ export type ProjectMaxAggregateOutputType = { responsibleId: number | null stageId: number | null workspaceId: number | null + key: string | null + visibility: $Enums.ProjectVisibility | null + priority: $Enums.ProjectPriority | null + budgetPlanned: number | null + budgetActual: number | null + startDate: Date | null + endDate: Date | null + actualStartDate: Date | null + actualEndDate: Date | null + progress: number | null + currency: string | null + phasesCount: number | null + methodology: $Enums.ProjectMethodology | null + archivedAt: Date | null sequence: number | null createdAt: Date | null updatedAt: Date | null + deletedAt: Date | null } export type ProjectCountAggregateOutputType = { @@ -73,9 +111,26 @@ export type ProjectCountAggregateOutputType = { responsibleId: number stageId: number workspaceId: number + key: number + visibility: number + priority: number + budgetPlanned: number + budgetActual: number + startDate: number + endDate: number + actualStartDate: number + actualEndDate: number + progress: number + currency: number + phasesCount: number + methodology: number + tags: number + customFields: number + archivedAt: number sequence: number createdAt: number updatedAt: number + deletedAt: number _all: number } @@ -85,6 +140,10 @@ export type ProjectAvgAggregateInputType = { responsibleId?: true stageId?: true workspaceId?: true + budgetPlanned?: true + budgetActual?: true + progress?: true + phasesCount?: true sequence?: true } @@ -93,6 +152,10 @@ export type ProjectSumAggregateInputType = { responsibleId?: true stageId?: true workspaceId?: true + budgetPlanned?: true + budgetActual?: true + progress?: true + phasesCount?: true sequence?: true } @@ -103,9 +166,24 @@ export type ProjectMinAggregateInputType = { responsibleId?: true stageId?: true workspaceId?: true + key?: true + visibility?: true + priority?: true + budgetPlanned?: true + budgetActual?: true + startDate?: true + endDate?: true + actualStartDate?: true + actualEndDate?: true + progress?: true + currency?: true + phasesCount?: true + methodology?: true + archivedAt?: true sequence?: true createdAt?: true updatedAt?: true + deletedAt?: true } export type ProjectMaxAggregateInputType = { @@ -115,9 +193,24 @@ export type ProjectMaxAggregateInputType = { responsibleId?: true stageId?: true workspaceId?: true + key?: true + visibility?: true + priority?: true + budgetPlanned?: true + budgetActual?: true + startDate?: true + endDate?: true + actualStartDate?: true + actualEndDate?: true + progress?: true + currency?: true + phasesCount?: true + methodology?: true + archivedAt?: true sequence?: true createdAt?: true updatedAt?: true + deletedAt?: true } export type ProjectCountAggregateInputType = { @@ -127,9 +220,26 @@ export type ProjectCountAggregateInputType = { responsibleId?: true stageId?: true workspaceId?: true + key?: true + visibility?: true + priority?: true + budgetPlanned?: true + budgetActual?: true + startDate?: true + endDate?: true + actualStartDate?: true + actualEndDate?: true + progress?: true + currency?: true + phasesCount?: true + methodology?: true + tags?: true + customFields?: true + archivedAt?: true sequence?: true createdAt?: true updatedAt?: true + deletedAt?: true _all?: true } @@ -226,9 +336,26 @@ export type ProjectGroupByOutputType = { responsibleId: number | null stageId: number | null workspaceId: number + key: string | null + visibility: $Enums.ProjectVisibility + priority: $Enums.ProjectPriority + budgetPlanned: number + budgetActual: number + startDate: Date | null + endDate: Date | null + actualStartDate: Date | null + actualEndDate: Date | null + progress: number + currency: string + phasesCount: number + methodology: $Enums.ProjectMethodology + tags: string[] + customFields: runtime.JsonValue | null + archivedAt: Date | null sequence: number createdAt: Date updatedAt: Date + deletedAt: Date | null _count: ProjectCountAggregateOutputType | null _avg: ProjectAvgAggregateOutputType | null _sum: ProjectSumAggregateOutputType | null @@ -261,9 +388,26 @@ export type ProjectWhereInput = { responsibleId?: Prisma.IntNullableFilter<"Project"> | number | null stageId?: Prisma.IntNullableFilter<"Project"> | number | null workspaceId?: Prisma.IntFilter<"Project"> | number + key?: Prisma.StringNullableFilter<"Project"> | string | null + visibility?: Prisma.EnumProjectVisibilityFilter<"Project"> | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFilter<"Project"> | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFilter<"Project"> | number + budgetActual?: Prisma.FloatFilter<"Project"> | number + startDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + endDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + actualStartDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + actualEndDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + progress?: Prisma.FloatFilter<"Project"> | number + currency?: Prisma.StringFilter<"Project"> | string + phasesCount?: Prisma.IntFilter<"Project"> | number + methodology?: Prisma.EnumProjectMethodologyFilter<"Project"> | $Enums.ProjectMethodology + tags?: Prisma.StringNullableListFilter<"Project"> + customFields?: Prisma.JsonNullableFilter<"Project"> + archivedAt?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null sequence?: Prisma.IntFilter<"Project"> | number createdAt?: Prisma.DateTimeFilter<"Project"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Project"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null tasks?: Prisma.TaskListRelationFilter responsible?: Prisma.XOR | null stage?: Prisma.XOR | null @@ -281,9 +425,26 @@ export type ProjectOrderByWithRelationInput = { responsibleId?: Prisma.SortOrderInput | Prisma.SortOrder stageId?: Prisma.SortOrderInput | Prisma.SortOrder workspaceId?: Prisma.SortOrder + key?: Prisma.SortOrderInput | Prisma.SortOrder + visibility?: Prisma.SortOrder + priority?: Prisma.SortOrder + budgetPlanned?: Prisma.SortOrder + budgetActual?: Prisma.SortOrder + startDate?: Prisma.SortOrderInput | Prisma.SortOrder + endDate?: Prisma.SortOrderInput | Prisma.SortOrder + actualStartDate?: Prisma.SortOrderInput | Prisma.SortOrder + actualEndDate?: Prisma.SortOrderInput | Prisma.SortOrder + progress?: Prisma.SortOrder + currency?: Prisma.SortOrder + phasesCount?: Prisma.SortOrder + methodology?: Prisma.SortOrder + tags?: Prisma.SortOrder + customFields?: Prisma.SortOrderInput | Prisma.SortOrder + archivedAt?: Prisma.SortOrderInput | Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder tasks?: Prisma.TaskOrderByRelationAggregateInput responsible?: Prisma.UserOrderByWithRelationInput stage?: Prisma.ProjectStageOrderByWithRelationInput @@ -296,6 +457,7 @@ export type ProjectOrderByWithRelationInput = { export type ProjectWhereUniqueInput = Prisma.AtLeast<{ id?: number + key?: string AND?: Prisma.ProjectWhereInput | Prisma.ProjectWhereInput[] OR?: Prisma.ProjectWhereInput[] NOT?: Prisma.ProjectWhereInput | Prisma.ProjectWhereInput[] @@ -304,9 +466,25 @@ export type ProjectWhereUniqueInput = Prisma.AtLeast<{ responsibleId?: Prisma.IntNullableFilter<"Project"> | number | null stageId?: Prisma.IntNullableFilter<"Project"> | number | null workspaceId?: Prisma.IntFilter<"Project"> | number + visibility?: Prisma.EnumProjectVisibilityFilter<"Project"> | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFilter<"Project"> | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFilter<"Project"> | number + budgetActual?: Prisma.FloatFilter<"Project"> | number + startDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + endDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + actualStartDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + actualEndDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + progress?: Prisma.FloatFilter<"Project"> | number + currency?: Prisma.StringFilter<"Project"> | string + phasesCount?: Prisma.IntFilter<"Project"> | number + methodology?: Prisma.EnumProjectMethodologyFilter<"Project"> | $Enums.ProjectMethodology + tags?: Prisma.StringNullableListFilter<"Project"> + customFields?: Prisma.JsonNullableFilter<"Project"> + archivedAt?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null sequence?: Prisma.IntFilter<"Project"> | number createdAt?: Prisma.DateTimeFilter<"Project"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Project"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null tasks?: Prisma.TaskListRelationFilter responsible?: Prisma.XOR | null stage?: Prisma.XOR | null @@ -315,7 +493,7 @@ export type ProjectWhereUniqueInput = Prisma.AtLeast<{ attachments?: Prisma.AttachmentListRelationFilter timesheets?: Prisma.TimesheetListRelationFilter members?: Prisma.ProjectMemberListRelationFilter -}, "id"> +}, "id" | "key"> export type ProjectOrderByWithAggregationInput = { id?: Prisma.SortOrder @@ -324,9 +502,26 @@ export type ProjectOrderByWithAggregationInput = { responsibleId?: Prisma.SortOrderInput | Prisma.SortOrder stageId?: Prisma.SortOrderInput | Prisma.SortOrder workspaceId?: Prisma.SortOrder + key?: Prisma.SortOrderInput | Prisma.SortOrder + visibility?: Prisma.SortOrder + priority?: Prisma.SortOrder + budgetPlanned?: Prisma.SortOrder + budgetActual?: Prisma.SortOrder + startDate?: Prisma.SortOrderInput | Prisma.SortOrder + endDate?: Prisma.SortOrderInput | Prisma.SortOrder + actualStartDate?: Prisma.SortOrderInput | Prisma.SortOrder + actualEndDate?: Prisma.SortOrderInput | Prisma.SortOrder + progress?: Prisma.SortOrder + currency?: Prisma.SortOrder + phasesCount?: Prisma.SortOrder + methodology?: Prisma.SortOrder + tags?: Prisma.SortOrder + customFields?: Prisma.SortOrderInput | Prisma.SortOrder + archivedAt?: Prisma.SortOrderInput | Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder _count?: Prisma.ProjectCountOrderByAggregateInput _avg?: Prisma.ProjectAvgOrderByAggregateInput _max?: Prisma.ProjectMaxOrderByAggregateInput @@ -344,17 +539,51 @@ export type ProjectScalarWhereWithAggregatesInput = { responsibleId?: Prisma.IntNullableWithAggregatesFilter<"Project"> | number | null stageId?: Prisma.IntNullableWithAggregatesFilter<"Project"> | number | null workspaceId?: Prisma.IntWithAggregatesFilter<"Project"> | number + key?: Prisma.StringNullableWithAggregatesFilter<"Project"> | string | null + visibility?: Prisma.EnumProjectVisibilityWithAggregatesFilter<"Project"> | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityWithAggregatesFilter<"Project"> | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatWithAggregatesFilter<"Project"> | number + budgetActual?: Prisma.FloatWithAggregatesFilter<"Project"> | number + startDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Project"> | Date | string | null + endDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Project"> | Date | string | null + actualStartDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Project"> | Date | string | null + actualEndDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Project"> | Date | string | null + progress?: Prisma.FloatWithAggregatesFilter<"Project"> | number + currency?: Prisma.StringWithAggregatesFilter<"Project"> | string + phasesCount?: Prisma.IntWithAggregatesFilter<"Project"> | number + methodology?: Prisma.EnumProjectMethodologyWithAggregatesFilter<"Project"> | $Enums.ProjectMethodology + tags?: Prisma.StringNullableListFilter<"Project"> + customFields?: Prisma.JsonNullableWithAggregatesFilter<"Project"> + archivedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"Project"> | Date | string | null sequence?: Prisma.IntWithAggregatesFilter<"Project"> | number createdAt?: Prisma.DateTimeWithAggregatesFilter<"Project"> | Date | string updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Project"> | Date | string + deletedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"Project"> | Date | string | null } export type ProjectCreateInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput @@ -372,9 +601,26 @@ export type ProjectUncheckedCreateInput = { responsibleId?: number | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput @@ -385,9 +631,26 @@ export type ProjectUncheckedCreateInput = { export type ProjectUpdateInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput @@ -405,9 +668,26 @@ export type ProjectUncheckedUpdateInput = { responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput @@ -422,17 +702,51 @@ export type ProjectCreateManyInput = { responsibleId?: number | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type ProjectUpdateManyMutationInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type ProjectUncheckedUpdateManyInput = { @@ -442,9 +756,26 @@ export type ProjectUncheckedUpdateManyInput = { responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type ProjectListRelationFilter = { @@ -457,6 +788,14 @@ export type ProjectOrderByRelationAggregateInput = { _count?: Prisma.SortOrder } +export type StringNullableListFilter<$PrismaModel = never> = { + equals?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + has?: string | Prisma.StringFieldRefInput<$PrismaModel> | null + hasEvery?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + hasSome?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + isEmpty?: boolean +} + export type ProjectCountOrderByAggregateInput = { id?: Prisma.SortOrder name?: Prisma.SortOrder @@ -464,9 +803,26 @@ export type ProjectCountOrderByAggregateInput = { responsibleId?: Prisma.SortOrder stageId?: Prisma.SortOrder workspaceId?: Prisma.SortOrder + key?: Prisma.SortOrder + visibility?: Prisma.SortOrder + priority?: Prisma.SortOrder + budgetPlanned?: Prisma.SortOrder + budgetActual?: Prisma.SortOrder + startDate?: Prisma.SortOrder + endDate?: Prisma.SortOrder + actualStartDate?: Prisma.SortOrder + actualEndDate?: Prisma.SortOrder + progress?: Prisma.SortOrder + currency?: Prisma.SortOrder + phasesCount?: Prisma.SortOrder + methodology?: Prisma.SortOrder + tags?: Prisma.SortOrder + customFields?: Prisma.SortOrder + archivedAt?: Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder } export type ProjectAvgOrderByAggregateInput = { @@ -474,6 +830,10 @@ export type ProjectAvgOrderByAggregateInput = { responsibleId?: Prisma.SortOrder stageId?: Prisma.SortOrder workspaceId?: Prisma.SortOrder + budgetPlanned?: Prisma.SortOrder + budgetActual?: Prisma.SortOrder + progress?: Prisma.SortOrder + phasesCount?: Prisma.SortOrder sequence?: Prisma.SortOrder } @@ -484,9 +844,24 @@ export type ProjectMaxOrderByAggregateInput = { responsibleId?: Prisma.SortOrder stageId?: Prisma.SortOrder workspaceId?: Prisma.SortOrder + key?: Prisma.SortOrder + visibility?: Prisma.SortOrder + priority?: Prisma.SortOrder + budgetPlanned?: Prisma.SortOrder + budgetActual?: Prisma.SortOrder + startDate?: Prisma.SortOrder + endDate?: Prisma.SortOrder + actualStartDate?: Prisma.SortOrder + actualEndDate?: Prisma.SortOrder + progress?: Prisma.SortOrder + currency?: Prisma.SortOrder + phasesCount?: Prisma.SortOrder + methodology?: Prisma.SortOrder + archivedAt?: Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder } export type ProjectMinOrderByAggregateInput = { @@ -496,9 +871,24 @@ export type ProjectMinOrderByAggregateInput = { responsibleId?: Prisma.SortOrder stageId?: Prisma.SortOrder workspaceId?: Prisma.SortOrder + key?: Prisma.SortOrder + visibility?: Prisma.SortOrder + priority?: Prisma.SortOrder + budgetPlanned?: Prisma.SortOrder + budgetActual?: Prisma.SortOrder + startDate?: Prisma.SortOrder + endDate?: Prisma.SortOrder + actualStartDate?: Prisma.SortOrder + actualEndDate?: Prisma.SortOrder + progress?: Prisma.SortOrder + currency?: Prisma.SortOrder + phasesCount?: Prisma.SortOrder + methodology?: Prisma.SortOrder + archivedAt?: Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder } export type ProjectSumOrderByAggregateInput = { @@ -506,6 +896,10 @@ export type ProjectSumOrderByAggregateInput = { responsibleId?: Prisma.SortOrder stageId?: Prisma.SortOrder workspaceId?: Prisma.SortOrder + budgetPlanned?: Prisma.SortOrder + budgetActual?: Prisma.SortOrder + progress?: Prisma.SortOrder + phasesCount?: Prisma.SortOrder sequence?: Prisma.SortOrder } @@ -645,6 +1039,35 @@ export type ProjectUncheckedUpdateManyWithoutStageNestedInput = { deleteMany?: Prisma.ProjectScalarWhereInput | Prisma.ProjectScalarWhereInput[] } +export type ProjectCreatetagsInput = { + set: string[] +} + +export type EnumProjectVisibilityFieldUpdateOperationsInput = { + set?: $Enums.ProjectVisibility +} + +export type EnumProjectPriorityFieldUpdateOperationsInput = { + set?: $Enums.ProjectPriority +} + +export type FloatFieldUpdateOperationsInput = { + set?: number + increment?: number + decrement?: number + multiply?: number + divide?: number +} + +export type EnumProjectMethodologyFieldUpdateOperationsInput = { + set?: $Enums.ProjectMethodology +} + +export type ProjectUpdatetagsInput = { + set?: string[] + push?: string | string[] +} + export type NullableIntFieldUpdateOperationsInput = { set?: number | null increment?: number @@ -730,9 +1153,26 @@ export type ProjectUpdateOneRequiredWithoutMembersNestedInput = { export type ProjectCreateWithoutResponsibleInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput workspace: Prisma.WorkspaceCreateNestedOneWithoutProjectsInput @@ -748,9 +1188,26 @@ export type ProjectUncheckedCreateWithoutResponsibleInput = { description?: string | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput @@ -794,17 +1251,51 @@ export type ProjectScalarWhereInput = { responsibleId?: Prisma.IntNullableFilter<"Project"> | number | null stageId?: Prisma.IntNullableFilter<"Project"> | number | null workspaceId?: Prisma.IntFilter<"Project"> | number + key?: Prisma.StringNullableFilter<"Project"> | string | null + visibility?: Prisma.EnumProjectVisibilityFilter<"Project"> | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFilter<"Project"> | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFilter<"Project"> | number + budgetActual?: Prisma.FloatFilter<"Project"> | number + startDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + endDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + actualStartDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + actualEndDate?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null + progress?: Prisma.FloatFilter<"Project"> | number + currency?: Prisma.StringFilter<"Project"> | string + phasesCount?: Prisma.IntFilter<"Project"> | number + methodology?: Prisma.EnumProjectMethodologyFilter<"Project"> | $Enums.ProjectMethodology + tags?: Prisma.StringNullableListFilter<"Project"> + customFields?: Prisma.JsonNullableFilter<"Project"> + archivedAt?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null sequence?: Prisma.IntFilter<"Project"> | number createdAt?: Prisma.DateTimeFilter<"Project"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Project"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Project"> | Date | string | null } export type ProjectCreateWithoutWorkspaceInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput @@ -820,9 +1311,26 @@ export type ProjectUncheckedCreateWithoutWorkspaceInput = { description?: string | null responsibleId?: number | null stageId?: number | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput @@ -859,9 +1367,26 @@ export type ProjectUpdateManyWithWhereWithoutWorkspaceInput = { export type ProjectCreateWithoutStageInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput workspace: Prisma.WorkspaceCreateNestedOneWithoutProjectsInput @@ -877,9 +1402,26 @@ export type ProjectUncheckedCreateWithoutStageInput = { description?: string | null responsibleId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput @@ -916,9 +1458,26 @@ export type ProjectUpdateManyWithWhereWithoutStageInput = { export type ProjectCreateWithoutTasksInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput workspace: Prisma.WorkspaceCreateNestedOneWithoutProjectsInput @@ -935,9 +1494,26 @@ export type ProjectUncheckedCreateWithoutTasksInput = { responsibleId?: number | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutProjectInput @@ -963,9 +1539,26 @@ export type ProjectUpdateToOneWithWhereWithoutTasksInput = { export type ProjectUpdateWithoutTasksInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput workspace?: Prisma.WorkspaceUpdateOneRequiredWithoutProjectsNestedInput @@ -982,9 +1575,26 @@ export type ProjectUncheckedUpdateWithoutTasksInput = { responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutProjectNestedInput @@ -994,9 +1604,26 @@ export type ProjectUncheckedUpdateWithoutTasksInput = { export type ProjectCreateWithoutTimesheetsInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput @@ -1013,9 +1640,26 @@ export type ProjectUncheckedCreateWithoutTimesheetsInput = { responsibleId?: number | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput @@ -1041,9 +1685,26 @@ export type ProjectUpdateToOneWithWhereWithoutTimesheetsInput = { export type ProjectUpdateWithoutTimesheetsInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput @@ -1060,9 +1721,26 @@ export type ProjectUncheckedUpdateWithoutTimesheetsInput = { responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput @@ -1072,9 +1750,26 @@ export type ProjectUncheckedUpdateWithoutTimesheetsInput = { export type ProjectCreateWithoutCommentsInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput @@ -1091,9 +1786,26 @@ export type ProjectUncheckedCreateWithoutCommentsInput = { responsibleId?: number | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutProjectInput @@ -1119,9 +1831,26 @@ export type ProjectUpdateToOneWithWhereWithoutCommentsInput = { export type ProjectUpdateWithoutCommentsInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput @@ -1138,9 +1867,26 @@ export type ProjectUncheckedUpdateWithoutCommentsInput = { responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutProjectNestedInput @@ -1150,9 +1896,26 @@ export type ProjectUncheckedUpdateWithoutCommentsInput = { export type ProjectCreateWithoutAttachmentsInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput @@ -1169,9 +1932,26 @@ export type ProjectUncheckedCreateWithoutAttachmentsInput = { responsibleId?: number | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutProjectInput @@ -1197,9 +1977,26 @@ export type ProjectUpdateToOneWithWhereWithoutAttachmentsInput = { export type ProjectUpdateWithoutAttachmentsInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput @@ -1216,9 +2013,26 @@ export type ProjectUncheckedUpdateWithoutAttachmentsInput = { responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutProjectNestedInput @@ -1228,9 +2042,26 @@ export type ProjectUncheckedUpdateWithoutAttachmentsInput = { export type ProjectCreateWithoutMembersInput = { name: string description?: string | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskCreateNestedManyWithoutProjectInput responsible?: Prisma.UserCreateNestedOneWithoutProjectsInput stage?: Prisma.ProjectStageCreateNestedOneWithoutProjectsInput @@ -1247,9 +2078,26 @@ export type ProjectUncheckedCreateWithoutMembersInput = { responsibleId?: number | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutProjectInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutProjectInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutProjectInput @@ -1275,9 +2123,26 @@ export type ProjectUpdateToOneWithWhereWithoutMembersInput = { export type ProjectUpdateWithoutMembersInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput @@ -1294,9 +2159,26 @@ export type ProjectUncheckedUpdateWithoutMembersInput = { responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput @@ -1309,17 +2191,51 @@ export type ProjectCreateManyResponsibleInput = { description?: string | null stageId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type ProjectUpdateWithoutResponsibleInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput workspace?: Prisma.WorkspaceUpdateOneRequiredWithoutProjectsNestedInput @@ -1335,9 +2251,26 @@ export type ProjectUncheckedUpdateWithoutResponsibleInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput @@ -1351,9 +2284,26 @@ export type ProjectUncheckedUpdateManyWithoutResponsibleInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type ProjectCreateManyWorkspaceInput = { @@ -1362,17 +2312,51 @@ export type ProjectCreateManyWorkspaceInput = { description?: string | null responsibleId?: number | null stageId?: number | null + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type ProjectUpdateWithoutWorkspaceInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput stage?: Prisma.ProjectStageUpdateOneWithoutProjectsNestedInput @@ -1388,9 +2372,26 @@ export type ProjectUncheckedUpdateWithoutWorkspaceInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput @@ -1404,9 +2405,26 @@ export type ProjectUncheckedUpdateManyWithoutWorkspaceInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type ProjectCreateManyStageInput = { @@ -1415,17 +2433,51 @@ export type ProjectCreateManyStageInput = { description?: string | null responsibleId?: number | null workspaceId: number + key?: string | null + visibility?: $Enums.ProjectVisibility + priority?: $Enums.ProjectPriority + budgetPlanned?: number + budgetActual?: number + startDate?: Date | string | null + endDate?: Date | string | null + actualStartDate?: Date | string | null + actualEndDate?: Date | string | null + progress?: number + currency?: string + phasesCount?: number + methodology?: $Enums.ProjectMethodology + tags?: Prisma.ProjectCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type ProjectUpdateWithoutStageInput = { name?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUpdateManyWithoutProjectNestedInput responsible?: Prisma.UserUpdateOneWithoutProjectsNestedInput workspace?: Prisma.WorkspaceUpdateOneRequiredWithoutProjectsNestedInput @@ -1441,9 +2493,26 @@ export type ProjectUncheckedUpdateWithoutStageInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null tasks?: Prisma.TaskUncheckedUpdateManyWithoutProjectNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutProjectNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutProjectNestedInput @@ -1457,9 +2526,26 @@ export type ProjectUncheckedUpdateManyWithoutStageInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null responsibleId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null workspaceId?: Prisma.IntFieldUpdateOperationsInput | number + key?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + visibility?: Prisma.EnumProjectVisibilityFieldUpdateOperationsInput | $Enums.ProjectVisibility + priority?: Prisma.EnumProjectPriorityFieldUpdateOperationsInput | $Enums.ProjectPriority + budgetPlanned?: Prisma.FloatFieldUpdateOperationsInput | number + budgetActual?: Prisma.FloatFieldUpdateOperationsInput | number + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualStartDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + actualEndDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + progress?: Prisma.FloatFieldUpdateOperationsInput | number + currency?: Prisma.StringFieldUpdateOperationsInput | string + phasesCount?: Prisma.IntFieldUpdateOperationsInput | number + methodology?: Prisma.EnumProjectMethodologyFieldUpdateOperationsInput | $Enums.ProjectMethodology + tags?: Prisma.ProjectUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + archivedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } @@ -1536,9 +2622,26 @@ export type ProjectSelect responsible?: boolean | Prisma.Project$responsibleArgs stage?: boolean | Prisma.Project$stageArgs @@ -1557,9 +2660,26 @@ export type ProjectSelectCreateManyAndReturn stage?: boolean | Prisma.Project$stageArgs workspace?: boolean | Prisma.WorkspaceDefaultArgs @@ -1572,9 +2692,26 @@ export type ProjectSelectUpdateManyAndReturn stage?: boolean | Prisma.Project$stageArgs workspace?: boolean | Prisma.WorkspaceDefaultArgs @@ -1587,12 +2724,29 @@ export type ProjectSelectScalar = { responsibleId?: boolean stageId?: boolean workspaceId?: boolean + key?: boolean + visibility?: boolean + priority?: boolean + budgetPlanned?: boolean + budgetActual?: boolean + startDate?: boolean + endDate?: boolean + actualStartDate?: boolean + actualEndDate?: boolean + progress?: boolean + currency?: boolean + phasesCount?: boolean + methodology?: boolean + tags?: boolean + customFields?: boolean + archivedAt?: boolean sequence?: boolean createdAt?: boolean updatedAt?: boolean + deletedAt?: boolean } -export type ProjectOmit = runtime.Types.Extensions.GetOmit<"id" | "name" | "description" | "responsibleId" | "stageId" | "workspaceId" | "sequence" | "createdAt" | "updatedAt", ExtArgs["result"]["project"]> +export type ProjectOmit = runtime.Types.Extensions.GetOmit<"id" | "name" | "description" | "responsibleId" | "stageId" | "workspaceId" | "key" | "visibility" | "priority" | "budgetPlanned" | "budgetActual" | "startDate" | "endDate" | "actualStartDate" | "actualEndDate" | "progress" | "currency" | "phasesCount" | "methodology" | "tags" | "customFields" | "archivedAt" | "sequence" | "createdAt" | "updatedAt" | "deletedAt", ExtArgs["result"]["project"]> export type ProjectInclude = { tasks?: boolean | Prisma.Project$tasksArgs responsible?: boolean | Prisma.Project$responsibleArgs @@ -1634,9 +2788,26 @@ export type $ProjectPayload composites: {} } @@ -2074,9 +3245,26 @@ export interface ProjectFieldRefs { readonly responsibleId: Prisma.FieldRef<"Project", 'Int'> readonly stageId: Prisma.FieldRef<"Project", 'Int'> readonly workspaceId: Prisma.FieldRef<"Project", 'Int'> + readonly key: Prisma.FieldRef<"Project", 'String'> + readonly visibility: Prisma.FieldRef<"Project", 'ProjectVisibility'> + readonly priority: Prisma.FieldRef<"Project", 'ProjectPriority'> + readonly budgetPlanned: Prisma.FieldRef<"Project", 'Float'> + readonly budgetActual: Prisma.FieldRef<"Project", 'Float'> + readonly startDate: Prisma.FieldRef<"Project", 'DateTime'> + readonly endDate: Prisma.FieldRef<"Project", 'DateTime'> + readonly actualStartDate: Prisma.FieldRef<"Project", 'DateTime'> + readonly actualEndDate: Prisma.FieldRef<"Project", 'DateTime'> + readonly progress: Prisma.FieldRef<"Project", 'Float'> + readonly currency: Prisma.FieldRef<"Project", 'String'> + readonly phasesCount: Prisma.FieldRef<"Project", 'Int'> + readonly methodology: Prisma.FieldRef<"Project", 'ProjectMethodology'> + readonly tags: Prisma.FieldRef<"Project", 'String[]'> + readonly customFields: Prisma.FieldRef<"Project", 'Json'> + readonly archivedAt: Prisma.FieldRef<"Project", 'DateTime'> readonly sequence: Prisma.FieldRef<"Project", 'Int'> readonly createdAt: Prisma.FieldRef<"Project", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"Project", 'DateTime'> + readonly deletedAt: Prisma.FieldRef<"Project", 'DateTime'> } diff --git a/backend/prisma/generated/models/Task.ts b/backend/prisma/generated/models/Task.ts index 6f36c3b..a918344 100644 --- a/backend/prisma/generated/models/Task.ts +++ b/backend/prisma/generated/models/Task.ts @@ -31,6 +31,11 @@ export type TaskAvgAggregateOutputType = { userId: number | null projectId: number | null stageId: number | null + parentTaskId: number | null + reporterId: number | null + estimatedHours: number | null + remainingHours: number | null + progress: number | null sequence: number | null } @@ -39,6 +44,11 @@ export type TaskSumAggregateOutputType = { userId: number | null projectId: number | null stageId: number | null + parentTaskId: number | null + reporterId: number | null + estimatedHours: number | null + remainingHours: number | null + progress: number | null sequence: number | null } @@ -49,6 +59,17 @@ export type TaskMinAggregateOutputType = { userId: number | null projectId: number | null stageId: number | null + parentTaskId: number | null + type: $Enums.TaskType | null + reporterId: number | null + startDate: Date | null + dueDate: Date | null + completedAt: Date | null + estimatedHours: number | null + remainingHours: number | null + progress: number | null + priority: $Enums.TaskPriority | null + deletedAt: Date | null sequence: number | null createdAt: Date | null updatedAt: Date | null @@ -61,6 +82,17 @@ export type TaskMaxAggregateOutputType = { userId: number | null projectId: number | null stageId: number | null + parentTaskId: number | null + type: $Enums.TaskType | null + reporterId: number | null + startDate: Date | null + dueDate: Date | null + completedAt: Date | null + estimatedHours: number | null + remainingHours: number | null + progress: number | null + priority: $Enums.TaskPriority | null + deletedAt: Date | null sequence: number | null createdAt: Date | null updatedAt: Date | null @@ -73,6 +105,22 @@ export type TaskCountAggregateOutputType = { userId: number projectId: number stageId: number + parentTaskId: number + type: number + reporterId: number + watchers: number + startDate: number + dueDate: number + completedAt: number + estimatedHours: number + remainingHours: number + progress: number + priority: number + tags: number + checklist: number + dependencies: number + customFields: number + deletedAt: number sequence: number createdAt: number updatedAt: number @@ -85,6 +133,11 @@ export type TaskAvgAggregateInputType = { userId?: true projectId?: true stageId?: true + parentTaskId?: true + reporterId?: true + estimatedHours?: true + remainingHours?: true + progress?: true sequence?: true } @@ -93,6 +146,11 @@ export type TaskSumAggregateInputType = { userId?: true projectId?: true stageId?: true + parentTaskId?: true + reporterId?: true + estimatedHours?: true + remainingHours?: true + progress?: true sequence?: true } @@ -103,6 +161,17 @@ export type TaskMinAggregateInputType = { userId?: true projectId?: true stageId?: true + parentTaskId?: true + type?: true + reporterId?: true + startDate?: true + dueDate?: true + completedAt?: true + estimatedHours?: true + remainingHours?: true + progress?: true + priority?: true + deletedAt?: true sequence?: true createdAt?: true updatedAt?: true @@ -115,6 +184,17 @@ export type TaskMaxAggregateInputType = { userId?: true projectId?: true stageId?: true + parentTaskId?: true + type?: true + reporterId?: true + startDate?: true + dueDate?: true + completedAt?: true + estimatedHours?: true + remainingHours?: true + progress?: true + priority?: true + deletedAt?: true sequence?: true createdAt?: true updatedAt?: true @@ -127,6 +207,22 @@ export type TaskCountAggregateInputType = { userId?: true projectId?: true stageId?: true + parentTaskId?: true + type?: true + reporterId?: true + watchers?: true + startDate?: true + dueDate?: true + completedAt?: true + estimatedHours?: true + remainingHours?: true + progress?: true + priority?: true + tags?: true + checklist?: true + dependencies?: true + customFields?: true + deletedAt?: true sequence?: true createdAt?: true updatedAt?: true @@ -226,6 +322,22 @@ export type TaskGroupByOutputType = { userId: number projectId: number stageId: number | null + parentTaskId: number | null + type: $Enums.TaskType + reporterId: number | null + watchers: runtime.JsonValue | null + startDate: Date | null + dueDate: Date | null + completedAt: Date | null + estimatedHours: number + remainingHours: number + progress: number + priority: $Enums.TaskPriority + tags: string[] + checklist: runtime.JsonValue | null + dependencies: runtime.JsonValue | null + customFields: runtime.JsonValue | null + deletedAt: Date | null sequence: number createdAt: Date updatedAt: Date @@ -261,6 +373,22 @@ export type TaskWhereInput = { userId?: Prisma.IntFilter<"Task"> | number projectId?: Prisma.IntFilter<"Task"> | number stageId?: Prisma.IntNullableFilter<"Task"> | number | null + parentTaskId?: Prisma.IntNullableFilter<"Task"> | number | null + type?: Prisma.EnumTaskTypeFilter<"Task"> | $Enums.TaskType + reporterId?: Prisma.IntNullableFilter<"Task"> | number | null + watchers?: Prisma.JsonNullableFilter<"Task"> + startDate?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + dueDate?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + completedAt?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + estimatedHours?: Prisma.FloatFilter<"Task"> | number + remainingHours?: Prisma.FloatFilter<"Task"> | number + progress?: Prisma.FloatFilter<"Task"> | number + priority?: Prisma.EnumTaskPriorityFilter<"Task"> | $Enums.TaskPriority + tags?: Prisma.StringNullableListFilter<"Task"> + checklist?: Prisma.JsonNullableFilter<"Task"> + dependencies?: Prisma.JsonNullableFilter<"Task"> + customFields?: Prisma.JsonNullableFilter<"Task"> + deletedAt?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null sequence?: Prisma.IntFilter<"Task"> | number createdAt?: Prisma.DateTimeFilter<"Task"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Task"> | Date | string @@ -270,6 +398,9 @@ export type TaskWhereInput = { comments?: Prisma.CommentListRelationFilter attachments?: Prisma.AttachmentListRelationFilter timesheets?: Prisma.TimesheetListRelationFilter + parentTask?: Prisma.XOR | null + subtasks?: Prisma.TaskListRelationFilter + reporter?: Prisma.XOR | null } export type TaskOrderByWithRelationInput = { @@ -279,6 +410,22 @@ export type TaskOrderByWithRelationInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder stageId?: Prisma.SortOrderInput | Prisma.SortOrder + parentTaskId?: Prisma.SortOrderInput | Prisma.SortOrder + type?: Prisma.SortOrder + reporterId?: Prisma.SortOrderInput | Prisma.SortOrder + watchers?: Prisma.SortOrderInput | Prisma.SortOrder + startDate?: Prisma.SortOrderInput | Prisma.SortOrder + dueDate?: Prisma.SortOrderInput | Prisma.SortOrder + completedAt?: Prisma.SortOrderInput | Prisma.SortOrder + estimatedHours?: Prisma.SortOrder + remainingHours?: Prisma.SortOrder + progress?: Prisma.SortOrder + priority?: Prisma.SortOrder + tags?: Prisma.SortOrder + checklist?: Prisma.SortOrderInput | Prisma.SortOrder + dependencies?: Prisma.SortOrderInput | Prisma.SortOrder + customFields?: Prisma.SortOrderInput | Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -288,6 +435,9 @@ export type TaskOrderByWithRelationInput = { comments?: Prisma.CommentOrderByRelationAggregateInput attachments?: Prisma.AttachmentOrderByRelationAggregateInput timesheets?: Prisma.TimesheetOrderByRelationAggregateInput + parentTask?: Prisma.TaskOrderByWithRelationInput + subtasks?: Prisma.TaskOrderByRelationAggregateInput + reporter?: Prisma.UserOrderByWithRelationInput } export type TaskWhereUniqueInput = Prisma.AtLeast<{ @@ -300,6 +450,22 @@ export type TaskWhereUniqueInput = Prisma.AtLeast<{ userId?: Prisma.IntFilter<"Task"> | number projectId?: Prisma.IntFilter<"Task"> | number stageId?: Prisma.IntNullableFilter<"Task"> | number | null + parentTaskId?: Prisma.IntNullableFilter<"Task"> | number | null + type?: Prisma.EnumTaskTypeFilter<"Task"> | $Enums.TaskType + reporterId?: Prisma.IntNullableFilter<"Task"> | number | null + watchers?: Prisma.JsonNullableFilter<"Task"> + startDate?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + dueDate?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + completedAt?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + estimatedHours?: Prisma.FloatFilter<"Task"> | number + remainingHours?: Prisma.FloatFilter<"Task"> | number + progress?: Prisma.FloatFilter<"Task"> | number + priority?: Prisma.EnumTaskPriorityFilter<"Task"> | $Enums.TaskPriority + tags?: Prisma.StringNullableListFilter<"Task"> + checklist?: Prisma.JsonNullableFilter<"Task"> + dependencies?: Prisma.JsonNullableFilter<"Task"> + customFields?: Prisma.JsonNullableFilter<"Task"> + deletedAt?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null sequence?: Prisma.IntFilter<"Task"> | number createdAt?: Prisma.DateTimeFilter<"Task"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Task"> | Date | string @@ -309,6 +475,9 @@ export type TaskWhereUniqueInput = Prisma.AtLeast<{ comments?: Prisma.CommentListRelationFilter attachments?: Prisma.AttachmentListRelationFilter timesheets?: Prisma.TimesheetListRelationFilter + parentTask?: Prisma.XOR | null + subtasks?: Prisma.TaskListRelationFilter + reporter?: Prisma.XOR | null }, "id"> export type TaskOrderByWithAggregationInput = { @@ -318,6 +487,22 @@ export type TaskOrderByWithAggregationInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder stageId?: Prisma.SortOrderInput | Prisma.SortOrder + parentTaskId?: Prisma.SortOrderInput | Prisma.SortOrder + type?: Prisma.SortOrder + reporterId?: Prisma.SortOrderInput | Prisma.SortOrder + watchers?: Prisma.SortOrderInput | Prisma.SortOrder + startDate?: Prisma.SortOrderInput | Prisma.SortOrder + dueDate?: Prisma.SortOrderInput | Prisma.SortOrder + completedAt?: Prisma.SortOrderInput | Prisma.SortOrder + estimatedHours?: Prisma.SortOrder + remainingHours?: Prisma.SortOrder + progress?: Prisma.SortOrder + priority?: Prisma.SortOrder + tags?: Prisma.SortOrder + checklist?: Prisma.SortOrderInput | Prisma.SortOrder + dependencies?: Prisma.SortOrderInput | Prisma.SortOrder + customFields?: Prisma.SortOrderInput | Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -338,6 +523,22 @@ export type TaskScalarWhereWithAggregatesInput = { userId?: Prisma.IntWithAggregatesFilter<"Task"> | number projectId?: Prisma.IntWithAggregatesFilter<"Task"> | number stageId?: Prisma.IntNullableWithAggregatesFilter<"Task"> | number | null + parentTaskId?: Prisma.IntNullableWithAggregatesFilter<"Task"> | number | null + type?: Prisma.EnumTaskTypeWithAggregatesFilter<"Task"> | $Enums.TaskType + reporterId?: Prisma.IntNullableWithAggregatesFilter<"Task"> | number | null + watchers?: Prisma.JsonNullableWithAggregatesFilter<"Task"> + startDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Task"> | Date | string | null + dueDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Task"> | Date | string | null + completedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"Task"> | Date | string | null + estimatedHours?: Prisma.FloatWithAggregatesFilter<"Task"> | number + remainingHours?: Prisma.FloatWithAggregatesFilter<"Task"> | number + progress?: Prisma.FloatWithAggregatesFilter<"Task"> | number + priority?: Prisma.EnumTaskPriorityWithAggregatesFilter<"Task"> | $Enums.TaskPriority + tags?: Prisma.StringNullableListFilter<"Task"> + checklist?: Prisma.JsonNullableWithAggregatesFilter<"Task"> + dependencies?: Prisma.JsonNullableWithAggregatesFilter<"Task"> + customFields?: Prisma.JsonNullableWithAggregatesFilter<"Task"> + deletedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"Task"> | Date | string | null sequence?: Prisma.IntWithAggregatesFilter<"Task"> | number createdAt?: Prisma.DateTimeWithAggregatesFilter<"Task"> | Date | string updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Task"> | Date | string @@ -346,6 +547,20 @@ export type TaskScalarWhereWithAggregatesInput = { export type TaskCreateInput = { title: string description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -355,6 +570,9 @@ export type TaskCreateInput = { comments?: Prisma.CommentCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput } export type TaskUncheckedCreateInput = { @@ -364,17 +582,48 @@ export type TaskUncheckedCreateInput = { userId: number projectId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput } export type TaskUpdateInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -384,6 +633,9 @@ export type TaskUpdateInput = { comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput } export type TaskUncheckedUpdateInput = { @@ -393,12 +645,29 @@ export type TaskUncheckedUpdateInput = { userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput } export type TaskCreateManyInput = { @@ -408,6 +677,22 @@ export type TaskCreateManyInput = { userId: number projectId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -416,6 +701,20 @@ export type TaskCreateManyInput = { export type TaskUpdateManyMutationInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -428,6 +727,22 @@ export type TaskUncheckedUpdateManyInput = { userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -443,6 +758,11 @@ export type TaskOrderByRelationAggregateInput = { _count?: Prisma.SortOrder } +export type TaskNullableScalarRelationFilter = { + is?: Prisma.TaskWhereInput | null + isNot?: Prisma.TaskWhereInput | null +} + export type TaskCountOrderByAggregateInput = { id?: Prisma.SortOrder title?: Prisma.SortOrder @@ -450,6 +770,22 @@ export type TaskCountOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder stageId?: Prisma.SortOrder + parentTaskId?: Prisma.SortOrder + type?: Prisma.SortOrder + reporterId?: Prisma.SortOrder + watchers?: Prisma.SortOrder + startDate?: Prisma.SortOrder + dueDate?: Prisma.SortOrder + completedAt?: Prisma.SortOrder + estimatedHours?: Prisma.SortOrder + remainingHours?: Prisma.SortOrder + progress?: Prisma.SortOrder + priority?: Prisma.SortOrder + tags?: Prisma.SortOrder + checklist?: Prisma.SortOrder + dependencies?: Prisma.SortOrder + customFields?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -460,6 +796,11 @@ export type TaskAvgOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder stageId?: Prisma.SortOrder + parentTaskId?: Prisma.SortOrder + reporterId?: Prisma.SortOrder + estimatedHours?: Prisma.SortOrder + remainingHours?: Prisma.SortOrder + progress?: Prisma.SortOrder sequence?: Prisma.SortOrder } @@ -470,6 +811,17 @@ export type TaskMaxOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder stageId?: Prisma.SortOrder + parentTaskId?: Prisma.SortOrder + type?: Prisma.SortOrder + reporterId?: Prisma.SortOrder + startDate?: Prisma.SortOrder + dueDate?: Prisma.SortOrder + completedAt?: Prisma.SortOrder + estimatedHours?: Prisma.SortOrder + remainingHours?: Prisma.SortOrder + progress?: Prisma.SortOrder + priority?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -482,6 +834,17 @@ export type TaskMinOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder stageId?: Prisma.SortOrder + parentTaskId?: Prisma.SortOrder + type?: Prisma.SortOrder + reporterId?: Prisma.SortOrder + startDate?: Prisma.SortOrder + dueDate?: Prisma.SortOrder + completedAt?: Prisma.SortOrder + estimatedHours?: Prisma.SortOrder + remainingHours?: Prisma.SortOrder + progress?: Prisma.SortOrder + priority?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder sequence?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -492,14 +855,14 @@ export type TaskSumOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder stageId?: Prisma.SortOrder + parentTaskId?: Prisma.SortOrder + reporterId?: Prisma.SortOrder + estimatedHours?: Prisma.SortOrder + remainingHours?: Prisma.SortOrder + progress?: Prisma.SortOrder sequence?: Prisma.SortOrder } -export type TaskNullableScalarRelationFilter = { - is?: Prisma.TaskWhereInput | null - isNot?: Prisma.TaskWhereInput | null -} - export type TaskCreateNestedManyWithoutUserInput = { create?: Prisma.XOR | Prisma.TaskCreateWithoutUserInput[] | Prisma.TaskUncheckedCreateWithoutUserInput[] connectOrCreate?: Prisma.TaskCreateOrConnectWithoutUserInput | Prisma.TaskCreateOrConnectWithoutUserInput[] @@ -507,6 +870,13 @@ export type TaskCreateNestedManyWithoutUserInput = { connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] } +export type TaskCreateNestedManyWithoutReporterInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutReporterInput[] | Prisma.TaskUncheckedCreateWithoutReporterInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutReporterInput | Prisma.TaskCreateOrConnectWithoutReporterInput[] + createMany?: Prisma.TaskCreateManyReporterInputEnvelope + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] +} + export type TaskUncheckedCreateNestedManyWithoutUserInput = { create?: Prisma.XOR | Prisma.TaskCreateWithoutUserInput[] | Prisma.TaskUncheckedCreateWithoutUserInput[] connectOrCreate?: Prisma.TaskCreateOrConnectWithoutUserInput | Prisma.TaskCreateOrConnectWithoutUserInput[] @@ -514,6 +884,13 @@ export type TaskUncheckedCreateNestedManyWithoutUserInput = { connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] } +export type TaskUncheckedCreateNestedManyWithoutReporterInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutReporterInput[] | Prisma.TaskUncheckedCreateWithoutReporterInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutReporterInput | Prisma.TaskCreateOrConnectWithoutReporterInput[] + createMany?: Prisma.TaskCreateManyReporterInputEnvelope + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] +} + export type TaskUpdateManyWithoutUserNestedInput = { create?: Prisma.XOR | Prisma.TaskCreateWithoutUserInput[] | Prisma.TaskUncheckedCreateWithoutUserInput[] connectOrCreate?: Prisma.TaskCreateOrConnectWithoutUserInput | Prisma.TaskCreateOrConnectWithoutUserInput[] @@ -528,6 +905,20 @@ export type TaskUpdateManyWithoutUserNestedInput = { deleteMany?: Prisma.TaskScalarWhereInput | Prisma.TaskScalarWhereInput[] } +export type TaskUpdateManyWithoutReporterNestedInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutReporterInput[] | Prisma.TaskUncheckedCreateWithoutReporterInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutReporterInput | Prisma.TaskCreateOrConnectWithoutReporterInput[] + upsert?: Prisma.TaskUpsertWithWhereUniqueWithoutReporterInput | Prisma.TaskUpsertWithWhereUniqueWithoutReporterInput[] + createMany?: Prisma.TaskCreateManyReporterInputEnvelope + set?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + disconnect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + delete?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + update?: Prisma.TaskUpdateWithWhereUniqueWithoutReporterInput | Prisma.TaskUpdateWithWhereUniqueWithoutReporterInput[] + updateMany?: Prisma.TaskUpdateManyWithWhereWithoutReporterInput | Prisma.TaskUpdateManyWithWhereWithoutReporterInput[] + deleteMany?: Prisma.TaskScalarWhereInput | Prisma.TaskScalarWhereInput[] +} + export type TaskUncheckedUpdateManyWithoutUserNestedInput = { create?: Prisma.XOR | Prisma.TaskCreateWithoutUserInput[] | Prisma.TaskUncheckedCreateWithoutUserInput[] connectOrCreate?: Prisma.TaskCreateOrConnectWithoutUserInput | Prisma.TaskCreateOrConnectWithoutUserInput[] @@ -542,6 +933,20 @@ export type TaskUncheckedUpdateManyWithoutUserNestedInput = { deleteMany?: Prisma.TaskScalarWhereInput | Prisma.TaskScalarWhereInput[] } +export type TaskUncheckedUpdateManyWithoutReporterNestedInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutReporterInput[] | Prisma.TaskUncheckedCreateWithoutReporterInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutReporterInput | Prisma.TaskCreateOrConnectWithoutReporterInput[] + upsert?: Prisma.TaskUpsertWithWhereUniqueWithoutReporterInput | Prisma.TaskUpsertWithWhereUniqueWithoutReporterInput[] + createMany?: Prisma.TaskCreateManyReporterInputEnvelope + set?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + disconnect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + delete?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + update?: Prisma.TaskUpdateWithWhereUniqueWithoutReporterInput | Prisma.TaskUpdateWithWhereUniqueWithoutReporterInput[] + updateMany?: Prisma.TaskUpdateManyWithWhereWithoutReporterInput | Prisma.TaskUpdateManyWithWhereWithoutReporterInput[] + deleteMany?: Prisma.TaskScalarWhereInput | Prisma.TaskScalarWhereInput[] +} + export type TaskCreateNestedManyWithoutStageInput = { create?: Prisma.XOR | Prisma.TaskCreateWithoutStageInput[] | Prisma.TaskUncheckedCreateWithoutStageInput[] connectOrCreate?: Prisma.TaskCreateOrConnectWithoutStageInput | Prisma.TaskCreateOrConnectWithoutStageInput[] @@ -626,6 +1031,81 @@ export type TaskUncheckedUpdateManyWithoutProjectNestedInput = { deleteMany?: Prisma.TaskScalarWhereInput | Prisma.TaskScalarWhereInput[] } +export type TaskCreatetagsInput = { + set: string[] +} + +export type TaskCreateNestedOneWithoutSubtasksInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutSubtasksInput + connect?: Prisma.TaskWhereUniqueInput +} + +export type TaskCreateNestedManyWithoutParentTaskInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutParentTaskInput[] | Prisma.TaskUncheckedCreateWithoutParentTaskInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutParentTaskInput | Prisma.TaskCreateOrConnectWithoutParentTaskInput[] + createMany?: Prisma.TaskCreateManyParentTaskInputEnvelope + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] +} + +export type TaskUncheckedCreateNestedManyWithoutParentTaskInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutParentTaskInput[] | Prisma.TaskUncheckedCreateWithoutParentTaskInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutParentTaskInput | Prisma.TaskCreateOrConnectWithoutParentTaskInput[] + createMany?: Prisma.TaskCreateManyParentTaskInputEnvelope + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] +} + +export type EnumTaskTypeFieldUpdateOperationsInput = { + set?: $Enums.TaskType +} + +export type EnumTaskPriorityFieldUpdateOperationsInput = { + set?: $Enums.TaskPriority +} + +export type TaskUpdatetagsInput = { + set?: string[] + push?: string | string[] +} + +export type TaskUpdateOneWithoutSubtasksNestedInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutSubtasksInput + upsert?: Prisma.TaskUpsertWithoutSubtasksInput + disconnect?: Prisma.TaskWhereInput | boolean + delete?: Prisma.TaskWhereInput | boolean + connect?: Prisma.TaskWhereUniqueInput + update?: Prisma.XOR, Prisma.TaskUncheckedUpdateWithoutSubtasksInput> +} + +export type TaskUpdateManyWithoutParentTaskNestedInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutParentTaskInput[] | Prisma.TaskUncheckedCreateWithoutParentTaskInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutParentTaskInput | Prisma.TaskCreateOrConnectWithoutParentTaskInput[] + upsert?: Prisma.TaskUpsertWithWhereUniqueWithoutParentTaskInput | Prisma.TaskUpsertWithWhereUniqueWithoutParentTaskInput[] + createMany?: Prisma.TaskCreateManyParentTaskInputEnvelope + set?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + disconnect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + delete?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + update?: Prisma.TaskUpdateWithWhereUniqueWithoutParentTaskInput | Prisma.TaskUpdateWithWhereUniqueWithoutParentTaskInput[] + updateMany?: Prisma.TaskUpdateManyWithWhereWithoutParentTaskInput | Prisma.TaskUpdateManyWithWhereWithoutParentTaskInput[] + deleteMany?: Prisma.TaskScalarWhereInput | Prisma.TaskScalarWhereInput[] +} + +export type TaskUncheckedUpdateManyWithoutParentTaskNestedInput = { + create?: Prisma.XOR | Prisma.TaskCreateWithoutParentTaskInput[] | Prisma.TaskUncheckedCreateWithoutParentTaskInput[] + connectOrCreate?: Prisma.TaskCreateOrConnectWithoutParentTaskInput | Prisma.TaskCreateOrConnectWithoutParentTaskInput[] + upsert?: Prisma.TaskUpsertWithWhereUniqueWithoutParentTaskInput | Prisma.TaskUpsertWithWhereUniqueWithoutParentTaskInput[] + createMany?: Prisma.TaskCreateManyParentTaskInputEnvelope + set?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + disconnect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + delete?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + connect?: Prisma.TaskWhereUniqueInput | Prisma.TaskWhereUniqueInput[] + update?: Prisma.TaskUpdateWithWhereUniqueWithoutParentTaskInput | Prisma.TaskUpdateWithWhereUniqueWithoutParentTaskInput[] + updateMany?: Prisma.TaskUpdateManyWithWhereWithoutParentTaskInput | Prisma.TaskUpdateManyWithWhereWithoutParentTaskInput[] + deleteMany?: Prisma.TaskScalarWhereInput | Prisma.TaskScalarWhereInput[] +} + export type TaskCreateNestedOneWithoutTimesheetsInput = { create?: Prisma.XOR connectOrCreate?: Prisma.TaskCreateOrConnectWithoutTimesheetsInput @@ -677,6 +1157,20 @@ export type TaskUpdateOneWithoutAttachmentsNestedInput = { export type TaskCreateWithoutUserInput = { title: string description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -685,6 +1179,9 @@ export type TaskCreateWithoutUserInput = { comments?: Prisma.CommentCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput } export type TaskUncheckedCreateWithoutUserInput = { @@ -693,12 +1190,29 @@ export type TaskUncheckedCreateWithoutUserInput = { description?: string | null projectId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput } export type TaskCreateOrConnectWithoutUserInput = { @@ -711,6 +1225,77 @@ export type TaskCreateManyUserInputEnvelope = { skipDuplicates?: boolean } +export type TaskCreateWithoutReporterInput = { + title: string + description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string + user: Prisma.UserCreateNestedOneWithoutTasksInput + project: Prisma.ProjectCreateNestedOneWithoutTasksInput + stage?: Prisma.TaskStageCreateNestedOneWithoutTasksInput + comments?: Prisma.CommentCreateNestedManyWithoutTaskInput + attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput + timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput +} + +export type TaskUncheckedCreateWithoutReporterInput = { + id?: number + title: string + description?: string | null + userId: number + projectId: number + stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string + comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput + attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput + timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput +} + +export type TaskCreateOrConnectWithoutReporterInput = { + where: Prisma.TaskWhereUniqueInput + create: Prisma.XOR +} + +export type TaskCreateManyReporterInputEnvelope = { + data: Prisma.TaskCreateManyReporterInput | Prisma.TaskCreateManyReporterInput[] + skipDuplicates?: boolean +} + export type TaskUpsertWithWhereUniqueWithoutUserInput = { where: Prisma.TaskWhereUniqueInput update: Prisma.XOR @@ -737,14 +1322,60 @@ export type TaskScalarWhereInput = { userId?: Prisma.IntFilter<"Task"> | number projectId?: Prisma.IntFilter<"Task"> | number stageId?: Prisma.IntNullableFilter<"Task"> | number | null + parentTaskId?: Prisma.IntNullableFilter<"Task"> | number | null + type?: Prisma.EnumTaskTypeFilter<"Task"> | $Enums.TaskType + reporterId?: Prisma.IntNullableFilter<"Task"> | number | null + watchers?: Prisma.JsonNullableFilter<"Task"> + startDate?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + dueDate?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + completedAt?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null + estimatedHours?: Prisma.FloatFilter<"Task"> | number + remainingHours?: Prisma.FloatFilter<"Task"> | number + progress?: Prisma.FloatFilter<"Task"> | number + priority?: Prisma.EnumTaskPriorityFilter<"Task"> | $Enums.TaskPriority + tags?: Prisma.StringNullableListFilter<"Task"> + checklist?: Prisma.JsonNullableFilter<"Task"> + dependencies?: Prisma.JsonNullableFilter<"Task"> + customFields?: Prisma.JsonNullableFilter<"Task"> + deletedAt?: Prisma.DateTimeNullableFilter<"Task"> | Date | string | null sequence?: Prisma.IntFilter<"Task"> | number createdAt?: Prisma.DateTimeFilter<"Task"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Task"> | Date | string } +export type TaskUpsertWithWhereUniqueWithoutReporterInput = { + where: Prisma.TaskWhereUniqueInput + update: Prisma.XOR + create: Prisma.XOR +} + +export type TaskUpdateWithWhereUniqueWithoutReporterInput = { + where: Prisma.TaskWhereUniqueInput + data: Prisma.XOR +} + +export type TaskUpdateManyWithWhereWithoutReporterInput = { + where: Prisma.TaskScalarWhereInput + data: Prisma.XOR +} + export type TaskCreateWithoutStageInput = { title: string description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -753,6 +1384,9 @@ export type TaskCreateWithoutStageInput = { comments?: Prisma.CommentCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput } export type TaskUncheckedCreateWithoutStageInput = { @@ -761,12 +1395,29 @@ export type TaskUncheckedCreateWithoutStageInput = { description?: string | null userId: number projectId: number + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput } export type TaskCreateOrConnectWithoutStageInput = { @@ -798,6 +1449,20 @@ export type TaskUpdateManyWithWhereWithoutStageInput = { export type TaskCreateWithoutProjectInput = { title: string description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -806,6 +1471,9 @@ export type TaskCreateWithoutProjectInput = { comments?: Prisma.CommentCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput } export type TaskUncheckedCreateWithoutProjectInput = { @@ -814,12 +1482,29 @@ export type TaskUncheckedCreateWithoutProjectInput = { description?: string | null userId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput } export type TaskCreateOrConnectWithoutProjectInput = { @@ -848,9 +1533,248 @@ export type TaskUpdateManyWithWhereWithoutProjectInput = { data: Prisma.XOR } +export type TaskCreateWithoutSubtasksInput = { + title: string + description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string + user: Prisma.UserCreateNestedOneWithoutTasksInput + project: Prisma.ProjectCreateNestedOneWithoutTasksInput + stage?: Prisma.TaskStageCreateNestedOneWithoutTasksInput + comments?: Prisma.CommentCreateNestedManyWithoutTaskInput + attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput + timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput +} + +export type TaskUncheckedCreateWithoutSubtasksInput = { + id?: number + title: string + description?: string | null + userId: number + projectId: number + stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string + comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput + attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput + timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput +} + +export type TaskCreateOrConnectWithoutSubtasksInput = { + where: Prisma.TaskWhereUniqueInput + create: Prisma.XOR +} + +export type TaskCreateWithoutParentTaskInput = { + title: string + description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string + user: Prisma.UserCreateNestedOneWithoutTasksInput + project: Prisma.ProjectCreateNestedOneWithoutTasksInput + stage?: Prisma.TaskStageCreateNestedOneWithoutTasksInput + comments?: Prisma.CommentCreateNestedManyWithoutTaskInput + attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput + timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput +} + +export type TaskUncheckedCreateWithoutParentTaskInput = { + id?: number + title: string + description?: string | null + userId: number + projectId: number + stageId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string + comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput + attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput + timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput +} + +export type TaskCreateOrConnectWithoutParentTaskInput = { + where: Prisma.TaskWhereUniqueInput + create: Prisma.XOR +} + +export type TaskCreateManyParentTaskInputEnvelope = { + data: Prisma.TaskCreateManyParentTaskInput | Prisma.TaskCreateManyParentTaskInput[] + skipDuplicates?: boolean +} + +export type TaskUpsertWithoutSubtasksInput = { + update: Prisma.XOR + create: Prisma.XOR + where?: Prisma.TaskWhereInput +} + +export type TaskUpdateToOneWithWhereWithoutSubtasksInput = { + where?: Prisma.TaskWhereInput + data: Prisma.XOR +} + +export type TaskUpdateWithoutSubtasksInput = { + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + user?: Prisma.UserUpdateOneRequiredWithoutTasksNestedInput + project?: Prisma.ProjectUpdateOneRequiredWithoutTasksNestedInput + stage?: Prisma.TaskStageUpdateOneWithoutTasksNestedInput + comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput + attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput + timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput +} + +export type TaskUncheckedUpdateWithoutSubtasksInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + userId?: Prisma.IntFieldUpdateOperationsInput | number + projectId?: Prisma.IntFieldUpdateOperationsInput | number + stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput + attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput + timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput +} + +export type TaskUpsertWithWhereUniqueWithoutParentTaskInput = { + where: Prisma.TaskWhereUniqueInput + update: Prisma.XOR + create: Prisma.XOR +} + +export type TaskUpdateWithWhereUniqueWithoutParentTaskInput = { + where: Prisma.TaskWhereUniqueInput + data: Prisma.XOR +} + +export type TaskUpdateManyWithWhereWithoutParentTaskInput = { + where: Prisma.TaskScalarWhereInput + data: Prisma.XOR +} + export type TaskCreateWithoutTimesheetsInput = { title: string description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -859,6 +1783,9 @@ export type TaskCreateWithoutTimesheetsInput = { stage?: Prisma.TaskStageCreateNestedOneWithoutTasksInput comments?: Prisma.CommentCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput } export type TaskUncheckedCreateWithoutTimesheetsInput = { @@ -868,11 +1795,28 @@ export type TaskUncheckedCreateWithoutTimesheetsInput = { userId: number projectId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput } export type TaskCreateOrConnectWithoutTimesheetsInput = { @@ -894,6 +1838,20 @@ export type TaskUpdateToOneWithWhereWithoutTimesheetsInput = { export type TaskUpdateWithoutTimesheetsInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -902,6 +1860,9 @@ export type TaskUpdateWithoutTimesheetsInput = { stage?: Prisma.TaskStageUpdateOneWithoutTasksNestedInput comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput } export type TaskUncheckedUpdateWithoutTimesheetsInput = { @@ -911,16 +1872,47 @@ export type TaskUncheckedUpdateWithoutTimesheetsInput = { userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput } export type TaskCreateWithoutCommentsInput = { title: string description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -929,6 +1921,9 @@ export type TaskCreateWithoutCommentsInput = { stage?: Prisma.TaskStageCreateNestedOneWithoutTasksInput attachments?: Prisma.AttachmentCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput } export type TaskUncheckedCreateWithoutCommentsInput = { @@ -938,11 +1933,28 @@ export type TaskUncheckedCreateWithoutCommentsInput = { userId: number projectId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string attachments?: Prisma.AttachmentUncheckedCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput } export type TaskCreateOrConnectWithoutCommentsInput = { @@ -964,6 +1976,20 @@ export type TaskUpdateToOneWithWhereWithoutCommentsInput = { export type TaskUpdateWithoutCommentsInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -972,6 +1998,9 @@ export type TaskUpdateWithoutCommentsInput = { stage?: Prisma.TaskStageUpdateOneWithoutTasksNestedInput attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput } export type TaskUncheckedUpdateWithoutCommentsInput = { @@ -981,16 +2010,47 @@ export type TaskUncheckedUpdateWithoutCommentsInput = { userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput } export type TaskCreateWithoutAttachmentsInput = { title: string description?: string | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -999,6 +2059,9 @@ export type TaskCreateWithoutAttachmentsInput = { stage?: Prisma.TaskStageCreateNestedOneWithoutTasksInput comments?: Prisma.CommentCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetCreateNestedManyWithoutTaskInput + parentTask?: Prisma.TaskCreateNestedOneWithoutSubtasksInput + subtasks?: Prisma.TaskCreateNestedManyWithoutParentTaskInput + reporter?: Prisma.UserCreateNestedOneWithoutReportedTasksInput } export type TaskUncheckedCreateWithoutAttachmentsInput = { @@ -1008,11 +2071,28 @@ export type TaskUncheckedCreateWithoutAttachmentsInput = { userId: number projectId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string comments?: Prisma.CommentUncheckedCreateNestedManyWithoutTaskInput timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutTaskInput + subtasks?: Prisma.TaskUncheckedCreateNestedManyWithoutParentTaskInput } export type TaskCreateOrConnectWithoutAttachmentsInput = { @@ -1034,6 +2114,20 @@ export type TaskUpdateToOneWithWhereWithoutAttachmentsInput = { export type TaskUpdateWithoutAttachmentsInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -1042,6 +2136,9 @@ export type TaskUpdateWithoutAttachmentsInput = { stage?: Prisma.TaskStageUpdateOneWithoutTasksNestedInput comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput } export type TaskUncheckedUpdateWithoutAttachmentsInput = { @@ -1051,11 +2148,28 @@ export type TaskUncheckedUpdateWithoutAttachmentsInput = { userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput } export type TaskCreateManyUserInput = { @@ -1064,6 +2178,49 @@ export type TaskCreateManyUserInput = { description?: string | null projectId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string +} + +export type TaskCreateManyReporterInput = { + id?: number + title: string + description?: string | null + userId: number + projectId: number + stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -1072,6 +2229,20 @@ export type TaskCreateManyUserInput = { export type TaskUpdateWithoutUserInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -1080,6 +2251,9 @@ export type TaskUpdateWithoutUserInput = { comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput } export type TaskUncheckedUpdateWithoutUserInput = { @@ -1088,12 +2262,29 @@ export type TaskUncheckedUpdateWithoutUserInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null projectId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput } export type TaskUncheckedUpdateManyWithoutUserInput = { @@ -1102,6 +2293,110 @@ export type TaskUncheckedUpdateManyWithoutUserInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null projectId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type TaskUpdateWithoutReporterInput = { + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + user?: Prisma.UserUpdateOneRequiredWithoutTasksNestedInput + project?: Prisma.ProjectUpdateOneRequiredWithoutTasksNestedInput + stage?: Prisma.TaskStageUpdateOneWithoutTasksNestedInput + comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput + attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput + timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput +} + +export type TaskUncheckedUpdateWithoutReporterInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + userId?: Prisma.IntFieldUpdateOperationsInput | number + projectId?: Prisma.IntFieldUpdateOperationsInput | number + stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput + attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput + timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput +} + +export type TaskUncheckedUpdateManyWithoutReporterInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + userId?: Prisma.IntFieldUpdateOperationsInput | number + projectId?: Prisma.IntFieldUpdateOperationsInput | number + stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -1113,6 +2408,22 @@ export type TaskCreateManyStageInput = { description?: string | null userId: number projectId: number + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -1121,6 +2432,20 @@ export type TaskCreateManyStageInput = { export type TaskUpdateWithoutStageInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -1129,6 +2454,9 @@ export type TaskUpdateWithoutStageInput = { comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput } export type TaskUncheckedUpdateWithoutStageInput = { @@ -1137,12 +2465,29 @@ export type TaskUncheckedUpdateWithoutStageInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput } export type TaskUncheckedUpdateManyWithoutStageInput = { @@ -1151,6 +2496,22 @@ export type TaskUncheckedUpdateManyWithoutStageInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -1162,6 +2523,22 @@ export type TaskCreateManyProjectInput = { description?: string | null userId: number stageId?: number | null + parentTaskId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null sequence?: number createdAt?: Date | string updatedAt?: Date | string @@ -1170,6 +2547,20 @@ export type TaskCreateManyProjectInput = { export type TaskUpdateWithoutProjectInput = { title?: Prisma.StringFieldUpdateOperationsInput | string description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -1178,6 +2569,9 @@ export type TaskUpdateWithoutProjectInput = { comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + parentTask?: Prisma.TaskUpdateOneWithoutSubtasksNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput } export type TaskUncheckedUpdateWithoutProjectInput = { @@ -1186,12 +2580,29 @@ export type TaskUncheckedUpdateWithoutProjectInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput } export type TaskUncheckedUpdateManyWithoutProjectInput = { @@ -1200,6 +2611,137 @@ export type TaskUncheckedUpdateManyWithoutProjectInput = { description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null userId?: Prisma.IntFieldUpdateOperationsInput | number stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + parentTaskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type TaskCreateManyParentTaskInput = { + id?: number + title: string + description?: string | null + userId: number + projectId: number + stageId?: number | null + type?: $Enums.TaskType + reporterId?: number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Date | string | null + dueDate?: Date | string | null + completedAt?: Date | string | null + estimatedHours?: number + remainingHours?: number + progress?: number + priority?: $Enums.TaskPriority + tags?: Prisma.TaskCreatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Date | string | null + sequence?: number + createdAt?: Date | string + updatedAt?: Date | string +} + +export type TaskUpdateWithoutParentTaskInput = { + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + user?: Prisma.UserUpdateOneRequiredWithoutTasksNestedInput + project?: Prisma.ProjectUpdateOneRequiredWithoutTasksNestedInput + stage?: Prisma.TaskStageUpdateOneWithoutTasksNestedInput + comments?: Prisma.CommentUpdateManyWithoutTaskNestedInput + attachments?: Prisma.AttachmentUpdateManyWithoutTaskNestedInput + timesheets?: Prisma.TimesheetUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUpdateManyWithoutParentTaskNestedInput + reporter?: Prisma.UserUpdateOneWithoutReportedTasksNestedInput +} + +export type TaskUncheckedUpdateWithoutParentTaskInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + userId?: Prisma.IntFieldUpdateOperationsInput | number + projectId?: Prisma.IntFieldUpdateOperationsInput | number + stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + sequence?: Prisma.IntFieldUpdateOperationsInput | number + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + comments?: Prisma.CommentUncheckedUpdateManyWithoutTaskNestedInput + attachments?: Prisma.AttachmentUncheckedUpdateManyWithoutTaskNestedInput + timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutTaskNestedInput + subtasks?: Prisma.TaskUncheckedUpdateManyWithoutParentTaskNestedInput +} + +export type TaskUncheckedUpdateManyWithoutParentTaskInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + title?: Prisma.StringFieldUpdateOperationsInput | string + description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + userId?: Prisma.IntFieldUpdateOperationsInput | number + projectId?: Prisma.IntFieldUpdateOperationsInput | number + stageId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + type?: Prisma.EnumTaskTypeFieldUpdateOperationsInput | $Enums.TaskType + reporterId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + watchers?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + startDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + dueDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + completedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + estimatedHours?: Prisma.FloatFieldUpdateOperationsInput | number + remainingHours?: Prisma.FloatFieldUpdateOperationsInput | number + progress?: Prisma.FloatFieldUpdateOperationsInput | number + priority?: Prisma.EnumTaskPriorityFieldUpdateOperationsInput | $Enums.TaskPriority + tags?: Prisma.TaskUpdatetagsInput | string[] + checklist?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + dependencies?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null sequence?: Prisma.IntFieldUpdateOperationsInput | number createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string @@ -1214,12 +2756,14 @@ export type TaskCountOutputType = { comments: number attachments: number timesheets: number + subtasks: number } export type TaskCountOutputTypeSelect = { comments?: boolean | TaskCountOutputTypeCountCommentsArgs attachments?: boolean | TaskCountOutputTypeCountAttachmentsArgs timesheets?: boolean | TaskCountOutputTypeCountTimesheetsArgs + subtasks?: boolean | TaskCountOutputTypeCountSubtasksArgs } /** @@ -1253,6 +2797,13 @@ export type TaskCountOutputTypeCountTimesheetsArgs = { + where?: Prisma.TaskWhereInput +} + export type TaskSelect = runtime.Types.Extensions.GetSelect<{ id?: boolean @@ -1261,6 +2812,22 @@ export type TaskSelect attachments?: boolean | Prisma.Task$attachmentsArgs timesheets?: boolean | Prisma.Task$timesheetsArgs + parentTask?: boolean | Prisma.Task$parentTaskArgs + subtasks?: boolean | Prisma.Task$subtasksArgs + reporter?: boolean | Prisma.Task$reporterArgs _count?: boolean | Prisma.TaskCountOutputTypeDefaultArgs }, ExtArgs["result"]["task"]> @@ -1280,12 +2850,30 @@ export type TaskSelectCreateManyAndReturn project?: boolean | Prisma.ProjectDefaultArgs stage?: boolean | Prisma.Task$stageArgs + parentTask?: boolean | Prisma.Task$parentTaskArgs + reporter?: boolean | Prisma.Task$reporterArgs }, ExtArgs["result"]["task"]> export type TaskSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ @@ -1295,12 +2883,30 @@ export type TaskSelectUpdateManyAndReturn project?: boolean | Prisma.ProjectDefaultArgs stage?: boolean | Prisma.Task$stageArgs + parentTask?: boolean | Prisma.Task$parentTaskArgs + reporter?: boolean | Prisma.Task$reporterArgs }, ExtArgs["result"]["task"]> export type TaskSelectScalar = { @@ -1310,12 +2916,28 @@ export type TaskSelectScalar = { userId?: boolean projectId?: boolean stageId?: boolean + parentTaskId?: boolean + type?: boolean + reporterId?: boolean + watchers?: boolean + startDate?: boolean + dueDate?: boolean + completedAt?: boolean + estimatedHours?: boolean + remainingHours?: boolean + progress?: boolean + priority?: boolean + tags?: boolean + checklist?: boolean + dependencies?: boolean + customFields?: boolean + deletedAt?: boolean sequence?: boolean createdAt?: boolean updatedAt?: boolean } -export type TaskOmit = runtime.Types.Extensions.GetOmit<"id" | "title" | "description" | "userId" | "projectId" | "stageId" | "sequence" | "createdAt" | "updatedAt", ExtArgs["result"]["task"]> +export type TaskOmit = runtime.Types.Extensions.GetOmit<"id" | "title" | "description" | "userId" | "projectId" | "stageId" | "parentTaskId" | "type" | "reporterId" | "watchers" | "startDate" | "dueDate" | "completedAt" | "estimatedHours" | "remainingHours" | "progress" | "priority" | "tags" | "checklist" | "dependencies" | "customFields" | "deletedAt" | "sequence" | "createdAt" | "updatedAt", ExtArgs["result"]["task"]> export type TaskInclude = { user?: boolean | Prisma.UserDefaultArgs project?: boolean | Prisma.ProjectDefaultArgs @@ -1323,17 +2945,24 @@ export type TaskInclude attachments?: boolean | Prisma.Task$attachmentsArgs timesheets?: boolean | Prisma.Task$timesheetsArgs + parentTask?: boolean | Prisma.Task$parentTaskArgs + subtasks?: boolean | Prisma.Task$subtasksArgs + reporter?: boolean | Prisma.Task$reporterArgs _count?: boolean | Prisma.TaskCountOutputTypeDefaultArgs } export type TaskIncludeCreateManyAndReturn = { user?: boolean | Prisma.UserDefaultArgs project?: boolean | Prisma.ProjectDefaultArgs stage?: boolean | Prisma.Task$stageArgs + parentTask?: boolean | Prisma.Task$parentTaskArgs + reporter?: boolean | Prisma.Task$reporterArgs } export type TaskIncludeUpdateManyAndReturn = { user?: boolean | Prisma.UserDefaultArgs project?: boolean | Prisma.ProjectDefaultArgs stage?: boolean | Prisma.Task$stageArgs + parentTask?: boolean | Prisma.Task$parentTaskArgs + reporter?: boolean | Prisma.Task$reporterArgs } export type $TaskPayload = { @@ -1345,6 +2974,9 @@ export type $TaskPayload[] attachments: Prisma.$AttachmentPayload[] timesheets: Prisma.$TimesheetPayload[] + parentTask: Prisma.$TaskPayload | null + subtasks: Prisma.$TaskPayload[] + reporter: Prisma.$UserPayload | null } scalars: runtime.Types.Extensions.GetPayloadResult<{ id: number @@ -1353,6 +2985,22 @@ export type $TaskPayload = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> attachments = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> timesheets = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + parentTask = {}>(args?: Prisma.Subset>): Prisma.Prisma__TaskClient, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + subtasks = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + reporter = {}>(args?: Prisma.Subset>): Prisma.Prisma__UserClient, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. @@ -1791,6 +3442,22 @@ export interface TaskFieldRefs { readonly userId: Prisma.FieldRef<"Task", 'Int'> readonly projectId: Prisma.FieldRef<"Task", 'Int'> readonly stageId: Prisma.FieldRef<"Task", 'Int'> + readonly parentTaskId: Prisma.FieldRef<"Task", 'Int'> + readonly type: Prisma.FieldRef<"Task", 'TaskType'> + readonly reporterId: Prisma.FieldRef<"Task", 'Int'> + readonly watchers: Prisma.FieldRef<"Task", 'Json'> + readonly startDate: Prisma.FieldRef<"Task", 'DateTime'> + readonly dueDate: Prisma.FieldRef<"Task", 'DateTime'> + readonly completedAt: Prisma.FieldRef<"Task", 'DateTime'> + readonly estimatedHours: Prisma.FieldRef<"Task", 'Float'> + readonly remainingHours: Prisma.FieldRef<"Task", 'Float'> + readonly progress: Prisma.FieldRef<"Task", 'Float'> + readonly priority: Prisma.FieldRef<"Task", 'TaskPriority'> + readonly tags: Prisma.FieldRef<"Task", 'String[]'> + readonly checklist: Prisma.FieldRef<"Task", 'Json'> + readonly dependencies: Prisma.FieldRef<"Task", 'Json'> + readonly customFields: Prisma.FieldRef<"Task", 'Json'> + readonly deletedAt: Prisma.FieldRef<"Task", 'DateTime'> readonly sequence: Prisma.FieldRef<"Task", 'Int'> readonly createdAt: Prisma.FieldRef<"Task", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"Task", 'DateTime'> @@ -2280,6 +3947,68 @@ export type Task$timesheetsArgs = { + /** + * Select specific fields to fetch from the Task + */ + select?: Prisma.TaskSelect | null + /** + * Omit specific fields from the Task + */ + omit?: Prisma.TaskOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.TaskInclude | null + where?: Prisma.TaskWhereInput +} + +/** + * Task.subtasks + */ +export type Task$subtasksArgs = { + /** + * Select specific fields to fetch from the Task + */ + select?: Prisma.TaskSelect | null + /** + * Omit specific fields from the Task + */ + omit?: Prisma.TaskOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.TaskInclude | null + where?: Prisma.TaskWhereInput + orderBy?: Prisma.TaskOrderByWithRelationInput | Prisma.TaskOrderByWithRelationInput[] + cursor?: Prisma.TaskWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.TaskScalarFieldEnum | Prisma.TaskScalarFieldEnum[] +} + +/** + * Task.reporter + */ +export type Task$reporterArgs = { + /** + * Select specific fields to fetch from the User + */ + select?: Prisma.UserSelect | null + /** + * Omit specific fields from the User + */ + omit?: Prisma.UserOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.UserInclude | null + where?: Prisma.UserWhereInput +} + /** * Task without action */ diff --git a/backend/prisma/generated/models/Timesheet.ts b/backend/prisma/generated/models/Timesheet.ts index 4994ad1..7b54fdf 100644 --- a/backend/prisma/generated/models/Timesheet.ts +++ b/backend/prisma/generated/models/Timesheet.ts @@ -32,6 +32,9 @@ export type TimesheetAvgAggregateOutputType = { userId: number | null projectId: number | null taskId: number | null + hourlyRate: runtime.Decimal | null + cost: runtime.Decimal | null + approvedById: number | null } export type TimesheetSumAggregateOutputType = { @@ -40,6 +43,9 @@ export type TimesheetSumAggregateOutputType = { userId: number | null projectId: number | null taskId: number | null + hourlyRate: runtime.Decimal | null + cost: runtime.Decimal | null + approvedById: number | null } export type TimesheetMinAggregateOutputType = { @@ -50,8 +56,18 @@ export type TimesheetMinAggregateOutputType = { userId: number | null projectId: number | null taskId: number | null + startTime: Date | null + endTime: Date | null + billable: boolean | null + hourlyRate: runtime.Decimal | null + cost: runtime.Decimal | null + source: $Enums.TimesheetSource | null + approvalStatus: $Enums.ApprovalStatus | null + approvedById: number | null + approvedAt: Date | null createdAt: Date | null updatedAt: Date | null + deletedAt: Date | null } export type TimesheetMaxAggregateOutputType = { @@ -62,8 +78,18 @@ export type TimesheetMaxAggregateOutputType = { userId: number | null projectId: number | null taskId: number | null + startTime: Date | null + endTime: Date | null + billable: boolean | null + hourlyRate: runtime.Decimal | null + cost: runtime.Decimal | null + source: $Enums.TimesheetSource | null + approvalStatus: $Enums.ApprovalStatus | null + approvedById: number | null + approvedAt: Date | null createdAt: Date | null updatedAt: Date | null + deletedAt: Date | null } export type TimesheetCountAggregateOutputType = { @@ -74,8 +100,20 @@ export type TimesheetCountAggregateOutputType = { userId: number projectId: number taskId: number + startTime: number + endTime: number + billable: number + hourlyRate: number + cost: number + source: number + approvalStatus: number + approvedById: number + approvedAt: number + tags: number + customFields: number createdAt: number updatedAt: number + deletedAt: number _all: number } @@ -86,6 +124,9 @@ export type TimesheetAvgAggregateInputType = { userId?: true projectId?: true taskId?: true + hourlyRate?: true + cost?: true + approvedById?: true } export type TimesheetSumAggregateInputType = { @@ -94,6 +135,9 @@ export type TimesheetSumAggregateInputType = { userId?: true projectId?: true taskId?: true + hourlyRate?: true + cost?: true + approvedById?: true } export type TimesheetMinAggregateInputType = { @@ -104,8 +148,18 @@ export type TimesheetMinAggregateInputType = { userId?: true projectId?: true taskId?: true + startTime?: true + endTime?: true + billable?: true + hourlyRate?: true + cost?: true + source?: true + approvalStatus?: true + approvedById?: true + approvedAt?: true createdAt?: true updatedAt?: true + deletedAt?: true } export type TimesheetMaxAggregateInputType = { @@ -116,8 +170,18 @@ export type TimesheetMaxAggregateInputType = { userId?: true projectId?: true taskId?: true + startTime?: true + endTime?: true + billable?: true + hourlyRate?: true + cost?: true + source?: true + approvalStatus?: true + approvedById?: true + approvedAt?: true createdAt?: true updatedAt?: true + deletedAt?: true } export type TimesheetCountAggregateInputType = { @@ -128,8 +192,20 @@ export type TimesheetCountAggregateInputType = { userId?: true projectId?: true taskId?: true + startTime?: true + endTime?: true + billable?: true + hourlyRate?: true + cost?: true + source?: true + approvalStatus?: true + approvedById?: true + approvedAt?: true + tags?: true + customFields?: true createdAt?: true updatedAt?: true + deletedAt?: true _all?: true } @@ -227,8 +303,20 @@ export type TimesheetGroupByOutputType = { userId: number projectId: number taskId: number | null + startTime: Date | null + endTime: Date | null + billable: boolean + hourlyRate: runtime.Decimal | null + cost: runtime.Decimal | null + source: $Enums.TimesheetSource + approvalStatus: $Enums.ApprovalStatus + approvedById: number | null + approvedAt: Date | null + tags: string[] + customFields: runtime.JsonValue | null createdAt: Date updatedAt: Date + deletedAt: Date | null _count: TimesheetCountAggregateOutputType | null _avg: TimesheetAvgAggregateOutputType | null _sum: TimesheetSumAggregateOutputType | null @@ -262,11 +350,24 @@ export type TimesheetWhereInput = { userId?: Prisma.IntFilter<"Timesheet"> | number projectId?: Prisma.IntFilter<"Timesheet"> | number taskId?: Prisma.IntNullableFilter<"Timesheet"> | number | null + startTime?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + endTime?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + billable?: Prisma.BoolFilter<"Timesheet"> | boolean + hourlyRate?: Prisma.DecimalNullableFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.DecimalNullableFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFilter<"Timesheet"> | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFilter<"Timesheet"> | $Enums.ApprovalStatus + approvedById?: Prisma.IntNullableFilter<"Timesheet"> | number | null + approvedAt?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + tags?: Prisma.StringNullableListFilter<"Timesheet"> + customFields?: Prisma.JsonNullableFilter<"Timesheet"> createdAt?: Prisma.DateTimeFilter<"Timesheet"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Timesheet"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null project?: Prisma.XOR user?: Prisma.XOR task?: Prisma.XOR | null + approvedBy?: Prisma.XOR | null } export type TimesheetOrderByWithRelationInput = { @@ -277,11 +378,24 @@ export type TimesheetOrderByWithRelationInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrderInput | Prisma.SortOrder + startTime?: Prisma.SortOrderInput | Prisma.SortOrder + endTime?: Prisma.SortOrderInput | Prisma.SortOrder + billable?: Prisma.SortOrder + hourlyRate?: Prisma.SortOrderInput | Prisma.SortOrder + cost?: Prisma.SortOrderInput | Prisma.SortOrder + source?: Prisma.SortOrder + approvalStatus?: Prisma.SortOrder + approvedById?: Prisma.SortOrderInput | Prisma.SortOrder + approvedAt?: Prisma.SortOrderInput | Prisma.SortOrder + tags?: Prisma.SortOrder + customFields?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder project?: Prisma.ProjectOrderByWithRelationInput user?: Prisma.UserOrderByWithRelationInput task?: Prisma.TaskOrderByWithRelationInput + approvedBy?: Prisma.UserOrderByWithRelationInput } export type TimesheetWhereUniqueInput = Prisma.AtLeast<{ @@ -295,11 +409,24 @@ export type TimesheetWhereUniqueInput = Prisma.AtLeast<{ userId?: Prisma.IntFilter<"Timesheet"> | number projectId?: Prisma.IntFilter<"Timesheet"> | number taskId?: Prisma.IntNullableFilter<"Timesheet"> | number | null + startTime?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + endTime?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + billable?: Prisma.BoolFilter<"Timesheet"> | boolean + hourlyRate?: Prisma.DecimalNullableFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.DecimalNullableFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFilter<"Timesheet"> | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFilter<"Timesheet"> | $Enums.ApprovalStatus + approvedById?: Prisma.IntNullableFilter<"Timesheet"> | number | null + approvedAt?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + tags?: Prisma.StringNullableListFilter<"Timesheet"> + customFields?: Prisma.JsonNullableFilter<"Timesheet"> createdAt?: Prisma.DateTimeFilter<"Timesheet"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Timesheet"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null project?: Prisma.XOR user?: Prisma.XOR task?: Prisma.XOR | null + approvedBy?: Prisma.XOR | null }, "id"> export type TimesheetOrderByWithAggregationInput = { @@ -310,8 +437,20 @@ export type TimesheetOrderByWithAggregationInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrderInput | Prisma.SortOrder + startTime?: Prisma.SortOrderInput | Prisma.SortOrder + endTime?: Prisma.SortOrderInput | Prisma.SortOrder + billable?: Prisma.SortOrder + hourlyRate?: Prisma.SortOrderInput | Prisma.SortOrder + cost?: Prisma.SortOrderInput | Prisma.SortOrder + source?: Prisma.SortOrder + approvalStatus?: Prisma.SortOrder + approvedById?: Prisma.SortOrderInput | Prisma.SortOrder + approvedAt?: Prisma.SortOrderInput | Prisma.SortOrder + tags?: Prisma.SortOrder + customFields?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder _count?: Prisma.TimesheetCountOrderByAggregateInput _avg?: Prisma.TimesheetAvgOrderByAggregateInput _max?: Prisma.TimesheetMaxOrderByAggregateInput @@ -330,19 +469,43 @@ export type TimesheetScalarWhereWithAggregatesInput = { userId?: Prisma.IntWithAggregatesFilter<"Timesheet"> | number projectId?: Prisma.IntWithAggregatesFilter<"Timesheet"> | number taskId?: Prisma.IntNullableWithAggregatesFilter<"Timesheet"> | number | null + startTime?: Prisma.DateTimeNullableWithAggregatesFilter<"Timesheet"> | Date | string | null + endTime?: Prisma.DateTimeNullableWithAggregatesFilter<"Timesheet"> | Date | string | null + billable?: Prisma.BoolWithAggregatesFilter<"Timesheet"> | boolean + hourlyRate?: Prisma.DecimalNullableWithAggregatesFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.DecimalNullableWithAggregatesFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceWithAggregatesFilter<"Timesheet"> | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusWithAggregatesFilter<"Timesheet"> | $Enums.ApprovalStatus + approvedById?: Prisma.IntNullableWithAggregatesFilter<"Timesheet"> | number | null + approvedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"Timesheet"> | Date | string | null + tags?: Prisma.StringNullableListFilter<"Timesheet"> + customFields?: Prisma.JsonNullableWithAggregatesFilter<"Timesheet"> createdAt?: Prisma.DateTimeWithAggregatesFilter<"Timesheet"> | Date | string updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Timesheet"> | Date | string + deletedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"Timesheet"> | Date | string | null } export type TimesheetCreateInput = { description: string date: Date | string timeSpent: number + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null project: Prisma.ProjectCreateNestedOneWithoutTimesheetsInput user: Prisma.UserCreateNestedOneWithoutTimesheetsInput task?: Prisma.TaskCreateNestedOneWithoutTimesheetsInput + approvedBy?: Prisma.UserCreateNestedOneWithoutApprovedTimesheetsInput } export type TimesheetUncheckedCreateInput = { @@ -353,19 +516,43 @@ export type TimesheetUncheckedCreateInput = { userId: number projectId: number taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetUpdateInput = { description?: Prisma.StringFieldUpdateOperationsInput | string date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null project?: Prisma.ProjectUpdateOneRequiredWithoutTimesheetsNestedInput user?: Prisma.UserUpdateOneRequiredWithoutTimesheetsNestedInput task?: Prisma.TaskUpdateOneWithoutTimesheetsNestedInput + approvedBy?: Prisma.UserUpdateOneWithoutApprovedTimesheetsNestedInput } export type TimesheetUncheckedUpdateInput = { @@ -376,8 +563,20 @@ export type TimesheetUncheckedUpdateInput = { userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetCreateManyInput = { @@ -388,16 +587,39 @@ export type TimesheetCreateManyInput = { userId: number projectId: number taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetUpdateManyMutationInput = { description?: Prisma.StringFieldUpdateOperationsInput | string date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetUncheckedUpdateManyInput = { @@ -408,8 +630,20 @@ export type TimesheetUncheckedUpdateManyInput = { userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetListRelationFilter = { @@ -430,8 +664,20 @@ export type TimesheetCountOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder + startTime?: Prisma.SortOrder + endTime?: Prisma.SortOrder + billable?: Prisma.SortOrder + hourlyRate?: Prisma.SortOrder + cost?: Prisma.SortOrder + source?: Prisma.SortOrder + approvalStatus?: Prisma.SortOrder + approvedById?: Prisma.SortOrder + approvedAt?: Prisma.SortOrder + tags?: Prisma.SortOrder + customFields?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder } export type TimesheetAvgOrderByAggregateInput = { @@ -440,6 +686,9 @@ export type TimesheetAvgOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder + hourlyRate?: Prisma.SortOrder + cost?: Prisma.SortOrder + approvedById?: Prisma.SortOrder } export type TimesheetMaxOrderByAggregateInput = { @@ -450,8 +699,18 @@ export type TimesheetMaxOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder + startTime?: Prisma.SortOrder + endTime?: Prisma.SortOrder + billable?: Prisma.SortOrder + hourlyRate?: Prisma.SortOrder + cost?: Prisma.SortOrder + source?: Prisma.SortOrder + approvalStatus?: Prisma.SortOrder + approvedById?: Prisma.SortOrder + approvedAt?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder } export type TimesheetMinOrderByAggregateInput = { @@ -462,8 +721,18 @@ export type TimesheetMinOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder + startTime?: Prisma.SortOrder + endTime?: Prisma.SortOrder + billable?: Prisma.SortOrder + hourlyRate?: Prisma.SortOrder + cost?: Prisma.SortOrder + source?: Prisma.SortOrder + approvalStatus?: Prisma.SortOrder + approvedById?: Prisma.SortOrder + approvedAt?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder + deletedAt?: Prisma.SortOrder } export type TimesheetSumOrderByAggregateInput = { @@ -472,6 +741,9 @@ export type TimesheetSumOrderByAggregateInput = { userId?: Prisma.SortOrder projectId?: Prisma.SortOrder taskId?: Prisma.SortOrder + hourlyRate?: Prisma.SortOrder + cost?: Prisma.SortOrder + approvedById?: Prisma.SortOrder } export type TimesheetCreateNestedManyWithoutUserInput = { @@ -481,6 +753,13 @@ export type TimesheetCreateNestedManyWithoutUserInput = { connect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] } +export type TimesheetCreateNestedManyWithoutApprovedByInput = { + create?: Prisma.XOR | Prisma.TimesheetCreateWithoutApprovedByInput[] | Prisma.TimesheetUncheckedCreateWithoutApprovedByInput[] + connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutApprovedByInput | Prisma.TimesheetCreateOrConnectWithoutApprovedByInput[] + createMany?: Prisma.TimesheetCreateManyApprovedByInputEnvelope + connect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] +} + export type TimesheetUncheckedCreateNestedManyWithoutUserInput = { create?: Prisma.XOR | Prisma.TimesheetCreateWithoutUserInput[] | Prisma.TimesheetUncheckedCreateWithoutUserInput[] connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutUserInput | Prisma.TimesheetCreateOrConnectWithoutUserInput[] @@ -488,6 +767,13 @@ export type TimesheetUncheckedCreateNestedManyWithoutUserInput = { connect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] } +export type TimesheetUncheckedCreateNestedManyWithoutApprovedByInput = { + create?: Prisma.XOR | Prisma.TimesheetCreateWithoutApprovedByInput[] | Prisma.TimesheetUncheckedCreateWithoutApprovedByInput[] + connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutApprovedByInput | Prisma.TimesheetCreateOrConnectWithoutApprovedByInput[] + createMany?: Prisma.TimesheetCreateManyApprovedByInputEnvelope + connect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] +} + export type TimesheetUpdateManyWithoutUserNestedInput = { create?: Prisma.XOR | Prisma.TimesheetCreateWithoutUserInput[] | Prisma.TimesheetUncheckedCreateWithoutUserInput[] connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutUserInput | Prisma.TimesheetCreateOrConnectWithoutUserInput[] @@ -502,6 +788,20 @@ export type TimesheetUpdateManyWithoutUserNestedInput = { deleteMany?: Prisma.TimesheetScalarWhereInput | Prisma.TimesheetScalarWhereInput[] } +export type TimesheetUpdateManyWithoutApprovedByNestedInput = { + create?: Prisma.XOR | Prisma.TimesheetCreateWithoutApprovedByInput[] | Prisma.TimesheetUncheckedCreateWithoutApprovedByInput[] + connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutApprovedByInput | Prisma.TimesheetCreateOrConnectWithoutApprovedByInput[] + upsert?: Prisma.TimesheetUpsertWithWhereUniqueWithoutApprovedByInput | Prisma.TimesheetUpsertWithWhereUniqueWithoutApprovedByInput[] + createMany?: Prisma.TimesheetCreateManyApprovedByInputEnvelope + set?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + disconnect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + delete?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + connect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + update?: Prisma.TimesheetUpdateWithWhereUniqueWithoutApprovedByInput | Prisma.TimesheetUpdateWithWhereUniqueWithoutApprovedByInput[] + updateMany?: Prisma.TimesheetUpdateManyWithWhereWithoutApprovedByInput | Prisma.TimesheetUpdateManyWithWhereWithoutApprovedByInput[] + deleteMany?: Prisma.TimesheetScalarWhereInput | Prisma.TimesheetScalarWhereInput[] +} + export type TimesheetUncheckedUpdateManyWithoutUserNestedInput = { create?: Prisma.XOR | Prisma.TimesheetCreateWithoutUserInput[] | Prisma.TimesheetUncheckedCreateWithoutUserInput[] connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutUserInput | Prisma.TimesheetCreateOrConnectWithoutUserInput[] @@ -516,6 +816,20 @@ export type TimesheetUncheckedUpdateManyWithoutUserNestedInput = { deleteMany?: Prisma.TimesheetScalarWhereInput | Prisma.TimesheetScalarWhereInput[] } +export type TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput = { + create?: Prisma.XOR | Prisma.TimesheetCreateWithoutApprovedByInput[] | Prisma.TimesheetUncheckedCreateWithoutApprovedByInput[] + connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutApprovedByInput | Prisma.TimesheetCreateOrConnectWithoutApprovedByInput[] + upsert?: Prisma.TimesheetUpsertWithWhereUniqueWithoutApprovedByInput | Prisma.TimesheetUpsertWithWhereUniqueWithoutApprovedByInput[] + createMany?: Prisma.TimesheetCreateManyApprovedByInputEnvelope + set?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + disconnect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + delete?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + connect?: Prisma.TimesheetWhereUniqueInput | Prisma.TimesheetWhereUniqueInput[] + update?: Prisma.TimesheetUpdateWithWhereUniqueWithoutApprovedByInput | Prisma.TimesheetUpdateWithWhereUniqueWithoutApprovedByInput[] + updateMany?: Prisma.TimesheetUpdateManyWithWhereWithoutApprovedByInput | Prisma.TimesheetUpdateManyWithWhereWithoutApprovedByInput[] + deleteMany?: Prisma.TimesheetScalarWhereInput | Prisma.TimesheetScalarWhereInput[] +} + export type TimesheetCreateNestedManyWithoutProjectInput = { create?: Prisma.XOR | Prisma.TimesheetCreateWithoutProjectInput[] | Prisma.TimesheetUncheckedCreateWithoutProjectInput[] connectOrCreate?: Prisma.TimesheetCreateOrConnectWithoutProjectInput | Prisma.TimesheetCreateOrConnectWithoutProjectInput[] @@ -600,22 +914,51 @@ export type TimesheetUncheckedUpdateManyWithoutTaskNestedInput = { deleteMany?: Prisma.TimesheetScalarWhereInput | Prisma.TimesheetScalarWhereInput[] } -export type FloatFieldUpdateOperationsInput = { - set?: number - increment?: number - decrement?: number - multiply?: number - divide?: number +export type TimesheetCreatetagsInput = { + set: string[] +} + +export type NullableDecimalFieldUpdateOperationsInput = { + set?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + increment?: runtime.Decimal | runtime.DecimalJsLike | number | string + decrement?: runtime.Decimal | runtime.DecimalJsLike | number | string + multiply?: runtime.Decimal | runtime.DecimalJsLike | number | string + divide?: runtime.Decimal | runtime.DecimalJsLike | number | string +} + +export type EnumTimesheetSourceFieldUpdateOperationsInput = { + set?: $Enums.TimesheetSource +} + +export type EnumApprovalStatusFieldUpdateOperationsInput = { + set?: $Enums.ApprovalStatus +} + +export type TimesheetUpdatetagsInput = { + set?: string[] + push?: string | string[] } export type TimesheetCreateWithoutUserInput = { description: string date: Date | string timeSpent: number + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null project: Prisma.ProjectCreateNestedOneWithoutTimesheetsInput task?: Prisma.TaskCreateNestedOneWithoutTimesheetsInput + approvedBy?: Prisma.UserCreateNestedOneWithoutApprovedTimesheetsInput } export type TimesheetUncheckedCreateWithoutUserInput = { @@ -625,8 +968,20 @@ export type TimesheetUncheckedCreateWithoutUserInput = { timeSpent: number projectId: number taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetCreateOrConnectWithoutUserInput = { @@ -639,6 +994,61 @@ export type TimesheetCreateManyUserInputEnvelope = { skipDuplicates?: boolean } +export type TimesheetCreateWithoutApprovedByInput = { + description: string + date: Date | string + timeSpent: number + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + createdAt?: Date | string + updatedAt?: Date | string + deletedAt?: Date | string | null + project: Prisma.ProjectCreateNestedOneWithoutTimesheetsInput + user: Prisma.UserCreateNestedOneWithoutTimesheetsInput + task?: Prisma.TaskCreateNestedOneWithoutTimesheetsInput +} + +export type TimesheetUncheckedCreateWithoutApprovedByInput = { + id?: number + description: string + date: Date | string + timeSpent: number + userId: number + projectId: number + taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + createdAt?: Date | string + updatedAt?: Date | string + deletedAt?: Date | string | null +} + +export type TimesheetCreateOrConnectWithoutApprovedByInput = { + where: Prisma.TimesheetWhereUniqueInput + create: Prisma.XOR +} + +export type TimesheetCreateManyApprovedByInputEnvelope = { + data: Prisma.TimesheetCreateManyApprovedByInput | Prisma.TimesheetCreateManyApprovedByInput[] + skipDuplicates?: boolean +} + export type TimesheetUpsertWithWhereUniqueWithoutUserInput = { where: Prisma.TimesheetWhereUniqueInput update: Prisma.XOR @@ -666,18 +1076,58 @@ export type TimesheetScalarWhereInput = { userId?: Prisma.IntFilter<"Timesheet"> | number projectId?: Prisma.IntFilter<"Timesheet"> | number taskId?: Prisma.IntNullableFilter<"Timesheet"> | number | null + startTime?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + endTime?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + billable?: Prisma.BoolFilter<"Timesheet"> | boolean + hourlyRate?: Prisma.DecimalNullableFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.DecimalNullableFilter<"Timesheet"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFilter<"Timesheet"> | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFilter<"Timesheet"> | $Enums.ApprovalStatus + approvedById?: Prisma.IntNullableFilter<"Timesheet"> | number | null + approvedAt?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null + tags?: Prisma.StringNullableListFilter<"Timesheet"> + customFields?: Prisma.JsonNullableFilter<"Timesheet"> createdAt?: Prisma.DateTimeFilter<"Timesheet"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Timesheet"> | Date | string + deletedAt?: Prisma.DateTimeNullableFilter<"Timesheet"> | Date | string | null +} + +export type TimesheetUpsertWithWhereUniqueWithoutApprovedByInput = { + where: Prisma.TimesheetWhereUniqueInput + update: Prisma.XOR + create: Prisma.XOR +} + +export type TimesheetUpdateWithWhereUniqueWithoutApprovedByInput = { + where: Prisma.TimesheetWhereUniqueInput + data: Prisma.XOR +} + +export type TimesheetUpdateManyWithWhereWithoutApprovedByInput = { + where: Prisma.TimesheetScalarWhereInput + data: Prisma.XOR } export type TimesheetCreateWithoutProjectInput = { description: string date: Date | string timeSpent: number + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null user: Prisma.UserCreateNestedOneWithoutTimesheetsInput task?: Prisma.TaskCreateNestedOneWithoutTimesheetsInput + approvedBy?: Prisma.UserCreateNestedOneWithoutApprovedTimesheetsInput } export type TimesheetUncheckedCreateWithoutProjectInput = { @@ -687,8 +1137,20 @@ export type TimesheetUncheckedCreateWithoutProjectInput = { timeSpent: number userId: number taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetCreateOrConnectWithoutProjectInput = { @@ -721,10 +1183,22 @@ export type TimesheetCreateWithoutTaskInput = { description: string date: Date | string timeSpent: number + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null project: Prisma.ProjectCreateNestedOneWithoutTimesheetsInput user: Prisma.UserCreateNestedOneWithoutTimesheetsInput + approvedBy?: Prisma.UserCreateNestedOneWithoutApprovedTimesheetsInput } export type TimesheetUncheckedCreateWithoutTaskInput = { @@ -734,8 +1208,20 @@ export type TimesheetUncheckedCreateWithoutTaskInput = { timeSpent: number userId: number projectId: number + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetCreateOrConnectWithoutTaskInput = { @@ -771,18 +1257,65 @@ export type TimesheetCreateManyUserInput = { timeSpent: number projectId: number taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + createdAt?: Date | string + updatedAt?: Date | string + deletedAt?: Date | string | null +} + +export type TimesheetCreateManyApprovedByInput = { + id?: number + description: string + date: Date | string + timeSpent: number + userId: number + projectId: number + taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetUpdateWithoutUserInput = { description?: Prisma.StringFieldUpdateOperationsInput | string date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null project?: Prisma.ProjectUpdateOneRequiredWithoutTimesheetsNestedInput task?: Prisma.TaskUpdateOneWithoutTimesheetsNestedInput + approvedBy?: Prisma.UserUpdateOneWithoutApprovedTimesheetsNestedInput } export type TimesheetUncheckedUpdateWithoutUserInput = { @@ -792,8 +1325,20 @@ export type TimesheetUncheckedUpdateWithoutUserInput = { timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetUncheckedUpdateManyWithoutUserInput = { @@ -803,8 +1348,88 @@ export type TimesheetUncheckedUpdateManyWithoutUserInput = { timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null +} + +export type TimesheetUpdateWithoutApprovedByInput = { + description?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + project?: Prisma.ProjectUpdateOneRequiredWithoutTimesheetsNestedInput + user?: Prisma.UserUpdateOneRequiredWithoutTimesheetsNestedInput + task?: Prisma.TaskUpdateOneWithoutTimesheetsNestedInput +} + +export type TimesheetUncheckedUpdateWithoutApprovedByInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + description?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + userId?: Prisma.IntFieldUpdateOperationsInput | number + projectId?: Prisma.IntFieldUpdateOperationsInput | number + taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null +} + +export type TimesheetUncheckedUpdateManyWithoutApprovedByInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + description?: Prisma.StringFieldUpdateOperationsInput | string + date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + userId?: Prisma.IntFieldUpdateOperationsInput | number + projectId?: Prisma.IntFieldUpdateOperationsInput | number + taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetCreateManyProjectInput = { @@ -814,18 +1439,42 @@ export type TimesheetCreateManyProjectInput = { timeSpent: number userId: number taskId?: number | null + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetUpdateWithoutProjectInput = { description?: Prisma.StringFieldUpdateOperationsInput | string date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null user?: Prisma.UserUpdateOneRequiredWithoutTimesheetsNestedInput task?: Prisma.TaskUpdateOneWithoutTimesheetsNestedInput + approvedBy?: Prisma.UserUpdateOneWithoutApprovedTimesheetsNestedInput } export type TimesheetUncheckedUpdateWithoutProjectInput = { @@ -835,8 +1484,20 @@ export type TimesheetUncheckedUpdateWithoutProjectInput = { timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number userId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetUncheckedUpdateManyWithoutProjectInput = { @@ -846,8 +1507,20 @@ export type TimesheetUncheckedUpdateManyWithoutProjectInput = { timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number userId?: Prisma.IntFieldUpdateOperationsInput | number taskId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetCreateManyTaskInput = { @@ -857,18 +1530,42 @@ export type TimesheetCreateManyTaskInput = { timeSpent: number userId: number projectId: number + startTime?: Date | string | null + endTime?: Date | string | null + billable?: boolean + hourlyRate?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: $Enums.TimesheetSource + approvalStatus?: $Enums.ApprovalStatus + approvedById?: number | null + approvedAt?: Date | string | null + tags?: Prisma.TimesheetCreatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Date | string updatedAt?: Date | string + deletedAt?: Date | string | null } export type TimesheetUpdateWithoutTaskInput = { description?: Prisma.StringFieldUpdateOperationsInput | string date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null project?: Prisma.ProjectUpdateOneRequiredWithoutTimesheetsNestedInput user?: Prisma.UserUpdateOneRequiredWithoutTimesheetsNestedInput + approvedBy?: Prisma.UserUpdateOneWithoutApprovedTimesheetsNestedInput } export type TimesheetUncheckedUpdateWithoutTaskInput = { @@ -878,8 +1575,20 @@ export type TimesheetUncheckedUpdateWithoutTaskInput = { timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } export type TimesheetUncheckedUpdateManyWithoutTaskInput = { @@ -889,8 +1598,20 @@ export type TimesheetUncheckedUpdateManyWithoutTaskInput = { timeSpent?: Prisma.FloatFieldUpdateOperationsInput | number userId?: Prisma.IntFieldUpdateOperationsInput | number projectId?: Prisma.IntFieldUpdateOperationsInput | number + startTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + endTime?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + billable?: Prisma.BoolFieldUpdateOperationsInput | boolean + hourlyRate?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + cost?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null + source?: Prisma.EnumTimesheetSourceFieldUpdateOperationsInput | $Enums.TimesheetSource + approvalStatus?: Prisma.EnumApprovalStatusFieldUpdateOperationsInput | $Enums.ApprovalStatus + approvedById?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + approvedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + tags?: Prisma.TimesheetUpdatetagsInput | string[] + customFields?: Prisma.NullableJsonNullValueInput | runtime.InputJsonValue createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null } @@ -903,11 +1624,24 @@ export type TimesheetSelect user?: boolean | Prisma.UserDefaultArgs task?: boolean | Prisma.Timesheet$taskArgs + approvedBy?: boolean | Prisma.Timesheet$approvedByArgs }, ExtArgs["result"]["timesheet"]> export type TimesheetSelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ @@ -918,11 +1652,24 @@ export type TimesheetSelectCreateManyAndReturn user?: boolean | Prisma.UserDefaultArgs task?: boolean | Prisma.Timesheet$taskArgs + approvedBy?: boolean | Prisma.Timesheet$approvedByArgs }, ExtArgs["result"]["timesheet"]> export type TimesheetSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ @@ -933,11 +1680,24 @@ export type TimesheetSelectUpdateManyAndReturn user?: boolean | Prisma.UserDefaultArgs task?: boolean | Prisma.Timesheet$taskArgs + approvedBy?: boolean | Prisma.Timesheet$approvedByArgs }, ExtArgs["result"]["timesheet"]> export type TimesheetSelectScalar = { @@ -948,25 +1708,40 @@ export type TimesheetSelectScalar = { userId?: boolean projectId?: boolean taskId?: boolean + startTime?: boolean + endTime?: boolean + billable?: boolean + hourlyRate?: boolean + cost?: boolean + source?: boolean + approvalStatus?: boolean + approvedById?: boolean + approvedAt?: boolean + tags?: boolean + customFields?: boolean createdAt?: boolean updatedAt?: boolean + deletedAt?: boolean } -export type TimesheetOmit = runtime.Types.Extensions.GetOmit<"id" | "description" | "date" | "timeSpent" | "userId" | "projectId" | "taskId" | "createdAt" | "updatedAt", ExtArgs["result"]["timesheet"]> +export type TimesheetOmit = runtime.Types.Extensions.GetOmit<"id" | "description" | "date" | "timeSpent" | "userId" | "projectId" | "taskId" | "startTime" | "endTime" | "billable" | "hourlyRate" | "cost" | "source" | "approvalStatus" | "approvedById" | "approvedAt" | "tags" | "customFields" | "createdAt" | "updatedAt" | "deletedAt", ExtArgs["result"]["timesheet"]> export type TimesheetInclude = { project?: boolean | Prisma.ProjectDefaultArgs user?: boolean | Prisma.UserDefaultArgs task?: boolean | Prisma.Timesheet$taskArgs + approvedBy?: boolean | Prisma.Timesheet$approvedByArgs } export type TimesheetIncludeCreateManyAndReturn = { project?: boolean | Prisma.ProjectDefaultArgs user?: boolean | Prisma.UserDefaultArgs task?: boolean | Prisma.Timesheet$taskArgs + approvedBy?: boolean | Prisma.Timesheet$approvedByArgs } export type TimesheetIncludeUpdateManyAndReturn = { project?: boolean | Prisma.ProjectDefaultArgs user?: boolean | Prisma.UserDefaultArgs task?: boolean | Prisma.Timesheet$taskArgs + approvedBy?: boolean | Prisma.Timesheet$approvedByArgs } export type $TimesheetPayload = { @@ -975,6 +1750,7 @@ export type $TimesheetPayload user: Prisma.$UserPayload task: Prisma.$TaskPayload | null + approvedBy: Prisma.$UserPayload | null } scalars: runtime.Types.Extensions.GetPayloadResult<{ id: number @@ -984,8 +1760,20 @@ export type $TimesheetPayload composites: {} } @@ -1383,6 +2171,7 @@ export interface Prisma__TimesheetClient = {}>(args?: Prisma.Subset>): Prisma.Prisma__ProjectClient, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions> user = {}>(args?: Prisma.Subset>): Prisma.Prisma__UserClient, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions> task = {}>(args?: Prisma.Subset>): Prisma.Prisma__TaskClient, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + approvedBy = {}>(args?: Prisma.Subset>): Prisma.Prisma__UserClient, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. @@ -1419,8 +2208,20 @@ export interface TimesheetFieldRefs { readonly userId: Prisma.FieldRef<"Timesheet", 'Int'> readonly projectId: Prisma.FieldRef<"Timesheet", 'Int'> readonly taskId: Prisma.FieldRef<"Timesheet", 'Int'> + readonly startTime: Prisma.FieldRef<"Timesheet", 'DateTime'> + readonly endTime: Prisma.FieldRef<"Timesheet", 'DateTime'> + readonly billable: Prisma.FieldRef<"Timesheet", 'Boolean'> + readonly hourlyRate: Prisma.FieldRef<"Timesheet", 'Decimal'> + readonly cost: Prisma.FieldRef<"Timesheet", 'Decimal'> + readonly source: Prisma.FieldRef<"Timesheet", 'TimesheetSource'> + readonly approvalStatus: Prisma.FieldRef<"Timesheet", 'ApprovalStatus'> + readonly approvedById: Prisma.FieldRef<"Timesheet", 'Int'> + readonly approvedAt: Prisma.FieldRef<"Timesheet", 'DateTime'> + readonly tags: Prisma.FieldRef<"Timesheet", 'String[]'> + readonly customFields: Prisma.FieldRef<"Timesheet", 'Json'> readonly createdAt: Prisma.FieldRef<"Timesheet", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"Timesheet", 'DateTime'> + readonly deletedAt: Prisma.FieldRef<"Timesheet", 'DateTime'> } @@ -1835,6 +2636,25 @@ export type Timesheet$taskArgs = { + /** + * Select specific fields to fetch from the User + */ + select?: Prisma.UserSelect | null + /** + * Omit specific fields from the User + */ + omit?: Prisma.UserOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.UserInclude | null + where?: Prisma.UserWhereInput +} + /** * Timesheet without action */ diff --git a/backend/prisma/generated/models/User.ts b/backend/prisma/generated/models/User.ts index 9ede1df..7f0d872 100644 --- a/backend/prisma/generated/models/User.ts +++ b/backend/prisma/generated/models/User.ts @@ -310,6 +310,8 @@ export type UserWhereInput = { comments?: Prisma.CommentListRelationFilter projectMemberships?: Prisma.ProjectMemberListRelationFilter workspaceMembers?: Prisma.WorkspaceMemberListRelationFilter + reportedTasks?: Prisma.TaskListRelationFilter + approvedTimesheets?: Prisma.TimesheetListRelationFilter conversations?: Prisma.ConversationParticipantListRelationFilter messages?: Prisma.MessageListRelationFilter } @@ -337,6 +339,8 @@ export type UserOrderByWithRelationInput = { comments?: Prisma.CommentOrderByRelationAggregateInput projectMemberships?: Prisma.ProjectMemberOrderByRelationAggregateInput workspaceMembers?: Prisma.WorkspaceMemberOrderByRelationAggregateInput + reportedTasks?: Prisma.TaskOrderByRelationAggregateInput + approvedTimesheets?: Prisma.TimesheetOrderByRelationAggregateInput conversations?: Prisma.ConversationParticipantOrderByRelationAggregateInput messages?: Prisma.MessageOrderByRelationAggregateInput } @@ -367,6 +371,8 @@ export type UserWhereUniqueInput = Prisma.AtLeast<{ comments?: Prisma.CommentListRelationFilter projectMemberships?: Prisma.ProjectMemberListRelationFilter workspaceMembers?: Prisma.WorkspaceMemberListRelationFilter + reportedTasks?: Prisma.TaskListRelationFilter + approvedTimesheets?: Prisma.TimesheetListRelationFilter conversations?: Prisma.ConversationParticipantListRelationFilter messages?: Prisma.MessageListRelationFilter }, "id" | "email"> @@ -439,6 +445,8 @@ export type UserCreateInput = { comments?: Prisma.CommentCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -466,6 +474,8 @@ export type UserUncheckedCreateInput = { comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -492,6 +502,8 @@ export type UserUpdateInput = { comments?: Prisma.CommentUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -519,6 +531,8 @@ export type UserUncheckedUpdateInput = { comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -726,6 +740,12 @@ export type UserCreateNestedOneWithoutTasksInput = { connect?: Prisma.UserWhereUniqueInput } +export type UserCreateNestedOneWithoutReportedTasksInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.UserCreateOrConnectWithoutReportedTasksInput + connect?: Prisma.UserWhereUniqueInput +} + export type UserUpdateOneRequiredWithoutTasksNestedInput = { create?: Prisma.XOR connectOrCreate?: Prisma.UserCreateOrConnectWithoutTasksInput @@ -734,12 +754,28 @@ export type UserUpdateOneRequiredWithoutTasksNestedInput = { update?: Prisma.XOR, Prisma.UserUncheckedUpdateWithoutTasksInput> } +export type UserUpdateOneWithoutReportedTasksNestedInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.UserCreateOrConnectWithoutReportedTasksInput + upsert?: Prisma.UserUpsertWithoutReportedTasksInput + disconnect?: Prisma.UserWhereInput | boolean + delete?: Prisma.UserWhereInput | boolean + connect?: Prisma.UserWhereUniqueInput + update?: Prisma.XOR, Prisma.UserUncheckedUpdateWithoutReportedTasksInput> +} + export type UserCreateNestedOneWithoutTimesheetsInput = { create?: Prisma.XOR connectOrCreate?: Prisma.UserCreateOrConnectWithoutTimesheetsInput connect?: Prisma.UserWhereUniqueInput } +export type UserCreateNestedOneWithoutApprovedTimesheetsInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.UserCreateOrConnectWithoutApprovedTimesheetsInput + connect?: Prisma.UserWhereUniqueInput +} + export type UserUpdateOneRequiredWithoutTimesheetsNestedInput = { create?: Prisma.XOR connectOrCreate?: Prisma.UserCreateOrConnectWithoutTimesheetsInput @@ -748,6 +784,16 @@ export type UserUpdateOneRequiredWithoutTimesheetsNestedInput = { update?: Prisma.XOR, Prisma.UserUncheckedUpdateWithoutTimesheetsInput> } +export type UserUpdateOneWithoutApprovedTimesheetsNestedInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.UserCreateOrConnectWithoutApprovedTimesheetsInput + upsert?: Prisma.UserUpsertWithoutApprovedTimesheetsInput + disconnect?: Prisma.UserWhereInput | boolean + delete?: Prisma.UserWhereInput | boolean + connect?: Prisma.UserWhereUniqueInput + update?: Prisma.XOR, Prisma.UserUncheckedUpdateWithoutApprovedTimesheetsInput> +} + export type UserCreateNestedOneWithoutCommentsInput = { create?: Prisma.XOR connectOrCreate?: Prisma.UserCreateOrConnectWithoutCommentsInput @@ -825,6 +871,8 @@ export type UserCreateWithoutWorkspaceMembersInput = { timesheets?: Prisma.TimesheetCreateNestedManyWithoutUserInput comments?: Prisma.CommentCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -851,6 +899,8 @@ export type UserUncheckedCreateWithoutWorkspaceMembersInput = { timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutUserInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -892,6 +942,8 @@ export type UserUpdateWithoutWorkspaceMembersInput = { timesheets?: Prisma.TimesheetUpdateManyWithoutUserNestedInput comments?: Prisma.CommentUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -918,6 +970,8 @@ export type UserUncheckedUpdateWithoutWorkspaceMembersInput = { timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutUserNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -943,6 +997,8 @@ export type UserCreateWithoutProjectsInput = { comments?: Prisma.CommentCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -969,6 +1025,8 @@ export type UserUncheckedCreateWithoutProjectsInput = { comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -1010,6 +1068,8 @@ export type UserUpdateWithoutProjectsInput = { comments?: Prisma.CommentUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -1036,6 +1096,8 @@ export type UserUncheckedUpdateWithoutProjectsInput = { comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -1061,6 +1123,8 @@ export type UserCreateWithoutTasksInput = { comments?: Prisma.CommentCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -1087,6 +1151,8 @@ export type UserUncheckedCreateWithoutTasksInput = { comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -1096,6 +1162,66 @@ export type UserCreateOrConnectWithoutTasksInput = { create: Prisma.XOR } +export type UserCreateWithoutReportedTasksInput = { + name: string + email: string + password: string + phone?: string | null + mobile?: string | null + firstName: string + lastName?: string | null + status?: boolean + address?: string | null + bio?: string | null + birthDate?: Date | string | null + gender?: $Enums.Gender | null + role?: $Enums.UserRole + createdAt?: Date | string + updatedAt?: Date | string + tasks?: Prisma.TaskCreateNestedManyWithoutUserInput + projects?: Prisma.ProjectCreateNestedManyWithoutResponsibleInput + timesheets?: Prisma.TimesheetCreateNestedManyWithoutUserInput + comments?: Prisma.CommentCreateNestedManyWithoutUserInput + projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput + workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput + conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput + messages?: Prisma.MessageCreateNestedManyWithoutSenderInput +} + +export type UserUncheckedCreateWithoutReportedTasksInput = { + id?: number + name: string + email: string + password: string + phone?: string | null + mobile?: string | null + firstName: string + lastName?: string | null + status?: boolean + address?: string | null + bio?: string | null + birthDate?: Date | string | null + gender?: $Enums.Gender | null + role?: $Enums.UserRole + createdAt?: Date | string + updatedAt?: Date | string + tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutUserInput + projects?: Prisma.ProjectUncheckedCreateNestedManyWithoutResponsibleInput + timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutUserInput + comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput + projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput + workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput + conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput + messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput +} + +export type UserCreateOrConnectWithoutReportedTasksInput = { + where: Prisma.UserWhereUniqueInput + create: Prisma.XOR +} + export type UserUpsertWithoutTasksInput = { update: Prisma.XOR create: Prisma.XOR @@ -1128,6 +1254,8 @@ export type UserUpdateWithoutTasksInput = { comments?: Prisma.CommentUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -1154,6 +1282,74 @@ export type UserUncheckedUpdateWithoutTasksInput = { comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput + conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput + messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput +} + +export type UserUpsertWithoutReportedTasksInput = { + update: Prisma.XOR + create: Prisma.XOR + where?: Prisma.UserWhereInput +} + +export type UserUpdateToOneWithWhereWithoutReportedTasksInput = { + where?: Prisma.UserWhereInput + data: Prisma.XOR +} + +export type UserUpdateWithoutReportedTasksInput = { + name?: Prisma.StringFieldUpdateOperationsInput | string + email?: Prisma.StringFieldUpdateOperationsInput | string + password?: Prisma.StringFieldUpdateOperationsInput | string + phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + mobile?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + firstName?: Prisma.StringFieldUpdateOperationsInput | string + lastName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + status?: Prisma.BoolFieldUpdateOperationsInput | boolean + address?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + bio?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + birthDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + gender?: Prisma.NullableEnumGenderFieldUpdateOperationsInput | $Enums.Gender | null + role?: Prisma.EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + tasks?: Prisma.TaskUpdateManyWithoutUserNestedInput + projects?: Prisma.ProjectUpdateManyWithoutResponsibleNestedInput + timesheets?: Prisma.TimesheetUpdateManyWithoutUserNestedInput + comments?: Prisma.CommentUpdateManyWithoutUserNestedInput + projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput + workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput + conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput + messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput +} + +export type UserUncheckedUpdateWithoutReportedTasksInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + email?: Prisma.StringFieldUpdateOperationsInput | string + password?: Prisma.StringFieldUpdateOperationsInput | string + phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + mobile?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + firstName?: Prisma.StringFieldUpdateOperationsInput | string + lastName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + status?: Prisma.BoolFieldUpdateOperationsInput | boolean + address?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + bio?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + birthDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + gender?: Prisma.NullableEnumGenderFieldUpdateOperationsInput | $Enums.Gender | null + role?: Prisma.EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + tasks?: Prisma.TaskUncheckedUpdateManyWithoutUserNestedInput + projects?: Prisma.ProjectUncheckedUpdateManyWithoutResponsibleNestedInput + timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutUserNestedInput + comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput + projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput + workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -1179,6 +1375,8 @@ export type UserCreateWithoutTimesheetsInput = { comments?: Prisma.CommentCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -1205,6 +1403,8 @@ export type UserUncheckedCreateWithoutTimesheetsInput = { comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -1214,6 +1414,66 @@ export type UserCreateOrConnectWithoutTimesheetsInput = { create: Prisma.XOR } +export type UserCreateWithoutApprovedTimesheetsInput = { + name: string + email: string + password: string + phone?: string | null + mobile?: string | null + firstName: string + lastName?: string | null + status?: boolean + address?: string | null + bio?: string | null + birthDate?: Date | string | null + gender?: $Enums.Gender | null + role?: $Enums.UserRole + createdAt?: Date | string + updatedAt?: Date | string + tasks?: Prisma.TaskCreateNestedManyWithoutUserInput + projects?: Prisma.ProjectCreateNestedManyWithoutResponsibleInput + timesheets?: Prisma.TimesheetCreateNestedManyWithoutUserInput + comments?: Prisma.CommentCreateNestedManyWithoutUserInput + projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput + workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput + messages?: Prisma.MessageCreateNestedManyWithoutSenderInput +} + +export type UserUncheckedCreateWithoutApprovedTimesheetsInput = { + id?: number + name: string + email: string + password: string + phone?: string | null + mobile?: string | null + firstName: string + lastName?: string | null + status?: boolean + address?: string | null + bio?: string | null + birthDate?: Date | string | null + gender?: $Enums.Gender | null + role?: $Enums.UserRole + createdAt?: Date | string + updatedAt?: Date | string + tasks?: Prisma.TaskUncheckedCreateNestedManyWithoutUserInput + projects?: Prisma.ProjectUncheckedCreateNestedManyWithoutResponsibleInput + timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutUserInput + comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput + projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput + workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput + messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput +} + +export type UserCreateOrConnectWithoutApprovedTimesheetsInput = { + where: Prisma.UserWhereUniqueInput + create: Prisma.XOR +} + export type UserUpsertWithoutTimesheetsInput = { update: Prisma.XOR create: Prisma.XOR @@ -1246,6 +1506,8 @@ export type UserUpdateWithoutTimesheetsInput = { comments?: Prisma.CommentUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -1272,6 +1534,74 @@ export type UserUncheckedUpdateWithoutTimesheetsInput = { comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput + conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput + messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput +} + +export type UserUpsertWithoutApprovedTimesheetsInput = { + update: Prisma.XOR + create: Prisma.XOR + where?: Prisma.UserWhereInput +} + +export type UserUpdateToOneWithWhereWithoutApprovedTimesheetsInput = { + where?: Prisma.UserWhereInput + data: Prisma.XOR +} + +export type UserUpdateWithoutApprovedTimesheetsInput = { + name?: Prisma.StringFieldUpdateOperationsInput | string + email?: Prisma.StringFieldUpdateOperationsInput | string + password?: Prisma.StringFieldUpdateOperationsInput | string + phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + mobile?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + firstName?: Prisma.StringFieldUpdateOperationsInput | string + lastName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + status?: Prisma.BoolFieldUpdateOperationsInput | boolean + address?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + bio?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + birthDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + gender?: Prisma.NullableEnumGenderFieldUpdateOperationsInput | $Enums.Gender | null + role?: Prisma.EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + tasks?: Prisma.TaskUpdateManyWithoutUserNestedInput + projects?: Prisma.ProjectUpdateManyWithoutResponsibleNestedInput + timesheets?: Prisma.TimesheetUpdateManyWithoutUserNestedInput + comments?: Prisma.CommentUpdateManyWithoutUserNestedInput + projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput + workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput + messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput +} + +export type UserUncheckedUpdateWithoutApprovedTimesheetsInput = { + id?: Prisma.IntFieldUpdateOperationsInput | number + name?: Prisma.StringFieldUpdateOperationsInput | string + email?: Prisma.StringFieldUpdateOperationsInput | string + password?: Prisma.StringFieldUpdateOperationsInput | string + phone?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + mobile?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + firstName?: Prisma.StringFieldUpdateOperationsInput | string + lastName?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + status?: Prisma.BoolFieldUpdateOperationsInput | boolean + address?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + bio?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + birthDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null + gender?: Prisma.NullableEnumGenderFieldUpdateOperationsInput | $Enums.Gender | null + role?: Prisma.EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + tasks?: Prisma.TaskUncheckedUpdateManyWithoutUserNestedInput + projects?: Prisma.ProjectUncheckedUpdateManyWithoutResponsibleNestedInput + timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutUserNestedInput + comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput + projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput + workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -1297,6 +1627,8 @@ export type UserCreateWithoutCommentsInput = { timesheets?: Prisma.TimesheetCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -1323,6 +1655,8 @@ export type UserUncheckedCreateWithoutCommentsInput = { timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -1364,6 +1698,8 @@ export type UserUpdateWithoutCommentsInput = { timesheets?: Prisma.TimesheetUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -1390,6 +1726,8 @@ export type UserUncheckedUpdateWithoutCommentsInput = { timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -1415,6 +1753,8 @@ export type UserCreateWithoutProjectMembershipsInput = { timesheets?: Prisma.TimesheetCreateNestedManyWithoutUserInput comments?: Prisma.CommentCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -1441,6 +1781,8 @@ export type UserUncheckedCreateWithoutProjectMembershipsInput = { timesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutUserInput comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -1482,6 +1824,8 @@ export type UserUpdateWithoutProjectMembershipsInput = { timesheets?: Prisma.TimesheetUpdateManyWithoutUserNestedInput comments?: Prisma.CommentUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -1508,6 +1852,8 @@ export type UserUncheckedUpdateWithoutProjectMembershipsInput = { timesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutUserNestedInput comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -1534,6 +1880,8 @@ export type UserCreateWithoutConversationsInput = { comments?: Prisma.CommentCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput messages?: Prisma.MessageCreateNestedManyWithoutSenderInput } @@ -1560,6 +1908,8 @@ export type UserUncheckedCreateWithoutConversationsInput = { comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput messages?: Prisma.MessageUncheckedCreateNestedManyWithoutSenderInput } @@ -1601,6 +1951,8 @@ export type UserUpdateWithoutConversationsInput = { comments?: Prisma.CommentUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput messages?: Prisma.MessageUpdateManyWithoutSenderNestedInput } @@ -1627,6 +1979,8 @@ export type UserUncheckedUpdateWithoutConversationsInput = { comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput messages?: Prisma.MessageUncheckedUpdateManyWithoutSenderNestedInput } @@ -1652,6 +2006,8 @@ export type UserCreateWithoutMessagesInput = { comments?: Prisma.CommentCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantCreateNestedManyWithoutUserInput } @@ -1678,6 +2034,8 @@ export type UserUncheckedCreateWithoutMessagesInput = { comments?: Prisma.CommentUncheckedCreateNestedManyWithoutUserInput projectMemberships?: Prisma.ProjectMemberUncheckedCreateNestedManyWithoutUserInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedCreateNestedManyWithoutUserInput + reportedTasks?: Prisma.TaskUncheckedCreateNestedManyWithoutReporterInput + approvedTimesheets?: Prisma.TimesheetUncheckedCreateNestedManyWithoutApprovedByInput conversations?: Prisma.ConversationParticipantUncheckedCreateNestedManyWithoutUserInput } @@ -1719,6 +2077,8 @@ export type UserUpdateWithoutMessagesInput = { comments?: Prisma.CommentUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUpdateManyWithoutUserNestedInput } @@ -1745,6 +2105,8 @@ export type UserUncheckedUpdateWithoutMessagesInput = { comments?: Prisma.CommentUncheckedUpdateManyWithoutUserNestedInput projectMemberships?: Prisma.ProjectMemberUncheckedUpdateManyWithoutUserNestedInput workspaceMembers?: Prisma.WorkspaceMemberUncheckedUpdateManyWithoutUserNestedInput + reportedTasks?: Prisma.TaskUncheckedUpdateManyWithoutReporterNestedInput + approvedTimesheets?: Prisma.TimesheetUncheckedUpdateManyWithoutApprovedByNestedInput conversations?: Prisma.ConversationParticipantUncheckedUpdateManyWithoutUserNestedInput } @@ -1760,6 +2122,8 @@ export type UserCountOutputType = { comments: number projectMemberships: number workspaceMembers: number + reportedTasks: number + approvedTimesheets: number conversations: number messages: number } @@ -1771,6 +2135,8 @@ export type UserCountOutputTypeSelect = { + where?: Prisma.TaskWhereInput +} + +/** + * UserCountOutputType without action + */ +export type UserCountOutputTypeCountApprovedTimesheetsArgs = { + where?: Prisma.TimesheetWhereInput +} + /** * UserCountOutputType without action */ @@ -1865,6 +2245,8 @@ export type UserSelect projectMemberships?: boolean | Prisma.User$projectMembershipsArgs workspaceMembers?: boolean | Prisma.User$workspaceMembersArgs + reportedTasks?: boolean | Prisma.User$reportedTasksArgs + approvedTimesheets?: boolean | Prisma.User$approvedTimesheetsArgs conversations?: boolean | Prisma.User$conversationsArgs messages?: boolean | Prisma.User$messagesArgs _count?: boolean | Prisma.UserCountOutputTypeDefaultArgs @@ -1935,6 +2317,8 @@ export type UserInclude projectMemberships?: boolean | Prisma.User$projectMembershipsArgs workspaceMembers?: boolean | Prisma.User$workspaceMembersArgs + reportedTasks?: boolean | Prisma.User$reportedTasksArgs + approvedTimesheets?: boolean | Prisma.User$approvedTimesheetsArgs conversations?: boolean | Prisma.User$conversationsArgs messages?: boolean | Prisma.User$messagesArgs _count?: boolean | Prisma.UserCountOutputTypeDefaultArgs @@ -1951,6 +2335,8 @@ export type $UserPayload[] projectMemberships: Prisma.$ProjectMemberPayload[] workspaceMembers: Prisma.$WorkspaceMemberPayload[] + reportedTasks: Prisma.$TaskPayload[] + approvedTimesheets: Prisma.$TimesheetPayload[] conversations: Prisma.$ConversationParticipantPayload[] messages: Prisma.$MessagePayload[] } @@ -2371,6 +2757,8 @@ export interface Prisma__UserClient = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> projectMemberships = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> workspaceMembers = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + reportedTasks = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + approvedTimesheets = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> conversations = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> messages = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> /** @@ -2949,6 +3337,54 @@ export type User$workspaceMembersArgs = { + /** + * Select specific fields to fetch from the Task + */ + select?: Prisma.TaskSelect | null + /** + * Omit specific fields from the Task + */ + omit?: Prisma.TaskOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.TaskInclude | null + where?: Prisma.TaskWhereInput + orderBy?: Prisma.TaskOrderByWithRelationInput | Prisma.TaskOrderByWithRelationInput[] + cursor?: Prisma.TaskWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.TaskScalarFieldEnum | Prisma.TaskScalarFieldEnum[] +} + +/** + * User.approvedTimesheets + */ +export type User$approvedTimesheetsArgs = { + /** + * Select specific fields to fetch from the Timesheet + */ + select?: Prisma.TimesheetSelect | null + /** + * Omit specific fields from the Timesheet + */ + omit?: Prisma.TimesheetOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.TimesheetInclude | null + where?: Prisma.TimesheetWhereInput + orderBy?: Prisma.TimesheetOrderByWithRelationInput | Prisma.TimesheetOrderByWithRelationInput[] + cursor?: Prisma.TimesheetWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.TimesheetScalarFieldEnum | Prisma.TimesheetScalarFieldEnum[] +} + /** * User.conversations */ diff --git a/backend/prisma/migrations/20260430154611_add_project_task_enhancements/migration.sql b/backend/prisma/migrations/20260430154611_add_project_task_enhancements/migration.sql new file mode 100644 index 0000000..7c2f702 --- /dev/null +++ b/backend/prisma/migrations/20260430154611_add_project_task_enhancements/migration.sql @@ -0,0 +1,18 @@ +-- CreateEnum +CREATE TYPE "ProjectMethodology" AS ENUM ('SCRUM', 'WATERFALL', 'KANBAN', 'AGILE', 'OTHER'); + +-- CreateEnum +CREATE TYPE "TaskPriority" AS ENUM ('LOW', 'MEDIUM', 'HIGH', 'URGENT'); + +-- AlterTable +ALTER TABLE "Project" ADD COLUMN "budgetActual" DOUBLE PRECISION NOT NULL DEFAULT 0, +ADD COLUMN "budgetPlanned" DOUBLE PRECISION NOT NULL DEFAULT 0, +ADD COLUMN "endDate" TIMESTAMP(3), +ADD COLUMN "methodology" "ProjectMethodology" NOT NULL DEFAULT 'KANBAN', +ADD COLUMN "phasesCount" INTEGER NOT NULL DEFAULT 1, +ADD COLUMN "startDate" TIMESTAMP(3); + +-- AlterTable +ALTER TABLE "Task" ADD COLUMN "dueDate" TIMESTAMP(3), +ADD COLUMN "estimatedHours" DOUBLE PRECISION NOT NULL DEFAULT 0, +ADD COLUMN "priority" "TaskPriority" NOT NULL DEFAULT 'MEDIUM'; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 73c44f3..d2d1434 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -31,6 +31,8 @@ model User { comments Comment[] projectMemberships ProjectMember[] workspaceMembers WorkspaceMember[] + reportedTasks Task[] @relation("ReportedTasks") + approvedTimesheets Timesheet[] @relation("ApprovedTimesheets") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt conversations ConversationParticipant[] @@ -87,6 +89,8 @@ model ProjectStage { projects Project[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + + @@index([workspaceId]) } model TaskStage { @@ -102,6 +106,8 @@ model TaskStage { tasks Task[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + + @@index([workspaceId]) } model Project { @@ -119,9 +125,32 @@ model Project { attachments Attachment[] timesheets Timesheet[] members ProjectMember[] - sequence Int @default(1000) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + + key String? @unique + visibility ProjectVisibility @default(TEAM) + priority ProjectPriority @default(MEDIUM) + budgetPlanned Float @default(0) + budgetActual Float @default(0) + startDate DateTime? + endDate DateTime? + actualStartDate DateTime? + actualEndDate DateTime? + progress Float @default(0) + currency String @default("USD") + phasesCount Int @default(1) + methodology ProjectMethodology @default(KANBAN) + tags String[] + customFields Json? + archivedAt DateTime? + + sequence Int @default(1000) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime? + + @@index([workspaceId]) + @@index([responsibleId]) + @@index([stageId]) } model Task { @@ -137,9 +166,35 @@ model Task { comments Comment[] attachments Attachment[] timesheets Timesheet[] - sequence Int @default(1000) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + + parentTaskId Int? + parentTask Task? @relation("Subtasks", fields: [parentTaskId], references: [id]) + subtasks Task[] @relation("Subtasks") + type TaskType @default(TASK) + reporterId Int? + reporter User? @relation("ReportedTasks", fields: [reporterId], references: [id]) + watchers Json? + startDate DateTime? + dueDate DateTime? + completedAt DateTime? + estimatedHours Float @default(0) + remainingHours Float @default(0) + progress Float @default(0) + priority TaskPriority @default(MEDIUM) + tags String[] + checklist Json? + dependencies Json? + customFields Json? + deletedAt DateTime? + + sequence Int @default(1000) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([projectId]) + @@index([userId]) + @@index([stageId]) + @@index([parentTaskId]) } model Timesheet { @@ -153,8 +208,27 @@ model Timesheet { taskId Int? user User @relation(fields: [userId], references: [id]) task Task? @relation(fields: [taskId], references: [id]) + + startTime DateTime? + endTime DateTime? + billable Boolean @default(true) + hourlyRate Decimal? + cost Decimal? + source TimesheetSource @default(MANUAL) + approvalStatus ApprovalStatus @default(PENDING) + approvedById Int? + approvedBy User? @relation("ApprovedTimesheets", fields: [approvedById], references: [id]) + approvedAt DateTime? + tags String[] + customFields Json? + createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + deletedAt DateTime? + + @@index([userId]) + @@index([projectId]) + @@index([taskId]) } model Comment { @@ -162,6 +236,7 @@ model Comment { content String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + deletedAt DateTime? userId Int projectId Int? taskId Int? @@ -171,6 +246,11 @@ model Comment { task Task? @relation(fields: [taskId], references: [id]) parent Comment? @relation("CommentReplies", fields: [parentId], references: [id]) replies Comment[] @relation("CommentReplies") + + @@index([userId]) + @@index([projectId]) + @@index([taskId]) + @@index([parentId]) } enum UserRole { @@ -202,6 +282,53 @@ enum TaskStatus { CANCELED } +enum ProjectMethodology { + SCRUM + WATERFALL + KANBAN + AGILE + OTHER +} + +enum ProjectVisibility { + PRIVATE + TEAM + PUBLIC +} + +enum ProjectPriority { + LOW + MEDIUM + HIGH + CRITICAL +} + +enum TaskType { + TASK + BUG + STORY + EPIC +} + +enum TaskPriority { + LOW + MEDIUM + HIGH + URGENT +} + +enum TimesheetSource { + MANUAL + TIMER + INTEGRATION +} + +enum ApprovalStatus { + PENDING + APPROVED + REJECTED +} + model Attachment { id Int @id @default(autoincrement()) filename String diff --git a/backend/scripts/migrate-passwords.ts b/backend/scripts/migrate-passwords.ts new file mode 100644 index 0000000..1061cfb --- /dev/null +++ b/backend/scripts/migrate-passwords.ts @@ -0,0 +1,59 @@ +import 'dotenv/config'; +import { PrismaClient } from '../prisma/generated/client'; +import { PrismaPg } from '@prisma/adapter-pg'; +import * as bcrypt from 'bcrypt'; + +const adapter = new PrismaPg({ + connectionString: process.env.DATABASE_URL as string, +}); +const prisma = new PrismaClient({ adapter }); + +async function migratePasswords() { + console.log('Starting password migration...'); + + const users = await prisma.user.findMany({ + select: { + id: true, + email: true, + password: true, + }, + }); + + let migratedCount = 0; + let alreadyHashedCount = 0; + + for (const user of users) { + // Check if password is already hashed (bcrypt hashes start with $2b$ or $2a$) + const isHashed = user.password.startsWith('$2'); + + if (!isHashed) { + console.log(`Migrating password for user: ${user.email}`); + const hashedPassword = await bcrypt.hash(user.password, 10); + + await prisma.user.update({ + where: { id: user.id }, + data: { password: hashedPassword }, + }); + + migratedCount++; + } else { + alreadyHashedCount++; + } + } + + console.log(`Migration complete:`); + console.log(`- Migrated: ${migratedCount} users`); + console.log(`- Already hashed: ${alreadyHashedCount} users`); + + await prisma.$disconnect(); +} + +migratePasswords() + .then(() => { + console.log('Password migration completed successfully'); + process.exit(0); + }) + .catch((error) => { + console.error('Error during password migration:', error); + process.exit(1); + }); diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index f830361..7a7d132 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -1,7 +1,9 @@ import { Module } from '@nestjs/common'; +import { Request, Response } from 'express'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; import { join } from 'path'; +import { ThrottlerModule } from '@nestjs/throttler'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { PrismaModule } from './prisma/prisma.module'; @@ -20,6 +22,12 @@ import { WorkspaceModule } from './workspace/workspace.module'; import { ProjectStageModule } from './project-stage/project-stage.module'; import { TaskStageModule } from './task-stage/task-stage.module'; import { ChatModule } from './chat/chat.module'; +import { HealthModule } from './health/health.module'; +import { validate } from './config/env.validation'; +import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core'; +import { LoggingInterceptor } from './common/interceptors/logging.interceptor'; +import { GlobalExceptionFilter } from './common/filters/global-exception.filter'; +import { depthLimitRule } from './common/validation/depth-limit.validation'; @Module({ imports: [ @@ -27,18 +35,30 @@ import { ChatModule } from './chat/chat.module'; GraphQLModule.forRoot({ driver: ApolloDriver, autoSchemaFile: join(process.cwd(), 'src/schema.gql'), - context: ({ req, res }) => ({ req, res }), + context: ({ req, res }: { req?: Request; res?: Response }) => ({ + req, + res, + }), + subscriptions: { + 'graphql-ws': true, + }, + validationRules: [depthLimitRule(5)], }), ConfigModule.forRoot({ isGlobal: true, + validate, }), + ThrottlerModule.forRoot([ + { + ttl: 60000, // 1 minute + limit: 100, // 100 requests per minute + }, + ]), UserModule, ProjectModule, TaskModule, BaseModule, TimesheetModule, - TimesheetModule, - CommentModule, CommentModule, AuthModule, AttachmentModule, @@ -48,8 +68,19 @@ import { ChatModule } from './chat/chat.module'; ProjectStageModule, TaskStageModule, ChatModule, + HealthModule, ], controllers: [AppController], - providers: [AppService], + providers: [ + AppService, + { + provide: APP_INTERCEPTOR, + useClass: LoggingInterceptor, + }, + { + provide: APP_FILTER, + useClass: GlobalExceptionFilter, + }, + ], }) export class AppModule {} diff --git a/backend/src/attachment/attachment.controller.ts b/backend/src/attachment/attachment.controller.ts index d5a0237..4b50a60 100644 --- a/backend/src/attachment/attachment.controller.ts +++ b/backend/src/attachment/attachment.controller.ts @@ -15,6 +15,7 @@ import { PrismaService } from '../prisma/prisma.service'; import { JwtAuthRestGuard } from '../auth/guards/jwt-auth-rest.guard'; import { CurrentUser } from '../auth/decorators/current-user.decorator'; import { ProjectRole } from 'prisma/generated/enums'; +import { User } from '../user/entities/user.entity'; import { join } from 'path'; import { existsSync } from 'fs'; @@ -31,7 +32,7 @@ export class AttachmentController { async getFile( @Param('id', ParseIntPipe) id: number, @Query('download') download: string, - @CurrentUser() user: any, + @CurrentUser() user: User, @Res() res: Response, ) { // 1. Find the attachment diff --git a/backend/src/attachment/attachment.resolver.ts b/backend/src/attachment/attachment.resolver.ts index d6505c1..670c63f 100644 --- a/backend/src/attachment/attachment.resolver.ts +++ b/backend/src/attachment/attachment.resolver.ts @@ -5,6 +5,7 @@ import { Attachment } from './entities/attachment.entity'; import { FileUpload, GraphQLUpload } from 'graphql-upload-ts'; import { GqlAuthGuard } from 'src/auth/guards/gql-auth.guard'; import { CurrentUser } from 'src/auth/decorators/current-user.decorator'; +import { User } from 'src/user/entities/user.entity'; @Resolver(() => Attachment) export class AttachmentResolver { @@ -17,7 +18,7 @@ export class AttachmentResolver { @Args('relationId', { type: () => Int }) relationId: number, @Args('relationType', { type: () => String }) relationType: 'project' | 'task' | 'comment' | 'message', - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.attachmentService.uploadFile( file, @@ -31,7 +32,7 @@ export class AttachmentResolver { @UseGuards(GqlAuthGuard) async removeAttachment( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.attachmentService.remove(id, user.id); } diff --git a/backend/src/attachment/attachment.service.spec.ts b/backend/src/attachment/attachment.service.spec.ts index 3427fb1..186686a 100644 --- a/backend/src/attachment/attachment.service.spec.ts +++ b/backend/src/attachment/attachment.service.spec.ts @@ -41,7 +41,8 @@ describe('AttachmentService', () => { service = module.get(AttachmentService); prisma = module.get(PrismaService); - projectMemberService = module.get(ProjectMemberService); + projectMemberService = + module.get(ProjectMemberService); }); afterEach(() => { diff --git a/backend/src/attachment/attachment.service.ts b/backend/src/attachment/attachment.service.ts index b8f8074..2b44243 100644 --- a/backend/src/attachment/attachment.service.ts +++ b/backend/src/attachment/attachment.service.ts @@ -1,5 +1,6 @@ import { Injectable, ForbiddenException, Logger } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; +import { Prisma } from '../../prisma/generated/client'; import { ProjectMemberService } from 'src/project-member/project-member.service'; import { ProjectRole } from 'prisma/generated/enums'; import { @@ -84,7 +85,56 @@ export class AttachmentService { } // 3. Proceed with upload - const { createReadStream, filename, mimetype } = file; + const filename = file.filename; + const mimetype = file.mimetype; + + // Stage 1: Validation of filename extension & mimetype against malicious code/executable upload blocks + const lowerFilename = filename.toLowerCase(); + const blockedExtensions = [ + '.html', + '.htm', + '.js', + '.jsx', + '.ts', + '.tsx', + '.exe', + '.bat', + '.cmd', + '.sh', + '.php', + '.pl', + '.py', + '.scr', + '.vbs', + '.msi', + '.jsp', + '.asp', + '.aspx', + '.jar', + ]; + const blockedMimeTypes = [ + 'text/html', + 'application/javascript', + 'application/x-javascript', + 'text/javascript', + 'application/x-msdownload', + 'application/x-sh', + 'application/x-bash', + 'application/x-php', + 'application/x-python', + 'application/x-httpd-php', + ]; + + const hasBlockedExt = blockedExtensions.some((ext) => + lowerFilename.endsWith(ext), + ); + const hasBlockedMime = blockedMimeTypes.includes(mimetype.toLowerCase()); + + if (hasBlockedExt || hasBlockedMime) { + throw new ForbiddenException( + `File upload blocked: File type not permitted for security reasons.`, + ); + } const uploadDir = join(process.cwd(), 'uploads'); if (!existsSync(uploadDir)) { @@ -97,29 +147,53 @@ export class AttachmentService { const relativePath = `/uploads/${uniqueFilename}`; return new Promise((resolve, reject) => { - createReadStream() + file + .createReadStream() .pipe(createWriteStream(filePath)) - .on('finish', async () => { - const stats = statSync(filePath); - - const data: any = { - filename, - path: relativePath, - mimeType: mimetype, - size: stats.size, - }; - - if (relationType === 'project') data.projectId = relationId; - else if (relationType === 'task') data.taskId = relationId; - else if (relationType === 'comment') data.commentId = relationId; - else if (relationType === 'message') data.conversationId = relationId; - - const attachment = await this.prisma.attachment.create({ - data, - }); - resolve(attachment); + .on('finish', () => { + void (async () => { + try { + const stats = statSync(filePath); + + // Stage 2: Size validation (Max 10MB) + const MAX_SIZE = 10 * 1024 * 1024; // 10MB + if (stats.size > MAX_SIZE) { + try { + unlinkSync(filePath); + } catch { + // file already deleted or not writable + } + return reject( + new ForbiddenException( + 'File exceeds the maximum limit of 10MB.', + ), + ); + } + + const data: Prisma.AttachmentUncheckedCreateInput = { + filename, + path: relativePath, + mimeType: mimetype, + size: stats.size, + }; + + if (relationType === 'project') data.projectId = relationId; + else if (relationType === 'task') data.taskId = relationId; + else if (relationType === 'message') + data.conversationId = relationId; + + const attachment = await this.prisma.attachment.create({ + data, + }); + resolve(attachment); + } catch (error) { + reject(error instanceof Error ? error : new Error(String(error))); + } + })(); }) - .on('error', (error: any) => reject(error)); + .on('error', (error: unknown) => + reject(error instanceof Error ? error : new Error(String(error))), + ); }); } diff --git a/backend/src/auth/auth.module.ts b/backend/src/auth/auth.module.ts index efe3fe0..e8a23e8 100644 --- a/backend/src/auth/auth.module.ts +++ b/backend/src/auth/auth.module.ts @@ -17,7 +17,7 @@ import { ProjectPermissionGuard } from './guards/project-permission.guard'; JwtModule.registerAsync({ imports: [ConfigModule], inject: [ConfigService], - useFactory: async (configService: ConfigService) => ({ + useFactory: (configService: ConfigService) => ({ secret: configService.get('JWT_SECRET_KEY'), signOptions: { expiresIn: '1d' }, }), diff --git a/backend/src/auth/auth.service.spec.ts b/backend/src/auth/auth.service.spec.ts index 0fec1b9..599d41b 100644 --- a/backend/src/auth/auth.service.spec.ts +++ b/backend/src/auth/auth.service.spec.ts @@ -31,7 +31,7 @@ describe('AuthService', () => { it('should return an access token and user info', () => { const user = { id: 1, email: 'test@example.com' }; const result = service.login(user); - + expect(result).toEqual({ access_token: 'mockToken', user: user, diff --git a/backend/src/auth/auth.service.ts b/backend/src/auth/auth.service.ts index 192acf2..4ac3112 100644 --- a/backend/src/auth/auth.service.ts +++ b/backend/src/auth/auth.service.ts @@ -5,7 +5,7 @@ import { JwtService } from '@nestjs/jwt'; export class AuthService { constructor(private readonly jwtService: JwtService) {} - login(user: any) { + login(user: { id: number; email: string }) { const payload = { username: user.email, sub: user.id }; return { access_token: this.jwtService.sign(payload), diff --git a/backend/src/auth/decorators/current-user.decorator.ts b/backend/src/auth/decorators/current-user.decorator.ts index bc07e08..2fdeffe 100644 --- a/backend/src/auth/decorators/current-user.decorator.ts +++ b/backend/src/auth/decorators/current-user.decorator.ts @@ -4,6 +4,6 @@ import { GqlExecutionContext } from '@nestjs/graphql'; export const CurrentUser = createParamDecorator( (data: unknown, context: ExecutionContext) => { const ctx = GqlExecutionContext.create(context); - return ctx.getContext().req.user; + return ctx.getContext<{ req: { user: unknown } }>().req.user; }, ); diff --git a/backend/src/auth/guards/gql-auth.guard.ts b/backend/src/auth/guards/gql-auth.guard.ts index 493d0f3..200a682 100644 --- a/backend/src/auth/guards/gql-auth.guard.ts +++ b/backend/src/auth/guards/gql-auth.guard.ts @@ -6,6 +6,6 @@ import { AuthGuard } from '@nestjs/passport'; export class GqlAuthGuard extends AuthGuard('jwt') { getRequest(context: ExecutionContext) { const ctx = GqlExecutionContext.create(context); - return ctx.getContext().req; + return ctx.getContext<{ req: unknown }>().req; } } diff --git a/backend/src/auth/guards/project-access.guard.ts b/backend/src/auth/guards/project-access.guard.ts index ad29e85..8f9045b 100644 --- a/backend/src/auth/guards/project-access.guard.ts +++ b/backend/src/auth/guards/project-access.guard.ts @@ -28,11 +28,16 @@ export class ProjectAccessGuard implements CanActivate { async canActivate(context: ExecutionContext): Promise { const ctx = GqlExecutionContext.create(context); - const request = ctx.getContext().req; - const args = ctx.getArgs(); + const gqlCtx = ctx.getContext<{ req: { user?: { id: number } } }>(); + const request = gqlCtx.req; + const args = ctx.getArgs<{ + id?: number; + projectId?: number; + input?: { projectId?: number }; + }>(); // Get the authenticated user - const user = request.user; + const user = request?.user; if (!user) { throw new ForbiddenException('User not authenticated'); } diff --git a/backend/src/auth/guards/project-permission.guard.ts b/backend/src/auth/guards/project-permission.guard.ts index b159346..8773920 100644 --- a/backend/src/auth/guards/project-permission.guard.ts +++ b/backend/src/auth/guards/project-permission.guard.ts @@ -47,11 +47,17 @@ export class ProjectPermissionGuard implements CanActivate { } const ctx = GqlExecutionContext.create(context); - const request = ctx.getContext().req; - const args = ctx.getArgs(); + const gqlCtx = ctx.getContext<{ req: { user?: { id: number } } }>(); + const request = gqlCtx.req; + const args = ctx.getArgs<{ + id?: number; + projectId?: number; + input?: { projectId?: number }; + updateProjectInput?: { id?: number }; + }>(); // Get the authenticated user - const user = request.user; + const user = request?.user; if (!user) { throw new ForbiddenException('User not authenticated'); } @@ -68,16 +74,11 @@ export class ProjectPermissionGuard implements CanActivate { } // Check if user has one of the required roles - try { - await this.projectMemberService.checkPermission( - user.id, - projectId, - requiredRoles, - ); - return true; - } catch (error) { - // checkPermission throws ForbiddenException if user doesn't have permission - throw error; - } + await this.projectMemberService.checkPermission( + user.id, + projectId, + requiredRoles, + ); + return true; } } diff --git a/backend/src/auth/guards/roles.guard.ts b/backend/src/auth/guards/roles.guard.ts index 659c6b1..347d253 100644 --- a/backend/src/auth/guards/roles.guard.ts +++ b/backend/src/auth/guards/roles.guard.ts @@ -24,7 +24,8 @@ export class RolesGuard implements CanActivate { } const ctx = GqlExecutionContext.create(context); - const { user } = ctx.getContext().req; + const gqlCtx = ctx.getContext<{ req: { user?: { role: UserRole } } }>(); + const user = gqlCtx.req?.user; if (!user) { return false; diff --git a/backend/src/auth/guards/ws-jwt.guard.ts b/backend/src/auth/guards/ws-jwt.guard.ts index 04b2fc5..040ee2b 100644 --- a/backend/src/auth/guards/ws-jwt.guard.ts +++ b/backend/src/auth/guards/ws-jwt.guard.ts @@ -24,14 +24,19 @@ export class WsJwtGuard implements CanActivate { throw new UnauthorizedException(); } - const payload = await this.jwtService.verifyAsync(authToken, { + const payload = await this.jwtService.verifyAsync<{ + sub: number; + username: string; + }>(authToken, { secret: this.configService.get('JWT_SECRET_KEY'), }); - // Attach user information to the client - client['user'] = payload; + interface AuthenticatedSocket extends Socket { + user?: { sub: number; username: string }; + } + (client as AuthenticatedSocket).user = payload; return true; - } catch (err) { + } catch { throw new UnauthorizedException(); } } diff --git a/backend/src/auth/strategies/jwt.strategy.ts b/backend/src/auth/strategies/jwt.strategy.ts index 854c836..6d53705 100644 --- a/backend/src/auth/strategies/jwt.strategy.ts +++ b/backend/src/auth/strategies/jwt.strategy.ts @@ -5,6 +5,8 @@ import { UserService } from '../../user/user.service'; import { ConfigService } from '@nestjs/config'; +import { Request } from 'express'; + @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor( @@ -13,10 +15,10 @@ export class JwtStrategy extends PassportStrategy(Strategy) { ) { super({ jwtFromRequest: ExtractJwt.fromExtractors([ - (req: any) => { - let token = null; + (req: Request) => { + let token: string | null = null; if (req && req.cookies) { - token = req.cookies['access_token']; + token = (req.cookies as Record)['access_token']; } return token || ExtractJwt.fromAuthHeaderAsBearerToken()(req); }, @@ -26,7 +28,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) { }); } - async validate(payload: any) { + async validate(payload: { sub: number; username: string }) { const user = await this.userService.findOne(payload.sub); if (!user) { throw new UnauthorizedException(); diff --git a/backend/src/auth/types/context.type.ts b/backend/src/auth/types/context.type.ts new file mode 100644 index 0000000..5ff215d --- /dev/null +++ b/backend/src/auth/types/context.type.ts @@ -0,0 +1,7 @@ +import { Request, Response } from 'express'; +import { User } from '../../user/entities/user.entity'; + +export interface GqlContext { + req: Request & { user?: User }; + res: Response; +} diff --git a/backend/src/chat/chat.gateway.ts b/backend/src/chat/chat.gateway.ts deleted file mode 100644 index afdb64f..0000000 --- a/backend/src/chat/chat.gateway.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { - WebSocketGateway, - WebSocketServer, - SubscribeMessage, - OnGatewayConnection, - OnGatewayDisconnect, - ConnectedSocket, - MessageBody, -} from '@nestjs/websockets'; -import { Server, Socket } from 'socket.io'; -import { ChatService } from './chat.service'; -import { MessageType } from '../../prisma/generated/client'; -import { UseGuards, Logger } from '@nestjs/common'; -import { WsJwtGuard } from '../auth/guards/ws-jwt.guard'; // I'll need to create this - -@WebSocketGateway({ - cors: { - origin: true, - credentials: true, - }, -}) -@UseGuards(WsJwtGuard) -export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { - @WebSocketServer() - server: Server; - - private readonly logger = new Logger(ChatGateway.name); - - constructor(private readonly chatService: ChatService) {} - - async handleConnection(client: Socket) { - this.logger.log(`Client connected: ${client.id}`); - // Authentication logic will be handled by guards or here - } - - handleDisconnect(client: Socket) { - this.logger.log(`Client disconnected: ${client.id}`); - } - - @SubscribeMessage('joinConversation') - handleJoinConversation( - @ConnectedSocket() client: Socket, - @MessageBody() conversationId: number, - ) { - client.join(`conversation_${conversationId}`); - return { event: 'joinedConversation', data: conversationId }; - } - - @SubscribeMessage('sendMessage') - async handleSendMessage( - @ConnectedSocket() client: Socket, - @MessageBody() - data: { - conversationId: number; - senderId: number; - content: string; - type: MessageType; - fileData?: { - url: string; - name: string; - size?: number; - mimeType?: string; - }; - metadata?: any; - attachmentIds?: number[]; - }, - ) { - const message = await this.chatService.saveMessage( - data.conversationId, - data.senderId, - data.content, - data.type, - data.fileData, - data.metadata, - data.attachmentIds, - ); - - this.logger.log(`Message sent: ${message.id}`); - this.logger.log(`Message data: ${JSON.stringify(data)}`); - - this.server - .to(`conversation_${data.conversationId}`) - .emit('newMessage', message); - - return message; - } - - @SubscribeMessage('markAsRead') - async handleMarkAsRead( - @ConnectedSocket() client: Socket, - @MessageBody() - data: { conversationId: number; userId: number }, - ) { - await this.chatService.markAsRead(data.conversationId, data.userId); - - // Notify other participants (optional, useful for read receipts) - this.server - .to(`conversation_${data.conversationId}`) - .emit('readStatusUpdated', { - conversationId: data.conversationId, - userId: data.userId, - }); - } - - @SubscribeMessage('updateMessage') - async handleUpdateMessage( - @ConnectedSocket() client: Socket, - @MessageBody() - data: { - id: number; - conversationId: number; - senderId: number; - content: string; - }, - ) { - const message = await this.chatService.updateMessage( - data.id, - data.senderId, - data.content, - ); - - this.server - .to(`conversation_${data.conversationId}`) - .emit('messageUpdated', message); - - return message; - } - - @SubscribeMessage('deleteMessage') - async handleDeleteMessage( - @ConnectedSocket() client: Socket, - @MessageBody() - data: { id: number; conversationId: number; senderId: number }, - ) { - await this.chatService.deleteMessage(data.id, data.senderId); - - this.server - .to(`conversation_${data.conversationId}`) - .emit('messageDeleted', { - id: data.id, - conversationId: data.conversationId, - }); - - return { id: data.id }; - } -} diff --git a/backend/src/chat/chat.module.ts b/backend/src/chat/chat.module.ts index 863c598..35dc600 100644 --- a/backend/src/chat/chat.module.ts +++ b/backend/src/chat/chat.module.ts @@ -1,13 +1,20 @@ import { Module } from '@nestjs/common'; import { ChatService } from './chat.service'; -import { ChatGateway } from './chat.gateway'; import { ChatResolver } from './chat.resolver'; import { PrismaModule } from '../prisma/prisma.module'; import { JwtModule } from '@nestjs/jwt'; +import { PubSub } from 'graphql-subscriptions'; @Module({ imports: [PrismaModule, JwtModule.register({})], - providers: [ChatService, ChatGateway, ChatResolver], - exports: [ChatService], + providers: [ + ChatService, + ChatResolver, + { + provide: 'PUB_SUB', + useValue: new PubSub(), + }, + ], + exports: [ChatService, 'PUB_SUB'], }) export class ChatModule {} diff --git a/backend/src/chat/chat.resolver.ts b/backend/src/chat/chat.resolver.ts index 3472da7..4074bfd 100644 --- a/backend/src/chat/chat.resolver.ts +++ b/backend/src/chat/chat.resolver.ts @@ -1,22 +1,35 @@ -import { Resolver, Query, Mutation, Args, Int, Context } from '@nestjs/graphql'; +import { + Resolver, + Query, + Mutation, + Subscription, + Args, + Int, + Context, +} from '@nestjs/graphql'; import { ChatService } from './chat.service'; import { Conversation, Message, ConversationParticipant, } from './entities/chat.entity'; -import { UseGuards } from '@nestjs/common'; +import { UseGuards, Inject } from '@nestjs/common'; import { GqlAuthGuard } from '../auth/guards/gql-auth.guard'; -import { ConversationType } from '../../prisma/generated/client'; +import { ConversationType, MessageType } from '../../prisma/generated/client'; +import { GqlContext } from '../auth/types/context.type'; +import { PubSub } from 'graphql-subscriptions'; @Resolver() export class ChatResolver { - constructor(private readonly chatService: ChatService) {} + constructor( + private readonly chatService: ChatService, + @Inject('PUB_SUB') private readonly pubSub: PubSub, + ) {} @Query(() => [Conversation]) @UseGuards(GqlAuthGuard) - async myConversations(@Context() context: any) { - return this.chatService.getUserConversations(context.req.user.id); + async myConversations(@Context() context: GqlContext) { + return this.chatService.getUserConversations(context.req.user!.id); } @Query(() => [Message]) @@ -33,10 +46,10 @@ export class ChatResolver { @UseGuards(GqlAuthGuard) async createDirectConversation( @Args('otherUserId', { type: () => Int }) otherUserId: number, - @Context() context: any, + @Context() context: GqlContext, ) { return this.chatService.findOrCreateDirectConversation( - context.req.user.id, + context.req.user!.id, otherUserId, ); } @@ -47,10 +60,10 @@ export class ChatResolver { @Args('name') name: string, @Args('workspaceId', { type: () => Int }) workspaceId: number, @Args('userIds', { type: () => [Int] }) userIds: number[], - @Context() context: any, + @Context() context: GqlContext, ) { // Ensure the creator is included - const allUserIds = Array.from(new Set([...userIds, context.req.user.id])); + const allUserIds = Array.from(new Set([...userIds, context.req.user!.id])); return this.chatService.createConversation( allUserIds, ConversationType.CHANNEL, @@ -89,29 +102,139 @@ export class ChatResolver { @UseGuards(GqlAuthGuard) async markAsRead( @Args('conversationId', { type: () => Int }) conversationId: number, - @Context() context: any, + @Context() context: GqlContext, ) { - await this.chatService.markAsRead(conversationId, context.req.user.id); + await this.chatService.markAsRead(conversationId, context.req.user!.id); return true; } + @Mutation(() => Message) + @UseGuards(GqlAuthGuard) + async sendMessage( + @Args('conversationId', { type: () => Int }) conversationId: number, + @Args('content') content: string, + @Args('type', { + type: () => MessageType, + nullable: true, + defaultValue: MessageType.TEXT, + }) + type?: MessageType, + @Args('attachmentIds', { type: () => [Int], nullable: true }) + attachmentIds?: number[], + @Args('metadata', { type: () => String, nullable: true }) metadata?: string, + @Context() context?: GqlContext, + ) { + const senderId = context!.req.user!.id; + const message = await this.chatService.saveMessage( + conversationId, + senderId, + content, + type, + undefined, + metadata, + attachmentIds, + ); + + // Publish to subscribers + await this.pubSub.publish('messageSent', { messageSent: message }); + return message; + } + @Mutation(() => Message) @UseGuards(GqlAuthGuard) async updateMessage( @Args('id', { type: () => Int }) id: number, @Args('content') content: string, - @Context() context: any, + @Context() context: GqlContext, ) { - return this.chatService.updateMessage(id, context.req.user.id, content); + const message = await this.chatService.updateMessage( + id, + context.req.user!.id, + content, + ); + + // Publish to subscribers + await this.pubSub.publish('messageUpdated', { messageUpdated: message }); + return message; } @Mutation(() => Boolean) @UseGuards(GqlAuthGuard) async deleteMessage( @Args('id', { type: () => Int }) id: number, - @Context() context: any, + @Context() context: GqlContext, ) { - await this.chatService.deleteMessage(id, context.req.user.id); + const senderId = context.req.user!.id; + const message = await this.chatService.deleteMessage(id, senderId); + + // Publish to subscribers + await this.pubSub.publish('messageDeleted', { + messageDeleted: { id, conversationId: message.conversationId }, + }); return true; } + + // ========================================== + // GraphQL Subscriptions + // ========================================== + + @Subscription(() => Message, { + filter: ( + payload: { messageSent: { conversationId: number } }, + variables: { conversationId: number }, + ) => { + console.log( + 'Subscription Filter payload:', + payload, + 'variables:', + variables, + ); + const isMatch = + payload.messageSent.conversationId === variables.conversationId; + console.log('Subscription Filter isMatch:', isMatch); + return isMatch; + }, + }) + messageSent( + @Args('conversationId', { type: () => Int }) conversationId: number, + ) { + void conversationId; + return this.pubSub.asyncIterableIterator('messageSent'); + } + + @Subscription(() => Message, { + filter: ( + payload: { messageUpdated: { conversationId: number } }, + variables: { conversationId: number }, + ) => { + const isMatch = + payload.messageUpdated.conversationId === variables.conversationId; + return isMatch; + }, + }) + messageUpdated( + @Args('conversationId', { type: () => Int }) conversationId: number, + ) { + void conversationId; + return this.pubSub.asyncIterableIterator('messageUpdated'); + } + + @Subscription(() => Int, { + filter: ( + payload: { messageDeleted: { conversationId: number } }, + variables: { conversationId: number }, + ) => { + const isMatch = + payload.messageDeleted.conversationId === variables.conversationId; + return isMatch; + }, + resolve: (payload: { messageDeleted: { id: number } }) => + payload.messageDeleted.id, + }) + messageDeleted( + @Args('conversationId', { type: () => Int }) conversationId: number, + ) { + void conversationId; + return this.pubSub.asyncIterableIterator('messageDeleted'); + } } diff --git a/backend/src/chat/chat.service.ts b/backend/src/chat/chat.service.ts index 5d17b14..7da8ebf 100644 --- a/backend/src/chat/chat.service.ts +++ b/backend/src/chat/chat.service.ts @@ -1,8 +1,13 @@ import { Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; -import { ConversationType, MessageType } from '../../prisma/generated/client'; +import { + ConversationType, + MessageType, + Prisma, +} from '../../prisma/generated/client'; import { getLinkPreview } from 'link-preview-js'; import { Logger } from '@nestjs/common'; +import { sanitizeString } from '../common/decorators/sanitized-string.decorator'; @Injectable() export class ChatService { @@ -63,7 +68,7 @@ export class ChatService { async saveMessage( conversationId: number, senderId: number, - content: string, + rawContent: string, type: MessageType = MessageType.TEXT, fileData?: { url: string; @@ -71,10 +76,12 @@ export class ChatService { size?: number; mimeType?: string; }, - metadata?: any, + metadata?: Prisma.InputJsonValue, attachmentIds?: number[], ) { - let linkPreviewData: any = null; + // Sanitize message content (WebSocket messages bypass DTO validation) + const content = sanitizeString(rawContent); + let linkPreviewData: Prisma.InputJsonValue | null = null; // Link preview only for TEXT messages if (type === MessageType.TEXT) { @@ -83,13 +90,20 @@ export class ChatService { if (matches && matches.length > 0) { try { - const preview: any = await getLinkPreview(matches[0], { + const preview = (await getLinkPreview(matches[0], { followRedirects: 'follow', - }); + })) as { + url?: string; + title?: string; + description?: string; + images?: string[]; + favicons?: string[]; + siteName?: string; + }; if (preview && preview.title) { linkPreviewData = { - url: preview.url, + url: preview.url || '', title: preview.title, description: preview.description || '', image: preview.images?.[0] || preview.favicons?.[0] || '', @@ -97,9 +111,10 @@ export class ChatService { favicons: preview.favicons?.[0] || '', }; } - } catch (error) { + } catch (error: unknown) { + const errMsg = error instanceof Error ? error.message : String(error); this.logger.error( - `Failed to fetch link preview for ${matches[0]}: ${error.message}`, + `Failed to fetch link preview for ${matches[0]}: ${errMsg}`, ); } } @@ -115,8 +130,8 @@ export class ChatService { fileName: fileData?.name, fileSize: fileData?.size, mimeType: fileData?.mimeType, - metadata: metadata ? (metadata as any) : undefined, - linkPreview: linkPreviewData as any, + metadata: metadata !== undefined ? metadata : undefined, + linkPreview: linkPreviewData !== null ? linkPreviewData : undefined, attachments: attachmentIds ? { connect: attachmentIds.map((id) => ({ id })), @@ -235,7 +250,9 @@ export class ChatService { }); } - async updateMessage(id: number, senderId: number, content: string) { + async updateMessage(id: number, senderId: number, rawContent: string) { + // Sanitize message content (WebSocket messages bypass DTO validation) + const content = sanitizeString(rawContent); const message = await this.prisma.message.findUnique({ where: { id }, }); diff --git a/backend/src/comment/comment.resolver.spec.ts b/backend/src/comment/comment.resolver.spec.ts index cafad9f..5be31e0 100644 --- a/backend/src/comment/comment.resolver.spec.ts +++ b/backend/src/comment/comment.resolver.spec.ts @@ -51,8 +51,8 @@ describe('CommentResolver', () => { const user = { id: 1 }; mockService.create.mockResolvedValue({ id: 1, ...input }); - await resolver.createComment(input as any, user); - + await resolver.createComment(input as any, user as any); + expect(mockService.create).toHaveBeenCalledWith(input, user.id); }); }); diff --git a/backend/src/comment/comment.resolver.ts b/backend/src/comment/comment.resolver.ts index 69c588e..5f01bcd 100644 --- a/backend/src/comment/comment.resolver.ts +++ b/backend/src/comment/comment.resolver.ts @@ -28,14 +28,14 @@ export class CommentResolver { @UseGuards(GqlAuthGuard) createComment( @Args('createCommentInput') createCommentInput: CreateCommentInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.commentService.create(createCommentInput, user.id); } @Query(() => [Comment], { name: 'comments' }) @UseGuards(GqlAuthGuard) - findAll(@CurrentUser() user: any) { + findAll(@CurrentUser() user: User) { return this.commentService.findAll(user.id); } @@ -43,7 +43,7 @@ export class CommentResolver { @UseGuards(GqlAuthGuard) findOne( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.commentService.findOne(id, user.id); } @@ -52,7 +52,7 @@ export class CommentResolver { @UseGuards(GqlAuthGuard) updateComment( @Args('updateCommentInput') updateCommentInput: UpdateCommentInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.commentService.update( updateCommentInput.id, @@ -65,7 +65,7 @@ export class CommentResolver { @UseGuards(GqlAuthGuard) removeComment( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.commentService.remove(id, user.id); } @@ -79,14 +79,14 @@ export class CommentResolver { @ResolveField(() => [Comment], { nullable: 'items' }) @UseGuards(GqlAuthGuard) - replies(@Parent() comment: Comment, @CurrentUser() user: any) { + replies(@Parent() comment: Comment, @CurrentUser() user: User) { const { id } = comment; return this.commentService.findByParentId(id, user.id); } @ResolveField(() => Comment, { nullable: true }) @UseGuards(GqlAuthGuard) - parent(@Parent() comment: Comment, @CurrentUser() user: any) { + parent(@Parent() comment: Comment, @CurrentUser() user: User) { const { parentId } = comment; if (!parentId) return null; return this.commentService.findOne(parentId, user.id); diff --git a/backend/src/comment/comment.service.spec.ts b/backend/src/comment/comment.service.spec.ts index efac6d0..742ec0b 100644 --- a/backend/src/comment/comment.service.spec.ts +++ b/backend/src/comment/comment.service.spec.ts @@ -38,7 +38,8 @@ describe('CommentService', () => { service = module.get(CommentService); prisma = module.get(PrismaService); - projectMemberService = module.get(ProjectMemberService); + projectMemberService = + module.get(ProjectMemberService); }); afterEach(() => { @@ -56,7 +57,7 @@ describe('CommentService', () => { mockPrisma.comment.create.mockResolvedValue({ id: 1, ...input }); const result = await service.create(input as any, 1); - + expect(result).toBeDefined(); expect(mockPrisma.comment.create).toHaveBeenCalled(); }); diff --git a/backend/src/comment/comment.service.ts b/backend/src/comment/comment.service.ts index 8f9637d..c3c4686 100644 --- a/backend/src/comment/comment.service.ts +++ b/backend/src/comment/comment.service.ts @@ -55,14 +55,15 @@ export class CommentService { return this.prisma.comment.findMany({ where: { projectId: { in: projectIds }, + deletedAt: null, }, include: { user: true, project: true, task: true, parent: true }, }); } async findOne(id: number, userId: number) { - const comment = await this.prisma.comment.findUnique({ - where: { id }, + const comment = await this.prisma.comment.findFirst({ + where: { id, deletedAt: null }, include: { user: true, project: true, task: true, parent: true }, }); @@ -118,15 +119,16 @@ export class CommentService { ProjectRole.ADMIN, ]); - return this.prisma.comment.delete({ + return this.prisma.comment.update({ where: { id }, + data: { deletedAt: new Date() }, }); } async findByParentId(parentId: number, userId: number) { // This is used for tree structure, should also verify access - const parentComment = await this.prisma.comment.findUnique({ - where: { id: parentId }, + const parentComment = await this.prisma.comment.findFirst({ + where: { id: parentId, deletedAt: null }, select: { projectId: true }, }); @@ -138,7 +140,7 @@ export class CommentService { } return this.prisma.comment.findMany({ - where: { parentId }, + where: { parentId, deletedAt: null }, include: { user: true, project: true, task: true, parent: true }, }); } diff --git a/backend/src/comment/dto/create-comment.input.ts b/backend/src/comment/dto/create-comment.input.ts index d5f249c..b9d9805 100644 --- a/backend/src/comment/dto/create-comment.input.ts +++ b/backend/src/comment/dto/create-comment.input.ts @@ -1,8 +1,10 @@ import { InputType, Int, Field } from '@nestjs/graphql'; +import { IsSanitizedString } from '../../common/decorators/sanitized-string.decorator'; @InputType() export class CreateCommentInput { @Field() + @IsSanitizedString() content: string; @Field(() => Int) diff --git a/backend/src/common/decorators/sanitized-string.decorator.ts b/backend/src/common/decorators/sanitized-string.decorator.ts new file mode 100644 index 0000000..31e03a9 --- /dev/null +++ b/backend/src/common/decorators/sanitized-string.decorator.ts @@ -0,0 +1,59 @@ +import { registerDecorator, ValidationOptions } from 'class-validator'; +import { filterXSS } from 'xss'; + +/** + * Custom validator decorator that sanitizes string inputs against XSS attacks. + * Uses the `xss` library which works in Node.js (unlike DOMPurify which requires a DOM). + * + * When applied to a DTO field, it: + * 1. Validates the value is a string + * 2. Checks if the string contains potentially dangerous XSS content + * 3. Rejects the value if XSS content is detected + * + * @example + * ```typescript + * @Field() + * @IsSanitizedString() + * name: string; + * ``` + */ +export function IsSanitizedString(validationOptions?: ValidationOptions) { + return function (object: object, propertyName: string) { + registerDecorator({ + name: 'isSanitizedString', + target: object.constructor, + propertyName: propertyName, + constraints: [], + options: { + message: `${propertyName} contains potentially unsafe content`, + ...validationOptions, + }, + validator: { + validate(value: unknown) { + if (value === null || value === undefined) { + return true; // Let @IsOptional() or @IsNotEmpty() handle null/undefined + } + + if (typeof value !== 'string') { + return false; + } + + // Sanitize the value using xss + const sanitized = filterXSS(value); + + // If sanitization changed the value, it contained potentially dangerous content + return sanitized === value; + }, + }, + }); + }; +} + +/** + * Utility function to sanitize a string value. + * Can be used in services/resolvers when you need to sanitize + * values that don't go through DTO validation (e.g. WebSocket messages). + */ +export function sanitizeString(value: string): string { + return filterXSS(value); +} diff --git a/backend/src/common/filters/global-exception.filter.ts b/backend/src/common/filters/global-exception.filter.ts new file mode 100644 index 0000000..ea08e53 --- /dev/null +++ b/backend/src/common/filters/global-exception.filter.ts @@ -0,0 +1,98 @@ +import { + ExceptionFilter, + Catch, + ArgumentsHost, + HttpException, + HttpStatus, + Logger, +} from '@nestjs/common'; +import { Request, Response } from 'express'; +import { GqlContextType } from '@nestjs/graphql'; + +interface SentryPlaceholder { + init?: (options: { dsn: string }) => void; + captureException?: (exception: unknown) => void; +} + +@Catch() +export class GlobalExceptionFilter implements ExceptionFilter { + private readonly logger = new Logger('ExceptionFilter'); + private isSentryInitialized = false; + + constructor() { + const dsn = process.env.SENTRY_DSN; + if (dsn) { + void this.initSentry(dsn); + } else { + this.logger.log( + 'No SENTRY_DSN found in environment. Sentry is disabled.', + ); + } + } + + private async initSentry(dsn: string) { + try { + const packageName = '@sentry/node'; + const sentry = (await import(packageName)) as SentryPlaceholder; + if (sentry.init) { + sentry.init({ dsn }); + } + this.isSentryInitialized = true; + this.logger.log('Sentry successfully initialized with DSN.'); + } catch { + this.logger.warn( + 'Sentry package (@sentry/node) not installed, falling back to local logging.', + ); + } + } + + catch(exception: unknown, host: ArgumentsHost) { + const status = + exception instanceof HttpException + ? exception.getStatus() + : HttpStatus.INTERNAL_SERVER_ERROR; + + const message = + exception instanceof Error ? exception.message : 'Internal server error'; + + // Log the error locally + this.logger.error( + `Unhandled Exception: ${message}`, + exception instanceof Error ? exception.stack : undefined, + ); + + // Send to Sentry if initialized + if (this.isSentryInitialized) { + void (async () => { + try { + const packageName = '@sentry/node'; + const sentry = (await import(packageName)) as SentryPlaceholder; + if (sentry.captureException) { + sentry.captureException(exception); + } + } catch { + // Safe fallback + } + })(); + } + + const ctxType = host.getType(); + + if (ctxType === 'graphql') { + // In GraphQL, NestJS handles resolver errors, but we can return the error formatted + return exception; + } else { + // Rest HTTP Response + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + const request = ctx.getRequest(); + + response.status(status).json({ + statusCode: status, + timestamp: new Date().toISOString(), + path: request.url, + message, + }); + } + } +} diff --git a/backend/src/common/interceptors/logging.interceptor.ts b/backend/src/common/interceptors/logging.interceptor.ts new file mode 100644 index 0000000..a58ab05 --- /dev/null +++ b/backend/src/common/interceptors/logging.interceptor.ts @@ -0,0 +1,120 @@ +import { + Injectable, + NestInterceptor, + ExecutionContext, + CallHandler, + Logger, +} from '@nestjs/common'; +import { GqlContextType, GqlExecutionContext } from '@nestjs/graphql'; +import { Observable } from 'rxjs'; +import { tap } from 'rxjs/operators'; +import { randomUUID } from 'crypto'; +import { GraphQLResolveInfo } from 'graphql'; +import { Request, Response } from 'express'; + +@Injectable() +export class LoggingInterceptor implements NestInterceptor { + private readonly logger = new Logger('IncomingRequest'); + + intercept(context: ExecutionContext, next: CallHandler): Observable { + const startTime = Date.now(); + const requestId = randomUUID(); + + const ctxType = context.getType(); + + if (ctxType === 'graphql') { + // GraphQL Request Logging + const gqlCtx = GqlExecutionContext.create(context); + const info = gqlCtx.getInfo(); + const req = gqlCtx.getContext<{ + req?: { + ip?: string; + headers?: Record; + user?: { id: number }; + }; + }>().req; + + const parentType = info.parentType.name; + const fieldName = info.fieldName; + const operation = info.operation.operation; + + const forwardedFor = req?.headers?.['x-forwarded-for']; + const clientIp = + req?.ip || + (Array.isArray(forwardedFor) ? forwardedFor[0] : forwardedFor) || + 'unknown'; + + const userAgentHeader = req?.headers?.['user-agent']; + const userAgent = + (Array.isArray(userAgentHeader) + ? userAgentHeader[0] + : userAgentHeader) || 'unknown'; + + const userId = req?.user?.id ? `User(${req.user.id})` : 'Guest'; + + this.logger.log( + `[${requestId}] 🚀 GraphQL ${operation.toUpperCase()} | ${parentType}.${fieldName} | Caller: ${userId} | IP: ${clientIp} | UA: ${userAgent}`, + ); + + return next.handle().pipe( + tap({ + next: () => { + const duration = Date.now() - startTime; + this.logger.log( + `[${requestId}] ✅ GraphQL ${parentType}.${fieldName} completed in ${duration}ms`, + ); + }, + error: (err: unknown) => { + const duration = Date.now() - startTime; + const errMsg = err instanceof Error ? err.message : String(err); + this.logger.error( + `[${requestId}] ❌ GraphQL ${parentType}.${fieldName} failed in ${duration}ms | Error: ${errMsg}`, + ); + }, + }), + ); + } else { + // HTTP Rest Request Logging (e.g., health checks, uploads) + const http = context.switchToHttp(); + const req = http.getRequest(); + const res = http.getResponse(); + + if (!req) return next.handle(); + + const method = req.method; + const url = req.originalUrl || req.url; + + const clientIp = req.ip || req.get('x-forwarded-for') || 'unknown'; + const userAgent = req.get('user-agent') || 'unknown'; + + // Avoid spamming health check logs at info level if undesired, or log them cleanly + const isHealth = url.includes('/health'); + if (!isHealth) { + this.logger.log( + `[${requestId}] 🌐 HTTP ${method} ${url} | IP: ${clientIp} | UA: ${userAgent}`, + ); + } + + return next.handle().pipe( + tap({ + next: () => { + const duration = Date.now() - startTime; + const statusCode = res.statusCode; + if (!isHealth) { + this.logger.log( + `[${requestId}] ✅ HTTP ${method} ${url} returned ${statusCode} in ${duration}ms`, + ); + } + }, + error: (err: unknown) => { + const duration = Date.now() - startTime; + const errMsg = err instanceof Error ? err.message : String(err); + this.logger.error( + `[${requestId}] ❌ HTTP ${method} ${url} failed in ${duration}ms | Error: ${errMsg}`, + ); + }, + }), + ); + } + } +} diff --git a/backend/src/common/validation/depth-limit.validation.spec.ts b/backend/src/common/validation/depth-limit.validation.spec.ts new file mode 100644 index 0000000..8ebfd05 --- /dev/null +++ b/backend/src/common/validation/depth-limit.validation.spec.ts @@ -0,0 +1,71 @@ +import { parse, validate, buildSchema, ValidationRule } from 'graphql'; +import { depthLimitRule } from './depth-limit.validation'; + +describe('depthLimitRule', () => { + const schema = buildSchema(` + type User { + id: ID! + name: String! + projects: [Project!]! + } + + type Project { + id: ID! + name: String! + tasks: [Task!]! + } + + type Task { + id: ID! + title: String! + assignee: User! + } + + type Query { + me: User! + } + `); + + const runValidation = (queryStr: string, rules: ValidationRule[]) => { + const document = parse(queryStr); + return validate(schema, document, rules); + }; + + it('should pass for queries within depth limit', () => { + const query = ` + query { + me { + name + projects { + name + } + } + } + `; + + const errors = runValidation(query, [depthLimitRule(4)]); + expect(errors).toHaveLength(0); + }); + + it('should fail for queries exceeding depth limit', () => { + const query = ` + query { + me { + projects { + tasks { + assignee { + name + } + } + } + } + } + `; + + const errors = runValidation(query, [depthLimitRule(3)]); + expect(errors.length).toBeGreaterThanOrEqual(1); + expect(errors[0].message).toContain( + 'Query exceeds maximum allowed depth of 3', + ); + }); +}); diff --git a/backend/src/common/validation/depth-limit.validation.ts b/backend/src/common/validation/depth-limit.validation.ts new file mode 100644 index 0000000..49f3eb6 --- /dev/null +++ b/backend/src/common/validation/depth-limit.validation.ts @@ -0,0 +1,30 @@ +import { ValidationContext, GraphQLError, ASTVisitor } from 'graphql'; + +/** + * Custom zero-dependency GraphQL query depth limiting validation rule. + * Prevents Denial of Service (DoS) attacks from deeply nested relational queries. + */ +export function depthLimitRule(maxDepth: number) { + return (context: ValidationContext): ASTVisitor => { + let depth = 0; + + return { + SelectionSet: { + enter(node) { + depth++; + if (depth > maxDepth) { + context.reportError( + new GraphQLError( + `Query exceeds maximum allowed depth of ${maxDepth}.`, + { nodes: [node] }, + ), + ); + } + }, + leave() { + depth--; + }, + }, + }; + }; +} diff --git a/backend/src/config/env.validation.spec.ts b/backend/src/config/env.validation.spec.ts new file mode 100644 index 0000000..74a9f2c --- /dev/null +++ b/backend/src/config/env.validation.spec.ts @@ -0,0 +1,42 @@ +import 'reflect-metadata'; +import { validate } from './env.validation'; + +describe('Environment Variable Validation', () => { + it('should pass and convert valid config', () => { + const validConfig = { + DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/mydb', + JWT_SECRET_KEY: 'supersecretkey', + PORT: '3000', + NODE_ENV: 'development', + }; + + const result = validate(validConfig); + + expect(result.DATABASE_URL).toBe(validConfig.DATABASE_URL); + expect(result.JWT_SECRET_KEY).toBe(validConfig.JWT_SECRET_KEY); + expect(result.PORT).toBe(3000); // Converted implicitly to number + expect(result.NODE_ENV).toBe('development'); + }); + + it('should throw an error if critical variables are missing', () => { + const invalidConfig = { + PORT: '3000', + }; + + expect(() => validate(invalidConfig)).toThrow( + /Missing or invalid required environment variables/, + ); + }); + + it('should throw an error if fields have invalid types', () => { + const invalidConfig = { + DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/mydb', + JWT_SECRET_KEY: 'supersecretkey', + NODE_ENV: 'invalid-env-name', // Should be development, production, or test + }; + + expect(() => validate(invalidConfig)).toThrow( + /Missing or invalid required environment variables/, + ); + }); +}); diff --git a/backend/src/config/env.validation.ts b/backend/src/config/env.validation.ts new file mode 100644 index 0000000..823a09a --- /dev/null +++ b/backend/src/config/env.validation.ts @@ -0,0 +1,65 @@ +import { plainToInstance } from 'class-transformer'; +import { + IsEnum, + IsNumber, + IsOptional, + IsString, + validateSync, +} from 'class-validator'; + +enum Environment { + Development = 'development', + Production = 'production', + Test = 'test', + Provision = 'provision', +} + +class EnvironmentVariables { + @IsEnum(Environment) + @IsOptional() + NODE_ENV: Environment = Environment.Development; + + @IsNumber() + @IsOptional() + PORT: number = 3000; + + @IsString() + DATABASE_URL: string; + + @IsString() + JWT_SECRET_KEY: string; + + @IsString() + @IsOptional() + FRONTEND_URL?: string; +} + +export function validate(config: Record) { + const validatedConfig = plainToInstance(EnvironmentVariables, config, { + enableImplicitConversion: true, + }); + + const errors = validateSync(validatedConfig, { + skipMissingProperties: false, + }); + + if (errors.length > 0) { + const errorDetails = errors + .map((err) => { + const constraints = err.constraints + ? Object.values(err.constraints).join(', ') + : 'unknown constraint'; + return ` - ${err.property}: ${constraints}`; + }) + .join('\n'); + + throw new Error( + `\n========================================================================\n` + + `🔥 ENV STARTUP ERROR: Missing or invalid required environment variables!\n` + + `========================================================================\n` + + `${errorDetails}\n` + + `========================================================================\n`, + ); + } + return validatedConfig; +} diff --git a/backend/src/dashboard/dashboard.service.ts b/backend/src/dashboard/dashboard.service.ts index 51689f3..22ebed7 100644 --- a/backend/src/dashboard/dashboard.service.ts +++ b/backend/src/dashboard/dashboard.service.ts @@ -1,44 +1,449 @@ import { Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; +import { + DashboardStats, + TasksByStageItem, + TasksByPriorityItem, + ProjectProgressItem, + TimelineEntry, + RecentActivityItem, + UpcomingDeadlineItem, + TimesheetSummary, +} from './dto/dashboard-stats.type'; @Injectable() export class DashboardService { - constructor(private prisma: PrismaService) {} + constructor(private readonly prisma: PrismaService) {} - async getStats(userId: number, workspaceId?: number) { - // If workspaceId is provided, we filter everything by it - const whereWorkspace = workspaceId ? { workspaceId } : {}; + async getStats( + userId: number, + workspaceId?: number, + ): Promise { + const now = new Date(); + const startOfWeek = new Date(now); + startOfWeek.setDate(now.getDate() - now.getDay()); + startOfWeek.setHours(0, 0, 0, 0); - // Total users in the system or members of the workspace - const totalUsers = workspaceId - ? await this.prisma.workspaceMember.count({ where: { workspaceId } }) - : await this.prisma.user.count(); + const startOfLastWeek = new Date(startOfWeek); + startOfLastWeek.setDate(startOfWeek.getDate() - 7); - const activeProjects = await this.prisma.project.count({ + const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); + + const thirtyDaysAgo = new Date(now); + thirtyDaysAgo.setDate(now.getDate() - 29); + + const workspaceFilter = workspaceId ? { workspaceId } : {}; + const projectFilter = workspaceId ? { project: { workspaceId } } : {}; + + const [ + totalUsers, + activeProjects, + pendingTasks, + completedThisWeek, + overdueTasks, + ] = await Promise.all([ + workspaceId + ? this.prisma.workspaceMember.count({ where: { workspaceId } }) + : this.prisma.user.count(), + + this.prisma.project.count({ + where: { + ...workspaceFilter, + archivedAt: null, + members: { some: { userId } }, + }, + }), + + this.prisma.task.count({ + where: { + userId, + deletedAt: null, + completedAt: null, + ...projectFilter, + stage: { isCompleted: false }, + }, + }), + + this.prisma.task.count({ + where: { + ...projectFilter, + deletedAt: null, + completedAt: { gte: startOfWeek }, + stage: { isCompleted: true }, + }, + }), + + this.prisma.task.count({ + where: { + userId, + deletedAt: null, + completedAt: null, + dueDate: { lt: now }, + stage: { isCompleted: false }, + }, + }), + ]); + + const [ + tasksByStage, + tasksByPriority, + projectsProgress, + activityTimeline, + upcomingDeadlines, + recentTasks, + recentComments, + timesheetSummary, + ] = await Promise.all([ + this._getTasksByStage(userId, workspaceId), + this._getTasksByPriority(userId, workspaceId), + this._getProjectsProgress(userId, workspaceId), + this._getActivityTimeline(workspaceId, thirtyDaysAgo), + this._getUpcomingDeadlines(userId, workspaceId, now), + this._getRecentTaskActivity(workspaceId), + this._getRecentCommentActivity(workspaceId), + this._getTimesheetSummary( + userId, + workspaceId, + startOfWeek, + startOfLastWeek, + startOfMonth, + ), + ]); + + const recentActivity = this._mergeRecentActivity( + recentTasks, + recentComments, + ); + + return { + totalUsers, + activeProjects, + pendingTasks, + completedThisWeek, + overdueTasks, + tasksByStage, + tasksByPriority, + projectsProgress, + activityTimeline, + upcomingDeadlines, + recentActivity, + timesheetSummary, + }; + } + + // ── Private helpers ───────────────────────────────────────────────────────── + + private async _getTasksByStage( + userId: number, + workspaceId?: number, + ): Promise { + const tasks = await this.prisma.task.findMany({ where: { - ...whereWorkspace, - members: { - some: { - userId: userId, - }, + userId, + deletedAt: null, + ...(workspaceId ? { project: { workspaceId } } : {}), + stage: { isNot: null }, + }, + select: { + stage: { + select: { title: true, color: true }, }, }, }); - const pendingTasks = await this.prisma.task.count({ + const map = new Map(); + + for (const t of tasks) { + if (!t.stage) continue; + const key = t.stage.title; + const existing = map.get(key); + if (existing) { + existing.count++; + } else { + map.set(key, { count: 1, color: t.stage.color }); + } + } + + const noStageCount = await this.prisma.task.count({ where: { - userId: userId, - project: workspaceId ? { workspaceId } : undefined, - stage: { - isCompleted: false, - }, + userId, + deletedAt: null, + stageId: null, + ...(workspaceId ? { project: { workspaceId } } : {}), + }, + }); + + const result: TasksByStageItem[] = Array.from(map.entries()).map( + ([stage, { count, color }]) => ({ stage, count, color }), + ); + + if (noStageCount > 0) { + result.push({ stage: 'No Stage', count: noStageCount, color: '#6b7280' }); + } + + return result; + } + + private async _getTasksByPriority( + userId: number, + workspaceId?: number, + ): Promise { + const priorities = ['LOW', 'MEDIUM', 'HIGH', 'URGENT'] as const; + + const counts = await Promise.all( + priorities.map((priority) => + this.prisma.task.count({ + where: { + userId, + deletedAt: null, + priority, + ...(workspaceId ? { project: { workspaceId } } : {}), + }, + }), + ), + ); + + return priorities.map((priority, i) => ({ priority, count: counts[i] })); + } + + private async _getProjectsProgress( + userId: number, + workspaceId?: number, + ): Promise { + const projects = await this.prisma.project.findMany({ + where: { + archivedAt: null, + ...(workspaceId ? { workspaceId } : {}), + members: { some: { userId } }, + }, + select: { + id: true, + name: true, + progress: true, + budgetPlanned: true, + budgetActual: true, + }, + orderBy: { updatedAt: 'desc' }, + take: 8, + }); + + return projects.map((p) => ({ + id: p.id, + projectName: p.name, + progress: p.progress, + budgetPlanned: p.budgetPlanned, + budgetActual: p.budgetActual, + })); + } + + private async _getActivityTimeline( + workspaceId: number | undefined, + from: Date, + ): Promise { + const tasks = await this.prisma.task.findMany({ + where: { + deletedAt: null, + createdAt: { gte: from }, + ...(workspaceId ? { project: { workspaceId } } : {}), + }, + select: { createdAt: true, completedAt: true }, + }); + + const timesheets = await this.prisma.timesheet.findMany({ + where: { + date: { gte: from }, + ...(workspaceId ? { project: { workspaceId } } : {}), + }, + select: { date: true, timeSpent: true }, + }); + + // Build map for last 30 days + const dayMap = new Map< + string, + { tasksCreated: number; tasksCompleted: number; hoursLogged: number } + >(); + + for (let i = 0; i < 30; i++) { + const d = new Date(from); + d.setDate(from.getDate() + i); + const key = d.toISOString().slice(0, 10); + dayMap.set(key, { tasksCreated: 0, tasksCompleted: 0, hoursLogged: 0 }); + } + + for (const t of tasks) { + const createdKey = t.createdAt.toISOString().slice(0, 10); + const entry = dayMap.get(createdKey); + if (entry) entry.tasksCreated++; + + if (t.completedAt) { + const completedKey = t.completedAt.toISOString().slice(0, 10); + const completedEntry = dayMap.get(completedKey); + if (completedEntry) completedEntry.tasksCompleted++; + } + } + + for (const ts of timesheets) { + const key = ts.date.toISOString().slice(0, 10); + const entry = dayMap.get(key); + if (entry) entry.hoursLogged += ts.timeSpent; + } + + return Array.from(dayMap.entries()).map(([date, data]) => ({ + date, + ...data, + })); + } + + private async _getUpcomingDeadlines( + userId: number, + workspaceId: number | undefined, + now: Date, + ): Promise { + const sevenDaysLater = new Date(now); + sevenDaysLater.setDate(now.getDate() + 7); + + const tasks = await this.prisma.task.findMany({ + where: { + userId, + deletedAt: null, + completedAt: null, + dueDate: { gte: now, lte: sevenDaysLater }, + ...(workspaceId ? { project: { workspaceId } } : {}), }, + select: { + id: true, + title: true, + dueDate: true, + priority: true, + project: { select: { name: true } }, + stage: { select: { title: true, color: true } }, + }, + orderBy: { dueDate: 'asc' }, + take: 10, }); + return tasks.map((t) => ({ + id: t.id, + title: t.title, + dueDate: t.dueDate!.toISOString(), + priority: t.priority, + projectName: t.project.name, + stageName: t.stage?.title, + stageColor: t.stage?.color, + })); + } + + private async _getRecentTaskActivity(workspaceId?: number) { + return this.prisma.task.findMany({ + where: { + deletedAt: null, + ...(workspaceId ? { project: { workspaceId } } : {}), + }, + select: { + id: true, + title: true, + createdAt: true, + user: { select: { name: true } }, + project: { select: { name: true } }, + }, + orderBy: { createdAt: 'desc' }, + take: 5, + }); + } + + private async _getRecentCommentActivity(workspaceId?: number) { + return this.prisma.comment.findMany({ + where: { + deletedAt: null, + ...(workspaceId + ? { + OR: [ + { project: { workspaceId } }, + { task: { project: { workspaceId } } }, + ], + } + : {}), + }, + select: { + id: true, + content: true, + createdAt: true, + user: { select: { name: true } }, + task: { select: { title: true } }, + project: { select: { name: true } }, + }, + orderBy: { createdAt: 'desc' }, + take: 5, + }); + } + + private _mergeRecentActivity( + tasks: Awaited>, + comments: Awaited< + ReturnType + >, + ): RecentActivityItem[] { + const taskItems: RecentActivityItem[] = tasks.map((t) => ({ + id: t.id, + type: 'TASK_CREATED', + title: t.title, + userName: t.user.name, + timestamp: t.createdAt.toISOString(), + projectName: t.project.name, + })); + + const commentItems: RecentActivityItem[] = comments.map((c) => ({ + id: c.id, + type: 'COMMENT_ADDED', + title: c.task?.title ?? c.project?.name ?? 'Unknown', + userName: c.user.name, + timestamp: c.createdAt.toISOString(), + projectName: c.project?.name ?? c.task?.title, + })); + + return [...taskItems, ...commentItems] + .sort( + (a, b) => + new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(), + ) + .slice(0, 10); + } + + private async _getTimesheetSummary( + userId: number, + workspaceId: number | undefined, + startOfWeek: Date, + startOfLastWeek: Date, + startOfMonth: Date, + ): Promise { + const workspaceFilter = workspaceId ? { project: { workspaceId } } : {}; + + const [thisWeekTs, lastWeekTs, thisMonthTs] = await Promise.all([ + this.prisma.timesheet.findMany({ + where: { userId, date: { gte: startOfWeek }, ...workspaceFilter }, + select: { timeSpent: true }, + }), + this.prisma.timesheet.findMany({ + where: { + userId, + date: { gte: startOfLastWeek, lt: startOfWeek }, + ...workspaceFilter, + }, + select: { timeSpent: true }, + }), + this.prisma.timesheet.findMany({ + where: { userId, date: { gte: startOfMonth }, ...workspaceFilter }, + select: { timeSpent: true }, + }), + ]); + + const sum = (ts: { timeSpent: number }[]) => + ts.reduce((acc, t) => acc + t.timeSpent, 0); + return { - totalUsers, - activeProjects, - pendingTasks, + thisWeek: sum(thisWeekTs), + lastWeek: sum(lastWeekTs), + thisMonth: sum(thisMonthTs), }; } } diff --git a/backend/src/dashboard/dto/dashboard-stats.type.ts b/backend/src/dashboard/dto/dashboard-stats.type.ts index d95cb3e..cef138b 100644 --- a/backend/src/dashboard/dto/dashboard-stats.type.ts +++ b/backend/src/dashboard/dto/dashboard-stats.type.ts @@ -1,7 +1,120 @@ -import { ObjectType, Field, Int } from '@nestjs/graphql'; +import { ObjectType, Field, Int, Float } from '@nestjs/graphql'; + +@ObjectType() +export class TasksByStageItem { + @Field() + stage: string; + + @Field(() => Int) + count: number; + + @Field() + color: string; +} + +@ObjectType() +export class TasksByPriorityItem { + @Field() + priority: string; + + @Field(() => Int) + count: number; +} + +@ObjectType() +export class ProjectProgressItem { + @Field(() => Int) + id: number; + + @Field() + projectName: string; + + @Field(() => Float) + progress: number; + + @Field(() => Float) + budgetPlanned: number; + + @Field(() => Float) + budgetActual: number; +} + +@ObjectType() +export class TimelineEntry { + @Field() + date: string; + + @Field(() => Int) + tasksCreated: number; + + @Field(() => Int) + tasksCompleted: number; + + @Field(() => Float) + hoursLogged: number; +} + +@ObjectType() +export class RecentActivityItem { + @Field(() => Int) + id: number; + + @Field() + type: string; + + @Field() + title: string; + + @Field() + userName: string; + + @Field() + timestamp: string; + + @Field({ nullable: true }) + projectName?: string; +} + +@ObjectType() +export class UpcomingDeadlineItem { + @Field(() => Int) + id: number; + + @Field() + title: string; + + @Field() + dueDate: string; + + @Field() + priority: string; + + @Field({ nullable: true }) + projectName?: string; + + @Field({ nullable: true }) + stageName?: string; + + @Field({ nullable: true }) + stageColor?: string; +} + +@ObjectType() +export class TimesheetSummary { + @Field(() => Float) + thisWeek: number; + + @Field(() => Float) + lastWeek: number; + + @Field(() => Float) + thisMonth: number; +} @ObjectType() export class DashboardStats { + // ── Core KPIs ────────────────────────────────────────────────────────────── + @Field(() => Int) totalUsers: number; @@ -10,4 +123,35 @@ export class DashboardStats { @Field(() => Int) pendingTasks: number; + + @Field(() => Int) + completedThisWeek: number; + + @Field(() => Int) + overdueTasks: number; + + // ── Charts data ──────────────────────────────────────────────────────────── + + @Field(() => [TasksByStageItem]) + tasksByStage: TasksByStageItem[]; + + @Field(() => [TasksByPriorityItem]) + tasksByPriority: TasksByPriorityItem[]; + + @Field(() => [ProjectProgressItem]) + projectsProgress: ProjectProgressItem[]; + + @Field(() => [TimelineEntry]) + activityTimeline: TimelineEntry[]; + + // ── Widgets ──────────────────────────────────────────────────────────────── + + @Field(() => [UpcomingDeadlineItem]) + upcomingDeadlines: UpcomingDeadlineItem[]; + + @Field(() => [RecentActivityItem]) + recentActivity: RecentActivityItem[]; + + @Field(() => TimesheetSummary) + timesheetSummary: TimesheetSummary; } diff --git a/backend/src/health/health.controller.ts b/backend/src/health/health.controller.ts new file mode 100644 index 0000000..66ee96c --- /dev/null +++ b/backend/src/health/health.controller.ts @@ -0,0 +1,103 @@ +import { Controller, Get, Res, HttpStatus } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { Response } from 'express'; + +interface HealthDetails { + database: { + status: 'up' | 'down' | 'unknown'; + error?: string; + }; + memory: { + status: 'up' | 'degraded'; + heapUsedMB?: number; + heapTotalMB?: number; + warning?: string; + }; +} + +interface HealthStatus { + status: 'up' | 'down' | 'degraded'; + timestamp: string; + uptime: number; + details: HealthDetails; +} + +@Controller('health') +export class HealthController { + constructor(private readonly prisma: PrismaService) {} + + @Get() + async checkHealth(@Res() res: Response) { + const healthStatus: HealthStatus = { + status: 'up', + timestamp: new Date().toISOString(), + uptime: process.uptime(), + details: { + database: { status: 'unknown' }, + memory: { status: 'up' }, + }, + }; + + let isHealthy = true; + + // Check Database Connectivity + try { + await this.prisma.$queryRaw`SELECT 1`; + healthStatus.details.database.status = 'up'; + } catch (error) { + isHealthy = false; + healthStatus.status = 'down'; + healthStatus.details.database = { + status: 'down', + error: error instanceof Error ? error.message : String(error), + }; + } + + // Check Memory Usage + const memoryUsage = process.memoryUsage(); + const heapUsedMB = Math.round(memoryUsage.heapUsed / 1024 / 1024); + const heapTotalMB = Math.round(memoryUsage.heapTotal / 1024 / 1024); + + healthStatus.details.memory = { + status: 'up', + heapUsedMB, + heapTotalMB, + }; + + // If heap size is unreasonably high (e.g. > 1GB), mark as degraded/unhealthy + if (heapUsedMB > 1024) { + isHealthy = false; + healthStatus.status = 'degraded'; + healthStatus.details.memory.status = 'degraded'; + healthStatus.details.memory.warning = 'High memory usage detected'; + } + + if (isHealthy) { + return res.status(HttpStatus.OK).json(healthStatus); + } else { + return res.status(HttpStatus.SERVICE_UNAVAILABLE).json(healthStatus); + } + } + + @Get('liveness') + checkLiveness(@Res() res: Response) { + // Basic liveness probe (checks if container/service is alive/running) + return res + .status(HttpStatus.OK) + .json({ status: 'alive', uptime: process.uptime() }); + } + + @Get('readiness') + async checkReadiness(@Res() res: Response) { + // Readiness probe (checks if app can serve traffic - needs database) + try { + await this.prisma.$queryRaw`SELECT 1`; + return res.status(HttpStatus.OK).json({ status: 'ready' }); + } catch (error) { + return res.status(HttpStatus.SERVICE_UNAVAILABLE).json({ + status: 'not_ready', + error: error instanceof Error ? error.message : String(error), + }); + } + } +} diff --git a/backend/src/health/health.module.ts b/backend/src/health/health.module.ts new file mode 100644 index 0000000..3f7f985 --- /dev/null +++ b/backend/src/health/health.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; +import { PrismaModule } from '../prisma/prisma.module'; + +@Module({ + imports: [PrismaModule], + controllers: [HealthController], +}) +export class HealthModule {} diff --git a/backend/src/main.ts b/backend/src/main.ts index e3c1632..7a90b4d 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -3,14 +3,70 @@ import { AppModule } from './app.module'; import { graphqlUploadExpress } from 'graphql-upload-ts'; import { ValidationPipe } from '@nestjs/common'; import * as cookieParser from 'cookie-parser'; +import helmet from 'helmet'; +import { Request, Response, NextFunction } from 'express'; async function bootstrap() { const app = await NestFactory.create(AppModule, { logger: ['error', 'warn', 'log', 'debug', 'verbose'], }); + + // Security headers with Helmet + app.use( + helmet({ + contentSecurityPolicy: { + directives: { + defaultSrc: ["'self'"], + styleSrc: ["'self'", "'unsafe-inline'"], + scriptSrc: ["'self'"], + imgSrc: ["'self'", 'data:', 'https:'], + }, + }, + crossOriginEmbedderPolicy: false, // Disable for GraphQL playground + }), + ); + app.use(cookieParser()); + + // Origin validation middleware (replaces deprecated csurf) + // Since we use httpOnly cookies with sameSite: 'lax', CSRF is largely mitigated. + // This middleware adds an extra layer by validating Origin/Referer on mutations. + const allowedOrigins = [ + process.env.FRONTEND_URL || 'http://localhost:5173', + 'http://localhost:3000', // Backend/GraphQL playground + ]; + + app.use((req: Request, res: Response, next: NextFunction) => { + // Skip validation for safe methods + const reqMethod = req.method; + if (['GET', 'HEAD', 'OPTIONS'].includes(reqMethod)) { + next(); + return; + } + + const origin = req.get('origin') || req.get('referer'); + + // Allow requests with no origin (same-origin requests, server-to-server) + if (!origin) { + next(); + return; + } + + // Validate origin against allowlist + const isAllowed = allowedOrigins.some((allowed) => + origin.startsWith(allowed), + ); + + if (!isAllowed) { + res.status(403).json({ message: 'Forbidden: Invalid origin' }); + return; + } + + next(); + }); + app.enableCors({ - origin: true, + origin: allowedOrigins, credentials: true, }); // Enable the global validation pipe @@ -19,4 +75,4 @@ async function bootstrap() { await app.listen(process.env.PORT ?? 3000); } -bootstrap(); +void bootstrap(); diff --git a/backend/src/project-member/project-member.resolver.spec.ts b/backend/src/project-member/project-member.resolver.spec.ts index edc7b68..a9be5b2 100644 --- a/backend/src/project-member/project-member.resolver.spec.ts +++ b/backend/src/project-member/project-member.resolver.spec.ts @@ -38,12 +38,16 @@ describe('ProjectMemberResolver', () => { describe('inviteToProject', () => { it('should call service with correct arguments', async () => { - const input = { projectId: 1, email: 'test@test.com', role: ProjectRole.MEMBER }; + const input = { + projectId: 1, + email: 'test@test.com', + role: ProjectRole.MEMBER, + }; const user = { id: 1 }; mockService.inviteUser.mockResolvedValue({ id: 1, ...input, userId: 2 }); - await resolver.inviteToProject(input, user); - + await resolver.inviteToProject(input, user as any); + expect(mockService.inviteUser).toHaveBeenCalledWith( input.projectId, user.id, diff --git a/backend/src/project-member/project-member.resolver.ts b/backend/src/project-member/project-member.resolver.ts index e02e67a..f0d7985 100644 --- a/backend/src/project-member/project-member.resolver.ts +++ b/backend/src/project-member/project-member.resolver.ts @@ -11,7 +11,7 @@ import { ProjectPermissionGuard } from 'src/auth/guards/project-permission.guard import { CurrentUser } from 'src/auth/decorators/current-user.decorator'; import { RequireProjectRole } from 'src/auth/decorators/require-project-role.decorator'; import { ProjectRole } from 'prisma/generated/enums'; -import { Project } from 'src/project/entities/project.entity'; +import { User } from 'src/user/entities/user.entity'; @Resolver(() => ProjectMember) export class ProjectMemberResolver { @@ -35,7 +35,7 @@ export class ProjectMemberResolver { */ @Query(() => [ProjectMember], { name: 'myProjectMemberships' }) @UseGuards(GqlAuthGuard) - async getMyProjects(@CurrentUser() user: any) { + async getMyProjects(@CurrentUser() user: User) { return this.projectMemberService.getUserProjects(user.id); } @@ -46,7 +46,7 @@ export class ProjectMemberResolver { @UseGuards(GqlAuthGuard) async getMyRole( @Args('projectId', { type: () => Int }) projectId: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.projectMemberService.getUserRole(user.id, projectId); } @@ -60,7 +60,7 @@ export class ProjectMemberResolver { @RequireProjectRole(ProjectRole.OWNER, ProjectRole.ADMIN) async inviteToProject( @Args('input') input: InviteToProjectInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.projectMemberService.inviteUser( input.projectId, @@ -77,10 +77,7 @@ export class ProjectMemberResolver { @Mutation(() => ProjectMember) @UseGuards(GqlAuthGuard, ProjectPermissionGuard) @RequireProjectRole(ProjectRole.OWNER, ProjectRole.ADMIN) - async updateMemberRole( - @Args('input') input: UpdateMemberRoleInput, - @CurrentUser() user: any, - ) { + async updateMemberRole(@Args('input') input: UpdateMemberRoleInput) { return this.projectMemberService.updateMemberRole( input.projectId, input.userId, @@ -95,10 +92,7 @@ export class ProjectMemberResolver { @Mutation(() => ProjectMember) @UseGuards(GqlAuthGuard, ProjectPermissionGuard) @RequireProjectRole(ProjectRole.OWNER, ProjectRole.ADMIN) - async removeMemberFromProject( - @Args('input') input: RemoveMemberInput, - @CurrentUser() user: any, - ) { + async removeMemberFromProject(@Args('input') input: RemoveMemberInput) { return this.projectMemberService.removeMember( input.projectId, input.userId, @@ -113,7 +107,7 @@ export class ProjectMemberResolver { @UseGuards(GqlAuthGuard, ProjectAccessGuard) async leaveProject( @Args('projectId', { type: () => Int }) projectId: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.projectMemberService.removeMember(projectId, user.id); } diff --git a/backend/src/project-member/project-member.service.spec.ts b/backend/src/project-member/project-member.service.spec.ts index a26253b..4b118a2 100644 --- a/backend/src/project-member/project-member.service.spec.ts +++ b/backend/src/project-member/project-member.service.spec.ts @@ -46,12 +46,19 @@ describe('ProjectMemberService', () => { describe('addMember', () => { it('should add a member successfully', async () => { mockPrisma.projectMember.findUnique.mockResolvedValue(null); - mockPrisma.project.findUnique.mockResolvedValue({ id: 1, workspaceId: 1 }); + mockPrisma.project.findUnique.mockResolvedValue({ + id: 1, + workspaceId: 1, + }); mockPrisma.user.findUnique.mockResolvedValue({ id: 1 }); - mockPrisma.projectMember.create.mockResolvedValue({ id: 1, userId: 1, projectId: 1 }); + mockPrisma.projectMember.create.mockResolvedValue({ + id: 1, + userId: 1, + projectId: 1, + }); const result = await service.addMember(1, 1, ProjectRole.MEMBER); - + expect(result).toBeDefined(); expect(mockPrisma.projectMember.create).toHaveBeenCalled(); }); diff --git a/backend/src/project-stage/project-stage.service.spec.ts b/backend/src/project-stage/project-stage.service.spec.ts index f420845..a46a4dd 100644 --- a/backend/src/project-stage/project-stage.service.spec.ts +++ b/backend/src/project-stage/project-stage.service.spec.ts @@ -38,11 +38,14 @@ describe('ProjectStageService', () => { describe('findAll', () => { it('should return all project stages', async () => { - const mockStages = [{ id: 1, name: 'Planning', workspaceId: 1 }, { id: 2, name: 'In Progress', workspaceId: 1 }]; + const mockStages = [ + { id: 1, name: 'Planning', workspaceId: 1 }, + { id: 2, name: 'In Progress', workspaceId: 1 }, + ]; mockPrisma.projectStage.findMany.mockResolvedValue(mockStages); const result = await service.findAll(1); - + expect(result).toEqual(mockStages); expect(mockPrisma.projectStage.findMany).toHaveBeenCalledWith({ where: { workspaceId: 1 }, diff --git a/backend/src/project/dto/create-project.input.ts b/backend/src/project/dto/create-project.input.ts index c0d8f9a..1a25d25 100644 --- a/backend/src/project/dto/create-project.input.ts +++ b/backend/src/project/dto/create-project.input.ts @@ -1,11 +1,19 @@ import { InputType, Int, Field } from '@nestjs/graphql'; +import { + ProjectMethodology, + ProjectVisibility, + ProjectPriority, +} from '../../../prisma/generated/enums'; +import { IsSanitizedString } from '../../common/decorators/sanitized-string.decorator'; @InputType() export class CreateProjectInput { @Field() + @IsSanitizedString() name: string; @Field({ nullable: true }) + @IsSanitizedString() description?: string; @Field(() => Int) @@ -19,4 +27,40 @@ export class CreateProjectInput { @Field(() => Int, { nullable: true }) sequence?: number; + + @Field(() => Number, { nullable: true, defaultValue: 0 }) + budgetPlanned?: number; + + @Field({ nullable: true }) + startDate?: Date; + + @Field({ nullable: true }) + endDate?: Date; + + @Field(() => Int, { nullable: true, defaultValue: 1 }) + phasesCount?: number; + + @Field(() => ProjectMethodology, { + nullable: true, + defaultValue: ProjectMethodology.KANBAN, + }) + methodology?: ProjectMethodology; + + @Field(() => ProjectVisibility, { + nullable: true, + defaultValue: ProjectVisibility.TEAM, + }) + visibility?: ProjectVisibility; + + @Field(() => ProjectPriority, { + nullable: true, + defaultValue: ProjectPriority.MEDIUM, + }) + priority?: ProjectPriority; + + @Field({ nullable: true, defaultValue: 'USD' }) + currency?: string; + + @Field(() => [String], { nullable: true }) + tags?: string[]; } diff --git a/backend/src/project/dto/update-project.input.ts b/backend/src/project/dto/update-project.input.ts index eba9e3f..b6e1a43 100644 --- a/backend/src/project/dto/update-project.input.ts +++ b/backend/src/project/dto/update-project.input.ts @@ -5,4 +5,19 @@ import { InputType, Field, Int, PartialType } from '@nestjs/graphql'; export class UpdateProjectInput extends PartialType(CreateProjectInput) { @Field(() => Int) id: number; + + @Field({ nullable: true }) + actualStartDate?: Date; + + @Field({ nullable: true }) + actualEndDate?: Date; + + @Field(() => Number, { nullable: true }) + progress?: number; + + @Field({ nullable: true }) + archivedAt?: Date; + + @Field({ nullable: true }) + key?: string; } diff --git a/backend/src/project/entities/project.entity.ts b/backend/src/project/entities/project.entity.ts index 83a6bf7..1f547f4 100644 --- a/backend/src/project/entities/project.entity.ts +++ b/backend/src/project/entities/project.entity.ts @@ -7,6 +7,24 @@ import { Attachment } from 'src/attachment/entities/attachment.entity'; import { ProjectMember } from 'src/project-member/entities/project-member.entity'; import { Workspace } from 'src/workspace/entities/workspace.entity'; import { ProjectStage } from 'src/project-stage/entities/project-stage.entity'; +import { registerEnumType } from '@nestjs/graphql'; +import { + ProjectMethodology, + ProjectVisibility, + ProjectPriority, +} from '../../../prisma/generated/enums'; + +registerEnumType(ProjectVisibility, { + name: 'ProjectVisibility', +}); + +registerEnumType(ProjectPriority, { + name: 'ProjectPriority', +}); + +registerEnumType(ProjectMethodology, { + name: 'ProjectMethodology', +}); @ObjectType() export class Project { @@ -60,4 +78,52 @@ export class Project { @Field(() => Int, { nullable: true }) sequence?: number; + + @Field(() => Number, { defaultValue: 0 }) + budgetPlanned: number; + + @Field(() => Number, { defaultValue: 0 }) + budgetActual: number; + + @Field({ nullable: true }) + startDate?: Date; + + @Field({ nullable: true }) + endDate?: Date; + + @Field(() => Int, { defaultValue: 1 }) + phasesCount: number; + + @Field(() => ProjectMethodology, { defaultValue: ProjectMethodology.KANBAN }) + methodology: ProjectMethodology; + + @Field({ nullable: true }) + key?: string; + + @Field(() => ProjectVisibility, { defaultValue: ProjectVisibility.TEAM }) + visibility: ProjectVisibility; + + @Field(() => ProjectPriority, { defaultValue: ProjectPriority.MEDIUM }) + priority: ProjectPriority; + + @Field({ nullable: true }) + actualStartDate?: Date; + + @Field({ nullable: true }) + actualEndDate?: Date; + + @Field(() => Number, { defaultValue: 0 }) + progress: number; + + @Field({ defaultValue: 'USD' }) + currency: string; + + @Field(() => [String], { nullable: 'items' }) + tags?: string[]; + + @Field({ nullable: true }) + archivedAt?: Date; + + @Field(() => Number, { defaultValue: 0 }) + totalHours?: number; } diff --git a/backend/src/project/project.resolver.spec.ts b/backend/src/project/project.resolver.spec.ts index 8da0b86..e718dba 100644 --- a/backend/src/project/project.resolver.spec.ts +++ b/backend/src/project/project.resolver.spec.ts @@ -44,8 +44,8 @@ describe('ProjectResolver', () => { const user = { id: 1 }; mockProjectService.create.mockResolvedValue({ id: 1, ...input }); - await resolver.createProject(input as any, user); - + await resolver.createProject(input as any, user as any); + expect(mockProjectService.create).toHaveBeenCalledWith(input, user.id); }); }); diff --git a/backend/src/project/project.resolver.ts b/backend/src/project/project.resolver.ts index 7bec5d8..d967fd3 100644 --- a/backend/src/project/project.resolver.ts +++ b/backend/src/project/project.resolver.ts @@ -1,4 +1,12 @@ -import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql'; +import { + Resolver, + Query, + Mutation, + Args, + Int, + ResolveField, + Parent, +} from '@nestjs/graphql'; import { UseGuards } from '@nestjs/common'; import { ProjectService } from './project.service'; import { Project } from './entities/project.entity'; @@ -10,10 +18,15 @@ import { ProjectPermissionGuard } from 'src/auth/guards/project-permission.guard import { CurrentUser } from 'src/auth/decorators/current-user.decorator'; import { RequireProjectRole } from 'src/auth/decorators/require-project-role.decorator'; import { ProjectRole } from 'prisma/generated/enums'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { User } from 'src/user/entities/user.entity'; @Resolver(() => Project) export class ProjectResolver { - constructor(private readonly projectService: ProjectService) {} + constructor( + private readonly projectService: ProjectService, + private readonly prisma: PrismaService, + ) {} /** * Create a new project - user is automatically added as OWNER @@ -22,7 +35,7 @@ export class ProjectResolver { @UseGuards(GqlAuthGuard) createProject( @Args('createProjectInput') createProjectInput: CreateProjectInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.projectService.create(createProjectInput, user.id); } @@ -33,7 +46,7 @@ export class ProjectResolver { @Query(() => [Project]) @UseGuards(GqlAuthGuard) projects( - @CurrentUser() user: any, + @CurrentUser() user: User, @Args('skip', { type: () => Int, nullable: true }) skip?: number, @Args('take', { type: () => Int, nullable: true }) take?: number, @Args('workspaceId', { type: () => Int, nullable: true }) @@ -49,7 +62,7 @@ export class ProjectResolver { @UseGuards(GqlAuthGuard, ProjectAccessGuard) project( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.projectService.findOne(id, user.id); } @@ -62,7 +75,7 @@ export class ProjectResolver { @RequireProjectRole(ProjectRole.OWNER, ProjectRole.ADMIN) updateProject( @Args('updateProjectInput') updateProjectInput: UpdateProjectInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.projectService.update( updateProjectInput.id, @@ -79,8 +92,17 @@ export class ProjectResolver { @RequireProjectRole(ProjectRole.OWNER) deleteProject( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.projectService.delete(id, user.id); } + + @ResolveField(() => Number) + async totalHours(@Parent() project: Project) { + const result = await this.prisma.timesheet.aggregate({ + where: { projectId: project.id }, + _sum: { timeSpent: true }, + }); + return result._sum.timeSpent || 0; + } } diff --git a/backend/src/project/project.service.spec.ts b/backend/src/project/project.service.spec.ts index 2d2c35f..c25f950 100644 --- a/backend/src/project/project.service.spec.ts +++ b/backend/src/project/project.service.spec.ts @@ -16,6 +16,7 @@ const mockPrisma = { create: jest.fn().mockResolvedValue(mockProject), findMany: jest.fn().mockResolvedValue([mockProject]), findUnique: jest.fn().mockResolvedValue(mockProject), + findFirst: jest.fn().mockResolvedValue(mockProject), update: jest.fn().mockResolvedValue(mockProject), delete: jest.fn().mockResolvedValue(mockProject), }, @@ -53,7 +54,8 @@ describe('ProjectService', () => { service = module.get(ProjectService); prisma = module.get(PrismaService); - projectMemberService = module.get(ProjectMemberService); + projectMemberService = + module.get(ProjectMemberService); }); it('should be defined', () => { @@ -68,26 +70,28 @@ describe('ProjectService', () => { }; const result = await service.create(createDto as any, 1); - + expect(prisma.workspaceMember.findUnique).toHaveBeenCalled(); expect(prisma.project.create).toHaveBeenCalled(); expect(projectMemberService.addMember).toHaveBeenCalledWith( mockProject.id, 1, - ProjectRole.OWNER + ProjectRole.OWNER, ); expect(result).toEqual(mockProject); }); it('should throw ForbiddenException if user is not a workspace member', async () => { - (mockPrisma.workspaceMember.findUnique as jest.Mock).mockResolvedValueOnce(null); - + mockPrisma.workspaceMember.findUnique.mockResolvedValueOnce(null); + const createDto = { name: 'New Project', workspaceId: 2, }; - await expect(service.create(createDto as any, 1)).rejects.toThrow(ForbiddenException); + await expect(service.create(createDto as any, 1)).rejects.toThrow( + ForbiddenException, + ); }); }); diff --git a/backend/src/project/project.service.ts b/backend/src/project/project.service.ts index 794af84..972e748 100644 --- a/backend/src/project/project.service.ts +++ b/backend/src/project/project.service.ts @@ -60,9 +60,15 @@ export class ProjectService { ); } + // Generate unique project key + const key = await this.generateProjectKey(createProjectInput.name); + // Create the project const project = await this.prisma.project.create({ - data: createProjectInput, + data: { + ...createProjectInput, + key, + }, include: { ...this.includeRelation }, }); @@ -163,4 +169,34 @@ export class ProjectService { where: { id }, }); } + + private async generateProjectKey(name: string): Promise { + let prefix = name + .substring(0, 3) + .toUpperCase() + .replace(/[^A-Z]/g, ''); + if (prefix.length < 2) prefix = 'PRJ'; + + const latestProject = await this.prisma.project.findFirst({ + where: { + key: { + startsWith: prefix + '-', + }, + }, + orderBy: { + key: 'desc', + }, + }); + + let nextNumber = 1; + if (latestProject && latestProject.key) { + const parts = latestProject.key.split('-'); + const lastNum = parseInt(parts[parts.length - 1]); + if (!isNaN(lastNum)) { + nextNumber = lastNum + 1; + } + } + + return `${prefix}-${nextNumber.toString().padStart(3, '0')}`; + } } diff --git a/backend/src/schema.gql b/backend/src/schema.gql index 8dfe500..c29e14f 100644 --- a/backend/src/schema.gql +++ b/backend/src/schema.gql @@ -45,6 +45,36 @@ type Task { stageId: Int stage: TaskStage sequence: Int + estimatedHours: Float! + dueDate: DateTime + priority: TaskPriority! + actualHours: Float! + parentTaskId: Int + parentTask: Task + subtasks: [Task]! + type: TaskType! + reporterId: Int + reporter: User + startDate: DateTime + completedAt: DateTime + remainingHours: Float! + progress: Float! + tags: [String]! + deletedAt: DateTime +} + +enum TaskPriority { + LOW + MEDIUM + HIGH + URGENT +} + +enum TaskType { + TASK + BUG + STORY + EPIC } type Timesheet { @@ -61,6 +91,29 @@ type Timesheet { project: Project! task: Task! taskId: Int! + startTime: DateTime + endTime: DateTime + billable: Boolean! + hourlyRate: Float + cost: Float + source: TimesheetSource! + approvalStatus: ApprovalStatus! + approvedById: Int + approvedBy: User + approvedAt: DateTime + tags: [String]! +} + +enum TimesheetSource { + MANUAL + TIMER + INTEGRATION +} + +enum ApprovalStatus { + PENDING + APPROVED + REJECTED } type ProjectMember { @@ -145,6 +198,43 @@ type Project { stageId: Int stage: ProjectStage sequence: Int + budgetPlanned: Float! + budgetActual: Float! + startDate: DateTime + endDate: DateTime + phasesCount: Int! + methodology: ProjectMethodology! + key: String + visibility: ProjectVisibility! + priority: ProjectPriority! + actualStartDate: DateTime + actualEndDate: DateTime + progress: Float! + currency: String! + tags: [String]! + archivedAt: DateTime + totalHours: Float! +} + +enum ProjectMethodology { + SCRUM + WATERFALL + KANBAN + AGILE + OTHER +} + +enum ProjectVisibility { + PRIVATE + TEAM + PUBLIC +} + +enum ProjectPriority { + LOW + MEDIUM + HIGH + CRITICAL } type Comment { @@ -185,6 +275,8 @@ type User { tasks: [Task]! timesheets: [Timesheet]! comments: [Comment]! + reportedTasks: [Task]! + approvedTimesheets: [Timesheet]! } type LoginResponse { @@ -192,10 +284,70 @@ type LoginResponse { user: User! } +type TasksByStageItem { + stage: String! + count: Int! + color: String! +} + +type TasksByPriorityItem { + priority: String! + count: Int! +} + +type ProjectProgressItem { + id: Int! + projectName: String! + progress: Float! + budgetPlanned: Float! + budgetActual: Float! +} + +type TimelineEntry { + date: String! + tasksCreated: Int! + tasksCompleted: Int! + hoursLogged: Float! +} + +type RecentActivityItem { + id: Int! + type: String! + title: String! + userName: String! + timestamp: String! + projectName: String +} + +type UpcomingDeadlineItem { + id: Int! + title: String! + dueDate: String! + priority: String! + projectName: String + stageName: String + stageColor: String +} + +type TimesheetSummary { + thisWeek: Float! + lastWeek: Float! + thisMonth: Float! +} + type DashboardStats { totalUsers: Int! activeProjects: Int! pendingTasks: Int! + completedThisWeek: Int! + overdueTasks: Int! + tasksByStage: [TasksByStageItem!]! + tasksByPriority: [TasksByPriorityItem!]! + projectsProgress: [ProjectProgressItem!]! + activityTimeline: [TimelineEntry!]! + upcomingDeadlines: [UpcomingDeadlineItem!]! + recentActivity: [RecentActivityItem!]! + timesheetSummary: TimesheetSummary! } type LinkPreview { @@ -269,7 +421,7 @@ type Query { myRoleInProject(projectId: Int!): String projects(skip: Int, take: Int, workspaceId: Int): [Project!]! project(id: Int!): Project! - tasks(skip: Int, take: Int, projectId: Int): [Task!]! + tasks(skip: Int, take: Int, projectId: Int, cursor: Int): [Task!]! getTask(id: Int!): Task! timesheets(skip: Int, take: Int, taskId: Int): [Timesheet!]! getTimesheet(id: Int!): Timesheet! @@ -306,6 +458,8 @@ type Mutation { createTimesheet(createTimesheetInput: CreateTimesheetInput!): Timesheet! updateTimesheet(updateTimesheetInput: UpdateTimesheetInput!): Timesheet! removeTimesheet(id: Int!): Timesheet! + approveTimesheet(id: Int!): Timesheet! + rejectTimesheet(id: Int!): Timesheet! createComment(createCommentInput: CreateCommentInput!): Comment! updateComment(updateCommentInput: UpdateCommentInput!): Comment! removeComment(id: Int!): Comment! @@ -329,6 +483,7 @@ type Mutation { addParticipant(conversationId: Int!, userId: Int!): ConversationParticipant! removeParticipant(conversationId: Int!, userId: Int!): Boolean! markAsRead(conversationId: Int!): Boolean! + sendMessage(conversationId: Int!, content: String!, type: MessageType = TEXT, attachmentIds: [Int!], metadata: String): Message! updateMessage(id: Int!, content: String!): Message! deleteMessage(id: Int!): Boolean! } @@ -394,6 +549,15 @@ input CreateProjectInput { workspaceId: Int! stageId: Int sequence: Int + budgetPlanned: Float = 0 + startDate: DateTime + endDate: DateTime + phasesCount: Int = 1 + methodology: ProjectMethodology = KANBAN + visibility: ProjectVisibility = TEAM + priority: ProjectPriority = MEDIUM + currency: String = "USD" + tags: [String!] } input UpdateProjectInput { @@ -403,7 +567,21 @@ input UpdateProjectInput { workspaceId: Int stageId: Int sequence: Int + budgetPlanned: Float = 0 + startDate: DateTime + endDate: DateTime + phasesCount: Int = 1 + methodology: ProjectMethodology = KANBAN + visibility: ProjectVisibility = TEAM + priority: ProjectPriority = MEDIUM + currency: String = "USD" + tags: [String!] id: Int! + actualStartDate: DateTime + actualEndDate: DateTime + progress: Float + archivedAt: DateTime + key: String } input CreateTaskInput { @@ -413,6 +591,14 @@ input CreateTaskInput { projectId: Int! stageId: Int sequence: Int + estimatedHours: Float = 0 + dueDate: DateTime + priority: TaskPriority = MEDIUM + parentTaskId: Int + type: TaskType = TASK + reporterId: Int + startDate: DateTime + tags: [String!] } input UpdateTaskInput { @@ -422,7 +608,19 @@ input UpdateTaskInput { projectId: Int stageId: Int sequence: Int + estimatedHours: Float = 0 + dueDate: DateTime + priority: TaskPriority = MEDIUM + parentTaskId: Int + type: TaskType = TASK + reporterId: Int + startDate: DateTime + tags: [String!] id: Int! + completedAt: DateTime + remainingHours: Float + progress: Float + deletedAt: DateTime } input CreateTimesheetInput { @@ -432,6 +630,12 @@ input CreateTimesheetInput { userId: Int! projectId: Int! taskId: Int! + startTime: DateTime + endTime: DateTime + billable: Boolean = true + hourlyRate: Float + source: TimesheetSource = MANUAL + tags: [String!] } input UpdateTimesheetInput { @@ -441,7 +645,17 @@ input UpdateTimesheetInput { userId: Int projectId: Int taskId: Int + startTime: DateTime + endTime: DateTime + billable: Boolean = true + hourlyRate: Float + source: TimesheetSource = MANUAL + tags: [String!] id: Int! + approvalStatus: ApprovalStatus + approvedById: Int + approvedAt: DateTime + cost: Float } input CreateCommentInput { @@ -532,4 +746,10 @@ input UpdateTaskStageInput { workspaceId: Int sequence: Int = 5 id: Int! +} + +type Subscription { + messageSent(conversationId: Int!): Message! + messageUpdated(conversationId: Int!): Message! + messageDeleted(conversationId: Int!): Int! } \ No newline at end of file diff --git a/backend/src/task-stage/task-stage.service.spec.ts b/backend/src/task-stage/task-stage.service.spec.ts index f99b608..53a7ce8 100644 --- a/backend/src/task-stage/task-stage.service.spec.ts +++ b/backend/src/task-stage/task-stage.service.spec.ts @@ -38,11 +38,14 @@ describe('TaskStageService', () => { describe('findAll', () => { it('should return all task stages', async () => { - const mockStages = [{ id: 1, name: 'To Do', workspaceId: 1 }, { id: 2, name: 'Done', workspaceId: 1 }]; + const mockStages = [ + { id: 1, name: 'To Do', workspaceId: 1 }, + { id: 2, name: 'Done', workspaceId: 1 }, + ]; mockPrisma.taskStage.findMany.mockResolvedValue(mockStages); const result = await service.findAll(1); - + expect(result).toEqual(mockStages); expect(mockPrisma.taskStage.findMany).toHaveBeenCalledWith({ where: { workspaceId: 1 }, diff --git a/backend/src/task/dto/create-task.input.ts b/backend/src/task/dto/create-task.input.ts index 32d7149..4bda3a2 100644 --- a/backend/src/task/dto/create-task.input.ts +++ b/backend/src/task/dto/create-task.input.ts @@ -1,11 +1,15 @@ import { InputType, Int, Field } from '@nestjs/graphql'; +import { TaskPriority, TaskType } from '../../../prisma/generated/enums'; +import { IsSanitizedString } from '../../common/decorators/sanitized-string.decorator'; @InputType() export class CreateTaskInput { @Field() + @IsSanitizedString() title: string; @Field({ nullable: true }) + @IsSanitizedString() description?: string; @Field(() => Int) @@ -19,4 +23,31 @@ export class CreateTaskInput { @Field(() => Int, { nullable: true }) sequence?: number; + + @Field(() => Number, { nullable: true, defaultValue: 0 }) + estimatedHours?: number; + + @Field({ nullable: true }) + dueDate?: Date; + + @Field(() => TaskPriority, { + nullable: true, + defaultValue: TaskPriority.MEDIUM, + }) + priority?: TaskPriority; + + @Field(() => Int, { nullable: true }) + parentTaskId?: number; + + @Field(() => TaskType, { nullable: true, defaultValue: TaskType.TASK }) + type?: TaskType; + + @Field(() => Int, { nullable: true }) + reporterId?: number; + + @Field({ nullable: true }) + startDate?: Date; + + @Field(() => [String], { nullable: true }) + tags?: string[]; } diff --git a/backend/src/task/dto/update-task.input.ts b/backend/src/task/dto/update-task.input.ts index 749b976..3552013 100644 --- a/backend/src/task/dto/update-task.input.ts +++ b/backend/src/task/dto/update-task.input.ts @@ -5,4 +5,16 @@ import { InputType, Field, Int, PartialType } from '@nestjs/graphql'; export class UpdateTaskInput extends PartialType(CreateTaskInput) { @Field(() => Int) id: number; + + @Field({ nullable: true }) + completedAt?: Date; + + @Field(() => Number, { nullable: true }) + remainingHours?: number; + + @Field(() => Number, { nullable: true }) + progress?: number; + + @Field({ nullable: true }) + deletedAt?: Date; } diff --git a/backend/src/task/entities/task.entity.ts b/backend/src/task/entities/task.entity.ts index 388973b..a548012 100644 --- a/backend/src/task/entities/task.entity.ts +++ b/backend/src/task/entities/task.entity.ts @@ -5,6 +5,16 @@ import { User } from 'src/user/entities/user.entity'; import { Attachment } from 'src/attachment/entities/attachment.entity'; import { Comment as CommentChat } from 'src/comment/entities/comment.entity'; import { TaskStage } from 'src/task-stage/entities/task-stage.entity'; +import { registerEnumType } from '@nestjs/graphql'; +import { TaskPriority, TaskType } from '../../../prisma/generated/enums'; + +registerEnumType(TaskPriority, { + name: 'TaskPriority', +}); + +registerEnumType(TaskType, { + name: 'TaskType', +}); @ObjectType() export class Task extends Base { @@ -40,4 +50,52 @@ export class Task extends Base { @Field(() => Int, { nullable: true }) sequence?: number; + + @Field(() => Number, { defaultValue: 0 }) + estimatedHours: number; + + @Field({ nullable: true }) + dueDate?: Date; + + @Field(() => TaskPriority, { defaultValue: TaskPriority.MEDIUM }) + priority: TaskPriority; + + @Field(() => Number, { defaultValue: 0 }) + actualHours?: number; + + @Field(() => Int, { nullable: true }) + parentTaskId?: number; + + @Field(() => Task, { nullable: true }) + parentTask?: Task; + + @Field(() => [Task], { nullable: 'items' }) + subtasks?: Task[]; + + @Field(() => TaskType, { defaultValue: TaskType.TASK }) + type: TaskType; + + @Field(() => Int, { nullable: true }) + reporterId?: number; + + @Field(() => User, { nullable: true }) + reporter?: User; + + @Field({ nullable: true }) + startDate?: Date; + + @Field({ nullable: true }) + completedAt?: Date; + + @Field(() => Number, { defaultValue: 0 }) + remainingHours: number; + + @Field(() => Number, { defaultValue: 0 }) + progress: number; + + @Field(() => [String], { nullable: 'items' }) + tags?: string[]; + + @Field({ nullable: true }) + deletedAt?: Date; } diff --git a/backend/src/task/task.resolver.spec.ts b/backend/src/task/task.resolver.spec.ts index b4ddf4a..ae22cfb 100644 --- a/backend/src/task/task.resolver.spec.ts +++ b/backend/src/task/task.resolver.spec.ts @@ -44,8 +44,8 @@ describe('TaskResolver', () => { const user = { id: 1 }; mockTaskService.create.mockResolvedValue({ id: 1, ...input }); - await resolver.createTask(input as any, user); - + await resolver.createTask(input as any, user as any); + expect(mockTaskService.create).toHaveBeenCalledWith(input, user.id); }); }); diff --git a/backend/src/task/task.resolver.ts b/backend/src/task/task.resolver.ts index 6907dde..3bdaff9 100644 --- a/backend/src/task/task.resolver.ts +++ b/backend/src/task/task.resolver.ts @@ -1,4 +1,12 @@ -import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql'; +import { + Resolver, + Query, + Mutation, + Args, + Int, + ResolveField, + Parent, +} from '@nestjs/graphql'; import { UseGuards } from '@nestjs/common'; import { TaskService } from './task.service'; import { Task } from './entities/task.entity'; @@ -6,16 +14,21 @@ import { CreateTaskInput } from './dto/create-task.input'; import { UpdateTaskInput } from './dto/update-task.input'; import { GqlAuthGuard } from 'src/auth/guards/gql-auth.guard'; import { CurrentUser } from 'src/auth/decorators/current-user.decorator'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { User } from 'src/user/entities/user.entity'; @Resolver(() => Task) export class TaskResolver { - constructor(private readonly taskService: TaskService) {} + constructor( + private readonly taskService: TaskService, + private readonly prisma: PrismaService, + ) {} @Mutation(() => Task) @UseGuards(GqlAuthGuard) createTask( @Args('createTaskInput') createTaskInput: CreateTaskInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.taskService.create(createTaskInput, user.id); } @@ -23,19 +36,20 @@ export class TaskResolver { @Query(() => [Task]) @UseGuards(GqlAuthGuard) tasks( - @CurrentUser() user: any, + @CurrentUser() user: User, @Args('skip', { type: () => Int, nullable: true }) skip?: number, @Args('take', { type: () => Int, nullable: true }) take?: number, @Args('projectId', { type: () => Int, nullable: true }) projectId?: number, + @Args('cursor', { type: () => Int, nullable: true }) cursor?: number, ) { - return this.taskService.findAll(user.id, skip, take, projectId); + return this.taskService.findAll(user.id, skip, take, projectId, cursor); } @Query(() => Task) @UseGuards(GqlAuthGuard) getTask( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.taskService.findOne(id, user.id); } @@ -44,7 +58,7 @@ export class TaskResolver { @UseGuards(GqlAuthGuard) updateTask( @Args('updateTaskInput') updateTaskInput: UpdateTaskInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.taskService.update( updateTaskInput.id, @@ -57,8 +71,17 @@ export class TaskResolver { @UseGuards(GqlAuthGuard) removeTask( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.taskService.remove(id, user.id); } + + @ResolveField(() => Number) + async actualHours(@Parent() task: Task) { + const result = await this.prisma.timesheet.aggregate({ + where: { taskId: task.id }, + _sum: { timeSpent: true }, + }); + return result._sum.timeSpent || 0; + } } diff --git a/backend/src/task/task.service.spec.ts b/backend/src/task/task.service.spec.ts index aa629bc..f1dde5e 100644 --- a/backend/src/task/task.service.spec.ts +++ b/backend/src/task/task.service.spec.ts @@ -49,7 +49,8 @@ describe('TaskService', () => { service = module.get(TaskService); prisma = module.get(PrismaService); - projectMemberService = module.get(ProjectMemberService); + projectMemberService = + module.get(ProjectMemberService); }); it('should be defined', () => { @@ -65,13 +66,13 @@ describe('TaskService', () => { }; const result = await service.create(createDto as any, 1); - + expect(result).toEqual(mockTask); - expect(projectMemberService.checkPermission).toHaveBeenCalledWith( - 1, - 1, - [ProjectRole.OWNER, ProjectRole.ADMIN, ProjectRole.MEMBER] - ); + expect(projectMemberService.checkPermission).toHaveBeenCalledWith(1, 1, [ + ProjectRole.OWNER, + ProjectRole.ADMIN, + ProjectRole.MEMBER, + ]); expect(prisma.task.create).toHaveBeenCalled(); }); }); diff --git a/backend/src/task/task.service.ts b/backend/src/task/task.service.ts index b761b84..f06ff33 100644 --- a/backend/src/task/task.service.ts +++ b/backend/src/task/task.service.ts @@ -1,8 +1,4 @@ -import { - Injectable, - ForbiddenException, - NotFoundException, -} from '@nestjs/common'; +import { Injectable, NotFoundException } from '@nestjs/common'; import { CreateTaskInput } from './dto/create-task.input'; import { UpdateTaskInput } from './dto/update-task.input'; import { PrismaService } from 'src/prisma/prisma.service'; @@ -21,6 +17,9 @@ export class TaskService { user: true, project: true, stage: true, + reporter: true, + parentTask: true, + subtasks: true, attachments: true, comments: { where: { parentId: null }, @@ -55,6 +54,7 @@ export class TaskService { skip?: number, take?: number, projectId?: number, + cursor?: number, ) { let projectIds: number[] = []; @@ -70,8 +70,9 @@ export class TaskService { } return this.prisma.task.findMany({ - skip, + skip: skip !== undefined ? skip : cursor !== undefined ? 1 : undefined, take, + cursor: cursor !== undefined ? { id: cursor } : undefined, where: { projectId: { in: projectIds }, }, @@ -88,6 +89,10 @@ export class TaskService { include: { user: true, project: true, + stage: true, + reporter: true, + parentTask: true, + subtasks: true, comments: { where: { parentId: null }, include: { @@ -127,7 +132,7 @@ export class TaskService { return this.prisma.task.update({ where: { id }, data: updateTaskInput, - include: { user: true, project: true, attachments: true }, + include: this.includeRelation, }); } diff --git a/backend/src/timesheet/dto/create-timesheet.input.ts b/backend/src/timesheet/dto/create-timesheet.input.ts index 76e48b8..93897ac 100644 --- a/backend/src/timesheet/dto/create-timesheet.input.ts +++ b/backend/src/timesheet/dto/create-timesheet.input.ts @@ -1,4 +1,5 @@ import { InputType, Int, Field } from '@nestjs/graphql'; +import { TimesheetSource } from '../../../prisma/generated/enums'; @InputType() export class CreateTimesheetInput { @@ -19,4 +20,25 @@ export class CreateTimesheetInput { @Field(() => Int) taskId: number; + + @Field({ nullable: true }) + startTime?: Date; + + @Field({ nullable: true }) + endTime?: Date; + + @Field({ nullable: true, defaultValue: true }) + billable?: boolean; + + @Field(() => Number, { nullable: true }) + hourlyRate?: number; + + @Field(() => TimesheetSource, { + nullable: true, + defaultValue: TimesheetSource.MANUAL, + }) + source?: TimesheetSource; + + @Field(() => [String], { nullable: true }) + tags?: string[]; } diff --git a/backend/src/timesheet/dto/update-timesheet.input.ts b/backend/src/timesheet/dto/update-timesheet.input.ts index 601aad2..3f5a30e 100644 --- a/backend/src/timesheet/dto/update-timesheet.input.ts +++ b/backend/src/timesheet/dto/update-timesheet.input.ts @@ -1,8 +1,21 @@ import { CreateTimesheetInput } from './create-timesheet.input'; import { InputType, Field, Int, PartialType } from '@nestjs/graphql'; +import { ApprovalStatus } from '../../../prisma/generated/enums'; @InputType() export class UpdateTimesheetInput extends PartialType(CreateTimesheetInput) { @Field(() => Int) id: number; + + @Field(() => ApprovalStatus, { nullable: true }) + approvalStatus?: ApprovalStatus; + + @Field(() => Int, { nullable: true }) + approvedById?: number; + + @Field({ nullable: true }) + approvedAt?: Date; + + @Field(() => Number, { nullable: true }) + cost?: number; } diff --git a/backend/src/timesheet/entities/timesheet.entity.ts b/backend/src/timesheet/entities/timesheet.entity.ts index b7cd951..07f84ea 100644 --- a/backend/src/timesheet/entities/timesheet.entity.ts +++ b/backend/src/timesheet/entities/timesheet.entity.ts @@ -3,6 +3,19 @@ import { Base } from 'src/base/entities/base.entity'; import { User } from 'src/user/entities/user.entity'; import { Project } from 'src/project/entities/project.entity'; import { Task } from 'src/task/entities/task.entity'; +import { registerEnumType } from '@nestjs/graphql'; +import { + TimesheetSource, + ApprovalStatus, +} from '../../../prisma/generated/enums'; + +registerEnumType(TimesheetSource, { + name: 'TimesheetSource', +}); + +registerEnumType(ApprovalStatus, { + name: 'ApprovalStatus', +}); @ObjectType() export class Timesheet extends Base { @@ -32,4 +45,37 @@ export class Timesheet extends Base { @Field(() => Int) taskId: number; + + @Field({ nullable: true }) + startTime?: Date; + + @Field({ nullable: true }) + endTime?: Date; + + @Field({ defaultValue: true }) + billable: boolean; + + @Field(() => Number, { nullable: true }) + hourlyRate?: number; + + @Field(() => Number, { nullable: true }) + cost?: number; + + @Field(() => TimesheetSource, { defaultValue: TimesheetSource.MANUAL }) + source: TimesheetSource; + + @Field(() => ApprovalStatus, { defaultValue: ApprovalStatus.PENDING }) + approvalStatus: ApprovalStatus; + + @Field(() => Int, { nullable: true }) + approvedById?: number; + + @Field(() => User, { nullable: true }) + approvedBy?: User; + + @Field({ nullable: true }) + approvedAt?: Date; + + @Field(() => [String], { nullable: 'items' }) + tags?: string[]; } diff --git a/backend/src/timesheet/timesheet.resolver.spec.ts b/backend/src/timesheet/timesheet.resolver.spec.ts index c5f1fe8..7fdd9f8 100644 --- a/backend/src/timesheet/timesheet.resolver.spec.ts +++ b/backend/src/timesheet/timesheet.resolver.spec.ts @@ -43,12 +43,22 @@ describe('TimesheetResolver', () => { describe('createTimesheet', () => { it('should call service with correct arguments', async () => { - const input = { projectId: 1, taskId: 1, date: new Date().toISOString(), timeSpent: 2, description: 'Work' }; + const input = { + projectId: 1, + taskId: 1, + date: new Date().toISOString(), + timeSpent: 2, + description: 'Work', + }; const user = { id: 1 }; - mockTimesheetService.create.mockResolvedValue({ id: 1, ...input, userId: 1 }); + mockTimesheetService.create.mockResolvedValue({ + id: 1, + ...input, + userId: 1, + }); + + await resolver.createTimesheet(input as any, user as any); - await resolver.createTimesheet(input as any, user); - expect(mockTimesheetService.create).toHaveBeenCalledWith(input, user.id); }); }); diff --git a/backend/src/timesheet/timesheet.resolver.ts b/backend/src/timesheet/timesheet.resolver.ts index 486f6a9..134220c 100644 --- a/backend/src/timesheet/timesheet.resolver.ts +++ b/backend/src/timesheet/timesheet.resolver.ts @@ -6,6 +6,8 @@ import { CreateTimesheetInput } from './dto/create-timesheet.input'; import { UpdateTimesheetInput } from './dto/update-timesheet.input'; import { GqlAuthGuard } from 'src/auth/guards/gql-auth.guard'; import { CurrentUser } from 'src/auth/decorators/current-user.decorator'; +import { ApprovalStatus } from '../../prisma/generated/enums'; +import { User } from 'src/user/entities/user.entity'; @Resolver(() => Timesheet) export class TimesheetResolver { @@ -15,7 +17,7 @@ export class TimesheetResolver { @UseGuards(GqlAuthGuard) createTimesheet( @Args('createTimesheetInput') createTimesheetInput: CreateTimesheetInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.timesheetService.create(createTimesheetInput, user.id); } @@ -23,7 +25,7 @@ export class TimesheetResolver { @Query(() => [Timesheet], { name: 'timesheets' }) @UseGuards(GqlAuthGuard) findAll( - @CurrentUser() user: any, + @CurrentUser() user: User, @Args('skip', { type: () => Int, nullable: true }) skip?: number, @Args('take', { type: () => Int, nullable: true }) take?: number, @Args('taskId', { type: () => Int, nullable: true }) taskId?: number, @@ -35,7 +37,7 @@ export class TimesheetResolver { @UseGuards(GqlAuthGuard) findOne( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.timesheetService.findOne(id, user.id); } @@ -44,7 +46,7 @@ export class TimesheetResolver { @UseGuards(GqlAuthGuard) updateTimesheet( @Args('updateTimesheetInput') updateTimesheetInput: UpdateTimesheetInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.timesheetService.update( updateTimesheetInput.id, @@ -57,8 +59,42 @@ export class TimesheetResolver { @UseGuards(GqlAuthGuard) removeTimesheet( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.timesheetService.remove(id, user.id); } + + @Mutation(() => Timesheet) + @UseGuards(GqlAuthGuard) + approveTimesheet( + @Args('id', { type: () => Int }) id: number, + @CurrentUser() user: User, + ) { + return this.timesheetService.update( + id, + { + id, + approvalStatus: ApprovalStatus.APPROVED, + approvedById: user.id, + approvedAt: new Date(), + }, + user.id, + ); + } + + @Mutation(() => Timesheet) + @UseGuards(GqlAuthGuard) + rejectTimesheet( + @Args('id', { type: () => Int }) id: number, + @CurrentUser() user: User, + ) { + return this.timesheetService.update( + id, + { + id, + approvalStatus: ApprovalStatus.REJECTED, + }, + user.id, + ); + } } diff --git a/backend/src/timesheet/timesheet.service.spec.ts b/backend/src/timesheet/timesheet.service.spec.ts index fb93254..2539dda 100644 --- a/backend/src/timesheet/timesheet.service.spec.ts +++ b/backend/src/timesheet/timesheet.service.spec.ts @@ -49,7 +49,8 @@ describe('TimesheetService', () => { service = module.get(TimesheetService); prisma = module.get(PrismaService); - projectMemberService = module.get(ProjectMemberService); + projectMemberService = + module.get(ProjectMemberService); }); it('should be defined', () => { @@ -66,13 +67,13 @@ describe('TimesheetService', () => { }; const result = await service.create(createDto as any, 1); - + expect(result).toEqual(mockTimesheet); - expect(projectMemberService.checkPermission).toHaveBeenCalledWith( - 1, - 1, - [ProjectRole.OWNER, ProjectRole.ADMIN, ProjectRole.MEMBER] - ); + expect(projectMemberService.checkPermission).toHaveBeenCalledWith(1, 1, [ + ProjectRole.OWNER, + ProjectRole.ADMIN, + ProjectRole.MEMBER, + ]); expect(prisma.timesheet.create).toHaveBeenCalled(); }); }); diff --git a/backend/src/timesheet/timesheet.service.ts b/backend/src/timesheet/timesheet.service.ts index 884698f..942092b 100644 --- a/backend/src/timesheet/timesheet.service.ts +++ b/backend/src/timesheet/timesheet.service.ts @@ -1,8 +1,4 @@ -import { - Injectable, - ForbiddenException, - NotFoundException, -} from '@nestjs/common'; +import { Injectable, NotFoundException } from '@nestjs/common'; import { CreateTimesheetInput } from './dto/create-timesheet.input'; import { UpdateTimesheetInput } from './dto/update-timesheet.input'; import { PrismaService } from 'src/prisma/prisma.service'; @@ -17,7 +13,7 @@ export class TimesheetService { ) {} get includeRelation() { - return { user: true, project: true, task: true }; + return { user: true, project: true, task: true, approvedBy: true }; } async create(createTimesheetInput: CreateTimesheetInput, userId: number) { @@ -28,8 +24,12 @@ export class TimesheetService { [ProjectRole.OWNER, ProjectRole.ADMIN, ProjectRole.MEMBER], ); + const cost = createTimesheetInput.hourlyRate + ? createTimesheetInput.hourlyRate * createTimesheetInput.timeSpent + : undefined; + return this.prisma.timesheet.create({ - data: createTimesheetInput, + data: { ...createTimesheetInput, cost }, include: { ...this.includeRelation }, }); } @@ -45,15 +45,19 @@ export class TimesheetService { skip, take, where: { - AND: [taskId ? { taskId } : {}, { projectId: { in: projectIds } }], + AND: [ + taskId ? { taskId } : {}, + { projectId: { in: projectIds } }, + { deletedAt: null }, + ], }, include: { ...this.includeRelation }, }); } async findOne(id: number, userId: number) { - const timesheet = await this.prisma.timesheet.findUnique({ - where: { id }, + const timesheet = await this.prisma.timesheet.findFirst({ + where: { id, deletedAt: null }, include: { ...this.includeRelation }, }); @@ -81,9 +85,21 @@ export class TimesheetService { [ProjectRole.OWNER, ProjectRole.ADMIN, ProjectRole.MEMBER], ); + let cost = updateTimesheetInput.cost; + if ( + !cost && + (updateTimesheetInput.hourlyRate || updateTimesheetInput.timeSpent) + ) { + const rate = updateTimesheetInput.hourlyRate || timesheet.hourlyRate; + const hours = updateTimesheetInput.timeSpent || timesheet.timeSpent; + if (rate && hours) { + cost = Number(rate) * hours; + } + } + return this.prisma.timesheet.update({ where: { id }, - data: updateTimesheetInput, + data: { ...updateTimesheetInput, cost }, include: { ...this.includeRelation }, }); } @@ -98,8 +114,9 @@ export class TimesheetService { [ProjectRole.OWNER, ProjectRole.ADMIN], ); - return this.prisma.timesheet.delete({ + return this.prisma.timesheet.update({ where: { id }, + data: { deletedAt: new Date() }, }); } } diff --git a/backend/src/user/dto/create-user.input.ts b/backend/src/user/dto/create-user.input.ts index 800c28d..b30119b 100644 --- a/backend/src/user/dto/create-user.input.ts +++ b/backend/src/user/dto/create-user.input.ts @@ -1,5 +1,6 @@ import { InputType, Field, registerEnumType } from '@nestjs/graphql'; import { UserRole } from '../../../prisma/generated/client'; +import { IsSanitizedString } from '../../common/decorators/sanitized-string.decorator'; export { UserRole }; registerEnumType(UserRole, { @@ -9,6 +10,7 @@ registerEnumType(UserRole, { @InputType() export class CreateUserInput { @Field() + @IsSanitizedString() name: string; @Field() @@ -24,18 +26,22 @@ export class CreateUserInput { mobile: string; @Field() + @IsSanitizedString() firstName: string; @Field({ nullable: true }) + @IsSanitizedString() lastName: string; @Field({ defaultValue: true }) status: boolean; @Field({ nullable: true }) + @IsSanitizedString() address: string; @Field({ nullable: true }) + @IsSanitizedString() bio: string; @Field({ nullable: true }) diff --git a/backend/src/user/entities/user.entity.ts b/backend/src/user/entities/user.entity.ts index 47fdba1..eb0ec36 100644 --- a/backend/src/user/entities/user.entity.ts +++ b/backend/src/user/entities/user.entity.ts @@ -15,44 +15,50 @@ export class User extends Base { password: string; @Field({ nullable: true }) - phone?: string; + phone?: string | null; @Field({ nullable: true }) - mobile?: string; + mobile?: string | null; @Field() firstName: string; @Field({ nullable: true }) - lastName?: string; + lastName?: string | null; @Field({ defaultValue: true }) status: boolean; @Field({ nullable: true }) - address?: string; + address?: string | null; @Field({ nullable: true }) - bio?: string; + bio?: string | null; @Field({ nullable: true }) - birthDate?: Date; + birthDate?: Date | null; @Field() role: string; @Field(() => [ProjectMember], { nullable: 'items' }) - projectMemberships?: [ProjectMember]; + projectMemberships?: ProjectMember[]; @Field(() => [WorkspaceMember], { nullable: 'items' }) - workspaceMembers?: [WorkspaceMember]; + workspaceMembers?: WorkspaceMember[]; @Field(() => [Task], { nullable: 'items' }) - tasks?: [Task]; + tasks?: Task[]; @Field(() => [Timesheet], { nullable: 'items' }) - timesheets?: [Timesheet]; + timesheets?: Timesheet[]; @Field(() => [CommentChat], { nullable: 'items' }) - comments?: [CommentChat]; + comments?: CommentChat[]; + + @Field(() => [Task], { nullable: 'items' }) + reportedTasks?: Task[]; + + @Field(() => [Timesheet], { nullable: 'items' }) + approvedTimesheets?: Timesheet[]; } diff --git a/backend/src/user/user.resolver.spec.ts b/backend/src/user/user.resolver.spec.ts index 3c81f96..c179d8a 100644 --- a/backend/src/user/user.resolver.spec.ts +++ b/backend/src/user/user.resolver.spec.ts @@ -5,8 +5,6 @@ import { AuthService } from '../auth/auth.service'; describe('UserResolver', () => { let resolver: UserResolver; - let userService: UserService; - let authService: AuthService; const mockUserService = { findAll: jest.fn(), @@ -31,8 +29,6 @@ describe('UserResolver', () => { }).compile(); resolver = module.get(UserResolver); - userService = module.get(UserService); - authService = module.get(AuthService); }); afterEach(() => { @@ -49,7 +45,10 @@ describe('UserResolver', () => { mockUserService.findAll.mockResolvedValue(result); expect(await resolver.users()).toBe(result); - expect(mockUserService.findAll).toHaveBeenCalledWith(undefined, undefined); + expect(mockUserService.findAll).toHaveBeenCalledWith( + undefined, + undefined, + ); }); }); }); diff --git a/backend/src/user/user.resolver.ts b/backend/src/user/user.resolver.ts index c2a9f93..90d4436 100644 --- a/backend/src/user/user.resolver.ts +++ b/backend/src/user/user.resolver.ts @@ -5,11 +5,13 @@ import { CreateUserInput, UserRole } from './dto/create-user.input'; import { UpdateUserInput } from './dto/update-user.input'; import * as bcrypt from 'bcrypt'; import { UseGuards } from '@nestjs/common'; +import { Throttle } from '@nestjs/throttler'; import { GqlAuthGuard } from '../auth/guards/gql-auth.guard'; import { AuthService } from '../auth/auth.service'; import { LoginResponse } from '../auth/dto/login-response'; import { Roles } from '../auth/decorators/roles.decorator'; import { RolesGuard } from '../auth/guards/roles.guard'; +import { GqlContext } from '../auth/types/context.type'; @Resolver(() => User) export class UserResolver { @@ -30,7 +32,7 @@ export class UserResolver { @Query(() => User) @UseGuards(GqlAuthGuard) - me(@Context() context: any) { + me(@Context() context: GqlContext) { return context.req.user; } @@ -59,25 +61,21 @@ export class UserResolver { } @Mutation(() => LoginResponse) + @Throttle({ default: { limit: 5, ttl: 60000 } }) // 5 login attempts per minute async login( @Args('email') email: string, @Args('password') password: string, - @Context() context: any, + @Context() context: GqlContext, ) { const user = await this.userService.findByEmail(email); if (!user) { throw new Error('User not found'); } - let isMatch = await bcrypt.compare(password, user.password); - if (!isMatch) { - // if bcrypt compare failed, try to compare plain password - // (only for migration/dev, remove in prod ideally or re-hash) - isMatch = password === user.password; - } + const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) { throw new Error('Invalid credentials'); } - const loginResponse = await this.authService.login(user); + const loginResponse = this.authService.login(user); context.res.cookie('access_token', loginResponse.access_token, { httpOnly: true, @@ -90,9 +88,10 @@ export class UserResolver { } @Mutation(() => LoginResponse) + @Throttle({ default: { limit: 3, ttl: 60000 } }) // 3 registration attempts per minute async register( @Args('createUserInput') createUserInput: CreateUserInput, - @Context() context: any, + @Context() context: GqlContext, ) { // Ensure role is always USER for public registration const inputWithUserRole = { @@ -100,7 +99,10 @@ export class UserResolver { role: UserRole.USER, }; const user = await this.userService.create(inputWithUserRole); - const loginResponse = await this.authService.login(user); + if (!user) { + throw new Error('Registration failed'); + } + const loginResponse = this.authService.login(user); context.res.cookie('access_token', loginResponse.access_token, { httpOnly: true, @@ -113,7 +115,7 @@ export class UserResolver { } @Mutation(() => Boolean) - async logout(@Context() context: any) { + logout(@Context() context: GqlContext) { context.res.clearCookie('access_token'); return true; } diff --git a/backend/src/user/user.service.spec.ts b/backend/src/user/user.service.spec.ts index 7a02ec5..f236188 100644 --- a/backend/src/user/user.service.spec.ts +++ b/backend/src/user/user.service.spec.ts @@ -85,7 +85,7 @@ describe('UserService', () => { }; const result = await service.create(createDto as any); - + expect(prisma.$transaction).toHaveBeenCalled(); expect(prisma.user.create).toHaveBeenCalled(); expect(prisma.workspace.create).toHaveBeenCalled(); diff --git a/backend/src/workspace/dto/create-workspace.input.ts b/backend/src/workspace/dto/create-workspace.input.ts index 1ee0c22..f43bee6 100644 --- a/backend/src/workspace/dto/create-workspace.input.ts +++ b/backend/src/workspace/dto/create-workspace.input.ts @@ -1,10 +1,13 @@ import { InputType, Field } from '@nestjs/graphql'; +import { IsSanitizedString } from '../../common/decorators/sanitized-string.decorator'; @InputType() export class CreateWorkspaceInput { @Field() + @IsSanitizedString() name: string; @Field({ nullable: true }) + @IsSanitizedString() description?: string; } diff --git a/backend/src/workspace/entities/workspace.entity.ts b/backend/src/workspace/entities/workspace.entity.ts index 9b1bda1..82a159e 100644 --- a/backend/src/workspace/entities/workspace.entity.ts +++ b/backend/src/workspace/entities/workspace.entity.ts @@ -11,7 +11,7 @@ export class Workspace { name: string; @Field({ nullable: true }) - description?: string; + description?: string | null; @Field(() => [WorkspaceMember], { nullable: 'items' }) members?: WorkspaceMember[]; diff --git a/backend/src/workspace/workspace.resolver.spec.ts b/backend/src/workspace/workspace.resolver.spec.ts index 9ac9c46..d69f5f3 100644 --- a/backend/src/workspace/workspace.resolver.spec.ts +++ b/backend/src/workspace/workspace.resolver.spec.ts @@ -4,7 +4,6 @@ import { WorkspaceService } from './workspace.service'; describe('WorkspaceResolver', () => { let resolver: WorkspaceResolver; - let service: WorkspaceService; const mockService = { create: jest.fn(), @@ -24,7 +23,6 @@ describe('WorkspaceResolver', () => { }).compile(); resolver = module.get(WorkspaceResolver); - service = module.get(WorkspaceService); }); afterEach(() => { @@ -38,11 +36,11 @@ describe('WorkspaceResolver', () => { describe('createWorkspace', () => { it('should call service with correct arguments', async () => { const input = { name: 'Test Workspace', description: 'Test Description' }; - const user = { id: 1 }; + const user = { id: 1 } as any; mockService.create.mockResolvedValue({ id: 1, ...input, ownerId: 1 }); await resolver.createWorkspace(input, user); - + expect(mockService.create).toHaveBeenCalledWith(input, user.id); }); }); diff --git a/backend/src/workspace/workspace.resolver.ts b/backend/src/workspace/workspace.resolver.ts index 194450d..9f90d7a 100644 --- a/backend/src/workspace/workspace.resolver.ts +++ b/backend/src/workspace/workspace.resolver.ts @@ -10,6 +10,7 @@ import { RemoveWorkspaceMemberInput } from './dto/remove-workspace-member.input' import { WorkspaceMember } from './entities/workspace-member.entity'; import { GqlAuthGuard } from 'src/auth/guards/gql-auth.guard'; import { CurrentUser } from 'src/auth/decorators/current-user.decorator'; +import { User } from 'src/user/entities/user.entity'; @Resolver(() => Workspace) export class WorkspaceResolver { @@ -19,14 +20,14 @@ export class WorkspaceResolver { @UseGuards(GqlAuthGuard) createWorkspace( @Args('createWorkspaceInput') createWorkspaceInput: CreateWorkspaceInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.workspaceService.create(createWorkspaceInput, user.id); } @Query(() => [Workspace]) @UseGuards(GqlAuthGuard) - workspaces(@CurrentUser() user: any) { + workspaces(@CurrentUser() user: User) { return this.workspaceService.findAll(user.id); } @@ -34,7 +35,7 @@ export class WorkspaceResolver { @UseGuards(GqlAuthGuard) workspace( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.workspaceService.findOne(id, user.id); } @@ -43,7 +44,7 @@ export class WorkspaceResolver { @UseGuards(GqlAuthGuard) updateWorkspace( @Args('updateWorkspaceInput') updateWorkspaceInput: UpdateWorkspaceInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.workspaceService.update( updateWorkspaceInput.id, @@ -56,7 +57,7 @@ export class WorkspaceResolver { @UseGuards(GqlAuthGuard) removeWorkspace( @Args('id', { type: () => Int }) id: number, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.workspaceService.remove(id, user.id); } @@ -65,7 +66,7 @@ export class WorkspaceResolver { @UseGuards(GqlAuthGuard) inviteToWorkspace( @Args('input') input: InviteToWorkspaceInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.workspaceService.inviteUser( input.workspaceId, @@ -79,7 +80,7 @@ export class WorkspaceResolver { @UseGuards(GqlAuthGuard) updateWorkspaceMemberRole( @Args('input') input: UpdateWorkspaceMemberRoleInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.workspaceService.updateMemberRole( input.workspaceId, @@ -93,7 +94,7 @@ export class WorkspaceResolver { @UseGuards(GqlAuthGuard) removeMemberFromWorkspace( @Args('input') input: RemoveWorkspaceMemberInput, - @CurrentUser() user: any, + @CurrentUser() user: User, ) { return this.workspaceService.removeMember( input.workspaceId, diff --git a/backend/src/workspace/workspace.service.spec.ts b/backend/src/workspace/workspace.service.spec.ts index 22a512d..bf2764a 100644 --- a/backend/src/workspace/workspace.service.spec.ts +++ b/backend/src/workspace/workspace.service.spec.ts @@ -4,7 +4,6 @@ import { PrismaService } from 'src/prisma/prisma.service'; describe('WorkspaceService', () => { let service: WorkspaceService; - let prisma: PrismaService; const mockPrisma = { workspace: { @@ -32,7 +31,6 @@ describe('WorkspaceService', () => { }).compile(); service = module.get(WorkspaceService); - prisma = module.get(PrismaService); }); afterEach(() => { @@ -46,10 +44,14 @@ describe('WorkspaceService', () => { describe('create', () => { it('should create a workspace successfully', async () => { const input = { name: 'Test Workspace', description: 'Test Description' }; - mockPrisma.workspace.create.mockResolvedValue({ id: 1, ...input, ownerId: 1 }); + mockPrisma.workspace.create.mockResolvedValue({ + id: 1, + ...input, + ownerId: 1, + }); const result = await service.create(input, 1); - + expect(result).toBeDefined(); expect(mockPrisma.workspace.create).toHaveBeenCalled(); }); diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index d94e7de..d05c0e2 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -6,7 +6,7 @@ import tseslint from 'typescript-eslint' import { globalIgnores } from 'eslint/config' export default tseslint.config([ - globalIgnores(['dist']), + globalIgnores(['dist', '**/*.test.tsx', '**/*.spec.tsx', '**/*.test.ts', '**/*.spec.ts']), { files: ['**/*.{ts,tsx}'], extends: [ @@ -19,5 +19,8 @@ export default tseslint.config([ ecmaVersion: 2020, globals: globals.browser, }, + rules: { + 'react-refresh/only-export-components': 'off' + }, }, ]) diff --git a/frontend/index.html b/frontend/index.html index b19f21c..c93ffa7 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -2,7 +2,7 @@ - + Project Flow App diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 91399b8..f8a00e3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,11 +9,18 @@ "version": "0.1.0", "dependencies": { "@apollo/client": "^3.13.8", + "@fullcalendar/core": "^6.1.20", + "@fullcalendar/daygrid": "^6.1.20", + "@fullcalendar/interaction": "^6.1.20", + "@fullcalendar/list": "^6.1.20", + "@fullcalendar/react": "^6.1.20", + "@fullcalendar/timegrid": "^6.1.20", "@hello-pangea/dnd": "^18.0.1", "@types/leaflet": "^1.9.21", "apollo-upload-client": "^18.0.1", "emoji-picker-react": "^4.17.3", "graphql": "^16.11.0", + "graphql-ws": "^6.0.8", "leaflet": "^1.9.4", "linkify-react": "^4.3.2", "linkifyjs": "^4.3.2", @@ -23,7 +30,9 @@ "react-hook-form": "^7.62.0", "react-leaflet": "^5.0.0", "react-router-dom": "^7.6.3", - "socket.io-client": "^4.8.3" + "recharts": "^3.8.1", + "socket.io-client": "^4.8.3", + "zustand": "^5.0.12" }, "devDependencies": { "@eslint/js": "^9.29.0", @@ -1230,6 +1239,65 @@ "dev": true, "license": "MIT" }, + "node_modules/@fullcalendar/core": { + "version": "6.1.20", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.20.tgz", + "integrity": "sha512-1cukXLlePFiJ8YKXn/4tMKsy0etxYLCkXk8nUCFi11nRONF2Ba2CD5b21/ovtOO2tL6afTJfwmc1ed3HG7eB1g==", + "license": "MIT", + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/daygrid": { + "version": "6.1.20", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.20.tgz", + "integrity": "sha512-AO9vqhkLP77EesmJzuU+IGXgxNulsA8mgQHynclJ8U70vSwAVnbcLG9qftiTAFSlZjiY/NvhE7sflve6cJelyQ==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.20" + } + }, + "node_modules/@fullcalendar/interaction": { + "version": "6.1.20", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.20.tgz", + "integrity": "sha512-p6txmc5txL0bMiPaJxe2ip6o0T384TyoD2KGdsU6UjZ5yoBlaY+dg7kxfnYKpYMzEJLG58n+URrHr2PgNL2fyA==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.20" + } + }, + "node_modules/@fullcalendar/list": { + "version": "6.1.20", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.20.tgz", + "integrity": "sha512-7Hzkbb7uuSqrXwTyD0Ld/7SwWNxPD6SlU548vtkIpH55rZ4qquwtwYdMPgorHos5OynHA4OUrZNcH51CjrCf2g==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.20" + } + }, + "node_modules/@fullcalendar/react": { + "version": "6.1.20", + "resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-6.1.20.tgz", + "integrity": "sha512-1w0pZtceaUdfAnxMSCGHCQalhi+mR1jOe76sXzyAXpcPz/Lf0zHSdcGK/U2XpZlnQgQtBZW+d+QBnnzVQKCxAA==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.20", + "react": "^16.7.0 || ^17 || ^18 || ^19", + "react-dom": "^16.7.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/@fullcalendar/timegrid": { + "version": "6.1.20", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.20.tgz", + "integrity": "sha512-4H+/MWbz3ntA50lrPif+7TsvMeX3R1GSYjiLULz0+zEJ7/Yfd9pupZmAwUs/PBpA6aAcFmeRr0laWfcz1a9V1A==", + "license": "MIT", + "dependencies": { + "@fullcalendar/daygrid": "~6.1.20" + }, + "peerDependencies": { + "@fullcalendar/core": "~6.1.20" + } + }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", @@ -1574,6 +1642,42 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", + "integrity": "sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@reduxjs/toolkit/node_modules/immer": { + "version": "11.1.8", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.8.tgz", + "integrity": "sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.19", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", @@ -1937,6 +2041,18 @@ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "license": "MIT" }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@swc/helpers": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", @@ -2128,6 +2244,69 @@ "assertion-error": "^2.0.1" } }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", @@ -3109,7 +3288,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3237,6 +3415,127 @@ "devOptional": true, "license": "MIT" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/data-urls": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", @@ -3275,6 +3574,12 @@ "dev": true, "license": "MIT" }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -3402,6 +3707,16 @@ "dev": true, "license": "MIT" }, + "node_modules/es-toolkit": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.0.tgz", + "integrity": "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/esbuild": { "version": "0.27.7", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", @@ -3655,6 +3970,12 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -3981,6 +4302,32 @@ "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, + "node_modules/graphql-ws": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-6.0.8.tgz", + "integrity": "sha512-m3EOaNsUBXwAnkBWbzPfe0Nq8pXUfxsWnolC54sru3FzHvhTZL0Ouf/BoQsaGAXqM+YPerXOJ47BUnmgmoupCw==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@fastify/websocket": "^10 || ^11", + "crossws": "~0.3", + "graphql": "^15.10.1 || ^16", + "ws": "^8" + }, + "peerDependenciesMeta": { + "@fastify/websocket": { + "optional": true + }, + "crossws": { + "optional": true + }, + "ws": { + "optional": true + } + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4084,6 +4431,16 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -4121,6 +4478,15 @@ "node": ">=8" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -5101,6 +5467,16 @@ "dev": true, "license": "MIT" }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5375,6 +5751,36 @@ "node": ">=8.10.0" } }, + "node_modules/recharts": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.8.1.tgz", + "integrity": "sha512-mwzmO1s9sFL0TduUpwndxCUNoXsBw3u3E/0+A+cLcrSfQitSG62L32N69GhqUrrT5qKcAE3pCGVINC6pqkBBQg==", + "license": "MIT", + "workspaces": [ + "www" + ], + "dependencies": { + "@reduxjs/toolkit": "^1.9.0 || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^10.1.1", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.1.1", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -5395,6 +5801,15 @@ "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", "license": "MIT" }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/rehackt": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.1.0.tgz", @@ -5413,6 +5828,12 @@ } } }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -6307,6 +6728,28 @@ "dev": true, "license": "MIT" }, + "node_modules/victory-vendor": { + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/vite": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", @@ -6817,6 +7260,35 @@ "dependencies": { "zen-observable": "0.8.15" } + }, + "node_modules/zustand": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz", + "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/frontend/package.json b/frontend/package.json index 13e1bf5..77766dd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,11 +16,18 @@ }, "dependencies": { "@apollo/client": "^3.13.8", + "@fullcalendar/core": "^6.1.20", + "@fullcalendar/daygrid": "^6.1.20", + "@fullcalendar/interaction": "^6.1.20", + "@fullcalendar/list": "^6.1.20", + "@fullcalendar/react": "^6.1.20", + "@fullcalendar/timegrid": "^6.1.20", "@hello-pangea/dnd": "^18.0.1", "@types/leaflet": "^1.9.21", "apollo-upload-client": "^18.0.1", "emoji-picker-react": "^4.17.3", "graphql": "^16.11.0", + "graphql-ws": "^6.0.8", "leaflet": "^1.9.4", "linkify-react": "^4.3.2", "linkifyjs": "^4.3.2", @@ -30,30 +37,32 @@ "react-hook-form": "^7.62.0", "react-leaflet": "^5.0.0", "react-router-dom": "^7.6.3", - "socket.io-client": "^4.8.3" + "recharts": "^3.8.1", + "socket.io-client": "^4.8.3", + "zustand": "^5.0.12" }, "devDependencies": { "@eslint/js": "^9.29.0", "@headlessui/react": "^2.2.6", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", "@types/apollo-upload-client": "^18.0.1", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^4.5.2", + "@vitest/coverage-v8": "^3.0.0", "autoprefixer": "^10.4.21", "eslint": "^9.29.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.2.0", + "jsdom": "^26.0.0", "postcss": "^8.5.6", "prettier": "3.6.2", "tailwindcss": "^3.4.17", "typescript": "~5.8.3", "typescript-eslint": "^8.34.1", "vite": "^7.0.0", - "vitest": "^3.0.0", - "@testing-library/react": "^16.2.0", - "@testing-library/jest-dom": "^6.6.3", - "jsdom": "^26.0.0", - "@vitest/coverage-v8": "^3.0.0" + "vitest": "^3.0.0" } } diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 0000000..810df96 Binary files /dev/null and b/frontend/public/favicon.ico differ diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a2b3a78..c20519e 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,13 +1,10 @@ -import { AuthProvider } from './context/AuthProvider'; -import { WorkspaceProvider } from './context/WorkspaceProvider'; import { AppRoutes } from './AppRoutes'; +import { AppInit } from './components/AppInit'; export default function App() { return ( - - - - - + + + ); } diff --git a/frontend/src/AppRoutes.tsx b/frontend/src/AppRoutes.tsx index 8bb6a32..8ab665a 100644 --- a/frontend/src/AppRoutes.tsx +++ b/frontend/src/AppRoutes.tsx @@ -1,19 +1,57 @@ +import { lazy, Suspense } from 'react'; import { Routes, Route } from 'react-router-dom'; -import HomePage from './pages/Home'; -import LoginPage from './features/auth/pages/LoginPage'; -import RegisterPage from './features/auth/pages/RegisterPage'; import { ProtectedRoute } from './components/ProtectedRoute'; -import DashboardLayout from './layout/DashboardLayout'; +import PublicLayout from './layout/PublicLayout'; + +// Lazy load route pages +const HomePage = lazy(() => import('./pages/Home')); +const LoginPage = lazy(() => import('./features/auth/pages/LoginPage')); +const RegisterPage = lazy(() => import('./features/auth/pages/RegisterPage')); +const DashboardLayout = lazy(() => import('./layout/DashboardLayout')); + +// Stylish modern loader component +const RouteLoader = () => ( +
+
+ +
+); export const AppRoutes = () => { return ( - - } /> - } /> - } /> - }> - } /> - - + }> + + }> + } /> + } /> + } /> + + }> + } /> + + + ); }; diff --git a/frontend/src/apollo.ts b/frontend/src/apollo.ts index 1375f0c..ebe41a4 100644 --- a/frontend/src/apollo.ts +++ b/frontend/src/apollo.ts @@ -1,4 +1,7 @@ -import { ApolloClient, InMemoryCache } from '@apollo/client'; +import { ApolloClient, InMemoryCache, split } from '@apollo/client'; +import { getMainDefinition } from '@apollo/client/utilities'; +import { GraphQLWsLink } from '@apollo/client/link/subscriptions'; +import { createClient } from 'graphql-ws'; import createUploadLink from 'apollo-upload-client/createUploadLink.mjs'; import { GRAPHQL_URL } from './config/api'; @@ -11,7 +14,85 @@ const httpLink = createUploadLink({ credentials: 'include', }); +const wsLink = new GraphQLWsLink( + createClient({ + url: (() => { + if (GRAPHQL_URL.startsWith('http')) { + return GRAPHQL_URL.replace(/^http/, 'ws'); + } + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + return `${protocol}//${window.location.host}/graphql`; + })(), + }), +); + +const splitLink = split( + ({ query }) => { + const definition = getMainDefinition(query); + return ( + definition.kind === 'OperationDefinition' && + definition.operation === 'subscription' + ); + }, + wsLink, + httpLink, +); + export const client = new ApolloClient({ - link: httpLink, - cache: new InMemoryCache(), + link: splitLink, + cache: new InMemoryCache({ + typePolicies: { + Query: { + fields: { + conversationMessages: { + // Key by the conversationId parameter only, ignore cursor/limit for the cache key + keyArgs: ['conversationId'], + merge(existing = [], incoming) { + // De-duplicate messages based on id + const merged = [...existing] as { + __ref?: string; + id?: string | number; + }[]; + const incomingMap = new Map< + string | number | undefined, + { __ref?: string; id?: string | number } + >( + incoming.map( + (item: { __ref?: string; id?: string | number }) => [ + item.__ref || item.id, + item, + ], + ), + ); + + for (let i = 0; i < merged.length; i++) { + const itemRefOrId = merged[i].__ref || merged[i].id; + if (incomingMap.has(itemRefOrId)) { + merged[i] = incomingMap.get(itemRefOrId) as { + __ref?: string; + id?: string | number; + }; + incomingMap.delete(itemRefOrId); + } + } + + return [...merged, ...Array.from(incomingMap.values())]; + }, + }, + users: { + keyArgs: false, // Cache globally as a single list, skip pagination args + merge(_, incoming) { + return incoming; + }, + }, + projects: { + keyArgs: false, + merge(_, incoming) { + return incoming; + }, + }, + }, + }, + }, + }), }); diff --git a/frontend/src/components/AppInit.tsx b/frontend/src/components/AppInit.tsx new file mode 100644 index 0000000..dab1263 --- /dev/null +++ b/frontend/src/components/AppInit.tsx @@ -0,0 +1,57 @@ +import { useEffect } from 'react'; +import { useApolloClient } from '@apollo/client'; +import { GET_ME } from '../features/auth/gql/auth.graphql'; +import { useAuthStore } from '../store/authStore'; +import { useWorkspaceStore } from '../store/workspaceStore'; +import type { WorkspaceMember, Workspace } from '../types/Workspaces'; +import Logger from '../lib/logger'; + +export const AppInit = ({ children }: { children: React.ReactNode }) => { + const client = useApolloClient(); + const setAuth = useAuthStore((state) => state.setAuth); + const setLoadingAuth = useAuthStore((state) => state.setLoading); + const loadingAuth = useAuthStore((state) => state.loading); + const user = useAuthStore((state) => state.user); + + const setWorkspaces = useWorkspaceStore((state) => state.setWorkspaces); + + useEffect(() => { + const checkSession = async () => { + try { + const { data } = await client.query({ + query: GET_ME, + fetchPolicy: 'network-only', + }); + if (data?.me) { + setAuth(data.me, 'logged_in'); + } else { + setLoadingAuth(false); + } + } catch (error) { + Logger.error('Session check failed:', error); + setLoadingAuth(false); + } + }; + + checkSession(); + }, [client, setAuth, setLoadingAuth]); + + useEffect(() => { + if (user && user.workspaceMembers) { + const availableWorkspaces = user.workspaceMembers + .map((m: WorkspaceMember) => m.workspace) + .filter((w): w is Workspace => !!w); + setWorkspaces(availableWorkspaces); + } + }, [user, setWorkspaces]); + + if (loadingAuth) { + return ( +
+
+
+ ); + } + + return <>{children}; +}; diff --git a/frontend/src/components/Breadcrumbs.tsx b/frontend/src/components/Breadcrumbs.tsx new file mode 100644 index 0000000..40e7351 --- /dev/null +++ b/frontend/src/components/Breadcrumbs.tsx @@ -0,0 +1,83 @@ +import { useMemo } from 'react'; +import { useLocation, Link } from 'react-router-dom'; +import { ChevronRight, Home } from 'lucide-react'; + +/** + * Auto-generates a breadcrumb trail from the current URL. + * Supports dynamic segments like :projectId → shows "Project #id" + */ +export default function Breadcrumbs() { + const location = useLocation(); + + const crumbs = useMemo(() => { + const parts = location.pathname + .replace(/^\/dashboard\/?/, '') // strip /dashboard prefix + .split('/') + .filter(Boolean); + + if (parts.length === 0) return []; + + const result: { label: string; path: string }[] = []; + let accumulated = '/dashboard'; + + for (let i = 0; i < parts.length; i++) { + const segment = parts[i]; + accumulated += `/${segment}s`; + + // Humanize the segment + let label = segment; + const prevSegment = parts[i - 1]; + + if (/^\d+$/.test(segment)) { + // Numeric ID — contextual label + if (prevSegment === 'projects') label = `Project #${segment}`; + else if (prevSegment === 'tasks') label = `Task #${segment}`; + else if (prevSegment === 'timesheets') label = `Timesheet #${segment}`; + else if (prevSegment === 'users') label = `User #${segment}`; + else label = `#${segment}`; + } else { + // Capitalize and clean + label = segment + .replace(/[-_]/g, ' ') + .replace(/\b\w/g, (c) => c.toUpperCase()); + } + + result.push({ label, path: accumulated }); + } + + return result; + }, [location.pathname]); + + if (crumbs.length === 0) return null; + + return ( + + ); +} diff --git a/frontend/src/components/CommandPalette.tsx b/frontend/src/components/CommandPalette.tsx new file mode 100644 index 0000000..5442ea1 --- /dev/null +++ b/frontend/src/components/CommandPalette.tsx @@ -0,0 +1,375 @@ +import { useState, useEffect, useRef, useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useQuery } from '@apollo/client'; +import { + Search, + FolderGit2, + ListTodo, + Users, + LayoutDashboard, + CalendarDays, + GanttChartIcon, + Timer, + Settings, + User, + MessageSquare, + ArrowRight, + Hash, +} from 'lucide-react'; +import { GET_TASKS } from '../features/tasks/gql/task.graphql'; +import { GET_PROJECTS } from '../features/projects/gql/project.graphql'; +import { useWorkspaceStore } from '../store/workspaceStore'; + +interface CommandItem { + id: string; + label: string; + description?: string; + icon: React.ElementType; + action: () => void; + category: string; + keywords?: string; +} + +interface Props { + isOpen: boolean; + onClose: () => void; +} + +function useCommandItems( + navigate: ReturnType, + onClose: () => void, +) { + const activeWorkspace = useWorkspaceStore( + (state: { activeWorkspace: { id?: number } | null }) => + state.activeWorkspace, + ); + + const { data: tasksData } = useQuery<{ + tasks: { + id: number; + title: string; + project: { id: number; name: string }; + }[]; + }>(GET_TASKS, { + variables: { take: 50 }, + skip: !activeWorkspace, + }); + + const { data: projectsData } = useQuery<{ + projects: { id: number; name: string }[]; + }>(GET_PROJECTS, { + variables: { workspaceId: activeWorkspace?.id, take: 50 }, + skip: !activeWorkspace, + }); + + const go = useCallback( + (path: string) => { + navigate(path); + onClose(); + }, + [navigate, onClose], + ); + + const staticItems: CommandItem[] = [ + { + id: 'nav-dashboard', + label: 'Dashboard Overview', + icon: LayoutDashboard, + action: () => go('/dashboard'), + category: 'Navigate', + keywords: 'home overview stats', + }, + { + id: 'nav-projects', + label: 'Projects', + icon: FolderGit2, + action: () => go('/dashboard/projects'), + category: 'Navigate', + keywords: 'kanban board', + }, + { + id: 'nav-tasks', + label: 'Tasks', + icon: ListTodo, + action: () => go('/dashboard/tasks'), + category: 'Navigate', + keywords: 'kanban board list', + }, + { + id: 'nav-calendar', + label: 'Calendar', + icon: CalendarDays, + action: () => go('/dashboard/calendar'), + category: 'Navigate', + keywords: 'schedule dates', + }, + { + id: 'nav-timeline', + label: 'Timeline / Gantt', + icon: GanttChartIcon, + action: () => go('/dashboard/timeline'), + category: 'Navigate', + keywords: 'gantt chart', + }, + { + id: 'nav-timesheets', + label: 'Timesheets', + icon: Timer, + action: () => go('/dashboard/timesheets'), + category: 'Navigate', + keywords: 'time tracking hours', + }, + { + id: 'nav-users', + label: 'Users', + icon: Users, + action: () => go('/dashboard/users'), + category: 'Navigate', + keywords: 'team members admin', + }, + { + id: 'nav-discuss', + label: 'Discuss / Chat', + icon: MessageSquare, + action: () => go('/dashboard/discuss'), + category: 'Navigate', + keywords: 'messages channels', + }, + { + id: 'nav-profile', + label: 'My Profile', + icon: User, + action: () => go('/dashboard/profile'), + category: 'Navigate', + keywords: 'account settings', + }, + { + id: 'nav-workspace', + label: 'Workspace Settings', + icon: Settings, + action: () => go('/dashboard/workspace/settings'), + category: 'Navigate', + keywords: 'config stages members', + }, + { + id: 'new-project', + label: 'Create New Project', + icon: FolderGit2, + action: () => go('/dashboard/project/new'), + category: 'Actions', + keywords: 'add create', + }, + { + id: 'new-task', + label: 'Create New Task', + icon: ListTodo, + action: () => go('/dashboard/task/new'), + category: 'Actions', + keywords: 'add create', + }, + ]; + + const taskItems: CommandItem[] = (tasksData?.tasks ?? []).map((task) => ({ + id: `task-${task.id}`, + label: task.title, + description: task.project.name, + icon: Hash, + action: () => go(`/dashboard/task/${task.id}`), + category: 'Tasks', + keywords: task.title.toLowerCase(), + })); + + const projectItems: CommandItem[] = (projectsData?.projects ?? []).map( + (p) => ({ + id: `project-${p.id}`, + label: p.name, + icon: FolderGit2, + action: () => go(`/dashboard/project/${p.id}`), + category: 'Projects', + keywords: p.name.toLowerCase(), + }), + ); + + return [...staticItems, ...taskItems, ...projectItems]; +} + +export default function CommandPalette({ isOpen, onClose }: Props) { + const navigate = useNavigate(); + const [query, setQuery] = useState(''); + const [activeIndex, setActiveIndex] = useState(0); + const inputRef = useRef(null); + const listRef = useRef(null); + + const allItems = useCommandItems(navigate, onClose); + + const filtered = query.trim() + ? allItems.filter((item) => { + const q = query.toLowerCase(); + return ( + item.label.toLowerCase().includes(q) || + item.description?.toLowerCase().includes(q) || + item.keywords?.toLowerCase().includes(q) || + item.category.toLowerCase().includes(q) + ); + }) + : allItems.filter((item) => item.category === 'Navigate'); + + // Group by category + const grouped = filtered.reduce>( + (acc, item) => { + if (!acc[item.category]) acc[item.category] = []; + acc[item.category].push(item); + return acc; + }, + {}, + ); + + const flatList = Object.values(grouped).flat(); + + useEffect(() => { + if (isOpen) { + setQuery(''); + setActiveIndex(0); + setTimeout(() => inputRef.current?.focus(), 50); + } + }, [isOpen]); + + useEffect(() => setActiveIndex(0), [query]); + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'ArrowDown') { + e.preventDefault(); + setActiveIndex((i) => Math.min(i + 1, flatList.length - 1)); + } else if (e.key === 'ArrowUp') { + e.preventDefault(); + setActiveIndex((i) => Math.max(i - 1, 0)); + } else if (e.key === 'Enter') { + e.preventDefault(); + flatList[activeIndex]?.action(); + } else if (e.key === 'Escape') { + onClose(); + } + }; + + // Scroll active item into view + useEffect(() => { + const el = listRef.current?.querySelector(`[data-idx="${activeIndex}"]`); + el?.scrollIntoView({ block: 'nearest' }); + }, [activeIndex]); + + if (!isOpen) return null; + + let flatIdx = 0; + + return ( + <> + {/* Backdrop */} +
+ + {/* Palette */} +
+
+ {/* Search input */} +
+ + setQuery(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="Search or type a command…" + className="flex-1 bg-transparent text-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none" + /> + + ESC + +
+ + {/* Results */} +
+ {flatList.length === 0 ? ( +
+ No results for "{query}" +
+ ) : ( + Object.entries(grouped).map(([category, items]) => ( +
+
+ {category} +
+ {items.map((item) => { + const currentIdx = flatIdx++; + const isActive = activeIndex === currentIdx; + const Icon = item.icon; + + return ( + + ); + })} +
+ )) + )} +
+ + {/* Footer hint */} +
+ + ↑↓ navigate + + + open + + + Esc close + +
+
+
+ + ); +} diff --git a/frontend/src/components/Dialog.tsx b/frontend/src/components/Dialog.tsx index cc529f5..eb1a45f 100644 --- a/frontend/src/components/Dialog.tsx +++ b/frontend/src/components/Dialog.tsx @@ -21,7 +21,7 @@ export default function Modal({ onClose, title, children, - maxWidth = 'sm:max-w-lg', + maxWidth = 'sm:max-w-2xl', }: ModalProps) { return ( @@ -35,11 +35,11 @@ export default function Modal({ leaveFrom="opacity-100" leaveTo="opacity-0" > -
+
-
+
-
-
+
+
{title && ( {title} )}
-
{children}
+
+ {children} +
diff --git a/frontend/src/components/ErrorSection.tsx b/frontend/src/components/ErrorSection.tsx index f360fe1..452819e 100644 --- a/frontend/src/components/ErrorSection.tsx +++ b/frontend/src/components/ErrorSection.tsx @@ -19,27 +19,31 @@ export default function ErrorSection({ }; return ( - <> -
-
+
+
+
{errorMessage} - close('')} - /> -
-
-
- Copy to Clipboard -
- {isCopied ? ( -
Copied Success.
- ) : null}
+ +
+
+ + {isCopied && ( + + Copied Successfully + + )}
- +
); } diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index b3f46ec..d21032b 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -1,27 +1,32 @@ import { Link } from 'react-router-dom'; -import { useAuth } from '../context/AuthProvider'; +import { useAuthStore } from '../store/authStore'; export default function Header(): React.ReactElement { - const { session } = useAuth(); + const session = useAuthStore((state) => state.session); return ( -
-
- - ProjectFlow - -