From d689bb5e5a9579488f53c03e11a7ae263267241e Mon Sep 17 00:00:00 2001
From: Steve Reis <stevereis93@gmail.com>
Date: Thu, 2 Jun 2022 07:10:57 +0000
Subject: [PATCH] feat: Possibility to save experiments locally

---
 api/ormconfig.ts                              |   4 +-
 api/package-lock.json                         | 974 ++++++++----------
 api/package.json                              |  11 +-
 api/src/auth/auth.module.ts                   |   2 +
 api/src/auth/auth.resolver.spec.ts            |   4 +-
 api/src/auth/auth.resolver.ts                 |  12 +-
 api/src/auth/auth.service.ts                  |   2 +-
 api/src/auth/decorators/user.decorator.ts     |  14 -
 ...jwt-auth.guard.ts => global-auth.guard.ts} |  14 +-
 api/src/auth/strategies/engine.strategy.ts    |  22 +
 api/src/common/decorators/user.decorator.ts   |   2 +-
 .../engine/connectors/csv/main.connector.ts   |  66 +-
 .../connectors/datashield/main.connector.ts   |  45 +-
 .../engine/connectors/exareme/converters.ts   |  13 +-
 .../exareme/interfaces/test-utilities.ts      |   4 +-
 .../connectors/exareme/main.connector.ts      |  39 +-
 .../exareme/tests/e2e/3c.e2e-spec.ts          |   2 +-
 .../tests/e2e/calibration-belt.e2e-spec.ts    |   2 +-
 .../exareme/tests/e2e/cart.e2e-spec.ts        |   2 +-
 .../e2e/descriptiveStatistics.e2e-spec.ts     |   2 +-
 .../exareme/tests/e2e/id3.e2e-spec.ts         |   2 +-
 .../exareme/tests/e2e/k-means.e2e-spec.ts     |   2 +-
 .../tests/e2e/kaplan-meier.e2e-spec.ts        |   2 +-
 .../tests/e2e/linear-regression.e2e-spec.ts   |   2 +-
 .../tests/e2e/logistic-regression.e2e-spec.ts |   2 +-
 .../tests/e2e/multiple-histograms.e2e-spec.ts |   2 +-
 .../exareme/tests/e2e/naive-bayes.e2e-spec.ts |   2 +-
 .../tests/e2e/one-way-anova.e2e-spec.ts       |   2 +-
 .../exareme/tests/e2e/pca.e2e-spec.ts         |   2 +-
 .../tests/e2e/pearson-correlation.e2e-spec.ts |   2 +-
 .../tests/e2e/t-test-independant.e2e-spec.ts  |   2 +-
 .../tests/e2e/t-test-one-sample.e2e-spec.ts   |   2 +-
 .../tests/e2e/t-test-paired.e2e-spec.ts       |   2 +-
 .../tests/e2e/two-way-anova.e2e-spec.ts       |   2 +-
 .../connectors/exareme/transformations.ts     |  12 +-
 .../engine/connectors/local/main.connector.ts |  39 +-
 api/src/engine/engine.interfaces.ts           |  80 +-
 api/src/engine/engine.module.ts               |  36 +-
 api/src/engine/engine.resolver.ts             |  70 +-
 .../models/experiment/experiment.model.ts     |  53 +-
 .../experiment/list-experiments.model.ts      |   2 +-
 .../experiments/dto/experiment-update.dto.ts  |   3 +
 api/src/experiments/experiments.module.ts     |  11 +
 .../experiments/experiments.resolver.spec.ts  | 248 +++++
 api/src/experiments/experiments.resolver.ts   | 137 +++
 .../experiments/experiments.service.spec.ts   | 184 ++++
 api/src/experiments/experiments.service.ts    | 145 +++
 .../input/algorithm-parameter.input.ts        |   0
 .../models}/input/algorithm.input.ts          |   0
 .../models}/input/experiment-create.input.ts  |   0
 .../models}/input/experiment-edit.input.ts    |   0
 .../models/input/pagination-args.input.ts     |  10 +
 api/src/main/app.module.ts                    |   2 +
 .../1653484967792-CreateExperimentDB.ts       |  19 +
 .../1653487335545-ExperimentDateTypeUpdate.ts |  29 +
 api/src/schema.gql                            |  54 +-
 api/src/users/users.resolver.ts               |   8 +-
 api/src/users/users.service.ts                |   2 +-
 58 files changed, 1509 insertions(+), 899 deletions(-)
 delete mode 100644 api/src/auth/decorators/user.decorator.ts
 rename api/src/auth/guards/{jwt-auth.guard.ts => global-auth.guard.ts} (73%)
 create mode 100644 api/src/auth/strategies/engine.strategy.ts
 create mode 100644 api/src/experiments/dto/experiment-update.dto.ts
 create mode 100644 api/src/experiments/experiments.module.ts
 create mode 100644 api/src/experiments/experiments.resolver.spec.ts
 create mode 100644 api/src/experiments/experiments.resolver.ts
 create mode 100644 api/src/experiments/experiments.service.spec.ts
 create mode 100644 api/src/experiments/experiments.service.ts
 rename api/src/{engine/models/experiment => experiments/models}/input/algorithm-parameter.input.ts (100%)
 rename api/src/{engine/models/experiment => experiments/models}/input/algorithm.input.ts (100%)
 rename api/src/{engine/models/experiment => experiments/models}/input/experiment-create.input.ts (100%)
 rename api/src/{engine/models/experiment => experiments/models}/input/experiment-edit.input.ts (100%)
 create mode 100644 api/src/experiments/models/input/pagination-args.input.ts
 create mode 100644 api/src/migrations/1653484967792-CreateExperimentDB.ts
 create mode 100644 api/src/migrations/1653487335545-ExperimentDateTypeUpdate.ts

diff --git a/api/ormconfig.ts b/api/ormconfig.ts
index 27afa05..c4d8d9f 100644
--- a/api/ormconfig.ts
+++ b/api/ormconfig.ts
@@ -7,7 +7,7 @@ ConfigModule.forRoot({
   load: [dbConfiguration],
 });
 
-const config = {
+const ormconfig = {
   ...dbConfiguration(),
   entities: ['dist/**/*.entity.js', 'dist/**/*.model.js'],
   migrations: ['dist/migrations/*{.ts,.js}'],
@@ -17,4 +17,4 @@ const config = {
   },
 };
 
-export default config;
+export default ormconfig;
diff --git a/api/package-lock.json b/api/package-lock.json
index a7e5df0..39f229d 100644
--- a/api/package-lock.json
+++ b/api/package-lock.json
@@ -26,6 +26,7 @@
         "graphql-type-json": "^0.3.2",
         "jsonata": "^1.8.5",
         "passport": "^0.5.2",
+        "passport-custom": "^1.1.1",
         "passport-jwt": "^4.0.0",
         "passport-local": "^1.0.0",
         "pg": "^8.7.3",
@@ -145,16 +146,16 @@
       }
     },
     "node_modules/@angular-devkit/schematics-cli": {
-      "version": "13.2.5",
-      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-13.2.5.tgz",
-      "integrity": "sha512-/3Q1+wtE+l5XXoXX/7157yh4Wpi+FNEryx5gDcfPJchgtovxj28nzquD0vXnvpyr3Wd8OaMwg6vW4EfL82jRKg==",
+      "version": "13.3.5",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-13.3.5.tgz",
+      "integrity": "sha512-ARX20ebtfwzef8GdXIcB6uv0sjTsaEniZyXBFchEKD6kR5EYZVaBL+ZVUbmsU1d0XY///WzW7pqwCyu5H1u+vw==",
       "dev": true,
       "dependencies": {
-        "@angular-devkit/core": "13.2.5",
-        "@angular-devkit/schematics": "13.2.5",
+        "@angular-devkit/core": "13.3.5",
+        "@angular-devkit/schematics": "13.3.5",
         "ansi-colors": "4.1.1",
         "inquirer": "8.2.0",
-        "minimist": "1.2.5",
+        "minimist": "1.2.6",
         "symbol-observable": "4.0.0"
       },
       "bin": {
@@ -166,6 +167,75 @@
         "yarn": ">= 1.13.0"
       }
     },
+    "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/core": {
+      "version": "13.3.5",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.5.tgz",
+      "integrity": "sha512-w7vzK4VoYP9rLgxJ2SwEfrkpKybdD+QgQZlsDBzT0C6Ebp7b4gkNcNVFo8EiZvfDl6Yplw2IAP7g7fs3STn0hQ==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "8.9.0",
+        "ajv-formats": "2.1.1",
+        "fast-json-stable-stringify": "2.1.0",
+        "magic-string": "0.25.7",
+        "rxjs": "6.6.7",
+        "source-map": "0.7.3"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.15.0 || >=16.10.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "chokidar": "^3.5.2"
+      },
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/core/node_modules/rxjs": {
+      "version": "6.6.7",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^1.9.0"
+      },
+      "engines": {
+        "npm": ">=2.0.0"
+      }
+    },
+    "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/schematics": {
+      "version": "13.3.5",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.5.tgz",
+      "integrity": "sha512-0N/kL/Vfx0yVAEwa3HYxNx9wYb+G9r1JrLjJQQzDp+z9LtcojNf7j3oey6NXrDUs1WjVZOa/AIdRl3/DuaoG5w==",
+      "dev": true,
+      "dependencies": {
+        "@angular-devkit/core": "13.3.5",
+        "jsonc-parser": "3.0.0",
+        "magic-string": "0.25.7",
+        "ora": "5.4.1",
+        "rxjs": "6.6.7"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.15.0 || >=16.10.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      }
+    },
+    "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/schematics/node_modules/rxjs": {
+      "version": "6.6.7",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^1.9.0"
+      },
+      "engines": {
+        "npm": ">=2.0.0"
+      }
+    },
     "node_modules/@angular-devkit/schematics-cli/node_modules/chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -207,6 +277,12 @@
         "node": ">=8.0.0"
       }
     },
+    "node_modules/@angular-devkit/schematics-cli/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+      "dev": true
+    },
     "node_modules/@angular-devkit/schematics/node_modules/rxjs": {
       "version": "6.6.7",
       "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
@@ -883,6 +959,16 @@
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
       "dev": true
     },
+    "node_modules/@colors/colors": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+      "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
     "node_modules/@cspotcode/source-map-consumer": {
       "version": "0.8.0",
       "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
@@ -1514,20 +1600,20 @@
       }
     },
     "node_modules/@nestjs/cli": {
-      "version": "8.2.2",
-      "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.2.tgz",
-      "integrity": "sha512-ZonmNLCHfTVrZGgYf4mrpivnKGaRzVRAcux+WDbzhQDNIz70s7mdOPShXW1Vpq+7uRJDxlgO1vOMhmg4uEUIDg==",
+      "version": "8.2.6",
+      "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.6.tgz",
+      "integrity": "sha512-uvwKbUZJmgdJu1D24e+uUqHnwoB/0R9hLfUJjr5pTvLlP/RJugHAdJr7m1dQe92Xzdyi36kBN4Id3RXHgfz1UA==",
       "dev": true,
       "dependencies": {
-        "@angular-devkit/core": "13.2.5",
-        "@angular-devkit/schematics": "13.2.5",
-        "@angular-devkit/schematics-cli": "13.2.5",
+        "@angular-devkit/core": "13.3.5",
+        "@angular-devkit/schematics": "13.3.5",
+        "@angular-devkit/schematics-cli": "13.3.5",
         "@nestjs/schematics": "^8.0.3",
         "chalk": "3.0.0",
         "chokidar": "3.5.3",
-        "cli-table3": "0.6.1",
+        "cli-table3": "0.6.2",
         "commander": "4.1.1",
-        "fork-ts-checker-webpack-plugin": "7.2.1",
+        "fork-ts-checker-webpack-plugin": "7.2.11",
         "inquirer": "7.3.3",
         "node-emoji": "1.11.0",
         "ora": "5.4.1",
@@ -1536,10 +1622,10 @@
         "shelljs": "0.8.5",
         "source-map-support": "0.5.21",
         "tree-kill": "1.2.2",
-        "tsconfig-paths": "3.12.0",
+        "tsconfig-paths": "3.14.1",
         "tsconfig-paths-webpack-plugin": "3.5.2",
-        "typescript": "4.6.2",
-        "webpack": "5.66.0",
+        "typescript": "4.6.4",
+        "webpack": "5.72.1",
         "webpack-node-externals": "3.0.0"
       },
       "bin": {
@@ -1550,162 +1636,69 @@
         "npm": ">= 6.11.0"
       }
     },
-    "node_modules/@nestjs/cli/node_modules/@types/estree": {
-      "version": "0.0.50",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
-      "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
-      "dev": true
-    },
-    "node_modules/@nestjs/cli/node_modules/acorn": {
-      "version": "8.7.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
-      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+    "node_modules/@nestjs/cli/node_modules/@angular-devkit/core": {
+      "version": "13.3.5",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.5.tgz",
+      "integrity": "sha512-w7vzK4VoYP9rLgxJ2SwEfrkpKybdD+QgQZlsDBzT0C6Ebp7b4gkNcNVFo8EiZvfDl6Yplw2IAP7g7fs3STn0hQ==",
       "dev": true,
-      "bin": {
-        "acorn": "bin/acorn"
+      "dependencies": {
+        "ajv": "8.9.0",
+        "ajv-formats": "2.1.1",
+        "fast-json-stable-stringify": "2.1.0",
+        "magic-string": "0.25.7",
+        "rxjs": "6.6.7",
+        "source-map": "0.7.3"
       },
       "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/@nestjs/cli/node_modules/acorn-import-assertions": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
-      "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
-      "dev": true,
-      "peerDependencies": {
-        "acorn": "^8"
-      }
-    },
-    "node_modules/@nestjs/cli/node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
+        "node": "^12.20.0 || ^14.15.0 || >=16.10.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
       },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/@nestjs/cli/node_modules/ajv-keywords": {
-      "version": "3.5.2",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
-      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-      "dev": true,
       "peerDependencies": {
-        "ajv": "^6.9.1"
-      }
-    },
-    "node_modules/@nestjs/cli/node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "node_modules/@nestjs/cli/node_modules/json5": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
-      "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
-      "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.0"
+        "chokidar": "^3.5.2"
       },
-      "bin": {
-        "json5": "lib/cli.js"
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
       }
     },
-    "node_modules/@nestjs/cli/node_modules/schema-utils": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+    "node_modules/@nestjs/cli/node_modules/@angular-devkit/schematics": {
+      "version": "13.3.5",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.5.tgz",
+      "integrity": "sha512-0N/kL/Vfx0yVAEwa3HYxNx9wYb+G9r1JrLjJQQzDp+z9LtcojNf7j3oey6NXrDUs1WjVZOa/AIdRl3/DuaoG5w==",
       "dev": true,
       "dependencies": {
-        "@types/json-schema": "^7.0.8",
-        "ajv": "^6.12.5",
-        "ajv-keywords": "^3.5.2"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
+        "@angular-devkit/core": "13.3.5",
+        "jsonc-parser": "3.0.0",
+        "magic-string": "0.25.7",
+        "ora": "5.4.1",
+        "rxjs": "6.6.7"
       },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
-    "node_modules/@nestjs/cli/node_modules/strip-bom": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-      "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
-      "dev": true,
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/@nestjs/cli/node_modules/tsconfig-paths": {
-      "version": "3.12.0",
-      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
-      "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
-      "dev": true,
-      "dependencies": {
-        "@types/json5": "^0.0.29",
-        "json5": "^1.0.1",
-        "minimist": "^1.2.0",
-        "strip-bom": "^3.0.0"
+        "node": "^12.20.0 || ^14.15.0 || >=16.10.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
       }
     },
-    "node_modules/@nestjs/cli/node_modules/webpack": {
-      "version": "5.66.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.66.0.tgz",
-      "integrity": "sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg==",
+    "node_modules/@nestjs/cli/node_modules/rxjs": {
+      "version": "6.6.7",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
       "dev": true,
       "dependencies": {
-        "@types/eslint-scope": "^3.7.0",
-        "@types/estree": "^0.0.50",
-        "@webassemblyjs/ast": "1.11.1",
-        "@webassemblyjs/wasm-edit": "1.11.1",
-        "@webassemblyjs/wasm-parser": "1.11.1",
-        "acorn": "^8.4.1",
-        "acorn-import-assertions": "^1.7.6",
-        "browserslist": "^4.14.5",
-        "chrome-trace-event": "^1.0.2",
-        "enhanced-resolve": "^5.8.3",
-        "es-module-lexer": "^0.9.0",
-        "eslint-scope": "5.1.1",
-        "events": "^3.2.0",
-        "glob-to-regexp": "^0.4.1",
-        "graceful-fs": "^4.2.9",
-        "json-parse-better-errors": "^1.0.2",
-        "loader-runner": "^4.2.0",
-        "mime-types": "^2.1.27",
-        "neo-async": "^2.6.2",
-        "schema-utils": "^3.1.0",
-        "tapable": "^2.1.1",
-        "terser-webpack-plugin": "^5.1.3",
-        "watchpack": "^2.3.1",
-        "webpack-sources": "^3.2.2"
-      },
-      "bin": {
-        "webpack": "bin/webpack.js"
+        "tslib": "^1.9.0"
       },
       "engines": {
-        "node": ">=10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      },
-      "peerDependenciesMeta": {
-        "webpack-cli": {
-          "optional": true
-        }
+        "npm": ">=2.0.0"
       }
     },
+    "node_modules/@nestjs/cli/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+      "dev": true
+    },
     "node_modules/@nestjs/common": {
       "version": "8.4.0",
       "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-8.4.0.tgz",
@@ -3335,18 +3328,6 @@
         }
       }
     },
-    "node_modules/ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3"
-      },
-      "peerDependencies": {
-        "ajv": "^8.8.2"
-      }
-    },
     "node_modules/ansi-colors": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -4340,9 +4321,9 @@
       }
     },
     "node_modules/cli-table3": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz",
-      "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==",
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz",
+      "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==",
       "dev": true,
       "dependencies": {
         "string-width": "^4.2.0"
@@ -4351,7 +4332,7 @@
         "node": "10.* || >= 12.*"
       },
       "optionalDependencies": {
-        "colors": "1.4.0"
+        "@colors/colors": "1.5.0"
       }
     },
     "node_modules/cli-width": {
@@ -4423,16 +4404,6 @@
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
     },
-    "node_modules/colors": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
-      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.1.90"
-      }
-    },
     "node_modules/combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -5272,9 +5243,9 @@
       }
     },
     "node_modules/enhanced-resolve": {
-      "version": "5.9.2",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz",
-      "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==",
+      "version": "5.9.3",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz",
+      "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.4",
@@ -6105,9 +6076,9 @@
       }
     },
     "node_modules/fork-ts-checker-webpack-plugin": {
-      "version": "7.2.1",
-      "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.1.tgz",
-      "integrity": "sha512-uOfQdg/iQ8iokQ64qcbu8iZb114rOmaKLQFu7hU14/eJaKgsP91cQ7ts7v2iiDld6TzDe84Meksha8/MkWiCyw==",
+      "version": "7.2.11",
+      "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.11.tgz",
+      "integrity": "sha512-2e5+NyTUTE1Xq4fWo7KFEQblCaIvvINQwUX3jRmEGlgCTc1Ecqw/975EfQrQ0GEraxJTnp8KB9d/c8hlCHUMJA==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.16.7",
@@ -6118,7 +6089,7 @@
         "fs-extra": "^10.0.0",
         "memfs": "^3.4.1",
         "minimatch": "^3.0.4",
-        "schema-utils": "4.0.0",
+        "schema-utils": "^3.1.1",
         "semver": "^7.3.5",
         "tapable": "^2.2.1"
       },
@@ -8924,9 +8895,9 @@
       }
     },
     "node_modules/memfs": {
-      "version": "3.4.1",
-      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz",
-      "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==",
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.3.tgz",
+      "integrity": "sha512-eivjfi7Ahr6eQTn44nvTnR60e4a1Fs1Via2kCR5lHo/kyNoiMWaXCNJ/GpSd0ilXas2JSOl9B5FTIhflXu0hlg==",
       "dev": true,
       "dependencies": {
         "fs-monkey": "1.0.3"
@@ -9081,9 +9052,9 @@
       }
     },
     "node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
     "node_modules/minimist-options": {
       "version": "4.1.0",
@@ -12096,6 +12067,17 @@
         "url": "https://github.com/sponsors/jaredhanson"
       }
     },
+    "node_modules/passport-custom": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/passport-custom/-/passport-custom-1.1.1.tgz",
+      "integrity": "sha512-/2m7jUGxmCYvoqenLB9UrmkCgPt64h8ZtV+UtuQklZ/Tn1NpKBeOorCYkB/8lMRoiZ5hUrCoMmDtxCS/d38mlg==",
+      "dependencies": {
+        "passport-strategy": "1.x.x"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
     "node_modules/passport-jwt": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz",
@@ -13066,27 +13048,57 @@
       }
     },
     "node_modules/schema-utils": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
-      "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
       "dev": true,
       "dependencies": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.8.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.0.0"
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
       },
       "engines": {
-        "node": ">= 12.13.0"
+        "node": ">= 10.13.0"
       },
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/webpack"
       }
     },
-    "node_modules/semantic-release": {
-      "version": "19.0.2",
-      "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.2.tgz",
+    "node_modules/schema-utils/node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/schema-utils/node_modules/ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+      "dev": true,
+      "peerDependencies": {
+        "ajv": "^6.9.1"
+      }
+    },
+    "node_modules/schema-utils/node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "node_modules/semantic-release": {
+      "version": "19.0.2",
+      "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-19.0.2.tgz",
       "integrity": "sha512-7tPonjZxukKECmClhsfyMKDt0GR38feIC2HxgyYaBi+9tDySBLjK/zYDLhh+m6yjnHIJa9eBTKYE7k63ZQcYbw==",
       "dev": true,
       "dependencies": {
@@ -14092,55 +14104,6 @@
         }
       }
     },
-    "node_modules/terser-webpack-plugin/node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
-      "version": "3.5.2",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
-      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-      "dev": true,
-      "peerDependencies": {
-        "ajv": "^6.9.1"
-      }
-    },
-    "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
-      "dev": true,
-      "dependencies": {
-        "@types/json-schema": "^7.0.8",
-        "ajv": "^6.12.5",
-        "ajv-keywords": "^3.5.2"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/terser-webpack-plugin/node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -14491,14 +14454,14 @@
       }
     },
     "node_modules/tsconfig-paths": {
-      "version": "3.13.0",
-      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz",
-      "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==",
+      "version": "3.14.1",
+      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
+      "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
       "dev": true,
       "dependencies": {
         "@types/json5": "^0.0.29",
         "json5": "^1.0.1",
-        "minimist": "^1.2.0",
+        "minimist": "^1.2.6",
         "strip-bom": "^3.0.0"
       }
     },
@@ -14834,9 +14797,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
-      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "version": "4.6.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
+      "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -15054,11 +15017,10 @@
       }
     },
     "node_modules/webpack": {
-      "version": "5.70.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz",
-      "integrity": "sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw==",
+      "version": "5.72.1",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz",
+      "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "@types/eslint-scope": "^3.7.3",
         "@types/estree": "^0.0.51",
@@ -15069,13 +15031,13 @@
         "acorn-import-assertions": "^1.7.6",
         "browserslist": "^4.14.5",
         "chrome-trace-event": "^1.0.2",
-        "enhanced-resolve": "^5.9.2",
+        "enhanced-resolve": "^5.9.3",
         "es-module-lexer": "^0.9.0",
         "eslint-scope": "5.1.1",
         "events": "^3.2.0",
         "glob-to-regexp": "^0.4.1",
         "graceful-fs": "^4.2.9",
-        "json-parse-better-errors": "^1.0.2",
+        "json-parse-even-better-errors": "^2.3.1",
         "loader-runner": "^4.2.0",
         "mime-types": "^2.1.27",
         "neo-async": "^2.6.2",
@@ -15124,7 +15086,6 @@
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
       "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
       "dev": true,
-      "peer": true,
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -15137,64 +15098,10 @@
       "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
       "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
       "dev": true,
-      "peer": true,
       "peerDependencies": {
         "acorn": "^8"
       }
     },
-    "node_modules/webpack/node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/webpack/node_modules/ajv-keywords": {
-      "version": "3.5.2",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
-      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-      "dev": true,
-      "peer": true,
-      "peerDependencies": {
-        "ajv": "^6.9.1"
-      }
-    },
-    "node_modules/webpack/node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true,
-      "peer": true
-    },
-    "node_modules/webpack/node_modules/schema-utils": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "@types/json-schema": "^7.0.8",
-        "ajv": "^6.12.5",
-        "ajv-keywords": "^3.5.2"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/whatwg-encoding": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
@@ -15572,19 +15479,68 @@
       }
     },
     "@angular-devkit/schematics-cli": {
-      "version": "13.2.5",
-      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-13.2.5.tgz",
-      "integrity": "sha512-/3Q1+wtE+l5XXoXX/7157yh4Wpi+FNEryx5gDcfPJchgtovxj28nzquD0vXnvpyr3Wd8OaMwg6vW4EfL82jRKg==",
+      "version": "13.3.5",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-13.3.5.tgz",
+      "integrity": "sha512-ARX20ebtfwzef8GdXIcB6uv0sjTsaEniZyXBFchEKD6kR5EYZVaBL+ZVUbmsU1d0XY///WzW7pqwCyu5H1u+vw==",
       "dev": true,
       "requires": {
-        "@angular-devkit/core": "13.2.5",
-        "@angular-devkit/schematics": "13.2.5",
+        "@angular-devkit/core": "13.3.5",
+        "@angular-devkit/schematics": "13.3.5",
         "ansi-colors": "4.1.1",
         "inquirer": "8.2.0",
-        "minimist": "1.2.5",
+        "minimist": "1.2.6",
         "symbol-observable": "4.0.0"
       },
       "dependencies": {
+        "@angular-devkit/core": {
+          "version": "13.3.5",
+          "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.5.tgz",
+          "integrity": "sha512-w7vzK4VoYP9rLgxJ2SwEfrkpKybdD+QgQZlsDBzT0C6Ebp7b4gkNcNVFo8EiZvfDl6Yplw2IAP7g7fs3STn0hQ==",
+          "dev": true,
+          "requires": {
+            "ajv": "8.9.0",
+            "ajv-formats": "2.1.1",
+            "fast-json-stable-stringify": "2.1.0",
+            "magic-string": "0.25.7",
+            "rxjs": "6.6.7",
+            "source-map": "0.7.3"
+          },
+          "dependencies": {
+            "rxjs": {
+              "version": "6.6.7",
+              "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+              "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+              "dev": true,
+              "requires": {
+                "tslib": "^1.9.0"
+              }
+            }
+          }
+        },
+        "@angular-devkit/schematics": {
+          "version": "13.3.5",
+          "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.5.tgz",
+          "integrity": "sha512-0N/kL/Vfx0yVAEwa3HYxNx9wYb+G9r1JrLjJQQzDp+z9LtcojNf7j3oey6NXrDUs1WjVZOa/AIdRl3/DuaoG5w==",
+          "dev": true,
+          "requires": {
+            "@angular-devkit/core": "13.3.5",
+            "jsonc-parser": "3.0.0",
+            "magic-string": "0.25.7",
+            "ora": "5.4.1",
+            "rxjs": "6.6.7"
+          },
+          "dependencies": {
+            "rxjs": {
+              "version": "6.6.7",
+              "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+              "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+              "dev": true,
+              "requires": {
+                "tslib": "^1.9.0"
+              }
+            }
+          }
+        },
         "chalk": {
           "version": "4.1.2",
           "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -15616,6 +15572,12 @@
             "strip-ansi": "^6.0.0",
             "through": "^2.3.6"
           }
+        },
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+          "dev": true
         }
       }
     },
@@ -16128,6 +16090,13 @@
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
       "dev": true
     },
+    "@colors/colors": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+      "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+      "dev": true,
+      "optional": true
+    },
     "@cspotcode/source-map-consumer": {
       "version": "0.8.0",
       "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
@@ -16612,20 +16581,20 @@
       }
     },
     "@nestjs/cli": {
-      "version": "8.2.2",
-      "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.2.tgz",
-      "integrity": "sha512-ZonmNLCHfTVrZGgYf4mrpivnKGaRzVRAcux+WDbzhQDNIz70s7mdOPShXW1Vpq+7uRJDxlgO1vOMhmg4uEUIDg==",
+      "version": "8.2.6",
+      "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.6.tgz",
+      "integrity": "sha512-uvwKbUZJmgdJu1D24e+uUqHnwoB/0R9hLfUJjr5pTvLlP/RJugHAdJr7m1dQe92Xzdyi36kBN4Id3RXHgfz1UA==",
       "dev": true,
       "requires": {
-        "@angular-devkit/core": "13.2.5",
-        "@angular-devkit/schematics": "13.2.5",
-        "@angular-devkit/schematics-cli": "13.2.5",
+        "@angular-devkit/core": "13.3.5",
+        "@angular-devkit/schematics": "13.3.5",
+        "@angular-devkit/schematics-cli": "13.3.5",
         "@nestjs/schematics": "^8.0.3",
         "chalk": "3.0.0",
         "chokidar": "3.5.3",
-        "cli-table3": "0.6.1",
+        "cli-table3": "0.6.2",
         "commander": "4.1.1",
-        "fork-ts-checker-webpack-plugin": "7.2.1",
+        "fork-ts-checker-webpack-plugin": "7.2.11",
         "inquirer": "7.3.3",
         "node-emoji": "1.11.0",
         "ora": "5.4.1",
@@ -16634,126 +16603,54 @@
         "shelljs": "0.8.5",
         "source-map-support": "0.5.21",
         "tree-kill": "1.2.2",
-        "tsconfig-paths": "3.12.0",
+        "tsconfig-paths": "3.14.1",
         "tsconfig-paths-webpack-plugin": "3.5.2",
-        "typescript": "4.6.2",
-        "webpack": "5.66.0",
+        "typescript": "4.6.4",
+        "webpack": "5.72.1",
         "webpack-node-externals": "3.0.0"
       },
       "dependencies": {
-        "@types/estree": {
-          "version": "0.0.50",
-          "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
-          "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
-          "dev": true
-        },
-        "acorn": {
-          "version": "8.7.0",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
-          "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
-          "dev": true
-        },
-        "acorn-import-assertions": {
-          "version": "1.8.0",
-          "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
-          "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
-          "dev": true,
-          "requires": {}
-        },
-        "ajv": {
-          "version": "6.12.6",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+        "@angular-devkit/core": {
+          "version": "13.3.5",
+          "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.5.tgz",
+          "integrity": "sha512-w7vzK4VoYP9rLgxJ2SwEfrkpKybdD+QgQZlsDBzT0C6Ebp7b4gkNcNVFo8EiZvfDl6Yplw2IAP7g7fs3STn0hQ==",
           "dev": true,
           "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "fast-json-stable-stringify": "^2.0.0",
-            "json-schema-traverse": "^0.4.1",
-            "uri-js": "^4.2.2"
+            "ajv": "8.9.0",
+            "ajv-formats": "2.1.1",
+            "fast-json-stable-stringify": "2.1.0",
+            "magic-string": "0.25.7",
+            "rxjs": "6.6.7",
+            "source-map": "0.7.3"
           }
         },
-        "ajv-keywords": {
-          "version": "3.5.2",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
-          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true,
-          "requires": {}
-        },
-        "json-schema-traverse": {
-          "version": "0.4.1",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-          "dev": true
-        },
-        "json5": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
-          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+        "@angular-devkit/schematics": {
+          "version": "13.3.5",
+          "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.5.tgz",
+          "integrity": "sha512-0N/kL/Vfx0yVAEwa3HYxNx9wYb+G9r1JrLjJQQzDp+z9LtcojNf7j3oey6NXrDUs1WjVZOa/AIdRl3/DuaoG5w==",
           "dev": true,
           "requires": {
-            "minimist": "^1.2.0"
+            "@angular-devkit/core": "13.3.5",
+            "jsonc-parser": "3.0.0",
+            "magic-string": "0.25.7",
+            "ora": "5.4.1",
+            "rxjs": "6.6.7"
           }
         },
-        "schema-utils": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+        "rxjs": {
+          "version": "6.6.7",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+          "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
           "dev": true,
           "requires": {
-            "@types/json-schema": "^7.0.8",
-            "ajv": "^6.12.5",
-            "ajv-keywords": "^3.5.2"
+            "tslib": "^1.9.0"
           }
         },
-        "strip-bom": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
           "dev": true
-        },
-        "tsconfig-paths": {
-          "version": "3.12.0",
-          "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
-          "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
-          "dev": true,
-          "requires": {
-            "@types/json5": "^0.0.29",
-            "json5": "^1.0.1",
-            "minimist": "^1.2.0",
-            "strip-bom": "^3.0.0"
-          }
-        },
-        "webpack": {
-          "version": "5.66.0",
-          "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.66.0.tgz",
-          "integrity": "sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg==",
-          "dev": true,
-          "requires": {
-            "@types/eslint-scope": "^3.7.0",
-            "@types/estree": "^0.0.50",
-            "@webassemblyjs/ast": "1.11.1",
-            "@webassemblyjs/wasm-edit": "1.11.1",
-            "@webassemblyjs/wasm-parser": "1.11.1",
-            "acorn": "^8.4.1",
-            "acorn-import-assertions": "^1.7.6",
-            "browserslist": "^4.14.5",
-            "chrome-trace-event": "^1.0.2",
-            "enhanced-resolve": "^5.8.3",
-            "es-module-lexer": "^0.9.0",
-            "eslint-scope": "5.1.1",
-            "events": "^3.2.0",
-            "glob-to-regexp": "^0.4.1",
-            "graceful-fs": "^4.2.9",
-            "json-parse-better-errors": "^1.0.2",
-            "loader-runner": "^4.2.0",
-            "mime-types": "^2.1.27",
-            "neo-async": "^2.6.2",
-            "schema-utils": "^3.1.0",
-            "tapable": "^2.1.1",
-            "terser-webpack-plugin": "^5.1.3",
-            "watchpack": "^2.3.1",
-            "webpack-sources": "^3.2.2"
-          }
         }
       }
     },
@@ -18070,15 +17967,6 @@
         "ajv": "^8.0.0"
       }
     },
-    "ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "dev": true,
-      "requires": {
-        "fast-deep-equal": "^3.1.3"
-      }
-    },
     "ansi-colors": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -18837,12 +18725,12 @@
       "dev": true
     },
     "cli-table3": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz",
-      "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==",
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz",
+      "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==",
       "dev": true,
       "requires": {
-        "colors": "1.4.0",
+        "@colors/colors": "1.5.0",
         "string-width": "^4.2.0"
       }
     },
@@ -18902,13 +18790,6 @@
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
     },
-    "colors": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
-      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
-      "dev": true,
-      "optional": true
-    },
     "combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -19593,9 +19474,9 @@
       }
     },
     "enhanced-resolve": {
-      "version": "5.9.2",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz",
-      "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==",
+      "version": "5.9.3",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz",
+      "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==",
       "dev": true,
       "requires": {
         "graceful-fs": "^4.2.4",
@@ -20225,9 +20106,9 @@
       "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
     },
     "fork-ts-checker-webpack-plugin": {
-      "version": "7.2.1",
-      "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.1.tgz",
-      "integrity": "sha512-uOfQdg/iQ8iokQ64qcbu8iZb114rOmaKLQFu7hU14/eJaKgsP91cQ7ts7v2iiDld6TzDe84Meksha8/MkWiCyw==",
+      "version": "7.2.11",
+      "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.11.tgz",
+      "integrity": "sha512-2e5+NyTUTE1Xq4fWo7KFEQblCaIvvINQwUX3jRmEGlgCTc1Ecqw/975EfQrQ0GEraxJTnp8KB9d/c8hlCHUMJA==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.16.7",
@@ -20238,7 +20119,7 @@
         "fs-extra": "^10.0.0",
         "memfs": "^3.4.1",
         "minimatch": "^3.0.4",
-        "schema-utils": "4.0.0",
+        "schema-utils": "^3.1.1",
         "semver": "^7.3.5",
         "tapable": "^2.2.1"
       },
@@ -22351,9 +22232,9 @@
       "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
     },
     "memfs": {
-      "version": "3.4.1",
-      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz",
-      "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==",
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.3.tgz",
+      "integrity": "sha512-eivjfi7Ahr6eQTn44nvTnR60e4a1Fs1Via2kCR5lHo/kyNoiMWaXCNJ/GpSd0ilXas2JSOl9B5FTIhflXu0hlg==",
       "dev": true,
       "requires": {
         "fs-monkey": "1.0.3"
@@ -22462,9 +22343,9 @@
       }
     },
     "minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
     "minimist-options": {
       "version": "4.1.0",
@@ -24622,6 +24503,14 @@
         "pause": "0.0.1"
       }
     },
+    "passport-custom": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/passport-custom/-/passport-custom-1.1.1.tgz",
+      "integrity": "sha512-/2m7jUGxmCYvoqenLB9UrmkCgPt64h8ZtV+UtuQklZ/Tn1NpKBeOorCYkB/8lMRoiZ5hUrCoMmDtxCS/d38mlg==",
+      "requires": {
+        "passport-strategy": "1.x.x"
+      }
+    },
     "passport-jwt": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz",
@@ -25321,15 +25210,41 @@
       }
     },
     "schema-utils": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
-      "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
       "dev": true,
       "requires": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.8.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.0.0"
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.12.6",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^3.1.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "ajv-keywords": {
+          "version": "3.5.2",
+          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+          "dev": true,
+          "requires": {}
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        }
       }
     },
     "semantic-release": {
@@ -26121,42 +26036,6 @@
         "terser": "^5.7.2"
       },
       "dependencies": {
-        "ajv": {
-          "version": "6.12.6",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "fast-json-stable-stringify": "^2.0.0",
-            "json-schema-traverse": "^0.4.1",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "ajv-keywords": {
-          "version": "3.5.2",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
-          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true,
-          "requires": {}
-        },
-        "json-schema-traverse": {
-          "version": "0.4.1",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-          "dev": true
-        },
-        "schema-utils": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
-          "dev": true,
-          "requires": {
-            "@types/json-schema": "^7.0.8",
-            "ajv": "^6.12.5",
-            "ajv-keywords": "^3.5.2"
-          }
-        },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -26386,14 +26265,14 @@
       }
     },
     "tsconfig-paths": {
-      "version": "3.13.0",
-      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz",
-      "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==",
+      "version": "3.14.1",
+      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
+      "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
       "dev": true,
       "requires": {
         "@types/json5": "^0.0.29",
         "json5": "^1.0.1",
-        "minimist": "^1.2.0",
+        "minimist": "^1.2.6",
         "strip-bom": "^3.0.0"
       },
       "dependencies": {
@@ -26596,9 +26475,9 @@
       }
     },
     "typescript": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
-      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "version": "4.6.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
+      "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
       "dev": true
     },
     "uglify-js": {
@@ -26767,11 +26646,10 @@
       "dev": true
     },
     "webpack": {
-      "version": "5.70.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz",
-      "integrity": "sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw==",
+      "version": "5.72.1",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz",
+      "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==",
       "dev": true,
-      "peer": true,
       "requires": {
         "@types/eslint-scope": "^3.7.3",
         "@types/estree": "^0.0.51",
@@ -26782,13 +26660,13 @@
         "acorn-import-assertions": "^1.7.6",
         "browserslist": "^4.14.5",
         "chrome-trace-event": "^1.0.2",
-        "enhanced-resolve": "^5.9.2",
+        "enhanced-resolve": "^5.9.3",
         "es-module-lexer": "^0.9.0",
         "eslint-scope": "5.1.1",
         "events": "^3.2.0",
         "glob-to-regexp": "^0.4.1",
         "graceful-fs": "^4.2.9",
-        "json-parse-better-errors": "^1.0.2",
+        "json-parse-even-better-errors": "^2.3.1",
         "loader-runner": "^4.2.0",
         "mime-types": "^2.1.27",
         "neo-async": "^2.6.2",
@@ -26803,56 +26681,14 @@
           "version": "8.7.0",
           "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
           "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
-          "dev": true,
-          "peer": true
+          "dev": true
         },
         "acorn-import-assertions": {
           "version": "1.8.0",
           "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
           "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
           "dev": true,
-          "peer": true,
           "requires": {}
-        },
-        "ajv": {
-          "version": "6.12.6",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "fast-json-stable-stringify": "^2.0.0",
-            "json-schema-traverse": "^0.4.1",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "ajv-keywords": {
-          "version": "3.5.2",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
-          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-          "dev": true,
-          "peer": true,
-          "requires": {}
-        },
-        "json-schema-traverse": {
-          "version": "0.4.1",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-          "dev": true,
-          "peer": true
-        },
-        "schema-utils": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
-          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "@types/json-schema": "^7.0.8",
-            "ajv": "^6.12.5",
-            "ajv-keywords": "^3.5.2"
-          }
         }
       }
     },
diff --git a/api/package.json b/api/package.json
index 7e11e66..1e71e56 100644
--- a/api/package.json
+++ b/api/package.json
@@ -43,6 +43,7 @@
     "graphql-type-json": "^0.3.2",
     "jsonata": "^1.8.5",
     "passport": "^0.5.2",
+    "passport-custom": "^1.1.1",
     "passport-jwt": "^4.0.0",
     "passport-local": "^1.0.0",
     "pg": "^8.7.3",
@@ -98,12 +99,12 @@
       "^.+\\.(t|j)s$": "ts-jest"
     },
     "collectCoverageFrom": [
-      "**/*.(t|j)s", 
-      "!**/*e2e-spec.ts", 
-      "!**/*.module.ts", 
+      "**/*.(t|j)s",
+      "!**/*e2e-spec.ts",
+      "!**/*.module.ts",
       "!**/*.decorator.ts",
-      "!**/*.model.ts", 
-      "!**/*.input.ts", 
+      "!**/*.model.ts",
+      "!**/*.input.ts",
       "!**/jest.config.ts",
       "!**/main.ts"
     ],
diff --git a/api/src/auth/auth.module.ts b/api/src/auth/auth.module.ts
index 805f0dc..936e09c 100644
--- a/api/src/auth/auth.module.ts
+++ b/api/src/auth/auth.module.ts
@@ -5,6 +5,7 @@ import { PassportModule } from '@nestjs/passport';
 import { authConstants } from './auth-constants';
 import { AuthResolver } from './auth.resolver';
 import { AuthService } from './auth.service';
+import { EngineStrategy } from './strategies/engine.strategy';
 import { JwtBearerStrategy } from './strategies/jwt-bearer.strategy';
 import { JwtCookiesStrategy } from './strategies/jwt-cookies.strategy';
 import { LocalStrategy } from './strategies/local.strategy';
@@ -30,6 +31,7 @@ import { LocalStrategy } from './strategies/local.strategy';
     LocalStrategy,
     JwtBearerStrategy,
     JwtCookiesStrategy,
+    EngineStrategy,
     AuthResolver,
   ],
   exports: [AuthService],
diff --git a/api/src/auth/auth.resolver.spec.ts b/api/src/auth/auth.resolver.spec.ts
index c109dbe..e545b55 100644
--- a/api/src/auth/auth.resolver.spec.ts
+++ b/api/src/auth/auth.resolver.spec.ts
@@ -79,9 +79,9 @@ describe('AuthResolver', () => {
     expect(data.accessToken).toBe(authData.accessToken);
   });
 
-  it('logout', () => {
+  it('logout', async () => {
     const request: any = jest.fn();
-    resolver.logout(request, res, user);
+    await resolver.logout(request, res, user);
 
     expect(mockClearCookie.mock.calls[0][0]).toBe(authConstants.cookie.name);
   });
diff --git a/api/src/auth/auth.resolver.ts b/api/src/auth/auth.resolver.ts
index cfa8e71..d01434a 100644
--- a/api/src/auth/auth.resolver.ts
+++ b/api/src/auth/auth.resolver.ts
@@ -7,6 +7,7 @@ import {
 import { ConfigService } from '@nestjs/config';
 import { Args, Mutation, Resolver } from '@nestjs/graphql';
 import { Response, Request } from 'express';
+import { CurrentUser } from '../common/decorators/user.decorator';
 import { GQLRequest } from '../common/decorators/gql-request.decoractor';
 import { GQLResponse } from '../common/decorators/gql-response.decoractor';
 import { parseToBoolean } from '../common/utilities';
@@ -18,8 +19,7 @@ import { IEngineOptions, IEngineService } from '../engine/engine.interfaces';
 import { User } from '../users/models/user.model';
 import { authConstants } from './auth-constants';
 import { AuthService } from './auth.service';
-import { CurrentUser } from './decorators/user.decorator';
-import { JwtAuthGuard } from './guards/jwt-auth.guard';
+import { GlobalAuthGuard } from './guards/global-auth.guard';
 import { LocalAuthGuard } from './guards/local-auth.guard';
 import { AuthenticationInput } from './inputs/authentication.input';
 import { AuthenticationOutput } from './outputs/authentication.output';
@@ -73,16 +73,16 @@ export class AuthResolver {
   }
 
   @Mutation(() => Boolean)
-  @UseGuards(JwtAuthGuard)
-  logout(
+  @UseGuards(GlobalAuthGuard)
+  async logout(
     @GQLRequest() req: Request,
     @GQLResponse() res: Response,
     @CurrentUser() user: User,
-  ): boolean {
+  ): Promise<boolean> {
     if (user) {
       this.logger.verbose(`${user.username} logged out`);
       try {
-        this.engineService.logout?.(req);
+        await this.engineService.logout?.(req);
       } catch (e) {
         this.logger.debug(
           `Service ${this.engineOptions.type} produce an error when logging out ${user.username}`,
diff --git a/api/src/auth/auth.service.ts b/api/src/auth/auth.service.ts
index 18eaadf..402dfc6 100644
--- a/api/src/auth/auth.service.ts
+++ b/api/src/auth/auth.service.ts
@@ -14,7 +14,7 @@ export class AuthService {
 
   async validateUser(username: string, password: string): Promise<User> {
     if (!this.engineService.login) throw new NotImplementedException();
-    return await this.engineService.login?.(username, password);
+    return this.engineService.login?.(username, password);
   }
 
   /**
diff --git a/api/src/auth/decorators/user.decorator.ts b/api/src/auth/decorators/user.decorator.ts
deleted file mode 100644
index 0aa940d..0000000
--- a/api/src/auth/decorators/user.decorator.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { createParamDecorator, ExecutionContext } from '@nestjs/common';
-import { GqlExecutionContext } from '@nestjs/graphql';
-import { User } from '../../users/models/user.model';
-
-/**
- * Retrieve the current user within the graphQL request
- * @returns instance of User or undefined
- */
-export const CurrentUser = createParamDecorator(
-  (data: unknown, context: ExecutionContext): User | undefined => {
-    const ctx = GqlExecutionContext.create(context);
-    return ctx.getContext().req.user;
-  },
-);
diff --git a/api/src/auth/guards/jwt-auth.guard.ts b/api/src/auth/guards/global-auth.guard.ts
similarity index 73%
rename from api/src/auth/guards/jwt-auth.guard.ts
rename to api/src/auth/guards/global-auth.guard.ts
index 2ee1a63..ecfd65e 100644
--- a/api/src/auth/guards/jwt-auth.guard.ts
+++ b/api/src/auth/guards/global-auth.guard.ts
@@ -4,11 +4,13 @@ import { Reflector } from '@nestjs/core';
 import { GqlExecutionContext } from '@nestjs/graphql';
 import { AuthGuard } from '@nestjs/passport';
 import { Observable } from 'rxjs';
-import { parseToBoolean } from '../../common/utilities';
-import { authConstants } from '../auth-constants';
 
 @Injectable()
-export class JwtAuthGuard extends AuthGuard(['jwt-cookies', 'jwt-bearer']) {
+export class GlobalAuthGuard extends AuthGuard([
+  'jwt-cookies',
+  'jwt-bearer',
+  'engine',
+]) {
   constructor(
     private readonly configService: ConfigService,
     private readonly reflector: Reflector,
@@ -31,11 +33,7 @@ export class JwtAuthGuard extends AuthGuard(['jwt-cookies', 'jwt-bearer']) {
       context.getHandler(),
     );
 
-    const skipAuth = parseToBoolean(
-      this.configService.get(authConstants.skipAuth, 'false'),
-    );
-
-    if (skipAuth || isPublic) {
+    if (isPublic) {
       return true;
     }
 
diff --git a/api/src/auth/strategies/engine.strategy.ts b/api/src/auth/strategies/engine.strategy.ts
new file mode 100644
index 0000000..f98cede
--- /dev/null
+++ b/api/src/auth/strategies/engine.strategy.ts
@@ -0,0 +1,22 @@
+import { Inject, Injectable } from '@nestjs/common';
+import { PassportStrategy } from '@nestjs/passport';
+import { ENGINE_SERVICE } from 'src/engine/engine.constants';
+import { IEngineService } from 'src/engine/engine.interfaces';
+import { Request } from 'express';
+import { Strategy } from 'passport-custom';
+
+@Injectable()
+export class EngineStrategy extends PassportStrategy(Strategy, 'engine') {
+  constructor(
+    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
+  ) {
+    super();
+  }
+
+  async validate(req: Request) {
+    if (!this.engineService.getActiveUser) return false;
+    const user = this.engineService.getActiveUser(req);
+
+    return user ?? false;
+  }
+}
diff --git a/api/src/common/decorators/user.decorator.ts b/api/src/common/decorators/user.decorator.ts
index 0aa940d..8db357e 100644
--- a/api/src/common/decorators/user.decorator.ts
+++ b/api/src/common/decorators/user.decorator.ts
@@ -7,7 +7,7 @@ import { User } from '../../users/models/user.model';
  * @returns instance of User or undefined
  */
 export const CurrentUser = createParamDecorator(
-  (data: unknown, context: ExecutionContext): User | undefined => {
+  (_data: unknown, context: ExecutionContext): User | undefined => {
     const ctx = GqlExecutionContext.create(context);
     return ctx.getContext().req.user;
   },
diff --git a/api/src/engine/connectors/csv/main.connector.ts b/api/src/engine/connectors/csv/main.connector.ts
index 79c592b..ebb2ee1 100644
--- a/api/src/engine/connectors/csv/main.connector.ts
+++ b/api/src/engine/connectors/csv/main.connector.ts
@@ -1,17 +1,14 @@
+import { HttpService } from '@nestjs/axios';
+import { NotImplementedException } from '@nestjs/common';
 import { firstValueFrom } from 'rxjs';
+import {
+  Dictionary,
+  ExperimentResult,
+} from 'src/common/interfaces/utilities.interface';
 import { IEngineOptions, IEngineService } from 'src/engine/engine.interfaces';
 import { Domain } from 'src/engine/models/domain.model';
-import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
-import {
-  Experiment,
-  PartialExperiment,
-} from 'src/engine/models/experiment/experiment.model';
-import { ListExperiments } from 'src/engine/models/experiment/list-experiments.model';
-import { ExperimentEditInput } from 'src/engine/models/experiment/input/experiment-edit.input';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
-import { HttpService } from '@nestjs/axios';
 import { Group } from 'src/engine/models/group.model';
-import { Dictionary } from 'src/common/interfaces/utilities.interface';
 import { User } from 'src/users/models/user.model';
 
 export default class CSVService implements IEngineService {
@@ -21,51 +18,15 @@ export default class CSVService implements IEngineService {
   ) {}
 
   async logout() {
-    throw new Error('Method not implemented.');
+    throw new NotImplementedException();
   }
 
   async getAlgorithms(): Promise<Algorithm[]> {
-    throw new Error('Method not implemented.');
+    throw new NotImplementedException();
   }
 
-  async createExperiment(
-    data: ExperimentCreateInput,
-    isTransient: boolean,
-  ): Promise<Experiment> {
-    return {
-      id: '',
-      domain: '',
-      datasets: [],
-      algorithm: {
-        name: '',
-      },
-      name: 'test',
-      variables: [],
-    };
-  }
-
-  async listExperiments(page: number, name: string): Promise<ListExperiments> {
-    return {
-      experiments: [],
-      currentPage: 0,
-      totalExperiments: 0,
-      totalPages: 0,
-    };
-  }
-
-  async getExperiment(id: string): Promise<Experiment> {
-    throw new Error('Method not implemented.');
-  }
-
-  async removeExperiment(id: string): Promise<PartialExperiment> {
-    throw new Error('Method not implemented.');
-  }
-
-  async editExperient(
-    id: string,
-    expriment: ExperimentEditInput,
-  ): Promise<Experiment> {
-    throw new Error('Method not implemented.');
+  async runExperiment(): Promise<ExperimentResult[]> {
+    throw new NotImplementedException();
   }
 
   async getDomains(): Promise<Domain[]> {
@@ -154,17 +115,12 @@ export default class CSVService implements IEngineService {
   }
 
   async getActiveUser(): Promise<User> {
-    const dummyUser = {
+    return {
       username: 'anonymous',
       id: 'anonymousId',
       fullname: 'anonymous',
       email: 'anonymous@anonymous.com',
       agreeNDA: true,
     };
-    return dummyUser;
-  }
-
-  getAlgorithmsREST(): string {
-    return '[]';
   }
 }
diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/main.connector.ts
index f796f3c..153ceac 100644
--- a/api/src/engine/connectors/datashield/main.connector.ts
+++ b/api/src/engine/connectors/datashield/main.connector.ts
@@ -7,7 +7,10 @@ import {
 } from '@nestjs/common';
 import { Request } from 'express';
 import { catchError, firstValueFrom } from 'rxjs';
-import { MIME_TYPES } from 'src/common/interfaces/utilities.interface';
+import {
+  ExperimentResult,
+  MIME_TYPES,
+} from 'src/common/interfaces/utilities.interface';
 import { errorAxiosHandler } from 'src/common/utilities';
 import { ENGINE_MODULE_OPTIONS } from 'src/engine/engine.constants';
 import {
@@ -18,13 +21,12 @@ import {
 import { Domain } from 'src/engine/models/domain.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
 import { Experiment } from 'src/engine/models/experiment/experiment.model';
-import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
-import { ListExperiments } from 'src/engine/models/experiment/list-experiments.model';
 import { RawResult } from 'src/engine/models/result/raw-result.model';
 import {
   TableResult,
   TableStyle,
 } from 'src/engine/models/result/table-result.model';
+import { ExperimentCreateInput } from 'src/experiments/models/input/experiment-create.input';
 import { User } from 'src/users/models/user.model';
 import {
   dataToGroups,
@@ -65,7 +67,7 @@ export default class DataShieldService implements IEngineService {
         .pipe(catchError((e) => errorAxiosHandler(e))),
     );
 
-    const cookies = (loginData.headers['set-cookie'] as string[]) ?? [];
+    const cookies = loginData.headers['set-cookie'] ?? [];
     if (loginData.headers && loginData.headers['set-cookie']) {
       cookies.forEach((cookie) => {
         const [key, value] = cookie.split(/={1}/);
@@ -143,11 +145,10 @@ export default class DataShieldService implements IEngineService {
     };
   }
 
-  async createExperiment(
+  async runExperiment(
     data: ExperimentCreateInput,
-    isTransient: boolean,
     request: Request,
-  ): Promise<Experiment> {
+  ): Promise<ExperimentResult[]> {
     const user = request.user as User;
     const cookie = [`sid=${user.extraFields['sid']}`, `user=${user.id}`].join(
       ';',
@@ -166,37 +167,21 @@ export default class DataShieldService implements IEngineService {
     switch (data.algorithm.id) {
       case 'MULTIPLE_HISTOGRAMS': {
         expResult.results = await Promise.all<RawResult>(
-          data.variables.map(
-            async (variable) => await this.getHistogram(variable, cookie),
-          ),
+          data.variables.map((variable) => this.getHistogram(variable, cookie)),
         );
         break;
       }
       case 'DESCRIPTIVE_STATS': {
         expResult.results = await Promise.all<TableResult>(
-          [...data.variables, ...data.coVariables].map(
-            async (variable) =>
-              await this.getDescriptiveStats(variable, cookie),
+          [...data.variables, ...data.coVariables].map((variable) =>
+            this.getDescriptiveStats(variable, cookie),
           ),
         );
         break;
       }
     }
 
-    return expResult;
-  }
-
-  async listExperiments(): Promise<ListExperiments> {
-    return {
-      totalExperiments: 0,
-      experiments: [],
-      totalPages: 0,
-      currentPage: 0,
-    };
-  }
-
-  async getExperiment(id: string): Promise<Experiment> {
-    throw new NotImplementedException();
+    return expResult.results;
   }
 
   async logout(request: Request): Promise<void> {
@@ -214,7 +199,7 @@ export default class DataShieldService implements IEngineService {
     });
   }
 
-  async getDomains(ids: string[], request: Request): Promise<Domain[]> {
+  async getDomains(_ids: string[], request: Request): Promise<Domain[]> {
     const user = request.user as User;
     const sid = user && user.extraFields && user.extraFields['sid'];
 
@@ -249,8 +234,4 @@ export default class DataShieldService implements IEngineService {
       fullname: user.id,
     };
   }
-
-  getAlgorithmsREST(): string {
-    return '[]';
-  }
 }
diff --git a/api/src/engine/connectors/exareme/converters.ts b/api/src/engine/connectors/exareme/converters.ts
index 73ac0f4..a1c28d5 100644
--- a/api/src/engine/connectors/exareme/converters.ts
+++ b/api/src/engine/connectors/exareme/converters.ts
@@ -1,9 +1,12 @@
 import { MIME_TYPES } from 'src/common/interfaces/utilities.interface';
 import { Category } from 'src/engine/models/category.model';
 import { Dataset } from 'src/engine/models/dataset.model';
-import { Experiment } from 'src/engine/models/experiment/experiment.model';
-import { AlgorithmParamInput } from 'src/engine/models/experiment/input/algorithm-parameter.input';
-import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
+import {
+  Experiment,
+  ExperimentStatus,
+} from 'src/engine/models/experiment/experiment.model';
+import { AlgorithmParamInput } from 'src/experiments/models/input/algorithm-parameter.input';
+import { ExperimentCreateInput } from 'src/experiments/models/input/experiment-create.input';
 import { Group } from 'src/engine/models/group.model';
 import { ResultUnion } from 'src/engine/models/result/common/result-union.model';
 import {
@@ -36,7 +39,7 @@ export const dataToGroup = (data: Hierarchy): Group => {
       ? data.groups.map(dataToGroup).map((group) => group.id)
       : [],
     variables: data.variables
-      ? data.variables.map((data: VariableEntity) => data.code)
+      ? data.variables.map((v: VariableEntity) => v.code)
       : [],
   };
 };
@@ -223,7 +226,7 @@ export const dataToExperiment = (
     return {
       id: data.uuid,
       name: data.name,
-      status: 'error',
+      status: ExperimentStatus.ERROR,
       variables: [],
       domain: data['domain'] ?? '',
       results: [
diff --git a/api/src/engine/connectors/exareme/interfaces/test-utilities.ts b/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
index 2ad1c79..6746a8f 100644
--- a/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
+++ b/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
@@ -1,6 +1,6 @@
 import { IEngineService } from 'src/engine/engine.interfaces';
 import { Experiment } from 'src/engine/models/experiment/experiment.model';
-import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from 'src/experiments/models/input/experiment-create.input';
 
 const TIMEOUT_DURATION_SECONDS = 60 * 10;
 
@@ -30,7 +30,7 @@ const createExperiment = async (
   input: ExperimentCreateInput,
   service: IEngineService,
 ): Promise<Experiment | undefined> => {
-  return await service.createExperiment(input, false);
+  return service.createExperiment(input, false);
 };
 
 const waitForResult = (
diff --git a/api/src/engine/connectors/exareme/main.connector.ts b/api/src/engine/connectors/exareme/main.connector.ts
index 8a9d84b..9420070 100644
--- a/api/src/engine/connectors/exareme/main.connector.ts
+++ b/api/src/engine/connectors/exareme/main.connector.ts
@@ -22,8 +22,8 @@ import {
   Experiment,
   PartialExperiment,
 } from 'src/engine/models/experiment/experiment.model';
-import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
-import { ExperimentEditInput } from 'src/engine/models/experiment/input/experiment-edit.input';
+import { ExperimentCreateInput } from 'src/experiments/models/input/experiment-create.input';
+import { ExperimentEditInput } from 'src/experiments/models/input/experiment-edit.input';
 import { ListExperiments } from 'src/engine/models/experiment/list-experiments.model';
 import { Group } from 'src/engine/models/group.model';
 import { Variable } from 'src/engine/models/variable.model';
@@ -118,7 +118,7 @@ export default class ExaremeService implements IEngineService {
     return dataToExperiment(resultAPI.data);
   }
 
-  async editExperient(
+  async editExperiment(
     id: string,
     expriment: ExperimentEditInput,
     request: Request,
@@ -156,18 +156,18 @@ export default class ExaremeService implements IEngineService {
 
       return (
         data?.data
-          .filter((data) => !ids || ids.length == 0 || ids.includes(data.code))
-          .map((data): Domain => {
-            const groups = this.flattenGroups(data.metadataHierarchy);
+          .filter((d) => !ids || ids.length == 0 || ids.includes(d.code))
+          .map((d): Domain => {
+            const groups = this.flattenGroups(d.metadataHierarchy);
 
             return {
-              id: data.code,
-              label: data.label,
+              id: d.code,
+              label: d.label,
               groups: groups,
-              rootGroup: dataToGroup(data.metadataHierarchy),
-              datasets: data.datasets ? data.datasets.map(dataToDataset) : [],
-              variables: data.metadataHierarchy
-                ? this.flattenVariables(data.metadataHierarchy, groups)
+              rootGroup: dataToGroup(d.metadataHierarchy),
+              datasets: d.datasets ? d.datasets.map(dataToDataset) : [],
+              variables: d.metadataHierarchy
+                ? this.flattenVariables(d.metadataHierarchy, groups)
                 : [],
             };
           }) ?? []
@@ -187,7 +187,10 @@ export default class ExaremeService implements IEngineService {
     try {
       return transformToUser.evaluate(response.data);
     } catch (e) {
-      new InternalServerErrorException('Cannot parse user data from Engine', e);
+      throw new InternalServerErrorException(
+        'Cannot parse user data from Engine',
+        e,
+      );
     }
   }
 
@@ -202,14 +205,6 @@ export default class ExaremeService implements IEngineService {
     return undefined; //we don't want to manage data locally
   }
 
-  getAlgorithmsREST(request: Request): Observable<string> {
-    const path = this.options.baseurl + 'algorithms';
-
-    return this.get<string>(request, path, { params: request.query }).pipe(
-      map((response) => response.data),
-    );
-  }
-
   getPassthrough(
     suffix: string,
     request: Request,
@@ -233,7 +228,7 @@ export default class ExaremeService implements IEngineService {
   };
 
   private flattenVariables = (data: Hierarchy, groups: Group[]): Variable[] => {
-    const group = groups.find((group) => group.id == data.code);
+    const group = groups.find((g) => g.id == data.code);
     let variables = data.variables ? data.variables.map(dataToVariable) : [];
 
     variables.forEach((variable) => (variable.groups = group ? [group] : []));
diff --git a/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
index 8770e90..7b4d577 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
index 447b8f4..2e696f0 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
index f8b0085..550e75c 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
@@ -3,7 +3,7 @@ import { RawResult } from 'src/engine/models/result/raw-result.model';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
index 5808b15..12737e1 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
@@ -4,7 +4,7 @@ import { TableResult } from 'src/engine/models/result/table-result.model';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
index 4ef963a..6a34e18 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
@@ -3,7 +3,7 @@ import { RawResult } from 'src/engine/models/result/raw-result.model';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
index 5705472..b754a06 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
@@ -3,7 +3,7 @@ import { RawResult } from 'src/engine/models/result/raw-result.model';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
index b076616..2defac9 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
index 4ed7f22..e50a0ad 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
@@ -3,7 +3,7 @@ import { RawResult } from 'src/engine/models/result/raw-result.model';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
index abc045c..50bc9e6 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
@@ -3,7 +3,7 @@ import { RawResult } from 'src/engine/models/result/raw-result.model';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
index 7604dd9..8eba296 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
   generateNumber,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
index 024e412..cefa59c 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
index e836179..3f954f5 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
index 79f65b8..36f78cf 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
index e1617dd..8bc3f92 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
index 2dee185..208516e 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
index a08e6fb..c9cf5af 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
index dd2b971..45d2220 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
index 7b616e3..021723c 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
 import { ENGINE_SERVICE } from '../../../../engine.constants';
 import { IEngineService } from '../../../../engine.interfaces';
-import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
diff --git a/api/src/engine/connectors/exareme/transformations.ts b/api/src/engine/connectors/exareme/transformations.ts
index 8ecf464..4a91590 100644
--- a/api/src/engine/connectors/exareme/transformations.ts
+++ b/api/src/engine/connectors/exareme/transformations.ts
@@ -7,7 +7,7 @@ export const transformToExperiment = jsonata(`
 ( 
     $params := ["y", "pathology", "dataset", "filter", "x", "formula"];
     $toArray := function($x) { $type($x) = 'array' ? $x : [$x]};
-    $convDate := function($v) { $type($v) = 'string' ? $toMillis($v) : $v };
+    $convDate := function($v) { $type($v) = 'string' ? $v : $fromMillis($v) };
     $rp := function($v) {$replace($v, /(\\+|\\*|-)/, ',')};
     $strSafe := function($v) { $type($v) = 'string' ? $v : "" };
     $formula := $eval(algorithm.parameters[name = "formula"].value);
@@ -171,12 +171,10 @@ dataToHeatmap.registerFunction(
   (a) => {
     const matrix = [];
 
-    a.forEach(
-      (elem: { y: number | number; x: number | number; value: number }) => {
-        matrix[elem.y] = matrix[elem.y] ?? [];
-        matrix[elem.y][elem.x] = elem.value;
-      },
-    );
+    a.forEach((elem: { y: number; x: number; value: number }) => {
+      matrix[elem.y] = matrix[elem.y] ?? [];
+      matrix[elem.y][elem.x] = elem.value;
+    });
 
     return matrix;
   },
diff --git a/api/src/engine/connectors/local/main.connector.ts b/api/src/engine/connectors/local/main.connector.ts
index 600fcc9..ef95f60 100644
--- a/api/src/engine/connectors/local/main.connector.ts
+++ b/api/src/engine/connectors/local/main.connector.ts
@@ -1,13 +1,7 @@
 import { IEngineService } from 'src/engine/engine.interfaces';
 import { Domain } from 'src/engine/models/domain.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
-import {
-  Experiment,
-  PartialExperiment,
-} from 'src/engine/models/experiment/experiment.model';
-import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
-import { ExperimentEditInput } from 'src/engine/models/experiment/input/experiment-edit.input';
-import { ListExperiments } from 'src/engine/models/experiment/list-experiments.model';
+import { ResultUnion } from 'src/engine/models/result/common/result-union.model';
 import { User } from 'src/users/models/user.model';
 
 export default class LocalService implements IEngineService {
@@ -22,29 +16,7 @@ export default class LocalService implements IEngineService {
     throw new Error('Method not implemented.');
   }
 
-  async createExperiment(
-    data: ExperimentCreateInput,
-    isTransient: boolean,
-  ): Promise<Experiment> {
-    throw new Error('Method not implemented.');
-  }
-
-  async listExperiments(page: number, name: string): Promise<ListExperiments> {
-    throw new Error('Method not implemented.');
-  }
-
-  async getExperiment(id: string): Promise<Experiment> {
-    throw new Error('Method not implemented.');
-  }
-
-  async removeExperiment(id: string): Promise<PartialExperiment> {
-    throw new Error('Method not implemented.');
-  }
-
-  async editExperient(
-    id: string,
-    expriment: ExperimentEditInput,
-  ): Promise<Experiment> {
+  async runExperiment(): Promise<Array<typeof ResultUnion>> {
     throw new Error('Method not implemented.');
   }
 
@@ -68,17 +40,12 @@ export default class LocalService implements IEngineService {
   }
 
   async getActiveUser(): Promise<User> {
-    const dummyUser = {
+    return {
       username: 'anonymous',
       id: 'anonymousId',
       fullname: 'anonymous',
       email: 'anonymous@anonymous.com',
       agreeNDA: true,
     };
-    return dummyUser;
-  }
-
-  getAlgorithmsREST(): string {
-    return '[]';
   }
 }
diff --git a/api/src/engine/engine.interfaces.ts b/api/src/engine/engine.interfaces.ts
index 8ca0765..d9ef0e6 100644
--- a/api/src/engine/engine.interfaces.ts
+++ b/api/src/engine/engine.interfaces.ts
@@ -9,9 +9,10 @@ import {
   Experiment,
   PartialExperiment,
 } from './models/experiment/experiment.model';
-import { ExperimentCreateInput } from './models/experiment/input/experiment-create.input';
-import { ExperimentEditInput } from './models/experiment/input/experiment-edit.input';
+import { ExperimentCreateInput } from '../experiments/models/input/experiment-create.input';
+import { ExperimentEditInput } from '../experiments/models/input/experiment-edit.input';
 import { ListExperiments } from './models/experiment/list-experiments.model';
+import { ResultUnion } from './models/result/common/result-union.model';
 
 export interface IEngineOptions {
   type: string;
@@ -23,45 +24,108 @@ export type IConfiguration = Pick<Configuration, 'contactLink' | 'hasGalaxy'>;
 export interface IEngineService {
   /**
    * Allow specific configuration for the engine
-   *
-   * `connectorId` is always overwrite by the engine module
    */
   getConfiguration?(): IConfiguration;
 
+  /**
+   * Get the list of domains along with a list of variables
+   * @param ids - Ids to filter the domain needed
+   * @param req - Request - this is the request object from the HTTP request.
+   */
   getDomains(ids: string[], req?: Request): Domain[] | Promise<Domain[]>;
 
-  createExperiment(
+  /**
+   * Create and return a full detailed experiment
+   * @param {ExperimentCreateInput} data - ExperimentCreateInput - this is the data that you want to
+   * send to the API.
+   * @param [isTransient=false] - If true, the experiment will be created as a transient experiment.
+   * @param {Request} req - Request - this is the request object from the HTTP request.
+   * @returns An experiment object
+   */
+  createExperiment?(
     data: ExperimentCreateInput,
     isTransient: boolean,
     req?: Request,
   ): Promise<Experiment>;
 
+  /**
+   * Run an experiment and return results (Transient only)
+   * @param {ExperimentCreateInput} data - ExperimentCreateInput - Data context for the experiment.
+   * @param {Request} req - Request - this is the request object from the HTTP request.
+   * @returns ResultUnion
+   */
+  runExperiment?(
+    data: ExperimentCreateInput,
+    req?: Request,
+  ): Promise<Array<typeof ResultUnion>>;
+
+  /**
+   * Get a list of experiment (limited to 10 per page)
+   * @param page - the page number
+   * @param name - the name of the experiment you are looking for
+   * @param req - Request - this is the request object from the HTTP request.
+   */
   listExperiments?(
     page: number,
     name: string,
     req?: Request,
   ): Promise<ListExperiments>;
 
-  getExperiment(id: string, req?: Request): Promise<Experiment>;
+  /**
+   * It takes an experiment id and a request object, and returns a promise of an experiment
+   * @param {string} id - the id of the experiment you want to get
+   * @param {Request} req - Request - this is the request object from the HTTP request.
+   * @returns An experiment object
+   */
+  getExperiment?(id: string, req?: Request): Promise<Experiment>;
 
+  /**
+   * Remove an experiment
+   * @param id - the id of the experiment you want to remove
+   * @param req - this is the request object from the user HTTP request
+   */
   removeExperiment?(id: string, req?: Request): Promise<PartialExperiment>;
 
-  editExperient?(
+  /**
+   * Update an experiment
+   * @param id - the id of the experiment you want to remove
+   * @param data - this is the data object containing the updated fields
+   * @param req - this is the request object from the user HTTP request
+   */
+  editExperiment?(
     id: string,
-    expriment: ExperimentEditInput,
+    data: ExperimentEditInput,
     req?: Request,
   ): Promise<Experiment>;
 
+  /**
+   * Retrieve the list of available algorithms
+   * @param req - Request - this is the request object from the HTTP request.
+   */
   getAlgorithms(req?: Request): Promise<Algorithm[]>;
 
+  /**
+   * Get the current user logged in
+   * @param req - Request - this is the request object from the HTTP request.
+   */
   getActiveUser?(req?: Request): Promise<User>;
 
+  /**
+   * Update the current logged in user
+   * @param req - Request - this is the request object from the HTTP request.
+   * @param userId - the id to update
+   * @param data - Data object with the updated fields
+   */
   updateUser?(
     req?: Request,
     userId?: string,
     data?: UpdateUserInput,
   ): Promise<UpdateUserInput | undefined>;
 
+  /**
+   * Perform a logout on the current logged in user
+   * @param req - Request - this is the request object from the HTTP request.
+   */
   logout?(req?: Request): Promise<void>;
 
   /**
diff --git a/api/src/engine/engine.module.ts b/api/src/engine/engine.module.ts
index efdf729..d636740 100644
--- a/api/src/engine/engine.module.ts
+++ b/api/src/engine/engine.module.ts
@@ -1,5 +1,11 @@
 import { HttpModule, HttpService } from '@nestjs/axios';
-import { DynamicModule, Global, Logger, Module } from '@nestjs/common';
+import {
+  DynamicModule,
+  Global,
+  InternalServerErrorException,
+  Logger,
+  Module,
+} from '@nestjs/common';
 import { ENGINE_MODULE_OPTIONS, ENGINE_SERVICE } from './engine.constants';
 import { EngineController } from './engine.controller';
 import { IEngineOptions, IEngineService } from './engine.interfaces';
@@ -23,7 +29,7 @@ export class EngineModule {
     const engineProvider = {
       provide: ENGINE_SERVICE,
       useFactory: async (httpService: HttpService) => {
-        return await this.createEngineConnection(
+        return this.createEngineConnection(
           optionsProvider.useValue,
           httpService,
         );
@@ -44,14 +50,24 @@ export class EngineModule {
     opt: IEngineOptions,
     httpService: HttpService,
   ): Promise<IEngineService> {
-    try {
-      const service = await import(`./connectors/${opt.type}/main.connector`);
-      const engine = new service.default(opt, httpService);
+    const service = await import(`./connectors/${opt.type}/main.connector`);
+    const instance: IEngineService = new service.default(opt, httpService);
 
-      return engine;
-    } catch (e) {
-      this.logger.error(`There is a problem with the connector '${opt.type}'`);
-      this.logger.verbose(e);
-    }
+    if (instance.createExperiment && instance.runExperiment)
+      throw new InternalServerErrorException(
+        `Connector ${opt.type} should declare either createExperiment or runExperiment not both`,
+      );
+
+    if (
+      instance.createExperiment &&
+      (!instance.getExperiment ||
+        !instance.listExperiments ||
+        !instance.removeExperiment ||
+        !instance.editExperiment)
+    )
+      throw new InternalServerErrorException(
+        `Connector ${opt.type} has 'createExperiment' implemented it implies that getExperiment, listExperiments, removeExperiment and editExperiment methods must also be implemented.`,
+      );
+    return instance;
   }
 }
diff --git a/api/src/engine/engine.resolver.ts b/api/src/engine/engine.resolver.ts
index d5acde6..78b2abd 100644
--- a/api/src/engine/engine.resolver.ts
+++ b/api/src/engine/engine.resolver.ts
@@ -1,9 +1,13 @@
 import { Inject, UseGuards, UseInterceptors } from '@nestjs/common';
-import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
+import { ConfigService } from '@nestjs/config';
+import { Args, Query, Resolver } from '@nestjs/graphql';
 import { Request } from 'express';
-import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
-import { GQLRequest } from '../common/decorators/gql-request.decoractor';
+import { Public } from 'src/auth/decorators/public.decorator';
+import { GlobalAuthGuard } from 'src/auth/guards/global-auth.guard';
 import { Md5 } from 'ts-md5';
+import { authConstants } from '../auth/auth-constants';
+import { GQLRequest } from '../common/decorators/gql-request.decoractor';
+import { parseToBoolean } from '../common/utilities';
 import {
   ENGINE_MODULE_OPTIONS,
   ENGINE_ONTOLOGY_URL,
@@ -11,24 +15,13 @@ import {
   ENGINE_SKIP_TOS,
 } from './engine.constants';
 import { IEngineOptions, IEngineService } from './engine.interfaces';
+import { ErrorsInterceptor } from './interceptors/errors.interceptor';
 import { Configuration } from './models/configuration.model';
 import { Domain } from './models/domain.model';
 import { Algorithm } from './models/experiment/algorithm.model';
-import {
-  Experiment,
-  PartialExperiment,
-} from './models/experiment/experiment.model';
-import { ExperimentCreateInput } from './models/experiment/input/experiment-create.input';
-import { ExperimentEditInput } from './models/experiment/input/experiment-edit.input';
-import { ListExperiments } from './models/experiment/list-experiments.model';
-import { ConfigService } from '@nestjs/config';
-import { parseToBoolean } from '../common/utilities';
-import { authConstants } from '../auth/auth-constants';
-import { Public } from 'src/auth/decorators/public.decorator';
-import { ErrorsInterceptor } from './interceptors/errors.interceptor';
 
 @UseInterceptors(ErrorsInterceptor)
-@UseGuards(JwtAuthGuard)
+@UseGuards(GlobalAuthGuard)
 @Resolver()
 export class EngineResolver {
   constructor(
@@ -76,53 +69,8 @@ export class EngineResolver {
     return this.engineService.getDomains(ids, req);
   }
 
-  @Query(() => ListExperiments)
-  async experimentList(
-    @Args('page', { nullable: true, defaultValue: 0 }) page: number,
-    @Args('name', { nullable: true, defaultValue: '' }) name: string,
-    @GQLRequest() req: Request,
-  ) {
-    return this.engineService.listExperiments(page, name, req);
-  }
-
-  @Query(() => Experiment)
-  async experiment(@Args('id') id: string, @GQLRequest() req: Request) {
-    return this.engineService.getExperiment(id, req);
-  }
-
   @Query(() => [Algorithm])
   async algorithms(@GQLRequest() req: Request) {
     return this.engineService.getAlgorithms(req);
   }
-
-  @Mutation(() => Experiment)
-  async createExperiment(
-    @GQLRequest() req: Request,
-    @Args('data') experimentCreateInput: ExperimentCreateInput,
-    @Args('isTransient', { nullable: true, defaultValue: false })
-    isTransient: boolean,
-  ) {
-    return this.engineService.createExperiment(
-      experimentCreateInput,
-      isTransient,
-      req,
-    );
-  }
-
-  @Mutation(() => Experiment)
-  async editExperiment(
-    @GQLRequest() req: Request,
-    @Args('id') id: string,
-    @Args('data') experiment: ExperimentEditInput,
-  ) {
-    return this.engineService.editExperient(id, experiment, req);
-  }
-
-  @Mutation(() => PartialExperiment)
-  async removeExperiment(
-    @Args('id') id: string,
-    @GQLRequest() req: Request,
-  ): Promise<PartialExperiment> {
-    return this.engineService.removeExperiment(id, req);
-  }
 }
diff --git a/api/src/engine/models/experiment/experiment.model.ts b/api/src/engine/models/experiment/experiment.model.ts
index b0fed2a..bffd7e8 100644
--- a/api/src/engine/models/experiment/experiment.model.ts
+++ b/api/src/engine/models/experiment/experiment.model.ts
@@ -1,7 +1,25 @@
-import { Field, ObjectType, PartialType } from '@nestjs/graphql';
+import {
+  Field,
+  ObjectType,
+  PartialType,
+  registerEnumType,
+} from '@nestjs/graphql';
+import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
 import { ResultUnion } from '../result/common/result-union.model';
 import { Author } from './author.model';
 
+export enum ExperimentStatus {
+  INIT = 'init',
+  PENDING = 'pending',
+  SUCCESS = 'success',
+  WARN = 'warn',
+  ERROR = 'error',
+}
+
+registerEnumType(ExperimentStatus, {
+  name: 'ExperimentStatus',
+});
+
 @ObjectType()
 export class Transformation {
   @Field({ description: "Variable's id on which to apply the transformation" })
@@ -37,59 +55,82 @@ export class AlgorithmResult {
   parameters?: ParamValue[];
 }
 
+@Entity()
 @ObjectType()
 export class Experiment {
+  @PrimaryGeneratedColumn('uuid')
   @Field()
   id: string;
 
+  @Column()
   @Field()
   name: string;
 
+  @Column('jsonb', { nullable: true })
   @Field(() => Author, { nullable: true, defaultValue: '' })
   author?: Author;
 
+  @Column()
   @Field({ nullable: true })
-  createdAt?: number;
+  createdAt?: string;
 
+  @Column({ nullable: true })
   @Field({ nullable: true })
-  updateAt?: number;
+  updateAt?: string;
 
+  @Column({ nullable: true })
   @Field({ nullable: true })
-  finishedAt?: number;
+  finishedAt?: string;
 
+  @Column({ nullable: true, default: false })
   @Field({ nullable: true, defaultValue: false })
   viewed?: boolean;
 
-  @Field({ nullable: true })
-  status?: string;
+  @Column({
+    type: 'enum',
+    enum: ExperimentStatus,
+    default: ExperimentStatus.INIT,
+  })
+  @Field(() => ExperimentStatus, { nullable: true })
+  status?: ExperimentStatus;
 
+  @Column({ nullable: true, default: false })
   @Field({ defaultValue: false })
   shared?: boolean;
 
+  @Column('jsonb', { nullable: true })
   @Field(() => [ResultUnion], { nullable: true, defaultValue: [] })
   results?: Array<typeof ResultUnion>;
 
+  @Column('text', { array: true })
   @Field(() => [String])
   datasets: string[];
 
+  @Column({ nullable: true })
   @Field(() => String, { nullable: true })
   filter?: string;
 
+  @Column()
   @Field()
   domain: string;
 
+  @Column('text', { array: true })
   @Field(() => [String])
   variables: string[];
 
+  @Column('text', { nullable: true, array: true })
   @Field(() => [String], { nullable: true, defaultValue: [] })
   coVariables?: string[];
 
+  @Column('text', { nullable: true, array: true })
   @Field(() => [String], { nullable: true, defaultValue: [] })
   filterVariables?: string[];
 
+  @Column('jsonb', { nullable: true })
   @Field(() => Formula, { nullable: true })
   formula?: Formula;
 
+  @Column('jsonb', { nullable: true })
   @Field()
   algorithm: AlgorithmResult;
 }
diff --git a/api/src/engine/models/experiment/list-experiments.model.ts b/api/src/engine/models/experiment/list-experiments.model.ts
index 8f8592e..6d00ac5 100644
--- a/api/src/engine/models/experiment/list-experiments.model.ts
+++ b/api/src/engine/models/experiment/list-experiments.model.ts
@@ -12,6 +12,6 @@ export class ListExperiments {
   @Field({ nullable: true })
   totalExperiments?: number;
 
-  @Field(() => [Experiment])
+  @Field(() => [Experiment], { nullable: true, defaultValue: [] })
   experiments: Experiment[];
 }
diff --git a/api/src/experiments/dto/experiment-update.dto.ts b/api/src/experiments/dto/experiment-update.dto.ts
new file mode 100644
index 0000000..71e1db0
--- /dev/null
+++ b/api/src/experiments/dto/experiment-update.dto.ts
@@ -0,0 +1,3 @@
+import { Experiment } from '../../engine/models/experiment/experiment.model';
+
+export type ExperimentUpdateDto = Partial<Omit<Experiment, 'id' | 'author'>>;
diff --git a/api/src/experiments/experiments.module.ts b/api/src/experiments/experiments.module.ts
new file mode 100644
index 0000000..1226957
--- /dev/null
+++ b/api/src/experiments/experiments.module.ts
@@ -0,0 +1,11 @@
+import { Module } from '@nestjs/common';
+import { ExperimentsService } from './experiments.service';
+import { ExperimentsResolver } from './experiments.resolver';
+import { TypeOrmModule } from '@nestjs/typeorm';
+import { Experiment } from 'src/engine/models/experiment/experiment.model';
+
+@Module({
+  imports: [TypeOrmModule.forFeature([Experiment])],
+  providers: [ExperimentsService, ExperimentsResolver],
+})
+export class ExperimentsModule {}
diff --git a/api/src/experiments/experiments.resolver.spec.ts b/api/src/experiments/experiments.resolver.spec.ts
new file mode 100644
index 0000000..0ff1cb0
--- /dev/null
+++ b/api/src/experiments/experiments.resolver.spec.ts
@@ -0,0 +1,248 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { ExperimentStatus } from '../engine/models/experiment/experiment.model';
+import { User } from '../users/models/user.model';
+import { ENGINE_SERVICE } from '../engine/engine.constants';
+import { IEngineService } from '../engine/engine.interfaces';
+import { ExperimentsResolver } from './experiments.resolver';
+import { ExperimentsService } from './experiments.service';
+import { ExperimentCreateInput } from './models/input/experiment-create.input';
+import { ExperimentEditInput } from './models/input/experiment-edit.input';
+
+type MockEngineService = Partial<Record<keyof IEngineService, jest.Mock>>;
+type MockExperimentService = Partial<
+  Record<keyof ExperimentsService, jest.Mock>
+>;
+
+const createEngineService = (): MockEngineService => ({
+  getDomains: jest.fn(),
+  getAlgorithms: jest.fn(),
+  createExperiment: jest.fn(),
+  runExperiment: jest.fn(),
+  getExperiment: jest.fn(),
+  editExperiment: jest.fn(),
+  listExperiments: jest.fn(),
+  removeExperiment: jest.fn(),
+});
+
+const createExperimentsService = (): MockExperimentService => ({
+  findAll: jest.fn(),
+  findOne: jest.fn(),
+  dataToExperiment: jest.fn(),
+  create: jest.fn(),
+  update: jest.fn(),
+  remove: jest.fn(),
+});
+
+describe('ExperimentsResolver', () => {
+  let resolver: ExperimentsResolver;
+  let engineService: MockEngineService;
+  let experimentsService: MockExperimentService;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      providers: [
+        ExperimentsResolver,
+        { provide: ExperimentsService, useValue: createExperimentsService() },
+        {
+          provide: ENGINE_SERVICE,
+          useValue: createEngineService(),
+        },
+      ],
+    }).compile();
+
+    engineService = module.get<MockEngineService>(ENGINE_SERVICE);
+    experimentsService = module.get<ExperimentsService>(
+      ExperimentsService,
+    ) as unknown as MockExperimentService;
+    resolver = module.get<ExperimentsResolver>(ExperimentsResolver);
+  });
+
+  it('should be defined', () => {
+    expect(resolver).toBeDefined();
+  });
+
+  describe('experimentList', () => {
+    describe('when engine method exist', () => {
+      it('should call engine method', async () => {
+        const request: any = jest.fn();
+        engineService.listExperiments.mockReturnValue({});
+        await resolver.experimentList(0, '', request);
+
+        expect(engineService.listExperiments.mock.calls.length).toBeGreaterThan(
+          0,
+        );
+      });
+    });
+
+    describe('when engine method does not exist', () => {
+      it('should call service method', async () => {
+        const request: any = jest.fn();
+        engineService.listExperiments = undefined;
+        experimentsService.findAll.mockReturnValue([[], 9]);
+        await resolver.experimentList(0, '', request);
+
+        expect(experimentsService.findAll.mock.calls.length).toBeGreaterThan(0);
+      });
+    });
+  });
+
+  describe('experiment', () => {
+    describe('when engine method exist', () => {
+      it('should call engine method', async () => {
+        const request: any = jest.fn();
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        await resolver.experiment('test', request, user);
+
+        expect(experimentsService.findOne.mock.calls.length).toBe(0);
+        expect(engineService.getExperiment.mock.calls.length).toBeGreaterThan(
+          0,
+        );
+      });
+    });
+
+    describe('when engine method does not exist', () => {
+      it('should call service method', async () => {
+        const request: any = jest.fn();
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        engineService.getExperiment = undefined;
+        await resolver.experiment('test', request, user);
+
+        expect(experimentsService.findOne.mock.calls.length).toBeGreaterThan(0);
+      });
+    });
+  });
+
+  describe('createExperiment', () => {
+    describe('when engine method exist', () => {
+      it('should call engine method', async () => {
+        const request: any = jest.fn();
+        const data: ExperimentCreateInput =
+          {} as unknown as ExperimentCreateInput;
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        await resolver.createExperiment(request, user, data, true);
+
+        expect(experimentsService.create.mock.calls.length).toBe(0);
+        expect(
+          engineService.createExperiment.mock.calls.length,
+        ).toBeGreaterThan(0);
+      });
+    });
+
+    describe('when engine method does not exist', () => {
+      it('should call service method', async () => {
+        const request: any = jest.fn();
+        const data: ExperimentCreateInput =
+          {} as unknown as ExperimentCreateInput;
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        engineService.createExperiment = undefined;
+        engineService.runExperiment.mockResolvedValue([]);
+        experimentsService.create.mockReturnValue({ id: 'test' });
+        await resolver.createExperiment(request, user, data, false);
+
+        expect(experimentsService.create.mock.calls.length).toBeGreaterThan(0);
+      });
+
+      it('should only call runExperiment if transient', async () => {
+        const request: any = jest.fn();
+        const data: ExperimentCreateInput =
+          {} as unknown as ExperimentCreateInput;
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        engineService.createExperiment = undefined;
+        engineService.runExperiment.mockResolvedValue([]);
+        experimentsService.create.mockReturnValue({ id: 'test' });
+        const result = await resolver.createExperiment(
+          request,
+          user,
+          data,
+          true,
+        );
+
+        expect(engineService.runExperiment.mock.calls.length).toBeGreaterThan(
+          0,
+        );
+        expect(result.status).toBe(ExperimentStatus.SUCCESS);
+      });
+    });
+  });
+
+  describe('editExperiment', () => {
+    describe('when engine method exist', () => {
+      it('should call engine method', async () => {
+        const request: any = jest.fn();
+        const data: ExperimentEditInput = {} as unknown as ExperimentEditInput;
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        await resolver.editExperiment(request, 'test', data, user);
+
+        expect(experimentsService.update.mock.calls.length).toBe(0);
+        expect(engineService.editExperiment.mock.calls.length).toBeGreaterThan(
+          0,
+        );
+      });
+    });
+
+    describe('when engine method does not exist', () => {
+      it('should call service method', async () => {
+        const request: any = jest.fn();
+        const data: ExperimentEditInput = {} as unknown as ExperimentEditInput;
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        engineService.editExperiment = undefined;
+        await resolver.editExperiment(request, 'test', data, user);
+
+        expect(experimentsService.update.mock.calls.length).toBeGreaterThan(0);
+      });
+    });
+  });
+
+  describe('removeExperiment', () => {
+    describe('when engine method exist', () => {
+      it('should call engine method', async () => {
+        const request: any = jest.fn();
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        await resolver.removeExperiment('test', request, user);
+
+        expect(experimentsService.remove.mock.calls.length).toBe(0);
+        expect(
+          engineService.removeExperiment.mock.calls.length,
+        ).toBeGreaterThan(0);
+      });
+    });
+
+    describe('when engine method does not exist', () => {
+      it('should call service method', async () => {
+        const request: any = jest.fn();
+        const user: User = {
+          id: 'dummyUser',
+          username: 'test',
+        };
+        engineService.removeExperiment = undefined;
+        await resolver.removeExperiment('test', request, user);
+
+        expect(experimentsService.remove.mock.calls.length).toBeGreaterThan(0);
+      });
+    });
+  });
+});
diff --git a/api/src/experiments/experiments.resolver.ts b/api/src/experiments/experiments.resolver.ts
new file mode 100644
index 0000000..754761e
--- /dev/null
+++ b/api/src/experiments/experiments.resolver.ts
@@ -0,0 +1,137 @@
+import { Inject, Logger, UseGuards } from '@nestjs/common';
+import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
+import { Request } from 'express';
+import { GlobalAuthGuard } from '../auth/guards/global-auth.guard';
+import { GQLRequest } from '../common/decorators/gql-request.decoractor';
+import { CurrentUser } from '../common/decorators/user.decorator';
+import { ENGINE_SERVICE } from '../engine/engine.constants';
+import { IEngineService } from '../engine/engine.interfaces';
+import {
+  Experiment,
+  ExperimentStatus,
+  PartialExperiment,
+} from '../engine/models/experiment/experiment.model';
+import { ListExperiments } from '../engine/models/experiment/list-experiments.model';
+import { User } from '../users/models/user.model';
+import { ExperimentsService } from './experiments.service';
+import { ExperimentCreateInput } from './models/input/experiment-create.input';
+import { ExperimentEditInput } from './models/input/experiment-edit.input';
+
+const LIMIT_EXP_BY_PAGE = 10; // TODO Consider refactoring to allow offset and limit in API call
+
+@UseGuards(GlobalAuthGuard)
+@Resolver()
+export class ExperimentsResolver {
+  private readonly logger = new Logger(ExperimentsResolver.name);
+
+  constructor(
+    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
+    private readonly experimentService: ExperimentsService,
+  ) {}
+
+  @Query(() => ListExperiments)
+  async experimentList(
+    @Args('page', { nullable: true, defaultValue: 0 }) page: number,
+    @Args('name', { nullable: true, defaultValue: '' }) name: string,
+    @GQLRequest() req: Request,
+  ): Promise<ListExperiments> {
+    if (this.engineService.listExperiments) {
+      return this.engineService.listExperiments(page, name, req);
+    }
+
+    const [results, total] = await this.experimentService.findAll(
+      {
+        limit: LIMIT_EXP_BY_PAGE,
+        offset: LIMIT_EXP_BY_PAGE * page,
+      },
+      name,
+    );
+    return {
+      experiments: results,
+      currentPage: page,
+      totalExperiments: total,
+      totalPages: Math.ceil(total / LIMIT_EXP_BY_PAGE),
+    };
+  }
+
+  @Query(() => Experiment)
+  async experiment(
+    @Args('id') id: string,
+    @GQLRequest() req: Request,
+    @CurrentUser() user: User,
+  ) {
+    if (this.engineService.getExperiment)
+      return this.engineService.getExperiment(id, req);
+
+    return this.experimentService.findOne(id, user);
+  }
+
+  @Mutation(() => Experiment)
+  async createExperiment(
+    @GQLRequest() req: Request,
+    @CurrentUser() user: User,
+    @Args('data') data: ExperimentCreateInput,
+    @Args('isTransient', { nullable: true, defaultValue: false })
+    isTransient: boolean,
+  ) {
+    if (this.engineService.createExperiment) {
+      return this.engineService.createExperiment(data, isTransient, req);
+    }
+
+    //if the experiment is transient we wait a response before returning a response
+    if (isTransient) {
+      const results = await this.engineService.runExperiment(data, req);
+      const expTransient = this.experimentService.dataToExperiment(data, user);
+      return { ...expTransient, results, status: ExperimentStatus.SUCCESS };
+    }
+
+    //if not we will create an experiment in local db
+    const experiment = await this.experimentService.create(
+      data,
+      user,
+      ExperimentStatus.PENDING,
+    );
+
+    //create an async query that will update the result when it's done
+    this.engineService.runExperiment(data, req).then((results) => {
+      this.experimentService.update(
+        experiment.id,
+        {
+          results,
+          finishedAt: new Date().toISOString(),
+          status: ExperimentStatus.SUCCESS,
+        },
+        user,
+      );
+    });
+
+    //we return the experiment before finishing the runExperiment
+    return experiment;
+  }
+
+  @Mutation(() => Experiment)
+  async editExperiment(
+    @GQLRequest() req: Request,
+    @Args('id') id: string,
+    @Args('data') experiment: ExperimentEditInput,
+    @CurrentUser() user: User,
+  ) {
+    console.log(this.engineService.editExperiment);
+    if (this.engineService.editExperiment)
+      return this.engineService.editExperiment(id, experiment, req);
+
+    return this.experimentService.update(id, experiment, user);
+  }
+
+  @Mutation(() => PartialExperiment)
+  async removeExperiment(
+    @Args('id') id: string,
+    @GQLRequest() req: Request,
+    @CurrentUser() user: User,
+  ): Promise<PartialExperiment> {
+    if (this.engineService.removeExperiment)
+      return this.engineService.removeExperiment(id, req);
+
+    return this.experimentService.remove(id, user);
+  }
+}
diff --git a/api/src/experiments/experiments.service.spec.ts b/api/src/experiments/experiments.service.spec.ts
new file mode 100644
index 0000000..4ff6cbf
--- /dev/null
+++ b/api/src/experiments/experiments.service.spec.ts
@@ -0,0 +1,184 @@
+import { ForbiddenException, NotFoundException } from '@nestjs/common';
+import { Test, TestingModule } from '@nestjs/testing';
+import { getRepositoryToken } from '@nestjs/typeorm';
+import { User } from 'src/users/models/user.model';
+import { Repository } from 'typeorm';
+import { Experiment } from '../engine/models/experiment/experiment.model';
+import { ExperimentsService } from './experiments.service';
+import { ExperimentCreateInput } from './models/input/experiment-create.input';
+
+type MockRepository<T = any> = Partial<Record<keyof Repository<T>, jest.Mock>>;
+const createMockRepository = <T = any>(): MockRepository<T> => ({
+  findOne: jest.fn(),
+  findAndCount: jest.fn(),
+  create: jest.fn(),
+  save: jest.fn(),
+  remove: jest.fn(),
+  update: jest.fn(),
+});
+
+describe('ExperimentsService', () => {
+  let service: ExperimentsService;
+  let experimentRepository: MockRepository;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      providers: [
+        ExperimentsService,
+        {
+          provide: getRepositoryToken(Experiment),
+          useValue: createMockRepository(),
+        },
+      ],
+    }).compile();
+
+    service = module.get<ExperimentsService>(ExperimentsService);
+    experimentRepository = module.get<MockRepository>(
+      getRepositoryToken(Experiment),
+    );
+  });
+
+  it('should be defined', () => {
+    expect(service).toBeDefined();
+  });
+
+  describe('findOne', () => {
+    describe('when experiment with ID exists', () => {
+      it('should return the experiment object', async () => {
+        const experimentId = '1';
+        const expectedExperiment = {};
+
+        experimentRepository.findOne.mockReturnValue(expectedExperiment);
+        const experiment = await service.findOne(experimentId);
+        expect(experiment).toEqual(expectedExperiment);
+      });
+      it('should throw an error if user does not match ', async () => {
+        const experimentId = '1';
+        const expectedExperiment = {
+          author: {
+            username: 'differentUsername',
+          },
+        };
+        const user: User = {
+          username: 'test',
+          id: 'dummyid',
+        };
+
+        experimentRepository.findOne.mockReturnValue(expectedExperiment);
+
+        try {
+          await service.findOne(experimentId, user);
+        } catch (err) {
+          expect(err).toBeInstanceOf(ForbiddenException);
+        }
+      });
+    });
+    describe('otherwise', () => {
+      it('should throw the "NotFoundException"', async () => {
+        const experimentId = '1';
+        experimentRepository.findOne.mockReturnValue(undefined);
+
+        try {
+          await service.findOne(experimentId);
+        } catch (err) {
+          expect(err).toBeInstanceOf(NotFoundException);
+          expect(err.message).toEqual(`Experiment #${experimentId} not found`);
+        }
+      });
+    });
+  });
+
+  describe('findAll', () => {
+    describe('Should return a list of experiments', () => {
+      it('should return the experiment object', async () => {
+        const excpectedList = [{}, {}, {}];
+        const expectedOutput = [excpectedList, excpectedList.length];
+
+        experimentRepository.findAndCount.mockReturnValue(expectedOutput);
+        const [experimentList, count] = await service.findAll();
+        expect(count).toEqual(excpectedList.length);
+        expect(experimentList).toStrictEqual(excpectedList);
+      });
+    });
+  });
+
+  describe('create', () => {
+    it('Should return an experiment', async () => {
+      const data: ExperimentCreateInput = {
+        domain: 'dummyDomain',
+        variables: [],
+        algorithm: {
+          id: 'dummyAlgo',
+          parameters: [],
+        },
+        datasets: ['dummyDataset'],
+        filter: '',
+        name: 'dummyExperiment',
+      };
+      const user: User = {
+        id: 'userId',
+        username: 'username',
+      };
+
+      const expectedExperiment: Experiment = {
+        ...data,
+        author: {
+          fullname: user.username,
+          username: user.username,
+        },
+        algorithm: {
+          name: data.algorithm.id,
+          parameters: [],
+        },
+        id: 'dummyid',
+      };
+
+      experimentRepository.create.mockReturnValue(expectedExperiment);
+      const experiment = await experimentRepository.create(data, user);
+
+      expect(experiment).toStrictEqual(expectedExperiment);
+    });
+  });
+
+  describe('update', () => {
+    it('should return updated experiment', async () => {
+      const user: User = {
+        id: 'userId',
+        username: 'username',
+      };
+      const expectedExperiment: Experiment = {
+        domain: 'dummyDomain',
+        variables: [],
+        datasets: ['dummyDataset'],
+        filter: '',
+        name: 'dummyExperiment',
+        author: {
+          fullname: user.username,
+          username: user.username,
+        },
+        algorithm: {
+          name: 'dummyAlgo',
+          parameters: [],
+        },
+        id: 'dummyid',
+      };
+
+      const updateData = { name: 'test' };
+
+      experimentRepository.findOne.mockReturnValue({
+        author: {
+          ...user,
+        },
+      });
+      experimentRepository.save.mockReturnValue(expectedExperiment);
+
+      const experiment = await service.update(
+        expectedExperiment.id,
+        updateData,
+        user,
+      );
+
+      expect(experiment).toStrictEqual(expectedExperiment);
+    });
+  });
+});
diff --git a/api/src/experiments/experiments.service.ts b/api/src/experiments/experiments.service.ts
new file mode 100644
index 0000000..e452228
--- /dev/null
+++ b/api/src/experiments/experiments.service.ts
@@ -0,0 +1,145 @@
+import {
+  ForbiddenException,
+  Injectable,
+  NotFoundException,
+} from '@nestjs/common';
+import { InjectRepository } from '@nestjs/typeorm';
+import {
+  Experiment,
+  ExperimentStatus,
+} from '../engine/models/experiment/experiment.model';
+import { User } from 'src/users/models/user.model';
+import { FindManyOptions, Like, Repository } from 'typeorm';
+import { ExperimentCreateInput } from './models/input/experiment-create.input';
+import { PaginationArgsInput } from './models/input/pagination-args.input';
+import { ExperimentUpdateDto } from './dto/experiment-update.dto';
+
+@Injectable()
+export class ExperimentsService {
+  constructor(
+    @InjectRepository(Experiment)
+    private readonly experimentRepository: Repository<Experiment>,
+  ) {}
+
+  /**
+   * It takes in a pagination object and a name, and returns a promise that resolves to an array of
+   * experiments and the total number of experiments
+   * @param {PaginationArgsInput} pagination - PaginationArgsInput = {}
+   * @param [name] - The name of the experiment.
+   * @returns An array of experiments and the total count of experiments.
+   */
+  async findAll(pagination: PaginationArgsInput = {}, name = '') {
+    const options: FindManyOptions<Experiment> = {};
+
+    if (name && name != '') {
+      options.where = { name: Like(`%${name}%`) };
+    }
+    options.order = {
+      createdAt: 'DESC',
+    };
+    options.skip = pagination.offset ?? 0;
+    options.take = pagination.limit ?? 10;
+
+    return this.experimentRepository.findAndCount(options);
+  }
+
+  /**
+   * It finds an experiment by its id, if the experiment does not exist throws a NotFoundException
+   * @param {string} id - string - the id of the experiment we want to find
+   * @returns The experiment object
+   */
+  async findOne(id: string): Promise<Experiment>;
+
+  /**
+   * It finds an experiment by its id, and if the user is not the author of the experiment, it throws a
+   * ForbiddenException
+   * @param {string} id - string - the id of the experiment we want to find
+   * @param {User} [user] - User - the user that is making the request
+   * @returns The experiment object
+   */
+  async findOne(id: string, user: User): Promise<Experiment>;
+  async findOne(id: string, user?: User): Promise<Experiment> {
+    const experiment = await this.experimentRepository.findOne(id);
+
+    if (!experiment) throw new NotFoundException(`Experiment #${id} not found`);
+
+    if (user && experiment.author.username !== user.username)
+      throw new ForbiddenException(
+        `Experiment #${id} is not available for user ${user.username}`,
+      );
+
+    return experiment;
+  }
+
+  dataToExperiment(
+    data: ExperimentCreateInput,
+    user: User,
+    status?: ExperimentStatus,
+  ): Partial<Experiment> {
+    return {
+      ...data,
+      status,
+      author: {
+        username: user.username,
+        fullname: user.fullname ?? user.username,
+      },
+      createdAt: new Date().toISOString(),
+      algorithm: {
+        name: data.algorithm.id,
+        parameters: data.algorithm.parameters.map((p) => ({
+          name: p.id,
+          value: p.value,
+        })),
+      },
+    };
+  }
+
+  /**
+   * It creates a new experiment and saves it to the database
+   * @param {ExperimentCreateInput} data - ExperimentCreateInput
+   * @param {User} user - User - This is the user that is currently logged in.
+   * @returns The experiment that was created.
+   */
+  create(
+    data: ExperimentCreateInput,
+    user: User,
+    status = ExperimentStatus.INIT,
+  ): Promise<Experiment> {
+    const experiment = this.experimentRepository.create(
+      this.dataToExperiment(data, user, status),
+    );
+
+    return this.experimentRepository.save(experiment);
+  }
+
+  /**
+   * It finds an experiment by id and user, then updates it with the new data
+   * @param {string} id - The id of the experiment to update
+   * @param {ExperimentUpdateDto} data - ExperimentUpdateDto
+   * @param {User} user - User - this is the user that is currently logged in.
+   * @returns The updated experiment
+   */
+  async update(id: string, data: ExperimentUpdateDto, user: User) {
+    const experiment = await this.findOne(id, user);
+
+    return this.experimentRepository.save({
+      ...experiment,
+      ...data,
+      id,
+      updateAt: new Date().toISOString(),
+    });
+  }
+
+  /**
+   * Find an experiment by id, then remove it.
+   *
+   * @param {string} id - The id of the experiment to be deleted.
+   * @param {User} user - User - This is the user that is currently logged in.
+   * @returns The experiment that was removed.
+   */
+  async remove(id: string, user: User): Promise<Experiment> {
+    const experiment = await this.findOne(id, user);
+
+    return this.experimentRepository.remove(experiment);
+  }
+}
diff --git a/api/src/engine/models/experiment/input/algorithm-parameter.input.ts b/api/src/experiments/models/input/algorithm-parameter.input.ts
similarity index 100%
rename from api/src/engine/models/experiment/input/algorithm-parameter.input.ts
rename to api/src/experiments/models/input/algorithm-parameter.input.ts
diff --git a/api/src/engine/models/experiment/input/algorithm.input.ts b/api/src/experiments/models/input/algorithm.input.ts
similarity index 100%
rename from api/src/engine/models/experiment/input/algorithm.input.ts
rename to api/src/experiments/models/input/algorithm.input.ts
diff --git a/api/src/engine/models/experiment/input/experiment-create.input.ts b/api/src/experiments/models/input/experiment-create.input.ts
similarity index 100%
rename from api/src/engine/models/experiment/input/experiment-create.input.ts
rename to api/src/experiments/models/input/experiment-create.input.ts
diff --git a/api/src/engine/models/experiment/input/experiment-edit.input.ts b/api/src/experiments/models/input/experiment-edit.input.ts
similarity index 100%
rename from api/src/engine/models/experiment/input/experiment-edit.input.ts
rename to api/src/experiments/models/input/experiment-edit.input.ts
diff --git a/api/src/experiments/models/input/pagination-args.input.ts b/api/src/experiments/models/input/pagination-args.input.ts
new file mode 100644
index 0000000..541b089
--- /dev/null
+++ b/api/src/experiments/models/input/pagination-args.input.ts
@@ -0,0 +1,10 @@
+import { Field, InputType } from '@nestjs/graphql';
+
+@InputType()
+export class PaginationArgsInput {
+  @Field()
+  limit?: number;
+
+  @Field()
+  offset?: number;
+}
diff --git a/api/src/main/app.module.ts b/api/src/main/app.module.ts
index ebc1be9..dd03343 100644
--- a/api/src/main/app.module.ts
+++ b/api/src/main/app.module.ts
@@ -9,6 +9,7 @@ import { AuthModule } from 'src/auth/auth.module';
 import dbConfig from 'src/config/db.config';
 import matomoConfig from 'src/config/matomo.config';
 import { EngineModule } from 'src/engine/engine.module';
+import { ExperimentsModule } from 'src/experiments/experiments.module';
 import { FilesModule } from 'src/files/files.module';
 import { UsersModule } from 'src/users/users.module';
 import { AppController } from './app.controller';
@@ -59,6 +60,7 @@ import { AppService } from './app.service';
     }),
     AuthModule,
     UsersModule,
+    ExperimentsModule,
     FilesModule,
   ],
   controllers: [AppController],
diff --git a/api/src/migrations/1653484967792-CreateExperimentDB.ts b/api/src/migrations/1653484967792-CreateExperimentDB.ts
new file mode 100644
index 0000000..12a28c1
--- /dev/null
+++ b/api/src/migrations/1653484967792-CreateExperimentDB.ts
@@ -0,0 +1,19 @@
+import { MigrationInterface, QueryRunner } from 'typeorm';
+
+export class CreateExperimentDB1653484967792 implements MigrationInterface {
+  name = 'CreateExperimentDB1653484967792';
+
+  public async up(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.query(
+      `CREATE TYPE "public"."experiment_status_enum" AS ENUM('init', 'pending', 'success', 'warn', 'error')`,
+    );
+    await queryRunner.query(
+      `CREATE TABLE "experiment" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying NOT NULL, "author" jsonb, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updateAt" TIMESTAMP NOT NULL DEFAULT now(), "finishedAt" character varying, "viewed" boolean DEFAULT false, "status" "public"."experiment_status_enum" NOT NULL DEFAULT 'init', "shared" boolean DEFAULT false, "results" jsonb, "datasets" text array NOT NULL, "filter" character varying, "domain" character varying NOT NULL, "variables" text array NOT NULL, "coVariables" text array, "filterVariables" text array, "formula" jsonb, "algorithm" jsonb, CONSTRAINT "PK_4f6eec215c62eec1e0fde987caf" PRIMARY KEY ("id"))`,
+    );
+  }
+
+  public async down(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.query(`DROP TABLE "experiment"`);
+    await queryRunner.query(`DROP TYPE "public"."experiment_status_enum"`);
+  }
+}
diff --git a/api/src/migrations/1653487335545-ExperimentDateTypeUpdate.ts b/api/src/migrations/1653487335545-ExperimentDateTypeUpdate.ts
new file mode 100644
index 0000000..0ad01fb
--- /dev/null
+++ b/api/src/migrations/1653487335545-ExperimentDateTypeUpdate.ts
@@ -0,0 +1,29 @@
+import { MigrationInterface, QueryRunner } from 'typeorm';
+
+export class ExperimentDateTypeUpdate1653487335545
+  implements MigrationInterface
+{
+  name = 'ExperimentDateTypeUpdate1653487335545';
+
+  public async up(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.query(`ALTER TABLE "experiment" DROP COLUMN "createdAt"`);
+    await queryRunner.query(
+      `ALTER TABLE "experiment" ADD "createdAt" character varying NOT NULL`,
+    );
+    await queryRunner.query(`ALTER TABLE "experiment" DROP COLUMN "updateAt"`);
+    await queryRunner.query(
+      `ALTER TABLE "experiment" ADD "updateAt" character varying`,
+    );
+  }
+
+  public async down(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.query(`ALTER TABLE "experiment" DROP COLUMN "updateAt"`);
+    await queryRunner.query(
+      `ALTER TABLE "experiment" ADD "updateAt" TIMESTAMP NOT NULL DEFAULT now()`,
+    );
+    await queryRunner.query(`ALTER TABLE "experiment" DROP COLUMN "createdAt"`);
+    await queryRunner.query(
+      `ALTER TABLE "experiment" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`,
+    );
+  }
+}
diff --git a/api/src/schema.gql b/api/src/schema.gql
index 61f22d7..bacb2ed 100644
--- a/api/src/schema.gql
+++ b/api/src/schema.gql
@@ -301,11 +301,11 @@ type Experiment {
   id: String!
   name: String!
   author: Author
-  createdAt: Float
-  updateAt: Float
-  finishedAt: Float
+  createdAt: String
+  updateAt: String
+  finishedAt: String
   viewed: Boolean
-  status: String
+  status: ExperimentStatus
   shared: Boolean!
   results: [ResultUnion!]
   datasets: [String!]!
@@ -318,15 +318,23 @@ type Experiment {
   algorithm: AlgorithmResult!
 }
 
+enum ExperimentStatus {
+  INIT
+  PENDING
+  SUCCESS
+  WARN
+  ERROR
+}
+
 type PartialExperiment {
   id: String
   name: String
   author: Author
-  createdAt: Float
-  updateAt: Float
-  finishedAt: Float
+  createdAt: String
+  updateAt: String
+  finishedAt: String
   viewed: Boolean
-  status: String
+  status: ExperimentStatus
   shared: Boolean
   results: [ResultUnion!]
   datasets: [String!]
@@ -343,25 +351,34 @@ type ListExperiments {
   currentPage: Float
   totalPages: Float
   totalExperiments: Float
-  experiments: [Experiment!]!
+  experiments: [Experiment!]
 }
 
 type Query {
   configuration: Configuration!
   domains(ids: [String!] = []): [Domain!]!
-  experimentList(page: Float = 0, name: String = ""): ListExperiments!
-  experiment(id: String!): Experiment!
   algorithms: [Algorithm!]!
   user: User!
+  experimentList(page: Float = 0, name: String = ""): ListExperiments!
+  experiment(id: String!): Experiment!
 }
 
 type Mutation {
-  createExperiment(data: ExperimentCreateInput!, isTransient: Boolean = false): Experiment!
-  editExperiment(id: String!, data: ExperimentEditInput!): Experiment!
-  removeExperiment(id: String!): PartialExperiment!
   login(variables: AuthenticationInput!): AuthenticationOutput!
   logout: Boolean!
   updateUser(updateUserInput: UpdateUserInput!): User!
+  createExperiment(data: ExperimentCreateInput!, isTransient: Boolean = false): Experiment!
+  editExperiment(id: String!, data: ExperimentEditInput!): Experiment!
+  removeExperiment(id: String!): PartialExperiment!
+}
+
+input AuthenticationInput {
+  username: String!
+  password: String!
+}
+
+input UpdateUserInput {
+  agreeNDA: Boolean!
 }
 
 input ExperimentCreateInput {
@@ -397,12 +414,3 @@ input ExperimentEditInput {
   shared: Boolean
   viewed: Boolean
 }
-
-input AuthenticationInput {
-  username: String!
-  password: String!
-}
-
-input UpdateUserInput {
-  agreeNDA: Boolean!
-}
diff --git a/api/src/users/users.resolver.ts b/api/src/users/users.resolver.ts
index ad1fcd0..494f842 100644
--- a/api/src/users/users.resolver.ts
+++ b/api/src/users/users.resolver.ts
@@ -7,15 +7,15 @@ import {
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import { ENGINE_SERVICE } from '../engine/engine.constants';
 import { IEngineService } from '../engine/engine.interfaces';
-import { CurrentUser } from '../auth/decorators/user.decorator';
-import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
 import { UpdateUserInput } from './inputs/update-user.input';
 import { User } from './models/user.model';
 import { UsersService } from './users.service';
 import { GQLRequest } from '../common/decorators/gql-request.decoractor';
 import { Request } from 'express';
+import { CurrentUser } from '../common/decorators/user.decorator';
+import { GlobalAuthGuard } from '../auth/guards/global-auth.guard';
 
-@UseGuards(JwtAuthGuard)
+@UseGuards(GlobalAuthGuard)
 @Resolver()
 export class UsersResolver {
   private readonly logger = new Logger(UsersResolver.name);
@@ -87,6 +87,6 @@ export class UsersResolver {
     if (updateData && Object.keys(updateData).length > 0)
       await this.usersService.update(user.id, updateData);
 
-    return await this.getUser(request, user);
+    return this.getUser(request, user);
   }
 }
diff --git a/api/src/users/users.service.ts b/api/src/users/users.service.ts
index d74ca14..bd8105d 100644
--- a/api/src/users/users.service.ts
+++ b/api/src/users/users.service.ts
@@ -38,6 +38,6 @@ export class UsersService {
       ...data,
     };
 
-    return await this.userRepository.save(updateData);
+    return this.userRepository.save(updateData);
   }
 }
-- 
GitLab