From 7748e6171b0cf3d4cee4bb619f25e62eecb37fba Mon Sep 17 00:00:00 2001 From: Jackson Roberts Date: Mon, 26 Jan 2026 17:09:18 -0600 Subject: [PATCH] Added Connectwise Compnay Syncing --- bun.lock | 43 + generated/prisma/browser.ts | 5 + generated/prisma/client.ts | 5 + generated/prisma/commonInputTypes.ts | 54 + generated/prisma/internal/class.ts | 14 +- generated/prisma/internal/prismaNamespace.ts | 106 +- .../prisma/internal/prismaNamespaceBrowser.ts | 15 +- generated/prisma/models.ts | 1 + generated/prisma/models/Company.ts | 1224 +++++++++++++++++ package.json | 5 +- prisma/schema.prisma | 15 +- src/constants.ts | 14 + src/index.ts | 10 + src/modules/cw-utils/fetchAllCompanies.ts | 27 + src/modules/cw-utils/refreshCompanies.ts | 40 + src/modules/globalEvents.ts | 7 +- src/types/ConnectWiseTypes.ts | 139 ++ utils/assignUserRole.ts | 41 + utils/createAdminRole.ts | 27 + 19 files changed, 1783 insertions(+), 9 deletions(-) create mode 100644 generated/prisma/models/Company.ts create mode 100644 src/modules/cw-utils/fetchAllCompanies.ts create mode 100644 src/modules/cw-utils/refreshCompanies.ts create mode 100644 src/types/ConnectWiseTypes.ts create mode 100644 utils/assignUserRole.ts create mode 100644 utils/createAdminRole.ts diff --git a/bun.lock b/bun.lock index 6500d50..b57b2f7 100644 --- a/bun.lock +++ b/bun.lock @@ -11,6 +11,7 @@ "@prisma/adapter-pg": "^7.3.0", "@prisma/client": "^7.3.0", "@socket.io/bun-engine": "^0.1.0", + "axios": "^1.13.3", "cors": "^2.8.6", "cuid": "^3.0.0", "hono": "^4.11.5", @@ -103,8 +104,12 @@ "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + "aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="], + "axios": ["axios@1.13.3", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-ERT8kdX7DZjtUm7IitEyV7InTHAF42iJuMArIiDIV5YtPanJkgw4hw5Dyg9fh0mihdWNn1GKaeIWErfe56UQ1g=="], + "base64id": ["base64id@2.0.0", "", {}, "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="], "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], @@ -113,12 +118,16 @@ "c12": ["c12@3.1.0", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="], + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + "chevrotain": ["chevrotain@10.5.0", "", { "dependencies": { "@chevrotain/cst-dts-gen": "10.5.0", "@chevrotain/gast": "10.5.0", "@chevrotain/types": "10.5.0", "@chevrotain/utils": "10.5.0", "lodash": "4.17.21", "regexp-to-ast": "0.5.0" } }, "sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A=="], "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + "confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], @@ -139,12 +148,16 @@ "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="], + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + "denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="], "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], "effect": ["effect@3.18.4", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA=="], @@ -155,24 +168,50 @@ "engine.io-parser": ["engine.io-parser@5.2.3", "", {}, "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q=="], + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], "fast-check": ["fast-check@3.23.2", "", { "dependencies": { "pure-rand": "^6.1.0" } }, "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A=="], + "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], + "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + "generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="], + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + "get-port-please": ["get-port-please@3.2.0", "", {}, "sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A=="], + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="], + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], "grammex": ["grammex@3.1.12", "", {}, "sha512-6ufJOsSA7LcQehIJNCO7HIBykfM7DXQual0Ny780/DEcJIpBlHRvcqEBWGPYd7hrXL2GJ3oJI1MIhaXjWmLQOQ=="], "graphmatch": ["graphmatch@1.1.0", "", {}, "sha512-0E62MaTW5rPZVRLyIJZG/YejmdA/Xr1QydHEw3Vt+qOKkMIOE8WDLc9ZX2bmAjtJFZcId4lEdrdmASsEy7D1QA=="], + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + "hono": ["hono@4.11.5", "", {}, "sha512-WemPi9/WfyMwZs+ZUXdiwcCh9Y+m7L+8vki9MzDw3jJ+W9Lc+12HGsd368Qc1vZi1xwW8BWMMsnK5efYKPdt4g=="], "http-status-codes": ["http-status-codes@2.3.0", "", {}, "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA=="], @@ -215,6 +254,8 @@ "lru.min": ["lru.min@1.1.3", "", {}, "sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], @@ -273,6 +314,8 @@ "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], + "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="], "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], diff --git a/generated/prisma/browser.ts b/generated/prisma/browser.ts index cde1741..8c56a70 100644 --- a/generated/prisma/browser.ts +++ b/generated/prisma/browser.ts @@ -32,3 +32,8 @@ export type User = Prisma.UserModel * */ export type Role = Prisma.RoleModel +/** + * Model Company + * + */ +export type Company = Prisma.CompanyModel diff --git a/generated/prisma/client.ts b/generated/prisma/client.ts index d181956..140ed38 100644 --- a/generated/prisma/client.ts +++ b/generated/prisma/client.ts @@ -54,3 +54,8 @@ export type User = Prisma.UserModel * */ export type Role = Prisma.RoleModel +/** + * Model Company + * + */ +export type Company = Prisma.CompanyModel diff --git a/generated/prisma/commonInputTypes.ts b/generated/prisma/commonInputTypes.ts index feb939f..219894b 100644 --- a/generated/prisma/commonInputTypes.ts +++ b/generated/prisma/commonInputTypes.ts @@ -148,6 +148,33 @@ export type StringNullableWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedStringNullableFilter<$PrismaModel> } +export type IntFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntFilter<$PrismaModel> | number +} + +export type IntWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number + _count?: Prisma.NestedIntFilter<$PrismaModel> + _avg?: Prisma.NestedFloatFilter<$PrismaModel> + _sum?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedIntFilter<$PrismaModel> + _max?: Prisma.NestedIntFilter<$PrismaModel> +} + export type NestedStringFilter<$PrismaModel = never> = { equals?: string | Prisma.StringFieldRefInput<$PrismaModel> in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> @@ -295,4 +322,31 @@ export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedStringNullableFilter<$PrismaModel> } +export type NestedIntWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number + _count?: Prisma.NestedIntFilter<$PrismaModel> + _avg?: Prisma.NestedFloatFilter<$PrismaModel> + _sum?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedIntFilter<$PrismaModel> + _max?: Prisma.NestedIntFilter<$PrismaModel> +} + +export type NestedFloatFilter<$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 +} + diff --git a/generated/prisma/internal/class.ts b/generated/prisma/internal/class.ts index 9cce4d3..2f5176c 100644 --- a/generated/prisma/internal/class.ts +++ b/generated/prisma/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.3.0", "engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735", "activeProvider": "postgresql", - "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel Session {\n id String @id @default(uuid())\n sessionKey String @unique @default(cuid())\n userId String\n expires DateTime\n refreshTokenGenerated Boolean @default(false)\n refreshedAt DateTime?\n invalidatedAt DateTime?\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel User {\n id String @id @default(cuid())\n roles Role[]\n permissions String?\n login String @unique\n name String?\n email String @unique\n emailVerified DateTime?\n image String?\n\n userId String @unique\n token String?\n\n sessions Session[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Role {\n id String @id @default(uuid())\n title String\n moniker String @unique // e.g. admin, super_admin, moderator\n\n permissions String\n users User[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel Session {\n id String @id @default(uuid())\n sessionKey String @unique @default(cuid())\n userId String\n expires DateTime\n refreshTokenGenerated Boolean @default(false)\n refreshedAt DateTime?\n invalidatedAt DateTime?\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel User {\n id String @id @default(cuid())\n roles Role[]\n permissions String?\n login String @unique\n name String?\n email String @unique\n emailVerified DateTime?\n image String?\n\n userId String @unique\n token String?\n\n sessions Session[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Role {\n id String @id @default(uuid())\n title String\n moniker String @unique // e.g. admin, super_admin, moderator\n\n permissions String\n users User[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Company {\n id String @id @default(cuid())\n name String\n\n cw_CompanyId Int @unique\n cw_Identifier String @unique\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionKey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expires\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenGenerated\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"refreshedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"invalidatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":null},\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roles\",\"kind\":\"object\",\"type\":\"Role\",\"relationName\":\"RoleToUser\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"login\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Role\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"moniker\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"RoleToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionKey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expires\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenGenerated\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"refreshedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"invalidatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":null},\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roles\",\"kind\":\"object\",\"type\":\"Role\",\"relationName\":\"RoleToUser\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"login\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Role\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"moniker\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"RoleToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Company\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cw_CompanyId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"cw_Identifier\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") async function decodeBase64AsWasm(wasmBase64: string): Promise { const { Buffer } = await import('node:buffer') @@ -205,6 +205,16 @@ export interface PrismaClient< * ``` */ get role(): Prisma.RoleDelegate; + + /** + * `prisma.company`: Exposes CRUD operations for the **Company** model. + * Example usage: + * ```ts + * // Fetch zero or more Companies + * const companies = await prisma.company.findMany() + * ``` + */ + get company(): Prisma.CompanyDelegate; } export function getPrismaClientClass(): PrismaClientConstructor { diff --git a/generated/prisma/internal/prismaNamespace.ts b/generated/prisma/internal/prismaNamespace.ts index 6fdc93d..e55030e 100644 --- a/generated/prisma/internal/prismaNamespace.ts +++ b/generated/prisma/internal/prismaNamespace.ts @@ -386,7 +386,8 @@ type FieldRefInputType = Model extends never ? never : FieldRe export const ModelName = { Session: 'Session', User: 'User', - Role: 'Role' + Role: 'Role', + Company: 'Company' } as const export type ModelName = (typeof ModelName)[keyof typeof ModelName] @@ -402,7 +403,7 @@ export type TypeMap + fields: Prisma.CompanyFieldRefs + operations: { + findUnique: { + args: Prisma.CompanyFindUniqueArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findUniqueOrThrow: { + args: Prisma.CompanyFindUniqueOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findFirst: { + args: Prisma.CompanyFindFirstArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findFirstOrThrow: { + args: Prisma.CompanyFindFirstOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findMany: { + args: Prisma.CompanyFindManyArgs + result: runtime.Types.Utils.PayloadToResult[] + } + create: { + args: Prisma.CompanyCreateArgs + result: runtime.Types.Utils.PayloadToResult + } + createMany: { + args: Prisma.CompanyCreateManyArgs + result: BatchPayload + } + createManyAndReturn: { + args: Prisma.CompanyCreateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + delete: { + args: Prisma.CompanyDeleteArgs + result: runtime.Types.Utils.PayloadToResult + } + update: { + args: Prisma.CompanyUpdateArgs + result: runtime.Types.Utils.PayloadToResult + } + deleteMany: { + args: Prisma.CompanyDeleteManyArgs + result: BatchPayload + } + updateMany: { + args: Prisma.CompanyUpdateManyArgs + result: BatchPayload + } + updateManyAndReturn: { + args: Prisma.CompanyUpdateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + upsert: { + args: Prisma.CompanyUpsertArgs + result: runtime.Types.Utils.PayloadToResult + } + aggregate: { + args: Prisma.CompanyAggregateArgs + result: runtime.Types.Utils.Optional + } + groupBy: { + args: Prisma.CompanyGroupByArgs + result: runtime.Types.Utils.Optional[] + } + count: { + args: Prisma.CompanyCountArgs + result: runtime.Types.Utils.Optional | number + } + } + } } } & { other: { @@ -709,6 +784,18 @@ export const RoleScalarFieldEnum = { export type RoleScalarFieldEnum = (typeof RoleScalarFieldEnum)[keyof typeof RoleScalarFieldEnum] +export const CompanyScalarFieldEnum = { + id: 'id', + name: 'name', + cw_CompanyId: 'cw_CompanyId', + cw_Identifier: 'cw_Identifier', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum] + + export const SortOrder = { asc: 'asc', desc: 'desc' @@ -787,6 +874,20 @@ export type IntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'In export type ListIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Int[]'> + +/** + * Reference to a field of type 'Float' + */ +export type FloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float'> + + + +/** + * Reference to a field of type 'Float[]' + */ +export type ListFloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float[]'> + + /** * Batch Payload for updateMany & deleteMany & createMany */ @@ -885,6 +986,7 @@ export type GlobalOmitConfig = { session?: Prisma.SessionOmit user?: Prisma.UserOmit role?: Prisma.RoleOmit + company?: Prisma.CompanyOmit } /* Types for Logging */ diff --git a/generated/prisma/internal/prismaNamespaceBrowser.ts b/generated/prisma/internal/prismaNamespaceBrowser.ts index 4be0826..b6b9521 100644 --- a/generated/prisma/internal/prismaNamespaceBrowser.ts +++ b/generated/prisma/internal/prismaNamespaceBrowser.ts @@ -53,7 +53,8 @@ export const AnyNull = runtime.AnyNull export const ModelName = { Session: 'Session', User: 'User', - Role: 'Role' + Role: 'Role', + Company: 'Company' } as const export type ModelName = (typeof ModelName)[keyof typeof ModelName] @@ -114,6 +115,18 @@ export const RoleScalarFieldEnum = { export type RoleScalarFieldEnum = (typeof RoleScalarFieldEnum)[keyof typeof RoleScalarFieldEnum] +export const CompanyScalarFieldEnum = { + id: 'id', + name: 'name', + cw_CompanyId: 'cw_CompanyId', + cw_Identifier: 'cw_Identifier', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum] + + export const SortOrder = { asc: 'asc', desc: 'desc' diff --git a/generated/prisma/models.ts b/generated/prisma/models.ts index 5076f8f..99e7913 100644 --- a/generated/prisma/models.ts +++ b/generated/prisma/models.ts @@ -11,4 +11,5 @@ export type * from './models/Session.ts' export type * from './models/User.ts' export type * from './models/Role.ts' +export type * from './models/Company.ts' export type * from './commonInputTypes.ts' \ No newline at end of file diff --git a/generated/prisma/models/Company.ts b/generated/prisma/models/Company.ts new file mode 100644 index 0000000..74664f9 --- /dev/null +++ b/generated/prisma/models/Company.ts @@ -0,0 +1,1224 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file exports the `Company` model and its related types. + * + * 🟢 You can import this file directly. + */ +import type * as runtime from "@prisma/client/runtime/client" +import type * as $Enums from "../enums.ts" +import type * as Prisma from "../internal/prismaNamespace.ts" + +/** + * Model Company + * + */ +export type CompanyModel = runtime.Types.Result.DefaultSelection + +export type AggregateCompany = { + _count: CompanyCountAggregateOutputType | null + _avg: CompanyAvgAggregateOutputType | null + _sum: CompanySumAggregateOutputType | null + _min: CompanyMinAggregateOutputType | null + _max: CompanyMaxAggregateOutputType | null +} + +export type CompanyAvgAggregateOutputType = { + cw_CompanyId: number | null +} + +export type CompanySumAggregateOutputType = { + cw_CompanyId: number | null +} + +export type CompanyMinAggregateOutputType = { + id: string | null + name: string | null + cw_CompanyId: number | null + cw_Identifier: string | null + createdAt: Date | null + updatedAt: Date | null +} + +export type CompanyMaxAggregateOutputType = { + id: string | null + name: string | null + cw_CompanyId: number | null + cw_Identifier: string | null + createdAt: Date | null + updatedAt: Date | null +} + +export type CompanyCountAggregateOutputType = { + id: number + name: number + cw_CompanyId: number + cw_Identifier: number + createdAt: number + updatedAt: number + _all: number +} + + +export type CompanyAvgAggregateInputType = { + cw_CompanyId?: true +} + +export type CompanySumAggregateInputType = { + cw_CompanyId?: true +} + +export type CompanyMinAggregateInputType = { + id?: true + name?: true + cw_CompanyId?: true + cw_Identifier?: true + createdAt?: true + updatedAt?: true +} + +export type CompanyMaxAggregateInputType = { + id?: true + name?: true + cw_CompanyId?: true + cw_Identifier?: true + createdAt?: true + updatedAt?: true +} + +export type CompanyCountAggregateInputType = { + id?: true + name?: true + cw_CompanyId?: true + cw_Identifier?: true + createdAt?: true + updatedAt?: true + _all?: true +} + +export type CompanyAggregateArgs = { + /** + * Filter which Company to aggregate. + */ + where?: Prisma.CompanyWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Companies to fetch. + */ + orderBy?: Prisma.CompanyOrderByWithRelationInput | Prisma.CompanyOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the start position + */ + cursor?: Prisma.CompanyWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Companies from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Companies. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Count returned Companies + **/ + _count?: true | CompanyCountAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to average + **/ + _avg?: CompanyAvgAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to sum + **/ + _sum?: CompanySumAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the minimum value + **/ + _min?: CompanyMinAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the maximum value + **/ + _max?: CompanyMaxAggregateInputType +} + +export type GetCompanyAggregateType = { + [P in keyof T & keyof AggregateCompany]: P extends '_count' | 'count' + ? T[P] extends true + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType +} + + + + +export type CompanyGroupByArgs = { + where?: Prisma.CompanyWhereInput + orderBy?: Prisma.CompanyOrderByWithAggregationInput | Prisma.CompanyOrderByWithAggregationInput[] + by: Prisma.CompanyScalarFieldEnum[] | Prisma.CompanyScalarFieldEnum + having?: Prisma.CompanyScalarWhereWithAggregatesInput + take?: number + skip?: number + _count?: CompanyCountAggregateInputType | true + _avg?: CompanyAvgAggregateInputType + _sum?: CompanySumAggregateInputType + _min?: CompanyMinAggregateInputType + _max?: CompanyMaxAggregateInputType +} + +export type CompanyGroupByOutputType = { + id: string + name: string + cw_CompanyId: number + cw_Identifier: string + createdAt: Date + updatedAt: Date + _count: CompanyCountAggregateOutputType | null + _avg: CompanyAvgAggregateOutputType | null + _sum: CompanySumAggregateOutputType | null + _min: CompanyMinAggregateOutputType | null + _max: CompanyMaxAggregateOutputType | null +} + +type GetCompanyGroupByPayload = Prisma.PrismaPromise< + Array< + Prisma.PickEnumerable & + { + [P in ((keyof T) & (keyof CompanyGroupByOutputType))]: P extends '_count' + ? T[P] extends boolean + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType + } + > + > + + + +export type CompanyWhereInput = { + AND?: Prisma.CompanyWhereInput | Prisma.CompanyWhereInput[] + OR?: Prisma.CompanyWhereInput[] + NOT?: Prisma.CompanyWhereInput | Prisma.CompanyWhereInput[] + id?: Prisma.StringFilter<"Company"> | string + name?: Prisma.StringFilter<"Company"> | string + cw_CompanyId?: Prisma.IntFilter<"Company"> | number + cw_Identifier?: Prisma.StringFilter<"Company"> | string + createdAt?: Prisma.DateTimeFilter<"Company"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"Company"> | Date | string +} + +export type CompanyOrderByWithRelationInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + cw_CompanyId?: Prisma.SortOrder + cw_Identifier?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type CompanyWhereUniqueInput = Prisma.AtLeast<{ + id?: string + cw_CompanyId?: number + cw_Identifier?: string + AND?: Prisma.CompanyWhereInput | Prisma.CompanyWhereInput[] + OR?: Prisma.CompanyWhereInput[] + NOT?: Prisma.CompanyWhereInput | Prisma.CompanyWhereInput[] + name?: Prisma.StringFilter<"Company"> | string + createdAt?: Prisma.DateTimeFilter<"Company"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"Company"> | Date | string +}, "id" | "cw_CompanyId" | "cw_Identifier"> + +export type CompanyOrderByWithAggregationInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + cw_CompanyId?: Prisma.SortOrder + cw_Identifier?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder + _count?: Prisma.CompanyCountOrderByAggregateInput + _avg?: Prisma.CompanyAvgOrderByAggregateInput + _max?: Prisma.CompanyMaxOrderByAggregateInput + _min?: Prisma.CompanyMinOrderByAggregateInput + _sum?: Prisma.CompanySumOrderByAggregateInput +} + +export type CompanyScalarWhereWithAggregatesInput = { + AND?: Prisma.CompanyScalarWhereWithAggregatesInput | Prisma.CompanyScalarWhereWithAggregatesInput[] + OR?: Prisma.CompanyScalarWhereWithAggregatesInput[] + NOT?: Prisma.CompanyScalarWhereWithAggregatesInput | Prisma.CompanyScalarWhereWithAggregatesInput[] + id?: Prisma.StringWithAggregatesFilter<"Company"> | string + name?: Prisma.StringWithAggregatesFilter<"Company"> | string + cw_CompanyId?: Prisma.IntWithAggregatesFilter<"Company"> | number + cw_Identifier?: Prisma.StringWithAggregatesFilter<"Company"> | string + createdAt?: Prisma.DateTimeWithAggregatesFilter<"Company"> | Date | string + updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Company"> | Date | string +} + +export type CompanyCreateInput = { + id?: string + name: string + cw_CompanyId: number + cw_Identifier: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type CompanyUncheckedCreateInput = { + id?: string + name: string + cw_CompanyId: number + cw_Identifier: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type CompanyUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + cw_CompanyId?: Prisma.IntFieldUpdateOperationsInput | number + cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CompanyUncheckedUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + cw_CompanyId?: Prisma.IntFieldUpdateOperationsInput | number + cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CompanyCreateManyInput = { + id?: string + name: string + cw_CompanyId: number + cw_Identifier: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type CompanyUpdateManyMutationInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + cw_CompanyId?: Prisma.IntFieldUpdateOperationsInput | number + cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CompanyUncheckedUpdateManyInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + cw_CompanyId?: Prisma.IntFieldUpdateOperationsInput | number + cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CompanyCountOrderByAggregateInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + cw_CompanyId?: Prisma.SortOrder + cw_Identifier?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type CompanyAvgOrderByAggregateInput = { + cw_CompanyId?: Prisma.SortOrder +} + +export type CompanyMaxOrderByAggregateInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + cw_CompanyId?: Prisma.SortOrder + cw_Identifier?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type CompanyMinOrderByAggregateInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + cw_CompanyId?: Prisma.SortOrder + cw_Identifier?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type CompanySumOrderByAggregateInput = { + cw_CompanyId?: Prisma.SortOrder +} + +export type IntFieldUpdateOperationsInput = { + set?: number + increment?: number + decrement?: number + multiply?: number + divide?: number +} + + + +export type CompanySelect = runtime.Types.Extensions.GetSelect<{ + id?: boolean + name?: boolean + cw_CompanyId?: boolean + cw_Identifier?: boolean + createdAt?: boolean + updatedAt?: boolean +}, ExtArgs["result"]["company"]> + +export type CompanySelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + name?: boolean + cw_CompanyId?: boolean + cw_Identifier?: boolean + createdAt?: boolean + updatedAt?: boolean +}, ExtArgs["result"]["company"]> + +export type CompanySelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + name?: boolean + cw_CompanyId?: boolean + cw_Identifier?: boolean + createdAt?: boolean + updatedAt?: boolean +}, ExtArgs["result"]["company"]> + +export type CompanySelectScalar = { + id?: boolean + name?: boolean + cw_CompanyId?: boolean + cw_Identifier?: boolean + createdAt?: boolean + updatedAt?: boolean +} + +export type CompanyOmit = runtime.Types.Extensions.GetOmit<"id" | "name" | "cw_CompanyId" | "cw_Identifier" | "createdAt" | "updatedAt", ExtArgs["result"]["company"]> + +export type $CompanyPayload = { + name: "Company" + objects: {} + scalars: runtime.Types.Extensions.GetPayloadResult<{ + id: string + name: string + cw_CompanyId: number + cw_Identifier: string + createdAt: Date + updatedAt: Date + }, ExtArgs["result"]["company"]> + composites: {} +} + +export type CompanyGetPayload = runtime.Types.Result.GetResult + +export type CompanyCountArgs = + Omit & { + select?: CompanyCountAggregateInputType | true + } + +export interface CompanyDelegate { + [K: symbol]: { types: Prisma.TypeMap['model']['Company'], meta: { name: 'Company' } } + /** + * Find zero or one Company that matches the filter. + * @param {CompanyFindUniqueArgs} args - Arguments to find a Company + * @example + * // Get one Company + * const company = await prisma.company.findUnique({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUnique(args: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find one Company that matches the filter or throw an error with `error.code='P2025'` + * if no matches were found. + * @param {CompanyFindUniqueOrThrowArgs} args - Arguments to find a Company + * @example + * // Get one Company + * const company = await prisma.company.findUniqueOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUniqueOrThrow(args: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find the first Company that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CompanyFindFirstArgs} args - Arguments to find a Company + * @example + * // Get one Company + * const company = await prisma.company.findFirst({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirst(args?: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find the first Company that matches the filter or + * throw `PrismaKnownClientError` with `P2025` code if no matches were found. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CompanyFindFirstOrThrowArgs} args - Arguments to find a Company + * @example + * // Get one Company + * const company = await prisma.company.findFirstOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirstOrThrow(args?: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find zero or more Companies that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CompanyFindManyArgs} args - Arguments to filter and select certain fields only. + * @example + * // Get all Companies + * const companies = await prisma.company.findMany() + * + * // Get first 10 Companies + * const companies = await prisma.company.findMany({ take: 10 }) + * + * // Only select the `id` + * const companyWithIdOnly = await prisma.company.findMany({ select: { id: true } }) + * + */ + findMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions>> + + /** + * Create a Company. + * @param {CompanyCreateArgs} args - Arguments to create a Company. + * @example + * // Create one Company + * const Company = await prisma.company.create({ + * data: { + * // ... data to create a Company + * } + * }) + * + */ + create(args: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Create many Companies. + * @param {CompanyCreateManyArgs} args - Arguments to create many Companies. + * @example + * // Create many Companies + * const company = await prisma.company.createMany({ + * data: [ + * // ... provide data here + * ] + * }) + * + */ + createMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Create many Companies and returns the data saved in the database. + * @param {CompanyCreateManyAndReturnArgs} args - Arguments to create many Companies. + * @example + * // Create many Companies + * const company = await prisma.company.createManyAndReturn({ + * data: [ + * // ... provide data here + * ] + * }) + * + * // Create many Companies and only return the `id` + * const companyWithIdOnly = await prisma.company.createManyAndReturn({ + * select: { id: true }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + createManyAndReturn(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "createManyAndReturn", GlobalOmitOptions>> + + /** + * Delete a Company. + * @param {CompanyDeleteArgs} args - Arguments to delete one Company. + * @example + * // Delete one Company + * const Company = await prisma.company.delete({ + * where: { + * // ... filter to delete one Company + * } + * }) + * + */ + delete(args: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Update one Company. + * @param {CompanyUpdateArgs} args - Arguments to update one Company. + * @example + * // Update one Company + * const company = await prisma.company.update({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + update(args: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Delete zero or more Companies. + * @param {CompanyDeleteManyArgs} args - Arguments to filter Companies to delete. + * @example + * // Delete a few Companies + * const { count } = await prisma.company.deleteMany({ + * where: { + * // ... provide filter here + * } + * }) + * + */ + deleteMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more Companies. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CompanyUpdateManyArgs} args - Arguments to update one or more rows. + * @example + * // Update many Companies + * const company = await prisma.company.updateMany({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + updateMany(args: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more Companies and returns the data updated in the database. + * @param {CompanyUpdateManyAndReturnArgs} args - Arguments to update many Companies. + * @example + * // Update many Companies + * const company = await prisma.company.updateManyAndReturn({ + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * + * // Update zero or more Companies and only return the `id` + * const companyWithIdOnly = await prisma.company.updateManyAndReturn({ + * select: { id: true }, + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + updateManyAndReturn(args: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "updateManyAndReturn", GlobalOmitOptions>> + + /** + * Create or update one Company. + * @param {CompanyUpsertArgs} args - Arguments to update or create a Company. + * @example + * // Update or create a Company + * const company = await prisma.company.upsert({ + * create: { + * // ... data to create a Company + * }, + * update: { + * // ... in case it already exists, update + * }, + * where: { + * // ... the filter for the Company we want to update + * } + * }) + */ + upsert(args: Prisma.SelectSubset>): Prisma.Prisma__CompanyClient, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + + /** + * Count the number of Companies. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CompanyCountArgs} args - Arguments to filter Companies to count. + * @example + * // Count the number of Companies + * const count = await prisma.company.count({ + * where: { + * // ... the filter for the Companies we want to count + * } + * }) + **/ + count( + args?: Prisma.Subset, + ): Prisma.PrismaPromise< + T extends runtime.Types.Utils.Record<'select', any> + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number + > + + /** + * Allows you to perform aggregations operations on a Company. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CompanyAggregateArgs} args - Select which aggregations you would like to apply and on what fields. + * @example + * // Ordered by age ascending + * // Where email contains prisma.io + * // Limited to the 10 users + * const aggregations = await prisma.user.aggregate({ + * _avg: { + * age: true, + * }, + * where: { + * email: { + * contains: "prisma.io", + * }, + * }, + * orderBy: { + * age: "asc", + * }, + * take: 10, + * }) + **/ + aggregate(args: Prisma.Subset): Prisma.PrismaPromise> + + /** + * Group by Company. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {CompanyGroupByArgs} args - Group by arguments. + * @example + * // Group by city, order by createdAt, get count + * const result = await prisma.user.groupBy({ + * by: ['city', 'createdAt'], + * orderBy: { + * createdAt: true + * }, + * _count: { + * _all: true + * }, + * }) + * + **/ + groupBy< + T extends CompanyGroupByArgs, + HasSelectOrTake extends Prisma.Or< + Prisma.Extends<'skip', Prisma.Keys>, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: CompanyGroupByArgs['orderBy'] } + : { orderBy?: CompanyGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(args: Prisma.SubsetIntersection & InputErrors): {} extends InputErrors ? GetCompanyGroupByPayload : Prisma.PrismaPromise +/** + * Fields of the Company model + */ +readonly fields: CompanyFieldRefs; +} + +/** + * The delegate class that acts as a "Promise-like" for Company. + * Why is this prefixed with `Prisma__`? + * Because we want to prevent naming conflicts as mentioned in + * https://github.com/prisma/prisma-client-js/issues/707 + */ +export interface Prisma__CompanyClient extends Prisma.PrismaPromise { + readonly [Symbol.toStringTag]: "PrismaPromise" + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback for only the rejection of the Promise. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of the callback. + */ + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): runtime.Types.Utils.JsPromise +} + + + + +/** + * Fields of the Company model + */ +export interface CompanyFieldRefs { + readonly id: Prisma.FieldRef<"Company", 'String'> + readonly name: Prisma.FieldRef<"Company", 'String'> + readonly cw_CompanyId: Prisma.FieldRef<"Company", 'Int'> + readonly cw_Identifier: Prisma.FieldRef<"Company", 'String'> + readonly createdAt: Prisma.FieldRef<"Company", 'DateTime'> + readonly updatedAt: Prisma.FieldRef<"Company", 'DateTime'> +} + + +// Custom InputTypes +/** + * Company findUnique + */ +export type CompanyFindUniqueArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * Filter, which Company to fetch. + */ + where: Prisma.CompanyWhereUniqueInput +} + +/** + * Company findUniqueOrThrow + */ +export type CompanyFindUniqueOrThrowArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * Filter, which Company to fetch. + */ + where: Prisma.CompanyWhereUniqueInput +} + +/** + * Company findFirst + */ +export type CompanyFindFirstArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * Filter, which Company to fetch. + */ + where?: Prisma.CompanyWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Companies to fetch. + */ + orderBy?: Prisma.CompanyOrderByWithRelationInput | Prisma.CompanyOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for Companies. + */ + cursor?: Prisma.CompanyWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Companies from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Companies. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of Companies. + */ + distinct?: Prisma.CompanyScalarFieldEnum | Prisma.CompanyScalarFieldEnum[] +} + +/** + * Company findFirstOrThrow + */ +export type CompanyFindFirstOrThrowArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * Filter, which Company to fetch. + */ + where?: Prisma.CompanyWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Companies to fetch. + */ + orderBy?: Prisma.CompanyOrderByWithRelationInput | Prisma.CompanyOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for Companies. + */ + cursor?: Prisma.CompanyWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Companies from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Companies. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of Companies. + */ + distinct?: Prisma.CompanyScalarFieldEnum | Prisma.CompanyScalarFieldEnum[] +} + +/** + * Company findMany + */ +export type CompanyFindManyArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * Filter, which Companies to fetch. + */ + where?: Prisma.CompanyWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Companies to fetch. + */ + orderBy?: Prisma.CompanyOrderByWithRelationInput | Prisma.CompanyOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for listing Companies. + */ + cursor?: Prisma.CompanyWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Companies from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Companies. + */ + skip?: number + distinct?: Prisma.CompanyScalarFieldEnum | Prisma.CompanyScalarFieldEnum[] +} + +/** + * Company create + */ +export type CompanyCreateArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * The data needed to create a Company. + */ + data: Prisma.XOR +} + +/** + * Company createMany + */ +export type CompanyCreateManyArgs = { + /** + * The data used to create many Companies. + */ + data: Prisma.CompanyCreateManyInput | Prisma.CompanyCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * Company createManyAndReturn + */ +export type CompanyCreateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelectCreateManyAndReturn | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * The data used to create many Companies. + */ + data: Prisma.CompanyCreateManyInput | Prisma.CompanyCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * Company update + */ +export type CompanyUpdateArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * The data needed to update a Company. + */ + data: Prisma.XOR + /** + * Choose, which Company to update. + */ + where: Prisma.CompanyWhereUniqueInput +} + +/** + * Company updateMany + */ +export type CompanyUpdateManyArgs = { + /** + * The data used to update Companies. + */ + data: Prisma.XOR + /** + * Filter which Companies to update + */ + where?: Prisma.CompanyWhereInput + /** + * Limit how many Companies to update. + */ + limit?: number +} + +/** + * Company updateManyAndReturn + */ +export type CompanyUpdateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelectUpdateManyAndReturn | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * The data used to update Companies. + */ + data: Prisma.XOR + /** + * Filter which Companies to update + */ + where?: Prisma.CompanyWhereInput + /** + * Limit how many Companies to update. + */ + limit?: number +} + +/** + * Company upsert + */ +export type CompanyUpsertArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * The filter to search for the Company to update in case it exists. + */ + where: Prisma.CompanyWhereUniqueInput + /** + * In case the Company found by the `where` argument doesn't exist, create a new Company with this data. + */ + create: Prisma.XOR + /** + * In case the Company was found with the provided `where` argument, update it with this data. + */ + update: Prisma.XOR +} + +/** + * Company delete + */ +export type CompanyDeleteArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null + /** + * Filter which Company to delete. + */ + where: Prisma.CompanyWhereUniqueInput +} + +/** + * Company deleteMany + */ +export type CompanyDeleteManyArgs = { + /** + * Filter which Companies to delete + */ + where?: Prisma.CompanyWhereInput + /** + * Limit how many Companies to delete. + */ + limit?: number +} + +/** + * Company without action + */ +export type CompanyDefaultArgs = { + /** + * Select specific fields to fetch from the Company + */ + select?: Prisma.CompanySelect | null + /** + * Omit specific fields from the Company + */ + omit?: Prisma.CompanyOmit | null +} diff --git a/package.json b/package.json index dfb0424..19c5acb 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,9 @@ "db:gen": "prisma generate", "db:push": "prisma migrate dev --skip-generate", "utils:dev": "docker compose -f .docker/docker-compose.yml up --build", - "utils:gen_private_keys": "bun ./utils/genPrivateKeys" + "utils:gen_private_keys": "bun ./utils/genPrivateKeys", + "utils:create_admin_role": "bun ./utils/createAdminRole", + "utils:assign_user_role": "bun ./utils/assignUserRole" }, "dependencies": { "@azure/msal-node": "^5.0.2", @@ -30,6 +32,7 @@ "@prisma/adapter-pg": "^7.3.0", "@prisma/client": "^7.3.0", "@socket.io/bun-engine": "^0.1.0", + "axios": "^1.13.3", "cors": "^2.8.6", "cuid": "^3.0.0", "hono": "^4.11.5", diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 37a11be..38460c5 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -34,7 +34,7 @@ model User { emailVerified DateTime? image String? - userId String @unique + userId String @unique token String? sessions Session[] @@ -53,4 +53,15 @@ model Role { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt -} \ No newline at end of file +} + +model Company { + id String @id @default(cuid()) + name String + + cw_CompanyId Int @unique + cw_Identifier String @unique + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/src/constants.ts b/src/constants.ts index 0c7e775..7613d58 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,6 +4,7 @@ import { Prisma, PrismaClient } from "../generated/prisma/client"; import * as msal from "@azure/msal-node"; import { Server } from "socket.io"; import { Server as Engine } from "@socket.io/bun-engine"; +import axios from "axios"; const connectionString = `${process.env.DATABASE_URL}`; const adapter = new PrismaPg({ connectionString }); @@ -55,3 +56,16 @@ const engine = new Engine(); io.bind(engine); export { io, engine }; + +// Connectwise API Client + +const connectWiseApi = axios.create({ + baseURL: `https://ttscw.totaltech.net/v4_6_release/apis/3.0/`, + headers: { + Authorization: `Basic ${process.env.CW_BASIC_TOKEN}`, + clientId: `${process.env.CW_CLIENT_ID}`, + "Content-Type": "application/json", + }, +}); + +export { connectWiseApi }; diff --git a/src/index.ts b/src/index.ts index 01d7f15..c0e35a1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,15 @@ +import { refresh } from "./api/auth"; import app from "./api/server"; import { engine, PORT } from "./constants"; +import { refreshCompanies } from "./modules/cw-utils/refreshCompanies"; +import { events, setupEventDebugger } from "./modules/globalEvents"; + +// Setup global event debugger in non-production environments +if (Bun.env.NODE_ENV == "development") setupEventDebugger(); + +// Refresh the internal list of companies every minute +await refreshCompanies(); +setInterval(() => refreshCompanies, 60 * 1000); Bun.serve({ port: PORT, diff --git a/src/modules/cw-utils/fetchAllCompanies.ts b/src/modules/cw-utils/fetchAllCompanies.ts new file mode 100644 index 0000000..dfa0d6b --- /dev/null +++ b/src/modules/cw-utils/fetchAllCompanies.ts @@ -0,0 +1,27 @@ +import { Collection } from "@discordjs/collection"; +import { connectWiseApi } from "../../constants"; +import { Company } from "../../types/ConnectWiseTypes"; + +export const fetchAllCwCompanies = async (): Promise< + Collection +> => { + let allCompanies = new Collection(); + const pageCount = 1000; + + const count = (await connectWiseApi.get("/company/companies/count")).data + .count; + const totalPages = Math.ceil(count / pageCount); + + for (let page = 0; page < totalPages; page++) { + const response = await connectWiseApi.get( + `/company/companies?page=${page + 1}&pageSize=${pageCount}`, + ); + const companies = response.data; + + for (const company of companies) { + allCompanies.set(company.id, company); + } + } + + return allCompanies; +}; diff --git a/src/modules/cw-utils/refreshCompanies.ts b/src/modules/cw-utils/refreshCompanies.ts new file mode 100644 index 0000000..9b9e7bd --- /dev/null +++ b/src/modules/cw-utils/refreshCompanies.ts @@ -0,0 +1,40 @@ +import { connectWiseApi, prisma } from "../../constants"; +import { events } from "../globalEvents"; +import { fetchAllCwCompanies } from "./fetchAllCompanies"; + +export const refreshCompanies = async () => { + events.emit("cw:companies:refreshed:check"); + + // Dynamically import to avoid circular dependency + const internalCompanyCount = await prisma.company.count(); + const externalCompanyCount = + (await connectWiseApi.get("/company/companies/count")).data.count - 1; + + if (internalCompanyCount !== externalCompanyCount) { + console.log( + `Company count mismatch detected. Internal: ${internalCompanyCount}, External: ${externalCompanyCount}. Refreshing...`, + ); + + const allCompanies = await fetchAllCwCompanies(); + + await Promise.all( + allCompanies.map(async (company) => { + return await prisma.company.upsert({ + where: { cw_CompanyId: company.id }, + create: { + cw_CompanyId: company.id, + cw_Identifier: company.identifier, + name: company.name, + }, + update: { + name: company.name, + }, + }); + }), + ); + events.emit("cw:companies:refreshed", { + internalCompaniesCount: internalCompanyCount, + externalCompaniesCount: externalCompanyCount, + }); + } +}; diff --git a/src/modules/globalEvents.ts b/src/modules/globalEvents.ts index cb6a695..91962c8 100644 --- a/src/modules/globalEvents.ts +++ b/src/modules/globalEvents.ts @@ -53,6 +53,11 @@ interface EventTypes { err: Error; role: RoleController; }) => void; + "cw:companies:refreshed:check": () => void; + "cw:companies:refreshed": (data: { + internalCompaniesCount: number; + externalCompaniesCount: number; + }) => void; } export const events = new Eventra(); @@ -61,4 +66,4 @@ export function setupEventDebugger() { events.any((eventName, ...args) => { console.log(`[ Event Debugger ] (${eventName})`); }); -} \ No newline at end of file +} diff --git a/src/types/ConnectWiseTypes.ts b/src/types/ConnectWiseTypes.ts new file mode 100644 index 0000000..a0da7e2 --- /dev/null +++ b/src/types/ConnectWiseTypes.ts @@ -0,0 +1,139 @@ +export interface Company { + id: number; + identifier: string; + name: string; + status: CompanyStatus; + addressLine1: string; + city: string; + state: string; + zip: string; + phoneNumber: string; + faxNumber: string; + website: string; + territory: Territory; + market: Market; + accountNumber: string; + defaultContact: Contact; + dateAcquired: string; + annualRevenue: number; + numberOfEmployees: number; + leadFlag: boolean; + unsubscribeFlag: boolean; + vendorIdentifier: string; + taxIdentifier: string; + taxCode: TaxCode; + billingTerms: BasicEntity; + billToCompany: LinkedCompany; + billingSite: LinkedSite; + billingContact: Contact; + invoiceDeliveryMethod: BasicEntity; + invoiceToEmailAddress: string; + deletedFlag: boolean; + dateDeleted: string; + mobileGuid: string; + resellerIdentifier: string; + isVendorFlag: boolean; + types: TypeItem[]; + site: LinkedSite; + _info: CompanyInfo; + customFields: CustomField[]; +} + +export interface CompanyStatus { + id: number; + name: string; + _info: { + status_href: string; + }; +} + +export interface Territory { + id: number; + name: string; + _info: { + location_href: string; + }; +} + +export interface Market { + id: number; + name: string; + _info: { + Market_href: string; + }; +} + +export interface TaxCode { + id: number; + name: string; + _info: { + taxCode_href: string; + }; +} + +export interface BasicEntity { + id: number; + name: string; +} + +export interface LinkedCompany extends BasicEntity { + identifier: string; + _info: { + company_href: string; + }; +} + +export interface LinkedSite extends BasicEntity { + _info: { + site_href: string; + }; +} + +export interface Contact { + id: number; + name: string; + _info: { + contact_href: string; + }; +} + +export interface TypeItem { + id: number; + name: string; + _info: { + type_href: string; + }; +} + +export interface CompanyInfo { + lastUpdated: string; + updatedBy: string; + dateEntered: string; + enteredBy: string; + contacts_href: string; + agreements_href: string; + tickets_href: string; + opportunities_href: string; + activities_href: string; + projects_href: string; + configurations_href: string; + orders_href: string; + documents_href: string; + sites_href: string; + teams_href: string; + reports_href: string; + notes_href: string; +} + +export interface CustomField { + id: number; + caption: string; + type: string; + entryMethod: string; + numberOfDecimals: number; + value: string | null; + connectWiseId: string; + rowNum: number; + userDefinedFieldRecId: number; + podId: string; +} diff --git a/utils/assignUserRole.ts b/utils/assignUserRole.ts new file mode 100644 index 0000000..ec4cc79 --- /dev/null +++ b/utils/assignUserRole.ts @@ -0,0 +1,41 @@ +import { prisma } from "../src/constants"; +await (async () => { + const userIdentifier = Bun.argv[2]; + const roleIdentifier = Bun.argv[3]; + + if (Bun.argv.length !== 4) + console.error( + "2 arguments expected. \n Format: bun utils:assign_user_role {user} {role}" + ); + + const user = await prisma.user.findFirst({ + where: { OR: [{ id: userIdentifier }, { login: userIdentifier }] }, + }); + + if (!user) + return console.error( + `User with identifier '${userIdentifier}' doesn't exist` + ); + + const role = await prisma.role.findFirst({ + where: { OR: [{ id: roleIdentifier }, { moniker: roleIdentifier }] }, + include: { users: true }, + }); + + if (!role) + return console.error( + `Role with identifier '${roleIdentifier}' doesn't exist` + ); + + if (role.users.map((v) => v.id).includes(user.id)) + return console.log("User already has role!"); + + await prisma.user.update({ + where: { id: user.id }, + data: { roles: { set: { id: role.id } } }, + }); + + return console.log( + `User '${user.login}' has been given role '${role.title}'!` + ); +})(); diff --git a/utils/createAdminRole.ts b/utils/createAdminRole.ts new file mode 100644 index 0000000..054c00c --- /dev/null +++ b/utils/createAdminRole.ts @@ -0,0 +1,27 @@ +import cuid from "cuid"; +import { prisma } from "../src/constants"; +import { signPermissions } from "../src/modules/permission-utils/signPermissions"; + +let newRole; +let id = cuid(); +const admin = await prisma.role.findFirst({ + where: { moniker: "administrator" }, +}); + +if (admin) console.log("Admin already exists", admin); + +if (!admin) + newRole = await prisma.role.create({ + data: { + id, + moniker: "administrator", + title: "Admin", + permissions: signPermissions({ + issuer: "roles", + subject: id, + permissions: ["*"], + }), + }, + }); + +console.log("Admin Role Created!", newRole);