diff --git a/README.md b/README.md
index d156dfd83ab7707378e772907b485cab06a12971..962f4e9e52835d36c8d773866022210e7f405c0d 100644
--- a/README.md
+++ b/README.md
@@ -10,16 +10,13 @@ The docker container replaces them in the `env.template.js` file and moves that
 the `index.html`.
 When accessing the website, these variables will be loaded dynamically into the application.
 
-| Variable                | Default | Value    | Description                                      |
-|-------------------------|---------|----------|--------------------------------------------------|
-| `AUTH_API_BASE_URL`     | unset   | HTTP URL | Base URL for the Auth Service API                |
-| `WORKFLOW_API_BASE_URL` | unset   | HTTP URL | Base URL for the Workflow Service API            |
-| `RESOURCE_API_BASE_URL` | unset   | HTTP URL | Base URL for the Resource Service API            |
-| `S3PROXY_API_BASE_URL`  | unset   | HTTP URL | Base URL for the S3Proxy Service API             |
-| `S3_URL`                | unset   | HTTP URL | URL of the S3 storage to interact with           |
-| `DEV_SYSTEM`            | `false` | boolean  | Flag if the service is installed on a Dev system |
-| `MATOMO_HOST`           | unset   | HTTP URL | URL to a Matomo instance to enable tracking      |
-| `MATOMO_SITE_ID`        | unset   | integer  | Site id of the website on the Matomo instance    |
+| Variable         | Default | Value    | Description                                      |
+|------------------|---------|----------|--------------------------------------------------|
+| `API_BASE_URL`   | unset   | HTTP URL | Base URL for the CloWM Service API               |
+| `S3_URL`         | unset   | HTTP URL | URL of the S3 storage to interact with           |
+| `DEV_SYSTEM`     | `false` | boolean  | Flag if the service is installed on a Dev system |
+| `MATOMO_HOST`    | unset   | HTTP URL | URL to a Matomo instance to enable tracking      |
+| `MATOMO_SITE_ID` | unset   | integer  | Site id of the website on the Matomo instance    |
 
 ## License
 
diff --git a/package-lock.json b/package-lock.json
index ebea944118bbc5a94b5c5a4ea17d93c8b1345664..f732dd75a66047df138a1f61421b2c891471b636 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -48,7 +48,7 @@
         "@vue/tsconfig": "~0.5.0",
         "axios": "~1.6.0",
         "eslint": "~8.57.0",
-        "eslint-plugin-vue": "~9.25.0",
+        "eslint-plugin-vue": "~9.26.0",
         "highlight.js": "^11.9.0",
         "npm-run-all": "~4.1.5",
         "openapi-typescript-codegen": "^0.29.0",
@@ -865,14 +865,14 @@
       }
     },
     "node_modules/@aws-sdk/util-locate-window": {
-      "version": "3.535.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.535.0.tgz",
-      "integrity": "sha512-PHJ3SL6d2jpcgbqdgiPxkXpu7Drc2PYViwxSIqvvMKhDwzSB1W3mMvtpzwKM4IE7zLFodZo0GKjJ9AsoXndXhA==",
+      "version": "3.568.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz",
+      "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==",
       "dependencies": {
         "tslib": "^2.6.2"
       },
       "engines": {
-        "node": ">=14.0.0"
+        "node": ">=16.0.0"
       }
     },
     "node_modules/@aws-sdk/util-user-agent-browser": {
@@ -962,9 +962,9 @@
       }
     },
     "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
-      "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.3.tgz",
+      "integrity": "sha512-yTgnwQpFVYfvvo4SvRFB0SwrW8YjOxEoT7wfMT7Ol5v7v5LDNvSGo67aExmxOb87nQNeWPVvaGBNfQ7BXcrZ9w==",
       "cpu": [
         "ppc64"
       ],
@@ -973,14 +973,15 @@
       "os": [
         "aix"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
-      "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.3.tgz",
+      "integrity": "sha512-bviJOLMgurLJtF1/mAoJLxDZDL6oU5/ztMHnJQRejbJrSc9FFu0QoUoFhvi6qSKJEw9y5oGyvr9fuDtzJ30rNQ==",
       "cpu": [
         "arm"
       ],
@@ -989,14 +990,15 @@
       "os": [
         "android"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/android-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
-      "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.3.tgz",
+      "integrity": "sha512-c+ty9necz3zB1Y+d/N+mC6KVVkGUUOcm4ZmT5i/Fk5arOaY3i6CA3P5wo/7+XzV8cb4GrI/Zjp8NuOQ9Lfsosw==",
       "cpu": [
         "arm64"
       ],
@@ -1005,14 +1007,15 @@
       "os": [
         "android"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/android-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
-      "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.3.tgz",
+      "integrity": "sha512-JReHfYCRK3FVX4Ra+y5EBH1b9e16TV2OxrPAvzMsGeES0X2Ndm9ImQRI4Ket757vhc5XBOuGperw63upesclRw==",
       "cpu": [
         "x64"
       ],
@@ -1021,14 +1024,15 @@
       "os": [
         "android"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
-      "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.3.tgz",
+      "integrity": "sha512-U3fuQ0xNiAkXOmQ6w5dKpEvXQRSpHOnbw7gEfHCRXPeTKW9sBzVck6C5Yneb8LfJm0l6le4NQfkNPnWMSlTFUQ==",
       "cpu": [
         "arm64"
       ],
@@ -1037,14 +1041,15 @@
       "os": [
         "darwin"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/darwin-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
-      "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.3.tgz",
+      "integrity": "sha512-3m1CEB7F07s19wmaMNI2KANLcnaqryJxO1fXHUV5j1rWn+wMxdUYoPyO2TnAbfRZdi7ADRwJClmOwgT13qlP3Q==",
       "cpu": [
         "x64"
       ],
@@ -1053,14 +1058,15 @@
       "os": [
         "darwin"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
-      "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.3.tgz",
+      "integrity": "sha512-fsNAAl5pU6wmKHq91cHWQT0Fz0vtyE1JauMzKotrwqIKAswwP5cpHUCxZNSTuA/JlqtScq20/5KZ+TxQdovU/g==",
       "cpu": [
         "arm64"
       ],
@@ -1069,14 +1075,15 @@
       "os": [
         "freebsd"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
-      "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.3.tgz",
+      "integrity": "sha512-tci+UJ4zP5EGF4rp8XlZIdq1q1a/1h9XuronfxTMCNBslpCtmk97Q/5qqy1Mu4zIc0yswN/yP/BLX+NTUC1bXA==",
       "cpu": [
         "x64"
       ],
@@ -1085,14 +1092,15 @@
       "os": [
         "freebsd"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-arm": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
-      "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.3.tgz",
+      "integrity": "sha512-f6kz2QpSuyHHg01cDawj0vkyMwuIvN62UAguQfnNVzbge2uWLhA7TCXOn83DT0ZvyJmBI943MItgTovUob36SQ==",
       "cpu": [
         "arm"
       ],
@@ -1101,14 +1109,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
-      "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.3.tgz",
+      "integrity": "sha512-vvG6R5g5ieB4eCJBQevyDMb31LMHthLpXTc2IGkFnPWS/GzIFDnaYFp558O+XybTmYrVjxnryru7QRleJvmZ6Q==",
       "cpu": [
         "arm64"
       ],
@@ -1117,14 +1126,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-ia32": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
-      "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.3.tgz",
+      "integrity": "sha512-HjCWhH7K96Na+66TacDLJmOI9R8iDWDDiqe17C7znGvvE4sW1ECt9ly0AJ3dJH62jHyVqW9xpxZEU1jKdt+29A==",
       "cpu": [
         "ia32"
       ],
@@ -1133,14 +1143,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
-      "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.3.tgz",
+      "integrity": "sha512-BGpimEccmHBZRcAhdlRIxMp7x9PyJxUtj7apL2IuoG9VxvU/l/v1z015nFs7Si7tXUwEsvjc1rOJdZCn4QTU+Q==",
       "cpu": [
         "loong64"
       ],
@@ -1149,14 +1160,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
-      "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.3.tgz",
+      "integrity": "sha512-5rMOWkp7FQGtAH3QJddP4w3s47iT20hwftqdm7b+loe95o8JU8ro3qZbhgMRy0VuFU0DizymF1pBKkn3YHWtsw==",
       "cpu": [
         "mips64el"
       ],
@@ -1165,14 +1177,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
-      "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.3.tgz",
+      "integrity": "sha512-h0zj1ldel89V5sjPLo5H1SyMzp4VrgN1tPkN29TmjvO1/r0MuMRwJxL8QY05SmfsZRs6TF0c/IDH3u7XYYmbAg==",
       "cpu": [
         "ppc64"
       ],
@@ -1181,14 +1194,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
-      "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.3.tgz",
+      "integrity": "sha512-dkAKcTsTJ+CRX6bnO17qDJbLoW37npd5gSNtSzjYQr0svghLJYGYB0NF1SNcU1vDcjXLYS5pO4qOW4YbFama4A==",
       "cpu": [
         "riscv64"
       ],
@@ -1197,14 +1211,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-s390x": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
-      "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.3.tgz",
+      "integrity": "sha512-vnD1YUkovEdnZWEuMmy2X2JmzsHQqPpZElXx6dxENcIwTu+Cu5ERax6+Ke1QsE814Zf3c6rxCfwQdCTQ7tPuXA==",
       "cpu": [
         "s390x"
       ],
@@ -1213,14 +1228,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/linux-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
-      "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.3.tgz",
+      "integrity": "sha512-IOXOIm9WaK7plL2gMhsWJd+l2bfrhfilv0uPTptoRoSb2p09RghhQQp9YY6ZJhk/kqmeRt6siRdMSLLwzuT0KQ==",
       "cpu": [
         "x64"
       ],
@@ -1229,14 +1245,15 @@
       "os": [
         "linux"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
-      "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.3.tgz",
+      "integrity": "sha512-uTgCwsvQ5+vCQnqM//EfDSuomo2LhdWhFPS8VL8xKf+PKTCrcT/2kPPoWMTs22aB63MLdGMJiE3f1PHvCDmUOw==",
       "cpu": [
         "x64"
       ],
@@ -1245,14 +1262,15 @@
       "os": [
         "netbsd"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
-      "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.3.tgz",
+      "integrity": "sha512-vNAkR17Ub2MgEud2Wag/OE4HTSI6zlb291UYzHez/psiKarp0J8PKGDnAhMBcHFoOHMXHfExzmjMojJNbAStrQ==",
       "cpu": [
         "x64"
       ],
@@ -1261,14 +1279,15 @@
       "os": [
         "openbsd"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/sunos-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
-      "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.3.tgz",
+      "integrity": "sha512-W8H9jlGiSBomkgmouaRoTXo49j4w4Kfbl6I1bIdO/vT0+0u4f20ko3ELzV3hPI6XV6JNBVX+8BC+ajHkvffIJA==",
       "cpu": [
         "x64"
       ],
@@ -1277,14 +1296,15 @@
       "os": [
         "sunos"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/win32-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
-      "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.3.tgz",
+      "integrity": "sha512-EjEomwyLSCg8Ag3LDILIqYCZAq/y3diJ04PnqGRgq8/4O3VNlXyMd54j/saShaN4h5o5mivOjAzmU6C3X4v0xw==",
       "cpu": [
         "arm64"
       ],
@@ -1293,14 +1313,15 @@
       "os": [
         "win32"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/win32-ia32": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
-      "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.3.tgz",
+      "integrity": "sha512-WGiE/GgbsEwR33++5rzjiYsKyHywE8QSZPF7Rfx9EBfK3Qn3xyR6IjyCr5Uk38Kg8fG4/2phN7sXp4NPWd3fcw==",
       "cpu": [
         "ia32"
       ],
@@ -1309,14 +1330,15 @@
       "os": [
         "win32"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
-      "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.3.tgz",
+      "integrity": "sha512-xRxC0jaJWDLYvcUvjQmHCJSfMrgmUuvsoXgDeU/wTorQ1ngDdUBuFtgY3W1Pc5sprGAvZBtWdJX7RPg/iZZUqA==",
       "cpu": [
         "x64"
       ],
@@ -1325,6 +1347,7 @@
       "os": [
         "win32"
       ],
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
@@ -1774,9 +1797,9 @@
       ]
     },
     "node_modules/@rushstack/eslint-patch": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.2.tgz",
-      "integrity": "sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==",
+      "version": "1.10.3",
+      "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
+      "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==",
       "dev": true
     },
     "node_modules/@smithy/abort-controller": {
@@ -2453,9 +2476,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "20.12.7",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
-      "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
+      "version": "20.12.12",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
+      "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
       "dev": true,
       "dependencies": {
         "undici-types": "~5.26.4"
@@ -2486,21 +2509,19 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz",
-      "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz",
+      "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==",
       "dev": true,
       "dependencies": {
         "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "7.8.0",
-        "@typescript-eslint/type-utils": "7.8.0",
-        "@typescript-eslint/utils": "7.8.0",
-        "@typescript-eslint/visitor-keys": "7.8.0",
-        "debug": "^4.3.4",
+        "@typescript-eslint/scope-manager": "7.9.0",
+        "@typescript-eslint/type-utils": "7.9.0",
+        "@typescript-eslint/utils": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0",
         "graphemer": "^1.4.0",
         "ignore": "^5.3.1",
         "natural-compare": "^1.4.0",
-        "semver": "^7.6.0",
         "ts-api-utils": "^1.3.0"
       },
       "engines": {
@@ -2521,15 +2542,15 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz",
-      "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz",
+      "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "7.8.0",
-        "@typescript-eslint/types": "7.8.0",
-        "@typescript-eslint/typescript-estree": "7.8.0",
-        "@typescript-eslint/visitor-keys": "7.8.0",
+        "@typescript-eslint/scope-manager": "7.9.0",
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/typescript-estree": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -2549,13 +2570,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz",
-      "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz",
+      "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.8.0",
-        "@typescript-eslint/visitor-keys": "7.8.0"
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0"
       },
       "engines": {
         "node": "^18.18.0 || >=20.0.0"
@@ -2566,13 +2587,13 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz",
-      "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz",
+      "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "7.8.0",
-        "@typescript-eslint/utils": "7.8.0",
+        "@typescript-eslint/typescript-estree": "7.9.0",
+        "@typescript-eslint/utils": "7.9.0",
         "debug": "^4.3.4",
         "ts-api-utils": "^1.3.0"
       },
@@ -2593,9 +2614,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz",
-      "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz",
+      "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==",
       "dev": true,
       "engines": {
         "node": "^18.18.0 || >=20.0.0"
@@ -2606,13 +2627,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz",
-      "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz",
+      "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.8.0",
-        "@typescript-eslint/visitor-keys": "7.8.0",
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -2634,18 +2655,15 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz",
-      "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz",
+      "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
-        "@types/json-schema": "^7.0.15",
-        "@types/semver": "^7.5.8",
-        "@typescript-eslint/scope-manager": "7.8.0",
-        "@typescript-eslint/types": "7.8.0",
-        "@typescript-eslint/typescript-estree": "7.8.0",
-        "semver": "^7.6.0"
+        "@typescript-eslint/scope-manager": "7.9.0",
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/typescript-estree": "7.9.0"
       },
       "engines": {
         "node": "^18.18.0 || >=20.0.0"
@@ -2659,12 +2677,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz",
-      "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==",
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz",
+      "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.8.0",
+        "@typescript-eslint/types": "7.9.0",
         "eslint-visitor-keys": "^3.4.3"
       },
       "engines": {
@@ -2695,40 +2713,40 @@
       }
     },
     "node_modules/@volar/language-core": {
-      "version": "2.2.0-alpha.12",
-      "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.0-alpha.12.tgz",
-      "integrity": "sha512-zgWof8q02kADyb4lalVzoqnvTs/wJRDul5qHl0VC2ZVXwes6j2ZYumjXqAW+8W1CQp8lfJkEn9Z6a5jvU6S7Jw==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.4.tgz",
+      "integrity": "sha512-7As47GndxGxsqqYnbreLrfB5NDUeQioPM2LJKUuB4/34c0NpEJ2byVl3c9KYdjIdiEstWZ9JLtLKNTaPWb5jtA==",
       "dev": true,
       "dependencies": {
-        "@volar/source-map": "2.2.0-alpha.12"
+        "@volar/source-map": "2.2.4"
       }
     },
     "node_modules/@volar/source-map": {
-      "version": "2.2.0-alpha.12",
-      "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.0-alpha.12.tgz",
-      "integrity": "sha512-d7vDWBE3Ijenff+f1GbWWvdXK4i0wsWsDnfry7G0Jwhbs2/q+NoQya27ZEc3Is0E5m7sOmgUOvRnLGLKEmWFBg==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.4.tgz",
+      "integrity": "sha512-m92FLpR9vB1YEZfiZ+bfgpLrToL/DNkOrorWVep3pffHrwwI4Tx2oIQN+sqHJfKkiT5N3J1owC+8crhAEinfjg==",
       "dev": true,
       "dependencies": {
         "muggle-string": "^0.4.0"
       }
     },
     "node_modules/@volar/typescript": {
-      "version": "2.2.0-alpha.12",
-      "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.0-alpha.12.tgz",
-      "integrity": "sha512-Ie4/Pj7NcIZWss+kteREZUYRU0jjiAmWCNoUJ7ViYQsYCrtiLMgPthha09V9zAyhk1rUGErF7/TLtAAX1VuflA==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.4.tgz",
+      "integrity": "sha512-uAQC53tgEbHO62G8NXMfmBrJAlP2QJ9WxVEEQqqK3I6VSy8frL5LbH3hAWODxiwMWixv74wJLWlKbWXOgdIoRQ==",
       "dev": true,
       "dependencies": {
-        "@volar/language-core": "2.2.0-alpha.12",
+        "@volar/language-core": "2.2.4",
         "path-browserify": "^1.0.1"
       }
     },
     "node_modules/@vue/compiler-core": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.26.tgz",
-      "integrity": "sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
+      "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
       "dependencies": {
         "@babel/parser": "^7.24.4",
-        "@vue/shared": "3.4.26",
+        "@vue/shared": "3.4.27",
         "entities": "^4.5.0",
         "estree-walker": "^2.0.2",
         "source-map-js": "^1.2.0"
@@ -2740,24 +2758,24 @@
       "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
     },
     "node_modules/@vue/compiler-dom": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz",
-      "integrity": "sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
+      "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
       "dependencies": {
-        "@vue/compiler-core": "3.4.26",
-        "@vue/shared": "3.4.26"
+        "@vue/compiler-core": "3.4.27",
+        "@vue/shared": "3.4.27"
       }
     },
     "node_modules/@vue/compiler-sfc": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz",
-      "integrity": "sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
+      "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
       "dependencies": {
         "@babel/parser": "^7.24.4",
-        "@vue/compiler-core": "3.4.26",
-        "@vue/compiler-dom": "3.4.26",
-        "@vue/compiler-ssr": "3.4.26",
-        "@vue/shared": "3.4.26",
+        "@vue/compiler-core": "3.4.27",
+        "@vue/compiler-dom": "3.4.27",
+        "@vue/compiler-ssr": "3.4.27",
+        "@vue/shared": "3.4.27",
         "estree-walker": "^2.0.2",
         "magic-string": "^0.30.10",
         "postcss": "^8.4.38",
@@ -2778,12 +2796,12 @@
       }
     },
     "node_modules/@vue/compiler-ssr": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz",
-      "integrity": "sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
+      "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
       "dependencies": {
-        "@vue/compiler-dom": "3.4.26",
-        "@vue/shared": "3.4.26"
+        "@vue/compiler-dom": "3.4.27",
+        "@vue/shared": "3.4.27"
       }
     },
     "node_modules/@vue/devtools-api": {
@@ -2830,12 +2848,12 @@
       }
     },
     "node_modules/@vue/language-core": {
-      "version": "2.0.15",
-      "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.15.tgz",
-      "integrity": "sha512-a2n5Oc+PkWPX5zhnTkddH/hzPCrQmwUz1EwmFje3mqd+c8Ux+yCVEnAE2XtGQZoELgSWvY7EmJfidRbs+nR19Q==",
+      "version": "2.0.19",
+      "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.19.tgz",
+      "integrity": "sha512-A9EGOnvb51jOvnCYoRLnMP+CcoPlbZVxI9gZXE/y2GksRWM6j/PrLEIC++pnosWTN08tFpJgxhSS//E9v/Sg+Q==",
       "dev": true,
       "dependencies": {
-        "@volar/language-core": "2.2.0-alpha.12",
+        "@volar/language-core": "~2.2.4",
         "@vue/compiler-dom": "^3.4.0",
         "@vue/shared": "^3.4.0",
         "computeds": "^0.0.1",
@@ -2853,48 +2871,48 @@
       }
     },
     "node_modules/@vue/reactivity": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.26.tgz",
-      "integrity": "sha512-E/ynEAu/pw0yotJeLdvZEsp5Olmxt+9/WqzvKff0gE67tw73gmbx6tRkiagE/eH0UCubzSlGRebCbidB1CpqZQ==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz",
+      "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==",
       "dependencies": {
-        "@vue/shared": "3.4.26"
+        "@vue/shared": "3.4.27"
       }
     },
     "node_modules/@vue/runtime-core": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.26.tgz",
-      "integrity": "sha512-AFJDLpZvhT4ujUgZSIL9pdNcO23qVFh7zWCsNdGQBw8ecLNxOOnPcK9wTTIYCmBJnuPHpukOwo62a2PPivihqw==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz",
+      "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==",
       "dependencies": {
-        "@vue/reactivity": "3.4.26",
-        "@vue/shared": "3.4.26"
+        "@vue/reactivity": "3.4.27",
+        "@vue/shared": "3.4.27"
       }
     },
     "node_modules/@vue/runtime-dom": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.26.tgz",
-      "integrity": "sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
+      "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
       "dependencies": {
-        "@vue/runtime-core": "3.4.26",
-        "@vue/shared": "3.4.26",
+        "@vue/runtime-core": "3.4.27",
+        "@vue/shared": "3.4.27",
         "csstype": "^3.1.3"
       }
     },
     "node_modules/@vue/server-renderer": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.26.tgz",
-      "integrity": "sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
+      "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
       "dependencies": {
-        "@vue/compiler-ssr": "3.4.26",
-        "@vue/shared": "3.4.26"
+        "@vue/compiler-ssr": "3.4.27",
+        "@vue/shared": "3.4.27"
       },
       "peerDependencies": {
-        "vue": "3.4.26"
+        "vue": "3.4.27"
       }
     },
     "node_modules/@vue/shared": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.26.tgz",
-      "integrity": "sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ=="
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
+      "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
     },
     "node_modules/@vue/tsconfig": {
       "version": "0.5.1",
@@ -3213,9 +3231,9 @@
       }
     },
     "node_modules/chart.js": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
-      "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
+      "version": "4.4.3",
+      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz",
+      "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==",
       "dependencies": {
         "@kurkle/color": "^0.3.0"
       },
@@ -3505,9 +3523,9 @@
       }
     },
     "node_modules/dompurify": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.1.tgz",
-      "integrity": "sha512-tVP8C/GJwnABOn/7cx/ymx/hXpmBfWIPihC1aOEvS8GbMqy3pgeYtJk1HXN3CO7tu+8bpY18f6isjR5Cymj0TQ=="
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.3.tgz",
+      "integrity": "sha512-5sOWYSNPaxz6o2MUPvtyxTTqR4D3L77pr5rUQoWgD5ROQtVIZQgJkXbo1DLlK3vj11YGw5+LnF4SYti4gZmwng=="
     },
     "node_modules/entities": {
       "version": "4.5.0",
@@ -3654,11 +3672,12 @@
       }
     },
     "node_modules/esbuild": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
-      "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.3.tgz",
+      "integrity": "sha512-Kgq0/ZsAPzKrbOjCQcjoSmPoWhlcVnGAUo7jvaLHoxW1Drto0KGkR1xBNg2Cp43b9ImvxmPEJZ9xkfcnqPsfBw==",
       "dev": true,
       "hasInstallScript": true,
+      "peer": true,
       "bin": {
         "esbuild": "bin/esbuild"
       },
@@ -3666,29 +3685,29 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.20.2",
-        "@esbuild/android-arm": "0.20.2",
-        "@esbuild/android-arm64": "0.20.2",
-        "@esbuild/android-x64": "0.20.2",
-        "@esbuild/darwin-arm64": "0.20.2",
-        "@esbuild/darwin-x64": "0.20.2",
-        "@esbuild/freebsd-arm64": "0.20.2",
-        "@esbuild/freebsd-x64": "0.20.2",
-        "@esbuild/linux-arm": "0.20.2",
-        "@esbuild/linux-arm64": "0.20.2",
-        "@esbuild/linux-ia32": "0.20.2",
-        "@esbuild/linux-loong64": "0.20.2",
-        "@esbuild/linux-mips64el": "0.20.2",
-        "@esbuild/linux-ppc64": "0.20.2",
-        "@esbuild/linux-riscv64": "0.20.2",
-        "@esbuild/linux-s390x": "0.20.2",
-        "@esbuild/linux-x64": "0.20.2",
-        "@esbuild/netbsd-x64": "0.20.2",
-        "@esbuild/openbsd-x64": "0.20.2",
-        "@esbuild/sunos-x64": "0.20.2",
-        "@esbuild/win32-arm64": "0.20.2",
-        "@esbuild/win32-ia32": "0.20.2",
-        "@esbuild/win32-x64": "0.20.2"
+        "@esbuild/aix-ppc64": "0.21.3",
+        "@esbuild/android-arm": "0.21.3",
+        "@esbuild/android-arm64": "0.21.3",
+        "@esbuild/android-x64": "0.21.3",
+        "@esbuild/darwin-arm64": "0.21.3",
+        "@esbuild/darwin-x64": "0.21.3",
+        "@esbuild/freebsd-arm64": "0.21.3",
+        "@esbuild/freebsd-x64": "0.21.3",
+        "@esbuild/linux-arm": "0.21.3",
+        "@esbuild/linux-arm64": "0.21.3",
+        "@esbuild/linux-ia32": "0.21.3",
+        "@esbuild/linux-loong64": "0.21.3",
+        "@esbuild/linux-mips64el": "0.21.3",
+        "@esbuild/linux-ppc64": "0.21.3",
+        "@esbuild/linux-riscv64": "0.21.3",
+        "@esbuild/linux-s390x": "0.21.3",
+        "@esbuild/linux-x64": "0.21.3",
+        "@esbuild/netbsd-x64": "0.21.3",
+        "@esbuild/openbsd-x64": "0.21.3",
+        "@esbuild/sunos-x64": "0.21.3",
+        "@esbuild/win32-arm64": "0.21.3",
+        "@esbuild/win32-ia32": "0.21.3",
+        "@esbuild/win32-x64": "0.21.3"
       }
     },
     "node_modules/escape-string-regexp": {
@@ -3801,9 +3820,9 @@
       }
     },
     "node_modules/eslint-plugin-vue": {
-      "version": "9.25.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
-      "integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
+      "version": "9.26.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.26.0.tgz",
+      "integrity": "sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
@@ -4061,9 +4080,9 @@
       }
     },
     "node_modules/filesize": {
-      "version": "10.1.1",
-      "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.1.tgz",
-      "integrity": "sha512-L0cdwZrKlwZQkMSFnCflJ6J2Y+5egO/p3vgRSDQGxQt++QbUZe5gMbRO6kg6gzwQDPvq2Fk9AmoxUNfZ5gdqaQ==",
+      "version": "10.1.2",
+      "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.2.tgz",
+      "integrity": "sha512-Dx770ai81ohflojxhU+oG+Z2QGvKdYxgEr9OSA8UVrqhwNHjfH9A8f5NKfg83fEH8ZFA5N5llJo5T3PIoZ4CRA==",
       "engines": {
         "node": ">= 10.4.0"
       }
@@ -4562,9 +4581,9 @@
       }
     },
     "node_modules/immutable": {
-      "version": "4.3.5",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
-      "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
+      "version": "4.3.6",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz",
+      "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==",
       "dev": true
     },
     "node_modules/import-fresh": {
@@ -5014,17 +5033,6 @@
       "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
       "dev": true
     },
-    "node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/magic-string": {
       "version": "0.25.9",
       "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
@@ -5566,9 +5574,9 @@
       }
     },
     "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+      "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
     },
     "node_modules/picomatch": {
       "version": "2.3.1",
@@ -6043,9 +6051,9 @@
       }
     },
     "node_modules/sass": {
-      "version": "1.75.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz",
-      "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==",
+      "version": "1.77.2",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz",
+      "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -6060,12 +6068,9 @@
       }
     },
     "node_modules/semver": {
-      "version": "7.6.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
-      "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
+      "version": "7.6.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+      "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
       "bin": {
         "semver": "bin/semver.js"
       },
@@ -6632,9 +6637,9 @@
       }
     },
     "node_modules/vite": {
-      "version": "5.2.10",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz",
-      "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz",
+      "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==",
       "dev": true,
       "dependencies": {
         "esbuild": "^0.20.1",
@@ -6686,16 +6691,422 @@
         }
       }
     },
+    "node_modules/vite/node_modules/@esbuild/aix-ppc64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+      "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/android-arm": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+      "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/android-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+      "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/android-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+      "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/darwin-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+      "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/darwin-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+      "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+      "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/freebsd-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+      "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-arm": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+      "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+      "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-ia32": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+      "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-loong64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+      "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-mips64el": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+      "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-ppc64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+      "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-riscv64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+      "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-s390x": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+      "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/linux-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+      "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/netbsd-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+      "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/openbsd-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+      "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/sunos-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+      "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/win32-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+      "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/win32-ia32": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+      "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/@esbuild/win32-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+      "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite/node_modules/esbuild": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
+      "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.20.2",
+        "@esbuild/android-arm": "0.20.2",
+        "@esbuild/android-arm64": "0.20.2",
+        "@esbuild/android-x64": "0.20.2",
+        "@esbuild/darwin-arm64": "0.20.2",
+        "@esbuild/darwin-x64": "0.20.2",
+        "@esbuild/freebsd-arm64": "0.20.2",
+        "@esbuild/freebsd-x64": "0.20.2",
+        "@esbuild/linux-arm": "0.20.2",
+        "@esbuild/linux-arm64": "0.20.2",
+        "@esbuild/linux-ia32": "0.20.2",
+        "@esbuild/linux-loong64": "0.20.2",
+        "@esbuild/linux-mips64el": "0.20.2",
+        "@esbuild/linux-ppc64": "0.20.2",
+        "@esbuild/linux-riscv64": "0.20.2",
+        "@esbuild/linux-s390x": "0.20.2",
+        "@esbuild/linux-x64": "0.20.2",
+        "@esbuild/netbsd-x64": "0.20.2",
+        "@esbuild/openbsd-x64": "0.20.2",
+        "@esbuild/sunos-x64": "0.20.2",
+        "@esbuild/win32-arm64": "0.20.2",
+        "@esbuild/win32-ia32": "0.20.2",
+        "@esbuild/win32-x64": "0.20.2"
+      }
+    },
     "node_modules/vue": {
-      "version": "3.4.26",
-      "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.26.tgz",
-      "integrity": "sha512-bUIq/p+VB+0xrJubaemrfhk1/FiW9iX+pDV+62I/XJ6EkspAO9/DXEjbDFoe8pIfOZBqfk45i9BMc41ptP/uRg==",
+      "version": "3.4.27",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz",
+      "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
       "dependencies": {
-        "@vue/compiler-dom": "3.4.26",
-        "@vue/compiler-sfc": "3.4.26",
-        "@vue/runtime-dom": "3.4.26",
-        "@vue/server-renderer": "3.4.26",
-        "@vue/shared": "3.4.26"
+        "@vue/compiler-dom": "3.4.27",
+        "@vue/compiler-sfc": "3.4.27",
+        "@vue/runtime-dom": "3.4.27",
+        "@vue/server-renderer": "3.4.27",
+        "@vue/shared": "3.4.27"
       },
       "peerDependencies": {
         "typescript": "*"
@@ -6764,13 +7175,13 @@
       }
     },
     "node_modules/vue-tsc": {
-      "version": "2.0.15",
-      "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.15.tgz",
-      "integrity": "sha512-R7qcN33tJcNvo59g7ZuoZN1bbIe3rkDz4YjaK5kH/WxeyOZV4ynqa2IsQO4sCHXdx9hFTVDEXWuUgbGPuCz49A==",
+      "version": "2.0.19",
+      "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.19.tgz",
+      "integrity": "sha512-JWay5Zt2/871iodGF72cELIbcAoPyhJxq56mPPh+M2K7IwI688FMrFKc/+DvB05wDWEuCPexQJ6L10zSwzzapg==",
       "dev": true,
       "dependencies": {
-        "@volar/typescript": "2.2.0-alpha.12",
-        "@vue/language-core": "2.0.15",
+        "@volar/typescript": "~2.2.4",
+        "@vue/language-core": "2.0.19",
         "semver": "^7.5.4"
       },
       "bin": {
@@ -6868,11 +7279,6 @@
         "node": ">=12"
       }
     },
-    "node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
-    },
     "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 734586f8e5e803a0c79ec91c30f49eea96fbd4f5..c52435aa8bb0bccccfc2697e3f78f025f89055e1 100644
--- a/package.json
+++ b/package.json
@@ -10,10 +10,7 @@
     "build-only": "vite build",
     "type-check": "vue-tsc --noEmit",
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
-    "generate-s3-client": "openapi --input http://localhost:9999/api/s3proxy-service/openapi.json --output src/client/s3proxy --client axios",
-    "generate-auth-client": "openapi --input http://localhost:9999/api/auth-service/openapi.json --output src/client/auth --client axios",
-    "generate-workflow-client": "openapi --input http://localhost:9999/api/workflow-service/openapi.json --output src/client/workflow --client axios",
-    "generate-resource-client": "openapi --input http://localhost:9999/api/resource-service/openapi.json --output src/client/resource --client axios"
+    "generate-clowm-client": "openapi --input http://localhost:9999/api/openapi.json --output src/client --client axios"
   },
   "dependencies": {
     "@aws-sdk/client-s3": "<3.530.0",
@@ -55,7 +52,7 @@
     "@vue/tsconfig": "~0.5.0",
     "axios": "~1.6.0",
     "eslint": "~8.57.0",
-    "eslint-plugin-vue": "~9.25.0",
+    "eslint-plugin-vue": "~9.26.0",
     "highlight.js": "^11.9.0",
     "npm-run-all": "~4.1.5",
     "openapi-typescript-codegen": "^0.29.0",
diff --git a/src/App.vue b/src/App.vue
index 62e5c5084f580afc492cd0e7fc5254a6c2d84d04..55e8ce1bb8db5cab8526d8bb4687fc636e93fa70 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -3,10 +3,7 @@ import { onBeforeMount, onMounted } from "vue";
 import { useCookies } from "vue3-cookies";
 import { useAuthStore } from "@/stores/users";
 import { useRoute, useRouter } from "vue-router";
-import { OpenAPI as S3ProxyOpenAPI } from "@/client/s3proxy";
-import { OpenAPI as AuthOpenAPI } from "@/client/auth";
-import { OpenAPI as WorkflowOpenAPI } from "@/client/workflow";
-import { OpenAPI as ResourceOpenAPI } from "@/client/resource";
+import { OpenAPI } from "@/client";
 import { environment } from "@/environment";
 import axios from "axios";
 import { useNameStore } from "@/stores/names";
@@ -28,10 +25,7 @@ const bucketRepository = useBucketStore();
 const s3KeyRepository = useS3KeyStore();
 
 onBeforeMount(() => {
-  S3ProxyOpenAPI.BASE = environment.S3PROXY_API_BASE_URL;
-  AuthOpenAPI.BASE = environment.AUTH_API_BASE_URL;
-  WorkflowOpenAPI.BASE = environment.WORKFLOW_API_BASE_URL;
-  ResourceOpenAPI.BASE = environment.RESOURCE_API_BASE_URL;
+  OpenAPI.BASE = environment.API_BASE_URL;
   axios.interceptors.response.use(
     (res) => res,
     (err) => {
@@ -46,8 +40,7 @@ onBeforeMount(() => {
           query: {
             login_error:
               err.response.status === 400 ? "token_invalid" : "token_expired",
-            return_path:
-              route.name != "login" ? encodeURI(route.path) : undefined,
+            next: route.name != "login" ? encodeURI(route.path) : undefined,
           },
         });
       }
@@ -77,7 +70,7 @@ onBeforeMount(() => {
       // redirect the user to the login page and preserve query params for login error message
       return {
         name: "login",
-        query: { ...to.query, return_path: encodeURI(to.path) },
+        query: { ...to.query, next: encodeURI(to.path) },
       };
     } else if (
       to.meta.requiresDeveloperRole &&
@@ -96,9 +89,9 @@ onBeforeMount(() => {
       return { name: "dashboard" };
     } else if (to.meta.adminRole && !userRepository.admin) {
       return { name: "dashboard" };
-    } else if (to.name !== "login" && to.query.return_path) {
+    } else if (to.name !== "login" && to.query.next) {
       // return to original path after login
-      return { path: decodeURI(to.query.return_path as string) };
+      return { path: decodeURI(to.query.next as string) };
     }
   });
   nameRepository.loadNameMapping();
diff --git a/src/assets/env.template.js b/src/assets/env.template.js
index 5571870426b74b4fe61107a64e159f44254cb681..745f96e910f0f33cde9c93dfd8876ccc7bca7a53 100644
--- a/src/assets/env.template.js
+++ b/src/assets/env.template.js
@@ -3,10 +3,7 @@
 
   // Environment variables
   window["env"]["s3Url"] = "${S3_URL}";
-  window["env"]["workflowApiUrl"] = "${WORKFLOW_API_BASE_URL}";
-  window["env"]["s3proxyApiUrl"] = "${S3PROXY_API_BASE_URL}";
-  window["env"]["authApiUrl"] = "${AUTH_API_BASE_URL}";
-  window["env"]["resourceApiUrl"] = "${RESOURCE_API_BASE_URL}";
+  window["env"]["apiUrl"] = "${WORKFLOW_API_BASE_URL}";
   window["env"]["devSystem"] = "${DEV_SYSTEM}";
   window["env"]["matomoHost"] = "${MATOMO_HOST}";
   window["env"]["matomoSiteId"] = "${MATOMO_SITE_ID}";
diff --git a/src/client/auth/index.ts b/src/client/auth/index.ts
deleted file mode 100644
index 199503503a6fc5e2d9dc5c6e8a5882105f6c98c3..0000000000000000000000000000000000000000
--- a/src/client/auth/index.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export { ApiError } from './core/ApiError';
-export { CancelablePromise, CancelError } from './core/CancelablePromise';
-export { OpenAPI } from './core/OpenAPI';
-export type { OpenAPIConfig } from './core/OpenAPI';
-
-export type { ErrorDetail } from './models/ErrorDetail';
-export type { HTTPValidationError } from './models/HTTPValidationError';
-export { OIDCProvider } from './models/OIDCProvider';
-export { RoleEnum } from './models/RoleEnum';
-export type { User } from './models/User';
-export type { ValidationError } from './models/ValidationError';
-
-export { AuthService } from './services/AuthService';
-export { UserService } from './services/UserService';
diff --git a/src/client/auth/services/UserService.ts b/src/client/auth/services/UserService.ts
deleted file mode 100644
index 37b02f80d6aeaf418bab6a02d9ffa4e1b01fbacf..0000000000000000000000000000000000000000
--- a/src/client/auth/services/UserService.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { RoleEnum } from '../models/RoleEnum';
-import type { User } from '../models/User';
-import type { CancelablePromise } from '../core/CancelablePromise';
-import { OpenAPI } from '../core/OpenAPI';
-import { request as __request } from '../core/request';
-export class UserService {
-    /**
-     * Get the logged in user
-     * Return the user associated with the used JWT.
-     * Permission `user:read` required.
-     * @returns User Successful Response
-     * @throws ApiError
-     */
-    public static userGetLoggedInUser(): CancelablePromise<User> {
-        return __request(OpenAPI, {
-            method: 'GET',
-            url: '/users/me',
-            errors: {
-                400: `Error decoding JWT Token`,
-                401: `Not Authenticated`,
-                403: `Not Authorized`,
-                404: `Entity not Found`,
-            },
-        });
-    }
-    /**
-     * List users and search by their name
-     * Return the users that have a specific substring in their name.
-     *
-     * Permission `user:read_any` required, except when `name_substring` as only query parameter is set,
-     * then permission `user:search` required.
-     * @param nameSubstring Filter users by a substring in their name. Permission `user:search` required
-     * @param filterRoles Filter users by their role. If multiple are selected, they are concatenating by an OR Expression. Permission `user:read_any` required
-     * @param includeRoles Flag whether to include the roles of the users in the response. If True, permission `user:read_any` required.
-     * @returns User Successful Response
-     * @throws ApiError
-     */
-    public static userListUsers(
-        nameSubstring?: string,
-        filterRoles?: Array<RoleEnum>,
-        includeRoles: boolean = false,
-    ): CancelablePromise<Array<User>> {
-        return __request(OpenAPI, {
-            method: 'GET',
-            url: '/users',
-            query: {
-                'name_substring': nameSubstring,
-                'filter_roles': filterRoles,
-                'include_roles': includeRoles,
-            },
-            errors: {
-                400: `Error decoding JWT Token`,
-                401: `Not Authenticated`,
-                403: `Not Authorized`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Get a user by its uid
-     * Return the user with the specific uid.
-     *
-     * Permission `user:read` required if the current user has the same uid as `uid` otherwise `user:read_any` required.
-     * @param uid UID of a user
-     * @param includeRoles Flag whether to include the roles of the users in the response. If True, permission `user:read_any` required.
-     * @returns User Successful Response
-     * @throws ApiError
-     */
-    public static userGetUser(
-        uid: string,
-        includeRoles: boolean = false,
-    ): CancelablePromise<User> {
-        return __request(OpenAPI, {
-            method: 'GET',
-            url: '/users/{uid}',
-            path: {
-                'uid': uid,
-            },
-            query: {
-                'include_roles': includeRoles,
-            },
-            errors: {
-                400: `Error decoding JWT Token`,
-                401: `Not Authenticated`,
-                403: `Not Authorized`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-}
diff --git a/src/client/auth/core/ApiError.ts b/src/client/core/ApiError.ts
similarity index 100%
rename from src/client/auth/core/ApiError.ts
rename to src/client/core/ApiError.ts
diff --git a/src/client/auth/core/ApiRequestOptions.ts b/src/client/core/ApiRequestOptions.ts
similarity index 100%
rename from src/client/auth/core/ApiRequestOptions.ts
rename to src/client/core/ApiRequestOptions.ts
diff --git a/src/client/auth/core/ApiResult.ts b/src/client/core/ApiResult.ts
similarity index 100%
rename from src/client/auth/core/ApiResult.ts
rename to src/client/core/ApiResult.ts
diff --git a/src/client/auth/core/CancelablePromise.ts b/src/client/core/CancelablePromise.ts
similarity index 100%
rename from src/client/auth/core/CancelablePromise.ts
rename to src/client/core/CancelablePromise.ts
diff --git a/src/client/auth/core/OpenAPI.ts b/src/client/core/OpenAPI.ts
similarity index 96%
rename from src/client/auth/core/OpenAPI.ts
rename to src/client/core/OpenAPI.ts
index 0f6eb187b0cec075a8d22e60fc2bb652cb7d3ee7..2745d3477a41ac7553a988ad41f38a72f63c9dda 100644
--- a/src/client/auth/core/OpenAPI.ts
+++ b/src/client/core/OpenAPI.ts
@@ -20,7 +20,7 @@ export type OpenAPIConfig = {
 };
 
 export const OpenAPI: OpenAPIConfig = {
-    BASE: '/api/auth-service',
+    BASE: '/api',
     VERSION: '1.0.0',
     WITH_CREDENTIALS: false,
     CREDENTIALS: 'include',
diff --git a/src/client/auth/core/request.ts b/src/client/core/request.ts
similarity index 100%
rename from src/client/auth/core/request.ts
rename to src/client/core/request.ts
diff --git a/src/client/index.ts b/src/client/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4e8c4b36cd6a701bba0ad2f7b46e078f6fcd73e9
--- /dev/null
+++ b/src/client/index.ts
@@ -0,0 +1,71 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export { ApiError } from './core/ApiError';
+export { CancelablePromise, CancelError } from './core/CancelablePromise';
+export { OpenAPI } from './core/OpenAPI';
+export type { OpenAPIConfig } from './core/OpenAPI';
+
+export type { AnonymizedWorkflowExecution } from './models/AnonymizedWorkflowExecution';
+export type { Body_Bucket_update_bucket_public_state } from './models/Body_Bucket_update_bucket_public_state';
+export type { Body_Workflow_Version_upload_workflow_version_icon } from './models/Body_Workflow_Version_upload_workflow_version_icon';
+export type { BucketIn } from './models/BucketIn';
+export type { BucketOut } from './models/BucketOut';
+export type { BucketPermissionIn } from './models/BucketPermissionIn';
+export type { BucketPermissionOut } from './models/BucketPermissionOut';
+export type { BucketPermissionParameters } from './models/BucketPermissionParameters';
+export type { BucketSizeLimits } from './models/BucketSizeLimits';
+export { BucketType } from './models/BucketType';
+export type { DevWorkflowExecutionIn } from './models/DevWorkflowExecutionIn';
+export { DocumentationEnum } from './models/DocumentationEnum';
+export type { ErrorDetail } from './models/ErrorDetail';
+export { FileTree } from './models/FileTree';
+export type { HTTPValidationError } from './models/HTTPValidationError';
+export type { IconUpdateOut } from './models/IconUpdateOut';
+export { OIDCProvider } from './models/OIDCProvider';
+export type { ParameterExtension } from './models/ParameterExtension';
+export { Permission } from './models/Permission';
+export { PermissionStatus } from './models/PermissionStatus';
+export type { ResourceIn } from './models/ResourceIn';
+export type { ResourceOut } from './models/ResourceOut';
+export type { ResourceVersionIn } from './models/ResourceVersionIn';
+export type { ResourceVersionOut } from './models/ResourceVersionOut';
+export { ResourceVersionStatus } from './models/ResourceVersionStatus';
+export { RoleEnum } from './models/RoleEnum';
+export type { S3Key } from './models/S3Key';
+export type { UserIn } from './models/UserIn';
+export type { UserOut } from './models/UserOut';
+export type { UserOutExtended } from './models/UserOutExtended';
+export type { UserRequestAnswer } from './models/UserRequestAnswer';
+export type { UserRoles } from './models/UserRoles';
+export type { UserSynchronizationRequestIn } from './models/UserSynchronizationRequestIn';
+export type { UserSynchronizationRequestOut } from './models/UserSynchronizationRequestOut';
+export type { ValidationError } from './models/ValidationError';
+export type { WorkflowCredentialsIn } from './models/WorkflowCredentialsIn';
+export type { WorkflowCredentialsOut } from './models/WorkflowCredentialsOut';
+export type { WorkflowExecutionIn } from './models/WorkflowExecutionIn';
+export type { WorkflowExecutionOut } from './models/WorkflowExecutionOut';
+export { WorkflowExecutionStatus } from './models/WorkflowExecutionStatus';
+export type { WorkflowIn } from './models/WorkflowIn';
+export type { WorkflowModeIn } from './models/WorkflowModeIn';
+export type { WorkflowModeOut } from './models/WorkflowModeOut';
+export type { WorkflowOut } from './models/WorkflowOut';
+export type { WorkflowStatistic } from './models/WorkflowStatistic';
+export type { WorkflowUpdate } from './models/WorkflowUpdate';
+export type { WorkflowVersion } from './models/WorkflowVersion';
+export { WorkflowVersionStatus } from './models/WorkflowVersionStatus';
+export type { WorkflowVersionStatusSchema } from './models/WorkflowVersionStatusSchema';
+
+export { AuthService } from './services/AuthService';
+export { BucketService } from './services/BucketService';
+export { BucketPermissionService } from './services/BucketPermissionService';
+export { ResourceService } from './services/ResourceService';
+export { ResourceVersionService } from './services/ResourceVersionService';
+export { S3KeyService } from './services/S3KeyService';
+export { UserService } from './services/UserService';
+export { WorkflowService } from './services/WorkflowService';
+export { WorkflowCredentialsService } from './services/WorkflowCredentialsService';
+export { WorkflowExecutionService } from './services/WorkflowExecutionService';
+export { WorkflowModeService } from './services/WorkflowModeService';
+export { WorkflowVersionService } from './services/WorkflowVersionService';
diff --git a/src/client/workflow/models/AnonymizedWorkflowExecution.ts b/src/client/models/AnonymizedWorkflowExecution.ts
similarity index 100%
rename from src/client/workflow/models/AnonymizedWorkflowExecution.ts
rename to src/client/models/AnonymizedWorkflowExecution.ts
diff --git a/src/client/s3proxy/models/Body_Bucket_update_bucket_public_state.ts b/src/client/models/Body_Bucket_update_bucket_public_state.ts
similarity index 100%
rename from src/client/s3proxy/models/Body_Bucket_update_bucket_public_state.ts
rename to src/client/models/Body_Bucket_update_bucket_public_state.ts
diff --git a/src/client/workflow/models/Body_Workflow_Version_upload_workflow_version_icon.ts b/src/client/models/Body_Workflow_Version_upload_workflow_version_icon.ts
similarity index 100%
rename from src/client/workflow/models/Body_Workflow_Version_upload_workflow_version_icon.ts
rename to src/client/models/Body_Workflow_Version_upload_workflow_version_icon.ts
diff --git a/src/client/s3proxy/models/BucketIn.ts b/src/client/models/BucketIn.ts
similarity index 100%
rename from src/client/s3proxy/models/BucketIn.ts
rename to src/client/models/BucketIn.ts
diff --git a/src/client/s3proxy/models/BucketOut.ts b/src/client/models/BucketOut.ts
similarity index 100%
rename from src/client/s3proxy/models/BucketOut.ts
rename to src/client/models/BucketOut.ts
diff --git a/src/client/s3proxy/models/BucketPermissionIn.ts b/src/client/models/BucketPermissionIn.ts
similarity index 100%
rename from src/client/s3proxy/models/BucketPermissionIn.ts
rename to src/client/models/BucketPermissionIn.ts
diff --git a/src/client/s3proxy/models/BucketPermissionOut.ts b/src/client/models/BucketPermissionOut.ts
similarity index 100%
rename from src/client/s3proxy/models/BucketPermissionOut.ts
rename to src/client/models/BucketPermissionOut.ts
diff --git a/src/client/s3proxy/models/BucketPermissionParameters.ts b/src/client/models/BucketPermissionParameters.ts
similarity index 100%
rename from src/client/s3proxy/models/BucketPermissionParameters.ts
rename to src/client/models/BucketPermissionParameters.ts
diff --git a/src/client/s3proxy/models/BucketSizeLimits.ts b/src/client/models/BucketSizeLimits.ts
similarity index 88%
rename from src/client/s3proxy/models/BucketSizeLimits.ts
rename to src/client/models/BucketSizeLimits.ts
index 22e59a73fb77094c3c60adc896ee9c60157b2ce6..25323318a3e290b53e09e86f58dfc01b2905e124 100644
--- a/src/client/s3proxy/models/BucketSizeLimits.ts
+++ b/src/client/models/BucketSizeLimits.ts
@@ -2,6 +2,9 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
+/**
+ * Schema to represent bucket limits.
+ */
 export type BucketSizeLimits = {
     /**
      * Size limit of the bucket in KiB
diff --git a/src/client/s3proxy/models/BucketType.ts b/src/client/models/BucketType.ts
similarity index 100%
rename from src/client/s3proxy/models/BucketType.ts
rename to src/client/models/BucketType.ts
diff --git a/src/client/workflow/models/DevWorkflowExecutionIn.ts b/src/client/models/DevWorkflowExecutionIn.ts
similarity index 100%
rename from src/client/workflow/models/DevWorkflowExecutionIn.ts
rename to src/client/models/DevWorkflowExecutionIn.ts
diff --git a/src/client/workflow/models/DocumentationEnum.ts b/src/client/models/DocumentationEnum.ts
similarity index 100%
rename from src/client/workflow/models/DocumentationEnum.ts
rename to src/client/models/DocumentationEnum.ts
diff --git a/src/client/auth/models/ErrorDetail.ts b/src/client/models/ErrorDetail.ts
similarity index 100%
rename from src/client/auth/models/ErrorDetail.ts
rename to src/client/models/ErrorDetail.ts
diff --git a/src/client/resource/models/FileTree.ts b/src/client/models/FileTree.ts
similarity index 100%
rename from src/client/resource/models/FileTree.ts
rename to src/client/models/FileTree.ts
diff --git a/src/client/auth/models/HTTPValidationError.ts b/src/client/models/HTTPValidationError.ts
similarity index 100%
rename from src/client/auth/models/HTTPValidationError.ts
rename to src/client/models/HTTPValidationError.ts
diff --git a/src/client/workflow/models/IconUpdateOut.ts b/src/client/models/IconUpdateOut.ts
similarity index 100%
rename from src/client/workflow/models/IconUpdateOut.ts
rename to src/client/models/IconUpdateOut.ts
diff --git a/src/client/auth/models/OIDCProvider.ts b/src/client/models/OIDCProvider.ts
similarity index 100%
rename from src/client/auth/models/OIDCProvider.ts
rename to src/client/models/OIDCProvider.ts
diff --git a/src/client/workflow/models/ParameterExtension.ts b/src/client/models/ParameterExtension.ts
similarity index 100%
rename from src/client/workflow/models/ParameterExtension.ts
rename to src/client/models/ParameterExtension.ts
diff --git a/src/client/s3proxy/models/Permission.ts b/src/client/models/Permission.ts
similarity index 100%
rename from src/client/s3proxy/models/Permission.ts
rename to src/client/models/Permission.ts
diff --git a/src/client/s3proxy/models/PermissionStatus.ts b/src/client/models/PermissionStatus.ts
similarity index 100%
rename from src/client/s3proxy/models/PermissionStatus.ts
rename to src/client/models/PermissionStatus.ts
diff --git a/src/client/resource/models/ResourceIn.ts b/src/client/models/ResourceIn.ts
similarity index 100%
rename from src/client/resource/models/ResourceIn.ts
rename to src/client/models/ResourceIn.ts
diff --git a/src/client/resource/models/ResourceOut.ts b/src/client/models/ResourceOut.ts
similarity index 95%
rename from src/client/resource/models/ResourceOut.ts
rename to src/client/models/ResourceOut.ts
index 60b1290a47dc8151de42df19e72fcaf143092f6f..b9d4d9a7776164e55048a56f15d000cebc98bcca 100644
--- a/src/client/resource/models/ResourceOut.ts
+++ b/src/client/models/ResourceOut.ts
@@ -27,7 +27,7 @@ export type ResourceOut = {
     /**
      * ID of the maintainer
      */
-    maintainer_id: string;
+    maintainer_id: (string | null);
     /**
      * Versions of the resource
      */
diff --git a/src/client/resource/models/ResourceVersionIn.ts b/src/client/models/ResourceVersionIn.ts
similarity index 100%
rename from src/client/resource/models/ResourceVersionIn.ts
rename to src/client/models/ResourceVersionIn.ts
diff --git a/src/client/resource/models/ResourceVersionOut.ts b/src/client/models/ResourceVersionOut.ts
similarity index 88%
rename from src/client/resource/models/ResourceVersionOut.ts
rename to src/client/models/ResourceVersionOut.ts
index 56881be8c538135a467df287d9bc53472d05d183..cda547e72a646a4bdaaeebb6f9a378a2d741e024 100644
--- a/src/client/resource/models/ResourceVersionOut.ts
+++ b/src/client/models/ResourceVersionOut.ts
@@ -2,7 +2,7 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
-import type { Status } from './Status';
+import type { ResourceVersionStatus } from './ResourceVersionStatus';
 export type ResourceVersionOut = {
     /**
      * Short tag describing the version of the resource
@@ -11,7 +11,7 @@ export type ResourceVersionOut = {
     /**
      * Status of the resource version
      */
-    status: Status;
+    status: ResourceVersionStatus;
     /**
      * ID of the resource version
      */
diff --git a/src/client/resource/models/Status.ts b/src/client/models/ResourceVersionStatus.ts
similarity index 95%
rename from src/client/resource/models/Status.ts
rename to src/client/models/ResourceVersionStatus.ts
index 71fd950a1903618a6dacb1e94e7a2cbf7489db34..3b2b88014dbff47537b8b6a4ca2d36296732ee26 100644
--- a/src/client/resource/models/Status.ts
+++ b/src/client/models/ResourceVersionStatus.ts
@@ -5,7 +5,7 @@
 /**
  * Enumeration for the possible status of a resource version.
  */
-export enum Status {
+export enum ResourceVersionStatus {
     RESOURCE_REQUESTED = 'RESOURCE_REQUESTED',
     WAIT_FOR_REVIEW = 'WAIT_FOR_REVIEW',
     DENIED = 'DENIED',
diff --git a/src/client/auth/models/RoleEnum.ts b/src/client/models/RoleEnum.ts
similarity index 76%
rename from src/client/auth/models/RoleEnum.ts
rename to src/client/models/RoleEnum.ts
index 66c17a59edee7c6ac452ac757275260821cdd48f..f99f38d450bf8b9fc149f8884bacd7d9ba3a960d 100644
--- a/src/client/auth/models/RoleEnum.ts
+++ b/src/client/models/RoleEnum.ts
@@ -2,14 +2,10 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
-/**
- * Enumeration for the Roles in the CloWM Services.
- */
 export enum RoleEnum {
     ADMINISTRATOR = 'administrator',
     USER = 'user',
     REVIEWER = 'reviewer',
     DEVELOPER = 'developer',
-    FOREIGN_USER = 'foreign_user',
     DB_MAINTAINER = 'db_maintainer',
 }
diff --git a/src/client/s3proxy/models/S3Key.ts b/src/client/models/S3Key.ts
similarity index 100%
rename from src/client/s3proxy/models/S3Key.ts
rename to src/client/models/S3Key.ts
diff --git a/src/client/models/UserIn.ts b/src/client/models/UserIn.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f95190fbc2b4dd57167c586d634b415b75d0e0b0
--- /dev/null
+++ b/src/client/models/UserIn.ts
@@ -0,0 +1,17 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { RoleEnum } from './RoleEnum';
+export type UserIn = {
+    /**
+     * Full Name of the user
+     */
+    display_name: string;
+    roles?: Array<RoleEnum>;
+    /**
+     * Email of the user
+     */
+    email: string;
+};
+
diff --git a/src/client/resource/models/ErrorDetail.ts b/src/client/models/UserOut.ts
similarity index 50%
rename from src/client/resource/models/ErrorDetail.ts
rename to src/client/models/UserOut.ts
index 3b8a588e591ca42adc538757044eee2cf6b5881a..31a72c1fcd2a2572d993fcd4783b1ebac1019e39 100644
--- a/src/client/resource/models/ErrorDetail.ts
+++ b/src/client/models/UserOut.ts
@@ -3,12 +3,16 @@
 /* tslint:disable */
 /* eslint-disable */
 /**
- * Schema for a error due to a rejected request.
+ * Schema for a user.
  */
-export type ErrorDetail = {
+export type UserOut = {
     /**
-     * Detail about the occurred error
+     * Full Name of the user
      */
-    detail: string;
+    display_name: string;
+    /**
+     * ID of the user
+     */
+    uid: string;
 };
 
diff --git a/src/client/auth/models/User.ts b/src/client/models/UserOutExtended.ts
similarity index 70%
rename from src/client/auth/models/User.ts
rename to src/client/models/UserOutExtended.ts
index 537adb1841d16979e6ee0939fa21a4f96a232c00..388029c42f15f285a1f5add98255160f37b07340 100644
--- a/src/client/auth/models/User.ts
+++ b/src/client/models/UserOutExtended.ts
@@ -3,21 +3,22 @@
 /* tslint:disable */
 /* eslint-disable */
 import type { RoleEnum } from './RoleEnum';
-/**
- * Schema for a user.
- */
-export type User = {
+export type UserOutExtended = {
     /**
-     * ID of the user
+     * Roles of the user
      */
-    uid: string;
+    roles: Array<RoleEnum>;
     /**
      * Full Name of the user
      */
     display_name: string;
     /**
-     * Roles of the user
+     * ID of the user
+     */
+    uid: string;
+    /**
+     * Lifesicence ID of the user
      */
-    roles?: (Array<RoleEnum> | null);
+    lifescience_id?: (string | null);
 };
 
diff --git a/src/client/resource/models/UserRequestAnswer.ts b/src/client/models/UserRequestAnswer.ts
similarity index 100%
rename from src/client/resource/models/UserRequestAnswer.ts
rename to src/client/models/UserRequestAnswer.ts
diff --git a/src/client/s3proxy/models/ErrorDetail.ts b/src/client/models/UserRoles.ts
similarity index 51%
rename from src/client/s3proxy/models/ErrorDetail.ts
rename to src/client/models/UserRoles.ts
index 3b8a588e591ca42adc538757044eee2cf6b5881a..0ec55923947ba54d7c9a08b122819d6c480c2f68 100644
--- a/src/client/s3proxy/models/ErrorDetail.ts
+++ b/src/client/models/UserRoles.ts
@@ -2,13 +2,11 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
-/**
- * Schema for a error due to a rejected request.
- */
-export type ErrorDetail = {
+import type { RoleEnum } from './RoleEnum';
+export type UserRoles = {
     /**
-     * Detail about the occurred error
+     * Roles of the user
      */
-    detail: string;
+    roles: Array<RoleEnum>;
 };
 
diff --git a/src/client/resource/models/UserSynchronizationRequestIn.ts b/src/client/models/UserSynchronizationRequestIn.ts
similarity index 100%
rename from src/client/resource/models/UserSynchronizationRequestIn.ts
rename to src/client/models/UserSynchronizationRequestIn.ts
diff --git a/src/client/resource/models/UserSynchronizationRequestOut.ts b/src/client/models/UserSynchronizationRequestOut.ts
similarity index 100%
rename from src/client/resource/models/UserSynchronizationRequestOut.ts
rename to src/client/models/UserSynchronizationRequestOut.ts
diff --git a/src/client/auth/models/ValidationError.ts b/src/client/models/ValidationError.ts
similarity index 100%
rename from src/client/auth/models/ValidationError.ts
rename to src/client/models/ValidationError.ts
diff --git a/src/client/workflow/models/WorkflowCredentialsIn.ts b/src/client/models/WorkflowCredentialsIn.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowCredentialsIn.ts
rename to src/client/models/WorkflowCredentialsIn.ts
diff --git a/src/client/workflow/models/WorkflowCredentialsOut.ts b/src/client/models/WorkflowCredentialsOut.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowCredentialsOut.ts
rename to src/client/models/WorkflowCredentialsOut.ts
diff --git a/src/client/workflow/models/WorkflowExecutionIn.ts b/src/client/models/WorkflowExecutionIn.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowExecutionIn.ts
rename to src/client/models/WorkflowExecutionIn.ts
diff --git a/src/client/workflow/models/WorkflowExecutionOut.ts b/src/client/models/WorkflowExecutionOut.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowExecutionOut.ts
rename to src/client/models/WorkflowExecutionOut.ts
diff --git a/src/client/workflow/models/WorkflowExecutionStatus.ts b/src/client/models/WorkflowExecutionStatus.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowExecutionStatus.ts
rename to src/client/models/WorkflowExecutionStatus.ts
diff --git a/src/client/workflow/models/WorkflowIn.ts b/src/client/models/WorkflowIn.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowIn.ts
rename to src/client/models/WorkflowIn.ts
diff --git a/src/client/workflow/models/WorkflowModeIn.ts b/src/client/models/WorkflowModeIn.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowModeIn.ts
rename to src/client/models/WorkflowModeIn.ts
diff --git a/src/client/workflow/models/WorkflowModeOut.ts b/src/client/models/WorkflowModeOut.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowModeOut.ts
rename to src/client/models/WorkflowModeOut.ts
diff --git a/src/client/workflow/models/WorkflowOut.ts b/src/client/models/WorkflowOut.ts
similarity index 95%
rename from src/client/workflow/models/WorkflowOut.ts
rename to src/client/models/WorkflowOut.ts
index d4968c2c9c30003675c80ffc24fe181e1d4f303b..0f41c54708f8442104ed669472d31780574fd1e1 100644
--- a/src/client/workflow/models/WorkflowOut.ts
+++ b/src/client/models/WorkflowOut.ts
@@ -27,7 +27,7 @@ export type WorkflowOut = {
     /**
      * ID of developer of the workflow
      */
-    developer_id: string;
+    developer_id?: (string | null);
     /**
      * Flag if the workflow is hosted in a private git repository
      */
diff --git a/src/client/workflow/models/WorkflowStatistic.ts b/src/client/models/WorkflowStatistic.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowStatistic.ts
rename to src/client/models/WorkflowStatistic.ts
diff --git a/src/client/workflow/models/WorkflowUpdate.ts b/src/client/models/WorkflowUpdate.ts
similarity index 100%
rename from src/client/workflow/models/WorkflowUpdate.ts
rename to src/client/models/WorkflowUpdate.ts
diff --git a/src/client/workflow/models/WorkflowVersion.ts b/src/client/models/WorkflowVersion.ts
similarity index 87%
rename from src/client/workflow/models/WorkflowVersion.ts
rename to src/client/models/WorkflowVersion.ts
index da35ffd2a70d3d61a1adc69fd1a1672e78448492..1974ff18e1a2a3bc5434fc72b959ec01ade3ecc9 100644
--- a/src/client/workflow/models/WorkflowVersion.ts
+++ b/src/client/models/WorkflowVersion.ts
@@ -3,12 +3,12 @@
 /* tslint:disable */
 /* eslint-disable */
 import type { ParameterExtension } from './ParameterExtension';
-import type { Status } from './Status';
+import type { WorkflowVersionStatus } from './WorkflowVersionStatus';
 export type WorkflowVersion = {
     /**
      * Status of the workflow version
      */
-    status: Status;
+    status: WorkflowVersionStatus;
     /**
      * ID of the corresponding workflow
      */
@@ -18,13 +18,13 @@ export type WorkflowVersion = {
      */
     version: string;
     /**
-     * Hash of the git commit
+     * URL to the uploaded icon
      */
-    workflow_version_id: string;
+    icon_url?: (string | null);
     /**
-     * URL of the icon for this workflow version
+     * Hash of the git commit
      */
-    icon_url?: (string | null);
+    workflow_version_id: string;
     /**
      * Timestamp when the version was created as UNIX timestamp
      */
diff --git a/src/client/workflow/models/Status.ts b/src/client/models/WorkflowVersionStatus.ts
similarity index 89%
rename from src/client/workflow/models/Status.ts
rename to src/client/models/WorkflowVersionStatus.ts
index db27a378d22e80e9ca6f7a66c7ed6ac9acc591f7..cb031bbc90005091e8be8a16b0db718c829d10fb 100644
--- a/src/client/workflow/models/Status.ts
+++ b/src/client/models/WorkflowVersionStatus.ts
@@ -5,7 +5,7 @@
 /**
  * Enumeration for the possible status of a workflow version.
  */
-export enum Status {
+export enum WorkflowVersionStatus {
     CREATED = 'CREATED',
     DENIED = 'DENIED',
     PUBLISHED = 'PUBLISHED',
diff --git a/src/client/workflow/models/WorkflowVersionStatus.ts b/src/client/models/WorkflowVersionStatusSchema.ts
similarity index 56%
rename from src/client/workflow/models/WorkflowVersionStatus.ts
rename to src/client/models/WorkflowVersionStatusSchema.ts
index 9477c1f502dd983e11adf94656318f547606a044..c4dd3e49c2f9a8ec1950133364eb023835ac468f 100644
--- a/src/client/workflow/models/WorkflowVersionStatus.ts
+++ b/src/client/models/WorkflowVersionStatusSchema.ts
@@ -2,11 +2,11 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
-import type { Status } from './Status';
-export type WorkflowVersionStatus = {
+import type { WorkflowVersionStatus } from './WorkflowVersionStatus';
+export type WorkflowVersionStatusSchema = {
     /**
      * Status of the workflow version
      */
-    status: Status;
+    status: WorkflowVersionStatus;
 };
 
diff --git a/src/client/resource/core/ApiError.ts b/src/client/resource/core/ApiError.ts
deleted file mode 100644
index ec7b16af6f41b1323a8e3aa3d529bf2324959e66..0000000000000000000000000000000000000000
--- a/src/client/resource/core/ApiError.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ApiRequestOptions } from './ApiRequestOptions';
-import type { ApiResult } from './ApiResult';
-
-export class ApiError extends Error {
-    public readonly url: string;
-    public readonly status: number;
-    public readonly statusText: string;
-    public readonly body: any;
-    public readonly request: ApiRequestOptions;
-
-    constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
-        super(message);
-
-        this.name = 'ApiError';
-        this.url = response.url;
-        this.status = response.status;
-        this.statusText = response.statusText;
-        this.body = response.body;
-        this.request = request;
-    }
-}
diff --git a/src/client/resource/core/ApiRequestOptions.ts b/src/client/resource/core/ApiRequestOptions.ts
deleted file mode 100644
index 93143c3ce1ba5323894d4ac10299f62493f030f6..0000000000000000000000000000000000000000
--- a/src/client/resource/core/ApiRequestOptions.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ApiRequestOptions = {
-    readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
-    readonly url: string;
-    readonly path?: Record<string, any>;
-    readonly cookies?: Record<string, any>;
-    readonly headers?: Record<string, any>;
-    readonly query?: Record<string, any>;
-    readonly formData?: Record<string, any>;
-    readonly body?: any;
-    readonly mediaType?: string;
-    readonly responseHeader?: string;
-    readonly errors?: Record<number, string>;
-};
diff --git a/src/client/resource/core/ApiResult.ts b/src/client/resource/core/ApiResult.ts
deleted file mode 100644
index ee1126e2ccd1e37dba97511c38c56a282ceac4dc..0000000000000000000000000000000000000000
--- a/src/client/resource/core/ApiResult.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ApiResult = {
-    readonly url: string;
-    readonly ok: boolean;
-    readonly status: number;
-    readonly statusText: string;
-    readonly body: any;
-};
diff --git a/src/client/resource/core/CancelablePromise.ts b/src/client/resource/core/CancelablePromise.ts
deleted file mode 100644
index d70de92946d977e9da7970871375117a8b04770a..0000000000000000000000000000000000000000
--- a/src/client/resource/core/CancelablePromise.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export class CancelError extends Error {
-
-    constructor(message: string) {
-        super(message);
-        this.name = 'CancelError';
-    }
-
-    public get isCancelled(): boolean {
-        return true;
-    }
-}
-
-export interface OnCancel {
-    readonly isResolved: boolean;
-    readonly isRejected: boolean;
-    readonly isCancelled: boolean;
-
-    (cancelHandler: () => void): void;
-}
-
-export class CancelablePromise<T> implements Promise<T> {
-    #isResolved: boolean;
-    #isRejected: boolean;
-    #isCancelled: boolean;
-    readonly #cancelHandlers: (() => void)[];
-    readonly #promise: Promise<T>;
-    #resolve?: (value: T | PromiseLike<T>) => void;
-    #reject?: (reason?: any) => void;
-
-    constructor(
-        executor: (
-            resolve: (value: T | PromiseLike<T>) => void,
-            reject: (reason?: any) => void,
-            onCancel: OnCancel
-        ) => void
-    ) {
-        this.#isResolved = false;
-        this.#isRejected = false;
-        this.#isCancelled = false;
-        this.#cancelHandlers = [];
-        this.#promise = new Promise<T>((resolve, reject) => {
-            this.#resolve = resolve;
-            this.#reject = reject;
-
-            const onResolve = (value: T | PromiseLike<T>): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#isResolved = true;
-                if (this.#resolve) this.#resolve(value);
-            };
-
-            const onReject = (reason?: any): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#isRejected = true;
-                if (this.#reject) this.#reject(reason);
-            };
-
-            const onCancel = (cancelHandler: () => void): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#cancelHandlers.push(cancelHandler);
-            };
-
-            Object.defineProperty(onCancel, 'isResolved', {
-                get: (): boolean => this.#isResolved,
-            });
-
-            Object.defineProperty(onCancel, 'isRejected', {
-                get: (): boolean => this.#isRejected,
-            });
-
-            Object.defineProperty(onCancel, 'isCancelled', {
-                get: (): boolean => this.#isCancelled,
-            });
-
-            return executor(onResolve, onReject, onCancel as OnCancel);
-        });
-    }
-
-    get [Symbol.toStringTag]() {
-        return "Cancellable Promise";
-    }
-
-    public then<TResult1 = T, TResult2 = never>(
-        onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
-        onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
-    ): Promise<TResult1 | TResult2> {
-        return this.#promise.then(onFulfilled, onRejected);
-    }
-
-    public catch<TResult = never>(
-        onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
-    ): Promise<T | TResult> {
-        return this.#promise.catch(onRejected);
-    }
-
-    public finally(onFinally?: (() => void) | null): Promise<T> {
-        return this.#promise.finally(onFinally);
-    }
-
-    public cancel(): void {
-        if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-            return;
-        }
-        this.#isCancelled = true;
-        if (this.#cancelHandlers.length) {
-            try {
-                for (const cancelHandler of this.#cancelHandlers) {
-                    cancelHandler();
-                }
-            } catch (error) {
-                console.warn('Cancellation threw an error', error);
-                return;
-            }
-        }
-        this.#cancelHandlers.length = 0;
-        if (this.#reject) this.#reject(new CancelError('Request aborted'));
-    }
-
-    public get isCancelled(): boolean {
-        return this.#isCancelled;
-    }
-}
diff --git a/src/client/resource/core/OpenAPI.ts b/src/client/resource/core/OpenAPI.ts
deleted file mode 100644
index 0ead9e182ad0cce6f9abc4021dec0367eb60cb63..0000000000000000000000000000000000000000
--- a/src/client/resource/core/OpenAPI.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ApiRequestOptions } from './ApiRequestOptions';
-
-type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
-type Headers = Record<string, string>;
-
-export type OpenAPIConfig = {
-    BASE: string;
-    VERSION: string;
-    WITH_CREDENTIALS: boolean;
-    CREDENTIALS: 'include' | 'omit' | 'same-origin';
-    TOKEN?: string | Resolver<string> | undefined;
-    USERNAME?: string | Resolver<string> | undefined;
-    PASSWORD?: string | Resolver<string> | undefined;
-    HEADERS?: Headers | Resolver<Headers> | undefined;
-    ENCODE_PATH?: ((path: string) => string) | undefined;
-};
-
-export const OpenAPI: OpenAPIConfig = {
-    BASE: '/api/resource-service',
-    VERSION: '1.0.0',
-    WITH_CREDENTIALS: false,
-    CREDENTIALS: 'include',
-    TOKEN: undefined,
-    USERNAME: undefined,
-    PASSWORD: undefined,
-    HEADERS: undefined,
-    ENCODE_PATH: undefined,
-};
diff --git a/src/client/resource/core/request.ts b/src/client/resource/core/request.ts
deleted file mode 100644
index 1dc6fef4aab4086ff57b48d26b20ec26bb8fa472..0000000000000000000000000000000000000000
--- a/src/client/resource/core/request.ts
+++ /dev/null
@@ -1,323 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import axios from 'axios';
-import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
-import FormData from 'form-data';
-
-import { ApiError } from './ApiError';
-import type { ApiRequestOptions } from './ApiRequestOptions';
-import type { ApiResult } from './ApiResult';
-import { CancelablePromise } from './CancelablePromise';
-import type { OnCancel } from './CancelablePromise';
-import type { OpenAPIConfig } from './OpenAPI';
-
-export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
-    return value !== undefined && value !== null;
-};
-
-export const isString = (value: any): value is string => {
-    return typeof value === 'string';
-};
-
-export const isStringWithValue = (value: any): value is string => {
-    return isString(value) && value !== '';
-};
-
-export const isBlob = (value: any): value is Blob => {
-    return (
-        typeof value === 'object' &&
-        typeof value.type === 'string' &&
-        typeof value.stream === 'function' &&
-        typeof value.arrayBuffer === 'function' &&
-        typeof value.constructor === 'function' &&
-        typeof value.constructor.name === 'string' &&
-        /^(Blob|File)$/.test(value.constructor.name) &&
-        /^(Blob|File)$/.test(value[Symbol.toStringTag])
-    );
-};
-
-export const isFormData = (value: any): value is FormData => {
-    return value instanceof FormData;
-};
-
-export const isSuccess = (status: number): boolean => {
-    return status >= 200 && status < 300;
-};
-
-export const base64 = (str: string): string => {
-    try {
-        return btoa(str);
-    } catch (err) {
-        // @ts-ignore
-        return Buffer.from(str).toString('base64');
-    }
-};
-
-export const getQueryString = (params: Record<string, any>): string => {
-    const qs: string[] = [];
-
-    const append = (key: string, value: any) => {
-        qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
-    };
-
-    const process = (key: string, value: any) => {
-        if (isDefined(value)) {
-            if (Array.isArray(value)) {
-                value.forEach(v => {
-                    process(key, v);
-                });
-            } else if (typeof value === 'object') {
-                Object.entries(value).forEach(([k, v]) => {
-                    process(`${key}[${k}]`, v);
-                });
-            } else {
-                append(key, value);
-            }
-        }
-    };
-
-    Object.entries(params).forEach(([key, value]) => {
-        process(key, value);
-    });
-
-    if (qs.length > 0) {
-        return `?${qs.join('&')}`;
-    }
-
-    return '';
-};
-
-const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
-    const encoder = config.ENCODE_PATH || encodeURI;
-
-    const path = options.url
-        .replace('{api-version}', config.VERSION)
-        .replace(/{(.*?)}/g, (substring: string, group: string) => {
-            if (options.path?.hasOwnProperty(group)) {
-                return encoder(String(options.path[group]));
-            }
-            return substring;
-        });
-
-    const url = `${config.BASE}${path}`;
-    if (options.query) {
-        return `${url}${getQueryString(options.query)}`;
-    }
-    return url;
-};
-
-export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
-    if (options.formData) {
-        const formData = new FormData();
-
-        const process = (key: string, value: any) => {
-            if (isString(value) || isBlob(value)) {
-                formData.append(key, value);
-            } else {
-                formData.append(key, JSON.stringify(value));
-            }
-        };
-
-        Object.entries(options.formData)
-            .filter(([_, value]) => isDefined(value))
-            .forEach(([key, value]) => {
-                if (Array.isArray(value)) {
-                    value.forEach(v => process(key, v));
-                } else {
-                    process(key, value);
-                }
-            });
-
-        return formData;
-    }
-    return undefined;
-};
-
-type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
-
-export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
-    if (typeof resolver === 'function') {
-        return (resolver as Resolver<T>)(options);
-    }
-    return resolver;
-};
-
-export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
-    const [token, username, password, additionalHeaders] = await Promise.all([
-        resolve(options, config.TOKEN),
-        resolve(options, config.USERNAME),
-        resolve(options, config.PASSWORD),
-        resolve(options, config.HEADERS),
-    ]);
-
-    const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
-
-    const headers = Object.entries({
-        Accept: 'application/json',
-        ...additionalHeaders,
-        ...options.headers,
-        ...formHeaders,
-    })
-    .filter(([_, value]) => isDefined(value))
-    .reduce((headers, [key, value]) => ({
-        ...headers,
-        [key]: String(value),
-    }), {} as Record<string, string>);
-
-    if (isStringWithValue(token)) {
-        headers['Authorization'] = `Bearer ${token}`;
-    }
-
-    if (isStringWithValue(username) && isStringWithValue(password)) {
-        const credentials = base64(`${username}:${password}`);
-        headers['Authorization'] = `Basic ${credentials}`;
-    }
-
-    if (options.body !== undefined) {
-        if (options.mediaType) {
-            headers['Content-Type'] = options.mediaType;
-        } else if (isBlob(options.body)) {
-            headers['Content-Type'] = options.body.type || 'application/octet-stream';
-        } else if (isString(options.body)) {
-            headers['Content-Type'] = 'text/plain';
-        } else if (!isFormData(options.body)) {
-            headers['Content-Type'] = 'application/json';
-        }
-    }
-
-    return headers;
-};
-
-export const getRequestBody = (options: ApiRequestOptions): any => {
-    if (options.body) {
-        return options.body;
-    }
-    return undefined;
-};
-
-export const sendRequest = async <T>(
-    config: OpenAPIConfig,
-    options: ApiRequestOptions,
-    url: string,
-    body: any,
-    formData: FormData | undefined,
-    headers: Record<string, string>,
-    onCancel: OnCancel,
-    axiosClient: AxiosInstance
-): Promise<AxiosResponse<T>> => {
-    const source = axios.CancelToken.source();
-
-    const requestConfig: AxiosRequestConfig = {
-        url,
-        headers,
-        data: body ?? formData,
-        method: options.method,
-        withCredentials: config.WITH_CREDENTIALS,
-        withXSRFToken: config.CREDENTIALS === 'include' ? config.WITH_CREDENTIALS : false,
-        cancelToken: source.token,
-    };
-
-    onCancel(() => source.cancel('The user aborted a request.'));
-
-    try {
-        return await axiosClient.request(requestConfig);
-    } catch (error) {
-        const axiosError = error as AxiosError<T>;
-        if (axiosError.response) {
-            return axiosError.response;
-        }
-        throw error;
-    }
-};
-
-export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
-    if (responseHeader) {
-        const content = response.headers[responseHeader];
-        if (isString(content)) {
-            return content;
-        }
-    }
-    return undefined;
-};
-
-export const getResponseBody = (response: AxiosResponse<any>): any => {
-    if (response.status !== 204) {
-        return response.data;
-    }
-    return undefined;
-};
-
-export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
-    const errors: Record<number, string> = {
-        400: 'Bad Request',
-        401: 'Unauthorized',
-        403: 'Forbidden',
-        404: 'Not Found',
-        500: 'Internal Server Error',
-        502: 'Bad Gateway',
-        503: 'Service Unavailable',
-        ...options.errors,
-    }
-
-    const error = errors[result.status];
-    if (error) {
-        throw new ApiError(options, result, error);
-    }
-
-    if (!result.ok) {
-        const errorStatus = result.status ?? 'unknown';
-        const errorStatusText = result.statusText ?? 'unknown';
-        const errorBody = (() => {
-            try {
-                return JSON.stringify(result.body, null, 2);
-            } catch (e) {
-                return undefined;
-            }
-        })();
-
-        throw new ApiError(options, result,
-            `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
-        );
-    }
-};
-
-/**
- * Request method
- * @param config The OpenAPI configuration object
- * @param options The request options from the service
- * @param axiosClient The axios client instance to use
- * @returns CancelablePromise<T>
- * @throws ApiError
- */
-export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
-    return new CancelablePromise(async (resolve, reject, onCancel) => {
-        try {
-            const url = getUrl(config, options);
-            const formData = getFormData(options);
-            const body = getRequestBody(options);
-            const headers = await getHeaders(config, options, formData);
-
-            if (!onCancel.isCancelled) {
-                const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
-                const responseBody = getResponseBody(response);
-                const responseHeader = getResponseHeader(response, options.responseHeader);
-
-                const result: ApiResult = {
-                    url,
-                    ok: isSuccess(response.status),
-                    status: response.status,
-                    statusText: response.statusText,
-                    body: responseHeader ?? responseBody,
-                };
-
-                catchErrorCodes(options, result);
-
-                resolve(result.body);
-            }
-        } catch (error) {
-            reject(error);
-        }
-    });
-};
diff --git a/src/client/resource/index.ts b/src/client/resource/index.ts
deleted file mode 100644
index 8a53b0b2f563ff6d17c66114d31cfa106d74c038..0000000000000000000000000000000000000000
--- a/src/client/resource/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export { ApiError } from './core/ApiError';
-export { CancelablePromise, CancelError } from './core/CancelablePromise';
-export { OpenAPI } from './core/OpenAPI';
-export type { OpenAPIConfig } from './core/OpenAPI';
-
-export type { ErrorDetail } from './models/ErrorDetail';
-export { FileTree } from './models/FileTree';
-export type { HTTPValidationError } from './models/HTTPValidationError';
-export type { ResourceIn } from './models/ResourceIn';
-export type { ResourceOut } from './models/ResourceOut';
-export type { ResourceVersionIn } from './models/ResourceVersionIn';
-export type { ResourceVersionOut } from './models/ResourceVersionOut';
-export { Status } from './models/Status';
-export type { UserRequestAnswer } from './models/UserRequestAnswer';
-export type { UserSynchronizationRequestIn } from './models/UserSynchronizationRequestIn';
-export type { UserSynchronizationRequestOut } from './models/UserSynchronizationRequestOut';
-export type { ValidationError } from './models/ValidationError';
-
-export { ResourceService } from './services/ResourceService';
-export { ResourceVersionService } from './services/ResourceVersionService';
diff --git a/src/client/resource/models/HTTPValidationError.ts b/src/client/resource/models/HTTPValidationError.ts
deleted file mode 100644
index f9b1a79e2c6debaa712bb1660d4353552f6fbfad..0000000000000000000000000000000000000000
--- a/src/client/resource/models/HTTPValidationError.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ValidationError } from './ValidationError';
-export type HTTPValidationError = {
-    detail?: Array<ValidationError>;
-};
-
diff --git a/src/client/resource/models/ValidationError.ts b/src/client/resource/models/ValidationError.ts
deleted file mode 100644
index aaf1c921e8b674c3da9543cc2cb597e8e90d6d8f..0000000000000000000000000000000000000000
--- a/src/client/resource/models/ValidationError.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ValidationError = {
-    loc: Array<(string | number)>;
-    msg: string;
-    type: string;
-};
-
diff --git a/src/client/s3proxy/core/ApiError.ts b/src/client/s3proxy/core/ApiError.ts
deleted file mode 100644
index ec7b16af6f41b1323a8e3aa3d529bf2324959e66..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/core/ApiError.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ApiRequestOptions } from './ApiRequestOptions';
-import type { ApiResult } from './ApiResult';
-
-export class ApiError extends Error {
-    public readonly url: string;
-    public readonly status: number;
-    public readonly statusText: string;
-    public readonly body: any;
-    public readonly request: ApiRequestOptions;
-
-    constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
-        super(message);
-
-        this.name = 'ApiError';
-        this.url = response.url;
-        this.status = response.status;
-        this.statusText = response.statusText;
-        this.body = response.body;
-        this.request = request;
-    }
-}
diff --git a/src/client/s3proxy/core/ApiRequestOptions.ts b/src/client/s3proxy/core/ApiRequestOptions.ts
deleted file mode 100644
index 93143c3ce1ba5323894d4ac10299f62493f030f6..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/core/ApiRequestOptions.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ApiRequestOptions = {
-    readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
-    readonly url: string;
-    readonly path?: Record<string, any>;
-    readonly cookies?: Record<string, any>;
-    readonly headers?: Record<string, any>;
-    readonly query?: Record<string, any>;
-    readonly formData?: Record<string, any>;
-    readonly body?: any;
-    readonly mediaType?: string;
-    readonly responseHeader?: string;
-    readonly errors?: Record<number, string>;
-};
diff --git a/src/client/s3proxy/core/ApiResult.ts b/src/client/s3proxy/core/ApiResult.ts
deleted file mode 100644
index ee1126e2ccd1e37dba97511c38c56a282ceac4dc..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/core/ApiResult.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ApiResult = {
-    readonly url: string;
-    readonly ok: boolean;
-    readonly status: number;
-    readonly statusText: string;
-    readonly body: any;
-};
diff --git a/src/client/s3proxy/core/CancelablePromise.ts b/src/client/s3proxy/core/CancelablePromise.ts
deleted file mode 100644
index d70de92946d977e9da7970871375117a8b04770a..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/core/CancelablePromise.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export class CancelError extends Error {
-
-    constructor(message: string) {
-        super(message);
-        this.name = 'CancelError';
-    }
-
-    public get isCancelled(): boolean {
-        return true;
-    }
-}
-
-export interface OnCancel {
-    readonly isResolved: boolean;
-    readonly isRejected: boolean;
-    readonly isCancelled: boolean;
-
-    (cancelHandler: () => void): void;
-}
-
-export class CancelablePromise<T> implements Promise<T> {
-    #isResolved: boolean;
-    #isRejected: boolean;
-    #isCancelled: boolean;
-    readonly #cancelHandlers: (() => void)[];
-    readonly #promise: Promise<T>;
-    #resolve?: (value: T | PromiseLike<T>) => void;
-    #reject?: (reason?: any) => void;
-
-    constructor(
-        executor: (
-            resolve: (value: T | PromiseLike<T>) => void,
-            reject: (reason?: any) => void,
-            onCancel: OnCancel
-        ) => void
-    ) {
-        this.#isResolved = false;
-        this.#isRejected = false;
-        this.#isCancelled = false;
-        this.#cancelHandlers = [];
-        this.#promise = new Promise<T>((resolve, reject) => {
-            this.#resolve = resolve;
-            this.#reject = reject;
-
-            const onResolve = (value: T | PromiseLike<T>): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#isResolved = true;
-                if (this.#resolve) this.#resolve(value);
-            };
-
-            const onReject = (reason?: any): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#isRejected = true;
-                if (this.#reject) this.#reject(reason);
-            };
-
-            const onCancel = (cancelHandler: () => void): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#cancelHandlers.push(cancelHandler);
-            };
-
-            Object.defineProperty(onCancel, 'isResolved', {
-                get: (): boolean => this.#isResolved,
-            });
-
-            Object.defineProperty(onCancel, 'isRejected', {
-                get: (): boolean => this.#isRejected,
-            });
-
-            Object.defineProperty(onCancel, 'isCancelled', {
-                get: (): boolean => this.#isCancelled,
-            });
-
-            return executor(onResolve, onReject, onCancel as OnCancel);
-        });
-    }
-
-    get [Symbol.toStringTag]() {
-        return "Cancellable Promise";
-    }
-
-    public then<TResult1 = T, TResult2 = never>(
-        onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
-        onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
-    ): Promise<TResult1 | TResult2> {
-        return this.#promise.then(onFulfilled, onRejected);
-    }
-
-    public catch<TResult = never>(
-        onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
-    ): Promise<T | TResult> {
-        return this.#promise.catch(onRejected);
-    }
-
-    public finally(onFinally?: (() => void) | null): Promise<T> {
-        return this.#promise.finally(onFinally);
-    }
-
-    public cancel(): void {
-        if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-            return;
-        }
-        this.#isCancelled = true;
-        if (this.#cancelHandlers.length) {
-            try {
-                for (const cancelHandler of this.#cancelHandlers) {
-                    cancelHandler();
-                }
-            } catch (error) {
-                console.warn('Cancellation threw an error', error);
-                return;
-            }
-        }
-        this.#cancelHandlers.length = 0;
-        if (this.#reject) this.#reject(new CancelError('Request aborted'));
-    }
-
-    public get isCancelled(): boolean {
-        return this.#isCancelled;
-    }
-}
diff --git a/src/client/s3proxy/core/OpenAPI.ts b/src/client/s3proxy/core/OpenAPI.ts
deleted file mode 100644
index 35524ea4ce5a4157bdab674f394ae304ee6f0a35..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/core/OpenAPI.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ApiRequestOptions } from './ApiRequestOptions';
-
-type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
-type Headers = Record<string, string>;
-
-export type OpenAPIConfig = {
-    BASE: string;
-    VERSION: string;
-    WITH_CREDENTIALS: boolean;
-    CREDENTIALS: 'include' | 'omit' | 'same-origin';
-    TOKEN?: string | Resolver<string> | undefined;
-    USERNAME?: string | Resolver<string> | undefined;
-    PASSWORD?: string | Resolver<string> | undefined;
-    HEADERS?: Headers | Resolver<Headers> | undefined;
-    ENCODE_PATH?: ((path: string) => string) | undefined;
-};
-
-export const OpenAPI: OpenAPIConfig = {
-    BASE: '/api/s3proxy-service',
-    VERSION: '2.0.0',
-    WITH_CREDENTIALS: false,
-    CREDENTIALS: 'include',
-    TOKEN: undefined,
-    USERNAME: undefined,
-    PASSWORD: undefined,
-    HEADERS: undefined,
-    ENCODE_PATH: undefined,
-};
diff --git a/src/client/s3proxy/core/request.ts b/src/client/s3proxy/core/request.ts
deleted file mode 100644
index 1dc6fef4aab4086ff57b48d26b20ec26bb8fa472..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/core/request.ts
+++ /dev/null
@@ -1,323 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import axios from 'axios';
-import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
-import FormData from 'form-data';
-
-import { ApiError } from './ApiError';
-import type { ApiRequestOptions } from './ApiRequestOptions';
-import type { ApiResult } from './ApiResult';
-import { CancelablePromise } from './CancelablePromise';
-import type { OnCancel } from './CancelablePromise';
-import type { OpenAPIConfig } from './OpenAPI';
-
-export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
-    return value !== undefined && value !== null;
-};
-
-export const isString = (value: any): value is string => {
-    return typeof value === 'string';
-};
-
-export const isStringWithValue = (value: any): value is string => {
-    return isString(value) && value !== '';
-};
-
-export const isBlob = (value: any): value is Blob => {
-    return (
-        typeof value === 'object' &&
-        typeof value.type === 'string' &&
-        typeof value.stream === 'function' &&
-        typeof value.arrayBuffer === 'function' &&
-        typeof value.constructor === 'function' &&
-        typeof value.constructor.name === 'string' &&
-        /^(Blob|File)$/.test(value.constructor.name) &&
-        /^(Blob|File)$/.test(value[Symbol.toStringTag])
-    );
-};
-
-export const isFormData = (value: any): value is FormData => {
-    return value instanceof FormData;
-};
-
-export const isSuccess = (status: number): boolean => {
-    return status >= 200 && status < 300;
-};
-
-export const base64 = (str: string): string => {
-    try {
-        return btoa(str);
-    } catch (err) {
-        // @ts-ignore
-        return Buffer.from(str).toString('base64');
-    }
-};
-
-export const getQueryString = (params: Record<string, any>): string => {
-    const qs: string[] = [];
-
-    const append = (key: string, value: any) => {
-        qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
-    };
-
-    const process = (key: string, value: any) => {
-        if (isDefined(value)) {
-            if (Array.isArray(value)) {
-                value.forEach(v => {
-                    process(key, v);
-                });
-            } else if (typeof value === 'object') {
-                Object.entries(value).forEach(([k, v]) => {
-                    process(`${key}[${k}]`, v);
-                });
-            } else {
-                append(key, value);
-            }
-        }
-    };
-
-    Object.entries(params).forEach(([key, value]) => {
-        process(key, value);
-    });
-
-    if (qs.length > 0) {
-        return `?${qs.join('&')}`;
-    }
-
-    return '';
-};
-
-const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
-    const encoder = config.ENCODE_PATH || encodeURI;
-
-    const path = options.url
-        .replace('{api-version}', config.VERSION)
-        .replace(/{(.*?)}/g, (substring: string, group: string) => {
-            if (options.path?.hasOwnProperty(group)) {
-                return encoder(String(options.path[group]));
-            }
-            return substring;
-        });
-
-    const url = `${config.BASE}${path}`;
-    if (options.query) {
-        return `${url}${getQueryString(options.query)}`;
-    }
-    return url;
-};
-
-export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
-    if (options.formData) {
-        const formData = new FormData();
-
-        const process = (key: string, value: any) => {
-            if (isString(value) || isBlob(value)) {
-                formData.append(key, value);
-            } else {
-                formData.append(key, JSON.stringify(value));
-            }
-        };
-
-        Object.entries(options.formData)
-            .filter(([_, value]) => isDefined(value))
-            .forEach(([key, value]) => {
-                if (Array.isArray(value)) {
-                    value.forEach(v => process(key, v));
-                } else {
-                    process(key, value);
-                }
-            });
-
-        return formData;
-    }
-    return undefined;
-};
-
-type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
-
-export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
-    if (typeof resolver === 'function') {
-        return (resolver as Resolver<T>)(options);
-    }
-    return resolver;
-};
-
-export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
-    const [token, username, password, additionalHeaders] = await Promise.all([
-        resolve(options, config.TOKEN),
-        resolve(options, config.USERNAME),
-        resolve(options, config.PASSWORD),
-        resolve(options, config.HEADERS),
-    ]);
-
-    const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
-
-    const headers = Object.entries({
-        Accept: 'application/json',
-        ...additionalHeaders,
-        ...options.headers,
-        ...formHeaders,
-    })
-    .filter(([_, value]) => isDefined(value))
-    .reduce((headers, [key, value]) => ({
-        ...headers,
-        [key]: String(value),
-    }), {} as Record<string, string>);
-
-    if (isStringWithValue(token)) {
-        headers['Authorization'] = `Bearer ${token}`;
-    }
-
-    if (isStringWithValue(username) && isStringWithValue(password)) {
-        const credentials = base64(`${username}:${password}`);
-        headers['Authorization'] = `Basic ${credentials}`;
-    }
-
-    if (options.body !== undefined) {
-        if (options.mediaType) {
-            headers['Content-Type'] = options.mediaType;
-        } else if (isBlob(options.body)) {
-            headers['Content-Type'] = options.body.type || 'application/octet-stream';
-        } else if (isString(options.body)) {
-            headers['Content-Type'] = 'text/plain';
-        } else if (!isFormData(options.body)) {
-            headers['Content-Type'] = 'application/json';
-        }
-    }
-
-    return headers;
-};
-
-export const getRequestBody = (options: ApiRequestOptions): any => {
-    if (options.body) {
-        return options.body;
-    }
-    return undefined;
-};
-
-export const sendRequest = async <T>(
-    config: OpenAPIConfig,
-    options: ApiRequestOptions,
-    url: string,
-    body: any,
-    formData: FormData | undefined,
-    headers: Record<string, string>,
-    onCancel: OnCancel,
-    axiosClient: AxiosInstance
-): Promise<AxiosResponse<T>> => {
-    const source = axios.CancelToken.source();
-
-    const requestConfig: AxiosRequestConfig = {
-        url,
-        headers,
-        data: body ?? formData,
-        method: options.method,
-        withCredentials: config.WITH_CREDENTIALS,
-        withXSRFToken: config.CREDENTIALS === 'include' ? config.WITH_CREDENTIALS : false,
-        cancelToken: source.token,
-    };
-
-    onCancel(() => source.cancel('The user aborted a request.'));
-
-    try {
-        return await axiosClient.request(requestConfig);
-    } catch (error) {
-        const axiosError = error as AxiosError<T>;
-        if (axiosError.response) {
-            return axiosError.response;
-        }
-        throw error;
-    }
-};
-
-export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
-    if (responseHeader) {
-        const content = response.headers[responseHeader];
-        if (isString(content)) {
-            return content;
-        }
-    }
-    return undefined;
-};
-
-export const getResponseBody = (response: AxiosResponse<any>): any => {
-    if (response.status !== 204) {
-        return response.data;
-    }
-    return undefined;
-};
-
-export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
-    const errors: Record<number, string> = {
-        400: 'Bad Request',
-        401: 'Unauthorized',
-        403: 'Forbidden',
-        404: 'Not Found',
-        500: 'Internal Server Error',
-        502: 'Bad Gateway',
-        503: 'Service Unavailable',
-        ...options.errors,
-    }
-
-    const error = errors[result.status];
-    if (error) {
-        throw new ApiError(options, result, error);
-    }
-
-    if (!result.ok) {
-        const errorStatus = result.status ?? 'unknown';
-        const errorStatusText = result.statusText ?? 'unknown';
-        const errorBody = (() => {
-            try {
-                return JSON.stringify(result.body, null, 2);
-            } catch (e) {
-                return undefined;
-            }
-        })();
-
-        throw new ApiError(options, result,
-            `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
-        );
-    }
-};
-
-/**
- * Request method
- * @param config The OpenAPI configuration object
- * @param options The request options from the service
- * @param axiosClient The axios client instance to use
- * @returns CancelablePromise<T>
- * @throws ApiError
- */
-export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
-    return new CancelablePromise(async (resolve, reject, onCancel) => {
-        try {
-            const url = getUrl(config, options);
-            const formData = getFormData(options);
-            const body = getRequestBody(options);
-            const headers = await getHeaders(config, options, formData);
-
-            if (!onCancel.isCancelled) {
-                const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
-                const responseBody = getResponseBody(response);
-                const responseHeader = getResponseHeader(response, options.responseHeader);
-
-                const result: ApiResult = {
-                    url,
-                    ok: isSuccess(response.status),
-                    status: response.status,
-                    statusText: response.statusText,
-                    body: responseHeader ?? responseBody,
-                };
-
-                catchErrorCodes(options, result);
-
-                resolve(result.body);
-            }
-        } catch (error) {
-            reject(error);
-        }
-    });
-};
diff --git a/src/client/s3proxy/index.ts b/src/client/s3proxy/index.ts
deleted file mode 100644
index 37a68b12fa1d1b590ba411ecb44acaa2199c6396..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/index.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export { ApiError } from './core/ApiError';
-export { CancelablePromise, CancelError } from './core/CancelablePromise';
-export { OpenAPI } from './core/OpenAPI';
-export type { OpenAPIConfig } from './core/OpenAPI';
-
-export type { Body_Bucket_update_bucket_public_state } from './models/Body_Bucket_update_bucket_public_state';
-export type { BucketIn } from './models/BucketIn';
-export type { BucketOut } from './models/BucketOut';
-export type { BucketPermissionIn } from './models/BucketPermissionIn';
-export type { BucketPermissionOut } from './models/BucketPermissionOut';
-export type { BucketPermissionParameters } from './models/BucketPermissionParameters';
-export type { BucketSizeLimits } from './models/BucketSizeLimits';
-export { BucketType } from './models/BucketType';
-export type { ErrorDetail } from './models/ErrorDetail';
-export type { HTTPValidationError } from './models/HTTPValidationError';
-export { Permission } from './models/Permission';
-export { PermissionStatus } from './models/PermissionStatus';
-export type { S3Key } from './models/S3Key';
-export type { ValidationError } from './models/ValidationError';
-
-export { BucketService } from './services/BucketService';
-export { BucketPermissionService } from './services/BucketPermissionService';
-export { S3KeyService } from './services/S3KeyService';
diff --git a/src/client/s3proxy/models/HTTPValidationError.ts b/src/client/s3proxy/models/HTTPValidationError.ts
deleted file mode 100644
index f9b1a79e2c6debaa712bb1660d4353552f6fbfad..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/models/HTTPValidationError.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ValidationError } from './ValidationError';
-export type HTTPValidationError = {
-    detail?: Array<ValidationError>;
-};
-
diff --git a/src/client/s3proxy/models/ValidationError.ts b/src/client/s3proxy/models/ValidationError.ts
deleted file mode 100644
index aaf1c921e8b674c3da9543cc2cb597e8e90d6d8f..0000000000000000000000000000000000000000
--- a/src/client/s3proxy/models/ValidationError.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ValidationError = {
-    loc: Array<(string | number)>;
-    msg: string;
-    type: string;
-};
-
diff --git a/src/client/auth/services/AuthService.ts b/src/client/services/AuthService.ts
similarity index 87%
rename from src/client/auth/services/AuthService.ts
rename to src/client/services/AuthService.ts
index 5cddd82bd5288be20e5ea44be156dbff0bab998d..570db5f34ef0f7595ec72f1e9c8680dadb79a442 100644
--- a/src/client/auth/services/AuthService.ts
+++ b/src/client/services/AuthService.ts
@@ -63,4 +63,18 @@ export class AuthService {
             },
         });
     }
+    /**
+     * Logout
+     * @returns void
+     * @throws ApiError
+     */
+    public static authLogout(): CancelablePromise<void> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/auth/logout',
+            errors: {
+                302: `Successful Response`,
+            },
+        });
+    }
 }
diff --git a/src/client/s3proxy/services/BucketPermissionService.ts b/src/client/services/BucketPermissionService.ts
similarity index 89%
rename from src/client/s3proxy/services/BucketPermissionService.ts
rename to src/client/services/BucketPermissionService.ts
index c8b5b77acb0ec882a00eebacfde15a361e3493a0..a0c61c11a12002cad893c17ccbf297cc0d911efb 100644
--- a/src/client/s3proxy/services/BucketPermissionService.ts
+++ b/src/client/services/BucketPermissionService.ts
@@ -34,8 +34,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -60,8 +60,8 @@ export class BucketPermissionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -71,7 +71,7 @@ export class BucketPermissionService {
      * Get all permissions for a user.
      * List all the bucket permissions for the given user.
      *
-     * Permission `bucket_permission:list_user` required if current user is the target the bucket permission,
+     * Permission `bucket_permission:list` required if current user is the target the bucket permission,
      * otherwise `bucket_permission:list_all` required.
      * @param uid UID of a user
      * @param permissionTypes Type of Bucket Permissions to fetch
@@ -96,8 +96,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -107,7 +107,7 @@ export class BucketPermissionService {
      * Get all permissions for a bucket.
      * List all the bucket permissions for the given bucket.
      *
-     * Permission `bucket_permission:list_bucket` required if current user is owner of the bucket,
+     * Permission `bucket_permission:list` required if current user is owner of the bucket,
      * otherwise `bucket_permission:list_all` required.
      * @param bucketName Name of bucket
      * @param permissionTypes Type of Bucket Permissions to fetch
@@ -132,8 +132,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -143,8 +143,6 @@ export class BucketPermissionService {
      * Get permission for bucket and user combination.
      * Get the bucket permissions for the specific combination of bucket and user.
      *
-     * The owner of the bucket and the grantee of the permission can view it.
-     *
      * Permission `bucket_permission:read` required if current user is the target or owner of the bucket permission,
      * otherwise `bucket_permission:read_any` required.
      * @param bucketName Name of bucket
@@ -165,8 +163,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -176,8 +174,6 @@ export class BucketPermissionService {
      * Delete a bucket permission
      * Delete the bucket permissions for the specific combination of bucket and user.
      *
-     * The owner of the bucket and the grantee of the permission can delete it.
-     *
      * Permission `bucket_permission:delete` required if current user is the target or owner of the bucket permission,
      * otherwise `bucket_permission:delete_any` required.
      * @param bucketName Name of bucket
@@ -198,8 +194,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -232,8 +228,8 @@ export class BucketPermissionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/s3proxy/services/BucketService.ts b/src/client/services/BucketService.ts
similarity index 90%
rename from src/client/s3proxy/services/BucketService.ts
rename to src/client/services/BucketService.ts
index b30e775be92d1ecbecc7d0dde1cc8b296b4ee82a..9bfc92ea572dcd34eca5316eae07b3532b6f6e11 100644
--- a/src/client/s3proxy/services/BucketService.ts
+++ b/src/client/services/BucketService.ts
@@ -13,10 +13,9 @@ import { request as __request } from '../core/request';
 export class BucketService {
     /**
      * List buckets of user
-     * List all the buckets in the system or of the desired user where the user has READ permissions for.
+     * List all the buckets in the system or of the desired user where the user has permissions for.
      *
-     * Permission `bucket:list` required if the current user is the owner of the bucket,
-     * otherwise `bucket:list_all` required.
+     * Permission `bucket:list_all` required. See parameter `owner_id` for exception.
      * @param ownerId UID of the user for whom to fetch the buckets for. Permission 'bucket:read_any' required if current user is not the target.
      * @param bucketType Type of the bucket to get. Ignored when `user` parameter not set
      * @returns BucketOut Successful Response
@@ -35,8 +34,8 @@ export class BucketService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -65,8 +64,8 @@ export class BucketService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -93,8 +92,8 @@ export class BucketService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -126,8 +125,8 @@ export class BucketService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -158,8 +157,8 @@ export class BucketService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -189,8 +188,8 @@ export class BucketService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/resource/services/ResourceService.ts b/src/client/services/ResourceService.ts
similarity index 83%
rename from src/client/resource/services/ResourceService.ts
rename to src/client/services/ResourceService.ts
index cc6bbea61cf3f6367fbb3e19be00dee1488ab14e..3dd0b4c92238f9e7a70ef54a6e13b316f69c678e 100644
--- a/src/client/resource/services/ResourceService.ts
+++ b/src/client/services/ResourceService.ts
@@ -4,7 +4,7 @@
 /* eslint-disable */
 import type { ResourceIn } from '../models/ResourceIn';
 import type { ResourceOut } from '../models/ResourceOut';
-import type { Status } from '../models/Status';
+import type { ResourceVersionStatus } from '../models/ResourceVersionStatus';
 import type { UserSynchronizationRequestOut } from '../models/UserSynchronizationRequestOut';
 import type { CancelablePromise } from '../core/CancelablePromise';
 import { OpenAPI } from '../core/OpenAPI';
@@ -24,7 +24,7 @@ export class ResourceService {
      */
     public static resourceListResources(
         maintainerId?: string,
-        versionStatus?: Array<Status>,
+        versionStatus?: Array<ResourceVersionStatus>,
         nameSubstring?: string,
         _public?: boolean,
     ): CancelablePromise<Array<ResourceOut>> {
@@ -38,9 +38,9 @@ export class ResourceService {
                 'public': _public,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -64,9 +64,9 @@ export class ResourceService {
             body: requestBody,
             mediaType: 'application/json',
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -76,7 +76,7 @@ export class ResourceService {
      * List resource sync requests
      * List all resource sync requests.
      *
-     * Permission `resource:sync` required.
+     * Permission `resource:update_any` required.
      * @returns UserSynchronizationRequestOut Successful Response
      * @throws ApiError
      */
@@ -85,9 +85,9 @@ export class ResourceService {
             method: 'GET',
             url: '/resources/sync_requests',
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
             },
         });
@@ -104,7 +104,7 @@ export class ResourceService {
      */
     public static resourceGetResource(
         rid: string,
-        versionStatus?: Array<Status>,
+        versionStatus?: Array<ResourceVersionStatus>,
     ): CancelablePromise<ResourceOut> {
         return __request(OpenAPI, {
             method: 'GET',
@@ -116,9 +116,9 @@ export class ResourceService {
                 'version_status': versionStatus,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -143,9 +143,9 @@ export class ResourceService {
                 'rid': rid,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/resource/services/ResourceVersionService.ts b/src/client/services/ResourceVersionService.ts
similarity index 84%
rename from src/client/resource/services/ResourceVersionService.ts
rename to src/client/services/ResourceVersionService.ts
index 07c338369313a43ac36d1940cef78ea88acb77df..82096e84490e9b687f1261dbf902a605303b46d8 100644
--- a/src/client/resource/services/ResourceVersionService.ts
+++ b/src/client/services/ResourceVersionService.ts
@@ -5,7 +5,7 @@
 import type { FileTree } from '../models/FileTree';
 import type { ResourceVersionIn } from '../models/ResourceVersionIn';
 import type { ResourceVersionOut } from '../models/ResourceVersionOut';
-import type { Status } from '../models/Status';
+import type { ResourceVersionStatus } from '../models/ResourceVersionStatus';
 import type { UserRequestAnswer } from '../models/UserRequestAnswer';
 import type { UserSynchronizationRequestIn } from '../models/UserSynchronizationRequestIn';
 import type { CancelablePromise } from '../core/CancelablePromise';
@@ -24,7 +24,7 @@ export class ResourceVersionService {
      */
     public static resourceVersionListResourceVersions(
         rid: string,
-        versionStatus?: Array<Status>,
+        versionStatus?: Array<ResourceVersionStatus>,
     ): CancelablePromise<Array<ResourceVersionOut>> {
         return __request(OpenAPI, {
             method: 'GET',
@@ -36,9 +36,9 @@ export class ResourceVersionService {
                 'version_status': versionStatus,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -67,9 +67,9 @@ export class ResourceVersionService {
             body: requestBody,
             mediaType: 'application/json',
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -98,9 +98,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -128,9 +128,9 @@ export class ResourceVersionService {
                 'rid': rid,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -140,7 +140,7 @@ export class ResourceVersionService {
      * Request resource version review
      * Request the review of a resource version.
      *
-     * Permission `resource:request_review` required.
+     * Permission `resource:update` required.
      * @param rid
      * @param rvid
      * @returns ResourceVersionOut Successful Response
@@ -158,9 +158,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -192,9 +192,9 @@ export class ResourceVersionService {
             body: requestBody,
             mediaType: 'application/json',
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -204,7 +204,7 @@ export class ResourceVersionService {
      * Review resource version
      * Review answer the resource version.
      *
-     * Permission `resource:review` required.
+     * Permission `resource:update_status` required.
      * @param rid
      * @param rvid
      * @param requestBody
@@ -226,9 +226,9 @@ export class ResourceVersionService {
             body: requestBody,
             mediaType: 'application/json',
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -238,7 +238,7 @@ export class ResourceVersionService {
      * Synchronize resource version with cluster
      * Synchronize the resource version to the cluster.
      *
-     * Permission `resource:sync` required.
+     * Permission `resource:update_any` required.
      * @param rid
      * @param rvid
      * @param requestBody
@@ -260,9 +260,9 @@ export class ResourceVersionService {
             body: requestBody,
             mediaType: 'application/json',
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -272,7 +272,7 @@ export class ResourceVersionService {
      * Set resource version to latest
      * Set the resource version as the latest version.
      *
-     * Permission `resource:set_latest` required.
+     * Permission `resource:update_any` required.
      * @param rid
      * @param rvid
      * @returns ResourceVersionOut Successful Response
@@ -290,9 +290,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -302,7 +302,7 @@ export class ResourceVersionService {
      * Delete resource version on cluster
      * Delete the resource version on the cluster.
      *
-     * Permission `resource:delete_cluster` required.
+     * Permission `resource:delete_any` required.
      * @param rid
      * @param rvid
      * @returns ResourceVersionOut Successful Response
@@ -320,9 +320,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -332,7 +332,7 @@ export class ResourceVersionService {
      * Delete resource version in S3
      * Delete the resource version in the S3 bucket.
      *
-     * Permission `resource:delete_s3` required.
+     * Permission `resource:delete_any` required.
      * @param rid
      * @param rvid
      * @returns ResourceVersionOut Successful Response
@@ -350,9 +350,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error in request parameters`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/s3proxy/services/S3KeyService.ts b/src/client/services/S3KeyService.ts
similarity index 91%
rename from src/client/s3proxy/services/S3KeyService.ts
rename to src/client/services/S3KeyService.ts
index 58f2f589547a448652785a8765be5067d5fa3d48..11e696118ce7822e2c5bbe0c04a0ffd199f28d30 100644
--- a/src/client/s3proxy/services/S3KeyService.ts
+++ b/src/client/services/S3KeyService.ts
@@ -27,8 +27,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -54,8 +54,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -84,8 +84,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -114,8 +114,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/services/UserService.ts b/src/client/services/UserService.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e8a4680902ac0345e732ffcfc146bfae11a10f06
--- /dev/null
+++ b/src/client/services/UserService.ts
@@ -0,0 +1,175 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { RoleEnum } from '../models/RoleEnum';
+import type { UserIn } from '../models/UserIn';
+import type { UserOut } from '../models/UserOut';
+import type { UserOutExtended } from '../models/UserOutExtended';
+import type { UserRoles } from '../models/UserRoles';
+import type { CancelablePromise } from '../core/CancelablePromise';
+import { OpenAPI } from '../core/OpenAPI';
+import { request as __request } from '../core/request';
+export class UserService {
+    /**
+     * Create User
+     * Create a new user in the system and notify him. The smtp MUST be the same as the one saved by the OIDC provider.
+     *
+     * Permission `user:create` required.
+     * @param requestBody
+     * @returns UserOutExtended Successful Response
+     * @throws ApiError
+     */
+    public static userCreateUser(
+        requestBody: UserIn,
+    ): CancelablePromise<UserOutExtended> {
+        return __request(OpenAPI, {
+            method: 'POST',
+            url: '/users',
+            body: requestBody,
+            mediaType: 'application/json',
+            errors: {
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+    /**
+     * List users and search by their name
+     * List all users in the system..
+     *
+     * Permission `user:list` required.
+     * @param nameSubstring Filter users by a substring in their name.
+     * @param filterRoles Filter users by their role. If multiple are selected, they are concatenating by an OR Expression.
+     * @returns UserOutExtended Successful Response
+     * @throws ApiError
+     */
+    public static userListUsers(
+        nameSubstring?: string,
+        filterRoles?: Array<RoleEnum>,
+    ): CancelablePromise<Array<UserOutExtended>> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/users',
+            query: {
+                'name_substring': nameSubstring,
+                'filter_roles': filterRoles,
+            },
+            errors: {
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+    /**
+     * Search Users
+     * Search for users in the system by their name.
+     *
+     * Permission `user: search` required.
+     * @param nameSubstring Filter users by a substring in their name.
+     * @returns UserOut Successful Response
+     * @throws ApiError
+     */
+    public static userSearchUsers(
+        nameSubstring: string,
+    ): CancelablePromise<Array<UserOut>> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/users/search',
+            query: {
+                'name_substring': nameSubstring,
+            },
+            errors: {
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+    /**
+     * Get the logged in user
+     * Return the user associated with the used JWT.
+     *
+     * Permission `user:read` required.
+     * @returns UserOutExtended Successful Response
+     * @throws ApiError
+     */
+    public static userGetLoggedInUser(): CancelablePromise<UserOutExtended> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/users/me',
+            errors: {
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
+                404: `Entity not Found`,
+            },
+        });
+    }
+    /**
+     * Get a user by its uid
+     * Return the user with the specific uid.
+     *
+     * Permission `user:read` required.
+     * @param uid UID of a user
+     * @returns UserOut Successful Response
+     * @throws ApiError
+     */
+    public static userGetUser(
+        uid: string,
+    ): CancelablePromise<UserOut> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/users/{uid}',
+            path: {
+                'uid': uid,
+            },
+            errors: {
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+    /**
+     * Update Roles
+     * Update the roles of a user.
+     *
+     * Permission `user:update` required.
+     * @param uid UID of a user
+     * @param requestBody
+     * @returns UserOutExtended Successful Response
+     * @throws ApiError
+     */
+    public static userUpdateRoles(
+        uid: string,
+        requestBody: UserRoles,
+    ): CancelablePromise<UserOutExtended> {
+        return __request(OpenAPI, {
+            method: 'PUT',
+            url: '/users/{uid}/roles',
+            path: {
+                'uid': uid,
+            },
+            body: requestBody,
+            mediaType: 'application/json',
+            errors: {
+                400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+}
diff --git a/src/client/workflow/services/WorkflowCredentialsService.ts b/src/client/services/WorkflowCredentialsService.ts
similarity index 88%
rename from src/client/workflow/services/WorkflowCredentialsService.ts
rename to src/client/services/WorkflowCredentialsService.ts
index f7e79f5df8c1edee6f0a55ed2332e7e7c0a6fa83..4d3b74cb483295567066b646fbc2e683753c0e6e 100644
--- a/src/client/workflow/services/WorkflowCredentialsService.ts
+++ b/src/client/services/WorkflowCredentialsService.ts
@@ -28,8 +28,8 @@ export class WorkflowCredentialsService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -59,8 +59,8 @@ export class WorkflowCredentialsService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -70,7 +70,8 @@ export class WorkflowCredentialsService {
      * Delete the credentials of a workflow
      * Delete the credentials for the repository of a workflow.
      *
-     * Permission `workflow:delete` required.
+     * Permission `workflow:delete` required if the developer of the workflow is the same as the the current user,
+     * other `workflow:delete_any`.
      * @param wid ID of a workflow
      * @returns void
      * @throws ApiError
@@ -86,8 +87,8 @@ export class WorkflowCredentialsService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowExecutionService.ts b/src/client/services/WorkflowExecutionService.ts
similarity index 90%
rename from src/client/workflow/services/WorkflowExecutionService.ts
rename to src/client/services/WorkflowExecutionService.ts
index c6d08278a58be2ae34d58a737900a4b98b0c9852..69fd3a4e8c282cce27220ce0c4a9a936e3c04b30 100644
--- a/src/client/workflow/services/WorkflowExecutionService.ts
+++ b/src/client/services/WorkflowExecutionService.ts
@@ -14,8 +14,8 @@ export class WorkflowExecutionService {
      * Start a new workflow execution
      * Start a new workflow execution. Workflow versions wit status `DEPRECATED` or `DENIED` can't be started.
      *
-     * Permission `workflow_execution:start` required if workflow versions status is `PUBLISHED`,
-     * otherwise `workflow_execution:start_unpublished` required.
+     * Permission `workflow_execution:create` required if workflow versions status is `PUBLISHED`,
+     * otherwise `workflow_execution:create_any` required.
      * @param requestBody
      * @returns WorkflowExecutionOut Successful Response
      * @throws ApiError
@@ -30,8 +30,8 @@ export class WorkflowExecutionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -64,8 +64,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -75,11 +75,11 @@ export class WorkflowExecutionService {
      * Start a workflow execution with arbitrary git repository
      * Start a new workflow execution from an arbitrary git repository.
      *
-     * Permission `workflow:create` required.
-     *
      * For private Gitlab repositories, a Project Access Token with the role Reporter and scope `read_api` is needed.
      *
      * For private GitHub repositories, a Personal Access Token (classic) with scope `repo` is needed.
+     *
+     * Permission `workflow:create` required.
      * @param requestBody
      * @returns WorkflowExecutionOut Successful Response
      * @throws ApiError
@@ -94,8 +94,8 @@ export class WorkflowExecutionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -122,8 +122,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -150,8 +150,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -178,8 +178,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -206,8 +206,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowModeService.ts b/src/client/services/WorkflowModeService.ts
similarity index 93%
rename from src/client/workflow/services/WorkflowModeService.ts
rename to src/client/services/WorkflowModeService.ts
index 3d68f8bc35c2ff99a123cfd1af32bf89d3d0a030..f96352df298d6fcc826dbb056d0d7d338bff098b 100644
--- a/src/client/workflow/services/WorkflowModeService.ts
+++ b/src/client/services/WorkflowModeService.ts
@@ -27,8 +27,8 @@ export class WorkflowModeService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowService.ts b/src/client/services/WorkflowService.ts
similarity index 87%
rename from src/client/workflow/services/WorkflowService.ts
rename to src/client/services/WorkflowService.ts
index 06a8be33ed8bcaa20777eff36f63a3cb1b6c3482..bed23014933fba346ecd4e2581d1fd570343adf2 100644
--- a/src/client/workflow/services/WorkflowService.ts
+++ b/src/client/services/WorkflowService.ts
@@ -3,12 +3,12 @@
 /* tslint:disable */
 /* eslint-disable */
 import type { AnonymizedWorkflowExecution } from '../models/AnonymizedWorkflowExecution';
-import type { Status } from '../models/Status';
 import type { WorkflowIn } from '../models/WorkflowIn';
 import type { WorkflowOut } from '../models/WorkflowOut';
 import type { WorkflowStatistic } from '../models/WorkflowStatistic';
 import type { WorkflowUpdate } from '../models/WorkflowUpdate';
 import type { WorkflowVersion } from '../models/WorkflowVersion';
+import type { WorkflowVersionStatus } from '../models/WorkflowVersionStatus';
 import type { CancelablePromise } from '../core/CancelablePromise';
 import { OpenAPI } from '../core/OpenAPI';
 import { request as __request } from '../core/request';
@@ -26,7 +26,7 @@ export class WorkflowService {
      */
     public static workflowListWorkflows(
         nameSubstring?: string,
-        versionStatus?: Array<Status>,
+        versionStatus?: Array<WorkflowVersionStatus>,
         developerId?: string,
     ): CancelablePromise<Array<WorkflowOut>> {
         return __request(OpenAPI, {
@@ -39,8 +39,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -50,11 +50,11 @@ export class WorkflowService {
      * Create a new workflow
      * Create a new workflow.
      *
-     * Permission `workflow:create` required.
-     *
      * For private Gitlab repositories, a Project Access Token with the role Reporter and scope `read_api` is needed.
      *
      * For private GitHub repositories, a Personal Access Token (classic) with scope `repo` is needed.
+     *
+     * Permission `workflow:create` required.
      * @param requestBody
      * @returns WorkflowOut Successful Response
      * @throws ApiError
@@ -69,8 +69,8 @@ export class WorkflowService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -80,8 +80,8 @@ export class WorkflowService {
      * Get anonymized workflow execution
      * Get the workflow executions with meta information and anonymized user IDs.
      *
-     * Permission `workflow:read_statistics` required if the `developer_id` is the same as the uid of the current user,
-     * other `workflow:read_statistics_any`.
+     * Permission `workflow:read` required if the `developer_id` is the same as the uid of the current user,
+     * other `workflow:read_any`.
      * @param developerId Filter by the developer of the workflows
      * @param workflowId Filter by workflow IDs
      * @param start Filter by workflow executions after this date
@@ -106,8 +106,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -125,7 +125,7 @@ export class WorkflowService {
      */
     public static workflowGetWorkflow(
         wid: string,
-        versionStatus?: Array<Status>,
+        versionStatus?: Array<WorkflowVersionStatus>,
     ): CancelablePromise<WorkflowOut> {
         return __request(OpenAPI, {
             method: 'GET',
@@ -138,8 +138,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -149,7 +149,8 @@ export class WorkflowService {
      * Delete a workflow
      * Delete a workflow.
      *
-     * Permission `workflow:delete` required.
+     * Permission `workflow:delete` required if the `developer_id` is the same as the uid of the current user,
+     * other `workflow:delete_any`.
      * @param wid ID of a workflow
      * @returns void
      * @throws ApiError
@@ -165,8 +166,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -192,8 +193,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -223,8 +224,8 @@ export class WorkflowService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowVersionService.ts b/src/client/services/WorkflowVersionService.ts
similarity index 91%
rename from src/client/workflow/services/WorkflowVersionService.ts
rename to src/client/services/WorkflowVersionService.ts
index 32b9bb5a55d87b86456e98c653cccd85bca1c5ee..f5d3ef06ab4779c3a5b4488cf4c9149156e22161 100644
--- a/src/client/workflow/services/WorkflowVersionService.ts
+++ b/src/client/services/WorkflowVersionService.ts
@@ -6,9 +6,9 @@ import type { Body_Workflow_Version_upload_workflow_version_icon } from '../mode
 import type { DocumentationEnum } from '../models/DocumentationEnum';
 import type { IconUpdateOut } from '../models/IconUpdateOut';
 import type { ParameterExtension } from '../models/ParameterExtension';
-import type { Status } from '../models/Status';
 import type { WorkflowVersion } from '../models/WorkflowVersion';
 import type { WorkflowVersionStatus } from '../models/WorkflowVersionStatus';
+import type { WorkflowVersionStatusSchema } from '../models/WorkflowVersionStatusSchema';
 import type { CancelablePromise } from '../core/CancelablePromise';
 import { OpenAPI } from '../core/OpenAPI';
 import { request as __request } from '../core/request';
@@ -25,7 +25,7 @@ export class WorkflowVersionService {
      */
     public static workflowVersionListWorkflowVersion(
         wid: string,
-        versionStatus?: Array<Status>,
+        versionStatus?: Array<WorkflowVersionStatus>,
     ): CancelablePromise<Array<WorkflowVersion>> {
         return __request(OpenAPI, {
             method: 'GET',
@@ -38,8 +38,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -69,8 +69,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -90,7 +90,7 @@ export class WorkflowVersionService {
     public static workflowVersionUpdateWorkflowVersionStatus(
         wid: string,
         gitCommitHash: string,
-        requestBody: WorkflowVersionStatus,
+        requestBody: WorkflowVersionStatusSchema,
     ): CancelablePromise<WorkflowVersion> {
         return __request(OpenAPI, {
             method: 'PATCH',
@@ -103,8 +103,8 @@ export class WorkflowVersionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -115,7 +115,7 @@ export class WorkflowVersionService {
      * Deprecate a workflow version.
      *
      * Permission `workflow:update` required if you are the developer of the workflow,
-     * otherwise `workflow:read_status`
+     * otherwise `workflow:update_status`
      * @param wid ID of a workflow
      * @param gitCommitHash Git commit git_commit_hash of specific version.
      * @returns WorkflowVersion Successful Response
@@ -134,8 +134,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -145,7 +145,6 @@ export class WorkflowVersionService {
      * Update parameter extension of workflow version
      * Update the parameter extension of a workflow version.
      *
-     *
      * Permission `workflow:update` required.
      * @param wid ID of a workflow
      * @param gitCommitHash Git commit git_commit_hash of specific version.
@@ -169,8 +168,8 @@ export class WorkflowVersionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -180,7 +179,6 @@ export class WorkflowVersionService {
      * Delete parameter extension of workflow version
      * Delete the parameter extension of a workflow version.
      *
-     *
      * Permission `workflow:update` required.
      * @param wid ID of a workflow
      * @param gitCommitHash Git commit git_commit_hash of specific version.
@@ -200,8 +198,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -239,8 +237,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -273,8 +271,8 @@ export class WorkflowVersionService {
             mediaType: 'multipart/form-data',
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -303,8 +301,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                401: `Not authenticated`,
-                403: `Not authorized`,
+                401: `Not Authenticated`,
+                403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/core/ApiError.ts b/src/client/workflow/core/ApiError.ts
deleted file mode 100644
index ec7b16af6f41b1323a8e3aa3d529bf2324959e66..0000000000000000000000000000000000000000
--- a/src/client/workflow/core/ApiError.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ApiRequestOptions } from './ApiRequestOptions';
-import type { ApiResult } from './ApiResult';
-
-export class ApiError extends Error {
-    public readonly url: string;
-    public readonly status: number;
-    public readonly statusText: string;
-    public readonly body: any;
-    public readonly request: ApiRequestOptions;
-
-    constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
-        super(message);
-
-        this.name = 'ApiError';
-        this.url = response.url;
-        this.status = response.status;
-        this.statusText = response.statusText;
-        this.body = response.body;
-        this.request = request;
-    }
-}
diff --git a/src/client/workflow/core/ApiRequestOptions.ts b/src/client/workflow/core/ApiRequestOptions.ts
deleted file mode 100644
index 93143c3ce1ba5323894d4ac10299f62493f030f6..0000000000000000000000000000000000000000
--- a/src/client/workflow/core/ApiRequestOptions.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ApiRequestOptions = {
-    readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
-    readonly url: string;
-    readonly path?: Record<string, any>;
-    readonly cookies?: Record<string, any>;
-    readonly headers?: Record<string, any>;
-    readonly query?: Record<string, any>;
-    readonly formData?: Record<string, any>;
-    readonly body?: any;
-    readonly mediaType?: string;
-    readonly responseHeader?: string;
-    readonly errors?: Record<number, string>;
-};
diff --git a/src/client/workflow/core/ApiResult.ts b/src/client/workflow/core/ApiResult.ts
deleted file mode 100644
index ee1126e2ccd1e37dba97511c38c56a282ceac4dc..0000000000000000000000000000000000000000
--- a/src/client/workflow/core/ApiResult.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ApiResult = {
-    readonly url: string;
-    readonly ok: boolean;
-    readonly status: number;
-    readonly statusText: string;
-    readonly body: any;
-};
diff --git a/src/client/workflow/core/CancelablePromise.ts b/src/client/workflow/core/CancelablePromise.ts
deleted file mode 100644
index d70de92946d977e9da7970871375117a8b04770a..0000000000000000000000000000000000000000
--- a/src/client/workflow/core/CancelablePromise.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export class CancelError extends Error {
-
-    constructor(message: string) {
-        super(message);
-        this.name = 'CancelError';
-    }
-
-    public get isCancelled(): boolean {
-        return true;
-    }
-}
-
-export interface OnCancel {
-    readonly isResolved: boolean;
-    readonly isRejected: boolean;
-    readonly isCancelled: boolean;
-
-    (cancelHandler: () => void): void;
-}
-
-export class CancelablePromise<T> implements Promise<T> {
-    #isResolved: boolean;
-    #isRejected: boolean;
-    #isCancelled: boolean;
-    readonly #cancelHandlers: (() => void)[];
-    readonly #promise: Promise<T>;
-    #resolve?: (value: T | PromiseLike<T>) => void;
-    #reject?: (reason?: any) => void;
-
-    constructor(
-        executor: (
-            resolve: (value: T | PromiseLike<T>) => void,
-            reject: (reason?: any) => void,
-            onCancel: OnCancel
-        ) => void
-    ) {
-        this.#isResolved = false;
-        this.#isRejected = false;
-        this.#isCancelled = false;
-        this.#cancelHandlers = [];
-        this.#promise = new Promise<T>((resolve, reject) => {
-            this.#resolve = resolve;
-            this.#reject = reject;
-
-            const onResolve = (value: T | PromiseLike<T>): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#isResolved = true;
-                if (this.#resolve) this.#resolve(value);
-            };
-
-            const onReject = (reason?: any): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#isRejected = true;
-                if (this.#reject) this.#reject(reason);
-            };
-
-            const onCancel = (cancelHandler: () => void): void => {
-                if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-                    return;
-                }
-                this.#cancelHandlers.push(cancelHandler);
-            };
-
-            Object.defineProperty(onCancel, 'isResolved', {
-                get: (): boolean => this.#isResolved,
-            });
-
-            Object.defineProperty(onCancel, 'isRejected', {
-                get: (): boolean => this.#isRejected,
-            });
-
-            Object.defineProperty(onCancel, 'isCancelled', {
-                get: (): boolean => this.#isCancelled,
-            });
-
-            return executor(onResolve, onReject, onCancel as OnCancel);
-        });
-    }
-
-    get [Symbol.toStringTag]() {
-        return "Cancellable Promise";
-    }
-
-    public then<TResult1 = T, TResult2 = never>(
-        onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
-        onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
-    ): Promise<TResult1 | TResult2> {
-        return this.#promise.then(onFulfilled, onRejected);
-    }
-
-    public catch<TResult = never>(
-        onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
-    ): Promise<T | TResult> {
-        return this.#promise.catch(onRejected);
-    }
-
-    public finally(onFinally?: (() => void) | null): Promise<T> {
-        return this.#promise.finally(onFinally);
-    }
-
-    public cancel(): void {
-        if (this.#isResolved || this.#isRejected || this.#isCancelled) {
-            return;
-        }
-        this.#isCancelled = true;
-        if (this.#cancelHandlers.length) {
-            try {
-                for (const cancelHandler of this.#cancelHandlers) {
-                    cancelHandler();
-                }
-            } catch (error) {
-                console.warn('Cancellation threw an error', error);
-                return;
-            }
-        }
-        this.#cancelHandlers.length = 0;
-        if (this.#reject) this.#reject(new CancelError('Request aborted'));
-    }
-
-    public get isCancelled(): boolean {
-        return this.#isCancelled;
-    }
-}
diff --git a/src/client/workflow/core/OpenAPI.ts b/src/client/workflow/core/OpenAPI.ts
deleted file mode 100644
index c81a8eb67c222d70f094b26ab861ecd3265a081f..0000000000000000000000000000000000000000
--- a/src/client/workflow/core/OpenAPI.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ApiRequestOptions } from './ApiRequestOptions';
-
-type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
-type Headers = Record<string, string>;
-
-export type OpenAPIConfig = {
-    BASE: string;
-    VERSION: string;
-    WITH_CREDENTIALS: boolean;
-    CREDENTIALS: 'include' | 'omit' | 'same-origin';
-    TOKEN?: string | Resolver<string> | undefined;
-    USERNAME?: string | Resolver<string> | undefined;
-    PASSWORD?: string | Resolver<string> | undefined;
-    HEADERS?: Headers | Resolver<Headers> | undefined;
-    ENCODE_PATH?: ((path: string) => string) | undefined;
-};
-
-export const OpenAPI: OpenAPIConfig = {
-    BASE: '/api/workflow-service',
-    VERSION: '1.0.0',
-    WITH_CREDENTIALS: false,
-    CREDENTIALS: 'include',
-    TOKEN: undefined,
-    USERNAME: undefined,
-    PASSWORD: undefined,
-    HEADERS: undefined,
-    ENCODE_PATH: undefined,
-};
diff --git a/src/client/workflow/core/request.ts b/src/client/workflow/core/request.ts
deleted file mode 100644
index 1dc6fef4aab4086ff57b48d26b20ec26bb8fa472..0000000000000000000000000000000000000000
--- a/src/client/workflow/core/request.ts
+++ /dev/null
@@ -1,323 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import axios from 'axios';
-import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
-import FormData from 'form-data';
-
-import { ApiError } from './ApiError';
-import type { ApiRequestOptions } from './ApiRequestOptions';
-import type { ApiResult } from './ApiResult';
-import { CancelablePromise } from './CancelablePromise';
-import type { OnCancel } from './CancelablePromise';
-import type { OpenAPIConfig } from './OpenAPI';
-
-export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
-    return value !== undefined && value !== null;
-};
-
-export const isString = (value: any): value is string => {
-    return typeof value === 'string';
-};
-
-export const isStringWithValue = (value: any): value is string => {
-    return isString(value) && value !== '';
-};
-
-export const isBlob = (value: any): value is Blob => {
-    return (
-        typeof value === 'object' &&
-        typeof value.type === 'string' &&
-        typeof value.stream === 'function' &&
-        typeof value.arrayBuffer === 'function' &&
-        typeof value.constructor === 'function' &&
-        typeof value.constructor.name === 'string' &&
-        /^(Blob|File)$/.test(value.constructor.name) &&
-        /^(Blob|File)$/.test(value[Symbol.toStringTag])
-    );
-};
-
-export const isFormData = (value: any): value is FormData => {
-    return value instanceof FormData;
-};
-
-export const isSuccess = (status: number): boolean => {
-    return status >= 200 && status < 300;
-};
-
-export const base64 = (str: string): string => {
-    try {
-        return btoa(str);
-    } catch (err) {
-        // @ts-ignore
-        return Buffer.from(str).toString('base64');
-    }
-};
-
-export const getQueryString = (params: Record<string, any>): string => {
-    const qs: string[] = [];
-
-    const append = (key: string, value: any) => {
-        qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
-    };
-
-    const process = (key: string, value: any) => {
-        if (isDefined(value)) {
-            if (Array.isArray(value)) {
-                value.forEach(v => {
-                    process(key, v);
-                });
-            } else if (typeof value === 'object') {
-                Object.entries(value).forEach(([k, v]) => {
-                    process(`${key}[${k}]`, v);
-                });
-            } else {
-                append(key, value);
-            }
-        }
-    };
-
-    Object.entries(params).forEach(([key, value]) => {
-        process(key, value);
-    });
-
-    if (qs.length > 0) {
-        return `?${qs.join('&')}`;
-    }
-
-    return '';
-};
-
-const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
-    const encoder = config.ENCODE_PATH || encodeURI;
-
-    const path = options.url
-        .replace('{api-version}', config.VERSION)
-        .replace(/{(.*?)}/g, (substring: string, group: string) => {
-            if (options.path?.hasOwnProperty(group)) {
-                return encoder(String(options.path[group]));
-            }
-            return substring;
-        });
-
-    const url = `${config.BASE}${path}`;
-    if (options.query) {
-        return `${url}${getQueryString(options.query)}`;
-    }
-    return url;
-};
-
-export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
-    if (options.formData) {
-        const formData = new FormData();
-
-        const process = (key: string, value: any) => {
-            if (isString(value) || isBlob(value)) {
-                formData.append(key, value);
-            } else {
-                formData.append(key, JSON.stringify(value));
-            }
-        };
-
-        Object.entries(options.formData)
-            .filter(([_, value]) => isDefined(value))
-            .forEach(([key, value]) => {
-                if (Array.isArray(value)) {
-                    value.forEach(v => process(key, v));
-                } else {
-                    process(key, value);
-                }
-            });
-
-        return formData;
-    }
-    return undefined;
-};
-
-type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
-
-export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
-    if (typeof resolver === 'function') {
-        return (resolver as Resolver<T>)(options);
-    }
-    return resolver;
-};
-
-export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
-    const [token, username, password, additionalHeaders] = await Promise.all([
-        resolve(options, config.TOKEN),
-        resolve(options, config.USERNAME),
-        resolve(options, config.PASSWORD),
-        resolve(options, config.HEADERS),
-    ]);
-
-    const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
-
-    const headers = Object.entries({
-        Accept: 'application/json',
-        ...additionalHeaders,
-        ...options.headers,
-        ...formHeaders,
-    })
-    .filter(([_, value]) => isDefined(value))
-    .reduce((headers, [key, value]) => ({
-        ...headers,
-        [key]: String(value),
-    }), {} as Record<string, string>);
-
-    if (isStringWithValue(token)) {
-        headers['Authorization'] = `Bearer ${token}`;
-    }
-
-    if (isStringWithValue(username) && isStringWithValue(password)) {
-        const credentials = base64(`${username}:${password}`);
-        headers['Authorization'] = `Basic ${credentials}`;
-    }
-
-    if (options.body !== undefined) {
-        if (options.mediaType) {
-            headers['Content-Type'] = options.mediaType;
-        } else if (isBlob(options.body)) {
-            headers['Content-Type'] = options.body.type || 'application/octet-stream';
-        } else if (isString(options.body)) {
-            headers['Content-Type'] = 'text/plain';
-        } else if (!isFormData(options.body)) {
-            headers['Content-Type'] = 'application/json';
-        }
-    }
-
-    return headers;
-};
-
-export const getRequestBody = (options: ApiRequestOptions): any => {
-    if (options.body) {
-        return options.body;
-    }
-    return undefined;
-};
-
-export const sendRequest = async <T>(
-    config: OpenAPIConfig,
-    options: ApiRequestOptions,
-    url: string,
-    body: any,
-    formData: FormData | undefined,
-    headers: Record<string, string>,
-    onCancel: OnCancel,
-    axiosClient: AxiosInstance
-): Promise<AxiosResponse<T>> => {
-    const source = axios.CancelToken.source();
-
-    const requestConfig: AxiosRequestConfig = {
-        url,
-        headers,
-        data: body ?? formData,
-        method: options.method,
-        withCredentials: config.WITH_CREDENTIALS,
-        withXSRFToken: config.CREDENTIALS === 'include' ? config.WITH_CREDENTIALS : false,
-        cancelToken: source.token,
-    };
-
-    onCancel(() => source.cancel('The user aborted a request.'));
-
-    try {
-        return await axiosClient.request(requestConfig);
-    } catch (error) {
-        const axiosError = error as AxiosError<T>;
-        if (axiosError.response) {
-            return axiosError.response;
-        }
-        throw error;
-    }
-};
-
-export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
-    if (responseHeader) {
-        const content = response.headers[responseHeader];
-        if (isString(content)) {
-            return content;
-        }
-    }
-    return undefined;
-};
-
-export const getResponseBody = (response: AxiosResponse<any>): any => {
-    if (response.status !== 204) {
-        return response.data;
-    }
-    return undefined;
-};
-
-export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
-    const errors: Record<number, string> = {
-        400: 'Bad Request',
-        401: 'Unauthorized',
-        403: 'Forbidden',
-        404: 'Not Found',
-        500: 'Internal Server Error',
-        502: 'Bad Gateway',
-        503: 'Service Unavailable',
-        ...options.errors,
-    }
-
-    const error = errors[result.status];
-    if (error) {
-        throw new ApiError(options, result, error);
-    }
-
-    if (!result.ok) {
-        const errorStatus = result.status ?? 'unknown';
-        const errorStatusText = result.statusText ?? 'unknown';
-        const errorBody = (() => {
-            try {
-                return JSON.stringify(result.body, null, 2);
-            } catch (e) {
-                return undefined;
-            }
-        })();
-
-        throw new ApiError(options, result,
-            `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
-        );
-    }
-};
-
-/**
- * Request method
- * @param config The OpenAPI configuration object
- * @param options The request options from the service
- * @param axiosClient The axios client instance to use
- * @returns CancelablePromise<T>
- * @throws ApiError
- */
-export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
-    return new CancelablePromise(async (resolve, reject, onCancel) => {
-        try {
-            const url = getUrl(config, options);
-            const formData = getFormData(options);
-            const body = getRequestBody(options);
-            const headers = await getHeaders(config, options, formData);
-
-            if (!onCancel.isCancelled) {
-                const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
-                const responseBody = getResponseBody(response);
-                const responseHeader = getResponseHeader(response, options.responseHeader);
-
-                const result: ApiResult = {
-                    url,
-                    ok: isSuccess(response.status),
-                    status: response.status,
-                    statusText: response.statusText,
-                    body: responseHeader ?? responseBody,
-                };
-
-                catchErrorCodes(options, result);
-
-                resolve(result.body);
-            }
-        } catch (error) {
-            reject(error);
-        }
-    });
-};
diff --git a/src/client/workflow/index.ts b/src/client/workflow/index.ts
deleted file mode 100644
index dbfd76902980623fcd2985e539d58771cd365855..0000000000000000000000000000000000000000
--- a/src/client/workflow/index.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export { ApiError } from './core/ApiError';
-export { CancelablePromise, CancelError } from './core/CancelablePromise';
-export { OpenAPI } from './core/OpenAPI';
-export type { OpenAPIConfig } from './core/OpenAPI';
-
-export type { AnonymizedWorkflowExecution } from './models/AnonymizedWorkflowExecution';
-export type { Body_Workflow_Version_upload_workflow_version_icon } from './models/Body_Workflow_Version_upload_workflow_version_icon';
-export type { DevWorkflowExecutionIn } from './models/DevWorkflowExecutionIn';
-export { DocumentationEnum } from './models/DocumentationEnum';
-export type { ErrorDetail } from './models/ErrorDetail';
-export type { HTTPValidationError } from './models/HTTPValidationError';
-export type { IconUpdateOut } from './models/IconUpdateOut';
-export type { ParameterExtension } from './models/ParameterExtension';
-export { Status } from './models/Status';
-export type { ValidationError } from './models/ValidationError';
-export type { WorkflowCredentialsIn } from './models/WorkflowCredentialsIn';
-export type { WorkflowCredentialsOut } from './models/WorkflowCredentialsOut';
-export type { WorkflowExecutionIn } from './models/WorkflowExecutionIn';
-export type { WorkflowExecutionOut } from './models/WorkflowExecutionOut';
-export { WorkflowExecutionStatus } from './models/WorkflowExecutionStatus';
-export type { WorkflowIn } from './models/WorkflowIn';
-export type { WorkflowModeIn } from './models/WorkflowModeIn';
-export type { WorkflowModeOut } from './models/WorkflowModeOut';
-export type { WorkflowOut } from './models/WorkflowOut';
-export type { WorkflowStatistic } from './models/WorkflowStatistic';
-export type { WorkflowUpdate } from './models/WorkflowUpdate';
-export type { WorkflowVersion } from './models/WorkflowVersion';
-export type { WorkflowVersionStatus } from './models/WorkflowVersionStatus';
-
-export { WorkflowService } from './services/WorkflowService';
-export { WorkflowCredentialsService } from './services/WorkflowCredentialsService';
-export { WorkflowExecutionService } from './services/WorkflowExecutionService';
-export { WorkflowModeService } from './services/WorkflowModeService';
-export { WorkflowVersionService } from './services/WorkflowVersionService';
diff --git a/src/client/workflow/models/ErrorDetail.ts b/src/client/workflow/models/ErrorDetail.ts
deleted file mode 100644
index 3b8a588e591ca42adc538757044eee2cf6b5881a..0000000000000000000000000000000000000000
--- a/src/client/workflow/models/ErrorDetail.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-/**
- * Schema for a error due to a rejected request.
- */
-export type ErrorDetail = {
-    /**
-     * Detail about the occurred error
-     */
-    detail: string;
-};
-
diff --git a/src/client/workflow/models/HTTPValidationError.ts b/src/client/workflow/models/HTTPValidationError.ts
deleted file mode 100644
index f9b1a79e2c6debaa712bb1660d4353552f6fbfad..0000000000000000000000000000000000000000
--- a/src/client/workflow/models/HTTPValidationError.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ValidationError } from './ValidationError';
-export type HTTPValidationError = {
-    detail?: Array<ValidationError>;
-};
-
diff --git a/src/client/workflow/models/ValidationError.ts b/src/client/workflow/models/ValidationError.ts
deleted file mode 100644
index aaf1c921e8b674c3da9543cc2cb597e8e90d6d8f..0000000000000000000000000000000000000000
--- a/src/client/workflow/models/ValidationError.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ValidationError = {
-    loc: Array<(string | number)>;
-    msg: string;
-    type: string;
-};
-
diff --git a/src/components/AppHeader.vue b/src/components/AppHeader.vue
index afc133156a816dd1a7636193d48b5483f37030fa..ff4585b608b7198191646544114c6ccf3ae4faec 100644
--- a/src/components/AppHeader.vue
+++ b/src/components/AppHeader.vue
@@ -5,10 +5,7 @@ import { useRoute } from "vue-router";
 import { useCookies } from "vue3-cookies";
 import { watch, ref, computed } from "vue";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
-import { OpenAPI as S3ProxyOpenAPI } from "@/client/s3proxy";
-import { OpenAPI as AuthOpenAPI } from "@/client/auth";
-import { OpenAPI as WorkflowOpenAPI } from "@/client/workflow";
-import { OpenAPI as ResourceOpenAPI } from "@/client/resource";
+import { OpenAPI } from "@/client";
 import CopyToClipboardIcon from "@/components/CopyToClipboardIcon.vue";
 import dayjs from "dayjs";
 
@@ -312,50 +309,14 @@ watch(
       <table class="table table-borderless table-sm">
         <tbody>
           <tr>
-            <td class="text-end">Auth Service:</td>
+            <td class="text-end">API:</td>
             <td>
-              <a :href="AuthOpenAPI.BASE + '/docs'" target="_blank">
+              <a :href="OpenAPI.BASE + '/docs'" target="_blank">
                 <font-awesome-icon
                   class="me-1"
                   icon="fa-solid fa-arrow-up-right-from-square"
                 />
-                {{ AuthOpenAPI.BASE }}</a
-              >
-            </td>
-          </tr>
-          <tr>
-            <td class="text-end">S3Proxy Service:</td>
-            <td>
-              <a :href="S3ProxyOpenAPI.BASE + '/docs'" target="_blank">
-                <font-awesome-icon
-                  class="me-1"
-                  icon="fa-solid fa-arrow-up-right-from-square"
-                />
-                {{ S3ProxyOpenAPI.BASE }}</a
-              >
-            </td>
-          </tr>
-          <tr>
-            <td class="text-end">Workflow Service:</td>
-            <td>
-              <a :href="WorkflowOpenAPI.BASE + '/docs'" target="_blank">
-                <font-awesome-icon
-                  class="me-1"
-                  icon="fa-solid fa-arrow-up-right-from-square"
-                />
-                {{ WorkflowOpenAPI.BASE }}</a
-              >
-            </td>
-          </tr>
-          <tr>
-            <td class="text-end">Resource Service:</td>
-            <td>
-              <a :href="ResourceOpenAPI.BASE + '/docs'" target="_blank">
-                <font-awesome-icon
-                  class="me-1"
-                  icon="fa-solid fa-arrow-up-right-from-square"
-                />
-                {{ ResourceOpenAPI.BASE }}</a
+                {{ OpenAPI.BASE }}</a
               >
             </td>
           </tr>
diff --git a/src/components/admin/UpdateBucketLimitsModal.vue b/src/components/admin/UpdateBucketLimitsModal.vue
index 09ea314205f2cec4676e7dbf541bd6a9e458637d..dda7de30ade92fd705e962ac9b1b6f8dda973b21 100644
--- a/src/components/admin/UpdateBucketLimitsModal.vue
+++ b/src/components/admin/UpdateBucketLimitsModal.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive, ref, watch } from "vue";
-import type { BucketOut, BucketSizeLimits } from "@/client/s3proxy";
+import type { BucketOut, BucketSizeLimits } from "@/client";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 import { filesize } from "filesize";
 import { useBucketStore } from "@/stores/buckets";
diff --git a/src/components/admin/UserRoleMark.vue b/src/components/admin/UserRoleMark.vue
index 84231b736c6731f6eb8dd7866ded024fb20e8e64..f87b5a6f6768b7c917cacf8f2a83c7abad9c6701 100644
--- a/src/components/admin/UserRoleMark.vue
+++ b/src/components/admin/UserRoleMark.vue
@@ -1,10 +1,10 @@
 <script setup lang="ts">
-import { RoleEnum, type User } from "@/client/auth";
+import { RoleEnum, type UserOutExtended } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 
 const props = defineProps<{
   role: RoleEnum;
-  user: User;
+  user: UserOutExtended;
 }>();
 </script>
 
diff --git a/src/components/modals/SearchUserModal.vue b/src/components/modals/SearchUserModal.vue
index 6416a0a5da16a3ba645655041632acdf9d43a55a..c6b5b26093a6a9d217a92b1e3751c79c3819054c 100644
--- a/src/components/modals/SearchUserModal.vue
+++ b/src/components/modals/SearchUserModal.vue
@@ -2,7 +2,7 @@
 import { reactive, ref, watch } from "vue";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import type { User } from "@/client/auth";
+import type { UserOut } from "@/client";
 import { useAuthStore } from "@/stores/users";
 
 const props = defineProps<{
@@ -17,7 +17,7 @@ const textInputElement = ref<HTMLInputElement | undefined>(undefined);
 
 const formState = reactive<{
   searchString: string;
-  potentialUsers: User[];
+  potentialUsers: UserOut[];
   lastSearchTimerId: ReturnType<typeof setTimeout> | null;
   error: boolean;
   loading: boolean;
@@ -46,7 +46,7 @@ watch(
 );
 
 const emit = defineEmits<{
-  (e: "user-found", user: User): void;
+  (e: "user-found", user: UserOut): void;
 }>();
 
 function modalClosed() {
@@ -61,7 +61,7 @@ function modalShown() {
 function searchUser(name: string) {
   formState.error = false;
   store
-    .fetchUsers(name)
+    .searchUser(name)
     .then((userSuggestions) => {
       if (props.filterUserSelf) {
         formState.potentialUsers = userSuggestions.filter(
diff --git a/src/components/object-storage/BucketListItem.vue b/src/components/object-storage/BucketListItem.vue
index ce41b994c98d7462643b567838d066d90471a2d2..672b09c18b2c63cc5a0260121f9100ca75ad4aa7 100644
--- a/src/components/object-storage/BucketListItem.vue
+++ b/src/components/object-storage/BucketListItem.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { BucketOut, BucketPermissionOut } from "@/client/s3proxy";
+import type { BucketOut, BucketPermissionOut } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import PermissionModal from "@/components/object-storage/modals/PermissionModal.vue";
 import BucketDetailModal from "@/components/object-storage/modals/BucketDetailModal.vue";
diff --git a/src/components/object-storage/modals/BucketDetailModal.vue b/src/components/object-storage/modals/BucketDetailModal.vue
index 2a2b0b1e5b08443a195484abd4ad86d076425e90..b76ef39f68320176d27094571bd2b7b446f2582b 100644
--- a/src/components/object-storage/modals/BucketDetailModal.vue
+++ b/src/components/object-storage/modals/BucketDetailModal.vue
@@ -1,11 +1,11 @@
 <script setup lang="ts">
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
-import type { BucketOut } from "@/client/s3proxy";
+import type { BucketOut } from "@/client";
 import dayjs from "dayjs";
 import { filesize } from "filesize";
 import { useS3ObjectStore } from "@/stores/s3objects";
 import { computed } from "vue";
-import { environment } from "../../../environment";
+import { environment } from "@/environment";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import BucketLimitProgressBar from "@/components/object-storage/BucketLimitProgressBar.vue";
 
diff --git a/src/components/object-storage/modals/CreateBucketModal.vue b/src/components/object-storage/modals/CreateBucketModal.vue
index 1f0aa226b784a52c8a34a8c08a031460d2b9aae9..ec625129b8b904bfa0b1166e37b5e34d0e16f29f 100644
--- a/src/components/object-storage/modals/CreateBucketModal.vue
+++ b/src/components/object-storage/modals/CreateBucketModal.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { BucketIn } from "@/client/s3proxy";
+import type { BucketIn } from "@/client";
 import { reactive, onMounted, ref } from "vue";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 import { useRouter } from "vue-router";
diff --git a/src/components/object-storage/modals/PermissionListModal.vue b/src/components/object-storage/modals/PermissionListModal.vue
index f2a08972f0b05acf3ab2bf374cbfd31e76536037..3eefe9fb64c0895281d5fa78024e5d1cd596d6a0 100644
--- a/src/components/object-storage/modals/PermissionListModal.vue
+++ b/src/components/object-storage/modals/PermissionListModal.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { BucketPermissionOut } from "@/client/s3proxy";
+import type { BucketPermissionOut } from "@/client";
 import type { FolderTree } from "@/types/PseudoFolder";
 import { reactive } from "vue";
 import { onBeforeMount, watch } from "vue";
diff --git a/src/components/object-storage/modals/PermissionModal.vue b/src/components/object-storage/modals/PermissionModal.vue
index 74a5e2f10f041af297ed5d94bd1e50e715ce18b0..a17b047d6241915c2622378fd831caec0a9716f7 100644
--- a/src/components/object-storage/modals/PermissionModal.vue
+++ b/src/components/object-storage/modals/PermissionModal.vue
@@ -9,10 +9,10 @@ import type {
   BucketPermissionOut,
   BucketPermissionIn,
   BucketPermissionParameters,
-} from "@/client/s3proxy";
-import type { User } from "@/client/auth";
+  UserOut,
+} from "@/client";
 import type { FolderTree } from "@/types/PseudoFolder";
-import { Permission } from "@/client/s3proxy";
+import { Permission } from "@/client";
 import { Toast } from "bootstrap";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { useBucketStore } from "@/stores/buckets";
@@ -230,7 +230,7 @@ function confirmedDeletePermission(bucketName: string, uid: string) {
   }
 }
 
-function updateUser(user: User) {
+function updateUser(user: UserOut) {
   permission.uid = user.uid;
 }
 
diff --git a/src/components/parameter-schema/ParameterSchemaFormComponent.vue b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
index 1de06571a5b3910fa6e21d6c1be1a4512a71ad21..80dea09b5255e29f4e5fd2723940d10f561c9f90 100644
--- a/src/components/parameter-schema/ParameterSchemaFormComponent.vue
+++ b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
@@ -19,7 +19,7 @@ import type {
   WorkflowParameters,
 } from "@/types/WorkflowParameters";
 import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
-import type { ParameterExtension } from "@/client/workflow";
+import type { ParameterExtension } from "@/client";
 
 const bucketRepository = useBucketStore();
 const resourceRepository = useResourceStore();
diff --git a/src/components/parameter-schema/form-mode/ParameterResourceInput.vue b/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
index e47cee1c03d6dc0a3099204ab70ca0a8556ae1d1..0a4a3efacc7bb824ec479487c7d66b02b657e232 100644
--- a/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { Status } from "@/client/resource";
+import { ResourceVersionStatus } from "@/client";
 import { computed, onMounted, reactive, watch } from "vue";
 import { useResourceStore } from "@/stores/resources";
 import type { ExtendedColors, SizeModifierType } from "@/types/PropTypes";
@@ -195,7 +195,7 @@ onMounted(() => {
       :value="version.resource_version_id"
     >
       {{ version.release }}
-      {{ version.status === Status.LATEST ? "- Latest" : "" }}
+      {{ version.status === ResourceVersionStatus.LATEST ? "- Latest" : "" }}
     </option>
   </select>
   <input
diff --git a/src/components/resources/ResourceCard.vue b/src/components/resources/ResourceCard.vue
index a527ad3784bc700ace1f7ce6e0992f502524b0e7..d2c21e8db37fe0ef4c43d3e8f906773aecc0330d 100644
--- a/src/components/resources/ResourceCard.vue
+++ b/src/components/resources/ResourceCard.vue
@@ -3,8 +3,8 @@ import {
   type FileTree,
   type ResourceOut,
   type ResourceVersionOut,
-  Status,
-} from "@/client/resource";
+  ResourceVersionStatus,
+} from "@/client";
 import { computed, onMounted, ref } from "vue";
 import dayjs from "dayjs";
 import CopyToClipboardIcon from "@/components/CopyToClipboardIcon.vue";
@@ -31,7 +31,7 @@ const props = defineProps<{
 }>();
 let refreshTimeout: NodeJS.Timeout | undefined = undefined;
 
-const stateToUIMapping: Record<Status, string> = {
+const stateToUIMapping: Record<ResourceVersionStatus, string> = {
   APPROVED: "Resource approved",
   WAIT_FOR_REVIEW: "Wait for review",
   CLUSTER_DELETE_ERROR: "Error deleting resource on cluster",
@@ -138,7 +138,7 @@ onMounted(() => {
           r.resource_version_id,
         );
       }
-      if (r.status == Status.RESOURCE_REQUESTED) {
+      if (r.status == ResourceVersionStatus.RESOURCE_REQUESTED) {
         checkS3Resource(r);
       }
     }
@@ -246,7 +246,9 @@ onMounted(() => {
                   }}
                 </div>
                 <div
-                  v-if="resourceVersion.status == Status.APPROVED"
+                  v-if="
+                    resourceVersion.status == ResourceVersionStatus.APPROVED
+                  "
                   class="d-grid gap-2"
                 >
                   <button
@@ -262,7 +264,8 @@ onMounted(() => {
                 <div
                   v-if="
                     props.extended &&
-                    resourceVersion.status == Status.RESOURCE_REQUESTED
+                    resourceVersion.status ==
+                      ResourceVersionStatus.RESOURCE_REQUESTED
                   "
                   class="d-flex justify-content-between align-items-center"
                 >
@@ -287,8 +290,9 @@ onMounted(() => {
                 </div>
                 <div
                   v-if="
-                    resourceVersion.status === Status.SYNCHRONIZED ||
-                    resourceVersion.status === Status.LATEST
+                    resourceVersion.status ===
+                      ResourceVersionStatus.SYNCHRONIZED ||
+                    resourceVersion.status === ResourceVersionStatus.LATEST
                   "
                 >
                   <label
@@ -331,7 +335,8 @@ onMounted(() => {
                 <div
                   v-if="
                     props.extended &&
-                    resourceVersion.status === Status.RESOURCE_REQUESTED
+                    resourceVersion.status ===
+                      ResourceVersionStatus.RESOURCE_REQUESTED
                   "
                 >
                   <label
diff --git a/src/components/resources/modals/CreateResourceModal.vue b/src/components/resources/modals/CreateResourceModal.vue
index 8087bec60048184bf1c78f6d50daa7903facbdd1..dace8d1944c2b84119063799a037691576016839 100644
--- a/src/components/resources/modals/CreateResourceModal.vue
+++ b/src/components/resources/modals/CreateResourceModal.vue
@@ -3,7 +3,7 @@ import { reactive, onMounted, ref } from "vue";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 import { Modal } from "bootstrap";
 import { useResourceStore } from "@/stores/resources";
-import type { ResourceIn } from "@/client/resource";
+import type { ResourceIn } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { Tooltip } from "bootstrap";
 
diff --git a/src/components/resources/modals/ResourceVersionInfoModal.vue b/src/components/resources/modals/ResourceVersionInfoModal.vue
index 13ace3a48316db4917febec9ac2b0739b528a1e5..713e8677b81aac7f52e72410cbea483061e8dd4a 100644
--- a/src/components/resources/modals/ResourceVersionInfoModal.vue
+++ b/src/components/resources/modals/ResourceVersionInfoModal.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
-import type { ResourceVersionOut, ResourceOut } from "@/client/resource";
+import type { ResourceVersionOut, ResourceOut } from "@/client";
 import CopyToClipboardIcon from "@/components/CopyToClipboardIcon.vue";
 import dayjs from "dayjs";
 import { computed } from "vue";
diff --git a/src/components/resources/modals/UpdateResourceModal.vue b/src/components/resources/modals/UpdateResourceModal.vue
index 3a430a639f46415a8e164b16cc47aea6d91c547d..3ca43a5edfce1ce4ea809d5ad7e14b2818622678 100644
--- a/src/components/resources/modals/UpdateResourceModal.vue
+++ b/src/components/resources/modals/UpdateResourceModal.vue
@@ -3,7 +3,7 @@ import { reactive, onMounted, ref } from "vue";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 import { Modal } from "bootstrap";
 import { useResourceStore } from "@/stores/resources";
-import type { ResourceVersionIn, ResourceOut } from "@/client/resource";
+import type { ResourceVersionIn, ResourceOut } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { Tooltip } from "bootstrap";
 
diff --git a/src/components/resources/modals/UploadResourceInfoModal.vue b/src/components/resources/modals/UploadResourceInfoModal.vue
index 6e2cefdf4276442a614cff647cea39639b1905cc..6da7a2e8c29fd997434e6bd868624fa94bc9dd88 100644
--- a/src/components/resources/modals/UploadResourceInfoModal.vue
+++ b/src/components/resources/modals/UploadResourceInfoModal.vue
@@ -1,11 +1,14 @@
 <script setup lang="ts">
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
-import { type ResourceVersionOut, Status } from "@/client/resource";
+import {
+  type ResourceVersionOut,
+  ResourceVersionStatus,
+  type S3Key,
+} from "@/client";
 import { computed, onMounted, ref, watch } from "vue";
 import { environment } from "@/environment";
 import CopyToClipboardIcon from "@/components/CopyToClipboardIcon.vue";
 import { useS3KeyStore } from "@/stores/s3keys";
-import type { S3Key } from "@/client/s3proxy";
 import { useS3ObjectStore } from "@/stores/s3objects";
 import { useResourceStore } from "@/stores/resources";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
@@ -35,7 +38,7 @@ watch(
   (newVersion, oldVersion) => {
     if (newVersion?.resource_version_id !== oldVersion?.resource_version_id) {
       resourceReviewEnabled.value = false;
-      if (newVersion?.status === Status.RESOURCE_REQUESTED) {
+      if (newVersion?.status === ResourceVersionStatus.RESOURCE_REQUESTED) {
         checkS3Resource(newVersion);
       }
     }
@@ -312,7 +315,10 @@ s3 = boto3.resource(
             Click <b>Request Review</b> to request a review of the resource.
           </p>
           <request-review-button
-            v-if="props.resourceVersion?.status === Status.RESOURCE_REQUESTED"
+            v-if="
+              props.resourceVersion?.status ===
+              ResourceVersionStatus.RESOURCE_REQUESTED
+            "
             class="mb-2"
             :disabled="!resourceReviewEnabled"
             @click-review="requestReview(props.resourceVersion)"
diff --git a/src/components/workflows/WorkflowCard.vue b/src/components/workflows/WorkflowCard.vue
index 9284e74222fcae9eb55c117bf2c605954f373e4e..f8f9d6eaeef4a623423c62fe834fb220990781f1 100644
--- a/src/components/workflows/WorkflowCard.vue
+++ b/src/components/workflows/WorkflowCard.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { WorkflowOut, WorkflowVersion } from "@/client/workflow";
+import type { WorkflowOut, WorkflowVersion } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import dayjs from "dayjs";
 import { onMounted, computed } from "vue";
diff --git a/src/components/workflows/WorkflowStatisticsChart.vue b/src/components/workflows/WorkflowStatisticsChart.vue
index 56a9648686e8d2b153373cc096bc43fdf0366cc5..ea9fa1a70c4b94068a4c220b8de44199d62515e7 100644
--- a/src/components/workflows/WorkflowStatisticsChart.vue
+++ b/src/components/workflows/WorkflowStatisticsChart.vue
@@ -13,7 +13,7 @@ import {
 import "@/utils/DayjsAdapter";
 import type { Element as ChartElement, Point, ChartItem } from "chart.js";
 import { onMounted, ref, watch, computed } from "vue";
-import type { WorkflowStatistic } from "@/client/workflow";
+import type { WorkflowStatistic } from "@/client";
 import dayjs from "dayjs";
 
 const canvas = ref<ChartItem | undefined>(undefined);
diff --git a/src/components/workflows/WorkflowWithVersionsCard.vue b/src/components/workflows/WorkflowWithVersionsCard.vue
index d69290f4af2202deca6798ce34d38e7ccf2932c6..cae0ee587fc8915a7699a8231367f64737031bbc 100644
--- a/src/components/workflows/WorkflowWithVersionsCard.vue
+++ b/src/components/workflows/WorkflowWithVersionsCard.vue
@@ -3,8 +3,8 @@ import type {
   AnonymizedWorkflowExecution,
   WorkflowOut,
   WorkflowVersion,
-} from "@/client/workflow";
-import { Status, WorkflowExecutionStatus } from "@/client/workflow";
+} from "@/client";
+import { WorkflowVersionStatus, WorkflowExecutionStatus } from "@/client";
 import { computed, onMounted, ref, watch } from "vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import dayjs from "dayjs";
@@ -228,10 +228,14 @@ onMounted(() => {
                 <th scope="row" class="fw-bold">{{ version.version }}</th>
                 <td
                   :class="{
-                    'text-success': version.status === Status.PUBLISHED,
-                    'text-danger': version.status === Status.DENIED,
-                    'text-secondary': version.status === Status.CREATED,
-                    'text-warning': version.status === Status.DEPRECATED,
+                    'text-success':
+                      version.status === WorkflowVersionStatus.PUBLISHED,
+                    'text-danger':
+                      version.status === WorkflowVersionStatus.DENIED,
+                    'text-secondary':
+                      version.status === WorkflowVersionStatus.CREATED,
+                    'text-warning':
+                      version.status === WorkflowVersionStatus.DEPRECATED,
                   }"
                 >
                   <font-awesome-icon
diff --git a/src/components/workflows/modals/ArbitraryWorkflowModal.vue b/src/components/workflows/modals/ArbitraryWorkflowModal.vue
index 9d2a0ec88180641f0cf9f3b33565c69c707bc215..6cf0681d247976f3ae80547e0edff2ed53a17899 100644
--- a/src/components/workflows/modals/ArbitraryWorkflowModal.vue
+++ b/src/components/workflows/modals/ArbitraryWorkflowModal.vue
@@ -10,7 +10,7 @@ import {
 } from "@/utils/GitRepository";
 import { Collapse, Modal } from "bootstrap";
 import { useWorkflowStore } from "@/stores/workflows";
-import type { WorkflowModeOut } from "@/client/workflow";
+import type { WorkflowModeOut } from "@/client";
 
 const props = defineProps<{
   modalId: string;
diff --git a/src/components/workflows/modals/CreateWorkflowModal.vue b/src/components/workflows/modals/CreateWorkflowModal.vue
index a75376e85af34975e10d0c60de3cc7c61fb7e85c..db2e210cb8163fe455f5e2d1352af40948d06df5 100644
--- a/src/components/workflows/modals/CreateWorkflowModal.vue
+++ b/src/components/workflows/modals/CreateWorkflowModal.vue
@@ -1,14 +1,10 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive, ref, watch } from "vue";
 import { Modal, Toast, Collapse, Tooltip } from "bootstrap";
-import type {
-  WorkflowIn,
-  WorkflowOut,
-  WorkflowModeOut,
-} from "@/client/workflow";
+import type { WorkflowIn, WorkflowOut, WorkflowModeOut } from "@/client";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import { ApiError } from "@/client/workflow";
+import { ApiError } from "@/client";
 import {
   GitRepository,
   requiredRepositoryFiles,
diff --git a/src/components/workflows/modals/ParameterModal.vue b/src/components/workflows/modals/ParameterModal.vue
index ee99004d2883014d8c2d41a102c2fdd514ce249c..ff06cf6ad68bfc2020d4bb81c5ba35455f1a8785 100644
--- a/src/components/workflows/modals/ParameterModal.vue
+++ b/src/components/workflows/modals/ParameterModal.vue
@@ -6,7 +6,7 @@ import type { RouteLocationRaw, RouteParamsRaw } from "vue-router";
 import { Modal } from "bootstrap";
 import { useRouter } from "vue-router";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import type { WorkflowExecutionOut, WorkflowVersion } from "@/client/workflow";
+import type { WorkflowExecutionOut, WorkflowVersion } from "@/client";
 import { useNameStore } from "@/stores/names";
 import { useWorkflowStore } from "@/stores/workflows";
 import { createDownloadUrl } from "@/utils/DownloadJson";
diff --git a/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue b/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue
index a6180547ba405a7fce7e7953a8804a13aeaf86f0..27ccc333dbe71c7fe47906c5359eaeb6037f81b6 100644
--- a/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue
+++ b/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
-import type { WorkflowCredentialsIn, WorkflowOut } from "@/client/workflow";
+import type { WorkflowCredentialsIn, WorkflowOut } from "@/client";
 import { onMounted, ref, reactive } from "vue";
 import { Modal, Toast } from "bootstrap";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
diff --git a/src/components/workflows/modals/UpdateWorkflowModal.vue b/src/components/workflows/modals/UpdateWorkflowModal.vue
index 114f51c8e04bbad57d32ab8dec8472c9a89b0b4e..ed2af5e554b6dd89c81c6b1e9fdbaa3570aada61 100644
--- a/src/components/workflows/modals/UpdateWorkflowModal.vue
+++ b/src/components/workflows/modals/UpdateWorkflowModal.vue
@@ -8,10 +8,10 @@ import type {
   WorkflowModeOut,
   WorkflowVersion,
   ApiError,
-} from "@/client/workflow";
+} from "@/client";
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import { WorkflowCredentialsService } from "@/client/workflow";
+import { WorkflowCredentialsService } from "@/client";
 import {
   GitRepository,
   requiredRepositoryFiles,
diff --git a/src/components/workflows/modals/UpdateWorkflowVersionIconModal.vue b/src/components/workflows/modals/UpdateWorkflowVersionIconModal.vue
index 1b18fd83a40744e058061ae66749e1b975d69ded..7df21357b9ed00a329fecf69260a22336662989d 100644
--- a/src/components/workflows/modals/UpdateWorkflowVersionIconModal.vue
+++ b/src/components/workflows/modals/UpdateWorkflowVersionIconModal.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
-import type { WorkflowVersion } from "@/client/workflow";
+import type { WorkflowVersion } from "@/client";
 import { onMounted, ref, reactive, computed } from "vue";
 import { Modal, Toast } from "bootstrap";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
diff --git a/src/environment.ts b/src/environment.ts
index 673d13a603c71c581fc3b6a956ce0a1359672bb8..d52a9ce714d66a17112870105a8d9cad8be2ab67 100644
--- a/src/environment.ts
+++ b/src/environment.ts
@@ -3,10 +3,7 @@
 const windowEnv: Record<string, string> = window["env"];
 export const environment: env = {
   S3_URL: windowEnv["s3Url"],
-  S3PROXY_API_BASE_URL: windowEnv["s3proxyApiUrl"],
-  AUTH_API_BASE_URL: windowEnv["authApiUrl"],
-  WORKFLOW_API_BASE_URL: windowEnv["workflowApiUrl"],
-  RESOURCE_API_BASE_URL: windowEnv["resourceApiUrl"],
+  API_BASE_URL: windowEnv["apiUrl"],
   MATOMO_SITE_ID: parseInt(windowEnv["matomoSiteId"]),
   MATOMO_HOST: windowEnv["matomoHost"],
   DEV_SYSTEM: windowEnv["devSystem"].toLowerCase() === "true",
@@ -14,11 +11,8 @@ export const environment: env = {
 
 type env = {
   S3_URL: string;
-  S3PROXY_API_BASE_URL: string;
-  AUTH_API_BASE_URL: string;
-  WORKFLOW_API_BASE_URL: string;
+  API_BASE_URL: string;
   MATOMO_SITE_ID: number;
   MATOMO_HOST: string;
-  RESOURCE_API_BASE_URL: string;
   DEV_SYSTEM: boolean;
 };
diff --git a/src/stores/buckets.ts b/src/stores/buckets.ts
index 46911174c735c67e20fa3777bd8f45386442837c..5c5d702f686a994ce2f7405e3cc5d8674ca44b6c 100644
--- a/src/stores/buckets.ts
+++ b/src/stores/buckets.ts
@@ -1,16 +1,12 @@
 import { defineStore } from "pinia";
-import {
-  BucketPermissionService,
-  BucketService,
-  BucketType,
-} from "@/client/s3proxy";
+import { BucketPermissionService, BucketService, BucketType } from "@/client";
 import type {
   BucketOut,
   BucketIn,
   BucketPermissionOut,
   BucketPermissionIn,
   BucketPermissionParameters,
-} from "@/client/s3proxy";
+} from "@/client";
 import { useAuthStore } from "@/stores/users";
 
 export const useBucketStore = defineStore({
diff --git a/src/stores/resources.ts b/src/stores/resources.ts
index 0c9a78176fa4531e24ba19585cbd540d966aca5e..f43fe0a04e9165aeb94657055eafedde3fb9c4be 100644
--- a/src/stores/resources.ts
+++ b/src/stores/resources.ts
@@ -8,12 +8,12 @@ import type {
   UserRequestAnswer,
   UserSynchronizationRequestIn,
   UserSynchronizationRequestOut,
-} from "@/client/resource";
+} from "@/client";
 import {
   ResourceService,
   ResourceVersionService,
-  Status,
-} from "@/client/resource";
+  ResourceVersionStatus,
+} from "@/client";
 import { useAuthStore } from "@/stores/users";
 import { useNameStore } from "@/stores/names";
 
@@ -69,7 +69,7 @@ export const useResourceStore = defineStore({
       return (resource_id) => {
         for (const version of this.resourceMapping[resource_id]?.versions ??
           []) {
-          if (version.status === Status.LATEST) {
+          if (version.status === ResourceVersionStatus.LATEST) {
             return version.resource_version_id;
           }
         }
@@ -89,7 +89,7 @@ export const useResourceStore = defineStore({
   actions: {
     fetchResource(
       resource_id: string,
-      versionStatus?: Status[],
+      versionStatus?: ResourceVersionStatus[],
     ): Promise<ResourceOut> {
       return ResourceService.resourceGetResource(
         resource_id,
@@ -130,7 +130,7 @@ export const useResourceStore = defineStore({
     },
     fetchResources(
       maintainerId?: string,
-      versionStatus?: Status[],
+      versionStatus?: ResourceVersionStatus[],
       searchString?: string,
       _public?: boolean,
     ): Promise<ResourceOut[]> {
@@ -142,7 +142,9 @@ export const useResourceStore = defineStore({
       ).then((resources) => {
         const userStore = useAuthStore();
         userStore.fetchUsernames(
-          resources.map((resource) => resource.maintainer_id),
+          resources
+            .map((resource) => resource.maintainer_id ?? "")
+            .filter((mid) => mid.length > 0),
         );
         const nameStore = useNameStore();
         for (const resource of resources) {
@@ -187,7 +189,9 @@ export const useResourceStore = defineStore({
       if (Object.keys(this.reviewableResourceMapping).length > 0) {
         onFinally?.();
       }
-      return this.fetchResources(undefined, [Status.WAIT_FOR_REVIEW])
+      return this.fetchResources(undefined, [
+        ResourceVersionStatus.WAIT_FOR_REVIEW,
+      ])
         .then((resources) => {
           const newMapping: Record<string, ResourceOut> = {};
           for (const resource of resources) {
@@ -203,14 +207,14 @@ export const useResourceStore = defineStore({
         onFinally?.();
       }
       return this.fetchResources(undefined, [
-        Status.APPROVED,
-        Status.SYNC_REQUESTED,
-        Status.SYNCHRONIZING,
-        Status.SYNC_ERROR,
-        Status.SYNCHRONIZED,
-        Status.SETTING_LATEST,
-        Status.LATEST,
-        Status.CLUSTER_DELETE_ERROR,
+        ResourceVersionStatus.APPROVED,
+        ResourceVersionStatus.SYNC_REQUESTED,
+        ResourceVersionStatus.SYNCHRONIZING,
+        ResourceVersionStatus.SYNC_ERROR,
+        ResourceVersionStatus.SYNCHRONIZED,
+        ResourceVersionStatus.SETTING_LATEST,
+        ResourceVersionStatus.LATEST,
+        ResourceVersionStatus.CLUSTER_DELETE_ERROR,
       ])
         .then((resources) => {
           const newMapping: Record<string, ResourceOut> = {};
diff --git a/src/stores/s3keys.ts b/src/stores/s3keys.ts
index 915426f43a5128a7912be1ce316397d144c1a70b..bb95b17c721d9b997fda0cdd0f25423e68186957 100644
--- a/src/stores/s3keys.ts
+++ b/src/stores/s3keys.ts
@@ -1,7 +1,7 @@
 import { defineStore } from "pinia";
 import { useAuthStore } from "@/stores/users";
-import type { S3Key } from "@/client/s3proxy";
-import { S3KeyService } from "@/client/s3proxy";
+import type { S3Key } from "@/client";
+import { S3KeyService } from "@/client";
 import { useS3ObjectStore } from "@/stores/s3objects";
 
 export const useS3KeyStore = defineStore({
diff --git a/src/stores/s3objects.ts b/src/stores/s3objects.ts
index 807218393a7a6527f0a9cd4982bc6ccaf055f365..8f2b67e5cd934f3459deb955014707650c003088 100644
--- a/src/stores/s3objects.ts
+++ b/src/stores/s3objects.ts
@@ -19,7 +19,7 @@ import {
   DeleteObjectsCommand,
 } from "@aws-sdk/client-s3";
 import { environment } from "@/environment";
-import type { S3Key } from "@/client/s3proxy";
+import type { S3Key } from "@/client";
 import { useBucketStore } from "@/stores/buckets";
 import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
 import dayjs from "dayjs";
diff --git a/src/stores/users.ts b/src/stores/users.ts
index 016203dee5a4a9e50e49020343096b531f19aecd..9b22015a3650476c41dc6be9588dc3b638bac303 100644
--- a/src/stores/users.ts
+++ b/src/stores/users.ts
@@ -1,10 +1,6 @@
 import { defineStore } from "pinia";
-import type { User } from "@/client/auth";
-import { UserService, RoleEnum } from "@/client/auth";
-import { OpenAPI as S3ProxyOpenAPI } from "@/client/s3proxy";
-import { OpenAPI as AuthOpenAPI } from "@/client/auth";
-import { OpenAPI as WorkflowOpenAPI } from "@/client/workflow";
-import { OpenAPI as ResourceOpenAPI } from "@/client/resource";
+import type { UserOutExtended, UserOut } from "@/client";
+import { OpenAPI, UserService, RoleEnum } from "@/client";
 import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
 import { useBucketStore } from "@/stores/buckets";
 import { useWorkflowStore } from "@/stores/workflows";
@@ -16,7 +12,6 @@ import { useNameStore } from "@/stores/names";
 type DecodedToken = {
   exp: number;
   iss: string;
-  roles: RoleEnum[];
   sub: string;
 };
 
@@ -46,54 +41,32 @@ export const useAuthStore = defineStore({
     }) as {
       token: string | null;
       decodedToken: DecodedToken | null;
-      user: User | null;
+      user: UserOutExtended | null;
     },
   getters: {
     roles(): string[] {
-      return (
-        this.user?.roles?.map((role) => role.toString()) ??
-        this.decodedToken?.["roles"] ??
-        []
-      );
+      return this.user?.roles?.map((role) => role.toString()) ?? [];
     },
     authenticated: (state) => state.token != null,
     currentUID(): string {
       return this.user?.uid ?? this.decodedToken?.["sub"] ?? "";
     },
-    foreignUser: (state) =>
-      state.user?.roles?.includes(RoleEnum.FOREIGN_USER) ??
-      state.decodedToken?.roles.includes(RoleEnum.FOREIGN_USER) ??
-      true,
-    normalUser: (state) =>
-      state.user?.roles?.includes(RoleEnum.USER) ??
-      state.decodedToken?.roles.includes(RoleEnum.USER) ??
-      false,
-    rewiewer: (state) =>
-      state.user?.roles?.includes(RoleEnum.REVIEWER) ??
-      state.decodedToken?.roles.includes(RoleEnum.REVIEWER) ??
-      false,
+    foreignUser: (state) => (state.user?.roles ?? []).length == 0,
+    normalUser: (state) => state.user?.roles.includes(RoleEnum.USER) ?? false,
+    rewiewer: (state) => state.user?.roles.includes(RoleEnum.REVIEWER) ?? false,
     workflowDev: (state) =>
-      state.user?.roles?.includes(RoleEnum.DEVELOPER) ??
-      state.decodedToken?.roles.includes(RoleEnum.DEVELOPER) ??
-      false,
+      state.user?.roles.includes(RoleEnum.DEVELOPER) ?? false,
     resourceMaintainer: (state) =>
-      state.user?.roles?.includes(RoleEnum.DB_MAINTAINER) ??
-      state.decodedToken?.roles.includes(RoleEnum.DB_MAINTAINER) ??
-      false,
+      state.user?.roles.includes(RoleEnum.DB_MAINTAINER) ?? false,
     admin: (state) =>
-      state.user?.roles?.includes(RoleEnum.ADMINISTRATOR) ??
-      state.decodedToken?.roles.includes(RoleEnum.ADMINISTRATOR) ??
-      false,
+      state.user?.roles.includes(RoleEnum.ADMINISTRATOR) ?? false,
   },
   actions: {
     setToken(token: string | null) {
       if (token != null) {
         this.token = token;
         this.decodedToken = parseJwt(token);
-        S3ProxyOpenAPI.TOKEN = token;
-        AuthOpenAPI.TOKEN = token;
-        WorkflowOpenAPI.TOKEN = token;
-        ResourceOpenAPI.TOKEN = token;
+        OpenAPI.TOKEN = token;
         UserService.userGetLoggedInUser()
           .then((user) => {
             this.updateUser(user);
@@ -105,16 +78,13 @@ export const useAuthStore = defineStore({
         this.logout();
       }
     },
-    updateUser(user: User) {
+    updateUser(user: UserOutExtended) {
       this.user = user;
       useNameStore().addNameToMapping(user.uid, user.display_name);
     },
     logout() {
       window._paq.push(["resetUserId"]);
-      S3ProxyOpenAPI.TOKEN = undefined;
-      AuthOpenAPI.TOKEN = undefined;
-      WorkflowOpenAPI.TOKEN = undefined;
-      ResourceOpenAPI.TOKEN = undefined;
+      OpenAPI.TOKEN = undefined;
       this.$reset();
       localStorage.clear();
       dbclear();
@@ -127,13 +97,19 @@ export const useAuthStore = defineStore({
     fetchUsers(
       searchString?: string,
       filterRoles?: RoleEnum[],
-      includeRoles = false,
-    ): Promise<User[]> {
-      return UserService.userListUsers(
-        searchString,
-        filterRoles,
-        includeRoles,
-      ).then((users) => {
+    ): Promise<UserOutExtended[]> {
+      return UserService.userListUsers(searchString, filterRoles).then(
+        (users) => {
+          const nameStore = useNameStore();
+          for (const user of users) {
+            nameStore.addNameToMapping(user.uid, user.display_name);
+          }
+          return users;
+        },
+      );
+    },
+    searchUser(searchString: string): Promise<UserOut[]> {
+      return UserService.userSearchUsers(searchString).then((users) => {
         const nameStore = useNameStore();
         for (const user of users) {
           nameStore.addNameToMapping(user.uid, user.display_name);
diff --git a/src/stores/workflowExecutions.ts b/src/stores/workflowExecutions.ts
index e90bd1d1bb182099af42944841287ba762f5c3ce..5eab671aba325ba2db854e43be4464451c3a96e2 100644
--- a/src/stores/workflowExecutions.ts
+++ b/src/stores/workflowExecutions.ts
@@ -4,12 +4,12 @@ import type {
   DevWorkflowExecutionIn,
   WorkflowExecutionIn,
   WorkflowExecutionOut,
-} from "@/client/workflow";
+} from "@/client";
 import {
   WorkflowExecutionService,
   WorkflowExecutionStatus,
   WorkflowService,
-} from "@/client/workflow";
+} from "@/client";
 import { useAuthStore } from "@/stores/users";
 import dayjs from "dayjs";
 import { set, get } from "idb-keyval";
diff --git a/src/stores/workflows.ts b/src/stores/workflows.ts
index cb9b3fd3f8405e9e3485de44a1d9500db624c76c..5643a6f9f8fa69086aaf8f958f776ddff2387aba 100644
--- a/src/stores/workflows.ts
+++ b/src/stores/workflows.ts
@@ -9,15 +9,15 @@ import type {
   WorkflowOut,
   WorkflowUpdate,
   WorkflowVersion,
-} from "@/client/workflow";
+} from "@/client";
 import {
+  WorkflowVersionStatus,
   DocumentationEnum,
-  Status,
   WorkflowCredentialsService,
   WorkflowModeService,
   WorkflowService,
   WorkflowVersionService,
-} from "@/client/workflow";
+} from "@/client";
 import { useAuthStore } from "@/stores/users";
 import { get, set } from "idb-keyval";
 import { useNameStore } from "@/stores/names";
@@ -51,7 +51,7 @@ export const useWorkflowStore = defineStore({
       return Object.values(this.comprehensiveWorkflowMapping).filter(
         (workflow) =>
           workflow.versions.filter(
-            (version) => version.status === Status.CREATED,
+            (version) => version.status === WorkflowVersionStatus.CREATED,
           ).length > 0,
       );
     },
@@ -124,7 +124,7 @@ export const useWorkflowStore = defineStore({
       }
       return WorkflowService.workflowListWorkflows(
         undefined,
-        Object.values(Status),
+        Object.values(WorkflowVersionStatus),
         authStore.currentUID,
       )
         .then((workflows) => {
@@ -197,7 +197,9 @@ export const useWorkflowStore = defineStore({
       if (this.reviewableWorkflows.length > 0) {
         onFinally?.();
       }
-      return WorkflowService.workflowListWorkflows(undefined, [Status.CREATED])
+      return WorkflowService.workflowListWorkflows(undefined, [
+        WorkflowVersionStatus.CREATED,
+      ])
         .then((workflows) => {
           for (const workflow of workflows) {
             this.__addNameToMapping(workflow.workflow_id, workflow.name);
@@ -253,7 +255,7 @@ export const useWorkflowStore = defineStore({
       }
       return WorkflowService.workflowGetWorkflow(
         workflow_id,
-        comprehensive ? Object.values(Status) : undefined,
+        comprehensive ? Object.values(WorkflowVersionStatus) : undefined,
       )
         .then((workflow) => {
           this.__addNameToMapping(workflow.workflow_id, workflow.name);
@@ -512,11 +514,13 @@ export const useWorkflowStore = defineStore({
     updateVersionStatus(
       workflow_id: string,
       version_id: string,
-      status: Status,
+      status: WorkflowVersionStatus,
     ): Promise<void> {
       return WorkflowVersionService.workflowVersionUpdateWorkflowVersionStatus(
         workflow_id,
         version_id,
+        /* eslint-disable @typescript-eslint/ban-ts-comment */
+        // @ts-ignore
         { status: status },
       ).then(() => {
         if (this.comprehensiveWorkflowMapping[workflow_id] == undefined) {
diff --git a/src/utils/GitRepository.ts b/src/utils/GitRepository.ts
index 505a42296de7bd29d7c7248bf397fcec24aecbd2..5953f28b25ee9140d213264efb3cb4e04fefd1c1 100644
--- a/src/utils/GitRepository.ts
+++ b/src/utils/GitRepository.ts
@@ -1,6 +1,6 @@
 import axios from "axios";
 import type { AxiosInstance, AxiosBasicCredentials } from "axios";
-import type { WorkflowModeOut, WorkflowModeIn } from "@/client/workflow";
+import type { WorkflowModeOut, WorkflowModeIn } from "@/client";
 
 export function requiredRepositoryFiles(
   modes?: WorkflowModeIn[] | WorkflowModeOut[],
diff --git a/src/utils/Workflow.ts b/src/utils/Workflow.ts
index e01237b68f4f3c5baaec652c5c10c5c3a36f6e2f..9ca73748f3637d5e53abbded76f00b07db39a393 100644
--- a/src/utils/Workflow.ts
+++ b/src/utils/Workflow.ts
@@ -1,4 +1,4 @@
-import type { WorkflowVersion } from "@/client/workflow";
+import type { WorkflowVersion } from "@/client";
 
 export function sortedVersions(
   versions: WorkflowVersion[],
diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue
index eb991253dfbe6cb2d5faafbed602b4471a081dee..b571a83af8863e50193f798dac04f933a819dcf9 100644
--- a/src/views/LoginView.vue
+++ b/src/views/LoginView.vue
@@ -2,7 +2,7 @@
 import { onBeforeMount, onMounted, computed } from "vue";
 import { useAuthStore } from "@/stores/users";
 import { useRouter } from "vue-router";
-import { OpenAPI as AuthOpenAPI } from "@/client/auth";
+import { OpenAPI } from "@/client";
 import { Toast } from "bootstrap";
 import BootstrapToast from "@/components/BootstrapToast.vue";
 
@@ -25,7 +25,7 @@ onBeforeMount(() => {
 });
 
 const returnPathQuery = computed<string>(() =>
-  props.returnPath ? `&return_path=${encodeURI(props.returnPath)}` : "",
+  props.returnPath ? `&next=${encodeURI(props.returnPath)}` : "",
 );
 
 onMounted(() => {
@@ -75,7 +75,7 @@ onMounted(() => {
         Login to this service with LifeScience
       </p>
       <a
-        :href="`${AuthOpenAPI.BASE}/auth/login?provider=lifescience${returnPathQuery}`"
+        :href="`${OpenAPI.BASE}/auth/login?provider=lifescience${returnPathQuery}`"
         class="m-2"
       >
         <img src="/src/assets/images/ls-login.png" alt="[LS Login]" />
diff --git a/src/views/admin/AdminBucketsView.vue b/src/views/admin/AdminBucketsView.vue
index 77f917a044702c6f9533b5570c91d77dae2d5887..2d471e9897509eec7901f5ca18c28797eb94b088 100644
--- a/src/views/admin/AdminBucketsView.vue
+++ b/src/views/admin/AdminBucketsView.vue
@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import { computed, reactive } from "vue";
-import { type BucketOut, BucketType } from "@/client/s3proxy";
+import { type BucketOut, BucketType } from "@/client";
 import SearchUserModal from "@/components/modals/SearchUserModal.vue";
-import type { User } from "@/client/auth";
+import type { UserOut } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { useBucketStore } from "@/stores/buckets";
 import { useNameStore } from "@/stores/names";
@@ -43,7 +43,7 @@ const filteredBuckets = computed<BucketOut[]>(() =>
   ),
 );
 
-function updateUser(user: User) {
+function updateUser(user: UserOut) {
   bucketState.ownerId = user.uid;
 }
 
diff --git a/src/views/admin/AdminResourcesView.vue b/src/views/admin/AdminResourcesView.vue
index 409ae18b0a7869ce314a9e75ec7794af3a83680c..fc8fb5a5c63124b351b93b7ff6d86d2a26cf6850 100644
--- a/src/views/admin/AdminResourcesView.vue
+++ b/src/views/admin/AdminResourcesView.vue
@@ -1,13 +1,13 @@
 <script setup lang="ts">
 import { useResourceStore } from "@/stores/resources";
 import { reactive } from "vue";
+import type { UserOut } from "@/client";
 import {
   type ResourceOut,
   type ResourceVersionOut,
-  Status,
-} from "@/client/resource";
+  ResourceVersionStatus,
+} from "@/client";
 import SearchUserModal from "@/components/modals/SearchUserModal.vue";
-import type { User } from "@/client/auth";
 import { useNameStore } from "@/stores/names";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import dayjs from "dayjs";
@@ -21,7 +21,7 @@ const resourceState = reactive<{
   resources: ResourceOut[];
   maintainerId: string;
   searchString: string;
-  resourceStatus: Status[];
+  resourceStatus: ResourceVersionStatus[];
   inspectVersionIndex: number;
   inspectResource?: ResourceOut;
   searched: boolean;
@@ -36,7 +36,7 @@ const resourceState = reactive<{
   searched: false,
 });
 
-function updateUser(user: User) {
+function updateUser(user: UserOut) {
   resourceState.maintainerId = user.uid;
 }
 
@@ -153,7 +153,10 @@ function resetForm() {
           class="form-select mb-4 w-fit"
           id="admin-resource-state-select"
         >
-          <option v-for="state in Object.values(Status)" :key="state">
+          <option
+            v-for="state in Object.values(ResourceVersionStatus)"
+            :key="state"
+          >
             {{ state }}
           </option>
         </select>
@@ -294,7 +297,12 @@ function resetForm() {
                         <span class="visually-hidden">Toggle Dropdown</span>
                       </button>
                       <ul class="dropdown-menu">
-                        <li v-if="version.status === Status.SYNCHRONIZED">
+                        <li
+                          v-if="
+                            version.status ===
+                            ResourceVersionStatus.SYNCHRONIZED
+                          "
+                        >
                           <button
                             class="dropdown-item"
                             type="button"
@@ -303,7 +311,12 @@ function resetForm() {
                             Set to Latest
                           </button>
                         </li>
-                        <li v-if="version.status === Status.WAIT_FOR_REVIEW">
+                        <li
+                          v-if="
+                            version.status ===
+                            ResourceVersionStatus.WAIT_FOR_REVIEW
+                          "
+                        >
                           <router-link
                             class="dropdown-item"
                             :to="{ name: 'resource-review' }"
@@ -311,7 +324,12 @@ function resetForm() {
                             Review Resource
                           </router-link>
                         </li>
-                        <li v-if="version.status === Status.SYNC_REQUESTED">
+                        <li
+                          v-if="
+                            version.status ===
+                            ResourceVersionStatus.SYNC_REQUESTED
+                          "
+                        >
                           <router-link
                             class="dropdown-item"
                             :to="{ name: 'admin-sync-requests' }"
@@ -321,8 +339,8 @@ function resetForm() {
                         </li>
                         <li
                           v-if="
-                            version.status === Status.APPROVED ||
-                            version.status === Status.SYNC_ERROR
+                            version.status === ResourceVersionStatus.APPROVED ||
+                            version.status === ResourceVersionStatus.SYNC_ERROR
                           "
                         >
                           <button
@@ -338,9 +356,11 @@ function resetForm() {
                         </li>
                         <li
                           v-if="
-                            version.status === Status.SYNCHRONIZED ||
-                            version.status === Status.CLUSTER_DELETE_ERROR ||
-                            version.status === Status.LATEST
+                            version.status ===
+                              ResourceVersionStatus.SYNCHRONIZED ||
+                            version.status ===
+                              ResourceVersionStatus.CLUSTER_DELETE_ERROR ||
+                            version.status === ResourceVersionStatus.LATEST
                           "
                         >
                           <button
@@ -354,9 +374,10 @@ function resetForm() {
                         </li>
                         <li
                           v-if="
-                            version.status === Status.APPROVED ||
-                            version.status === Status.S3_DELETE_ERROR ||
-                            version.status === Status.DENIED
+                            version.status === ResourceVersionStatus.APPROVED ||
+                            version.status ===
+                              ResourceVersionStatus.S3_DELETE_ERROR ||
+                            version.status === ResourceVersionStatus.DENIED
                           "
                         >
                           <button
diff --git a/src/views/admin/AdminSyncRequestsView.vue b/src/views/admin/AdminSyncRequestsView.vue
index bb7c0f6e7c94d8c3497d06196fa4b67e849e19d0..9981f2d9316533a67a09fd328d0ec31f9d3611c4 100644
--- a/src/views/admin/AdminSyncRequestsView.vue
+++ b/src/views/admin/AdminSyncRequestsView.vue
@@ -6,9 +6,9 @@ import { onMounted, reactive } from "vue";
 import {
   type ResourceOut,
   type ResourceVersionOut,
-  Status,
+  ResourceVersionStatus,
   type UserSynchronizationRequestOut,
-} from "@/client/resource";
+} from "@/client";
 import { useResourceStore } from "@/stores/resources";
 import { useNameStore } from "@/stores/names";
 import { useAuthStore } from "@/stores/users";
@@ -69,7 +69,7 @@ function syncVersion(resourceId: string, resourceVersionId: string) {
         created_at: 0,
         s3_path: "",
         cluster_path: "",
-        status: Status.SYNC_REQUESTED,
+        status: ResourceVersionStatus.SYNC_REQUESTED,
       },
       { deny: false },
     )
@@ -88,7 +88,7 @@ function fetchResources(
   return Promise.all(
     syncRequests.map((request) =>
       resourceRepository.fetchResource(request.resource_id, [
-        Status.SYNC_REQUESTED,
+        ResourceVersionStatus.SYNC_REQUESTED,
       ]),
     ),
   );
diff --git a/src/views/admin/AdminUsersView.vue b/src/views/admin/AdminUsersView.vue
index 34df43a3486840b63b056c42d8f1c196f4889e5b..8dbe2dccf280c14a0884e000ccfa0f1b105380b9 100644
--- a/src/views/admin/AdminUsersView.vue
+++ b/src/views/admin/AdminUsersView.vue
@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import { useAuthStore } from "@/stores/users";
 import { reactive } from "vue";
-import { RoleEnum, type User } from "@/client/auth";
+import { RoleEnum, type UserOutExtended } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import UserRoleMark from "@/components/admin/UserRoleMark.vue";
 
@@ -9,10 +9,10 @@ const userRepository = useAuthStore();
 
 const userState = reactive<{
   loading: boolean;
-  users: User[];
+  users: UserOutExtended[];
   searchString: string;
   userRoles: RoleEnum[];
-  inspectUser?: User;
+  inspectUser?: UserOutExtended;
   searched: boolean;
 }>({
   loading: false,
@@ -29,7 +29,6 @@ function searchUsers() {
     .fetchUsers(
       userState.searchString ? userState.searchString : undefined,
       userState.userRoles ? userState.userRoles : undefined,
-      true,
     )
     .then((users) => {
       userState.users = users;
diff --git a/src/views/object-storage/BucketsView.vue b/src/views/object-storage/BucketsView.vue
index 1781a606aa1eeadabf61cc9333c9009d17a312e9..69ea504715bf281b43b1d662ee3eb9a64ca42a06 100644
--- a/src/views/object-storage/BucketsView.vue
+++ b/src/views/object-storage/BucketsView.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive } from "vue";
-import type { BucketOut } from "@/client/s3proxy";
+import type { BucketOut } from "@/client";
 import { useRouter } from "vue-router";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import CreateBucketModal from "@/components/object-storage/modals/CreateBucketModal.vue";
diff --git a/src/views/object-storage/S3KeyView.vue b/src/views/object-storage/S3KeyView.vue
index 2f1b23cee9620d75d14911f908bae48b64e44a22..033d41ceca7ae18b6a495d4517be3f1ea6324675 100644
--- a/src/views/object-storage/S3KeyView.vue
+++ b/src/views/object-storage/S3KeyView.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { S3Key } from "@/client/s3proxy";
+import type { S3Key } from "@/client";
 import { reactive, watch } from "vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import DeleteModal from "@/components/modals/DeleteModal.vue";
diff --git a/src/views/resources/ListResourcesView.vue b/src/views/resources/ListResourcesView.vue
index 86bbaaada79262d54633b3af61fde49926e8dbb9..094ebfd84c4db9a477edfb672fbcf859ff441b87 100644
--- a/src/views/resources/ListResourcesView.vue
+++ b/src/views/resources/ListResourcesView.vue
@@ -5,7 +5,7 @@ import ResourceCard from "@/components/resources/ResourceCard.vue";
 import CardTransitionGroup from "@/components/transitions/CardTransitionGroup.vue";
 import { useAuthStore } from "@/stores/users";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import type { ResourceOut, ResourceVersionOut } from "@/client/resource";
+import type { ResourceOut, ResourceVersionOut } from "@/client";
 import ReasonModal from "@/components/modals/ReasonModal.vue";
 import { Modal, Toast } from "bootstrap";
 import BootstrapToast from "@/components/BootstrapToast.vue";
@@ -76,7 +76,11 @@ onMounted(() => {
       resourceState.loading = false;
     })
     .then((resources) => {
-      userRepository.fetchUsernames(resources.map((r) => r.maintainer_id));
+      userRepository.fetchUsernames(
+        resources
+          .map((r) => r.maintainer_id ?? "")
+          .filter((mid) => mid.length > 0),
+      );
     });
 });
 </script>
diff --git a/src/views/resources/MyResourcesView.vue b/src/views/resources/MyResourcesView.vue
index 227cd378c70601ea4f768d8f03436cf62c620767..679b880dd3d93285b97619dd9cb9707ad78e1db4 100644
--- a/src/views/resources/MyResourcesView.vue
+++ b/src/views/resources/MyResourcesView.vue
@@ -6,7 +6,7 @@ import ResourceCard from "@/components/resources/ResourceCard.vue";
 import CreateResourceModal from "@/components/resources/modals/CreateResourceModal.vue";
 import UploadResourceInfoModal from "@/components/resources/modals/UploadResourceInfoModal.vue";
 import { useS3KeyStore } from "@/stores/s3keys";
-import type { ResourceVersionOut, ResourceOut } from "@/client/resource";
+import type { ResourceVersionOut, ResourceOut } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import UpdateResourceModal from "@/components/resources/modals/UpdateResourceModal.vue";
 import ReasonModal from "@/components/modals/ReasonModal.vue";
diff --git a/src/views/resources/ReviewResourceView.vue b/src/views/resources/ReviewResourceView.vue
index a649029dad791945dc975f4031c0d25aae4e71cf..61da4124bb1183717d5c3ae88cedd155bd465216 100644
--- a/src/views/resources/ReviewResourceView.vue
+++ b/src/views/resources/ReviewResourceView.vue
@@ -4,8 +4,8 @@ import { computed, onMounted, reactive } from "vue";
 import {
   type ResourceOut,
   type ResourceVersionOut,
-  Status,
-} from "@/client/resource";
+  ResourceVersionStatus,
+} from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { Modal, Toast, Tooltip } from "bootstrap";
 import ResourceVersionInfoModal from "@/components/resources/modals/ResourceVersionInfoModal.vue";
@@ -194,7 +194,7 @@ onMounted(() => {
           </th>
           <th class="text-end">
             <div
-              v-if="version.status === Status.WAIT_FOR_REVIEW"
+              v-if="version.status === ResourceVersionStatus.WAIT_FOR_REVIEW"
               class="btn-group"
             >
               <button
@@ -217,7 +217,7 @@ onMounted(() => {
               </button>
             </div>
             <div
-              v-else-if="version.status === Status.SYNCHRONIZING"
+              v-else-if="version.status === ResourceVersionStatus.SYNCHRONIZING"
               class="progress"
               role="progressbar"
               aria-label="Animated striped example"
diff --git a/src/views/workflows/ArbitraryWorkflowView.vue b/src/views/workflows/ArbitraryWorkflowView.vue
index afd957546d2af26e272d6be3360ca5a79d4b398a..665ab1c9c1336c76b4e30baf65031c438f4c8bc1 100644
--- a/src/views/workflows/ArbitraryWorkflowView.vue
+++ b/src/views/workflows/ArbitraryWorkflowView.vue
@@ -7,7 +7,7 @@ import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { useRouter } from "vue-router";
 import { Toast } from "bootstrap";
 import { useWorkflowStore } from "@/stores/workflows";
-import type { WorkflowIn } from "@/client/workflow";
+import type { WorkflowIn } from "@/client";
 import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
 import ParameterSchemaFormComponent from "@/components/parameter-schema/ParameterSchemaFormComponent.vue";
 import BootstrapToast from "@/components/BootstrapToast.vue";
diff --git a/src/views/workflows/CreateClowmInfoView.vue b/src/views/workflows/CreateClowmInfoView.vue
index a709e7d571208aa30a0fdf4a905f4eb4bec9dff2..ec50dc22d3376952689d8fa474dc86cc414e983f 100644
--- a/src/views/workflows/CreateClowmInfoView.vue
+++ b/src/views/workflows/CreateClowmInfoView.vue
@@ -5,7 +5,7 @@ import { createDownloadUrl } from "@/utils/DownloadJson";
 import type { ClowmInfo } from "@/types/ClowmInfo";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { useWorkflowStore } from "@/stores/workflows";
-import { DocumentationEnum } from "@/client/workflow";
+import { DocumentationEnum } from "@/client";
 import DraggableLists from "@/components/DraggableLists.vue";
 import ParameterInput from "@/components/parameter-schema/form-mode/ParameterInput.vue";
 
diff --git a/src/views/workflows/CreateParameterTranslationView.vue b/src/views/workflows/CreateParameterTranslationView.vue
index fcc3083fe52935160a8539af1764baad5c96544b..7f9a104cef8e3e2fad950700732b128b73d5e66f 100644
--- a/src/views/workflows/CreateParameterTranslationView.vue
+++ b/src/views/workflows/CreateParameterTranslationView.vue
@@ -2,7 +2,7 @@
 import { useNameStore } from "@/stores/names";
 import { useWorkflowStore } from "@/stores/workflows";
 import { computed, onMounted, reactive, ref, watch } from "vue";
-import { DocumentationEnum, type ParameterExtension } from "@/client/workflow";
+import { DocumentationEnum, type ParameterExtension } from "@/client";
 import type { ClowmInfo } from "@/types/ClowmInfo";
 import ParameterInput from "@/components/parameter-schema/form-mode/ParameterInput.vue";
 import BootstrapToast from "@/components/BootstrapToast.vue";
diff --git a/src/views/workflows/ListWorkflowExecutionsView.vue b/src/views/workflows/ListWorkflowExecutionsView.vue
index bdb0999bac7bd3b7ebb274ea48e27cca9e7b6b30..7aa6bbc953508d1fc40c9e37f75f3c5ea769c13d 100644
--- a/src/views/workflows/ListWorkflowExecutionsView.vue
+++ b/src/views/workflows/ListWorkflowExecutionsView.vue
@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { onMounted, reactive, computed, onUnmounted } from "vue";
-import type { WorkflowExecutionOut } from "@/client/workflow";
+import type { WorkflowExecutionOut } from "@/client";
 import dayjs from "dayjs";
 import { Tooltip } from "bootstrap";
 import DeleteModal from "@/components/modals/DeleteModal.vue";
diff --git a/src/views/workflows/ListWorkflowsView.vue b/src/views/workflows/ListWorkflowsView.vue
index 3316af5eeae702dc950b8af8d879e1deabafa9d1..d6167b396b94758200311c9e65cca1191ae0a9fc 100644
--- a/src/views/workflows/ListWorkflowsView.vue
+++ b/src/views/workflows/ListWorkflowsView.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive } from "vue";
-import type { WorkflowOut } from "@/client/workflow";
+import type { WorkflowOut } from "@/client";
 import WorkflowCard from "@/components/workflows/WorkflowCard.vue";
 import CardTransitionGroup from "@/components/transitions/CardTransitionGroup.vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
diff --git a/src/views/workflows/MyWorkflowsView.vue b/src/views/workflows/MyWorkflowsView.vue
index 513a18d61612882987b6f3cdf133fe6522bd26be..4f12f2e3eccad54ee9d738af27e0fccec1e2005b 100644
--- a/src/views/workflows/MyWorkflowsView.vue
+++ b/src/views/workflows/MyWorkflowsView.vue
@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive } from "vue";
-import type { WorkflowOut, WorkflowVersion } from "@/client/workflow";
-import { Status } from "@/client/workflow";
+import type { WorkflowOut, WorkflowVersion } from "@/client";
+import { WorkflowVersionStatus } from "@/client";
 import WorkflowWithVersionsCard from "@/components/workflows/WorkflowWithVersionsCard.vue";
 import CreateWorkflowModal from "@/components/workflows/modals/CreateWorkflowModal.vue";
 import CardTransitionGroup from "@/components/transitions/CardTransitionGroup.vue";
@@ -31,7 +31,7 @@ const workflowsState = reactive<{
         version: "1.0.0",
         created_at: 0,
         workflow_version_id: "",
-        status: Status.CREATED,
+        status: WorkflowVersionStatus.CREATED,
         workflow_id: "",
         icon_url: "",
         modes: [],
@@ -49,7 +49,7 @@ const workflowsState = reactive<{
     modes: [],
     icon_url: null,
     created_at: 0,
-    status: Status.CREATED,
+    status: WorkflowVersionStatus.CREATED,
   },
 });
 
diff --git a/src/views/workflows/ReviewWorkflowsView.vue b/src/views/workflows/ReviewWorkflowsView.vue
index e8420b3969f3ac3e89ec203a15332c61eef1d4de..063873af59de91e7db5081f2adc227821346c21f 100644
--- a/src/views/workflows/ReviewWorkflowsView.vue
+++ b/src/views/workflows/ReviewWorkflowsView.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { onMounted, reactive } from "vue";
-import { Status } from "@/client/workflow";
+import { WorkflowVersionStatus } from "@/client";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { determineGitIcon } from "@/utils/GitRepository";
 import { sortedVersions } from "@/utils/Workflow";
@@ -25,7 +25,7 @@ const workflowsState = reactive<{
 function updateWorkflowVersionStatus(
   workflow_id: string,
   git_commit_hash: string,
-  new_status: Status,
+  new_status: WorkflowVersionStatus,
 ) {
   workflowsState.versionUpdateLoading = git_commit_hash;
   workflowRepository
@@ -51,7 +51,10 @@ onMounted(() => {
       }, 1000);
       return workflows;
     })
-    .then((workflows) => workflows.map((workflow) => workflow.developer_id))
+    .then((workflows) =>
+      workflows.map((workflow) => workflow.developer_id ?? ""),
+    )
+    .then((developer_ids) => developer_ids.filter((did) => did.length > 0))
     .then(userRepository.fetchUsernames);
 });
 </script>
@@ -174,19 +177,31 @@ onMounted(() => {
                     >
                       <span class="visually-hidden">Loading...</span>
                     </div>
-                    <div v-else-if="version.status === Status.PUBLISHED">
+                    <div
+                      v-else-if="
+                        version.status === WorkflowVersionStatus.PUBLISHED
+                      "
+                    >
                       <font-awesome-icon
                         icon="fa-solid fa-circle-check"
                         class="text-success"
                       />
                     </div>
-                    <div v-else-if="version.status === Status.DENIED">
+                    <div
+                      v-else-if="
+                        version.status === WorkflowVersionStatus.DENIED
+                      "
+                    >
                       <font-awesome-icon
                         icon="fa-solid fa-x"
                         class="text-danger"
                       />
                     </div>
-                    <div v-else-if="version.status === Status.DEPRECATED">
+                    <div
+                      v-else-if="
+                        version.status === WorkflowVersionStatus.DEPRECATED
+                      "
+                    >
                       <font-awesome-icon
                         icon="fa-solid fa-archive"
                         class="text-warning"
@@ -200,7 +215,7 @@ onMounted(() => {
                           updateWorkflowVersionStatus(
                             workflow.workflow_id,
                             version.workflow_version_id,
-                            Status.PUBLISHED,
+                            WorkflowVersionStatus.PUBLISHED,
                           )
                         "
                       >
@@ -213,7 +228,7 @@ onMounted(() => {
                           updateWorkflowVersionStatus(
                             workflow.workflow_id,
                             version.workflow_version_id,
-                            Status.DENIED,
+                            WorkflowVersionStatus.DENIED,
                           )
                         "
                       >
diff --git a/src/views/workflows/StartWorkflowView.vue b/src/views/workflows/StartWorkflowView.vue
index ee6c3cf5081199f6d24c019038c9f365e755bdd3..84612546ef51419895d1f689d41a3ee7eec06ccc 100644
--- a/src/views/workflows/StartWorkflowView.vue
+++ b/src/views/workflows/StartWorkflowView.vue
@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import ParameterSchemaFormComponent from "@/components/parameter-schema/ParameterSchemaFormComponent.vue";
-import type { WorkflowVersion } from "@/client/workflow";
-import { ApiError, DocumentationEnum } from "@/client/workflow";
+import type { WorkflowVersion } from "@/client";
+import { ApiError, DocumentationEnum } from "@/client";
 import { onMounted, reactive, watch } from "vue";
 import { useRouter } from "vue-router";
 import { Toast } from "bootstrap";
diff --git a/src/views/workflows/WorkflowVersionView.vue b/src/views/workflows/WorkflowVersionView.vue
index b130b670521c1d3521b76ca74c56824a02802f69..4d01da538dcdbfa5bcb22b81e1430ea14f7f65cd 100644
--- a/src/views/workflows/WorkflowVersionView.vue
+++ b/src/views/workflows/WorkflowVersionView.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { onMounted, reactive, watch } from "vue";
-import { DocumentationEnum } from "@/client/workflow";
+import { DocumentationEnum } from "@/client";
 import WorkflowDocumentationTabs from "@/components/workflows/WorkflowDocumentationTabs.vue";
 import { useWorkflowStore } from "@/stores/workflows";
 
diff --git a/src/views/workflows/WorkflowView.vue b/src/views/workflows/WorkflowView.vue
index 89bb7a07056b570364b1f215d5d1d717aef063c5..a60bd37c387d7ab6ea014b79bcc1d9dd1c8afb38 100644
--- a/src/views/workflows/WorkflowView.vue
+++ b/src/views/workflows/WorkflowView.vue
@@ -1,11 +1,7 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive, watch } from "vue";
-import type {
-  WorkflowOut,
-  WorkflowStatistic,
-  WorkflowVersion,
-} from "@/client/workflow";
-import { Status, WorkflowService } from "@/client/workflow";
+import type { WorkflowOut, WorkflowStatistic, WorkflowVersion } from "@/client";
+import { WorkflowVersionStatus, WorkflowService } from "@/client";
 import WorkflowStatisticsChart from "@/components/workflows/WorkflowStatisticsChart.vue";
 import { useRoute, useRouter } from "vue-router";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
@@ -70,7 +66,7 @@ const workflow = computed<WorkflowOut | undefined>(() =>
 const latestVersion = computed<WorkflowVersion | undefined>(() =>
   calculateLatestVersion(
     workflow.value?.versions?.filter(
-      (version) => version.status == Status.PUBLISHED,
+      (version) => version.status == WorkflowVersionStatus.PUBLISHED,
     ) || [],
   ),
 );
@@ -93,7 +89,7 @@ const activeVersionIcon = computed<string | undefined>(
 );
 
 const versionLaunchable = computed<boolean>(
-  () => activeVersion.value?.status == Status.PUBLISHED,
+  () => activeVersion.value?.status == WorkflowVersionStatus.PUBLISHED,
 );
 
 const gitIcon = computed<string>(() =>
@@ -101,7 +97,7 @@ const gitIcon = computed<string>(() =>
 );
 
 const allowVersionDeprecation = computed<boolean>(() => {
-  if (activeVersion.value?.status === Status.PUBLISHED) {
+  if (activeVersion.value?.status === WorkflowVersionStatus.PUBLISHED) {
     if (userRepository.rewiewer || userRepository.admin) {
       return true;
     } else if (
@@ -135,7 +131,9 @@ function updateWorkflow(workflowId: string) {
       workflowState.initialOpen = false;
     })
     .then((workflow) => {
-      userRepository.fetchUsernames([workflow.developer_id]);
+      if (workflow.developer_id) {
+        userRepository.fetchUsernames([workflow.developer_id]);
+      }
       return workflow;
     })
     .then((workflow) => {