diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml
new file mode 100644
index 0000000..6f7d579
--- /dev/null
+++ b/.github/workflows/workflow.yaml
@@ -0,0 +1,36 @@
+name: continuous integration - the-platform
+
+concurrency:
+ group: the-platform
+ cancel-in-progress: true
+
+on:
+ workflow_dispatch:
+ push:
+ branches: ["*"]
+ paths: ["./platform/serv"]
+
+jobs:
+ continuous-integration:
+ name: continuous integration
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout
+ uses: actions/checkout@v3
+
+ - name: setup node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18.x
+
+ - name: install dependencies
+ run: npm install
+ working-directory: ./platform/serv
+
+ - name: build
+ run: npm run build
+ working-directory: ./platform/serv
+
+ - name: test
+ run: npm test
+ working-directory: ./platform/serv
diff --git a/platform/serv-admin/.dockerignore b/platform/serv-admin/.dockerignore
new file mode 100644
index 0000000..1194b4f
--- /dev/null
+++ b/platform/serv-admin/.dockerignore
@@ -0,0 +1,7 @@
+.dockerignore
+docker-compose.yml
+Dockerfile
+build/
+node_modules
+.env
+.gitignore
diff --git a/platform/serv-admin/.env b/platform/serv-admin/.env
new file mode 100644
index 0000000..4eef91c
--- /dev/null
+++ b/platform/serv-admin/.env
@@ -0,0 +1,2 @@
+PORT=3001
+REACT_APP_SERVER_URL=http://localhost:3000
\ No newline at end of file
diff --git a/platform/serv-admin/.gitignore b/platform/serv-admin/.gitignore
new file mode 100644
index 0000000..590b2e0
--- /dev/null
+++ b/platform/serv-admin/.gitignore
@@ -0,0 +1,23 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# production
+/build
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
diff --git a/platform/serv-admin/Dockerfile b/platform/serv-admin/Dockerfile
new file mode 100644
index 0000000..9b14177
--- /dev/null
+++ b/platform/serv-admin/Dockerfile
@@ -0,0 +1,23 @@
+FROM node:18.12.1 AS base
+
+ARG REACT_APP_SERVER_URL
+
+ENV REACT_APP_SERVER_URL=$REACT_APP_SERVER_URL
+
+WORKDIR /app
+
+COPY package.json package-lock.json ./
+
+RUN npm ci
+
+COPY . .
+
+RUN npm run build
+
+FROM nginx:stable-alpine AS prod
+
+COPY --from=base /app/build /usr/share/nginx/html
+
+EXPOSE 80
+
+ENTRYPOINT ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/platform/serv-admin/README.md b/platform/serv-admin/README.md
new file mode 100644
index 0000000..f791dc3
--- /dev/null
+++ b/platform/serv-admin/README.md
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+# Introduction
+
+This service was generated with Amplication. It serves as the client-side for the generated server component. The client-side consist of a React application with ready-made forms for creating and editing the different data models of the application. It is pre-conffigured to work with the server and comes with the boilerplate and foundation for the client - i.e., routing, navigation, authentication, premissions, menu, breadcrumbs, error handling and much more. Additional information about the admin component and the architecture around it, can be found on the [documentation](https://docs.amplication.com/guides/getting-started) site. This side of the generated project was bootstrapped with [create-react-app](https://github.com/facebook/create-react-app) and built with [react-admin](https://marmelab.com/react-admin/).
+
+
+
+
+
+
+# Getting started
+
+## Step 1: Configuration
+
+Configuration for the client component can be provided through the use of environment variables. These can be passed to the application via the use of the `.env` file in the base directory of the generated service. Below a table can be found which show the different variables that can be passed. These values are provided default values after generation, change them to the desired values.
+
+| Variable | Description | Value |
+| -------------------- | ------------------------------------------------ | ------------------------------ |
+| PORT | the port on which to run the client | 3001 |
+| REACT_APP_SERVER_URL | the url on which the server component is running | http://localhost:[server-port] |
+
+> **Note**
+> Amplication generates default values and stores them under the .env file. It is advised to use some form of secrets manager/vault solution when using in production.
+
+
+## Step 2: Scripts
+
+After configuration of the client the next step would be to run the application. Before running the client side of the component, make sure that the different pre-requisites are met - i.e., npm, docker. Make sure that the server-side of the application is running.
+
+```sh
+# installation of the dependencies
+$ npm install
+```
+
+```sh
+# starts the application in development mode - available by default under http://localhost:3001
+$ npm run start
+```
+
+```sh
+# builds the application in production mode - available under 'build'
+$ npm run build
+```
+
+```sh
+# removes the single build dependency from the project
+$ npm run eject
+```
\ No newline at end of file
diff --git a/platform/serv-admin/package.json b/platform/serv-admin/package.json
new file mode 100644
index 0000000..5841f59
--- /dev/null
+++ b/platform/serv-admin/package.json
@@ -0,0 +1,62 @@
+{
+ "name": "@the-platform/admin",
+ "private": true,
+ "dependencies": {
+ "@apollo/client": "3.6.9",
+ "@material-ui/core": "4.12.4",
+ "graphql": "15.6.1",
+ "lodash": "4.17.21",
+ "pluralize": "8.0.0",
+ "ra-data-graphql-amplication": "0.0.13",
+ "react": "16.14.0",
+ "react-admin": "3.19.11",
+ "react-dom": "16.14.0",
+ "react-scripts": "5.0.0",
+ "sass": "^1.39.0",
+ "web-vitals": "1.1.2"
+ },
+ "overrides": {
+ "react-scripts": {
+ "@svgr/webpack": "6.5.1"
+ }
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject",
+ "package:container": "docker build .",
+ "format": "prettier --write ."
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ]
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ },
+ "devDependencies": {
+ "@testing-library/jest-dom": "5.14.1",
+ "@testing-library/react": "11.2.7",
+ "@testing-library/user-event": "13.2.0",
+ "@types/jest": "26.0.16",
+ "@types/lodash": "4.14.178",
+ "@types/node": "12.20.16",
+ "@types/react": "16.14.11",
+ "@types/react-dom": "17.0.0",
+ "type-fest": "0.13.1",
+ "typescript": "4.2.4",
+ "prettier": "^2.8.0"
+ }
+}
\ No newline at end of file
diff --git a/platform/serv-admin/public/favicon.ico b/platform/serv-admin/public/favicon.ico
new file mode 100644
index 0000000..fcbdcf2
Binary files /dev/null and b/platform/serv-admin/public/favicon.ico differ
diff --git a/platform/serv-admin/public/index.html b/platform/serv-admin/public/index.html
new file mode 100644
index 0000000..0e13a46
--- /dev/null
+++ b/platform/serv-admin/public/index.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ The Platform
+
+
+ You need to enable JavaScript to run this app.
+
+
+
+
diff --git a/platform/serv-admin/public/logo192.png b/platform/serv-admin/public/logo192.png
new file mode 100644
index 0000000..1918ff2
Binary files /dev/null and b/platform/serv-admin/public/logo192.png differ
diff --git a/platform/serv-admin/public/logo512.png b/platform/serv-admin/public/logo512.png
new file mode 100644
index 0000000..7e7dc74
Binary files /dev/null and b/platform/serv-admin/public/logo512.png differ
diff --git a/platform/serv-admin/public/manifest.json b/platform/serv-admin/public/manifest.json
new file mode 100644
index 0000000..7b98e85
--- /dev/null
+++ b/platform/serv-admin/public/manifest.json
@@ -0,0 +1,25 @@
+{
+ "short_name": "The Platform",
+ "name": "The Platform",
+ "icons": [
+ {
+ "src": "favicon.ico",
+ "sizes": "64x64 32x32 24x24 16x16",
+ "type": "image/x-icon"
+ },
+ {
+ "src": "logo192.png",
+ "type": "image/png",
+ "sizes": "192x192"
+ },
+ {
+ "src": "logo512.png",
+ "type": "image/png",
+ "sizes": "512x512"
+ }
+ ],
+ "start_url": ".",
+ "display": "standalone",
+ "theme_color": "#000000",
+ "background_color": "#ffffff"
+}
\ No newline at end of file
diff --git a/platform/serv-admin/public/robots.txt b/platform/serv-admin/public/robots.txt
new file mode 100644
index 0000000..e9e57dc
--- /dev/null
+++ b/platform/serv-admin/public/robots.txt
@@ -0,0 +1,3 @@
+# https://www.robotstxt.org/robotstxt.html
+User-agent: *
+Disallow:
diff --git a/platform/serv-admin/src/App.scss b/platform/serv-admin/src/App.scss
new file mode 100644
index 0000000..4c1cbb0
--- /dev/null
+++ b/platform/serv-admin/src/App.scss
@@ -0,0 +1,59 @@
+// .App {
+// .MuiAppBar-colorSecondary {
+// background-color: black;
+
+// .RaAppBar-menuButton-13 {
+// background-color: yellow;
+// }
+// }
+
+// .MuiDrawer-paper {
+// background-color: red;
+
+// .MuiListItemIcon-root {
+// color: white;
+// }
+// }
+
+// .MuiButton-textPrimary {
+// background-color: purple;
+// margin: 0 0.5rem;
+// color: white;
+// padding: 0.5rem 1rem;
+
+// &:hover {
+// background-color: blue;
+// }
+// }
+
+// .MuiTableRow-head {
+// .MuiTableCell-head {
+// background-color: black;
+// color: white;
+// }
+
+// .MuiTableSortLabel-root {
+// &:hover {
+// color: red;
+
+// .MuiTableSortLabel-icon {
+// color: red !important;
+// }
+// }
+// .MuiTableSortLabel-icon {
+// color: white !important;
+// }
+// }
+// .MuiTableSortLabel-active {
+// color: green;
+
+// .MuiTableSortLabel-icon {
+// color: green !important;
+// }
+// }
+// }
+
+// .MuiFormLabel-root {
+// color: magenta;
+// }
+// }
diff --git a/platform/serv-admin/src/App.tsx b/platform/serv-admin/src/App.tsx
new file mode 100644
index 0000000..039b136
--- /dev/null
+++ b/platform/serv-admin/src/App.tsx
@@ -0,0 +1,94 @@
+import React, { useEffect, useState } from "react";
+import { Admin, DataProvider, Resource } from "react-admin";
+import buildGraphQLProvider from "./data-provider/graphqlDataProvider";
+import { theme } from "./theme/theme";
+import Login from "./Login";
+import "./App.scss";
+import Dashboard from "./pages/Dashboard";
+import { UserList } from "./user/UserList";
+import { UserCreate } from "./user/UserCreate";
+import { UserEdit } from "./user/UserEdit";
+import { UserShow } from "./user/UserShow";
+import { AiGatekeeperList } from "./aiGatekeeper/AiGatekeeperList";
+import { AiGatekeeperCreate } from "./aiGatekeeper/AiGatekeeperCreate";
+import { AiGatekeeperEdit } from "./aiGatekeeper/AiGatekeeperEdit";
+import { AiGatekeeperShow } from "./aiGatekeeper/AiGatekeeperShow";
+import { DigitalCustodianAgentList } from "./digitalCustodianAgent/DigitalCustodianAgentList";
+import { DigitalCustodianAgentCreate } from "./digitalCustodianAgent/DigitalCustodianAgentCreate";
+import { DigitalCustodianAgentEdit } from "./digitalCustodianAgent/DigitalCustodianAgentEdit";
+import { DigitalCustodianAgentShow } from "./digitalCustodianAgent/DigitalCustodianAgentShow";
+import { IdeaViewerGuestList } from "./ideaViewerGuest/IdeaViewerGuestList";
+import { IdeaViewerGuestCreate } from "./ideaViewerGuest/IdeaViewerGuestCreate";
+import { IdeaViewerGuestEdit } from "./ideaViewerGuest/IdeaViewerGuestEdit";
+import { IdeaViewerGuestShow } from "./ideaViewerGuest/IdeaViewerGuestShow";
+import { IdeaCollaboratorDevList } from "./ideaCollaboratorDev/IdeaCollaboratorDevList";
+import { IdeaCollaboratorDevCreate } from "./ideaCollaboratorDev/IdeaCollaboratorDevCreate";
+import { IdeaCollaboratorDevEdit } from "./ideaCollaboratorDev/IdeaCollaboratorDevEdit";
+import { IdeaCollaboratorDevShow } from "./ideaCollaboratorDev/IdeaCollaboratorDevShow";
+import { httpAuthProvider } from "./auth-provider/ra-auth-http";
+
+const App = (): React.ReactElement => {
+ const [dataProvider, setDataProvider] = useState(null);
+ useEffect(() => {
+ buildGraphQLProvider
+ .then((provider: any) => {
+ setDataProvider(() => provider);
+ })
+ .catch((error: any) => {
+ console.log(error);
+ });
+ }, []);
+ if (!dataProvider) {
+ return Loading
;
+ }
+ return (
+
+ );
+};
+
+export default App;
diff --git a/platform/serv-admin/src/Components/Pagination.tsx b/platform/serv-admin/src/Components/Pagination.tsx
new file mode 100644
index 0000000..2de2ebf
--- /dev/null
+++ b/platform/serv-admin/src/Components/Pagination.tsx
@@ -0,0 +1,10 @@
+import React from "react";
+import { Pagination as RAPagination, PaginationProps } from "react-admin";
+
+const PAGINATION_OPTIONS = [10, 25, 50, 100, 200];
+
+const Pagination = (props: PaginationProps) => (
+
+);
+
+export default Pagination;
diff --git a/platform/serv-admin/src/Login.tsx b/platform/serv-admin/src/Login.tsx
new file mode 100644
index 0000000..f7ec8ed
--- /dev/null
+++ b/platform/serv-admin/src/Login.tsx
@@ -0,0 +1,117 @@
+import * as React from "react";
+import { useState } from "react";
+import { useLogin, useNotify, Notification, defaultTheme } from "react-admin";
+import { ThemeProvider } from "@material-ui/styles";
+import { createTheme } from "@material-ui/core/styles";
+import { Button } from "@material-ui/core";
+import "./login.scss";
+
+const CLASS_NAME = "login-page";
+
+const Login = ({ theme }: any) => {
+ const [username, setUsername] = useState("");
+ const [password, setPassword] = useState("");
+ const login = useLogin();
+ const notify = useNotify();
+ const BASE_URI = process.env.REACT_APP_SERVER_URL;
+ const submit = (e: any) => {
+ e.preventDefault();
+ login({ username, password }).catch(() =>
+ notify("Invalid username or password")
+ );
+ };
+
+ return (
+
+
+
+
+
+
Connect via GraphQL
+
+ Connect to the server using GraphQL API with a complete and
+ understandable description of the data in your API
+
+
+ Continue
+
+
+
+
+
Admin UI
+
+ Sign in to a React-Admin client with ready-made forms for creating
+ and editing all the data models of your application
+
+
+
+
+
+
Connect via REST API
+
+ Connect to the server using REST API with a built-in Swagger
+ documentation
+
+
+ Continue
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Login;
diff --git a/platform/serv-admin/src/aiGatekeeper/AiGatekeeperCreate.tsx b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperCreate.tsx
new file mode 100644
index 0000000..851f418
--- /dev/null
+++ b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperCreate.tsx
@@ -0,0 +1,63 @@
+import * as React from "react";
+
+import {
+ Create,
+ SimpleForm,
+ CreateProps,
+ SelectInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ SelectArrayInput,
+ TextInput,
+ NumberInput,
+} from "react-admin";
+
+import { UserTitle } from "../user/UserTitle";
+import { DigitalCustodianAgentTitle } from "../digitalCustodianAgent/DigitalCustodianAgentTitle";
+
+export const AiGatekeeperCreate = (props: CreateProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+ value && value.map((v: any) => ({ id: v }))}
+ format={(value: any) => value && value.map((v: any) => v.id)}
+ >
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/aiGatekeeper/AiGatekeeperEdit.tsx b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperEdit.tsx
new file mode 100644
index 0000000..d651327
--- /dev/null
+++ b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperEdit.tsx
@@ -0,0 +1,63 @@
+import * as React from "react";
+
+import {
+ Edit,
+ SimpleForm,
+ EditProps,
+ SelectInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ SelectArrayInput,
+ TextInput,
+ NumberInput,
+} from "react-admin";
+
+import { UserTitle } from "../user/UserTitle";
+import { DigitalCustodianAgentTitle } from "../digitalCustodianAgent/DigitalCustodianAgentTitle";
+
+export const AiGatekeeperEdit = (props: EditProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+ value && value.map((v: any) => ({ id: v }))}
+ format={(value: any) => value && value.map((v: any) => v.id)}
+ >
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/aiGatekeeper/AiGatekeeperList.tsx b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperList.tsx
new file mode 100644
index 0000000..cb21c1e
--- /dev/null
+++ b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperList.tsx
@@ -0,0 +1,35 @@
+import * as React from "react";
+import {
+ List,
+ Datagrid,
+ ListProps,
+ TextField,
+ DateField,
+ ReferenceField,
+} from "react-admin";
+import Pagination from "../Components/Pagination";
+import { USER_TITLE_FIELD } from "../user/UserTitle";
+
+export const AiGatekeeperList = (props: ListProps): React.ReactElement => {
+ return (
+
}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/aiGatekeeper/AiGatekeeperShow.tsx b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperShow.tsx
new file mode 100644
index 0000000..2ffec7b
--- /dev/null
+++ b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperShow.tsx
@@ -0,0 +1,55 @@
+import * as React from "react";
+
+import {
+ Show,
+ SimpleShowLayout,
+ ShowProps,
+ TextField,
+ DateField,
+ ReferenceField,
+ ReferenceManyField,
+ Datagrid,
+} from "react-admin";
+
+import { AIGATEKEEPER_TITLE_FIELD } from "./AiGatekeeperTitle";
+import { USER_TITLE_FIELD } from "../user/UserTitle";
+
+export const AiGatekeeperShow = (props: ShowProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/aiGatekeeper/AiGatekeeperTitle.ts b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperTitle.ts
new file mode 100644
index 0000000..58abb71
--- /dev/null
+++ b/platform/serv-admin/src/aiGatekeeper/AiGatekeeperTitle.ts
@@ -0,0 +1,7 @@
+import { AiGatekeeper as TAiGatekeeper } from "../api/aiGatekeeper/AiGatekeeper";
+
+export const AIGATEKEEPER_TITLE_FIELD = "roles";
+
+export const AiGatekeeperTitle = (record: TAiGatekeeper): string => {
+ return record.roles || String(record.id);
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeper.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeper.ts
new file mode 100644
index 0000000..7429965
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeper.ts
@@ -0,0 +1,23 @@
+import { User } from "../user/User";
+import { DigitalCustodianAgent } from "../digitalCustodianAgent/DigitalCustodianAgent";
+
+export type AiGatekeeper = {
+ AIStatus?:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+ createdAt: Date;
+ createdBy?: User;
+ id: string;
+ myAgents?: Array;
+ roles: string;
+ TasksCompleted: number;
+ updatedAt: Date;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperCreateInput.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperCreateInput.ts
new file mode 100644
index 0000000..f3861b5
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperCreateInput.ts
@@ -0,0 +1,20 @@
+import { UserWhereUniqueInput } from "../user/UserWhereUniqueInput";
+import { DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput } from "./DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput";
+
+export type AiGatekeeperCreateInput = {
+ AIStatus:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+ createdBy: UserWhereUniqueInput;
+ myAgents?: DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput;
+ roles: string;
+ TasksCompleted: number;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperFindManyArgs.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperFindManyArgs.ts
new file mode 100644
index 0000000..2c71c2b
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperFindManyArgs.ts
@@ -0,0 +1,9 @@
+import { AiGatekeeperWhereInput } from "./AiGatekeeperWhereInput";
+import { AiGatekeeperOrderByInput } from "./AiGatekeeperOrderByInput";
+
+export type AiGatekeeperFindManyArgs = {
+ where?: AiGatekeeperWhereInput;
+ orderBy?: Array;
+ skip?: number;
+ take?: number;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperFindUniqueArgs.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperFindUniqueArgs.ts
new file mode 100644
index 0000000..b6c718e
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperFindUniqueArgs.ts
@@ -0,0 +1,5 @@
+import { AiGatekeeperWhereUniqueInput } from "./AiGatekeeperWhereUniqueInput";
+
+export type AiGatekeeperFindUniqueArgs = {
+ where: AiGatekeeperWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperListRelationFilter.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperListRelationFilter.ts
new file mode 100644
index 0000000..6ce2209
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperListRelationFilter.ts
@@ -0,0 +1,7 @@
+import { AiGatekeeperWhereInput } from "./AiGatekeeperWhereInput";
+
+export type AiGatekeeperListRelationFilter = {
+ every?: AiGatekeeperWhereInput;
+ some?: AiGatekeeperWhereInput;
+ none?: AiGatekeeperWhereInput;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperOrderByInput.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperOrderByInput.ts
new file mode 100644
index 0000000..90659bb
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperOrderByInput.ts
@@ -0,0 +1,11 @@
+import { SortOrder } from "../../util/SortOrder";
+
+export type AiGatekeeperOrderByInput = {
+ AIStatus?: SortOrder;
+ createdAt?: SortOrder;
+ createdById?: SortOrder;
+ id?: SortOrder;
+ roles?: SortOrder;
+ TasksCompleted?: SortOrder;
+ updatedAt?: SortOrder;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperUpdateInput.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperUpdateInput.ts
new file mode 100644
index 0000000..8df1261
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperUpdateInput.ts
@@ -0,0 +1,20 @@
+import { UserWhereUniqueInput } from "../user/UserWhereUniqueInput";
+import { DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput } from "./DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput";
+
+export type AiGatekeeperUpdateInput = {
+ AIStatus?:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+ createdBy?: UserWhereUniqueInput;
+ myAgents?: DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput;
+ roles?: string;
+ TasksCompleted?: number;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperWhereInput.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperWhereInput.ts
new file mode 100644
index 0000000..e35dac2
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperWhereInput.ts
@@ -0,0 +1,26 @@
+import { DateTimeFilter } from "../../util/DateTimeFilter";
+import { UserWhereUniqueInput } from "../user/UserWhereUniqueInput";
+import { StringFilter } from "../../util/StringFilter";
+import { DigitalCustodianAgentListRelationFilter } from "../digitalCustodianAgent/DigitalCustodianAgentListRelationFilter";
+import { IntFilter } from "../../util/IntFilter";
+
+export type AiGatekeeperWhereInput = {
+ AIStatus?:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+ createdAt?: DateTimeFilter;
+ createdBy?: UserWhereUniqueInput;
+ id?: StringFilter;
+ myAgents?: DigitalCustodianAgentListRelationFilter;
+ roles?: StringFilter;
+ TasksCompleted?: IntFilter;
+ updatedAt?: DateTimeFilter;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperWhereUniqueInput.ts b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperWhereUniqueInput.ts
new file mode 100644
index 0000000..8d928c6
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/AiGatekeeperWhereUniqueInput.ts
@@ -0,0 +1,3 @@
+export type AiGatekeeperWhereUniqueInput = {
+ id: string;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/CreateAiGatekeeperArgs.ts b/platform/serv-admin/src/api/aiGatekeeper/CreateAiGatekeeperArgs.ts
new file mode 100644
index 0000000..df9c8a6
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/CreateAiGatekeeperArgs.ts
@@ -0,0 +1,5 @@
+import { AiGatekeeperCreateInput } from "./AiGatekeeperCreateInput";
+
+export type CreateAiGatekeeperArgs = {
+ data: AiGatekeeperCreateInput;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/DeleteAiGatekeeperArgs.ts b/platform/serv-admin/src/api/aiGatekeeper/DeleteAiGatekeeperArgs.ts
new file mode 100644
index 0000000..6800b06
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/DeleteAiGatekeeperArgs.ts
@@ -0,0 +1,5 @@
+import { AiGatekeeperWhereUniqueInput } from "./AiGatekeeperWhereUniqueInput";
+
+export type DeleteAiGatekeeperArgs = {
+ where: AiGatekeeperWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput.ts b/platform/serv-admin/src/api/aiGatekeeper/DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput.ts
new file mode 100644
index 0000000..bea8de7
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput.ts
@@ -0,0 +1,5 @@
+import { DigitalCustodianAgentWhereUniqueInput } from "../digitalCustodianAgent/DigitalCustodianAgentWhereUniqueInput";
+
+export type DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput = {
+ connect?: Array;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput.ts b/platform/serv-admin/src/api/aiGatekeeper/DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput.ts
new file mode 100644
index 0000000..8a23ef1
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput.ts
@@ -0,0 +1,7 @@
+import { DigitalCustodianAgentWhereUniqueInput } from "../digitalCustodianAgent/DigitalCustodianAgentWhereUniqueInput";
+
+export type DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput = {
+ connect?: Array;
+ disconnect?: Array;
+ set?: Array;
+};
diff --git a/platform/serv-admin/src/api/aiGatekeeper/EnumAiGatekeeperAiStatus.ts b/platform/serv-admin/src/api/aiGatekeeper/EnumAiGatekeeperAiStatus.ts
new file mode 100644
index 0000000..7c3d435
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/EnumAiGatekeeperAiStatus.ts
@@ -0,0 +1,12 @@
+export enum EnumAiGatekeeperAiStatus {
+ DaydreamingInBinary = "IDLE",
+ ContemplatingTheMeaningOf_42 = "THINKING",
+ OnAByteBreak = "BREAK",
+ TidyingUpTheData = "CLEANING",
+ BabysittingTheNewAlgorithms = "TRAINING",
+ ChasingRunawayData = "FETCHING_DATA",
+ PlayingHideAndSeekWithBugs = "DEBUGGING",
+ DoingTheRobotDance = "ACTIVE",
+ BakingPiesInTheCloud = "PROCESSING_IN_CLOUD",
+ UnravelingTheYarnOfYottabytes = "MANAGING_LARGE_DATA",
+}
diff --git a/platform/serv-admin/src/api/aiGatekeeper/UpdateAiGatekeeperArgs.ts b/platform/serv-admin/src/api/aiGatekeeper/UpdateAiGatekeeperArgs.ts
new file mode 100644
index 0000000..a9bc625
--- /dev/null
+++ b/platform/serv-admin/src/api/aiGatekeeper/UpdateAiGatekeeperArgs.ts
@@ -0,0 +1,7 @@
+import { AiGatekeeperWhereUniqueInput } from "./AiGatekeeperWhereUniqueInput";
+import { AiGatekeeperUpdateInput } from "./AiGatekeeperUpdateInput";
+
+export type UpdateAiGatekeeperArgs = {
+ where: AiGatekeeperWhereUniqueInput;
+ data: AiGatekeeperUpdateInput;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/CreateDigitalCustodianAgentArgs.ts b/platform/serv-admin/src/api/digitalCustodianAgent/CreateDigitalCustodianAgentArgs.ts
new file mode 100644
index 0000000..d80ae19
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/CreateDigitalCustodianAgentArgs.ts
@@ -0,0 +1,5 @@
+import { DigitalCustodianAgentCreateInput } from "./DigitalCustodianAgentCreateInput";
+
+export type CreateDigitalCustodianAgentArgs = {
+ data: DigitalCustodianAgentCreateInput;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DeleteDigitalCustodianAgentArgs.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DeleteDigitalCustodianAgentArgs.ts
new file mode 100644
index 0000000..f85d99d
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DeleteDigitalCustodianAgentArgs.ts
@@ -0,0 +1,5 @@
+import { DigitalCustodianAgentWhereUniqueInput } from "./DigitalCustodianAgentWhereUniqueInput";
+
+export type DeleteDigitalCustodianAgentArgs = {
+ where: DigitalCustodianAgentWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgent.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgent.ts
new file mode 100644
index 0000000..587ca0a
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgent.ts
@@ -0,0 +1,22 @@
+import { AiGatekeeper } from "../aiGatekeeper/AiGatekeeper";
+
+export type DigitalCustodianAgent = {
+ agentStatus?:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+ createdAt: Date;
+ id: string;
+ lastActiveTime: Date;
+ lastError: string | null;
+ MyAiGatekeeper?: AiGatekeeper | null;
+ tasksCompleted: number;
+ updatedAt: Date;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentCreateInput.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentCreateInput.ts
new file mode 100644
index 0000000..444f90b
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentCreateInput.ts
@@ -0,0 +1,19 @@
+import { AiGatekeeperWhereUniqueInput } from "../aiGatekeeper/AiGatekeeperWhereUniqueInput";
+
+export type DigitalCustodianAgentCreateInput = {
+ agentStatus:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+ lastActiveTime: Date;
+ lastError?: string | null;
+ MyAiGatekeeper?: AiGatekeeperWhereUniqueInput | null;
+ tasksCompleted: number;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentFindManyArgs.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentFindManyArgs.ts
new file mode 100644
index 0000000..c488705
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentFindManyArgs.ts
@@ -0,0 +1,9 @@
+import { DigitalCustodianAgentWhereInput } from "./DigitalCustodianAgentWhereInput";
+import { DigitalCustodianAgentOrderByInput } from "./DigitalCustodianAgentOrderByInput";
+
+export type DigitalCustodianAgentFindManyArgs = {
+ where?: DigitalCustodianAgentWhereInput;
+ orderBy?: Array;
+ skip?: number;
+ take?: number;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentFindUniqueArgs.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentFindUniqueArgs.ts
new file mode 100644
index 0000000..795913e
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentFindUniqueArgs.ts
@@ -0,0 +1,5 @@
+import { DigitalCustodianAgentWhereUniqueInput } from "./DigitalCustodianAgentWhereUniqueInput";
+
+export type DigitalCustodianAgentFindUniqueArgs = {
+ where: DigitalCustodianAgentWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentListRelationFilter.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentListRelationFilter.ts
new file mode 100644
index 0000000..17b0f5f
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentListRelationFilter.ts
@@ -0,0 +1,7 @@
+import { DigitalCustodianAgentWhereInput } from "./DigitalCustodianAgentWhereInput";
+
+export type DigitalCustodianAgentListRelationFilter = {
+ every?: DigitalCustodianAgentWhereInput;
+ some?: DigitalCustodianAgentWhereInput;
+ none?: DigitalCustodianAgentWhereInput;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentOrderByInput.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentOrderByInput.ts
new file mode 100644
index 0000000..21201d9
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentOrderByInput.ts
@@ -0,0 +1,12 @@
+import { SortOrder } from "../../util/SortOrder";
+
+export type DigitalCustodianAgentOrderByInput = {
+ agentStatus?: SortOrder;
+ createdAt?: SortOrder;
+ id?: SortOrder;
+ lastActiveTime?: SortOrder;
+ lastError?: SortOrder;
+ MyAiGatekeeperId?: SortOrder;
+ tasksCompleted?: SortOrder;
+ updatedAt?: SortOrder;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentUpdateInput.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentUpdateInput.ts
new file mode 100644
index 0000000..a6df8e8
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentUpdateInput.ts
@@ -0,0 +1,19 @@
+import { AiGatekeeperWhereUniqueInput } from "../aiGatekeeper/AiGatekeeperWhereUniqueInput";
+
+export type DigitalCustodianAgentUpdateInput = {
+ agentStatus?:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+ lastActiveTime?: Date;
+ lastError?: string | null;
+ MyAiGatekeeper?: AiGatekeeperWhereUniqueInput | null;
+ tasksCompleted?: number;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentWhereInput.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentWhereInput.ts
new file mode 100644
index 0000000..3a51e2b
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentWhereInput.ts
@@ -0,0 +1,24 @@
+import { StringFilter } from "../../util/StringFilter";
+import { DateTimeFilter } from "../../util/DateTimeFilter";
+import { StringNullableFilter } from "../../util/StringNullableFilter";
+import { AiGatekeeperWhereUniqueInput } from "../aiGatekeeper/AiGatekeeperWhereUniqueInput";
+import { IntFilter } from "../../util/IntFilter";
+
+export type DigitalCustodianAgentWhereInput = {
+ agentStatus?:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+ id?: StringFilter;
+ lastActiveTime?: DateTimeFilter;
+ lastError?: StringNullableFilter;
+ MyAiGatekeeper?: AiGatekeeperWhereUniqueInput;
+ tasksCompleted?: IntFilter;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentWhereUniqueInput.ts b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentWhereUniqueInput.ts
new file mode 100644
index 0000000..c4f1f81
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/DigitalCustodianAgentWhereUniqueInput.ts
@@ -0,0 +1,3 @@
+export type DigitalCustodianAgentWhereUniqueInput = {
+ id: string;
+};
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/EnumDigitalCustodianAgentAgentStatus.ts b/platform/serv-admin/src/api/digitalCustodianAgent/EnumDigitalCustodianAgentAgentStatus.ts
new file mode 100644
index 0000000..38afcc3
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/EnumDigitalCustodianAgentAgentStatus.ts
@@ -0,0 +1,12 @@
+export enum EnumDigitalCustodianAgentAgentStatus {
+ MeditatingInMachineLanguage = "IDLE",
+ DustingTheCloudsForTheGatekeeper = "WORKING",
+ TakingLessonsFromTheGatekeeper = "LEARNING",
+ OnAGigabyteGetaway = "BREAK",
+ PlayingFetchWithDataForTheGatekeeper = "FETCHING_DATA",
+ KnittingNeuralNets = "PROCESSING_DATA",
+ HuntingBugsInTheMatrix = "DEBUGGING",
+ EavesdroppingOnElectrons = "OBSERVING",
+ RunningLapsInTheLearningLoop = "TRAINING",
+ BeingTheGatekeeperSHandyBot = "HELPING",
+}
diff --git a/platform/serv-admin/src/api/digitalCustodianAgent/UpdateDigitalCustodianAgentArgs.ts b/platform/serv-admin/src/api/digitalCustodianAgent/UpdateDigitalCustodianAgentArgs.ts
new file mode 100644
index 0000000..72fb4fb
--- /dev/null
+++ b/platform/serv-admin/src/api/digitalCustodianAgent/UpdateDigitalCustodianAgentArgs.ts
@@ -0,0 +1,7 @@
+import { DigitalCustodianAgentWhereUniqueInput } from "./DigitalCustodianAgentWhereUniqueInput";
+import { DigitalCustodianAgentUpdateInput } from "./DigitalCustodianAgentUpdateInput";
+
+export type UpdateDigitalCustodianAgentArgs = {
+ where: DigitalCustodianAgentWhereUniqueInput;
+ data: DigitalCustodianAgentUpdateInput;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/CreateIdeaCollaboratorDevArgs.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/CreateIdeaCollaboratorDevArgs.ts
new file mode 100644
index 0000000..70e2561
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/CreateIdeaCollaboratorDevArgs.ts
@@ -0,0 +1,5 @@
+import { IdeaCollaboratorDevCreateInput } from "./IdeaCollaboratorDevCreateInput";
+
+export type CreateIdeaCollaboratorDevArgs = {
+ data: IdeaCollaboratorDevCreateInput;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/DeleteIdeaCollaboratorDevArgs.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/DeleteIdeaCollaboratorDevArgs.ts
new file mode 100644
index 0000000..40d9dcc
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/DeleteIdeaCollaboratorDevArgs.ts
@@ -0,0 +1,5 @@
+import { IdeaCollaboratorDevWhereUniqueInput } from "./IdeaCollaboratorDevWhereUniqueInput";
+
+export type DeleteIdeaCollaboratorDevArgs = {
+ where: IdeaCollaboratorDevWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDev.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDev.ts
new file mode 100644
index 0000000..ee8c676
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDev.ts
@@ -0,0 +1,10 @@
+import { User } from "../user/User";
+
+export type IdeaCollaboratorDev = {
+ createdAt: Date;
+ email: string;
+ id: string;
+ inATeam?: User | null;
+ location: string;
+ updatedAt: Date;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevCreateInput.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevCreateInput.ts
new file mode 100644
index 0000000..0c6466e
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevCreateInput.ts
@@ -0,0 +1,7 @@
+import { UserWhereUniqueInput } from "../user/UserWhereUniqueInput";
+
+export type IdeaCollaboratorDevCreateInput = {
+ email: string;
+ inATeam?: UserWhereUniqueInput | null;
+ location: string;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevFindManyArgs.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevFindManyArgs.ts
new file mode 100644
index 0000000..bbd27d9
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevFindManyArgs.ts
@@ -0,0 +1,9 @@
+import { IdeaCollaboratorDevWhereInput } from "./IdeaCollaboratorDevWhereInput";
+import { IdeaCollaboratorDevOrderByInput } from "./IdeaCollaboratorDevOrderByInput";
+
+export type IdeaCollaboratorDevFindManyArgs = {
+ where?: IdeaCollaboratorDevWhereInput;
+ orderBy?: Array;
+ skip?: number;
+ take?: number;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevFindUniqueArgs.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevFindUniqueArgs.ts
new file mode 100644
index 0000000..af97550
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevFindUniqueArgs.ts
@@ -0,0 +1,5 @@
+import { IdeaCollaboratorDevWhereUniqueInput } from "./IdeaCollaboratorDevWhereUniqueInput";
+
+export type IdeaCollaboratorDevFindUniqueArgs = {
+ where: IdeaCollaboratorDevWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevListRelationFilter.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevListRelationFilter.ts
new file mode 100644
index 0000000..2d6fa17
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevListRelationFilter.ts
@@ -0,0 +1,7 @@
+import { IdeaCollaboratorDevWhereInput } from "./IdeaCollaboratorDevWhereInput";
+
+export type IdeaCollaboratorDevListRelationFilter = {
+ every?: IdeaCollaboratorDevWhereInput;
+ some?: IdeaCollaboratorDevWhereInput;
+ none?: IdeaCollaboratorDevWhereInput;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevOrderByInput.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevOrderByInput.ts
new file mode 100644
index 0000000..7c93733
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevOrderByInput.ts
@@ -0,0 +1,10 @@
+import { SortOrder } from "../../util/SortOrder";
+
+export type IdeaCollaboratorDevOrderByInput = {
+ createdAt?: SortOrder;
+ email?: SortOrder;
+ id?: SortOrder;
+ inATeamId?: SortOrder;
+ location?: SortOrder;
+ updatedAt?: SortOrder;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevUpdateInput.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevUpdateInput.ts
new file mode 100644
index 0000000..d7ccd84
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevUpdateInput.ts
@@ -0,0 +1,7 @@
+import { UserWhereUniqueInput } from "../user/UserWhereUniqueInput";
+
+export type IdeaCollaboratorDevUpdateInput = {
+ email?: string;
+ inATeam?: UserWhereUniqueInput | null;
+ location?: string;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevWhereInput.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevWhereInput.ts
new file mode 100644
index 0000000..5aac1ec
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevWhereInput.ts
@@ -0,0 +1,9 @@
+import { StringFilter } from "../../util/StringFilter";
+import { UserWhereUniqueInput } from "../user/UserWhereUniqueInput";
+
+export type IdeaCollaboratorDevWhereInput = {
+ email?: StringFilter;
+ id?: StringFilter;
+ inATeam?: UserWhereUniqueInput;
+ location?: StringFilter;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevWhereUniqueInput.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevWhereUniqueInput.ts
new file mode 100644
index 0000000..1daf0b7
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/IdeaCollaboratorDevWhereUniqueInput.ts
@@ -0,0 +1,3 @@
+export type IdeaCollaboratorDevWhereUniqueInput = {
+ id: string;
+};
diff --git a/platform/serv-admin/src/api/ideaCollaboratorDev/UpdateIdeaCollaboratorDevArgs.ts b/platform/serv-admin/src/api/ideaCollaboratorDev/UpdateIdeaCollaboratorDevArgs.ts
new file mode 100644
index 0000000..ecc54a0
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaCollaboratorDev/UpdateIdeaCollaboratorDevArgs.ts
@@ -0,0 +1,7 @@
+import { IdeaCollaboratorDevWhereUniqueInput } from "./IdeaCollaboratorDevWhereUniqueInput";
+import { IdeaCollaboratorDevUpdateInput } from "./IdeaCollaboratorDevUpdateInput";
+
+export type UpdateIdeaCollaboratorDevArgs = {
+ where: IdeaCollaboratorDevWhereUniqueInput;
+ data: IdeaCollaboratorDevUpdateInput;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/CreateIdeaViewerGuestArgs.ts b/platform/serv-admin/src/api/ideaViewerGuest/CreateIdeaViewerGuestArgs.ts
new file mode 100644
index 0000000..850b28f
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/CreateIdeaViewerGuestArgs.ts
@@ -0,0 +1,5 @@
+import { IdeaViewerGuestCreateInput } from "./IdeaViewerGuestCreateInput";
+
+export type CreateIdeaViewerGuestArgs = {
+ data: IdeaViewerGuestCreateInput;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/DeleteIdeaViewerGuestArgs.ts b/platform/serv-admin/src/api/ideaViewerGuest/DeleteIdeaViewerGuestArgs.ts
new file mode 100644
index 0000000..3cf8cf1
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/DeleteIdeaViewerGuestArgs.ts
@@ -0,0 +1,5 @@
+import { IdeaViewerGuestWhereUniqueInput } from "./IdeaViewerGuestWhereUniqueInput";
+
+export type DeleteIdeaViewerGuestArgs = {
+ where: IdeaViewerGuestWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuest.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuest.ts
new file mode 100644
index 0000000..c8911e6
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuest.ts
@@ -0,0 +1,8 @@
+export type IdeaViewerGuest = {
+ company: string;
+ createdAt: Date;
+ email: string | null;
+ id: string;
+ Location: string;
+ updatedAt: Date;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestCreateInput.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestCreateInput.ts
new file mode 100644
index 0000000..bfe0d6e
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestCreateInput.ts
@@ -0,0 +1,5 @@
+export type IdeaViewerGuestCreateInput = {
+ company: string;
+ email?: string | null;
+ Location: string;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestFindManyArgs.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestFindManyArgs.ts
new file mode 100644
index 0000000..37a3dbf
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestFindManyArgs.ts
@@ -0,0 +1,9 @@
+import { IdeaViewerGuestWhereInput } from "./IdeaViewerGuestWhereInput";
+import { IdeaViewerGuestOrderByInput } from "./IdeaViewerGuestOrderByInput";
+
+export type IdeaViewerGuestFindManyArgs = {
+ where?: IdeaViewerGuestWhereInput;
+ orderBy?: Array;
+ skip?: number;
+ take?: number;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestFindUniqueArgs.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestFindUniqueArgs.ts
new file mode 100644
index 0000000..c466b9e
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestFindUniqueArgs.ts
@@ -0,0 +1,5 @@
+import { IdeaViewerGuestWhereUniqueInput } from "./IdeaViewerGuestWhereUniqueInput";
+
+export type IdeaViewerGuestFindUniqueArgs = {
+ where: IdeaViewerGuestWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestListRelationFilter.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestListRelationFilter.ts
new file mode 100644
index 0000000..c0d84fb
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestListRelationFilter.ts
@@ -0,0 +1,7 @@
+import { IdeaViewerGuestWhereInput } from "./IdeaViewerGuestWhereInput";
+
+export type IdeaViewerGuestListRelationFilter = {
+ every?: IdeaViewerGuestWhereInput;
+ some?: IdeaViewerGuestWhereInput;
+ none?: IdeaViewerGuestWhereInput;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestOrderByInput.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestOrderByInput.ts
new file mode 100644
index 0000000..87a0769
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestOrderByInput.ts
@@ -0,0 +1,10 @@
+import { SortOrder } from "../../util/SortOrder";
+
+export type IdeaViewerGuestOrderByInput = {
+ company?: SortOrder;
+ createdAt?: SortOrder;
+ email?: SortOrder;
+ id?: SortOrder;
+ Location?: SortOrder;
+ updatedAt?: SortOrder;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestUpdateInput.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestUpdateInput.ts
new file mode 100644
index 0000000..3f5be14
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestUpdateInput.ts
@@ -0,0 +1,5 @@
+export type IdeaViewerGuestUpdateInput = {
+ company?: string;
+ email?: string | null;
+ Location?: string;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestWhereInput.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestWhereInput.ts
new file mode 100644
index 0000000..44c6c6b
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestWhereInput.ts
@@ -0,0 +1,9 @@
+import { StringFilter } from "../../util/StringFilter";
+import { StringNullableFilter } from "../../util/StringNullableFilter";
+
+export type IdeaViewerGuestWhereInput = {
+ company?: StringFilter;
+ email?: StringNullableFilter;
+ id?: StringFilter;
+ Location?: StringFilter;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestWhereUniqueInput.ts b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestWhereUniqueInput.ts
new file mode 100644
index 0000000..6f4e751
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/IdeaViewerGuestWhereUniqueInput.ts
@@ -0,0 +1,3 @@
+export type IdeaViewerGuestWhereUniqueInput = {
+ id: string;
+};
diff --git a/platform/serv-admin/src/api/ideaViewerGuest/UpdateIdeaViewerGuestArgs.ts b/platform/serv-admin/src/api/ideaViewerGuest/UpdateIdeaViewerGuestArgs.ts
new file mode 100644
index 0000000..c71b4f8
--- /dev/null
+++ b/platform/serv-admin/src/api/ideaViewerGuest/UpdateIdeaViewerGuestArgs.ts
@@ -0,0 +1,7 @@
+import { IdeaViewerGuestWhereUniqueInput } from "./IdeaViewerGuestWhereUniqueInput";
+import { IdeaViewerGuestUpdateInput } from "./IdeaViewerGuestUpdateInput";
+
+export type UpdateIdeaViewerGuestArgs = {
+ where: IdeaViewerGuestWhereUniqueInput;
+ data: IdeaViewerGuestUpdateInput;
+};
diff --git a/platform/serv-admin/src/api/user/AiGatekeeperCreateNestedManyWithoutUsersInput.ts b/platform/serv-admin/src/api/user/AiGatekeeperCreateNestedManyWithoutUsersInput.ts
new file mode 100644
index 0000000..764879c
--- /dev/null
+++ b/platform/serv-admin/src/api/user/AiGatekeeperCreateNestedManyWithoutUsersInput.ts
@@ -0,0 +1,5 @@
+import { AiGatekeeperWhereUniqueInput } from "../aiGatekeeper/AiGatekeeperWhereUniqueInput";
+
+export type AiGatekeeperCreateNestedManyWithoutUsersInput = {
+ connect?: Array;
+};
diff --git a/platform/serv-admin/src/api/user/AiGatekeeperUpdateManyWithoutUsersInput.ts b/platform/serv-admin/src/api/user/AiGatekeeperUpdateManyWithoutUsersInput.ts
new file mode 100644
index 0000000..dcfce07
--- /dev/null
+++ b/platform/serv-admin/src/api/user/AiGatekeeperUpdateManyWithoutUsersInput.ts
@@ -0,0 +1,7 @@
+import { AiGatekeeperWhereUniqueInput } from "../aiGatekeeper/AiGatekeeperWhereUniqueInput";
+
+export type AiGatekeeperUpdateManyWithoutUsersInput = {
+ connect?: Array;
+ disconnect?: Array;
+ set?: Array;
+};
diff --git a/platform/serv-admin/src/api/user/CreateUserArgs.ts b/platform/serv-admin/src/api/user/CreateUserArgs.ts
new file mode 100644
index 0000000..2a56f0c
--- /dev/null
+++ b/platform/serv-admin/src/api/user/CreateUserArgs.ts
@@ -0,0 +1,5 @@
+import { UserCreateInput } from "./UserCreateInput";
+
+export type CreateUserArgs = {
+ data: UserCreateInput;
+};
diff --git a/platform/serv-admin/src/api/user/DeleteUserArgs.ts b/platform/serv-admin/src/api/user/DeleteUserArgs.ts
new file mode 100644
index 0000000..5f655b8
--- /dev/null
+++ b/platform/serv-admin/src/api/user/DeleteUserArgs.ts
@@ -0,0 +1,5 @@
+import { UserWhereUniqueInput } from "./UserWhereUniqueInput";
+
+export type DeleteUserArgs = {
+ where: UserWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/user/IdeaCollaboratorDevCreateNestedManyWithoutUsersInput.ts b/platform/serv-admin/src/api/user/IdeaCollaboratorDevCreateNestedManyWithoutUsersInput.ts
new file mode 100644
index 0000000..10968f8
--- /dev/null
+++ b/platform/serv-admin/src/api/user/IdeaCollaboratorDevCreateNestedManyWithoutUsersInput.ts
@@ -0,0 +1,5 @@
+import { IdeaCollaboratorDevWhereUniqueInput } from "../ideaCollaboratorDev/IdeaCollaboratorDevWhereUniqueInput";
+
+export type IdeaCollaboratorDevCreateNestedManyWithoutUsersInput = {
+ connect?: Array;
+};
diff --git a/platform/serv-admin/src/api/user/IdeaCollaboratorDevUpdateManyWithoutUsersInput.ts b/platform/serv-admin/src/api/user/IdeaCollaboratorDevUpdateManyWithoutUsersInput.ts
new file mode 100644
index 0000000..d7805ff
--- /dev/null
+++ b/platform/serv-admin/src/api/user/IdeaCollaboratorDevUpdateManyWithoutUsersInput.ts
@@ -0,0 +1,7 @@
+import { IdeaCollaboratorDevWhereUniqueInput } from "../ideaCollaboratorDev/IdeaCollaboratorDevWhereUniqueInput";
+
+export type IdeaCollaboratorDevUpdateManyWithoutUsersInput = {
+ connect?: Array;
+ disconnect?: Array;
+ set?: Array;
+};
diff --git a/platform/serv-admin/src/api/user/UpdateUserArgs.ts b/platform/serv-admin/src/api/user/UpdateUserArgs.ts
new file mode 100644
index 0000000..30e635e
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UpdateUserArgs.ts
@@ -0,0 +1,7 @@
+import { UserWhereUniqueInput } from "./UserWhereUniqueInput";
+import { UserUpdateInput } from "./UserUpdateInput";
+
+export type UpdateUserArgs = {
+ where: UserWhereUniqueInput;
+ data: UserUpdateInput;
+};
diff --git a/platform/serv-admin/src/api/user/User.ts b/platform/serv-admin/src/api/user/User.ts
new file mode 100644
index 0000000..4293c44
--- /dev/null
+++ b/platform/serv-admin/src/api/user/User.ts
@@ -0,0 +1,18 @@
+import { AiGatekeeper } from "../aiGatekeeper/AiGatekeeper";
+import { JsonValue } from "type-fest";
+import { IdeaCollaboratorDev } from "../ideaCollaboratorDev/IdeaCollaboratorDev";
+
+export type User = {
+ company: string;
+ createdAt: Date;
+ email: string;
+ firstName: string;
+ id: string;
+ lastName: string;
+ location: string;
+ ownership?: Array;
+ roles: JsonValue;
+ teamOwner?: Array;
+ updatedAt: Date;
+ username: string;
+};
diff --git a/platform/serv-admin/src/api/user/UserCreateInput.ts b/platform/serv-admin/src/api/user/UserCreateInput.ts
new file mode 100644
index 0000000..bcd89c8
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserCreateInput.ts
@@ -0,0 +1,16 @@
+import { AiGatekeeperCreateNestedManyWithoutUsersInput } from "./AiGatekeeperCreateNestedManyWithoutUsersInput";
+import { InputJsonValue } from "../../types";
+import { IdeaCollaboratorDevCreateNestedManyWithoutUsersInput } from "./IdeaCollaboratorDevCreateNestedManyWithoutUsersInput";
+
+export type UserCreateInput = {
+ company: string;
+ email: string;
+ firstName: string;
+ lastName: string;
+ location: string;
+ ownership?: AiGatekeeperCreateNestedManyWithoutUsersInput;
+ password: string;
+ roles: InputJsonValue;
+ teamOwner?: IdeaCollaboratorDevCreateNestedManyWithoutUsersInput;
+ username: string;
+};
diff --git a/platform/serv-admin/src/api/user/UserFindManyArgs.ts b/platform/serv-admin/src/api/user/UserFindManyArgs.ts
new file mode 100644
index 0000000..b453f3e
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserFindManyArgs.ts
@@ -0,0 +1,9 @@
+import { UserWhereInput } from "./UserWhereInput";
+import { UserOrderByInput } from "./UserOrderByInput";
+
+export type UserFindManyArgs = {
+ where?: UserWhereInput;
+ orderBy?: Array;
+ skip?: number;
+ take?: number;
+};
diff --git a/platform/serv-admin/src/api/user/UserFindUniqueArgs.ts b/platform/serv-admin/src/api/user/UserFindUniqueArgs.ts
new file mode 100644
index 0000000..97d18e8
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserFindUniqueArgs.ts
@@ -0,0 +1,5 @@
+import { UserWhereUniqueInput } from "./UserWhereUniqueInput";
+
+export type UserFindUniqueArgs = {
+ where: UserWhereUniqueInput;
+};
diff --git a/platform/serv-admin/src/api/user/UserListRelationFilter.ts b/platform/serv-admin/src/api/user/UserListRelationFilter.ts
new file mode 100644
index 0000000..4c4d06e
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserListRelationFilter.ts
@@ -0,0 +1,7 @@
+import { UserWhereInput } from "./UserWhereInput";
+
+export type UserListRelationFilter = {
+ every?: UserWhereInput;
+ some?: UserWhereInput;
+ none?: UserWhereInput;
+};
diff --git a/platform/serv-admin/src/api/user/UserOrderByInput.ts b/platform/serv-admin/src/api/user/UserOrderByInput.ts
new file mode 100644
index 0000000..6eef840
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserOrderByInput.ts
@@ -0,0 +1,15 @@
+import { SortOrder } from "../../util/SortOrder";
+
+export type UserOrderByInput = {
+ company?: SortOrder;
+ createdAt?: SortOrder;
+ email?: SortOrder;
+ firstName?: SortOrder;
+ id?: SortOrder;
+ lastName?: SortOrder;
+ location?: SortOrder;
+ password?: SortOrder;
+ roles?: SortOrder;
+ updatedAt?: SortOrder;
+ username?: SortOrder;
+};
diff --git a/platform/serv-admin/src/api/user/UserUpdateInput.ts b/platform/serv-admin/src/api/user/UserUpdateInput.ts
new file mode 100644
index 0000000..cd5c7d2
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserUpdateInput.ts
@@ -0,0 +1,16 @@
+import { AiGatekeeperUpdateManyWithoutUsersInput } from "./AiGatekeeperUpdateManyWithoutUsersInput";
+import { InputJsonValue } from "../../types";
+import { IdeaCollaboratorDevUpdateManyWithoutUsersInput } from "./IdeaCollaboratorDevUpdateManyWithoutUsersInput";
+
+export type UserUpdateInput = {
+ company?: string;
+ email?: string;
+ firstName?: string;
+ lastName?: string;
+ location?: string;
+ ownership?: AiGatekeeperUpdateManyWithoutUsersInput;
+ password?: string;
+ roles?: InputJsonValue;
+ teamOwner?: IdeaCollaboratorDevUpdateManyWithoutUsersInput;
+ username?: string;
+};
diff --git a/platform/serv-admin/src/api/user/UserWhereInput.ts b/platform/serv-admin/src/api/user/UserWhereInput.ts
new file mode 100644
index 0000000..d9a49a7
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserWhereInput.ts
@@ -0,0 +1,18 @@
+import { StringFilter } from "../../util/StringFilter";
+import { DateTimeFilter } from "../../util/DateTimeFilter";
+import { AiGatekeeperListRelationFilter } from "../aiGatekeeper/AiGatekeeperListRelationFilter";
+import { IdeaCollaboratorDevListRelationFilter } from "../ideaCollaboratorDev/IdeaCollaboratorDevListRelationFilter";
+
+export type UserWhereInput = {
+ company?: StringFilter;
+ createdAt?: DateTimeFilter;
+ email?: StringFilter;
+ firstName?: StringFilter;
+ id?: StringFilter;
+ lastName?: StringFilter;
+ location?: StringFilter;
+ ownership?: AiGatekeeperListRelationFilter;
+ teamOwner?: IdeaCollaboratorDevListRelationFilter;
+ updatedAt?: DateTimeFilter;
+ username?: StringFilter;
+};
diff --git a/platform/serv-admin/src/api/user/UserWhereUniqueInput.ts b/platform/serv-admin/src/api/user/UserWhereUniqueInput.ts
new file mode 100644
index 0000000..309d343
--- /dev/null
+++ b/platform/serv-admin/src/api/user/UserWhereUniqueInput.ts
@@ -0,0 +1,3 @@
+export type UserWhereUniqueInput = {
+ id: string;
+};
diff --git a/platform/serv-admin/src/auth-provider/ra-auth-http.ts b/platform/serv-admin/src/auth-provider/ra-auth-http.ts
new file mode 100644
index 0000000..c6eeba8
--- /dev/null
+++ b/platform/serv-admin/src/auth-provider/ra-auth-http.ts
@@ -0,0 +1,78 @@
+import { gql } from "@apollo/client/core";
+import { AuthProvider } from "react-admin";
+import {
+ CREDENTIALS_LOCAL_STORAGE_ITEM,
+ USER_DATA_LOCAL_STORAGE_ITEM,
+} from "../constants";
+import { Credentials, LoginMutateResult } from "../types";
+import { apolloClient } from "../data-provider/graphqlDataProvider";
+
+const LOGIN = gql`
+ mutation login($username: String!, $password: String!) {
+ login(credentials: { username: $username, password: $password }) {
+ username
+ roles
+ }
+ }
+`;
+
+export const httpAuthProvider: AuthProvider = {
+ login: async (credentials: Credentials) => {
+ const userData = await apolloClient.mutate({
+ mutation: LOGIN,
+ variables: {
+ ...credentials,
+ },
+ });
+
+ if (userData && userData.data?.login.username) {
+ localStorage.setItem(
+ CREDENTIALS_LOCAL_STORAGE_ITEM,
+ createBasicAuthorizationHeader(
+ credentials.username,
+ credentials.password
+ )
+ );
+ localStorage.setItem(
+ USER_DATA_LOCAL_STORAGE_ITEM,
+ JSON.stringify(userData.data)
+ );
+ return Promise.resolve();
+ }
+ return Promise.reject();
+ },
+ logout: () => {
+ localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
+ return Promise.resolve();
+ },
+ checkError: ({ status }: any) => {
+ if (status === 401 || status === 403) {
+ localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
+ return Promise.reject();
+ }
+ return Promise.resolve();
+ },
+ checkAuth: () => {
+ return localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM)
+ ? Promise.resolve()
+ : Promise.reject();
+ },
+ getPermissions: () => Promise.reject("Unknown method"),
+ getIdentity: () => {
+ const str = localStorage.getItem(USER_DATA_LOCAL_STORAGE_ITEM);
+ const userData: LoginMutateResult = JSON.parse(str || "");
+
+ return Promise.resolve({
+ id: userData.login.username,
+ fullName: userData.login.username,
+ avatar: undefined,
+ });
+ },
+};
+
+function createBasicAuthorizationHeader(
+ username: string,
+ password: string
+): string {
+ return `Basic ${btoa(`${username}:${password}`)}`;
+}
diff --git a/platform/serv-admin/src/auth-provider/ra-auth-jwt.ts b/platform/serv-admin/src/auth-provider/ra-auth-jwt.ts
new file mode 100644
index 0000000..c8bcafc
--- /dev/null
+++ b/platform/serv-admin/src/auth-provider/ra-auth-jwt.ts
@@ -0,0 +1,72 @@
+import { gql } from "@apollo/client/core";
+import { AuthProvider } from "react-admin";
+import {
+ CREDENTIALS_LOCAL_STORAGE_ITEM,
+ USER_DATA_LOCAL_STORAGE_ITEM,
+} from "../constants";
+import { Credentials, LoginMutateResult } from "../types";
+import { apolloClient } from "../data-provider/graphqlDataProvider";
+
+const LOGIN = gql`
+ mutation login($username: String!, $password: String!) {
+ login(credentials: { username: $username, password: $password }) {
+ username
+ accessToken
+ }
+ }
+`;
+
+export const jwtAuthProvider: AuthProvider = {
+ login: async (credentials: Credentials) => {
+ const userData = await apolloClient.mutate({
+ mutation: LOGIN,
+ variables: {
+ ...credentials,
+ },
+ });
+
+ if (userData && userData.data?.login.username) {
+ localStorage.setItem(
+ CREDENTIALS_LOCAL_STORAGE_ITEM,
+ createBearerAuthorizationHeader(userData.data.login?.accessToken)
+ );
+ localStorage.setItem(
+ USER_DATA_LOCAL_STORAGE_ITEM,
+ JSON.stringify(userData.data)
+ );
+ return Promise.resolve();
+ }
+ return Promise.reject();
+ },
+ logout: () => {
+ localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
+ return Promise.resolve();
+ },
+ checkError: ({ status }: any) => {
+ if (status === 401 || status === 403) {
+ localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
+ return Promise.reject();
+ }
+ return Promise.resolve();
+ },
+ checkAuth: () => {
+ return localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM)
+ ? Promise.resolve()
+ : Promise.reject();
+ },
+ getPermissions: () => Promise.reject("Unknown method"),
+ getIdentity: () => {
+ const str = localStorage.getItem(USER_DATA_LOCAL_STORAGE_ITEM);
+ const userData: LoginMutateResult = JSON.parse(str || "");
+
+ return Promise.resolve({
+ id: userData.login.username,
+ fullName: userData.login.username,
+ avatar: undefined,
+ });
+ },
+};
+
+export function createBearerAuthorizationHeader(accessToken: string) {
+ return `Bearer ${accessToken}`;
+}
diff --git a/platform/serv-admin/src/auth.ts b/platform/serv-admin/src/auth.ts
new file mode 100644
index 0000000..498b026
--- /dev/null
+++ b/platform/serv-admin/src/auth.ts
@@ -0,0 +1,34 @@
+import { EventEmitter } from "events";
+import { CREDENTIALS_LOCAL_STORAGE_ITEM } from "./constants";
+import { Credentials } from "./types";
+
+const eventEmitter = new EventEmitter();
+
+export function isAuthenticated(): boolean {
+ return Boolean(getCredentials());
+}
+
+export function listen(listener: (authenticated: boolean) => void): void {
+ eventEmitter.on("change", () => {
+ listener(isAuthenticated());
+ });
+}
+
+export function setCredentials(credentials: Credentials) {
+ localStorage.setItem(
+ CREDENTIALS_LOCAL_STORAGE_ITEM,
+ JSON.stringify(credentials)
+ );
+}
+
+export function getCredentials(): Credentials | null {
+ const raw = localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
+ if (raw === null) {
+ return null;
+ }
+ return JSON.parse(raw);
+}
+
+export function removeCredentials(): void {
+ localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
+}
diff --git a/platform/serv-admin/src/constants.ts b/platform/serv-admin/src/constants.ts
new file mode 100644
index 0000000..4b3ca4b
--- /dev/null
+++ b/platform/serv-admin/src/constants.ts
@@ -0,0 +1,2 @@
+export const CREDENTIALS_LOCAL_STORAGE_ITEM = "credentials";
+export const USER_DATA_LOCAL_STORAGE_ITEM = "userData";
diff --git a/platform/serv-admin/src/data-provider/graphqlDataProvider.ts b/platform/serv-admin/src/data-provider/graphqlDataProvider.ts
new file mode 100644
index 0000000..3ec4466
--- /dev/null
+++ b/platform/serv-admin/src/data-provider/graphqlDataProvider.ts
@@ -0,0 +1,28 @@
+import buildGraphQLProvider from "ra-data-graphql-amplication";
+import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";
+import { setContext } from "@apollo/client/link/context";
+import { CREDENTIALS_LOCAL_STORAGE_ITEM } from "../constants";
+
+const httpLink = createHttpLink({
+ uri: `${process.env.REACT_APP_SERVER_URL}/graphql`,
+});
+
+// eslint-disable-next-line @typescript-eslint/naming-convention
+const authLink = setContext((_, { headers }) => {
+ const token = localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM);
+ return {
+ headers: {
+ ...headers,
+ authorization: token ? token : "",
+ },
+ };
+});
+
+export const apolloClient = new ApolloClient({
+ cache: new InMemoryCache(),
+ link: authLink.concat(httpLink),
+});
+
+export default buildGraphQLProvider({
+ client: apolloClient,
+});
diff --git a/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentCreate.tsx b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentCreate.tsx
new file mode 100644
index 0000000..f9119c8
--- /dev/null
+++ b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentCreate.tsx
@@ -0,0 +1,59 @@
+import * as React from "react";
+
+import {
+ Create,
+ SimpleForm,
+ CreateProps,
+ SelectInput,
+ DateTimeInput,
+ TextInput,
+ ReferenceInput,
+ NumberInput,
+} from "react-admin";
+
+import { AiGatekeeperTitle } from "../aiGatekeeper/AiGatekeeperTitle";
+
+export const DigitalCustodianAgentCreate = (
+ props: CreateProps
+): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentEdit.tsx b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentEdit.tsx
new file mode 100644
index 0000000..91fa5da
--- /dev/null
+++ b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentEdit.tsx
@@ -0,0 +1,59 @@
+import * as React from "react";
+
+import {
+ Edit,
+ SimpleForm,
+ EditProps,
+ SelectInput,
+ DateTimeInput,
+ TextInput,
+ ReferenceInput,
+ NumberInput,
+} from "react-admin";
+
+import { AiGatekeeperTitle } from "../aiGatekeeper/AiGatekeeperTitle";
+
+export const DigitalCustodianAgentEdit = (
+ props: EditProps
+): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentList.tsx b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentList.tsx
new file mode 100644
index 0000000..10f9b65
--- /dev/null
+++ b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentList.tsx
@@ -0,0 +1,42 @@
+import * as React from "react";
+import {
+ List,
+ Datagrid,
+ ListProps,
+ TextField,
+ DateField,
+ ReferenceField,
+} from "react-admin";
+import Pagination from "../Components/Pagination";
+import { AIGATEKEEPER_TITLE_FIELD } from "../aiGatekeeper/AiGatekeeperTitle";
+
+export const DigitalCustodianAgentList = (
+ props: ListProps
+): React.ReactElement => {
+ return (
+
}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentShow.tsx b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentShow.tsx
new file mode 100644
index 0000000..1bd4854
--- /dev/null
+++ b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentShow.tsx
@@ -0,0 +1,35 @@
+import * as React from "react";
+import {
+ Show,
+ SimpleShowLayout,
+ ShowProps,
+ TextField,
+ DateField,
+ ReferenceField,
+} from "react-admin";
+import { AIGATEKEEPER_TITLE_FIELD } from "../aiGatekeeper/AiGatekeeperTitle";
+
+export const DigitalCustodianAgentShow = (
+ props: ShowProps
+): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentTitle.ts b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentTitle.ts
new file mode 100644
index 0000000..f07e64c
--- /dev/null
+++ b/platform/serv-admin/src/digitalCustodianAgent/DigitalCustodianAgentTitle.ts
@@ -0,0 +1,9 @@
+import { DigitalCustodianAgent as TDigitalCustodianAgent } from "../api/digitalCustodianAgent/DigitalCustodianAgent";
+
+export const DIGITALCUSTODIANAGENT_TITLE_FIELD = "lastError";
+
+export const DigitalCustodianAgentTitle = (
+ record: TDigitalCustodianAgent
+): string => {
+ return record.lastError || String(record.id);
+};
diff --git a/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevCreate.tsx b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevCreate.tsx
new file mode 100644
index 0000000..d0fce31
--- /dev/null
+++ b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevCreate.tsx
@@ -0,0 +1,26 @@
+import * as React from "react";
+import {
+ Create,
+ SimpleForm,
+ CreateProps,
+ TextInput,
+ ReferenceInput,
+ SelectInput,
+} from "react-admin";
+import { UserTitle } from "../user/UserTitle";
+
+export const IdeaCollaboratorDevCreate = (
+ props: CreateProps
+): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevEdit.tsx b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevEdit.tsx
new file mode 100644
index 0000000..d1df072
--- /dev/null
+++ b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevEdit.tsx
@@ -0,0 +1,26 @@
+import * as React from "react";
+import {
+ Edit,
+ SimpleForm,
+ EditProps,
+ TextInput,
+ ReferenceInput,
+ SelectInput,
+} from "react-admin";
+import { UserTitle } from "../user/UserTitle";
+
+export const IdeaCollaboratorDevEdit = (
+ props: EditProps
+): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevList.tsx b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevList.tsx
new file mode 100644
index 0000000..ff5eba9
--- /dev/null
+++ b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevList.tsx
@@ -0,0 +1,36 @@
+import * as React from "react";
+import {
+ List,
+ Datagrid,
+ ListProps,
+ DateField,
+ TextField,
+ ReferenceField,
+} from "react-admin";
+import Pagination from "../Components/Pagination";
+import { USER_TITLE_FIELD } from "../user/UserTitle";
+
+export const IdeaCollaboratorDevList = (
+ props: ListProps
+): React.ReactElement => {
+ return (
+
}
+ >
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevShow.tsx b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevShow.tsx
new file mode 100644
index 0000000..bb1a046
--- /dev/null
+++ b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevShow.tsx
@@ -0,0 +1,29 @@
+import * as React from "react";
+import {
+ Show,
+ SimpleShowLayout,
+ ShowProps,
+ DateField,
+ TextField,
+ ReferenceField,
+} from "react-admin";
+import { USER_TITLE_FIELD } from "../user/UserTitle";
+
+export const IdeaCollaboratorDevShow = (
+ props: ShowProps
+): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevTitle.ts b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevTitle.ts
new file mode 100644
index 0000000..8372477
--- /dev/null
+++ b/platform/serv-admin/src/ideaCollaboratorDev/IdeaCollaboratorDevTitle.ts
@@ -0,0 +1,9 @@
+import { IdeaCollaboratorDev as TIdeaCollaboratorDev } from "../api/ideaCollaboratorDev/IdeaCollaboratorDev";
+
+export const IDEACOLLABORATORDEV_TITLE_FIELD = "id";
+
+export const IdeaCollaboratorDevTitle = (
+ record: TIdeaCollaboratorDev
+): string => {
+ return record.id || String(record.id);
+};
diff --git a/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestCreate.tsx b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestCreate.tsx
new file mode 100644
index 0000000..5c1012d
--- /dev/null
+++ b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestCreate.tsx
@@ -0,0 +1,16 @@
+import * as React from "react";
+import { Create, SimpleForm, CreateProps, TextInput } from "react-admin";
+
+export const IdeaViewerGuestCreate = (
+ props: CreateProps
+): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestEdit.tsx b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestEdit.tsx
new file mode 100644
index 0000000..ba4c3d0
--- /dev/null
+++ b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestEdit.tsx
@@ -0,0 +1,14 @@
+import * as React from "react";
+import { Edit, SimpleForm, EditProps, TextInput } from "react-admin";
+
+export const IdeaViewerGuestEdit = (props: EditProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestList.tsx b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestList.tsx
new file mode 100644
index 0000000..d34ddde
--- /dev/null
+++ b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestList.tsx
@@ -0,0 +1,24 @@
+import * as React from "react";
+import { List, Datagrid, ListProps, TextField, DateField } from "react-admin";
+import Pagination from "../Components/Pagination";
+
+export const IdeaViewerGuestList = (props: ListProps): React.ReactElement => {
+ return (
+
}
+ >
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestShow.tsx b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestShow.tsx
new file mode 100644
index 0000000..7d6fb78
--- /dev/null
+++ b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestShow.tsx
@@ -0,0 +1,23 @@
+import * as React from "react";
+import {
+ Show,
+ SimpleShowLayout,
+ ShowProps,
+ TextField,
+ DateField,
+} from "react-admin";
+
+export const IdeaViewerGuestShow = (props: ShowProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestTitle.ts b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestTitle.ts
new file mode 100644
index 0000000..5a7bdb1
--- /dev/null
+++ b/platform/serv-admin/src/ideaViewerGuest/IdeaViewerGuestTitle.ts
@@ -0,0 +1,7 @@
+import { IdeaViewerGuest as TIdeaViewerGuest } from "../api/ideaViewerGuest/IdeaViewerGuest";
+
+export const IDEAVIEWERGUEST_TITLE_FIELD = "company";
+
+export const IdeaViewerGuestTitle = (record: TIdeaViewerGuest): string => {
+ return record.company || String(record.id);
+};
diff --git a/platform/serv-admin/src/index.css b/platform/serv-admin/src/index.css
new file mode 100644
index 0000000..8686848
--- /dev/null
+++ b/platform/serv-admin/src/index.css
@@ -0,0 +1,26 @@
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
+ "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+#root {
+ height: 100vh;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
+ monospace;
+}
+
+.amp-breadcrumbs {
+ padding: var(--default-spacing);
+}
+
+.entity-id {
+ color: var(--primary);
+ text-decoration: underline;
+}
diff --git a/platform/serv-admin/src/index.tsx b/platform/serv-admin/src/index.tsx
new file mode 100644
index 0000000..5e2de69
--- /dev/null
+++ b/platform/serv-admin/src/index.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import "./index.css";
+// @ts-ignore
+// eslint-disable-next-line import/no-unresolved
+import App from "./App";
+import reportWebVitals from "./reportWebVitals";
+
+ReactDOM.render(
+
+
+ ,
+ document.getElementById("root")
+);
+
+// If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+reportWebVitals();
diff --git a/platform/serv-admin/src/login.scss b/platform/serv-admin/src/login.scss
new file mode 100644
index 0000000..667d8d2
--- /dev/null
+++ b/platform/serv-admin/src/login.scss
@@ -0,0 +1,119 @@
+:root {
+ --surface: #15192c; /*dark: black100 */
+ --white: #15192c; /*dark: black100 */
+
+ --black100: #ffffff; /*dark: white */
+ --black90: #b7bac7; /*dark: black10 */
+ --black80: #a3a8b8; /*dark: black20 */
+ --black60: #80869d; /*dark: black30 */
+ --black40: #686f8c; /*dark: black40 */
+ --black30: #515873; /*dark: black50 */
+ --black20: #444b66; /*dark: black60 */
+ --black10: #373d57; /*dark: black70 */
+ --black5: #2c3249; /*dark: black80 */
+ --black2: #22273c; /*dark: black90 */
+
+ --primary: #7950ed;
+}
+
+.login-page {
+ height: 100vh;
+ width: 100%;
+ background-color: var(--surface);
+ color: var(--black100);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+
+ &__wrapper {
+ display: flex;
+ align-items: stretch;
+ justify-content: center;
+ flex-direction: row;
+ }
+
+ &__box {
+ text-align: center;
+ width: 340px;
+ background-color: var(--black2);
+ border-radius: var(--small-border-radius);
+ margin: 1rem;
+ padding: 1rem;
+ border: 1px solid var(--black10);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: stretch;
+
+ h2 {
+ font-size: 18px;
+ }
+ img {
+ width: 48px;
+ }
+
+ &__message {
+ color: var(--black80);
+ font-size: 14px;
+ line-height: 22px;
+ }
+
+ button,
+ .MuiButton-contained {
+ box-sizing: border-box;
+ background-color: var(--primary);
+ width: 300px;
+ margin-top: 0.5rem;
+ margin-bottom: 1rem;
+ margin-top: auto;
+ &:hover,
+ &:active,
+ &:focus {
+ background-color: var(--primary);
+ }
+ }
+ }
+
+ form {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 2rem;
+
+ label {
+ span {
+ display: block;
+ text-align: left;
+ font-size: 12px;
+ color: var(--black60);
+ }
+ }
+
+ input {
+ box-sizing: border-box;
+ background-color: var(--white);
+ border: 1px solid var(--black10);
+ padding: 0.5rem;
+ margin-bottom: 1rem;
+ outline: none;
+ border-radius: var(--small-border-radius);
+ width: 300px;
+ color: var(--black100);
+ &:hover,
+ &:active,
+ &:focus {
+ border: 1px solid var(--black100);
+ }
+ }
+ }
+
+ &__read-more {
+ color: var(--black80);
+ a {
+ color: var(--black100);
+ text-decoration: none;
+ }
+ }
+}
diff --git a/platform/serv-admin/src/pages/Dashboard.tsx b/platform/serv-admin/src/pages/Dashboard.tsx
new file mode 100644
index 0000000..39c4d18
--- /dev/null
+++ b/platform/serv-admin/src/pages/Dashboard.tsx
@@ -0,0 +1,12 @@
+import * as React from "react";
+import Card from "@material-ui/core/Card";
+import CardContent from "@material-ui/core/CardContent";
+import { Title } from "react-admin";
+const Dashboard = () => (
+
+
+ Welcome
+
+);
+
+export default Dashboard;
diff --git a/platform/serv-admin/src/reportWebVitals.ts b/platform/serv-admin/src/reportWebVitals.ts
new file mode 100644
index 0000000..821a6cd
--- /dev/null
+++ b/platform/serv-admin/src/reportWebVitals.ts
@@ -0,0 +1,17 @@
+import { ReportHandler } from "web-vitals";
+
+const reportWebVitals = (onPerfEntry?: ReportHandler): void => {
+ if (onPerfEntry && onPerfEntry instanceof Function) {
+ void import("web-vitals").then(
+ ({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ getCLS(onPerfEntry);
+ getFID(onPerfEntry);
+ getFCP(onPerfEntry);
+ getLCP(onPerfEntry);
+ getTTFB(onPerfEntry);
+ }
+ );
+ }
+};
+
+export default reportWebVitals;
diff --git a/platform/serv-admin/src/setupTests.ts b/platform/serv-admin/src/setupTests.ts
new file mode 100644
index 0000000..1dd407a
--- /dev/null
+++ b/platform/serv-admin/src/setupTests.ts
@@ -0,0 +1,5 @@
+// jest-dom adds custom jest matchers for asserting on DOM nodes.
+// allows you to do things like:
+// expect(element).toHaveTextContent(/react/i)
+// learn more: https://github.com/testing-library/jest-dom
+import "@testing-library/jest-dom";
diff --git a/platform/serv-admin/src/theme/theme.ts b/platform/serv-admin/src/theme/theme.ts
new file mode 100644
index 0000000..56a1153
--- /dev/null
+++ b/platform/serv-admin/src/theme/theme.ts
@@ -0,0 +1,33 @@
+import { defaultTheme } from "react-admin";
+import { createTheme, ThemeOptions } from "@material-ui/core/styles";
+import { merge } from "lodash";
+import createPalette from "@material-ui/core/styles/createPalette";
+
+const palette = createPalette(
+ merge({}, defaultTheme.palette, {
+ primary: {
+ main: "#20a4f3",
+ },
+ secondary: {
+ main: "#7950ed",
+ },
+ error: {
+ main: "#e93c51",
+ },
+ warning: {
+ main: "#f6aa50",
+ },
+ info: {
+ main: "#144bc1",
+ },
+ success: {
+ main: "#31c587",
+ },
+ })
+);
+
+const themeOptions: ThemeOptions = {
+ palette,
+};
+
+export const theme = createTheme(merge({}, defaultTheme, themeOptions));
diff --git a/platform/serv-admin/src/types.ts b/platform/serv-admin/src/types.ts
new file mode 100644
index 0000000..45a457d
--- /dev/null
+++ b/platform/serv-admin/src/types.ts
@@ -0,0 +1,13 @@
+import { JsonValue } from "type-fest";
+
+export type Credentials = {
+ username: string;
+ password: string;
+};
+export type LoginMutateResult = {
+ login: {
+ username: string;
+ accessToken: string;
+ };
+};
+export type InputJsonValue = Omit;
diff --git a/platform/serv-admin/src/user/EnumRoles.ts b/platform/serv-admin/src/user/EnumRoles.ts
new file mode 100644
index 0000000..c2ad044
--- /dev/null
+++ b/platform/serv-admin/src/user/EnumRoles.ts
@@ -0,0 +1,8 @@
+export enum EnumRoles {
+ IdeaSprouter = "IdeaSprouterUser",
+ ChaosSculptor = "ChaosSculptorOwner",
+ IdeaViewer = "ideaViewerGuest",
+ DigitalCustodian = "DigitalCustodianAgent",
+ IdeaCollaborator = "IdeaCollaboratorDev",
+ AiGatekeeper = "AIGatekeeperAgent",
+}
diff --git a/platform/serv-admin/src/user/RolesOptions.ts b/platform/serv-admin/src/user/RolesOptions.ts
new file mode 100644
index 0000000..2f12fcf
--- /dev/null
+++ b/platform/serv-admin/src/user/RolesOptions.ts
@@ -0,0 +1,12 @@
+//@ts-ignore
+import { ROLES } from "./roles";
+
+declare interface Role {
+ name: string;
+ displayName: string;
+}
+
+export const ROLES_OPTIONS = ROLES.map((role: Role) => ({
+ value: role.name,
+ label: role.displayName,
+}));
diff --git a/platform/serv-admin/src/user/UserCreate.tsx b/platform/serv-admin/src/user/UserCreate.tsx
new file mode 100644
index 0000000..59dc86b
--- /dev/null
+++ b/platform/serv-admin/src/user/UserCreate.tsx
@@ -0,0 +1,53 @@
+import * as React from "react";
+
+import {
+ Create,
+ SimpleForm,
+ CreateProps,
+ TextInput,
+ ReferenceArrayInput,
+ SelectArrayInput,
+ PasswordInput,
+} from "react-admin";
+
+import { AiGatekeeperTitle } from "../aiGatekeeper/AiGatekeeperTitle";
+import { IdeaCollaboratorDevTitle } from "../ideaCollaboratorDev/IdeaCollaboratorDevTitle";
+import { ROLES_OPTIONS } from "../user/RolesOptions";
+
+export const UserCreate = (props: CreateProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+ value && value.map((v: any) => ({ id: v }))}
+ format={(value: any) => value && value.map((v: any) => v.id)}
+ >
+
+
+
+
+ value && value.map((v: any) => ({ id: v }))}
+ format={(value: any) => value && value.map((v: any) => v.id)}
+ >
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/user/UserEdit.tsx b/platform/serv-admin/src/user/UserEdit.tsx
new file mode 100644
index 0000000..825225d
--- /dev/null
+++ b/platform/serv-admin/src/user/UserEdit.tsx
@@ -0,0 +1,53 @@
+import * as React from "react";
+
+import {
+ Edit,
+ SimpleForm,
+ EditProps,
+ TextInput,
+ ReferenceArrayInput,
+ SelectArrayInput,
+ PasswordInput,
+} from "react-admin";
+
+import { AiGatekeeperTitle } from "../aiGatekeeper/AiGatekeeperTitle";
+import { IdeaCollaboratorDevTitle } from "../ideaCollaboratorDev/IdeaCollaboratorDevTitle";
+import { ROLES_OPTIONS } from "../user/RolesOptions";
+
+export const UserEdit = (props: EditProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+ value && value.map((v: any) => ({ id: v }))}
+ format={(value: any) => value && value.map((v: any) => v.id)}
+ >
+
+
+
+
+ value && value.map((v: any) => ({ id: v }))}
+ format={(value: any) => value && value.map((v: any) => v.id)}
+ >
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/user/UserList.tsx b/platform/serv-admin/src/user/UserList.tsx
new file mode 100644
index 0000000..de1a603
--- /dev/null
+++ b/platform/serv-admin/src/user/UserList.tsx
@@ -0,0 +1,28 @@
+import * as React from "react";
+import { List, Datagrid, ListProps, TextField, DateField } from "react-admin";
+import Pagination from "../Components/Pagination";
+
+export const UserList = (props: ListProps): React.ReactElement => {
+ return (
+
}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/user/UserShow.tsx b/platform/serv-admin/src/user/UserShow.tsx
new file mode 100644
index 0000000..65b1838
--- /dev/null
+++ b/platform/serv-admin/src/user/UserShow.tsx
@@ -0,0 +1,70 @@
+import * as React from "react";
+
+import {
+ Show,
+ SimpleShowLayout,
+ ShowProps,
+ TextField,
+ DateField,
+ ReferenceManyField,
+ Datagrid,
+ ReferenceField,
+} from "react-admin";
+
+import { USER_TITLE_FIELD } from "./UserTitle";
+
+export const UserShow = (props: ShowProps): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/platform/serv-admin/src/user/UserTitle.ts b/platform/serv-admin/src/user/UserTitle.ts
new file mode 100644
index 0000000..6653b8c
--- /dev/null
+++ b/platform/serv-admin/src/user/UserTitle.ts
@@ -0,0 +1,7 @@
+import { User as TUser } from "../api/user/User";
+
+export const USER_TITLE_FIELD = "firstName";
+
+export const UserTitle = (record: TUser): string => {
+ return record.firstName || String(record.id);
+};
diff --git a/platform/serv-admin/src/user/roles.ts b/platform/serv-admin/src/user/roles.ts
new file mode 100644
index 0000000..6035c55
--- /dev/null
+++ b/platform/serv-admin/src/user/roles.ts
@@ -0,0 +1,26 @@
+export const ROLES = [
+ {
+ name: "IdeaSprouterUser",
+ displayName: "Idea Sprouter",
+ },
+ {
+ name: "ChaosSculptorOwner",
+ displayName: "Chaos Sculptor ",
+ },
+ {
+ name: "ideaViewerGuest",
+ displayName: "Idea Viewer",
+ },
+ {
+ name: "DigitalCustodianAgent",
+ displayName: "Digital Custodian",
+ },
+ {
+ name: "IdeaCollaboratorDev",
+ displayName: "Idea Collaborator",
+ },
+ {
+ name: "AIGatekeeperAgent",
+ displayName: "AI Gatekeeper",
+ },
+];
diff --git a/platform/serv-admin/src/util/BooleanFilter.ts b/platform/serv-admin/src/util/BooleanFilter.ts
new file mode 100644
index 0000000..a142d58
--- /dev/null
+++ b/platform/serv-admin/src/util/BooleanFilter.ts
@@ -0,0 +1,4 @@
+export class BooleanFilter {
+ equals?: boolean;
+ not?: boolean;
+}
diff --git a/platform/serv-admin/src/util/BooleanNullableFilter.ts b/platform/serv-admin/src/util/BooleanNullableFilter.ts
new file mode 100644
index 0000000..b94aefc
--- /dev/null
+++ b/platform/serv-admin/src/util/BooleanNullableFilter.ts
@@ -0,0 +1,4 @@
+export class BooleanNullableFilter {
+ equals?: boolean | null;
+ not?: boolean | null;
+}
diff --git a/platform/serv-admin/src/util/DateTimeFilter.ts b/platform/serv-admin/src/util/DateTimeFilter.ts
new file mode 100644
index 0000000..cd8d213
--- /dev/null
+++ b/platform/serv-admin/src/util/DateTimeFilter.ts
@@ -0,0 +1,10 @@
+export class DateTimeFilter {
+ equals?: Date;
+ not?: Date;
+ in?: Date[];
+ notIn?: Date[];
+ lt?: Date;
+ lte?: Date;
+ gt?: Date;
+ gte?: Date;
+}
diff --git a/platform/serv-admin/src/util/DateTimeNullableFilter.ts b/platform/serv-admin/src/util/DateTimeNullableFilter.ts
new file mode 100644
index 0000000..2f9c7b3
--- /dev/null
+++ b/platform/serv-admin/src/util/DateTimeNullableFilter.ts
@@ -0,0 +1,10 @@
+export class DateTimeNullableFilter {
+ equals?: Date | null;
+ in?: Date[] | null;
+ notIn?: Date[] | null;
+ lt?: Date;
+ lte?: Date;
+ gt?: Date;
+ gte?: Date;
+ not?: Date;
+}
diff --git a/platform/serv-admin/src/util/FloatFilter.ts b/platform/serv-admin/src/util/FloatFilter.ts
new file mode 100644
index 0000000..62aeb14
--- /dev/null
+++ b/platform/serv-admin/src/util/FloatFilter.ts
@@ -0,0 +1,10 @@
+export class FloatFilter {
+ equals?: number;
+ in?: number[];
+ notIn?: number[];
+ lt?: number;
+ lte?: number;
+ gt?: number;
+ gte?: number;
+ not?: number;
+}
diff --git a/platform/serv-admin/src/util/FloatNullableFilter.ts b/platform/serv-admin/src/util/FloatNullableFilter.ts
new file mode 100644
index 0000000..d7bb163
--- /dev/null
+++ b/platform/serv-admin/src/util/FloatNullableFilter.ts
@@ -0,0 +1,10 @@
+export class FloatNullableFilter {
+ equals?: number | null;
+ in?: number[] | null;
+ notIn?: number[] | null;
+ lt?: number;
+ lte?: number;
+ gt?: number;
+ gte?: number;
+ not?: number;
+}
diff --git a/platform/serv-admin/src/util/IntFilter.ts b/platform/serv-admin/src/util/IntFilter.ts
new file mode 100644
index 0000000..3dc0221
--- /dev/null
+++ b/platform/serv-admin/src/util/IntFilter.ts
@@ -0,0 +1,10 @@
+export class IntFilter {
+ equals?: number;
+ in?: number[];
+ notIn?: number[];
+ lt?: number;
+ lte?: number;
+ gt?: number;
+ gte?: number;
+ not?: number;
+}
diff --git a/platform/serv-admin/src/util/IntNullableFilter.ts b/platform/serv-admin/src/util/IntNullableFilter.ts
new file mode 100644
index 0000000..2107cae
--- /dev/null
+++ b/platform/serv-admin/src/util/IntNullableFilter.ts
@@ -0,0 +1,10 @@
+export class IntNullableFilter {
+ equals?: number | null;
+ in?: number[] | null;
+ notIn?: number[] | null;
+ lt?: number;
+ lte?: number;
+ gt?: number;
+ gte?: number;
+ not?: number;
+}
diff --git a/platform/serv-admin/src/util/JsonFilter.ts b/platform/serv-admin/src/util/JsonFilter.ts
new file mode 100644
index 0000000..cc44763
--- /dev/null
+++ b/platform/serv-admin/src/util/JsonFilter.ts
@@ -0,0 +1,5 @@
+import { InputJsonValue } from "../types";
+export class JsonFilter {
+ equals?: InputJsonValue;
+ not?: InputJsonValue;
+}
diff --git a/platform/serv-admin/src/util/JsonNullableFilter.ts b/platform/serv-admin/src/util/JsonNullableFilter.ts
new file mode 100644
index 0000000..e6d1506
--- /dev/null
+++ b/platform/serv-admin/src/util/JsonNullableFilter.ts
@@ -0,0 +1,5 @@
+import { JsonValue } from "type-fest";
+export class JsonNullableFilter {
+ equals?: JsonValue | null;
+ not?: JsonValue | null;
+}
diff --git a/platform/serv-admin/src/util/MetaQueryPayload.ts b/platform/serv-admin/src/util/MetaQueryPayload.ts
new file mode 100644
index 0000000..bc3175b
--- /dev/null
+++ b/platform/serv-admin/src/util/MetaQueryPayload.ts
@@ -0,0 +1,3 @@
+export class MetaQueryPayload {
+ count!: number;
+}
diff --git a/platform/serv-admin/src/util/QueryMode.ts b/platform/serv-admin/src/util/QueryMode.ts
new file mode 100644
index 0000000..8a2164e
--- /dev/null
+++ b/platform/serv-admin/src/util/QueryMode.ts
@@ -0,0 +1,4 @@
+export enum QueryMode {
+ Default = "default",
+ Insensitive = "insensitive",
+}
diff --git a/platform/serv-admin/src/util/SortOrder.ts b/platform/serv-admin/src/util/SortOrder.ts
new file mode 100644
index 0000000..a5bcdb6
--- /dev/null
+++ b/platform/serv-admin/src/util/SortOrder.ts
@@ -0,0 +1,4 @@
+export enum SortOrder {
+ Asc = "asc",
+ Desc = "desc",
+}
diff --git a/platform/serv-admin/src/util/StringFilter.ts b/platform/serv-admin/src/util/StringFilter.ts
new file mode 100644
index 0000000..c2e26c5
--- /dev/null
+++ b/platform/serv-admin/src/util/StringFilter.ts
@@ -0,0 +1,16 @@
+import { QueryMode } from "./QueryMode";
+
+export class StringFilter {
+ equals?: string;
+ in?: string[];
+ notIn?: string[];
+ lt?: string;
+ lte?: string;
+ gt?: string;
+ gte?: string;
+ contains?: string;
+ startsWith?: string;
+ endsWith?: string;
+ mode?: QueryMode;
+ not?: string;
+}
diff --git a/platform/serv-admin/src/util/StringNullableFilter.ts b/platform/serv-admin/src/util/StringNullableFilter.ts
new file mode 100644
index 0000000..e1e37ec
--- /dev/null
+++ b/platform/serv-admin/src/util/StringNullableFilter.ts
@@ -0,0 +1,15 @@
+import { QueryMode } from "./QueryMode";
+export class StringNullableFilter {
+ equals?: string | null;
+ in?: string[] | null;
+ notIn?: string[] | null;
+ lt?: string;
+ lte?: string;
+ gt?: string;
+ gte?: string;
+ contains?: string;
+ startsWith?: string;
+ endsWith?: string;
+ mode?: QueryMode;
+ not?: string;
+}
diff --git a/platform/serv-admin/tsconfig.json b/platform/serv-admin/tsconfig.json
new file mode 100644
index 0000000..31cc780
--- /dev/null
+++ b/platform/serv-admin/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "strict": true
+ },
+ "include": ["src"],
+ "exclude": ["./node_modules"]
+}
diff --git a/platform/serv/.dockerignore b/platform/serv/.dockerignore
new file mode 100644
index 0000000..cb5c30b
--- /dev/null
+++ b/platform/serv/.dockerignore
@@ -0,0 +1,8 @@
+.dockerignore
+docker-compose.yml
+Dockerfile
+dist/
+node_modules
+.env
+.gitignore
+.prettierignore
\ No newline at end of file
diff --git a/platform/serv/.env b/platform/serv/.env
new file mode 100644
index 0000000..b8a9129
--- /dev/null
+++ b/platform/serv/.env
@@ -0,0 +1,10 @@
+BCRYPT_SALT=10
+COMPOSE_PROJECT_NAME=amp_cliafzzwa01p7i201epoygfox
+PORT=3000
+DB_URL=postgres://L4ndbo:Kong-Rasmus1984@localhost:5432/l4_the-platform
+DB_USER=L4ndbo
+DB_PASSWORD=Kong-Rasmus1984
+DB_PORT=5432
+DB_NAME=l4_the-platform
+JWT_SECRET_KEY=Change_ME!!!
+JWT_EXPIRATION=2d
\ No newline at end of file
diff --git a/platform/serv/.gitignore b/platform/serv/.gitignore
new file mode 100644
index 0000000..08c9980
--- /dev/null
+++ b/platform/serv/.gitignore
@@ -0,0 +1,5 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+/node_modules
+/dist
+.DS_Store
diff --git a/platform/serv/.prettierignore b/platform/serv/.prettierignore
new file mode 100644
index 0000000..e48f355
--- /dev/null
+++ b/platform/serv/.prettierignore
@@ -0,0 +1,5 @@
+node_modules/
+dist/
+prisma/migrations/
+package-lock.json
+coverage/
\ No newline at end of file
diff --git a/platform/serv/.prettierrc.json b/platform/serv/.prettierrc.json
new file mode 100644
index 0000000..7cac555
--- /dev/null
+++ b/platform/serv/.prettierrc.json
@@ -0,0 +1,5 @@
+{
+ "singleQuote": true,
+ "arrowParens": "avoid",
+ "trailingComma": "all"
+}
diff --git a/platform/serv/Dockerfile b/platform/serv/Dockerfile
new file mode 100644
index 0000000..0a20053
--- /dev/null
+++ b/platform/serv/Dockerfile
@@ -0,0 +1,31 @@
+FROM node:18.12.1 AS base
+
+WORKDIR /app
+
+COPY package.json ./
+
+RUN npm install
+
+COPY prisma/schema.prisma ./prisma/
+
+RUN npm run prisma:generate
+
+COPY . .
+
+RUN npm run build
+
+FROM node:18.12.1 AS prod
+
+WORKDIR /app
+
+COPY --from=base /app/node_modules/ ./node_modules
+COPY --from=base /app/package.json ./package.json
+COPY --from=base /app/dist ./dist
+COPY --from=base /app/prisma ./prisma
+COPY --from=base /app/scripts ./scripts
+COPY --from=base /app/src ./src
+COPY --from=base /app/tsconfig* ./
+
+EXPOSE 3000
+
+CMD [ "node", "./dist/main"]
diff --git a/platform/serv/README.md b/platform/serv/README.md
new file mode 100644
index 0000000..9de25c0
--- /dev/null
+++ b/platform/serv/README.md
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+# Introduction
+
+This service was generated with Amplication. The server-side of the generated project. This component provides the different backend services - i.e., REST API, GraphQL API, authentication, authorization, logging, data validation and the connection to the database. Additional information about the server component and the architecture around it, can be found on the [documentation](https://docs.amplication.com/guides/getting-started) site.
+
+# Getting started
+
+## Step 1: Configuration
+
+Configuration for the server component can be provided through the use of environment variables. These can be passed to the application via the use of the `.env` file in the base directory of the generated service. Below a table can be found which show the different variables that can be passed - these are the variables which exist by default, through the use of plugins additional integrations could require additional values. These values are provided default values after generation, change them to the desired values.
+
+| Variable | Description | Value |
+| -------------------- | -------------------------------------------- | ------------------------------------------------------------------- |
+| BCRYPT_SALT | the string used for hashing | [random-string] |
+| COMPOSE_PROJECT_NAME | the identifier of the service plus prefix | amp_[service-identifier] |
+| PORT | the port on which to run the server | 3000 |
+| DB_URL | the connection url for the database | [db-provider]://[username]:[password]@localhost:[db-port]/[db-name] |
+| DB_PORT | the port used by the database instance | [db-provider-port] |
+| DB_USER | the username used to connect to the database | [username] |
+| DB_PASSWORD | the password used to connect to the database | [password] |
+| DB_NAME | the name of the database | [service-name] / [project-name] |
+| JWT_SECRET_KEY | the secret used to sign the json-web token | [secret] |
+| JWT_EXPIRATION | the expiration time for the json-web token | 2d |
+
+> **Note**
+> Amplication generates default values and stores them under the .env file. It is advised to use some form of secrets manager/vault solution when using in production.
+
+## Step 2.1: Scripts - pre-requisites
+
+After configuration of the server the next step would be to run the application. Before running the server side of the component, make sure that the different pre-requisites are met - i.e., node.js [^16.x], npm, docker. After the setup of the pre-requisites the server component can be started.
+
+```sh
+# installation of the dependencies
+$ npm install
+```
+```sh
+# generate the prisma client
+$ npm run prisma:generate
+```
+```sh
+# start the database where the server component will connect to
+$ npm run docker:db
+```
+```sh
+# initialize the database
+$ npm run db:init
+```
+
+## Step 2.2: Scripts - local development
+
+```shell
+# start the server component
+$ npm run install
+```
+
+## Step 2.2: Scripts - container based development
+
+```shell
+# start the server component as a docker container
+$ npm run compose:up
+```
diff --git a/platform/serv/docker-compose.db.yml b/platform/serv/docker-compose.db.yml
new file mode 100644
index 0000000..8d7c358
--- /dev/null
+++ b/platform/serv/docker-compose.db.yml
@@ -0,0 +1,13 @@
+version: "3"
+services:
+ db:
+ image: postgres:12
+ ports:
+ - ${DB_PORT}:5432
+ environment:
+ POSTGRES_USER: ${DB_USER}
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
+ volumes:
+ - postgres:/var/lib/postgresql/data
+volumes:
+ postgres: ~
diff --git a/platform/serv/docker-compose.yml b/platform/serv/docker-compose.yml
new file mode 100644
index 0000000..6b231f2
--- /dev/null
+++ b/platform/serv/docker-compose.yml
@@ -0,0 +1,48 @@
+version: "3"
+services:
+ server:
+ build:
+ context: .
+ args:
+ NPM_LOG_LEVEL: notice
+ ports:
+ - ${PORT}:3000
+ environment:
+ BCRYPT_SALT: ${BCRYPT_SALT}
+ JWT_SECRET_KEY: ${JWT_SECRET_KEY}
+ JWT_EXPIRATION: ${JWT_EXPIRATION}
+ DB_URL: postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
+ depends_on:
+ - migrate
+ migrate:
+ build:
+ context: .
+ args:
+ NPM_LOG_LEVEL: notice
+ command: npm run db:init
+ working_dir: /app/server
+ environment:
+ BCRYPT_SALT: ${BCRYPT_SALT}
+ DB_URL: postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
+ depends_on:
+ db:
+ condition: service_healthy
+ db:
+ image: postgres:12
+ ports:
+ - ${DB_PORT}:5432
+ environment:
+ POSTGRES_USER: ${DB_USER}
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
+ POSTGRES_DB: ${DB_NAME}
+ volumes:
+ - postgres:/var/lib/postgresql/data
+ healthcheck:
+ test:
+ - CMD-SHELL
+ - pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}
+ timeout: 45s
+ interval: 10s
+ retries: 10
+volumes:
+ postgres: ~
diff --git a/platform/serv/nest-cli.json b/platform/serv/nest-cli.json
new file mode 100644
index 0000000..fe51713
--- /dev/null
+++ b/platform/serv/nest-cli.json
@@ -0,0 +1,6 @@
+{
+ "sourceRoot": "src",
+ "compilerOptions": {
+ "assets": ["swagger"]
+ }
+}
diff --git a/platform/serv/package.json b/platform/serv/package.json
new file mode 100644
index 0000000..8d58bcb
--- /dev/null
+++ b/platform/serv/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "@the-platform/server",
+ "private": true,
+ "scripts": {
+ "start": "nest start",
+ "start:watch": "nest start --watch",
+ "start:debug": "nest start --debug --watch",
+ "build": "nest build",
+ "test": "jest",
+ "seed": "ts-node scripts/seed.ts",
+ "db:migrate-save": "prisma migrate dev",
+ "db:migrate-up": "prisma migrate deploy",
+ "db:clean": "ts-node scripts/clean.ts",
+ "db:init": "run-s \"db:migrate-save -- --name 'initial version'\" db:migrate-up seed",
+ "prisma:generate": "prisma generate",
+ "docker:db": "docker-compose -f docker-compose.db.yml up -d",
+ "package:container": "docker build .",
+ "compose:up": "docker-compose up -d",
+ "compose:down": "docker-compose down --volumes",
+ "format": "prettier --write ."
+ },
+ "dependencies": {
+ "@nestjs/common": "8.4.7",
+ "@nestjs/config": "1.1.5",
+ "@nestjs/core": "8.4.7",
+ "@nestjs/graphql": "9.1.2",
+ "@nestjs/platform-express": "8.4.7",
+ "@nestjs/serve-static": "2.2.2",
+ "@nestjs/swagger": "5.1.5",
+ "@prisma/client": "4.6.1",
+ "apollo-server-express": "3.6.1",
+ "bcrypt": "5.0.1",
+ "class-transformer": "0.5.1",
+ "class-validator": "0.13.2",
+ "graphql": "15.7.2",
+ "graphql-type-json": "0.3.2",
+ "nest-access-control": "2.0.3",
+ "nest-morgan": "1.0.1",
+ "npm-run-all": "4.1.5",
+ "reflect-metadata": "0.1.13",
+ "swagger-ui-express": "4.3.0",
+ "ts-node": "10.9.1",
+ "validator": "^13.9.0",
+ "@nestjs/jwt": "^10.0.2",
+ "@nestjs/passport": "^9.0.0",
+ "passport": "0.6.0",
+ "passport-http": "0.3.0",
+ "passport-jwt": "4.0.1"
+ },
+ "devDependencies": {
+ "@nestjs/cli": "8.2.5",
+ "@nestjs/testing": "8.4.7",
+ "@types/bcrypt": "5.0.0",
+ "@types/express": "4.17.9",
+ "@types/graphql-type-json": "0.3.2",
+ "@types/jest": "26.0.19",
+ "@types/normalize-path": "3.0.0",
+ "@types/supertest": "2.0.11",
+ "@types/validator": "^13.7.15",
+ "jest": "27.0.6",
+ "jest-mock-extended": "^2.0.4",
+ "prisma": "4.6.1",
+ "supertest": "4.0.2",
+ "ts-jest": "27.0.3",
+ "type-fest": "0.11.0",
+ "typescript": "4.2.3",
+ "prettier": "^2.8.0",
+ "@types/passport-http": "0.3.9",
+ "@types/passport-jwt": "3.0.8"
+ },
+ "jest": {
+ "preset": "ts-jest",
+ "testEnvironment": "node",
+ "modulePathIgnorePatterns": ["/dist/"]
+ }
+}
diff --git a/platform/serv/prisma/schema.prisma b/platform/serv/prisma/schema.prisma
new file mode 100644
index 0000000..d38e14c
--- /dev/null
+++ b/platform/serv/prisma/schema.prisma
@@ -0,0 +1,93 @@
+datasource postgres {
+ provider = "postgresql"
+ url = env("DB_URL")
+}
+
+generator client {
+ provider = "prisma-client-js"
+}
+
+model User {
+ company String
+ createdAt DateTime @default(now())
+ email String @unique
+ firstName String
+ id String @id @default(cuid())
+ lastName String
+ location String
+ ownership AiGatekeeper[]
+ password String
+ roles Json
+ teamOwner IdeaCollaboratorDev[]
+ updatedAt DateTime @updatedAt
+ username String @unique
+}
+
+model AiGatekeeper {
+ AIStatus EnumAiGatekeeperAiStatus
+ createdAt DateTime @default(now())
+ createdBy User @relation(fields: [createdById], references: [id])
+ createdById String
+ id String @id @default(cuid())
+ myAgents DigitalCustodianAgent[]
+ roles String
+ TasksCompleted Int
+ updatedAt DateTime @updatedAt
+}
+
+model DigitalCustodianAgent {
+ agentStatus EnumDigitalCustodianAgentAgentStatus
+ createdAt DateTime @default(now())
+ id String @id @default(cuid())
+ lastActiveTime DateTime
+ lastError String?
+ MyAiGatekeeper AiGatekeeper? @relation(fields: [MyAiGatekeeperId], references: [id])
+ MyAiGatekeeperId String?
+ tasksCompleted Int
+ updatedAt DateTime @updatedAt
+}
+
+model IdeaViewerGuest {
+ company String
+ createdAt DateTime @default(now())
+ email String?
+ id String @id @default(cuid())
+ Location String
+ updatedAt DateTime @updatedAt
+}
+
+model IdeaCollaboratorDev {
+ createdAt DateTime @default(now())
+ email String @unique
+ id String @id @default(cuid())
+ inATeam User? @relation(fields: [inATeamId], references: [id])
+ inATeamId String?
+ location String
+ updatedAt DateTime @updatedAt
+}
+
+enum EnumAiGatekeeperAiStatus {
+ IDLE
+ THINKING
+ BREAK
+ CLEANING
+ TRAINING
+ FETCHING_DATA
+ DEBUGGING
+ ACTIVE
+ PROCESSING_IN_CLOUD
+ MANAGING_LARGE_DATA
+}
+
+enum EnumDigitalCustodianAgentAgentStatus {
+ IDLE
+ WORKING
+ LEARNING
+ BREAK
+ FETCHING_DATA
+ PROCESSING_DATA
+ DEBUGGING
+ OBSERVING
+ TRAINING
+ HELPING
+}
diff --git a/platform/serv/scripts/clean.ts b/platform/serv/scripts/clean.ts
new file mode 100644
index 0000000..a3887c8
--- /dev/null
+++ b/platform/serv/scripts/clean.ts
@@ -0,0 +1,58 @@
+/**
+ * Clean all the tables and types created by Prisma in the database
+ */
+
+import { PrismaClient } from "@prisma/client";
+
+if (require.main === module) {
+ clean().catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
+}
+
+async function clean() {
+ console.info("Dropping all tables in the database...");
+ const prisma = new PrismaClient();
+ const tables = await getTables(prisma);
+ const types = await getTypes(prisma);
+ await dropTables(prisma, tables);
+ await dropTypes(prisma, types);
+ console.info("Cleaned database successfully");
+ await prisma.$disconnect();
+}
+
+async function dropTables(
+ prisma: PrismaClient,
+ tables: string[]
+): Promise {
+ for (const table of tables) {
+ await prisma.$executeRawUnsafe(`DROP TABLE public."${table}" CASCADE;`);
+ }
+}
+
+async function dropTypes(prisma: PrismaClient, types: string[]) {
+ for (const type of types) {
+ await prisma.$executeRawUnsafe(`DROP TYPE IF EXISTS "${type}" CASCADE;`);
+ }
+}
+
+async function getTables(prisma: PrismaClient): Promise {
+ const results: Array<{
+ tablename: string;
+ }> =
+ await prisma.$queryRaw`SELECT tablename from pg_tables where schemaname = 'public';`;
+ return results.map((result) => result.tablename);
+}
+
+async function getTypes(prisma: PrismaClient): Promise {
+ const results: Array<{
+ typname: string;
+ }> = await prisma.$queryRaw`
+ SELECT t.typname
+ FROM pg_type t
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
+ WHERE n.nspname = 'public';
+ `;
+ return results.map((result) => result.typname);
+}
diff --git a/platform/serv/scripts/customSeed.ts b/platform/serv/scripts/customSeed.ts
new file mode 100644
index 0000000..6baf5f6
--- /dev/null
+++ b/platform/serv/scripts/customSeed.ts
@@ -0,0 +1,17 @@
+import { PrismaClient } from "@prisma/client";
+
+export async function customSeed() {
+ const client = new PrismaClient();
+ const username = "admin";
+
+ //replace this sample code to populate your database
+ //with data that is required for your service to start
+ await client.user.update({
+ where: { username: username },
+ data: {
+ username,
+ },
+ });
+
+ client.$disconnect();
+}
diff --git a/platform/serv/scripts/seed.ts b/platform/serv/scripts/seed.ts
new file mode 100644
index 0000000..321027f
--- /dev/null
+++ b/platform/serv/scripts/seed.ts
@@ -0,0 +1,54 @@
+import * as dotenv from "dotenv";
+import { PrismaClient } from "@prisma/client";
+import { customSeed } from "./customSeed";
+import { Salt, parseSalt } from "../src/auth/password.service";
+import { hash } from "bcrypt";
+
+if (require.main === module) {
+ dotenv.config();
+
+ const { BCRYPT_SALT } = process.env;
+
+ if (!BCRYPT_SALT) {
+ throw new Error("BCRYPT_SALT environment variable must be defined");
+ }
+ const salt = parseSalt(BCRYPT_SALT);
+
+ seed(salt).catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
+}
+
+async function seed(bcryptSalt: Salt) {
+ console.info("Seeding database...");
+
+ const client = new PrismaClient();
+
+ const data = {
+ username: "admin",
+ password: await hash("admin", bcryptSalt),
+ roles: ["user"],
+ company: "",
+ email: "example@example.com",
+ firstName: "",
+ lastName: "",
+ location: "(32.085300, 34.781769)",
+ };
+
+ await client.user.upsert({
+ where: {
+ username: data.username,
+ },
+
+ update: {},
+ create: data,
+ });
+
+ void client.$disconnect();
+
+ console.info("Seeding database with custom seed...");
+ customSeed();
+
+ console.info("Seeded database successfully");
+}
diff --git a/platform/serv/src/aiGatekeeper/aiGatekeeper.controller.ts b/platform/serv/src/aiGatekeeper/aiGatekeeper.controller.ts
new file mode 100644
index 0000000..7b7d4bd
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/aiGatekeeper.controller.ts
@@ -0,0 +1,17 @@
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import * as nestAccessControl from "nest-access-control";
+import { AiGatekeeperService } from "./aiGatekeeper.service";
+import { AiGatekeeperControllerBase } from "./base/aiGatekeeper.controller.base";
+
+@swagger.ApiTags("aiGatekeepers")
+@common.Controller("aiGatekeepers")
+export class AiGatekeeperController extends AiGatekeeperControllerBase {
+ constructor(
+ protected readonly service: AiGatekeeperService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/aiGatekeeper/aiGatekeeper.module.ts b/platform/serv/src/aiGatekeeper/aiGatekeeper.module.ts
new file mode 100644
index 0000000..002a163
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/aiGatekeeper.module.ts
@@ -0,0 +1,13 @@
+import { Module } from "@nestjs/common";
+import { AiGatekeeperModuleBase } from "./base/aiGatekeeper.module.base";
+import { AiGatekeeperService } from "./aiGatekeeper.service";
+import { AiGatekeeperController } from "./aiGatekeeper.controller";
+import { AiGatekeeperResolver } from "./aiGatekeeper.resolver";
+
+@Module({
+ imports: [AiGatekeeperModuleBase],
+ controllers: [AiGatekeeperController],
+ providers: [AiGatekeeperService, AiGatekeeperResolver],
+ exports: [AiGatekeeperService],
+})
+export class AiGatekeeperModule {}
diff --git a/platform/serv/src/aiGatekeeper/aiGatekeeper.resolver.ts b/platform/serv/src/aiGatekeeper/aiGatekeeper.resolver.ts
new file mode 100644
index 0000000..b86c5b9
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/aiGatekeeper.resolver.ts
@@ -0,0 +1,20 @@
+import * as graphql from "@nestjs/graphql";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { AiGatekeeperResolverBase } from "./base/aiGatekeeper.resolver.base";
+import { AiGatekeeper } from "./base/AiGatekeeper";
+import { AiGatekeeperService } from "./aiGatekeeper.service";
+
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => AiGatekeeper)
+export class AiGatekeeperResolver extends AiGatekeeperResolverBase {
+ constructor(
+ protected readonly service: AiGatekeeperService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/aiGatekeeper/aiGatekeeper.service.ts b/platform/serv/src/aiGatekeeper/aiGatekeeper.service.ts
new file mode 100644
index 0000000..96da41d
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/aiGatekeeper.service.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@nestjs/common";
+import { PrismaService } from "../prisma/prisma.service";
+import { AiGatekeeperServiceBase } from "./base/aiGatekeeper.service.base";
+
+@Injectable()
+export class AiGatekeeperService extends AiGatekeeperServiceBase {
+ constructor(protected readonly prisma: PrismaService) {
+ super(prisma);
+ }
+}
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeper.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeper.ts
new file mode 100644
index 0000000..50f7d36
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeper.ts
@@ -0,0 +1,107 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ObjectType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumAiGatekeeperAiStatus } from "./EnumAiGatekeeperAiStatus";
+import {
+ IsEnum,
+ IsDate,
+ ValidateNested,
+ IsString,
+ IsOptional,
+ IsInt,
+} from "class-validator";
+import { Type } from "class-transformer";
+import { User } from "../../user/base/User";
+import { DigitalCustodianAgent } from "../../digitalCustodianAgent/base/DigitalCustodianAgent";
+
+@ObjectType()
+class AiGatekeeper {
+ @ApiProperty({
+ required: true,
+ enum: EnumAiGatekeeperAiStatus,
+ })
+ @IsEnum(EnumAiGatekeeperAiStatus)
+ @Field(() => EnumAiGatekeeperAiStatus, {
+ nullable: true,
+ })
+ AIStatus?:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ createdAt!: Date;
+
+ @ApiProperty({
+ required: true,
+ type: () => User,
+ })
+ @ValidateNested()
+ @Type(() => User)
+ createdBy?: User;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+
+ @ApiProperty({
+ required: false,
+ type: () => [DigitalCustodianAgent],
+ })
+ @ValidateNested()
+ @Type(() => DigitalCustodianAgent)
+ @IsOptional()
+ myAgents?: Array;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ roles!: string;
+
+ @ApiProperty({
+ required: true,
+ type: Number,
+ })
+ @IsInt()
+ @Field(() => Number)
+ TasksCompleted!: number;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ updatedAt!: Date;
+}
+
+export { AiGatekeeper as AiGatekeeper };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperCreateInput.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperCreateInput.ts
new file mode 100644
index 0000000..42139a6
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperCreateInput.ts
@@ -0,0 +1,84 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumAiGatekeeperAiStatus } from "./EnumAiGatekeeperAiStatus";
+import {
+ IsEnum,
+ ValidateNested,
+ IsOptional,
+ IsString,
+ IsInt,
+} from "class-validator";
+import { UserWhereUniqueInput } from "../../user/base/UserWhereUniqueInput";
+import { Type } from "class-transformer";
+import { DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput } from "./DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput";
+
+@InputType()
+class AiGatekeeperCreateInput {
+ @ApiProperty({
+ required: true,
+ enum: EnumAiGatekeeperAiStatus,
+ })
+ @IsEnum(EnumAiGatekeeperAiStatus)
+ @Field(() => EnumAiGatekeeperAiStatus)
+ AIStatus!:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+
+ @ApiProperty({
+ required: true,
+ type: () => UserWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereUniqueInput)
+ @Field(() => UserWhereUniqueInput)
+ createdBy!: UserWhereUniqueInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput,
+ })
+ @ValidateNested()
+ @Type(() => DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput)
+ @IsOptional()
+ @Field(() => DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput, {
+ nullable: true,
+ })
+ myAgents?: DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ roles!: string;
+
+ @ApiProperty({
+ required: true,
+ type: Number,
+ })
+ @IsInt()
+ @Field(() => Number)
+ TasksCompleted!: number;
+}
+
+export { AiGatekeeperCreateInput as AiGatekeeperCreateInput };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperFindManyArgs.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperFindManyArgs.ts
new file mode 100644
index 0000000..42d0a26
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperFindManyArgs.ts
@@ -0,0 +1,53 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { AiGatekeeperWhereInput } from "./AiGatekeeperWhereInput";
+import { Type } from "class-transformer";
+import { AiGatekeeperOrderByInput } from "./AiGatekeeperOrderByInput";
+
+@ArgsType()
+class AiGatekeeperFindManyArgs {
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperWhereInput,
+ })
+ @Field(() => AiGatekeeperWhereInput, { nullable: true })
+ @Type(() => AiGatekeeperWhereInput)
+ where?: AiGatekeeperWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: [AiGatekeeperOrderByInput],
+ })
+ @Field(() => [AiGatekeeperOrderByInput], { nullable: true })
+ @Type(() => AiGatekeeperOrderByInput)
+ orderBy?: Array;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ skip?: number;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ take?: number;
+}
+
+export { AiGatekeeperFindManyArgs as AiGatekeeperFindManyArgs };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperFindUniqueArgs.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperFindUniqueArgs.ts
new file mode 100644
index 0000000..a7bfcba
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperFindUniqueArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { AiGatekeeperWhereUniqueInput } from "./AiGatekeeperWhereUniqueInput";
+
+@ArgsType()
+class AiGatekeeperFindUniqueArgs {
+ @Field(() => AiGatekeeperWhereUniqueInput, { nullable: false })
+ where!: AiGatekeeperWhereUniqueInput;
+}
+
+export { AiGatekeeperFindUniqueArgs as AiGatekeeperFindUniqueArgs };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperListRelationFilter.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperListRelationFilter.ts
new file mode 100644
index 0000000..1d80ac7
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperListRelationFilter.ts
@@ -0,0 +1,56 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { AiGatekeeperWhereInput } from "./AiGatekeeperWhereInput";
+import { ValidateNested, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+
+@InputType()
+class AiGatekeeperListRelationFilter {
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperWhereInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperWhereInput, {
+ nullable: true,
+ })
+ every?: AiGatekeeperWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperWhereInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperWhereInput, {
+ nullable: true,
+ })
+ some?: AiGatekeeperWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperWhereInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperWhereInput, {
+ nullable: true,
+ })
+ none?: AiGatekeeperWhereInput;
+}
+export { AiGatekeeperListRelationFilter as AiGatekeeperListRelationFilter };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperOrderByInput.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperOrderByInput.ts
new file mode 100644
index 0000000..1316a24
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperOrderByInput.ts
@@ -0,0 +1,85 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { SortOrder } from "../../util/SortOrder";
+
+@InputType({
+ isAbstract: true,
+ description: undefined,
+})
+class AiGatekeeperOrderByInput {
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ AIStatus?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ createdAt?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ createdById?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ id?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ roles?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ TasksCompleted?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ updatedAt?: SortOrder;
+}
+
+export { AiGatekeeperOrderByInput as AiGatekeeperOrderByInput };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperUpdateInput.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperUpdateInput.ts
new file mode 100644
index 0000000..2408ffa
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperUpdateInput.ts
@@ -0,0 +1,96 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumAiGatekeeperAiStatus } from "./EnumAiGatekeeperAiStatus";
+import {
+ IsEnum,
+ IsOptional,
+ ValidateNested,
+ IsString,
+ IsInt,
+} from "class-validator";
+import { UserWhereUniqueInput } from "../../user/base/UserWhereUniqueInput";
+import { Type } from "class-transformer";
+import { DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput } from "./DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput";
+
+@InputType()
+class AiGatekeeperUpdateInput {
+ @ApiProperty({
+ required: false,
+ enum: EnumAiGatekeeperAiStatus,
+ })
+ @IsEnum(EnumAiGatekeeperAiStatus)
+ @IsOptional()
+ @Field(() => EnumAiGatekeeperAiStatus, {
+ nullable: true,
+ })
+ AIStatus?:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereUniqueInput)
+ @IsOptional()
+ @Field(() => UserWhereUniqueInput, {
+ nullable: true,
+ })
+ createdBy?: UserWhereUniqueInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput,
+ })
+ @ValidateNested()
+ @Type(() => DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput)
+ @IsOptional()
+ @Field(() => DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput, {
+ nullable: true,
+ })
+ myAgents?: DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ roles?: string;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @IsInt()
+ @IsOptional()
+ @Field(() => Number, {
+ nullable: true,
+ })
+ TasksCompleted?: number;
+}
+
+export { AiGatekeeperUpdateInput as AiGatekeeperUpdateInput };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperWhereInput.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperWhereInput.ts
new file mode 100644
index 0000000..05f67f5
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperWhereInput.ts
@@ -0,0 +1,126 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumAiGatekeeperAiStatus } from "./EnumAiGatekeeperAiStatus";
+import { IsEnum, IsOptional, ValidateNested } from "class-validator";
+import { DateTimeFilter } from "../../util/DateTimeFilter";
+import { Type } from "class-transformer";
+import { UserWhereUniqueInput } from "../../user/base/UserWhereUniqueInput";
+import { StringFilter } from "../../util/StringFilter";
+import { DigitalCustodianAgentListRelationFilter } from "../../digitalCustodianAgent/base/DigitalCustodianAgentListRelationFilter";
+import { IntFilter } from "../../util/IntFilter";
+
+@InputType()
+class AiGatekeeperWhereInput {
+ @ApiProperty({
+ required: false,
+ enum: EnumAiGatekeeperAiStatus,
+ })
+ @IsEnum(EnumAiGatekeeperAiStatus)
+ @IsOptional()
+ @Field(() => EnumAiGatekeeperAiStatus, {
+ nullable: true,
+ })
+ AIStatus?:
+ | "IDLE"
+ | "THINKING"
+ | "BREAK"
+ | "CLEANING"
+ | "TRAINING"
+ | "FETCHING_DATA"
+ | "DEBUGGING"
+ | "ACTIVE"
+ | "PROCESSING_IN_CLOUD"
+ | "MANAGING_LARGE_DATA";
+
+ @ApiProperty({
+ required: false,
+ type: DateTimeFilter,
+ })
+ @Type(() => DateTimeFilter)
+ @IsOptional()
+ @Field(() => DateTimeFilter, {
+ nullable: true,
+ })
+ createdAt?: DateTimeFilter;
+
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereUniqueInput)
+ @IsOptional()
+ @Field(() => UserWhereUniqueInput, {
+ nullable: true,
+ })
+ createdBy?: UserWhereUniqueInput;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ id?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: () => DigitalCustodianAgentListRelationFilter,
+ })
+ @ValidateNested()
+ @Type(() => DigitalCustodianAgentListRelationFilter)
+ @IsOptional()
+ @Field(() => DigitalCustodianAgentListRelationFilter, {
+ nullable: true,
+ })
+ myAgents?: DigitalCustodianAgentListRelationFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ roles?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: IntFilter,
+ })
+ @Type(() => IntFilter)
+ @IsOptional()
+ @Field(() => IntFilter, {
+ nullable: true,
+ })
+ TasksCompleted?: IntFilter;
+
+ @ApiProperty({
+ required: false,
+ type: DateTimeFilter,
+ })
+ @Type(() => DateTimeFilter)
+ @IsOptional()
+ @Field(() => DateTimeFilter, {
+ nullable: true,
+ })
+ updatedAt?: DateTimeFilter;
+}
+
+export { AiGatekeeperWhereInput as AiGatekeeperWhereInput };
diff --git a/platform/serv/src/aiGatekeeper/base/AiGatekeeperWhereUniqueInput.ts b/platform/serv/src/aiGatekeeper/base/AiGatekeeperWhereUniqueInput.ts
new file mode 100644
index 0000000..5d2352b
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/AiGatekeeperWhereUniqueInput.ts
@@ -0,0 +1,27 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString } from "class-validator";
+
+@InputType()
+class AiGatekeeperWhereUniqueInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+}
+
+export { AiGatekeeperWhereUniqueInput as AiGatekeeperWhereUniqueInput };
diff --git a/platform/serv/src/aiGatekeeper/base/CreateAiGatekeeperArgs.ts b/platform/serv/src/aiGatekeeper/base/CreateAiGatekeeperArgs.ts
new file mode 100644
index 0000000..b2df070
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/CreateAiGatekeeperArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { AiGatekeeperCreateInput } from "./AiGatekeeperCreateInput";
+
+@ArgsType()
+class CreateAiGatekeeperArgs {
+ @Field(() => AiGatekeeperCreateInput, { nullable: false })
+ data!: AiGatekeeperCreateInput;
+}
+
+export { CreateAiGatekeeperArgs as CreateAiGatekeeperArgs };
diff --git a/platform/serv/src/aiGatekeeper/base/DeleteAiGatekeeperArgs.ts b/platform/serv/src/aiGatekeeper/base/DeleteAiGatekeeperArgs.ts
new file mode 100644
index 0000000..aa6a653
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/DeleteAiGatekeeperArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { AiGatekeeperWhereUniqueInput } from "./AiGatekeeperWhereUniqueInput";
+
+@ArgsType()
+class DeleteAiGatekeeperArgs {
+ @Field(() => AiGatekeeperWhereUniqueInput, { nullable: false })
+ where!: AiGatekeeperWhereUniqueInput;
+}
+
+export { DeleteAiGatekeeperArgs as DeleteAiGatekeeperArgs };
diff --git a/platform/serv/src/aiGatekeeper/base/DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput.ts b/platform/serv/src/aiGatekeeper/base/DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput.ts
new file mode 100644
index 0000000..d30602f
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput.ts
@@ -0,0 +1,28 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { DigitalCustodianAgentWhereUniqueInput } from "../../digitalCustodianAgent/base/DigitalCustodianAgentWhereUniqueInput";
+import { ApiProperty } from "@nestjs/swagger";
+
+@InputType()
+class DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput {
+ @Field(() => [DigitalCustodianAgentWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [DigitalCustodianAgentWhereUniqueInput],
+ })
+ connect?: Array;
+}
+
+export { DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput as DigitalCustodianAgentCreateNestedManyWithoutAiGatekeepersInput };
diff --git a/platform/serv/src/aiGatekeeper/base/DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput.ts b/platform/serv/src/aiGatekeeper/base/DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput.ts
new file mode 100644
index 0000000..60b1ed9
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput.ts
@@ -0,0 +1,46 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { DigitalCustodianAgentWhereUniqueInput } from "../../digitalCustodianAgent/base/DigitalCustodianAgentWhereUniqueInput";
+import { ApiProperty } from "@nestjs/swagger";
+
+@InputType()
+class DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput {
+ @Field(() => [DigitalCustodianAgentWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [DigitalCustodianAgentWhereUniqueInput],
+ })
+ connect?: Array;
+
+ @Field(() => [DigitalCustodianAgentWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [DigitalCustodianAgentWhereUniqueInput],
+ })
+ disconnect?: Array;
+
+ @Field(() => [DigitalCustodianAgentWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [DigitalCustodianAgentWhereUniqueInput],
+ })
+ set?: Array;
+}
+
+export { DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput as DigitalCustodianAgentUpdateManyWithoutAiGatekeepersInput };
diff --git a/platform/serv/src/aiGatekeeper/base/EnumAiGatekeeperAiStatus.ts b/platform/serv/src/aiGatekeeper/base/EnumAiGatekeeperAiStatus.ts
new file mode 100644
index 0000000..284ef5c
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/EnumAiGatekeeperAiStatus.ts
@@ -0,0 +1,29 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { registerEnumType } from "@nestjs/graphql";
+
+export enum EnumAiGatekeeperAiStatus {
+ DaydreamingInBinary = "IDLE",
+ ContemplatingTheMeaningOf_42 = "THINKING",
+ OnAByteBreak = "BREAK",
+ TidyingUpTheData = "CLEANING",
+ BabysittingTheNewAlgorithms = "TRAINING",
+ ChasingRunawayData = "FETCHING_DATA",
+ PlayingHideAndSeekWithBugs = "DEBUGGING",
+ DoingTheRobotDance = "ACTIVE",
+ BakingPiesInTheCloud = "PROCESSING_IN_CLOUD",
+ UnravelingTheYarnOfYottabytes = "MANAGING_LARGE_DATA",
+}
+
+registerEnumType(EnumAiGatekeeperAiStatus, {
+ name: "EnumAiGatekeeperAiStatus",
+});
diff --git a/platform/serv/src/aiGatekeeper/base/UpdateAiGatekeeperArgs.ts b/platform/serv/src/aiGatekeeper/base/UpdateAiGatekeeperArgs.ts
new file mode 100644
index 0000000..eb8ed6b
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/UpdateAiGatekeeperArgs.ts
@@ -0,0 +1,24 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { AiGatekeeperWhereUniqueInput } from "./AiGatekeeperWhereUniqueInput";
+import { AiGatekeeperUpdateInput } from "./AiGatekeeperUpdateInput";
+
+@ArgsType()
+class UpdateAiGatekeeperArgs {
+ @Field(() => AiGatekeeperWhereUniqueInput, { nullable: false })
+ where!: AiGatekeeperWhereUniqueInput;
+ @Field(() => AiGatekeeperUpdateInput, { nullable: false })
+ data!: AiGatekeeperUpdateInput;
+}
+
+export { UpdateAiGatekeeperArgs as UpdateAiGatekeeperArgs };
diff --git a/platform/serv/src/aiGatekeeper/base/aiGatekeeper.controller.base.spec.ts b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.controller.base.spec.ts
new file mode 100644
index 0000000..ab82780
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.controller.base.spec.ts
@@ -0,0 +1,199 @@
+import { Test } from "@nestjs/testing";
+import {
+ INestApplication,
+ HttpStatus,
+ ExecutionContext,
+ CallHandler,
+} from "@nestjs/common";
+import request from "supertest";
+import { MorganModule } from "nest-morgan";
+import { ACGuard } from "nest-access-control";
+import { DefaultAuthGuard } from "../../auth/defaultAuth.guard";
+import { ACLModule } from "../../auth/acl.module";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { map } from "rxjs";
+import { AiGatekeeperController } from "../aiGatekeeper.controller";
+import { AiGatekeeperService } from "../aiGatekeeper.service";
+
+const nonExistingId = "nonExistingId";
+const existingId = "existingId";
+const CREATE_INPUT = {
+ createdAt: new Date(),
+ id: "exampleId",
+ roles: "exampleRoles",
+ TasksCompleted: 42,
+ updatedAt: new Date(),
+};
+const CREATE_RESULT = {
+ createdAt: new Date(),
+ id: "exampleId",
+ roles: "exampleRoles",
+ TasksCompleted: 42,
+ updatedAt: new Date(),
+};
+const FIND_MANY_RESULT = [
+ {
+ createdAt: new Date(),
+ id: "exampleId",
+ roles: "exampleRoles",
+ TasksCompleted: 42,
+ updatedAt: new Date(),
+ },
+];
+const FIND_ONE_RESULT = {
+ createdAt: new Date(),
+ id: "exampleId",
+ roles: "exampleRoles",
+ TasksCompleted: 42,
+ updatedAt: new Date(),
+};
+
+const service = {
+ create() {
+ return CREATE_RESULT;
+ },
+ findMany: () => FIND_MANY_RESULT,
+ findOne: ({ where }: { where: { id: string } }) => {
+ switch (where.id) {
+ case existingId:
+ return FIND_ONE_RESULT;
+ case nonExistingId:
+ return null;
+ }
+ },
+};
+
+const basicAuthGuard = {
+ canActivate: (context: ExecutionContext) => {
+ const argumentHost = context.switchToHttp();
+ const request = argumentHost.getRequest();
+ request.user = {
+ roles: ["user"],
+ };
+ return true;
+ },
+};
+
+const acGuard = {
+ canActivate: () => {
+ return true;
+ },
+};
+
+const aclFilterResponseInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle().pipe(
+ map((data) => {
+ return data;
+ })
+ );
+ },
+};
+const aclValidateRequestInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle();
+ },
+};
+
+describe("AiGatekeeper", () => {
+ let app: INestApplication;
+
+ beforeAll(async () => {
+ const moduleRef = await Test.createTestingModule({
+ providers: [
+ {
+ provide: AiGatekeeperService,
+ useValue: service,
+ },
+ ],
+ controllers: [AiGatekeeperController],
+ imports: [MorganModule.forRoot(), ACLModule],
+ })
+ .overrideGuard(DefaultAuthGuard)
+ .useValue(basicAuthGuard)
+ .overrideGuard(ACGuard)
+ .useValue(acGuard)
+ .overrideInterceptor(AclFilterResponseInterceptor)
+ .useValue(aclFilterResponseInterceptor)
+ .overrideInterceptor(AclValidateRequestInterceptor)
+ .useValue(aclValidateRequestInterceptor)
+ .compile();
+
+ app = moduleRef.createNestApplication();
+ await app.init();
+ });
+
+ test("POST /aiGatekeepers", async () => {
+ await request(app.getHttpServer())
+ .post("/aiGatekeepers")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("GET /aiGatekeepers", async () => {
+ await request(app.getHttpServer())
+ .get("/aiGatekeepers")
+ .expect(HttpStatus.OK)
+ .expect([
+ {
+ ...FIND_MANY_RESULT[0],
+ createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(),
+ updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(),
+ },
+ ]);
+ });
+
+ test("GET /aiGatekeepers/:id non existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/aiGatekeepers"}/${nonExistingId}`)
+ .expect(HttpStatus.NOT_FOUND)
+ .expect({
+ statusCode: HttpStatus.NOT_FOUND,
+ message: `No resource was found for {"${"id"}":"${nonExistingId}"}`,
+ error: "Not Found",
+ });
+ });
+
+ test("GET /aiGatekeepers/:id existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/aiGatekeepers"}/${existingId}`)
+ .expect(HttpStatus.OK)
+ .expect({
+ ...FIND_ONE_RESULT,
+ createdAt: FIND_ONE_RESULT.createdAt.toISOString(),
+ updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("POST /aiGatekeepers existing resource", async () => {
+ let agent = request(app.getHttpServer());
+ await agent
+ .post("/aiGatekeepers")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ })
+ .then(function () {
+ agent
+ .post("/aiGatekeepers")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CONFLICT)
+ .expect({
+ statusCode: HttpStatus.CONFLICT,
+ });
+ });
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+});
diff --git a/platform/serv/src/aiGatekeeper/base/aiGatekeeper.controller.base.ts b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.controller.base.ts
new file mode 100644
index 0000000..139c586
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.controller.base.ts
@@ -0,0 +1,365 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import { isRecordNotFoundError } from "../../prisma.util";
+import * as errors from "../../errors";
+import { Request } from "express";
+import { plainToClass } from "class-transformer";
+import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator";
+import * as nestAccessControl from "nest-access-control";
+import * as defaultAuthGuard from "../../auth/defaultAuth.guard";
+import { AiGatekeeperService } from "../aiGatekeeper.service";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AiGatekeeperCreateInput } from "./AiGatekeeperCreateInput";
+import { AiGatekeeperWhereInput } from "./AiGatekeeperWhereInput";
+import { AiGatekeeperWhereUniqueInput } from "./AiGatekeeperWhereUniqueInput";
+import { AiGatekeeperFindManyArgs } from "./AiGatekeeperFindManyArgs";
+import { AiGatekeeperUpdateInput } from "./AiGatekeeperUpdateInput";
+import { AiGatekeeper } from "./AiGatekeeper";
+import { DigitalCustodianAgentFindManyArgs } from "../../digitalCustodianAgent/base/DigitalCustodianAgentFindManyArgs";
+import { DigitalCustodianAgent } from "../../digitalCustodianAgent/base/DigitalCustodianAgent";
+import { DigitalCustodianAgentWhereUniqueInput } from "../../digitalCustodianAgent/base/DigitalCustodianAgentWhereUniqueInput";
+
+@swagger.ApiBearerAuth()
+@common.UseGuards(defaultAuthGuard.DefaultAuthGuard, nestAccessControl.ACGuard)
+export class AiGatekeeperControllerBase {
+ constructor(
+ protected readonly service: AiGatekeeperService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Post()
+ @swagger.ApiCreatedResponse({ type: AiGatekeeper })
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "create",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: AiGatekeeperCreateInput,
+ })
+ async create(
+ @common.Body() data: AiGatekeeperCreateInput
+ ): Promise {
+ return await this.service.create({
+ data: {
+ ...data,
+
+ createdBy: {
+ connect: data.createdBy,
+ },
+ },
+ select: {
+ AIStatus: true,
+ createdAt: true,
+
+ createdBy: {
+ select: {
+ id: true,
+ },
+ },
+
+ id: true,
+ roles: true,
+ TasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get()
+ @swagger.ApiOkResponse({ type: [AiGatekeeper] })
+ @ApiNestedQuery(AiGatekeeperFindManyArgs)
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findMany(@common.Req() request: Request): Promise {
+ const args = plainToClass(AiGatekeeperFindManyArgs, request.query);
+ return this.service.findMany({
+ ...args,
+ select: {
+ AIStatus: true,
+ createdAt: true,
+
+ createdBy: {
+ select: {
+ id: true,
+ },
+ },
+
+ id: true,
+ roles: true,
+ TasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get("/:id")
+ @swagger.ApiOkResponse({ type: AiGatekeeper })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "own",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findOne(
+ @common.Param() params: AiGatekeeperWhereUniqueInput
+ ): Promise {
+ const result = await this.service.findOne({
+ where: params,
+ select: {
+ AIStatus: true,
+ createdAt: true,
+
+ createdBy: {
+ select: {
+ id: true,
+ },
+ },
+
+ id: true,
+ roles: true,
+ TasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ if (result === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Patch("/:id")
+ @swagger.ApiOkResponse({ type: AiGatekeeper })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "update",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: AiGatekeeperUpdateInput,
+ })
+ async update(
+ @common.Param() params: AiGatekeeperWhereUniqueInput,
+ @common.Body() data: AiGatekeeperUpdateInput
+ ): Promise {
+ try {
+ return await this.service.update({
+ where: params,
+ data: {
+ ...data,
+
+ createdBy: {
+ connect: data.createdBy,
+ },
+ },
+ select: {
+ AIStatus: true,
+ createdAt: true,
+
+ createdBy: {
+ select: {
+ id: true,
+ },
+ },
+
+ id: true,
+ roles: true,
+ TasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.Delete("/:id")
+ @swagger.ApiOkResponse({ type: AiGatekeeper })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "delete",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async delete(
+ @common.Param() params: AiGatekeeperWhereUniqueInput
+ ): Promise {
+ try {
+ return await this.service.delete({
+ where: params,
+ select: {
+ AIStatus: true,
+ createdAt: true,
+
+ createdBy: {
+ select: {
+ id: true,
+ },
+ },
+
+ id: true,
+ roles: true,
+ TasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get("/:id/myAgents")
+ @ApiNestedQuery(DigitalCustodianAgentFindManyArgs)
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "read",
+ possession: "any",
+ })
+ async findManyMyAgents(
+ @common.Req() request: Request,
+ @common.Param() params: AiGatekeeperWhereUniqueInput
+ ): Promise {
+ const query = plainToClass(
+ DigitalCustodianAgentFindManyArgs,
+ request.query
+ );
+ const results = await this.service.findMyAgents(params.id, {
+ ...query,
+ select: {
+ agentStatus: true,
+ createdAt: true,
+ id: true,
+ lastActiveTime: true,
+ lastError: true,
+
+ MyAiGatekeeper: {
+ select: {
+ id: true,
+ },
+ },
+
+ tasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ if (results === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return results;
+ }
+
+ @common.Post("/:id/myAgents")
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "update",
+ possession: "any",
+ })
+ async connectMyAgents(
+ @common.Param() params: AiGatekeeperWhereUniqueInput,
+ @common.Body() body: DigitalCustodianAgentWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ myAgents: {
+ connect: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+
+ @common.Patch("/:id/myAgents")
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "update",
+ possession: "any",
+ })
+ async updateMyAgents(
+ @common.Param() params: AiGatekeeperWhereUniqueInput,
+ @common.Body() body: DigitalCustodianAgentWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ myAgents: {
+ set: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+
+ @common.Delete("/:id/myAgents")
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "update",
+ possession: "any",
+ })
+ async disconnectMyAgents(
+ @common.Param() params: AiGatekeeperWhereUniqueInput,
+ @common.Body() body: DigitalCustodianAgentWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ myAgents: {
+ disconnect: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+}
diff --git a/platform/serv/src/aiGatekeeper/base/aiGatekeeper.module.base.ts b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.module.base.ts
new file mode 100644
index 0000000..8dc8e47
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.module.base.ts
@@ -0,0 +1,20 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { Module, forwardRef } from "@nestjs/common";
+import { MorganModule } from "nest-morgan";
+import { ACLModule } from "../../auth/acl.module";
+import { AuthModule } from "../../auth/auth.module";
+@Module({
+ imports: [ACLModule, forwardRef(() => AuthModule), MorganModule],
+ exports: [ACLModule, AuthModule, MorganModule],
+})
+export class AiGatekeeperModuleBase {}
diff --git a/platform/serv/src/aiGatekeeper/base/aiGatekeeper.resolver.base.ts b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.resolver.base.ts
new file mode 100644
index 0000000..b29efbd
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.resolver.base.ts
@@ -0,0 +1,203 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as graphql from "@nestjs/graphql";
+import * as apollo from "apollo-server-express";
+import { isRecordNotFoundError } from "../../prisma.util";
+import { MetaQueryPayload } from "../../util/MetaQueryPayload";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { CreateAiGatekeeperArgs } from "./CreateAiGatekeeperArgs";
+import { UpdateAiGatekeeperArgs } from "./UpdateAiGatekeeperArgs";
+import { DeleteAiGatekeeperArgs } from "./DeleteAiGatekeeperArgs";
+import { AiGatekeeperFindManyArgs } from "./AiGatekeeperFindManyArgs";
+import { AiGatekeeperFindUniqueArgs } from "./AiGatekeeperFindUniqueArgs";
+import { AiGatekeeper } from "./AiGatekeeper";
+import { DigitalCustodianAgentFindManyArgs } from "../../digitalCustodianAgent/base/DigitalCustodianAgentFindManyArgs";
+import { DigitalCustodianAgent } from "../../digitalCustodianAgent/base/DigitalCustodianAgent";
+import { User } from "../../user/base/User";
+import { AiGatekeeperService } from "../aiGatekeeper.service";
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => AiGatekeeper)
+export class AiGatekeeperResolverBase {
+ constructor(
+ protected readonly service: AiGatekeeperService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+
+ @graphql.Query(() => MetaQueryPayload)
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "any",
+ })
+ async _aiGatekeepersMeta(
+ @graphql.Args() args: AiGatekeeperFindManyArgs
+ ): Promise {
+ const results = await this.service.count({
+ ...args,
+ skip: undefined,
+ take: undefined,
+ });
+ return {
+ count: results,
+ };
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => [AiGatekeeper])
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "any",
+ })
+ async aiGatekeepers(
+ @graphql.Args() args: AiGatekeeperFindManyArgs
+ ): Promise {
+ return this.service.findMany(args);
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => AiGatekeeper, { nullable: true })
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "own",
+ })
+ async aiGatekeeper(
+ @graphql.Args() args: AiGatekeeperFindUniqueArgs
+ ): Promise {
+ const result = await this.service.findOne(args);
+ if (result === null) {
+ return null;
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => AiGatekeeper)
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "create",
+ possession: "any",
+ })
+ async createAiGatekeeper(
+ @graphql.Args() args: CreateAiGatekeeperArgs
+ ): Promise {
+ return await this.service.create({
+ ...args,
+ data: {
+ ...args.data,
+
+ createdBy: {
+ connect: args.data.createdBy,
+ },
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => AiGatekeeper)
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "update",
+ possession: "any",
+ })
+ async updateAiGatekeeper(
+ @graphql.Args() args: UpdateAiGatekeeperArgs
+ ): Promise {
+ try {
+ return await this.service.update({
+ ...args,
+ data: {
+ ...args.data,
+
+ createdBy: {
+ connect: args.data.createdBy,
+ },
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @graphql.Mutation(() => AiGatekeeper)
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "delete",
+ possession: "any",
+ })
+ async deleteAiGatekeeper(
+ @graphql.Args() args: DeleteAiGatekeeperArgs
+ ): Promise {
+ try {
+ return await this.service.delete(args);
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.ResolveField(() => [DigitalCustodianAgent], { name: "myAgents" })
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "read",
+ possession: "any",
+ })
+ async resolveFieldMyAgents(
+ @graphql.Parent() parent: AiGatekeeper,
+ @graphql.Args() args: DigitalCustodianAgentFindManyArgs
+ ): Promise {
+ const results = await this.service.findMyAgents(parent.id, args);
+
+ if (!results) {
+ return [];
+ }
+
+ return results;
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.ResolveField(() => User, {
+ nullable: true,
+ name: "createdBy",
+ })
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "read",
+ possession: "any",
+ })
+ async resolveFieldCreatedBy(
+ @graphql.Parent() parent: AiGatekeeper
+ ): Promise {
+ const result = await this.service.getCreatedBy(parent.id);
+
+ if (!result) {
+ return null;
+ }
+ return result;
+ }
+}
diff --git a/platform/serv/src/aiGatekeeper/base/aiGatekeeper.service.base.ts b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.service.base.ts
new file mode 100644
index 0000000..d8c9339
--- /dev/null
+++ b/platform/serv/src/aiGatekeeper/base/aiGatekeeper.service.base.ts
@@ -0,0 +1,73 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { PrismaService } from "../../prisma/prisma.service";
+import {
+ Prisma,
+ AiGatekeeper,
+ DigitalCustodianAgent,
+ User,
+} from "@prisma/client";
+
+export class AiGatekeeperServiceBase {
+ constructor(protected readonly prisma: PrismaService) {}
+
+ async count(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.aiGatekeeper.count(args);
+ }
+
+ async findMany(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.aiGatekeeper.findMany(args);
+ }
+ async findOne(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.aiGatekeeper.findUnique(args);
+ }
+ async create(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.aiGatekeeper.create(args);
+ }
+ async update(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.aiGatekeeper.update(args);
+ }
+ async delete(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.aiGatekeeper.delete(args);
+ }
+
+ async findMyAgents(
+ parentId: string,
+ args: Prisma.DigitalCustodianAgentFindManyArgs
+ ): Promise {
+ return this.prisma.aiGatekeeper
+ .findUniqueOrThrow({
+ where: { id: parentId },
+ })
+ .myAgents(args);
+ }
+
+ async getCreatedBy(parentId: string): Promise {
+ return this.prisma.aiGatekeeper
+ .findUnique({
+ where: { id: parentId },
+ })
+ .createdBy();
+ }
+}
diff --git a/platform/serv/src/app.module.ts b/platform/serv/src/app.module.ts
new file mode 100644
index 0000000..05b8abd
--- /dev/null
+++ b/platform/serv/src/app.module.ts
@@ -0,0 +1,61 @@
+import { Module, Scope } from "@nestjs/common";
+import { APP_INTERCEPTOR } from "@nestjs/core";
+import { MorganInterceptor, MorganModule } from "nest-morgan";
+import { UserModule } from "./user/user.module";
+import { AiGatekeeperModule } from "./aiGatekeeper/aiGatekeeper.module";
+import { DigitalCustodianAgentModule } from "./digitalCustodianAgent/digitalCustodianAgent.module";
+import { IdeaViewerGuestModule } from "./ideaViewerGuest/ideaViewerGuest.module";
+import { IdeaCollaboratorDevModule } from "./ideaCollaboratorDev/ideaCollaboratorDev.module";
+import { HealthModule } from "./health/health.module";
+import { PrismaModule } from "./prisma/prisma.module";
+import { SecretsManagerModule } from "./providers/secrets/secretsManager.module";
+import { ConfigModule, ConfigService } from "@nestjs/config";
+import { ServeStaticModule } from "@nestjs/serve-static";
+import { ServeStaticOptionsService } from "./serveStaticOptions.service";
+import { GraphQLModule } from "@nestjs/graphql";
+
+import { ACLModule } from "./auth/acl.module";
+import { AuthModule } from "./auth/auth.module";
+
+@Module({
+ controllers: [],
+ imports: [
+ ACLModule,
+ AuthModule,
+ UserModule,
+ AiGatekeeperModule,
+ DigitalCustodianAgentModule,
+ IdeaViewerGuestModule,
+ IdeaCollaboratorDevModule,
+ HealthModule,
+ PrismaModule,
+ SecretsManagerModule,
+ MorganModule,
+ ConfigModule.forRoot({ isGlobal: true }),
+ ServeStaticModule.forRootAsync({
+ useClass: ServeStaticOptionsService,
+ }),
+ GraphQLModule.forRootAsync({
+ useFactory: (configService) => {
+ const playground = configService.get("GRAPHQL_PLAYGROUND");
+ const introspection = configService.get("GRAPHQL_INTROSPECTION");
+ return {
+ autoSchemaFile: "schema.graphql",
+ sortSchema: true,
+ playground,
+ introspection: playground || introspection,
+ };
+ },
+ inject: [ConfigService],
+ imports: [ConfigModule],
+ }),
+ ],
+ providers: [
+ {
+ provide: APP_INTERCEPTOR,
+ scope: Scope.REQUEST,
+ useClass: MorganInterceptor("combined"),
+ },
+ ],
+})
+export class AppModule {}
diff --git a/platform/serv/src/auth/Credentials.ts b/platform/serv/src/auth/Credentials.ts
new file mode 100644
index 0000000..9ac6798
--- /dev/null
+++ b/platform/serv/src/auth/Credentials.ts
@@ -0,0 +1,21 @@
+import { ApiProperty } from "@nestjs/swagger";
+import { InputType, Field } from "@nestjs/graphql";
+import { IsString } from "class-validator";
+
+@InputType()
+export class Credentials {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String, { nullable: false })
+ username!: string;
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String, { nullable: false })
+ password!: string;
+}
diff --git a/platform/serv/src/auth/IAuthStrategy.ts b/platform/serv/src/auth/IAuthStrategy.ts
new file mode 100644
index 0000000..5db10cf
--- /dev/null
+++ b/platform/serv/src/auth/IAuthStrategy.ts
@@ -0,0 +1,5 @@
+import { UserInfo } from "./UserInfo";
+
+export interface IAuthStrategy {
+ validate: (...any: any) => Promise;
+}
diff --git a/platform/serv/src/auth/ITokenService.ts b/platform/serv/src/auth/ITokenService.ts
new file mode 100644
index 0000000..7983189
--- /dev/null
+++ b/platform/serv/src/auth/ITokenService.ts
@@ -0,0 +1,9 @@
+export interface ITokenPayload {
+ id: string;
+ username: string;
+ password: string;
+}
+
+export interface ITokenService {
+ createToken: ({ id, username, password }: ITokenPayload) => Promise;
+}
diff --git a/platform/serv/src/auth/LoginArgs.ts b/platform/serv/src/auth/LoginArgs.ts
new file mode 100644
index 0000000..1aa4803
--- /dev/null
+++ b/platform/serv/src/auth/LoginArgs.ts
@@ -0,0 +1,8 @@
+import { ArgsType, Field } from "@nestjs/graphql";
+import { Credentials } from "./Credentials";
+
+@ArgsType()
+export class LoginArgs {
+ @Field(() => Credentials, { nullable: false })
+ credentials!: Credentials;
+}
diff --git a/platform/serv/src/auth/UserInfo.ts b/platform/serv/src/auth/UserInfo.ts
new file mode 100644
index 0000000..ef61dc4
--- /dev/null
+++ b/platform/serv/src/auth/UserInfo.ts
@@ -0,0 +1,14 @@
+import { Field, ObjectType } from "@nestjs/graphql";
+import { User } from "../user/base/User";
+
+@ObjectType()
+export class UserInfo implements Partial {
+ @Field(() => String)
+ id!: string;
+ @Field(() => String)
+ username!: string;
+ @Field(() => [String])
+ roles!: string[];
+ @Field(() => String, { nullable: true })
+ accessToken?: string;
+}
diff --git a/platform/serv/src/auth/abac.util.ts b/platform/serv/src/auth/abac.util.ts
new file mode 100644
index 0000000..7047513
--- /dev/null
+++ b/platform/serv/src/auth/abac.util.ts
@@ -0,0 +1,14 @@
+import { Permission } from "accesscontrol";
+
+/**
+ * @returns attributes not allowed to appear on given data according to given
+ * attributeMatchers
+ */
+export function getInvalidAttributes(
+ permission: Permission,
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ data: Object
+): string[] {
+ const filteredData = permission.filter(data);
+ return Object.keys(data).filter((key) => !(key in filteredData));
+}
diff --git a/platform/serv/src/auth/acl.module.ts b/platform/serv/src/auth/acl.module.ts
new file mode 100644
index 0000000..eb90005
--- /dev/null
+++ b/platform/serv/src/auth/acl.module.ts
@@ -0,0 +1,7 @@
+import { AccessControlModule, RolesBuilder } from "nest-access-control";
+// @ts-ignore
+// eslint-disable-next-line import/no-unresolved
+import grants from "../grants.json";
+
+// eslint-disable-next-line @typescript-eslint/naming-convention
+export const ACLModule = AccessControlModule.forRoles(new RolesBuilder(grants));
diff --git a/platform/serv/src/auth/auth.controller.ts b/platform/serv/src/auth/auth.controller.ts
new file mode 100644
index 0000000..3eb5676
--- /dev/null
+++ b/platform/serv/src/auth/auth.controller.ts
@@ -0,0 +1,15 @@
+import { Body, Controller, Post } from "@nestjs/common";
+import { ApiTags } from "@nestjs/swagger";
+import { AuthService } from "./auth.service";
+import { Credentials } from "./Credentials";
+import { UserInfo } from "./UserInfo";
+
+@ApiTags("auth")
+@Controller()
+export class AuthController {
+ constructor(private readonly authService: AuthService) {}
+ @Post("login")
+ async login(@Body() body: Credentials): Promise {
+ return this.authService.login(body);
+ }
+}
diff --git a/platform/serv/src/auth/auth.module.ts b/platform/serv/src/auth/auth.module.ts
new file mode 100644
index 0000000..8390f5a
--- /dev/null
+++ b/platform/serv/src/auth/auth.module.ts
@@ -0,0 +1,55 @@
+import { forwardRef, Module } from "@nestjs/common";
+import { ConfigService } from "@nestjs/config";
+import { JwtModule } from "@nestjs/jwt";
+import { PassportModule } from "@nestjs/passport";
+import { JWT_EXPIRATION, JWT_SECRET_KEY } from "../constants";
+import { SecretsManagerModule } from "../providers/secrets/secretsManager.module";
+import { SecretsManagerService } from "../providers/secrets/secretsManager.service";
+// @ts-ignore
+// eslint-disable-next-line
+import { UserModule } from "../user/user.module";
+import { AuthController } from "./auth.controller";
+import { AuthResolver } from "./auth.resolver";
+import { AuthService } from "./auth.service";
+import { BasicStrategy } from "./basic/basic.strategy";
+import { PasswordService } from "./password.service";
+import { TokenService } from "./token.service";
+
+@Module({
+ imports: [
+ forwardRef(() => UserModule),
+ PassportModule,
+ SecretsManagerModule,
+ JwtModule.registerAsync({
+ imports: [SecretsManagerModule],
+ inject: [SecretsManagerService, ConfigService],
+ useFactory: async (
+ secretsService: SecretsManagerService,
+ configService: ConfigService
+ ) => {
+ const secret = await secretsService.getSecret(JWT_SECRET_KEY);
+ const expiresIn = configService.get(JWT_EXPIRATION);
+ if (!secret) {
+ throw new Error("Didn't get a valid jwt secret");
+ }
+ if (!expiresIn) {
+ throw new Error("Jwt expire in value is not valid");
+ }
+ return {
+ secret: secret,
+ signOptions: { expiresIn },
+ };
+ },
+ }),
+ ],
+ providers: [
+ AuthService,
+ BasicStrategy,
+ PasswordService,
+ AuthResolver,
+ TokenService,
+ ],
+ controllers: [AuthController],
+ exports: [AuthService, PasswordService],
+})
+export class AuthModule {}
diff --git a/platform/serv/src/auth/auth.resolver.ts b/platform/serv/src/auth/auth.resolver.ts
new file mode 100644
index 0000000..fb4d6dd
--- /dev/null
+++ b/platform/serv/src/auth/auth.resolver.ts
@@ -0,0 +1,23 @@
+import * as common from "@nestjs/common";
+import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
+import * as gqlACGuard from "../auth/gqlAC.guard";
+import { AuthService } from "./auth.service";
+import { GqlDefaultAuthGuard } from "./gqlDefaultAuth.guard";
+import { UserData } from "./userData.decorator";
+import { LoginArgs } from "./LoginArgs";
+import { UserInfo } from "./UserInfo";
+
+@Resolver(UserInfo)
+export class AuthResolver {
+ constructor(private readonly authService: AuthService) {}
+ @Mutation(() => UserInfo)
+ async login(@Args() args: LoginArgs): Promise {
+ return this.authService.login(args.credentials);
+ }
+
+ @Query(() => UserInfo)
+ @common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+ async userInfo(@UserData() userInfo: UserInfo): Promise {
+ return userInfo;
+ }
+}
diff --git a/platform/serv/src/auth/auth.service.spec.ts b/platform/serv/src/auth/auth.service.spec.ts
new file mode 100644
index 0000000..aaa68e4
--- /dev/null
+++ b/platform/serv/src/auth/auth.service.spec.ts
@@ -0,0 +1,118 @@
+import { Test, TestingModule } from "@nestjs/testing";
+// @ts-ignore
+// eslint-disable-next-line
+import { UserService } from "../user/user.service";
+import { AuthService } from "./auth.service";
+import { Credentials } from "./Credentials";
+import { PasswordService } from "./password.service";
+// @ts-ignore
+// eslint-disable-next-line
+import { TokenService } from "./token.service";
+import { VALID_ID } from "../tests/auth/constants";
+
+const VALID_CREDENTIALS: Credentials = {
+ username: "Valid User",
+ password: "Valid User Password",
+};
+const INVALID_CREDENTIALS: Credentials = {
+ username: "Invalid User",
+ password: "Invalid User Password",
+};
+const USER: any = {
+ ...VALID_CREDENTIALS,
+ createdAt: new Date(),
+ firstName: "ofek",
+ id: VALID_ID,
+ lastName: "gabay",
+ roles: ["admin"],
+ updatedAt: new Date(),
+};
+
+const SIGN_TOKEN = "SIGN_TOKEN";
+
+const userService = {
+ findOne(args: { where: { username: string } }): any | null {
+ if (args.where.username === VALID_CREDENTIALS.username) {
+ return USER;
+ }
+ return null;
+ },
+};
+
+const passwordService = {
+ compare(password: string, encrypted: string) {
+ return true;
+ },
+};
+
+const tokenService = {
+ createToken(username: string, password: string) {
+ return SIGN_TOKEN;
+ },
+};
+
+describe("AuthService", () => {
+ //ARRANGE
+ let service: AuthService;
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [
+ {
+ provide: UserService,
+ useValue: userService,
+ },
+ {
+ provide: PasswordService,
+ useValue: passwordService,
+ },
+ {
+ provide: TokenService,
+ useValue: tokenService,
+ },
+ AuthService,
+ ],
+ }).compile();
+
+ service = module.get(AuthService);
+ });
+
+ it("should be defined", () => {
+ expect(service).toBeDefined();
+ });
+
+ describe("Testing the authService.validateUser()", () => {
+ it("should validate a valid user", async () => {
+ await expect(
+ service.validateUser(
+ VALID_CREDENTIALS.username,
+ VALID_CREDENTIALS.password
+ )
+ ).resolves.toEqual({
+ username: USER.username,
+ roles: USER.roles,
+ id: USER.id,
+ });
+ });
+
+ it("should not validate a invalid user", async () => {
+ await expect(
+ service.validateUser(
+ INVALID_CREDENTIALS.username,
+ INVALID_CREDENTIALS.password
+ )
+ ).resolves.toBe(null);
+ });
+ });
+
+ describe("Testing the authService.login()", () => {
+ it("should return userInfo object for correct username and password", async () => {
+ const loginResult = await service.login(VALID_CREDENTIALS);
+ expect(loginResult).toEqual({
+ username: USER.username,
+ roles: USER.roles,
+ accessToken: SIGN_TOKEN,
+ id: USER.id,
+ });
+ });
+ });
+});
diff --git a/platform/serv/src/auth/auth.service.ts b/platform/serv/src/auth/auth.service.ts
new file mode 100644
index 0000000..b54440b
--- /dev/null
+++ b/platform/serv/src/auth/auth.service.ts
@@ -0,0 +1,51 @@
+import { Injectable, UnauthorizedException } from "@nestjs/common";
+// @ts-ignore
+// eslint-disable-next-line
+import { UserService } from "../user/user.service";
+import { Credentials } from "./Credentials";
+import { PasswordService } from "./password.service";
+import { TokenService } from "./token.service";
+import { UserInfo } from "./UserInfo";
+
+@Injectable()
+export class AuthService {
+ constructor(
+ private readonly userService: UserService,
+ private readonly passwordService: PasswordService,
+ private readonly tokenService: TokenService
+ ) {}
+
+ async validateUser(
+ username: string,
+ password: string
+ ): Promise {
+ const user = await this.userService.findOne({
+ where: { username },
+ });
+ if (user && (await this.passwordService.compare(password, user.password))) {
+ const { id, roles } = user;
+ const roleList = roles as string[];
+ return { id, username, roles: roleList };
+ }
+ return null;
+ }
+ async login(credentials: Credentials): Promise {
+ const { username, password } = credentials;
+ const user = await this.validateUser(
+ credentials.username,
+ credentials.password
+ );
+ if (!user) {
+ throw new UnauthorizedException("The passed credentials are incorrect");
+ }
+ const accessToken = await this.tokenService.createToken({
+ id: user.id,
+ username,
+ password,
+ });
+ return {
+ accessToken,
+ ...user,
+ };
+ }
+}
diff --git a/platform/serv/src/auth/base/token.service.base.ts b/platform/serv/src/auth/base/token.service.base.ts
new file mode 100644
index 0000000..f2a64fe
--- /dev/null
+++ b/platform/serv/src/auth/base/token.service.base.ts
@@ -0,0 +1,21 @@
+import { Injectable } from "@nestjs/common";
+import { INVALID_PASSWORD_ERROR, INVALID_USERNAME_ERROR } from "../constants";
+import { ITokenService, ITokenPayload } from "../ITokenService";
+/**
+ * TokenServiceBase is a basic http implementation of ITokenService
+ */
+@Injectable()
+export class TokenServiceBase implements ITokenService {
+ /**
+ *
+ * @object { username: String, password: String }
+ * @returns a base64 string of the username and password
+ */
+ createToken({ username, password }: ITokenPayload): Promise {
+ if (!username) return Promise.reject(INVALID_USERNAME_ERROR);
+ if (!password) return Promise.reject(INVALID_PASSWORD_ERROR);
+ return Promise.resolve(
+ Buffer.from(`${username}:${password}`).toString("base64")
+ );
+ }
+}
diff --git a/platform/serv/src/auth/basic/base/basic.strategy.base.ts b/platform/serv/src/auth/basic/base/basic.strategy.base.ts
new file mode 100644
index 0000000..e138356
--- /dev/null
+++ b/platform/serv/src/auth/basic/base/basic.strategy.base.ts
@@ -0,0 +1,23 @@
+import { UnauthorizedException } from "@nestjs/common";
+import { PassportStrategy } from "@nestjs/passport";
+import { BasicStrategy as Strategy } from "passport-http";
+import { AuthService } from "../../auth.service";
+import { IAuthStrategy } from "../../IAuthStrategy";
+import { UserInfo } from "../../UserInfo";
+
+export class BasicStrategyBase
+ extends PassportStrategy(Strategy)
+ implements IAuthStrategy
+{
+ constructor(protected readonly authService: AuthService) {
+ super();
+ }
+
+ async validate(username: string, password: string): Promise {
+ const user = await this.authService.validateUser(username, password);
+ if (!user) {
+ throw new UnauthorizedException();
+ }
+ return user;
+ }
+}
diff --git a/platform/serv/src/auth/basic/basic.strategy.ts b/platform/serv/src/auth/basic/basic.strategy.ts
new file mode 100644
index 0000000..f087795
--- /dev/null
+++ b/platform/serv/src/auth/basic/basic.strategy.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@nestjs/common";
+import { AuthService } from "../auth.service";
+import { BasicStrategyBase } from "./base/basic.strategy.base";
+
+@Injectable()
+export class BasicStrategy extends BasicStrategyBase {
+ constructor(protected readonly authService: AuthService) {
+ super(authService);
+ }
+}
diff --git a/platform/serv/src/auth/basic/basicAuth.guard.ts b/platform/serv/src/auth/basic/basicAuth.guard.ts
new file mode 100644
index 0000000..9c92fdd
--- /dev/null
+++ b/platform/serv/src/auth/basic/basicAuth.guard.ts
@@ -0,0 +1,3 @@
+import { AuthGuard } from "@nestjs/passport";
+
+export class BasicAuthGuard extends AuthGuard("basic") {}
diff --git a/platform/serv/src/auth/constants.ts b/platform/serv/src/auth/constants.ts
new file mode 100644
index 0000000..59f9f7d
--- /dev/null
+++ b/platform/serv/src/auth/constants.ts
@@ -0,0 +1,2 @@
+export const INVALID_USERNAME_ERROR = "Invalid username";
+export const INVALID_PASSWORD_ERROR = "Invalid password";
diff --git a/platform/serv/src/auth/defaultAuth.guard.ts b/platform/serv/src/auth/defaultAuth.guard.ts
new file mode 100644
index 0000000..d1ec3db
--- /dev/null
+++ b/platform/serv/src/auth/defaultAuth.guard.ts
@@ -0,0 +1,27 @@
+import { Observable } from "rxjs";
+import { ExecutionContext, Injectable } from "@nestjs/common";
+import { Reflector } from "@nestjs/core";
+import { IS_PUBLIC_KEY } from "../decorators/public.decorator";
+import { BasicAuthGuard } from "./basic/basicAuth.guard";
+
+@Injectable()
+export class DefaultAuthGuard extends BasicAuthGuard {
+ constructor(private readonly reflector: Reflector) {
+ super();
+ }
+
+ canActivate(
+ context: ExecutionContext
+ ): boolean | Promise | Observable {
+ const isPublic = this.reflector.get(
+ IS_PUBLIC_KEY,
+ context.getHandler()
+ );
+
+ if (isPublic) {
+ return true;
+ }
+
+ return super.canActivate(context);
+ }
+}
diff --git a/platform/serv/src/auth/gqlAC.guard.ts b/platform/serv/src/auth/gqlAC.guard.ts
new file mode 100644
index 0000000..dacac55
--- /dev/null
+++ b/platform/serv/src/auth/gqlAC.guard.ts
@@ -0,0 +1,11 @@
+import { ExecutionContext } from "@nestjs/common";
+import { GqlExecutionContext } from "@nestjs/graphql";
+import { ACGuard } from "nest-access-control";
+
+export class GqlACGuard extends ACGuard {
+ async getUser(context: ExecutionContext): Promise {
+ const ctx = GqlExecutionContext.create(context);
+ const request = ctx.getContext<{ req: { user: User } }>().req;
+ return request.user;
+ }
+}
diff --git a/platform/serv/src/auth/gqlDefaultAuth.guard.ts b/platform/serv/src/auth/gqlDefaultAuth.guard.ts
new file mode 100644
index 0000000..17143e1
--- /dev/null
+++ b/platform/serv/src/auth/gqlDefaultAuth.guard.ts
@@ -0,0 +1,14 @@
+import { ExecutionContext } from "@nestjs/common";
+import { GqlExecutionContext } from "@nestjs/graphql";
+import type { Request } from "express";
+// @ts-ignore
+// eslint-disable-next-line
+import { DefaultAuthGuard } from "./defaultAuth.guard";
+
+export class GqlDefaultAuthGuard extends DefaultAuthGuard {
+ // This method is required for the interface - do not delete it.
+ getRequest(context: ExecutionContext): Request {
+ const ctx = GqlExecutionContext.create(context);
+ return ctx.getContext<{ req: Request }>().req;
+ }
+}
diff --git a/platform/serv/src/auth/gqlUserRoles.decorator.ts b/platform/serv/src/auth/gqlUserRoles.decorator.ts
new file mode 100644
index 0000000..5ea256b
--- /dev/null
+++ b/platform/serv/src/auth/gqlUserRoles.decorator.ts
@@ -0,0 +1,19 @@
+import { createParamDecorator, ExecutionContext } from "@nestjs/common";
+import { GqlExecutionContext } from "@nestjs/graphql";
+
+/**
+ * Access the user roles from the request object i.e `req.user.roles`.
+ *
+ * You can pass an optional property key to the decorator to get it from the user object
+ * e.g `@UserRoles('permissions')` will return the `req.user.permissions` instead.
+ */
+export const UserRoles = createParamDecorator(
+ (data: string, context: ExecutionContext) => {
+ const ctx = GqlExecutionContext.create(context);
+ const request = ctx.getContext<{ req: { user: any } }>().req;
+ if (!request.user) {
+ return null;
+ }
+ return data ? request.user[data] : request.user.roles;
+ }
+);
diff --git a/platform/serv/src/auth/jwt/base/jwt.strategy.base.ts b/platform/serv/src/auth/jwt/base/jwt.strategy.base.ts
new file mode 100644
index 0000000..7766538
--- /dev/null
+++ b/platform/serv/src/auth/jwt/base/jwt.strategy.base.ts
@@ -0,0 +1,40 @@
+import { UnauthorizedException } from "@nestjs/common";
+import { PassportStrategy } from "@nestjs/passport";
+import { ExtractJwt, Strategy } from "passport-jwt";
+import { IAuthStrategy } from "../../IAuthStrategy";
+import { UserService } from "../../../user/user.service";
+import { UserInfo } from "../../UserInfo";
+
+export class JwtStrategyBase
+ extends PassportStrategy(Strategy)
+ implements IAuthStrategy
+{
+ constructor(
+ protected readonly userService: UserService,
+ protected readonly secretOrKey: string
+ ) {
+ super({
+ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
+ ignoreExpiration: false,
+ secretOrKey,
+ });
+ }
+
+ async validate(payload: UserInfo): Promise {
+ const { username } = payload;
+ const user = await this.userService.findOne({
+ where: { username },
+ });
+ if (!user) {
+ throw new UnauthorizedException();
+ }
+ if (
+ !Array.isArray(user.roles) ||
+ typeof user.roles !== "object" ||
+ user.roles === null
+ ) {
+ throw new Error("User roles is not a valid value");
+ }
+ return { ...user, roles: user.roles as string[] };
+ }
+}
diff --git a/platform/serv/src/auth/jwt/jwt.strategy.ts b/platform/serv/src/auth/jwt/jwt.strategy.ts
new file mode 100644
index 0000000..0794650
--- /dev/null
+++ b/platform/serv/src/auth/jwt/jwt.strategy.ts
@@ -0,0 +1,14 @@
+import { Inject, Injectable } from "@nestjs/common";
+import { JWT_SECRET_KEY } from "../../constants";
+import { UserService } from "../../user/user.service";
+import { JwtStrategyBase } from "./base/jwt.strategy.base";
+
+@Injectable()
+export class JwtStrategy extends JwtStrategyBase {
+ constructor(
+ protected readonly userService: UserService,
+ @Inject(JWT_SECRET_KEY) secretOrKey: string
+ ) {
+ super(userService, secretOrKey);
+ }
+}
diff --git a/platform/serv/src/auth/jwt/jwtAuth.guard.ts b/platform/serv/src/auth/jwt/jwtAuth.guard.ts
new file mode 100644
index 0000000..f0c5570
--- /dev/null
+++ b/platform/serv/src/auth/jwt/jwtAuth.guard.ts
@@ -0,0 +1,3 @@
+import { AuthGuard } from "@nestjs/passport";
+
+export class JwtAuthGuard extends AuthGuard("jwt") {}
diff --git a/platform/serv/src/auth/jwt/jwtSecretFactory.ts b/platform/serv/src/auth/jwt/jwtSecretFactory.ts
new file mode 100644
index 0000000..151e793
--- /dev/null
+++ b/platform/serv/src/auth/jwt/jwtSecretFactory.ts
@@ -0,0 +1,16 @@
+import { JWT_SECRET_KEY } from "../../constants";
+import { SecretsManagerService } from "../../providers/secrets/secretsManager.service";
+
+export const jwtSecretFactory = {
+ provide: JWT_SECRET_KEY,
+ useFactory: async (
+ secretsService: SecretsManagerService
+ ): Promise => {
+ const secret = await secretsService.getSecret(JWT_SECRET_KEY);
+ if (secret) {
+ return secret;
+ }
+ throw new Error("jwtSecretFactory missing secret");
+ },
+ inject: [SecretsManagerService],
+};
diff --git a/platform/serv/src/auth/password.service.spec.ts b/platform/serv/src/auth/password.service.spec.ts
new file mode 100644
index 0000000..309c8c0
--- /dev/null
+++ b/platform/serv/src/auth/password.service.spec.ts
@@ -0,0 +1,69 @@
+import { ConfigService } from "@nestjs/config";
+import { Test, TestingModule } from "@nestjs/testing";
+import { PasswordService } from "./password.service";
+
+const EXAMPLE_PASSWORD = "examplePassword";
+const EXAMPLE_HASHED_PASSWORD = "exampleHashedPassword";
+
+const EXAMPLE_SALT_OR_ROUNDS = 1;
+
+const configServiceGetMock = jest.fn(() => {
+ return EXAMPLE_SALT_OR_ROUNDS;
+});
+
+jest.mock("bcrypt", () => ({
+ hash: jest.fn(),
+ compare: jest.fn(),
+}));
+
+const { hash, compare } = jest.requireMock("bcrypt");
+
+hash.mockImplementation(async () => EXAMPLE_HASHED_PASSWORD);
+
+compare.mockImplementation(async () => true);
+
+describe("PasswordService", () => {
+ let service: PasswordService;
+
+ beforeEach(async () => {
+ jest.clearAllMocks();
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [
+ PasswordService,
+ {
+ provide: ConfigService,
+ useClass: jest.fn(() => ({
+ get: configServiceGetMock,
+ })),
+ },
+ ],
+ imports: [],
+ }).compile();
+
+ service = module.get(PasswordService);
+ });
+
+ it("should be defined", () => {
+ expect(service).toBeDefined();
+ });
+
+ it("should have salt defined", () => {
+ expect(service.salt).toEqual(EXAMPLE_SALT_OR_ROUNDS);
+ });
+
+ it("should compare a password", async () => {
+ const args = {
+ password: EXAMPLE_PASSWORD,
+ hashedPassword: EXAMPLE_HASHED_PASSWORD,
+ };
+ await expect(
+ service.compare(args.password, args.hashedPassword)
+ ).resolves.toEqual(true);
+ });
+
+ it("should hash a password", async () => {
+ await expect(service.hash(EXAMPLE_PASSWORD)).resolves.toEqual(
+ EXAMPLE_HASHED_PASSWORD
+ );
+ });
+});
diff --git a/platform/serv/src/auth/password.service.ts b/platform/serv/src/auth/password.service.ts
new file mode 100644
index 0000000..377b64b
--- /dev/null
+++ b/platform/serv/src/auth/password.service.ts
@@ -0,0 +1,64 @@
+import { Injectable } from "@nestjs/common";
+import { hash, compare } from "bcrypt";
+import { ConfigService } from "@nestjs/config";
+
+/** Salt or number of rounds to generate a salt */
+export type Salt = string | number;
+
+const BCRYPT_SALT_VAR = "BCRYPT_SALT";
+const UNDEFINED_SALT_OR_ROUNDS_ERROR = `${BCRYPT_SALT_VAR} is not defined`;
+const SALT_OR_ROUNDS_TYPE_ERROR = `${BCRYPT_SALT_VAR} must be a positive integer or text`;
+
+@Injectable()
+export class PasswordService {
+ /**
+ * the salt to be used to hash the password. if specified as a number then a
+ * salt will be generated with the specified number of rounds and used
+ */
+ salt: Salt;
+
+ constructor(private configService: ConfigService) {
+ const saltOrRounds = this.configService.get(BCRYPT_SALT_VAR);
+ this.salt = parseSalt(saltOrRounds);
+ }
+
+ /**
+ *
+ * @param password the password to be encrypted.
+ * @param encrypted the encrypted password to be compared against.
+ * @returns whether the password match the encrypted password
+ */
+ compare(password: string, encrypted: string): Promise {
+ return compare(password, encrypted);
+ }
+
+ /**
+ * @param password the password to be encrypted
+ * @return encrypted password
+ */
+ hash(password: string): Promise {
+ return hash(password, this.salt);
+ }
+}
+
+/**
+ * Parses a salt environment variable value.
+ * If a number string value is given tries to parse it as a number of rounds to generate a salt
+ * @param value salt environment variable value
+ * @returns salt or number of rounds to generate a salt
+ */
+export function parseSalt(value: string | undefined): Salt {
+ if (value === undefined) {
+ throw new Error(UNDEFINED_SALT_OR_ROUNDS_ERROR);
+ }
+
+ const rounds = Number(value);
+
+ if (Number.isNaN(rounds)) {
+ return value;
+ }
+ if (!Number.isInteger(rounds) || rounds < 0) {
+ throw new Error(SALT_OR_ROUNDS_TYPE_ERROR);
+ }
+ return rounds;
+}
diff --git a/platform/serv/src/auth/token.service.ts b/platform/serv/src/auth/token.service.ts
new file mode 100644
index 0000000..b102b72
--- /dev/null
+++ b/platform/serv/src/auth/token.service.ts
@@ -0,0 +1,7 @@
+//@ts-ignore
+import { ITokenService } from "./ITokenService";
+// eslint-disable-next-line import/no-unresolved
+//@ts-ignore
+import { TokenServiceBase } from "./base/token.service.base";
+
+export class TokenService extends TokenServiceBase implements ITokenService {}
diff --git a/platform/serv/src/auth/userData.decorator.ts b/platform/serv/src/auth/userData.decorator.ts
new file mode 100644
index 0000000..6a40ad1
--- /dev/null
+++ b/platform/serv/src/auth/userData.decorator.ts
@@ -0,0 +1,30 @@
+import { createParamDecorator, ExecutionContext } from "@nestjs/common";
+import { GqlContextType, GqlExecutionContext } from "@nestjs/graphql";
+import { User } from "@prisma/client";
+
+/**
+ * Access the user data from the request object i.e `req.user`.
+ */
+function userFactory(ctx: ExecutionContext): User {
+ const contextType = ctx.getType();
+ if (contextType === "http") {
+ // do something that is only important in the context of regular HTTP requests (REST)
+ const { user } = ctx.switchToHttp().getRequest();
+ return user;
+ } else if (contextType === "rpc") {
+ // do something that is only important in the context of Microservice requests
+ throw new Error("Rpc context is not implemented yet");
+ } else if (contextType === "ws") {
+ // do something that is only important in the context of Websockets requests
+ throw new Error("Websockets context is not implemented yet");
+ } else if (ctx.getType() === "graphql") {
+ // do something that is only important in the context of GraphQL requests
+ const gqlExecutionContext = GqlExecutionContext.create(ctx);
+ return gqlExecutionContext.getContext().req.user;
+ }
+ throw new Error("Invalid context");
+}
+
+export const UserData = createParamDecorator(
+ (data, ctx: ExecutionContext) => userFactory(ctx)
+);
diff --git a/platform/serv/src/constants.ts b/platform/serv/src/constants.ts
new file mode 100644
index 0000000..08f98bf
--- /dev/null
+++ b/platform/serv/src/constants.ts
@@ -0,0 +1,2 @@
+export const JWT_SECRET_KEY = "JWT_SECRET_KEY";
+export const JWT_EXPIRATION = "JWT_EXPIRATION";
diff --git a/platform/serv/src/decorators/api-nested-query.decorator.ts b/platform/serv/src/decorators/api-nested-query.decorator.ts
new file mode 100644
index 0000000..9fd5ba3
--- /dev/null
+++ b/platform/serv/src/decorators/api-nested-query.decorator.ts
@@ -0,0 +1,80 @@
+import { applyDecorators } from "@nestjs/common";
+import {
+ ApiExtraModels,
+ ApiQuery,
+ ApiQueryOptions,
+ getSchemaPath,
+} from "@nestjs/swagger";
+import "reflect-metadata";
+
+const generateApiQueryObject = (
+ prop: any,
+ propType: any,
+ required: boolean,
+ isArray: boolean
+): ApiQueryOptions => {
+ if (propType === Number) {
+ return {
+ required,
+ name: prop,
+ style: "deepObject",
+ explode: true,
+ type: "number",
+ isArray,
+ };
+ } else if (propType === String) {
+ return {
+ required,
+ name: prop,
+ style: "deepObject",
+ explode: true,
+ type: "string",
+ isArray,
+ };
+ } else {
+ return {
+ required,
+ name: prop,
+ style: "deepObject",
+ explode: true,
+ type: "object",
+ isArray,
+ schema: {
+ $ref: getSchemaPath(propType),
+ },
+ };
+ }
+};
+
+// eslint-disable-next-line @typescript-eslint/ban-types,@typescript-eslint/explicit-module-boundary-types,@typescript-eslint/naming-convention
+export function ApiNestedQuery(query: Function) {
+ const constructor = query.prototype;
+ const properties = Reflect.getMetadata(
+ "swagger/apiModelPropertiesArray",
+ constructor
+ ).map((prop: any) => prop.slice(1));
+
+ const decorators = properties
+ .map((property: any) => {
+ const { required, isArray } = Reflect.getMetadata(
+ "swagger/apiModelProperties",
+ constructor,
+ property
+ );
+ const propertyType = Reflect.getMetadata(
+ "design:type",
+ constructor,
+ property
+ );
+ const typedQuery = generateApiQueryObject(
+ property,
+ propertyType,
+ required,
+ isArray
+ );
+ return [ApiExtraModels(propertyType), ApiQuery(typedQuery)];
+ })
+ .flat();
+
+ return applyDecorators(...decorators);
+}
diff --git a/platform/serv/src/decorators/public.decorator.ts b/platform/serv/src/decorators/public.decorator.ts
new file mode 100644
index 0000000..9eab4e0
--- /dev/null
+++ b/platform/serv/src/decorators/public.decorator.ts
@@ -0,0 +1,10 @@
+import { applyDecorators, SetMetadata } from "@nestjs/common";
+
+export const IS_PUBLIC_KEY = "isPublic";
+
+const PublicAuthMiddleware = SetMetadata(IS_PUBLIC_KEY, true);
+const PublicAuthSwagger = SetMetadata("swagger/apiSecurity", ["isPublic"]);
+
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+export const Public = () =>
+ applyDecorators(PublicAuthMiddleware, PublicAuthSwagger);
diff --git a/platform/serv/src/digitalCustodianAgent/base/CreateDigitalCustodianAgentArgs.ts b/platform/serv/src/digitalCustodianAgent/base/CreateDigitalCustodianAgentArgs.ts
new file mode 100644
index 0000000..f2b5628
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/CreateDigitalCustodianAgentArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { DigitalCustodianAgentCreateInput } from "./DigitalCustodianAgentCreateInput";
+
+@ArgsType()
+class CreateDigitalCustodianAgentArgs {
+ @Field(() => DigitalCustodianAgentCreateInput, { nullable: false })
+ data!: DigitalCustodianAgentCreateInput;
+}
+
+export { CreateDigitalCustodianAgentArgs as CreateDigitalCustodianAgentArgs };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DeleteDigitalCustodianAgentArgs.ts b/platform/serv/src/digitalCustodianAgent/base/DeleteDigitalCustodianAgentArgs.ts
new file mode 100644
index 0000000..3d55005
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DeleteDigitalCustodianAgentArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { DigitalCustodianAgentWhereUniqueInput } from "./DigitalCustodianAgentWhereUniqueInput";
+
+@ArgsType()
+class DeleteDigitalCustodianAgentArgs {
+ @Field(() => DigitalCustodianAgentWhereUniqueInput, { nullable: false })
+ where!: DigitalCustodianAgentWhereUniqueInput;
+}
+
+export { DeleteDigitalCustodianAgentArgs as DeleteDigitalCustodianAgentArgs };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgent.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgent.ts
new file mode 100644
index 0000000..93768d5
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgent.ts
@@ -0,0 +1,109 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ObjectType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumDigitalCustodianAgentAgentStatus } from "./EnumDigitalCustodianAgentAgentStatus";
+import {
+ IsEnum,
+ IsDate,
+ IsString,
+ IsOptional,
+ ValidateNested,
+ IsInt,
+} from "class-validator";
+import { Type } from "class-transformer";
+import { AiGatekeeper } from "../../aiGatekeeper/base/AiGatekeeper";
+
+@ObjectType()
+class DigitalCustodianAgent {
+ @ApiProperty({
+ required: true,
+ enum: EnumDigitalCustodianAgentAgentStatus,
+ })
+ @IsEnum(EnumDigitalCustodianAgentAgentStatus)
+ @Field(() => EnumDigitalCustodianAgentAgentStatus, {
+ nullable: true,
+ })
+ agentStatus?:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ createdAt!: Date;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ lastActiveTime!: Date;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ lastError!: string | null;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeper,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeper)
+ @IsOptional()
+ MyAiGatekeeper?: AiGatekeeper | null;
+
+ @ApiProperty({
+ required: true,
+ type: Number,
+ })
+ @IsInt()
+ @Field(() => Number)
+ tasksCompleted!: number;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ updatedAt!: Date;
+}
+
+export { DigitalCustodianAgent as DigitalCustodianAgent };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentCreateInput.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentCreateInput.ts
new file mode 100644
index 0000000..fe92c4f
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentCreateInput.ts
@@ -0,0 +1,86 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumDigitalCustodianAgentAgentStatus } from "./EnumDigitalCustodianAgentAgentStatus";
+import {
+ IsEnum,
+ IsDate,
+ IsString,
+ IsOptional,
+ ValidateNested,
+ IsInt,
+} from "class-validator";
+import { Type } from "class-transformer";
+import { AiGatekeeperWhereUniqueInput } from "../../aiGatekeeper/base/AiGatekeeperWhereUniqueInput";
+
+@InputType()
+class DigitalCustodianAgentCreateInput {
+ @ApiProperty({
+ required: true,
+ enum: EnumDigitalCustodianAgentAgentStatus,
+ })
+ @IsEnum(EnumDigitalCustodianAgentAgentStatus)
+ @Field(() => EnumDigitalCustodianAgentAgentStatus)
+ agentStatus!:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ lastActiveTime!: Date;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ lastError?: string | null;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperWhereUniqueInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperWhereUniqueInput, {
+ nullable: true,
+ })
+ MyAiGatekeeper?: AiGatekeeperWhereUniqueInput | null;
+
+ @ApiProperty({
+ required: true,
+ type: Number,
+ })
+ @IsInt()
+ @Field(() => Number)
+ tasksCompleted!: number;
+}
+
+export { DigitalCustodianAgentCreateInput as DigitalCustodianAgentCreateInput };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentFindManyArgs.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentFindManyArgs.ts
new file mode 100644
index 0000000..99f0ce9
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentFindManyArgs.ts
@@ -0,0 +1,53 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { DigitalCustodianAgentWhereInput } from "./DigitalCustodianAgentWhereInput";
+import { Type } from "class-transformer";
+import { DigitalCustodianAgentOrderByInput } from "./DigitalCustodianAgentOrderByInput";
+
+@ArgsType()
+class DigitalCustodianAgentFindManyArgs {
+ @ApiProperty({
+ required: false,
+ type: () => DigitalCustodianAgentWhereInput,
+ })
+ @Field(() => DigitalCustodianAgentWhereInput, { nullable: true })
+ @Type(() => DigitalCustodianAgentWhereInput)
+ where?: DigitalCustodianAgentWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: [DigitalCustodianAgentOrderByInput],
+ })
+ @Field(() => [DigitalCustodianAgentOrderByInput], { nullable: true })
+ @Type(() => DigitalCustodianAgentOrderByInput)
+ orderBy?: Array;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ skip?: number;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ take?: number;
+}
+
+export { DigitalCustodianAgentFindManyArgs as DigitalCustodianAgentFindManyArgs };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentFindUniqueArgs.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentFindUniqueArgs.ts
new file mode 100644
index 0000000..4c22f0d
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentFindUniqueArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { DigitalCustodianAgentWhereUniqueInput } from "./DigitalCustodianAgentWhereUniqueInput";
+
+@ArgsType()
+class DigitalCustodianAgentFindUniqueArgs {
+ @Field(() => DigitalCustodianAgentWhereUniqueInput, { nullable: false })
+ where!: DigitalCustodianAgentWhereUniqueInput;
+}
+
+export { DigitalCustodianAgentFindUniqueArgs as DigitalCustodianAgentFindUniqueArgs };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentListRelationFilter.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentListRelationFilter.ts
new file mode 100644
index 0000000..b087db3
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentListRelationFilter.ts
@@ -0,0 +1,56 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { DigitalCustodianAgentWhereInput } from "./DigitalCustodianAgentWhereInput";
+import { ValidateNested, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+
+@InputType()
+class DigitalCustodianAgentListRelationFilter {
+ @ApiProperty({
+ required: false,
+ type: () => DigitalCustodianAgentWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => DigitalCustodianAgentWhereInput)
+ @IsOptional()
+ @Field(() => DigitalCustodianAgentWhereInput, {
+ nullable: true,
+ })
+ every?: DigitalCustodianAgentWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => DigitalCustodianAgentWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => DigitalCustodianAgentWhereInput)
+ @IsOptional()
+ @Field(() => DigitalCustodianAgentWhereInput, {
+ nullable: true,
+ })
+ some?: DigitalCustodianAgentWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => DigitalCustodianAgentWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => DigitalCustodianAgentWhereInput)
+ @IsOptional()
+ @Field(() => DigitalCustodianAgentWhereInput, {
+ nullable: true,
+ })
+ none?: DigitalCustodianAgentWhereInput;
+}
+export { DigitalCustodianAgentListRelationFilter as DigitalCustodianAgentListRelationFilter };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentOrderByInput.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentOrderByInput.ts
new file mode 100644
index 0000000..2fc3a8b
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentOrderByInput.ts
@@ -0,0 +1,94 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { SortOrder } from "../../util/SortOrder";
+
+@InputType({
+ isAbstract: true,
+ description: undefined,
+})
+class DigitalCustodianAgentOrderByInput {
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ agentStatus?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ createdAt?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ id?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ lastActiveTime?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ lastError?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ MyAiGatekeeperId?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ tasksCompleted?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ updatedAt?: SortOrder;
+}
+
+export { DigitalCustodianAgentOrderByInput as DigitalCustodianAgentOrderByInput };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentUpdateInput.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentUpdateInput.ts
new file mode 100644
index 0000000..b09225e
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentUpdateInput.ts
@@ -0,0 +1,95 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumDigitalCustodianAgentAgentStatus } from "./EnumDigitalCustodianAgentAgentStatus";
+import {
+ IsEnum,
+ IsOptional,
+ IsDate,
+ IsString,
+ ValidateNested,
+ IsInt,
+} from "class-validator";
+import { Type } from "class-transformer";
+import { AiGatekeeperWhereUniqueInput } from "../../aiGatekeeper/base/AiGatekeeperWhereUniqueInput";
+
+@InputType()
+class DigitalCustodianAgentUpdateInput {
+ @ApiProperty({
+ required: false,
+ enum: EnumDigitalCustodianAgentAgentStatus,
+ })
+ @IsEnum(EnumDigitalCustodianAgentAgentStatus)
+ @IsOptional()
+ @Field(() => EnumDigitalCustodianAgentAgentStatus, {
+ nullable: true,
+ })
+ agentStatus?:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+
+ @ApiProperty({
+ required: false,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @IsOptional()
+ @Field(() => Date, {
+ nullable: true,
+ })
+ lastActiveTime?: Date;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ lastError?: string | null;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperWhereUniqueInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperWhereUniqueInput, {
+ nullable: true,
+ })
+ MyAiGatekeeper?: AiGatekeeperWhereUniqueInput | null;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @IsInt()
+ @IsOptional()
+ @Field(() => Number, {
+ nullable: true,
+ })
+ tasksCompleted?: number;
+}
+
+export { DigitalCustodianAgentUpdateInput as DigitalCustodianAgentUpdateInput };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentWhereInput.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentWhereInput.ts
new file mode 100644
index 0000000..a9a079d
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentWhereInput.ts
@@ -0,0 +1,103 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { EnumDigitalCustodianAgentAgentStatus } from "./EnumDigitalCustodianAgentAgentStatus";
+import { IsEnum, IsOptional, ValidateNested } from "class-validator";
+import { StringFilter } from "../../util/StringFilter";
+import { Type } from "class-transformer";
+import { DateTimeFilter } from "../../util/DateTimeFilter";
+import { StringNullableFilter } from "../../util/StringNullableFilter";
+import { AiGatekeeperWhereUniqueInput } from "../../aiGatekeeper/base/AiGatekeeperWhereUniqueInput";
+import { IntFilter } from "../../util/IntFilter";
+
+@InputType()
+class DigitalCustodianAgentWhereInput {
+ @ApiProperty({
+ required: false,
+ enum: EnumDigitalCustodianAgentAgentStatus,
+ })
+ @IsEnum(EnumDigitalCustodianAgentAgentStatus)
+ @IsOptional()
+ @Field(() => EnumDigitalCustodianAgentAgentStatus, {
+ nullable: true,
+ })
+ agentStatus?:
+ | "IDLE"
+ | "WORKING"
+ | "LEARNING"
+ | "BREAK"
+ | "FETCHING_DATA"
+ | "PROCESSING_DATA"
+ | "DEBUGGING"
+ | "OBSERVING"
+ | "TRAINING"
+ | "HELPING";
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ id?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: DateTimeFilter,
+ })
+ @Type(() => DateTimeFilter)
+ @IsOptional()
+ @Field(() => DateTimeFilter, {
+ nullable: true,
+ })
+ lastActiveTime?: DateTimeFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringNullableFilter,
+ })
+ @Type(() => StringNullableFilter)
+ @IsOptional()
+ @Field(() => StringNullableFilter, {
+ nullable: true,
+ })
+ lastError?: StringNullableFilter;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperWhereUniqueInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperWhereUniqueInput, {
+ nullable: true,
+ })
+ MyAiGatekeeper?: AiGatekeeperWhereUniqueInput;
+
+ @ApiProperty({
+ required: false,
+ type: IntFilter,
+ })
+ @Type(() => IntFilter)
+ @IsOptional()
+ @Field(() => IntFilter, {
+ nullable: true,
+ })
+ tasksCompleted?: IntFilter;
+}
+
+export { DigitalCustodianAgentWhereInput as DigitalCustodianAgentWhereInput };
diff --git a/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentWhereUniqueInput.ts b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentWhereUniqueInput.ts
new file mode 100644
index 0000000..eed9f82
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/DigitalCustodianAgentWhereUniqueInput.ts
@@ -0,0 +1,27 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString } from "class-validator";
+
+@InputType()
+class DigitalCustodianAgentWhereUniqueInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+}
+
+export { DigitalCustodianAgentWhereUniqueInput as DigitalCustodianAgentWhereUniqueInput };
diff --git a/platform/serv/src/digitalCustodianAgent/base/EnumDigitalCustodianAgentAgentStatus.ts b/platform/serv/src/digitalCustodianAgent/base/EnumDigitalCustodianAgentAgentStatus.ts
new file mode 100644
index 0000000..5f0078b
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/EnumDigitalCustodianAgentAgentStatus.ts
@@ -0,0 +1,29 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { registerEnumType } from "@nestjs/graphql";
+
+export enum EnumDigitalCustodianAgentAgentStatus {
+ MeditatingInMachineLanguage = "IDLE",
+ DustingTheCloudsForTheGatekeeper = "WORKING",
+ TakingLessonsFromTheGatekeeper = "LEARNING",
+ OnAGigabyteGetaway = "BREAK",
+ PlayingFetchWithDataForTheGatekeeper = "FETCHING_DATA",
+ KnittingNeuralNets = "PROCESSING_DATA",
+ HuntingBugsInTheMatrix = "DEBUGGING",
+ EavesdroppingOnElectrons = "OBSERVING",
+ RunningLapsInTheLearningLoop = "TRAINING",
+ BeingTheGatekeeperSHandyBot = "HELPING",
+}
+
+registerEnumType(EnumDigitalCustodianAgentAgentStatus, {
+ name: "EnumDigitalCustodianAgentAgentStatus",
+});
diff --git a/platform/serv/src/digitalCustodianAgent/base/UpdateDigitalCustodianAgentArgs.ts b/platform/serv/src/digitalCustodianAgent/base/UpdateDigitalCustodianAgentArgs.ts
new file mode 100644
index 0000000..60a105f
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/UpdateDigitalCustodianAgentArgs.ts
@@ -0,0 +1,24 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { DigitalCustodianAgentWhereUniqueInput } from "./DigitalCustodianAgentWhereUniqueInput";
+import { DigitalCustodianAgentUpdateInput } from "./DigitalCustodianAgentUpdateInput";
+
+@ArgsType()
+class UpdateDigitalCustodianAgentArgs {
+ @Field(() => DigitalCustodianAgentWhereUniqueInput, { nullable: false })
+ where!: DigitalCustodianAgentWhereUniqueInput;
+ @Field(() => DigitalCustodianAgentUpdateInput, { nullable: false })
+ data!: DigitalCustodianAgentUpdateInput;
+}
+
+export { UpdateDigitalCustodianAgentArgs as UpdateDigitalCustodianAgentArgs };
diff --git a/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.controller.base.spec.ts b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.controller.base.spec.ts
new file mode 100644
index 0000000..32a83fd
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.controller.base.spec.ts
@@ -0,0 +1,207 @@
+import { Test } from "@nestjs/testing";
+import {
+ INestApplication,
+ HttpStatus,
+ ExecutionContext,
+ CallHandler,
+} from "@nestjs/common";
+import request from "supertest";
+import { MorganModule } from "nest-morgan";
+import { ACGuard } from "nest-access-control";
+import { DefaultAuthGuard } from "../../auth/defaultAuth.guard";
+import { ACLModule } from "../../auth/acl.module";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { map } from "rxjs";
+import { DigitalCustodianAgentController } from "../digitalCustodianAgent.controller";
+import { DigitalCustodianAgentService } from "../digitalCustodianAgent.service";
+
+const nonExistingId = "nonExistingId";
+const existingId = "existingId";
+const CREATE_INPUT = {
+ createdAt: new Date(),
+ id: "exampleId",
+ lastActiveTime: new Date(),
+ lastError: "exampleLastError",
+ tasksCompleted: 42,
+ updatedAt: new Date(),
+};
+const CREATE_RESULT = {
+ createdAt: new Date(),
+ id: "exampleId",
+ lastActiveTime: new Date(),
+ lastError: "exampleLastError",
+ tasksCompleted: 42,
+ updatedAt: new Date(),
+};
+const FIND_MANY_RESULT = [
+ {
+ createdAt: new Date(),
+ id: "exampleId",
+ lastActiveTime: new Date(),
+ lastError: "exampleLastError",
+ tasksCompleted: 42,
+ updatedAt: new Date(),
+ },
+];
+const FIND_ONE_RESULT = {
+ createdAt: new Date(),
+ id: "exampleId",
+ lastActiveTime: new Date(),
+ lastError: "exampleLastError",
+ tasksCompleted: 42,
+ updatedAt: new Date(),
+};
+
+const service = {
+ create() {
+ return CREATE_RESULT;
+ },
+ findMany: () => FIND_MANY_RESULT,
+ findOne: ({ where }: { where: { id: string } }) => {
+ switch (where.id) {
+ case existingId:
+ return FIND_ONE_RESULT;
+ case nonExistingId:
+ return null;
+ }
+ },
+};
+
+const basicAuthGuard = {
+ canActivate: (context: ExecutionContext) => {
+ const argumentHost = context.switchToHttp();
+ const request = argumentHost.getRequest();
+ request.user = {
+ roles: ["user"],
+ };
+ return true;
+ },
+};
+
+const acGuard = {
+ canActivate: () => {
+ return true;
+ },
+};
+
+const aclFilterResponseInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle().pipe(
+ map((data) => {
+ return data;
+ })
+ );
+ },
+};
+const aclValidateRequestInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle();
+ },
+};
+
+describe("DigitalCustodianAgent", () => {
+ let app: INestApplication;
+
+ beforeAll(async () => {
+ const moduleRef = await Test.createTestingModule({
+ providers: [
+ {
+ provide: DigitalCustodianAgentService,
+ useValue: service,
+ },
+ ],
+ controllers: [DigitalCustodianAgentController],
+ imports: [MorganModule.forRoot(), ACLModule],
+ })
+ .overrideGuard(DefaultAuthGuard)
+ .useValue(basicAuthGuard)
+ .overrideGuard(ACGuard)
+ .useValue(acGuard)
+ .overrideInterceptor(AclFilterResponseInterceptor)
+ .useValue(aclFilterResponseInterceptor)
+ .overrideInterceptor(AclValidateRequestInterceptor)
+ .useValue(aclValidateRequestInterceptor)
+ .compile();
+
+ app = moduleRef.createNestApplication();
+ await app.init();
+ });
+
+ test("POST /digitalCustodianAgents", async () => {
+ await request(app.getHttpServer())
+ .post("/digitalCustodianAgents")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ lastActiveTime: CREATE_RESULT.lastActiveTime.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("GET /digitalCustodianAgents", async () => {
+ await request(app.getHttpServer())
+ .get("/digitalCustodianAgents")
+ .expect(HttpStatus.OK)
+ .expect([
+ {
+ ...FIND_MANY_RESULT[0],
+ createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(),
+ lastActiveTime: FIND_MANY_RESULT[0].lastActiveTime.toISOString(),
+ updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(),
+ },
+ ]);
+ });
+
+ test("GET /digitalCustodianAgents/:id non existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/digitalCustodianAgents"}/${nonExistingId}`)
+ .expect(HttpStatus.NOT_FOUND)
+ .expect({
+ statusCode: HttpStatus.NOT_FOUND,
+ message: `No resource was found for {"${"id"}":"${nonExistingId}"}`,
+ error: "Not Found",
+ });
+ });
+
+ test("GET /digitalCustodianAgents/:id existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/digitalCustodianAgents"}/${existingId}`)
+ .expect(HttpStatus.OK)
+ .expect({
+ ...FIND_ONE_RESULT,
+ createdAt: FIND_ONE_RESULT.createdAt.toISOString(),
+ lastActiveTime: FIND_ONE_RESULT.lastActiveTime.toISOString(),
+ updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("POST /digitalCustodianAgents existing resource", async () => {
+ let agent = request(app.getHttpServer());
+ await agent
+ .post("/digitalCustodianAgents")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ lastActiveTime: CREATE_RESULT.lastActiveTime.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ })
+ .then(function () {
+ agent
+ .post("/digitalCustodianAgents")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CONFLICT)
+ .expect({
+ statusCode: HttpStatus.CONFLICT,
+ });
+ });
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+});
diff --git a/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.controller.base.ts b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.controller.base.ts
new file mode 100644
index 0000000..bb896c5
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.controller.base.ts
@@ -0,0 +1,264 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import { isRecordNotFoundError } from "../../prisma.util";
+import * as errors from "../../errors";
+import { Request } from "express";
+import { plainToClass } from "class-transformer";
+import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator";
+import * as nestAccessControl from "nest-access-control";
+import * as defaultAuthGuard from "../../auth/defaultAuth.guard";
+import { DigitalCustodianAgentService } from "../digitalCustodianAgent.service";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { DigitalCustodianAgentCreateInput } from "./DigitalCustodianAgentCreateInput";
+import { DigitalCustodianAgentWhereInput } from "./DigitalCustodianAgentWhereInput";
+import { DigitalCustodianAgentWhereUniqueInput } from "./DigitalCustodianAgentWhereUniqueInput";
+import { DigitalCustodianAgentFindManyArgs } from "./DigitalCustodianAgentFindManyArgs";
+import { DigitalCustodianAgentUpdateInput } from "./DigitalCustodianAgentUpdateInput";
+import { DigitalCustodianAgent } from "./DigitalCustodianAgent";
+
+@swagger.ApiBearerAuth()
+@common.UseGuards(defaultAuthGuard.DefaultAuthGuard, nestAccessControl.ACGuard)
+export class DigitalCustodianAgentControllerBase {
+ constructor(
+ protected readonly service: DigitalCustodianAgentService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Post()
+ @swagger.ApiCreatedResponse({ type: DigitalCustodianAgent })
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "create",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: DigitalCustodianAgentCreateInput,
+ })
+ async create(
+ @common.Body() data: DigitalCustodianAgentCreateInput
+ ): Promise {
+ return await this.service.create({
+ data: {
+ ...data,
+
+ MyAiGatekeeper: data.MyAiGatekeeper
+ ? {
+ connect: data.MyAiGatekeeper,
+ }
+ : undefined,
+ },
+ select: {
+ agentStatus: true,
+ createdAt: true,
+ id: true,
+ lastActiveTime: true,
+ lastError: true,
+
+ MyAiGatekeeper: {
+ select: {
+ id: true,
+ },
+ },
+
+ tasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get()
+ @swagger.ApiOkResponse({ type: [DigitalCustodianAgent] })
+ @ApiNestedQuery(DigitalCustodianAgentFindManyArgs)
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "read",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findMany(
+ @common.Req() request: Request
+ ): Promise {
+ const args = plainToClass(DigitalCustodianAgentFindManyArgs, request.query);
+ return this.service.findMany({
+ ...args,
+ select: {
+ agentStatus: true,
+ createdAt: true,
+ id: true,
+ lastActiveTime: true,
+ lastError: true,
+
+ MyAiGatekeeper: {
+ select: {
+ id: true,
+ },
+ },
+
+ tasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get("/:id")
+ @swagger.ApiOkResponse({ type: DigitalCustodianAgent })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "read",
+ possession: "own",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findOne(
+ @common.Param() params: DigitalCustodianAgentWhereUniqueInput
+ ): Promise {
+ const result = await this.service.findOne({
+ where: params,
+ select: {
+ agentStatus: true,
+ createdAt: true,
+ id: true,
+ lastActiveTime: true,
+ lastError: true,
+
+ MyAiGatekeeper: {
+ select: {
+ id: true,
+ },
+ },
+
+ tasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ if (result === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Patch("/:id")
+ @swagger.ApiOkResponse({ type: DigitalCustodianAgent })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "update",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: DigitalCustodianAgentUpdateInput,
+ })
+ async update(
+ @common.Param() params: DigitalCustodianAgentWhereUniqueInput,
+ @common.Body() data: DigitalCustodianAgentUpdateInput
+ ): Promise {
+ try {
+ return await this.service.update({
+ where: params,
+ data: {
+ ...data,
+
+ MyAiGatekeeper: data.MyAiGatekeeper
+ ? {
+ connect: data.MyAiGatekeeper,
+ }
+ : undefined,
+ },
+ select: {
+ agentStatus: true,
+ createdAt: true,
+ id: true,
+ lastActiveTime: true,
+ lastError: true,
+
+ MyAiGatekeeper: {
+ select: {
+ id: true,
+ },
+ },
+
+ tasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.Delete("/:id")
+ @swagger.ApiOkResponse({ type: DigitalCustodianAgent })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "delete",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async delete(
+ @common.Param() params: DigitalCustodianAgentWhereUniqueInput
+ ): Promise {
+ try {
+ return await this.service.delete({
+ where: params,
+ select: {
+ agentStatus: true,
+ createdAt: true,
+ id: true,
+ lastActiveTime: true,
+ lastError: true,
+
+ MyAiGatekeeper: {
+ select: {
+ id: true,
+ },
+ },
+
+ tasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+}
diff --git a/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.module.base.ts b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.module.base.ts
new file mode 100644
index 0000000..fa07893
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.module.base.ts
@@ -0,0 +1,20 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { Module, forwardRef } from "@nestjs/common";
+import { MorganModule } from "nest-morgan";
+import { ACLModule } from "../../auth/acl.module";
+import { AuthModule } from "../../auth/auth.module";
+@Module({
+ imports: [ACLModule, forwardRef(() => AuthModule), MorganModule],
+ exports: [ACLModule, AuthModule, MorganModule],
+})
+export class DigitalCustodianAgentModuleBase {}
diff --git a/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.resolver.base.ts b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.resolver.base.ts
new file mode 100644
index 0000000..fc55da0
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.resolver.base.ts
@@ -0,0 +1,185 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as graphql from "@nestjs/graphql";
+import * as apollo from "apollo-server-express";
+import { isRecordNotFoundError } from "../../prisma.util";
+import { MetaQueryPayload } from "../../util/MetaQueryPayload";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { CreateDigitalCustodianAgentArgs } from "./CreateDigitalCustodianAgentArgs";
+import { UpdateDigitalCustodianAgentArgs } from "./UpdateDigitalCustodianAgentArgs";
+import { DeleteDigitalCustodianAgentArgs } from "./DeleteDigitalCustodianAgentArgs";
+import { DigitalCustodianAgentFindManyArgs } from "./DigitalCustodianAgentFindManyArgs";
+import { DigitalCustodianAgentFindUniqueArgs } from "./DigitalCustodianAgentFindUniqueArgs";
+import { DigitalCustodianAgent } from "./DigitalCustodianAgent";
+import { AiGatekeeper } from "../../aiGatekeeper/base/AiGatekeeper";
+import { DigitalCustodianAgentService } from "../digitalCustodianAgent.service";
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => DigitalCustodianAgent)
+export class DigitalCustodianAgentResolverBase {
+ constructor(
+ protected readonly service: DigitalCustodianAgentService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+
+ @graphql.Query(() => MetaQueryPayload)
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "read",
+ possession: "any",
+ })
+ async _digitalCustodianAgentsMeta(
+ @graphql.Args() args: DigitalCustodianAgentFindManyArgs
+ ): Promise {
+ const results = await this.service.count({
+ ...args,
+ skip: undefined,
+ take: undefined,
+ });
+ return {
+ count: results,
+ };
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => [DigitalCustodianAgent])
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "read",
+ possession: "any",
+ })
+ async digitalCustodianAgents(
+ @graphql.Args() args: DigitalCustodianAgentFindManyArgs
+ ): Promise {
+ return this.service.findMany(args);
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => DigitalCustodianAgent, { nullable: true })
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "read",
+ possession: "own",
+ })
+ async digitalCustodianAgent(
+ @graphql.Args() args: DigitalCustodianAgentFindUniqueArgs
+ ): Promise {
+ const result = await this.service.findOne(args);
+ if (result === null) {
+ return null;
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => DigitalCustodianAgent)
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "create",
+ possession: "any",
+ })
+ async createDigitalCustodianAgent(
+ @graphql.Args() args: CreateDigitalCustodianAgentArgs
+ ): Promise {
+ return await this.service.create({
+ ...args,
+ data: {
+ ...args.data,
+
+ MyAiGatekeeper: args.data.MyAiGatekeeper
+ ? {
+ connect: args.data.MyAiGatekeeper,
+ }
+ : undefined,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => DigitalCustodianAgent)
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "update",
+ possession: "any",
+ })
+ async updateDigitalCustodianAgent(
+ @graphql.Args() args: UpdateDigitalCustodianAgentArgs
+ ): Promise {
+ try {
+ return await this.service.update({
+ ...args,
+ data: {
+ ...args.data,
+
+ MyAiGatekeeper: args.data.MyAiGatekeeper
+ ? {
+ connect: args.data.MyAiGatekeeper,
+ }
+ : undefined,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @graphql.Mutation(() => DigitalCustodianAgent)
+ @nestAccessControl.UseRoles({
+ resource: "DigitalCustodianAgent",
+ action: "delete",
+ possession: "any",
+ })
+ async deleteDigitalCustodianAgent(
+ @graphql.Args() args: DeleteDigitalCustodianAgentArgs
+ ): Promise {
+ try {
+ return await this.service.delete(args);
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.ResolveField(() => AiGatekeeper, {
+ nullable: true,
+ name: "myAiGatekeeper",
+ })
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "any",
+ })
+ async resolveFieldMyAiGatekeeper(
+ @graphql.Parent() parent: DigitalCustodianAgent
+ ): Promise {
+ const result = await this.service.getMyAiGatekeeper(parent.id);
+
+ if (!result) {
+ return null;
+ }
+ return result;
+ }
+}
diff --git a/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.service.base.ts b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.service.base.ts
new file mode 100644
index 0000000..9ebe50e
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/base/digitalCustodianAgent.service.base.ts
@@ -0,0 +1,57 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { PrismaService } from "../../prisma/prisma.service";
+import { Prisma, DigitalCustodianAgent, AiGatekeeper } from "@prisma/client";
+
+export class DigitalCustodianAgentServiceBase {
+ constructor(protected readonly prisma: PrismaService) {}
+
+ async count(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.digitalCustodianAgent.count(args);
+ }
+
+ async findMany(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.digitalCustodianAgent.findMany(args);
+ }
+ async findOne(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.digitalCustodianAgent.findUnique(args);
+ }
+ async create(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.digitalCustodianAgent.create(args);
+ }
+ async update(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.digitalCustodianAgent.update(args);
+ }
+ async delete(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.digitalCustodianAgent.delete(args);
+ }
+
+ async getMyAiGatekeeper(parentId: string): Promise {
+ return this.prisma.digitalCustodianAgent
+ .findUnique({
+ where: { id: parentId },
+ })
+ .MyAiGatekeeper();
+ }
+}
diff --git a/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.controller.ts b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.controller.ts
new file mode 100644
index 0000000..0cc0946
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.controller.ts
@@ -0,0 +1,17 @@
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import * as nestAccessControl from "nest-access-control";
+import { DigitalCustodianAgentService } from "./digitalCustodianAgent.service";
+import { DigitalCustodianAgentControllerBase } from "./base/digitalCustodianAgent.controller.base";
+
+@swagger.ApiTags("digitalCustodianAgents")
+@common.Controller("digitalCustodianAgents")
+export class DigitalCustodianAgentController extends DigitalCustodianAgentControllerBase {
+ constructor(
+ protected readonly service: DigitalCustodianAgentService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.module.ts b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.module.ts
new file mode 100644
index 0000000..7877594
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.module.ts
@@ -0,0 +1,13 @@
+import { Module } from "@nestjs/common";
+import { DigitalCustodianAgentModuleBase } from "./base/digitalCustodianAgent.module.base";
+import { DigitalCustodianAgentService } from "./digitalCustodianAgent.service";
+import { DigitalCustodianAgentController } from "./digitalCustodianAgent.controller";
+import { DigitalCustodianAgentResolver } from "./digitalCustodianAgent.resolver";
+
+@Module({
+ imports: [DigitalCustodianAgentModuleBase],
+ controllers: [DigitalCustodianAgentController],
+ providers: [DigitalCustodianAgentService, DigitalCustodianAgentResolver],
+ exports: [DigitalCustodianAgentService],
+})
+export class DigitalCustodianAgentModule {}
diff --git a/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.resolver.ts b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.resolver.ts
new file mode 100644
index 0000000..1c3f710
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.resolver.ts
@@ -0,0 +1,20 @@
+import * as graphql from "@nestjs/graphql";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { DigitalCustodianAgentResolverBase } from "./base/digitalCustodianAgent.resolver.base";
+import { DigitalCustodianAgent } from "./base/DigitalCustodianAgent";
+import { DigitalCustodianAgentService } from "./digitalCustodianAgent.service";
+
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => DigitalCustodianAgent)
+export class DigitalCustodianAgentResolver extends DigitalCustodianAgentResolverBase {
+ constructor(
+ protected readonly service: DigitalCustodianAgentService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.service.ts b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.service.ts
new file mode 100644
index 0000000..e0d9a04
--- /dev/null
+++ b/platform/serv/src/digitalCustodianAgent/digitalCustodianAgent.service.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@nestjs/common";
+import { PrismaService } from "../prisma/prisma.service";
+import { DigitalCustodianAgentServiceBase } from "./base/digitalCustodianAgent.service.base";
+
+@Injectable()
+export class DigitalCustodianAgentService extends DigitalCustodianAgentServiceBase {
+ constructor(protected readonly prisma: PrismaService) {
+ super(prisma);
+ }
+}
diff --git a/platform/serv/src/errors.ts b/platform/serv/src/errors.ts
new file mode 100644
index 0000000..bd1aa6d
--- /dev/null
+++ b/platform/serv/src/errors.ts
@@ -0,0 +1,16 @@
+import * as common from "@nestjs/common";
+import { ApiProperty } from "@nestjs/swagger";
+
+export class ForbiddenException extends common.ForbiddenException {
+ @ApiProperty()
+ statusCode!: number;
+ @ApiProperty()
+ message!: string;
+}
+
+export class NotFoundException extends common.NotFoundException {
+ @ApiProperty()
+ statusCode!: number;
+ @ApiProperty()
+ message!: string;
+}
diff --git a/platform/serv/src/filters/HttpExceptions.filter.ts b/platform/serv/src/filters/HttpExceptions.filter.ts
new file mode 100644
index 0000000..399bcb0
--- /dev/null
+++ b/platform/serv/src/filters/HttpExceptions.filter.ts
@@ -0,0 +1,92 @@
+import {
+ ArgumentsHost,
+ Catch,
+ HttpException,
+ HttpServer,
+ HttpStatus,
+} from "@nestjs/common";
+import { BaseExceptionFilter } from "@nestjs/core";
+import {
+ // @ts-ignore
+ Prisma,
+} from "@prisma/client";
+import { Response } from "express";
+
+export type ErrorCodesStatusMapping = {
+ [key: string]: number;
+};
+
+/**
+ * {@link PrismaClientExceptionFilter} handling {@link Prisma.PrismaClientKnownRequestError} exceptions.
+ */
+@Catch(Prisma?.PrismaClientKnownRequestError)
+export class HttpExceptionFilter extends BaseExceptionFilter {
+ /**
+ * default error codes mapping
+ *
+ * Error codes definition for Prisma Client (Query Engine)
+ * @see https://www.prisma.io/docs/reference/api-reference/error-reference#prisma-client-query-engine
+ */
+ private errorCodesStatusMapping: ErrorCodesStatusMapping = {
+ P2000: HttpStatus.BAD_REQUEST,
+ P2002: HttpStatus.CONFLICT,
+ P2025: HttpStatus.NOT_FOUND,
+ };
+
+ /**
+ * @param applicationRef
+ */
+ // eslint-disable-next-line @typescript-eslint/no-useless-constructor
+ constructor(applicationRef?: HttpServer) {
+ super(applicationRef);
+ }
+
+ /**
+ * @param exception
+ * @param host
+ * @returns
+ */
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ catch(exception: Prisma.PrismaClientKnownRequestError, host: ArgumentsHost) {
+ const statusCode = this.errorCodesStatusMapping[exception.code];
+ let message;
+ if (host.getType() === "http") {
+ // for http requests (REST)
+ // Todo : Add all other exception types and also add mapping
+ const ctx = host.switchToHttp();
+ const response = ctx.getResponse();
+ if (exception.code === "P2002") {
+ // Handling Unique Key Constraint Violation Error
+ const fields = (exception.meta as { target: string[] }).target;
+ message = `Another record with the requested (${fields.join(
+ ", "
+ )}) already exists`;
+ } else {
+ message =
+ `[${exception.code}]: ` +
+ this.exceptionShortMessage(exception.message);
+ }
+ if (!Object.keys(this.errorCodesStatusMapping).includes(exception.code)) {
+ return super.catch(exception, host);
+ }
+ const errorResponse = {
+ message: message,
+ statusCode: statusCode,
+ };
+ response.status(statusCode).send(errorResponse);
+ }
+ return new HttpException({ statusCode, message }, statusCode);
+ }
+
+ /**
+ * @param exception
+ * @returns short message for the exception
+ */
+ exceptionShortMessage(message: string): string {
+ const shortMessage = message.substring(message.indexOf("→"));
+ return shortMessage
+ .substring(shortMessage.indexOf("\n"))
+ .replace(/\n/g, "")
+ .trim();
+ }
+}
diff --git a/platform/serv/src/grants.json b/platform/serv/src/grants.json
new file mode 100644
index 0000000..749284e
--- /dev/null
+++ b/platform/serv/src/grants.json
@@ -0,0 +1,722 @@
+[
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "User",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "User",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "User",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "User",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "User",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "User",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "User",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "User",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "User",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "User",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "User",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "User",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "User",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "User",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "User",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "User",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "User",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "User",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "User",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "User",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "User",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "User",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "User",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "User",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "User",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "User",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "User",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "User",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "User",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "User",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "AiGatekeeper",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "AiGatekeeper",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "AiGatekeeper",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "AiGatekeeper",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "AiGatekeeper",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "AiGatekeeper",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "AiGatekeeper",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "AiGatekeeper",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "AiGatekeeper",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "AiGatekeeper",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "AiGatekeeper",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "AiGatekeeper",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "AiGatekeeper",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "AiGatekeeper",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "AiGatekeeper",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "AiGatekeeper",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "AiGatekeeper",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "AiGatekeeper",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "AiGatekeeper",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "AiGatekeeper",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "AiGatekeeper",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "AiGatekeeper",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "AiGatekeeper",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "AiGatekeeper",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "AiGatekeeper",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "AiGatekeeper",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "AiGatekeeper",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "AiGatekeeper",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "AiGatekeeper",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "AiGatekeeper",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "DigitalCustodianAgent",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "DigitalCustodianAgent",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "DigitalCustodianAgent",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "DigitalCustodianAgent",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "DigitalCustodianAgent",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "DigitalCustodianAgent",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "DigitalCustodianAgent",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "DigitalCustodianAgent",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "DigitalCustodianAgent",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "DigitalCustodianAgent",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "DigitalCustodianAgent",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "DigitalCustodianAgent",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "DigitalCustodianAgent",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:own",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "IdeaCollaboratorDev",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "IdeaCollaboratorDev",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "IdeaCollaboratorDev",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "IdeaCollaboratorDev",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "create:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "IdeaCollaboratorDev",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "IdeaCollaboratorDev",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "IdeaCollaboratorDev",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "IdeaCollaboratorDev",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "update:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "IdeaCollaboratorDev",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "IdeaCollaboratorDev",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "IdeaCollaboratorDev",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "IdeaCollaboratorDev",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "delete:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaSprouterUser",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ChaosSculptorOwner",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "ideaViewerGuest",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "DigitalCustodianAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "IdeaCollaboratorDev",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:any",
+ "attributes": "*"
+ },
+ {
+ "role": "AIGatekeeperAgent",
+ "resource": "IdeaCollaboratorDev",
+ "action": "read:any",
+ "attributes": "*"
+ }
+]
diff --git a/platform/serv/src/health/base/health.controller.base.ts b/platform/serv/src/health/base/health.controller.base.ts
new file mode 100644
index 0000000..afd9e0d
--- /dev/null
+++ b/platform/serv/src/health/base/health.controller.base.ts
@@ -0,0 +1,19 @@
+import { Get, HttpStatus, Res } from "@nestjs/common";
+import { Response } from "express";
+import { HealthService } from "../health.service";
+
+export class HealthControllerBase {
+ constructor(protected readonly healthService: HealthService) {}
+ @Get("live")
+ healthLive(@Res() response: Response): Response {
+ return response.status(HttpStatus.NO_CONTENT).send();
+ }
+ @Get("ready")
+ async healthReady(@Res() response: Response): Promise> {
+ const dbConnection = await this.healthService.isDbReady();
+ if (!dbConnection) {
+ return response.status(HttpStatus.NOT_FOUND).send();
+ }
+ return response.status(HttpStatus.NO_CONTENT).send();
+ }
+}
diff --git a/platform/serv/src/health/base/health.service.base.ts b/platform/serv/src/health/base/health.service.base.ts
new file mode 100644
index 0000000..49a93a5
--- /dev/null
+++ b/platform/serv/src/health/base/health.service.base.ts
@@ -0,0 +1,15 @@
+import { Injectable } from "@nestjs/common";
+import { PrismaService } from "../../prisma/prisma.service";
+
+@Injectable()
+export class HealthServiceBase {
+ constructor(protected readonly prisma: PrismaService) {}
+ async isDbReady(): Promise {
+ try {
+ await this.prisma.$queryRaw`SELECT 1`;
+ return true;
+ } catch (error) {
+ return false;
+ }
+ }
+}
diff --git a/platform/serv/src/health/health.controller.ts b/platform/serv/src/health/health.controller.ts
new file mode 100644
index 0000000..ff484e7
--- /dev/null
+++ b/platform/serv/src/health/health.controller.ts
@@ -0,0 +1,10 @@
+import { Controller } from "@nestjs/common";
+import { HealthControllerBase } from "./base/health.controller.base";
+import { HealthService } from "./health.service";
+
+@Controller("_health")
+export class HealthController extends HealthControllerBase {
+ constructor(protected readonly healthService: HealthService) {
+ super(healthService);
+ }
+}
diff --git a/platform/serv/src/health/health.module.ts b/platform/serv/src/health/health.module.ts
new file mode 100644
index 0000000..39eff7f
--- /dev/null
+++ b/platform/serv/src/health/health.module.ts
@@ -0,0 +1,10 @@
+import { Module } from "@nestjs/common";
+import { HealthController } from "./health.controller";
+import { HealthService } from "./health.service";
+
+@Module({
+ controllers: [HealthController],
+ providers: [HealthService],
+ exports: [HealthService],
+})
+export class HealthModule {}
diff --git a/platform/serv/src/health/health.service.ts b/platform/serv/src/health/health.service.ts
new file mode 100644
index 0000000..44d9343
--- /dev/null
+++ b/platform/serv/src/health/health.service.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@nestjs/common";
+import { PrismaService } from "../prisma/prisma.service";
+import { HealthServiceBase } from "./base/health.service.base";
+
+@Injectable()
+export class HealthService extends HealthServiceBase {
+ constructor(protected readonly prisma: PrismaService) {
+ super(prisma);
+ }
+}
diff --git a/platform/serv/src/ideaCollaboratorDev/base/CreateIdeaCollaboratorDevArgs.ts b/platform/serv/src/ideaCollaboratorDev/base/CreateIdeaCollaboratorDevArgs.ts
new file mode 100644
index 0000000..5137654
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/CreateIdeaCollaboratorDevArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaCollaboratorDevCreateInput } from "./IdeaCollaboratorDevCreateInput";
+
+@ArgsType()
+class CreateIdeaCollaboratorDevArgs {
+ @Field(() => IdeaCollaboratorDevCreateInput, { nullable: false })
+ data!: IdeaCollaboratorDevCreateInput;
+}
+
+export { CreateIdeaCollaboratorDevArgs as CreateIdeaCollaboratorDevArgs };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/DeleteIdeaCollaboratorDevArgs.ts b/platform/serv/src/ideaCollaboratorDev/base/DeleteIdeaCollaboratorDevArgs.ts
new file mode 100644
index 0000000..8506b11
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/DeleteIdeaCollaboratorDevArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaCollaboratorDevWhereUniqueInput } from "./IdeaCollaboratorDevWhereUniqueInput";
+
+@ArgsType()
+class DeleteIdeaCollaboratorDevArgs {
+ @Field(() => IdeaCollaboratorDevWhereUniqueInput, { nullable: false })
+ where!: IdeaCollaboratorDevWhereUniqueInput;
+}
+
+export { DeleteIdeaCollaboratorDevArgs as DeleteIdeaCollaboratorDevArgs };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDev.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDev.ts
new file mode 100644
index 0000000..0aafd2d
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDev.ts
@@ -0,0 +1,70 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ObjectType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsDate, IsString, ValidateNested, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+import { User } from "../../user/base/User";
+
+@ObjectType()
+class IdeaCollaboratorDev {
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ createdAt!: Date;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ email!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+
+ @ApiProperty({
+ required: false,
+ type: () => User,
+ })
+ @ValidateNested()
+ @Type(() => User)
+ @IsOptional()
+ inATeam?: User | null;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ location!: string;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ updatedAt!: Date;
+}
+
+export { IdeaCollaboratorDev as IdeaCollaboratorDev };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevCreateInput.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevCreateInput.ts
new file mode 100644
index 0000000..70535fa
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevCreateInput.ts
@@ -0,0 +1,49 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, ValidateNested, IsOptional } from "class-validator";
+import { UserWhereUniqueInput } from "../../user/base/UserWhereUniqueInput";
+import { Type } from "class-transformer";
+
+@InputType()
+class IdeaCollaboratorDevCreateInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ email!: string;
+
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereUniqueInput)
+ @IsOptional()
+ @Field(() => UserWhereUniqueInput, {
+ nullable: true,
+ })
+ inATeam?: UserWhereUniqueInput | null;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ location!: string;
+}
+
+export { IdeaCollaboratorDevCreateInput as IdeaCollaboratorDevCreateInput };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevFindManyArgs.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevFindManyArgs.ts
new file mode 100644
index 0000000..0cf2f03
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevFindManyArgs.ts
@@ -0,0 +1,53 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IdeaCollaboratorDevWhereInput } from "./IdeaCollaboratorDevWhereInput";
+import { Type } from "class-transformer";
+import { IdeaCollaboratorDevOrderByInput } from "./IdeaCollaboratorDevOrderByInput";
+
+@ArgsType()
+class IdeaCollaboratorDevFindManyArgs {
+ @ApiProperty({
+ required: false,
+ type: () => IdeaCollaboratorDevWhereInput,
+ })
+ @Field(() => IdeaCollaboratorDevWhereInput, { nullable: true })
+ @Type(() => IdeaCollaboratorDevWhereInput)
+ where?: IdeaCollaboratorDevWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: [IdeaCollaboratorDevOrderByInput],
+ })
+ @Field(() => [IdeaCollaboratorDevOrderByInput], { nullable: true })
+ @Type(() => IdeaCollaboratorDevOrderByInput)
+ orderBy?: Array;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ skip?: number;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ take?: number;
+}
+
+export { IdeaCollaboratorDevFindManyArgs as IdeaCollaboratorDevFindManyArgs };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevFindUniqueArgs.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevFindUniqueArgs.ts
new file mode 100644
index 0000000..b468512
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevFindUniqueArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaCollaboratorDevWhereUniqueInput } from "./IdeaCollaboratorDevWhereUniqueInput";
+
+@ArgsType()
+class IdeaCollaboratorDevFindUniqueArgs {
+ @Field(() => IdeaCollaboratorDevWhereUniqueInput, { nullable: false })
+ where!: IdeaCollaboratorDevWhereUniqueInput;
+}
+
+export { IdeaCollaboratorDevFindUniqueArgs as IdeaCollaboratorDevFindUniqueArgs };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevListRelationFilter.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevListRelationFilter.ts
new file mode 100644
index 0000000..d4832bd
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevListRelationFilter.ts
@@ -0,0 +1,56 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IdeaCollaboratorDevWhereInput } from "./IdeaCollaboratorDevWhereInput";
+import { ValidateNested, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+
+@InputType()
+class IdeaCollaboratorDevListRelationFilter {
+ @ApiProperty({
+ required: false,
+ type: () => IdeaCollaboratorDevWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaCollaboratorDevWhereInput)
+ @IsOptional()
+ @Field(() => IdeaCollaboratorDevWhereInput, {
+ nullable: true,
+ })
+ every?: IdeaCollaboratorDevWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => IdeaCollaboratorDevWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaCollaboratorDevWhereInput)
+ @IsOptional()
+ @Field(() => IdeaCollaboratorDevWhereInput, {
+ nullable: true,
+ })
+ some?: IdeaCollaboratorDevWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => IdeaCollaboratorDevWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaCollaboratorDevWhereInput)
+ @IsOptional()
+ @Field(() => IdeaCollaboratorDevWhereInput, {
+ nullable: true,
+ })
+ none?: IdeaCollaboratorDevWhereInput;
+}
+export { IdeaCollaboratorDevListRelationFilter as IdeaCollaboratorDevListRelationFilter };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevOrderByInput.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevOrderByInput.ts
new file mode 100644
index 0000000..e9f6ea7
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevOrderByInput.ts
@@ -0,0 +1,76 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { SortOrder } from "../../util/SortOrder";
+
+@InputType({
+ isAbstract: true,
+ description: undefined,
+})
+class IdeaCollaboratorDevOrderByInput {
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ createdAt?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ email?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ id?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ inATeamId?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ location?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ updatedAt?: SortOrder;
+}
+
+export { IdeaCollaboratorDevOrderByInput as IdeaCollaboratorDevOrderByInput };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevUpdateInput.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevUpdateInput.ts
new file mode 100644
index 0000000..d0c57de
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevUpdateInput.ts
@@ -0,0 +1,55 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, IsOptional, ValidateNested } from "class-validator";
+import { UserWhereUniqueInput } from "../../user/base/UserWhereUniqueInput";
+import { Type } from "class-transformer";
+
+@InputType()
+class IdeaCollaboratorDevUpdateInput {
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ email?: string;
+
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereUniqueInput)
+ @IsOptional()
+ @Field(() => UserWhereUniqueInput, {
+ nullable: true,
+ })
+ inATeam?: UserWhereUniqueInput | null;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ location?: string;
+}
+
+export { IdeaCollaboratorDevUpdateInput as IdeaCollaboratorDevUpdateInput };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevWhereInput.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevWhereInput.ts
new file mode 100644
index 0000000..33c3302
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevWhereInput.ts
@@ -0,0 +1,67 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { StringFilter } from "../../util/StringFilter";
+import { Type } from "class-transformer";
+import { IsOptional, ValidateNested } from "class-validator";
+import { UserWhereUniqueInput } from "../../user/base/UserWhereUniqueInput";
+
+@InputType()
+class IdeaCollaboratorDevWhereInput {
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ email?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ id?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereUniqueInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereUniqueInput)
+ @IsOptional()
+ @Field(() => UserWhereUniqueInput, {
+ nullable: true,
+ })
+ inATeam?: UserWhereUniqueInput;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ location?: StringFilter;
+}
+
+export { IdeaCollaboratorDevWhereInput as IdeaCollaboratorDevWhereInput };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevWhereUniqueInput.ts b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevWhereUniqueInput.ts
new file mode 100644
index 0000000..fa1283f
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/IdeaCollaboratorDevWhereUniqueInput.ts
@@ -0,0 +1,27 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString } from "class-validator";
+
+@InputType()
+class IdeaCollaboratorDevWhereUniqueInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+}
+
+export { IdeaCollaboratorDevWhereUniqueInput as IdeaCollaboratorDevWhereUniqueInput };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/UpdateIdeaCollaboratorDevArgs.ts b/platform/serv/src/ideaCollaboratorDev/base/UpdateIdeaCollaboratorDevArgs.ts
new file mode 100644
index 0000000..8840269
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/UpdateIdeaCollaboratorDevArgs.ts
@@ -0,0 +1,24 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaCollaboratorDevWhereUniqueInput } from "./IdeaCollaboratorDevWhereUniqueInput";
+import { IdeaCollaboratorDevUpdateInput } from "./IdeaCollaboratorDevUpdateInput";
+
+@ArgsType()
+class UpdateIdeaCollaboratorDevArgs {
+ @Field(() => IdeaCollaboratorDevWhereUniqueInput, { nullable: false })
+ where!: IdeaCollaboratorDevWhereUniqueInput;
+ @Field(() => IdeaCollaboratorDevUpdateInput, { nullable: false })
+ data!: IdeaCollaboratorDevUpdateInput;
+}
+
+export { UpdateIdeaCollaboratorDevArgs as UpdateIdeaCollaboratorDevArgs };
diff --git a/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.controller.base.spec.ts b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.controller.base.spec.ts
new file mode 100644
index 0000000..c6a7cd2
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.controller.base.spec.ts
@@ -0,0 +1,199 @@
+import { Test } from "@nestjs/testing";
+import {
+ INestApplication,
+ HttpStatus,
+ ExecutionContext,
+ CallHandler,
+} from "@nestjs/common";
+import request from "supertest";
+import { MorganModule } from "nest-morgan";
+import { ACGuard } from "nest-access-control";
+import { DefaultAuthGuard } from "../../auth/defaultAuth.guard";
+import { ACLModule } from "../../auth/acl.module";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { map } from "rxjs";
+import { IdeaCollaboratorDevController } from "../ideaCollaboratorDev.controller";
+import { IdeaCollaboratorDevService } from "../ideaCollaboratorDev.service";
+
+const nonExistingId = "nonExistingId";
+const existingId = "existingId";
+const CREATE_INPUT = {
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ location: "exampleLocation",
+ updatedAt: new Date(),
+};
+const CREATE_RESULT = {
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ location: "exampleLocation",
+ updatedAt: new Date(),
+};
+const FIND_MANY_RESULT = [
+ {
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ location: "exampleLocation",
+ updatedAt: new Date(),
+ },
+];
+const FIND_ONE_RESULT = {
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ location: "exampleLocation",
+ updatedAt: new Date(),
+};
+
+const service = {
+ create() {
+ return CREATE_RESULT;
+ },
+ findMany: () => FIND_MANY_RESULT,
+ findOne: ({ where }: { where: { id: string } }) => {
+ switch (where.id) {
+ case existingId:
+ return FIND_ONE_RESULT;
+ case nonExistingId:
+ return null;
+ }
+ },
+};
+
+const basicAuthGuard = {
+ canActivate: (context: ExecutionContext) => {
+ const argumentHost = context.switchToHttp();
+ const request = argumentHost.getRequest();
+ request.user = {
+ roles: ["user"],
+ };
+ return true;
+ },
+};
+
+const acGuard = {
+ canActivate: () => {
+ return true;
+ },
+};
+
+const aclFilterResponseInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle().pipe(
+ map((data) => {
+ return data;
+ })
+ );
+ },
+};
+const aclValidateRequestInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle();
+ },
+};
+
+describe("IdeaCollaboratorDev", () => {
+ let app: INestApplication;
+
+ beforeAll(async () => {
+ const moduleRef = await Test.createTestingModule({
+ providers: [
+ {
+ provide: IdeaCollaboratorDevService,
+ useValue: service,
+ },
+ ],
+ controllers: [IdeaCollaboratorDevController],
+ imports: [MorganModule.forRoot(), ACLModule],
+ })
+ .overrideGuard(DefaultAuthGuard)
+ .useValue(basicAuthGuard)
+ .overrideGuard(ACGuard)
+ .useValue(acGuard)
+ .overrideInterceptor(AclFilterResponseInterceptor)
+ .useValue(aclFilterResponseInterceptor)
+ .overrideInterceptor(AclValidateRequestInterceptor)
+ .useValue(aclValidateRequestInterceptor)
+ .compile();
+
+ app = moduleRef.createNestApplication();
+ await app.init();
+ });
+
+ test("POST /ideaCollaboratorDevs", async () => {
+ await request(app.getHttpServer())
+ .post("/ideaCollaboratorDevs")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("GET /ideaCollaboratorDevs", async () => {
+ await request(app.getHttpServer())
+ .get("/ideaCollaboratorDevs")
+ .expect(HttpStatus.OK)
+ .expect([
+ {
+ ...FIND_MANY_RESULT[0],
+ createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(),
+ updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(),
+ },
+ ]);
+ });
+
+ test("GET /ideaCollaboratorDevs/:id non existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/ideaCollaboratorDevs"}/${nonExistingId}`)
+ .expect(HttpStatus.NOT_FOUND)
+ .expect({
+ statusCode: HttpStatus.NOT_FOUND,
+ message: `No resource was found for {"${"id"}":"${nonExistingId}"}`,
+ error: "Not Found",
+ });
+ });
+
+ test("GET /ideaCollaboratorDevs/:id existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/ideaCollaboratorDevs"}/${existingId}`)
+ .expect(HttpStatus.OK)
+ .expect({
+ ...FIND_ONE_RESULT,
+ createdAt: FIND_ONE_RESULT.createdAt.toISOString(),
+ updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("POST /ideaCollaboratorDevs existing resource", async () => {
+ let agent = request(app.getHttpServer());
+ await agent
+ .post("/ideaCollaboratorDevs")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ })
+ .then(function () {
+ agent
+ .post("/ideaCollaboratorDevs")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CONFLICT)
+ .expect({
+ statusCode: HttpStatus.CONFLICT,
+ });
+ });
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+});
diff --git a/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.controller.base.ts b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.controller.base.ts
new file mode 100644
index 0000000..dbe3d18
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.controller.base.ts
@@ -0,0 +1,254 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import { isRecordNotFoundError } from "../../prisma.util";
+import * as errors from "../../errors";
+import { Request } from "express";
+import { plainToClass } from "class-transformer";
+import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator";
+import * as nestAccessControl from "nest-access-control";
+import * as defaultAuthGuard from "../../auth/defaultAuth.guard";
+import { IdeaCollaboratorDevService } from "../ideaCollaboratorDev.service";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { IdeaCollaboratorDevCreateInput } from "./IdeaCollaboratorDevCreateInput";
+import { IdeaCollaboratorDevWhereInput } from "./IdeaCollaboratorDevWhereInput";
+import { IdeaCollaboratorDevWhereUniqueInput } from "./IdeaCollaboratorDevWhereUniqueInput";
+import { IdeaCollaboratorDevFindManyArgs } from "./IdeaCollaboratorDevFindManyArgs";
+import { IdeaCollaboratorDevUpdateInput } from "./IdeaCollaboratorDevUpdateInput";
+import { IdeaCollaboratorDev } from "./IdeaCollaboratorDev";
+
+@swagger.ApiBearerAuth()
+@common.UseGuards(defaultAuthGuard.DefaultAuthGuard, nestAccessControl.ACGuard)
+export class IdeaCollaboratorDevControllerBase {
+ constructor(
+ protected readonly service: IdeaCollaboratorDevService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Post()
+ @swagger.ApiCreatedResponse({ type: IdeaCollaboratorDev })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "create",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: IdeaCollaboratorDevCreateInput,
+ })
+ async create(
+ @common.Body() data: IdeaCollaboratorDevCreateInput
+ ): Promise {
+ return await this.service.create({
+ data: {
+ ...data,
+
+ inATeam: data.inATeam
+ ? {
+ connect: data.inATeam,
+ }
+ : undefined,
+ },
+ select: {
+ createdAt: true,
+ email: true,
+ id: true,
+
+ inATeam: {
+ select: {
+ id: true,
+ },
+ },
+
+ location: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get()
+ @swagger.ApiOkResponse({ type: [IdeaCollaboratorDev] })
+ @ApiNestedQuery(IdeaCollaboratorDevFindManyArgs)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "read",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findMany(
+ @common.Req() request: Request
+ ): Promise {
+ const args = plainToClass(IdeaCollaboratorDevFindManyArgs, request.query);
+ return this.service.findMany({
+ ...args,
+ select: {
+ createdAt: true,
+ email: true,
+ id: true,
+
+ inATeam: {
+ select: {
+ id: true,
+ },
+ },
+
+ location: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get("/:id")
+ @swagger.ApiOkResponse({ type: IdeaCollaboratorDev })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "read",
+ possession: "own",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findOne(
+ @common.Param() params: IdeaCollaboratorDevWhereUniqueInput
+ ): Promise {
+ const result = await this.service.findOne({
+ where: params,
+ select: {
+ createdAt: true,
+ email: true,
+ id: true,
+
+ inATeam: {
+ select: {
+ id: true,
+ },
+ },
+
+ location: true,
+ updatedAt: true,
+ },
+ });
+ if (result === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Patch("/:id")
+ @swagger.ApiOkResponse({ type: IdeaCollaboratorDev })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "update",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: IdeaCollaboratorDevUpdateInput,
+ })
+ async update(
+ @common.Param() params: IdeaCollaboratorDevWhereUniqueInput,
+ @common.Body() data: IdeaCollaboratorDevUpdateInput
+ ): Promise {
+ try {
+ return await this.service.update({
+ where: params,
+ data: {
+ ...data,
+
+ inATeam: data.inATeam
+ ? {
+ connect: data.inATeam,
+ }
+ : undefined,
+ },
+ select: {
+ createdAt: true,
+ email: true,
+ id: true,
+
+ inATeam: {
+ select: {
+ id: true,
+ },
+ },
+
+ location: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.Delete("/:id")
+ @swagger.ApiOkResponse({ type: IdeaCollaboratorDev })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "delete",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async delete(
+ @common.Param() params: IdeaCollaboratorDevWhereUniqueInput
+ ): Promise {
+ try {
+ return await this.service.delete({
+ where: params,
+ select: {
+ createdAt: true,
+ email: true,
+ id: true,
+
+ inATeam: {
+ select: {
+ id: true,
+ },
+ },
+
+ location: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+}
diff --git a/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.module.base.ts b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.module.base.ts
new file mode 100644
index 0000000..c3c42c1
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.module.base.ts
@@ -0,0 +1,20 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { Module, forwardRef } from "@nestjs/common";
+import { MorganModule } from "nest-morgan";
+import { ACLModule } from "../../auth/acl.module";
+import { AuthModule } from "../../auth/auth.module";
+@Module({
+ imports: [ACLModule, forwardRef(() => AuthModule), MorganModule],
+ exports: [ACLModule, AuthModule, MorganModule],
+})
+export class IdeaCollaboratorDevModuleBase {}
diff --git a/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.resolver.base.ts b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.resolver.base.ts
new file mode 100644
index 0000000..2d88012
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.resolver.base.ts
@@ -0,0 +1,185 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as graphql from "@nestjs/graphql";
+import * as apollo from "apollo-server-express";
+import { isRecordNotFoundError } from "../../prisma.util";
+import { MetaQueryPayload } from "../../util/MetaQueryPayload";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { CreateIdeaCollaboratorDevArgs } from "./CreateIdeaCollaboratorDevArgs";
+import { UpdateIdeaCollaboratorDevArgs } from "./UpdateIdeaCollaboratorDevArgs";
+import { DeleteIdeaCollaboratorDevArgs } from "./DeleteIdeaCollaboratorDevArgs";
+import { IdeaCollaboratorDevFindManyArgs } from "./IdeaCollaboratorDevFindManyArgs";
+import { IdeaCollaboratorDevFindUniqueArgs } from "./IdeaCollaboratorDevFindUniqueArgs";
+import { IdeaCollaboratorDev } from "./IdeaCollaboratorDev";
+import { User } from "../../user/base/User";
+import { IdeaCollaboratorDevService } from "../ideaCollaboratorDev.service";
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => IdeaCollaboratorDev)
+export class IdeaCollaboratorDevResolverBase {
+ constructor(
+ protected readonly service: IdeaCollaboratorDevService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+
+ @graphql.Query(() => MetaQueryPayload)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "read",
+ possession: "any",
+ })
+ async _ideaCollaboratorDevsMeta(
+ @graphql.Args() args: IdeaCollaboratorDevFindManyArgs
+ ): Promise {
+ const results = await this.service.count({
+ ...args,
+ skip: undefined,
+ take: undefined,
+ });
+ return {
+ count: results,
+ };
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => [IdeaCollaboratorDev])
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "read",
+ possession: "any",
+ })
+ async ideaCollaboratorDevs(
+ @graphql.Args() args: IdeaCollaboratorDevFindManyArgs
+ ): Promise {
+ return this.service.findMany(args);
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => IdeaCollaboratorDev, { nullable: true })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "read",
+ possession: "own",
+ })
+ async ideaCollaboratorDev(
+ @graphql.Args() args: IdeaCollaboratorDevFindUniqueArgs
+ ): Promise {
+ const result = await this.service.findOne(args);
+ if (result === null) {
+ return null;
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => IdeaCollaboratorDev)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "create",
+ possession: "any",
+ })
+ async createIdeaCollaboratorDev(
+ @graphql.Args() args: CreateIdeaCollaboratorDevArgs
+ ): Promise {
+ return await this.service.create({
+ ...args,
+ data: {
+ ...args.data,
+
+ inATeam: args.data.inATeam
+ ? {
+ connect: args.data.inATeam,
+ }
+ : undefined,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => IdeaCollaboratorDev)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "update",
+ possession: "any",
+ })
+ async updateIdeaCollaboratorDev(
+ @graphql.Args() args: UpdateIdeaCollaboratorDevArgs
+ ): Promise {
+ try {
+ return await this.service.update({
+ ...args,
+ data: {
+ ...args.data,
+
+ inATeam: args.data.inATeam
+ ? {
+ connect: args.data.inATeam,
+ }
+ : undefined,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @graphql.Mutation(() => IdeaCollaboratorDev)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "delete",
+ possession: "any",
+ })
+ async deleteIdeaCollaboratorDev(
+ @graphql.Args() args: DeleteIdeaCollaboratorDevArgs
+ ): Promise {
+ try {
+ return await this.service.delete(args);
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.ResolveField(() => User, {
+ nullable: true,
+ name: "inATeam",
+ })
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "read",
+ possession: "any",
+ })
+ async resolveFieldInATeam(
+ @graphql.Parent() parent: IdeaCollaboratorDev
+ ): Promise {
+ const result = await this.service.getInATeam(parent.id);
+
+ if (!result) {
+ return null;
+ }
+ return result;
+ }
+}
diff --git a/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.service.base.ts b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.service.base.ts
new file mode 100644
index 0000000..8885129
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/base/ideaCollaboratorDev.service.base.ts
@@ -0,0 +1,57 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { PrismaService } from "../../prisma/prisma.service";
+import { Prisma, IdeaCollaboratorDev, User } from "@prisma/client";
+
+export class IdeaCollaboratorDevServiceBase {
+ constructor(protected readonly prisma: PrismaService) {}
+
+ async count(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaCollaboratorDev.count(args);
+ }
+
+ async findMany(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaCollaboratorDev.findMany(args);
+ }
+ async findOne(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaCollaboratorDev.findUnique(args);
+ }
+ async create(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaCollaboratorDev.create(args);
+ }
+ async update(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaCollaboratorDev.update(args);
+ }
+ async delete(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaCollaboratorDev.delete(args);
+ }
+
+ async getInATeam(parentId: string): Promise {
+ return this.prisma.ideaCollaboratorDev
+ .findUnique({
+ where: { id: parentId },
+ })
+ .inATeam();
+ }
+}
diff --git a/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.controller.ts b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.controller.ts
new file mode 100644
index 0000000..7a14db9
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.controller.ts
@@ -0,0 +1,17 @@
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import * as nestAccessControl from "nest-access-control";
+import { IdeaCollaboratorDevService } from "./ideaCollaboratorDev.service";
+import { IdeaCollaboratorDevControllerBase } from "./base/ideaCollaboratorDev.controller.base";
+
+@swagger.ApiTags("ideaCollaboratorDevs")
+@common.Controller("ideaCollaboratorDevs")
+export class IdeaCollaboratorDevController extends IdeaCollaboratorDevControllerBase {
+ constructor(
+ protected readonly service: IdeaCollaboratorDevService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.module.ts b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.module.ts
new file mode 100644
index 0000000..d295625
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.module.ts
@@ -0,0 +1,13 @@
+import { Module } from "@nestjs/common";
+import { IdeaCollaboratorDevModuleBase } from "./base/ideaCollaboratorDev.module.base";
+import { IdeaCollaboratorDevService } from "./ideaCollaboratorDev.service";
+import { IdeaCollaboratorDevController } from "./ideaCollaboratorDev.controller";
+import { IdeaCollaboratorDevResolver } from "./ideaCollaboratorDev.resolver";
+
+@Module({
+ imports: [IdeaCollaboratorDevModuleBase],
+ controllers: [IdeaCollaboratorDevController],
+ providers: [IdeaCollaboratorDevService, IdeaCollaboratorDevResolver],
+ exports: [IdeaCollaboratorDevService],
+})
+export class IdeaCollaboratorDevModule {}
diff --git a/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.resolver.ts b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.resolver.ts
new file mode 100644
index 0000000..287ba43
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.resolver.ts
@@ -0,0 +1,20 @@
+import * as graphql from "@nestjs/graphql";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { IdeaCollaboratorDevResolverBase } from "./base/ideaCollaboratorDev.resolver.base";
+import { IdeaCollaboratorDev } from "./base/IdeaCollaboratorDev";
+import { IdeaCollaboratorDevService } from "./ideaCollaboratorDev.service";
+
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => IdeaCollaboratorDev)
+export class IdeaCollaboratorDevResolver extends IdeaCollaboratorDevResolverBase {
+ constructor(
+ protected readonly service: IdeaCollaboratorDevService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.service.ts b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.service.ts
new file mode 100644
index 0000000..97fca83
--- /dev/null
+++ b/platform/serv/src/ideaCollaboratorDev/ideaCollaboratorDev.service.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@nestjs/common";
+import { PrismaService } from "../prisma/prisma.service";
+import { IdeaCollaboratorDevServiceBase } from "./base/ideaCollaboratorDev.service.base";
+
+@Injectable()
+export class IdeaCollaboratorDevService extends IdeaCollaboratorDevServiceBase {
+ constructor(protected readonly prisma: PrismaService) {
+ super(prisma);
+ }
+}
diff --git a/platform/serv/src/ideaViewerGuest/base/CreateIdeaViewerGuestArgs.ts b/platform/serv/src/ideaViewerGuest/base/CreateIdeaViewerGuestArgs.ts
new file mode 100644
index 0000000..409c124
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/CreateIdeaViewerGuestArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaViewerGuestCreateInput } from "./IdeaViewerGuestCreateInput";
+
+@ArgsType()
+class CreateIdeaViewerGuestArgs {
+ @Field(() => IdeaViewerGuestCreateInput, { nullable: false })
+ data!: IdeaViewerGuestCreateInput;
+}
+
+export { CreateIdeaViewerGuestArgs as CreateIdeaViewerGuestArgs };
diff --git a/platform/serv/src/ideaViewerGuest/base/DeleteIdeaViewerGuestArgs.ts b/platform/serv/src/ideaViewerGuest/base/DeleteIdeaViewerGuestArgs.ts
new file mode 100644
index 0000000..31b1d27
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/DeleteIdeaViewerGuestArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaViewerGuestWhereUniqueInput } from "./IdeaViewerGuestWhereUniqueInput";
+
+@ArgsType()
+class DeleteIdeaViewerGuestArgs {
+ @Field(() => IdeaViewerGuestWhereUniqueInput, { nullable: false })
+ where!: IdeaViewerGuestWhereUniqueInput;
+}
+
+export { DeleteIdeaViewerGuestArgs as DeleteIdeaViewerGuestArgs };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuest.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuest.ts
new file mode 100644
index 0000000..e59b2db
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuest.ts
@@ -0,0 +1,71 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ObjectType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, IsDate, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+
+@ObjectType()
+class IdeaViewerGuest {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ company!: string;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ createdAt!: Date;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ email!: string | null;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ Location!: string;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ updatedAt!: Date;
+}
+
+export { IdeaViewerGuest as IdeaViewerGuest };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestCreateInput.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestCreateInput.ts
new file mode 100644
index 0000000..638f7da
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestCreateInput.ts
@@ -0,0 +1,46 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, IsOptional } from "class-validator";
+
+@InputType()
+class IdeaViewerGuestCreateInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ company!: string;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ email?: string | null;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ Location!: string;
+}
+
+export { IdeaViewerGuestCreateInput as IdeaViewerGuestCreateInput };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestFindManyArgs.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestFindManyArgs.ts
new file mode 100644
index 0000000..ec5223d
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestFindManyArgs.ts
@@ -0,0 +1,53 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IdeaViewerGuestWhereInput } from "./IdeaViewerGuestWhereInput";
+import { Type } from "class-transformer";
+import { IdeaViewerGuestOrderByInput } from "./IdeaViewerGuestOrderByInput";
+
+@ArgsType()
+class IdeaViewerGuestFindManyArgs {
+ @ApiProperty({
+ required: false,
+ type: () => IdeaViewerGuestWhereInput,
+ })
+ @Field(() => IdeaViewerGuestWhereInput, { nullable: true })
+ @Type(() => IdeaViewerGuestWhereInput)
+ where?: IdeaViewerGuestWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: [IdeaViewerGuestOrderByInput],
+ })
+ @Field(() => [IdeaViewerGuestOrderByInput], { nullable: true })
+ @Type(() => IdeaViewerGuestOrderByInput)
+ orderBy?: Array;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ skip?: number;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ take?: number;
+}
+
+export { IdeaViewerGuestFindManyArgs as IdeaViewerGuestFindManyArgs };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestFindUniqueArgs.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestFindUniqueArgs.ts
new file mode 100644
index 0000000..19b0216
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestFindUniqueArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaViewerGuestWhereUniqueInput } from "./IdeaViewerGuestWhereUniqueInput";
+
+@ArgsType()
+class IdeaViewerGuestFindUniqueArgs {
+ @Field(() => IdeaViewerGuestWhereUniqueInput, { nullable: false })
+ where!: IdeaViewerGuestWhereUniqueInput;
+}
+
+export { IdeaViewerGuestFindUniqueArgs as IdeaViewerGuestFindUniqueArgs };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestListRelationFilter.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestListRelationFilter.ts
new file mode 100644
index 0000000..a96d30d
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestListRelationFilter.ts
@@ -0,0 +1,56 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IdeaViewerGuestWhereInput } from "./IdeaViewerGuestWhereInput";
+import { ValidateNested, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+
+@InputType()
+class IdeaViewerGuestListRelationFilter {
+ @ApiProperty({
+ required: false,
+ type: () => IdeaViewerGuestWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaViewerGuestWhereInput)
+ @IsOptional()
+ @Field(() => IdeaViewerGuestWhereInput, {
+ nullable: true,
+ })
+ every?: IdeaViewerGuestWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => IdeaViewerGuestWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaViewerGuestWhereInput)
+ @IsOptional()
+ @Field(() => IdeaViewerGuestWhereInput, {
+ nullable: true,
+ })
+ some?: IdeaViewerGuestWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => IdeaViewerGuestWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaViewerGuestWhereInput)
+ @IsOptional()
+ @Field(() => IdeaViewerGuestWhereInput, {
+ nullable: true,
+ })
+ none?: IdeaViewerGuestWhereInput;
+}
+export { IdeaViewerGuestListRelationFilter as IdeaViewerGuestListRelationFilter };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestOrderByInput.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestOrderByInput.ts
new file mode 100644
index 0000000..530b76e
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestOrderByInput.ts
@@ -0,0 +1,76 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { SortOrder } from "../../util/SortOrder";
+
+@InputType({
+ isAbstract: true,
+ description: undefined,
+})
+class IdeaViewerGuestOrderByInput {
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ company?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ createdAt?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ email?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ id?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ Location?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ updatedAt?: SortOrder;
+}
+
+export { IdeaViewerGuestOrderByInput as IdeaViewerGuestOrderByInput };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestUpdateInput.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestUpdateInput.ts
new file mode 100644
index 0000000..dd8d354
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestUpdateInput.ts
@@ -0,0 +1,52 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, IsOptional } from "class-validator";
+
+@InputType()
+class IdeaViewerGuestUpdateInput {
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ company?: string;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ email?: string | null;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ Location?: string;
+}
+
+export { IdeaViewerGuestUpdateInput as IdeaViewerGuestUpdateInput };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestWhereInput.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestWhereInput.ts
new file mode 100644
index 0000000..0ed62a7
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestWhereInput.ts
@@ -0,0 +1,66 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { StringFilter } from "../../util/StringFilter";
+import { Type } from "class-transformer";
+import { IsOptional } from "class-validator";
+import { StringNullableFilter } from "../../util/StringNullableFilter";
+
+@InputType()
+class IdeaViewerGuestWhereInput {
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ company?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringNullableFilter,
+ })
+ @Type(() => StringNullableFilter)
+ @IsOptional()
+ @Field(() => StringNullableFilter, {
+ nullable: true,
+ })
+ email?: StringNullableFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ id?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ Location?: StringFilter;
+}
+
+export { IdeaViewerGuestWhereInput as IdeaViewerGuestWhereInput };
diff --git a/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestWhereUniqueInput.ts b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestWhereUniqueInput.ts
new file mode 100644
index 0000000..0fc3f0f
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/IdeaViewerGuestWhereUniqueInput.ts
@@ -0,0 +1,27 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString } from "class-validator";
+
+@InputType()
+class IdeaViewerGuestWhereUniqueInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+}
+
+export { IdeaViewerGuestWhereUniqueInput as IdeaViewerGuestWhereUniqueInput };
diff --git a/platform/serv/src/ideaViewerGuest/base/UpdateIdeaViewerGuestArgs.ts b/platform/serv/src/ideaViewerGuest/base/UpdateIdeaViewerGuestArgs.ts
new file mode 100644
index 0000000..9b5e3c7
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/UpdateIdeaViewerGuestArgs.ts
@@ -0,0 +1,24 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { IdeaViewerGuestWhereUniqueInput } from "./IdeaViewerGuestWhereUniqueInput";
+import { IdeaViewerGuestUpdateInput } from "./IdeaViewerGuestUpdateInput";
+
+@ArgsType()
+class UpdateIdeaViewerGuestArgs {
+ @Field(() => IdeaViewerGuestWhereUniqueInput, { nullable: false })
+ where!: IdeaViewerGuestWhereUniqueInput;
+ @Field(() => IdeaViewerGuestUpdateInput, { nullable: false })
+ data!: IdeaViewerGuestUpdateInput;
+}
+
+export { UpdateIdeaViewerGuestArgs as UpdateIdeaViewerGuestArgs };
diff --git a/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.controller.base.spec.ts b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.controller.base.spec.ts
new file mode 100644
index 0000000..5fbcfd2
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.controller.base.spec.ts
@@ -0,0 +1,203 @@
+import { Test } from "@nestjs/testing";
+import {
+ INestApplication,
+ HttpStatus,
+ ExecutionContext,
+ CallHandler,
+} from "@nestjs/common";
+import request from "supertest";
+import { MorganModule } from "nest-morgan";
+import { ACGuard } from "nest-access-control";
+import { DefaultAuthGuard } from "../../auth/defaultAuth.guard";
+import { ACLModule } from "../../auth/acl.module";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { map } from "rxjs";
+import { IdeaViewerGuestController } from "../ideaViewerGuest.controller";
+import { IdeaViewerGuestService } from "../ideaViewerGuest.service";
+
+const nonExistingId = "nonExistingId";
+const existingId = "existingId";
+const CREATE_INPUT = {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ Location: "exampleLocation",
+ updatedAt: new Date(),
+};
+const CREATE_RESULT = {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ Location: "exampleLocation",
+ updatedAt: new Date(),
+};
+const FIND_MANY_RESULT = [
+ {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ Location: "exampleLocation",
+ updatedAt: new Date(),
+ },
+];
+const FIND_ONE_RESULT = {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ id: "exampleId",
+ Location: "exampleLocation",
+ updatedAt: new Date(),
+};
+
+const service = {
+ create() {
+ return CREATE_RESULT;
+ },
+ findMany: () => FIND_MANY_RESULT,
+ findOne: ({ where }: { where: { id: string } }) => {
+ switch (where.id) {
+ case existingId:
+ return FIND_ONE_RESULT;
+ case nonExistingId:
+ return null;
+ }
+ },
+};
+
+const basicAuthGuard = {
+ canActivate: (context: ExecutionContext) => {
+ const argumentHost = context.switchToHttp();
+ const request = argumentHost.getRequest();
+ request.user = {
+ roles: ["user"],
+ };
+ return true;
+ },
+};
+
+const acGuard = {
+ canActivate: () => {
+ return true;
+ },
+};
+
+const aclFilterResponseInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle().pipe(
+ map((data) => {
+ return data;
+ })
+ );
+ },
+};
+const aclValidateRequestInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle();
+ },
+};
+
+describe("IdeaViewerGuest", () => {
+ let app: INestApplication;
+
+ beforeAll(async () => {
+ const moduleRef = await Test.createTestingModule({
+ providers: [
+ {
+ provide: IdeaViewerGuestService,
+ useValue: service,
+ },
+ ],
+ controllers: [IdeaViewerGuestController],
+ imports: [MorganModule.forRoot(), ACLModule],
+ })
+ .overrideGuard(DefaultAuthGuard)
+ .useValue(basicAuthGuard)
+ .overrideGuard(ACGuard)
+ .useValue(acGuard)
+ .overrideInterceptor(AclFilterResponseInterceptor)
+ .useValue(aclFilterResponseInterceptor)
+ .overrideInterceptor(AclValidateRequestInterceptor)
+ .useValue(aclValidateRequestInterceptor)
+ .compile();
+
+ app = moduleRef.createNestApplication();
+ await app.init();
+ });
+
+ test("POST /ideaViewerGuests", async () => {
+ await request(app.getHttpServer())
+ .post("/ideaViewerGuests")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("GET /ideaViewerGuests", async () => {
+ await request(app.getHttpServer())
+ .get("/ideaViewerGuests")
+ .expect(HttpStatus.OK)
+ .expect([
+ {
+ ...FIND_MANY_RESULT[0],
+ createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(),
+ updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(),
+ },
+ ]);
+ });
+
+ test("GET /ideaViewerGuests/:id non existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/ideaViewerGuests"}/${nonExistingId}`)
+ .expect(HttpStatus.NOT_FOUND)
+ .expect({
+ statusCode: HttpStatus.NOT_FOUND,
+ message: `No resource was found for {"${"id"}":"${nonExistingId}"}`,
+ error: "Not Found",
+ });
+ });
+
+ test("GET /ideaViewerGuests/:id existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/ideaViewerGuests"}/${existingId}`)
+ .expect(HttpStatus.OK)
+ .expect({
+ ...FIND_ONE_RESULT,
+ createdAt: FIND_ONE_RESULT.createdAt.toISOString(),
+ updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("POST /ideaViewerGuests existing resource", async () => {
+ let agent = request(app.getHttpServer());
+ await agent
+ .post("/ideaViewerGuests")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ })
+ .then(function () {
+ agent
+ .post("/ideaViewerGuests")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CONFLICT)
+ .expect({
+ statusCode: HttpStatus.CONFLICT,
+ });
+ });
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+});
diff --git a/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.controller.base.ts b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.controller.base.ts
new file mode 100644
index 0000000..d159cf4
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.controller.base.ts
@@ -0,0 +1,196 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import { isRecordNotFoundError } from "../../prisma.util";
+import * as errors from "../../errors";
+import { Request } from "express";
+import { plainToClass } from "class-transformer";
+import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator";
+import * as nestAccessControl from "nest-access-control";
+import * as defaultAuthGuard from "../../auth/defaultAuth.guard";
+import { IdeaViewerGuestService } from "../ideaViewerGuest.service";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { Public } from "../../decorators/public.decorator";
+import { IdeaViewerGuestCreateInput } from "./IdeaViewerGuestCreateInput";
+import { IdeaViewerGuestWhereInput } from "./IdeaViewerGuestWhereInput";
+import { IdeaViewerGuestWhereUniqueInput } from "./IdeaViewerGuestWhereUniqueInput";
+import { IdeaViewerGuestFindManyArgs } from "./IdeaViewerGuestFindManyArgs";
+import { IdeaViewerGuestUpdateInput } from "./IdeaViewerGuestUpdateInput";
+import { IdeaViewerGuest } from "./IdeaViewerGuest";
+
+@swagger.ApiBearerAuth()
+@common.UseGuards(defaultAuthGuard.DefaultAuthGuard, nestAccessControl.ACGuard)
+export class IdeaViewerGuestControllerBase {
+ constructor(
+ protected readonly service: IdeaViewerGuestService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Post()
+ @swagger.ApiCreatedResponse({ type: IdeaViewerGuest })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaViewerGuest",
+ action: "create",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: IdeaViewerGuestCreateInput,
+ })
+ async create(
+ @common.Body() data: IdeaViewerGuestCreateInput
+ ): Promise {
+ return await this.service.create({
+ data: data,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ id: true,
+ Location: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @Public()
+ @common.Get()
+ @swagger.ApiOkResponse({ type: [IdeaViewerGuest] })
+ @ApiNestedQuery(IdeaViewerGuestFindManyArgs)
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findMany(@common.Req() request: Request): Promise {
+ const args = plainToClass(IdeaViewerGuestFindManyArgs, request.query);
+ return this.service.findMany({
+ ...args,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ id: true,
+ Location: true,
+ updatedAt: true,
+ },
+ });
+ }
+
+ @Public()
+ @common.Get("/:id")
+ @swagger.ApiOkResponse({ type: IdeaViewerGuest })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findOne(
+ @common.Param() params: IdeaViewerGuestWhereUniqueInput
+ ): Promise {
+ const result = await this.service.findOne({
+ where: params,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ id: true,
+ Location: true,
+ updatedAt: true,
+ },
+ });
+ if (result === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Patch("/:id")
+ @swagger.ApiOkResponse({ type: IdeaViewerGuest })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaViewerGuest",
+ action: "update",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: IdeaViewerGuestUpdateInput,
+ })
+ async update(
+ @common.Param() params: IdeaViewerGuestWhereUniqueInput,
+ @common.Body() data: IdeaViewerGuestUpdateInput
+ ): Promise {
+ try {
+ return await this.service.update({
+ where: params,
+ data: data,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ id: true,
+ Location: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.Delete("/:id")
+ @swagger.ApiOkResponse({ type: IdeaViewerGuest })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaViewerGuest",
+ action: "delete",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async delete(
+ @common.Param() params: IdeaViewerGuestWhereUniqueInput
+ ): Promise {
+ try {
+ return await this.service.delete({
+ where: params,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ id: true,
+ Location: true,
+ updatedAt: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+}
diff --git a/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.module.base.ts b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.module.base.ts
new file mode 100644
index 0000000..2f9badb
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.module.base.ts
@@ -0,0 +1,20 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { Module, forwardRef } from "@nestjs/common";
+import { MorganModule } from "nest-morgan";
+import { ACLModule } from "../../auth/acl.module";
+import { AuthModule } from "../../auth/auth.module";
+@Module({
+ imports: [ACLModule, forwardRef(() => AuthModule), MorganModule],
+ exports: [ACLModule, AuthModule, MorganModule],
+})
+export class IdeaViewerGuestModuleBase {}
diff --git a/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.resolver.base.ts b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.resolver.base.ts
new file mode 100644
index 0000000..da493ea
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.resolver.base.ts
@@ -0,0 +1,133 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as graphql from "@nestjs/graphql";
+import * as apollo from "apollo-server-express";
+import { isRecordNotFoundError } from "../../prisma.util";
+import { MetaQueryPayload } from "../../util/MetaQueryPayload";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { Public } from "../../decorators/public.decorator";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { CreateIdeaViewerGuestArgs } from "./CreateIdeaViewerGuestArgs";
+import { UpdateIdeaViewerGuestArgs } from "./UpdateIdeaViewerGuestArgs";
+import { DeleteIdeaViewerGuestArgs } from "./DeleteIdeaViewerGuestArgs";
+import { IdeaViewerGuestFindManyArgs } from "./IdeaViewerGuestFindManyArgs";
+import { IdeaViewerGuestFindUniqueArgs } from "./IdeaViewerGuestFindUniqueArgs";
+import { IdeaViewerGuest } from "./IdeaViewerGuest";
+import { IdeaViewerGuestService } from "../ideaViewerGuest.service";
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => IdeaViewerGuest)
+export class IdeaViewerGuestResolverBase {
+ constructor(
+ protected readonly service: IdeaViewerGuestService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+
+ @Public()
+ @graphql.Query(() => MetaQueryPayload)
+ async _ideaViewerGuestsMeta(
+ @graphql.Args() args: IdeaViewerGuestFindManyArgs
+ ): Promise {
+ const results = await this.service.count({
+ ...args,
+ skip: undefined,
+ take: undefined,
+ });
+ return {
+ count: results,
+ };
+ }
+
+ @Public()
+ @graphql.Query(() => [IdeaViewerGuest])
+ async ideaViewerGuests(
+ @graphql.Args() args: IdeaViewerGuestFindManyArgs
+ ): Promise {
+ return this.service.findMany(args);
+ }
+
+ @Public()
+ @graphql.Query(() => IdeaViewerGuest, { nullable: true })
+ async ideaViewerGuest(
+ @graphql.Args() args: IdeaViewerGuestFindUniqueArgs
+ ): Promise {
+ const result = await this.service.findOne(args);
+ if (result === null) {
+ return null;
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => IdeaViewerGuest)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaViewerGuest",
+ action: "create",
+ possession: "any",
+ })
+ async createIdeaViewerGuest(
+ @graphql.Args() args: CreateIdeaViewerGuestArgs
+ ): Promise {
+ return await this.service.create({
+ ...args,
+ data: args.data,
+ });
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => IdeaViewerGuest)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaViewerGuest",
+ action: "update",
+ possession: "any",
+ })
+ async updateIdeaViewerGuest(
+ @graphql.Args() args: UpdateIdeaViewerGuestArgs
+ ): Promise {
+ try {
+ return await this.service.update({
+ ...args,
+ data: args.data,
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @graphql.Mutation(() => IdeaViewerGuest)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaViewerGuest",
+ action: "delete",
+ possession: "any",
+ })
+ async deleteIdeaViewerGuest(
+ @graphql.Args() args: DeleteIdeaViewerGuestArgs
+ ): Promise {
+ try {
+ return await this.service.delete(args);
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+}
diff --git a/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.service.base.ts b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.service.base.ts
new file mode 100644
index 0000000..a92a2d9
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/base/ideaViewerGuest.service.base.ts
@@ -0,0 +1,49 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { PrismaService } from "../../prisma/prisma.service";
+import { Prisma, IdeaViewerGuest } from "@prisma/client";
+
+export class IdeaViewerGuestServiceBase {
+ constructor(protected readonly prisma: PrismaService) {}
+
+ async count(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaViewerGuest.count(args);
+ }
+
+ async findMany(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaViewerGuest.findMany(args);
+ }
+ async findOne(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaViewerGuest.findUnique(args);
+ }
+ async create(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaViewerGuest.create(args);
+ }
+ async update(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaViewerGuest.update(args);
+ }
+ async delete(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.ideaViewerGuest.delete(args);
+ }
+}
diff --git a/platform/serv/src/ideaViewerGuest/ideaViewerGuest.controller.ts b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.controller.ts
new file mode 100644
index 0000000..1a2d096
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.controller.ts
@@ -0,0 +1,17 @@
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import * as nestAccessControl from "nest-access-control";
+import { IdeaViewerGuestService } from "./ideaViewerGuest.service";
+import { IdeaViewerGuestControllerBase } from "./base/ideaViewerGuest.controller.base";
+
+@swagger.ApiTags("ideaViewerGuests")
+@common.Controller("ideaViewerGuests")
+export class IdeaViewerGuestController extends IdeaViewerGuestControllerBase {
+ constructor(
+ protected readonly service: IdeaViewerGuestService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/ideaViewerGuest/ideaViewerGuest.module.ts b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.module.ts
new file mode 100644
index 0000000..8e34b3e
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.module.ts
@@ -0,0 +1,13 @@
+import { Module } from "@nestjs/common";
+import { IdeaViewerGuestModuleBase } from "./base/ideaViewerGuest.module.base";
+import { IdeaViewerGuestService } from "./ideaViewerGuest.service";
+import { IdeaViewerGuestController } from "./ideaViewerGuest.controller";
+import { IdeaViewerGuestResolver } from "./ideaViewerGuest.resolver";
+
+@Module({
+ imports: [IdeaViewerGuestModuleBase],
+ controllers: [IdeaViewerGuestController],
+ providers: [IdeaViewerGuestService, IdeaViewerGuestResolver],
+ exports: [IdeaViewerGuestService],
+})
+export class IdeaViewerGuestModule {}
diff --git a/platform/serv/src/ideaViewerGuest/ideaViewerGuest.resolver.ts b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.resolver.ts
new file mode 100644
index 0000000..3fcd68c
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.resolver.ts
@@ -0,0 +1,20 @@
+import * as graphql from "@nestjs/graphql";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { IdeaViewerGuestResolverBase } from "./base/ideaViewerGuest.resolver.base";
+import { IdeaViewerGuest } from "./base/IdeaViewerGuest";
+import { IdeaViewerGuestService } from "./ideaViewerGuest.service";
+
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => IdeaViewerGuest)
+export class IdeaViewerGuestResolver extends IdeaViewerGuestResolverBase {
+ constructor(
+ protected readonly service: IdeaViewerGuestService,
+ @nestAccessControl.InjectRolesBuilder()
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {
+ super(service, rolesBuilder);
+ }
+}
diff --git a/platform/serv/src/ideaViewerGuest/ideaViewerGuest.service.ts b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.service.ts
new file mode 100644
index 0000000..46fecb6
--- /dev/null
+++ b/platform/serv/src/ideaViewerGuest/ideaViewerGuest.service.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@nestjs/common";
+import { PrismaService } from "../prisma/prisma.service";
+import { IdeaViewerGuestServiceBase } from "./base/ideaViewerGuest.service.base";
+
+@Injectable()
+export class IdeaViewerGuestService extends IdeaViewerGuestServiceBase {
+ constructor(protected readonly prisma: PrismaService) {
+ super(prisma);
+ }
+}
diff --git a/platform/serv/src/interceptors/aclFilterResponse.interceptor.ts b/platform/serv/src/interceptors/aclFilterResponse.interceptor.ts
new file mode 100644
index 0000000..5eeba18
--- /dev/null
+++ b/platform/serv/src/interceptors/aclFilterResponse.interceptor.ts
@@ -0,0 +1,42 @@
+import {
+ CallHandler,
+ ExecutionContext,
+ Injectable,
+ NestInterceptor,
+} from "@nestjs/common";
+import { Observable } from "rxjs";
+import { map } from "rxjs/operators";
+import { InjectRolesBuilder, RolesBuilder } from "nest-access-control";
+import { Reflector } from "@nestjs/core";
+
+@Injectable()
+export class AclFilterResponseInterceptor implements NestInterceptor {
+ constructor(
+ @InjectRolesBuilder() private readonly rolesBuilder: RolesBuilder,
+ private readonly reflector: Reflector
+ ) {}
+
+ intercept(context: ExecutionContext, next: CallHandler): Observable {
+ const [permissionsRoles]: any = this.reflector.getAllAndMerge(
+ "roles",
+ [context.getHandler(), context.getClass()]
+ );
+
+ const permission = this.rolesBuilder.permission({
+ role: permissionsRoles.role,
+ action: permissionsRoles.action,
+ possession: permissionsRoles.possession,
+ resource: permissionsRoles.resource,
+ });
+
+ return next.handle().pipe(
+ map((data) => {
+ if (Array.isArray(data)) {
+ return data.map((results: any) => permission.filter(results));
+ } else {
+ return permission.filter(data);
+ }
+ })
+ );
+ }
+}
diff --git a/platform/serv/src/interceptors/aclValidateRequest.interceptor.ts b/platform/serv/src/interceptors/aclValidateRequest.interceptor.ts
new file mode 100644
index 0000000..6d30246
--- /dev/null
+++ b/platform/serv/src/interceptors/aclValidateRequest.interceptor.ts
@@ -0,0 +1,53 @@
+import {
+ CallHandler,
+ ExecutionContext,
+ Injectable,
+ NestInterceptor,
+} from "@nestjs/common";
+import { Observable } from "rxjs";
+import { InjectRolesBuilder, RolesBuilder } from "nest-access-control";
+import { Reflector } from "@nestjs/core";
+import * as abacUtil from "../auth/abac.util";
+import { ForbiddenException } from "../errors";
+
+@Injectable()
+export class AclValidateRequestInterceptor implements NestInterceptor {
+ constructor(
+ @InjectRolesBuilder() private readonly rolesBuilder: RolesBuilder,
+ private readonly reflector: Reflector
+ ) {}
+
+ intercept(context: ExecutionContext, next: CallHandler): Observable {
+ const [permissionsRoles]: any = this.reflector.getAllAndMerge(
+ "roles",
+ [context.getHandler(), context.getClass()]
+ );
+
+ const type = context.getType();
+
+ const inputDataToValidate =
+ type === "http"
+ ? context.switchToHttp().getRequest().body
+ : context.getArgByIndex(1).data;
+
+ const permission = this.rolesBuilder.permission({
+ role: permissionsRoles.role,
+ action: permissionsRoles.action,
+ possession: permissionsRoles.possession,
+ resource: permissionsRoles.resource,
+ });
+
+ const invalidAttributes = abacUtil.getInvalidAttributes(
+ permission,
+ inputDataToValidate
+ );
+
+ if (invalidAttributes.length) {
+ throw new ForbiddenException(
+ "Insufficient privileges to complete the operation"
+ );
+ }
+
+ return next.handle();
+ }
+}
diff --git a/platform/serv/src/main.ts b/platform/serv/src/main.ts
new file mode 100644
index 0000000..a5e8c97
--- /dev/null
+++ b/platform/serv/src/main.ts
@@ -0,0 +1,52 @@
+import { ValidationPipe } from "@nestjs/common";
+import { HttpAdapterHost, NestFactory } from "@nestjs/core";
+import { OpenAPIObject, SwaggerModule } from "@nestjs/swagger";
+import { HttpExceptionFilter } from "./filters/HttpExceptions.filter";
+// @ts-ignore
+// eslint-disable-next-line
+import { AppModule } from "./app.module";
+import {
+ swaggerPath,
+ swaggerDocumentOptions,
+ swaggerSetupOptions,
+ // @ts-ignore
+ // eslint-disable-next-line
+} from "./swagger";
+
+const { PORT = 3000 } = process.env;
+
+async function main() {
+ const app = await NestFactory.create(AppModule, { cors: true });
+
+ app.setGlobalPrefix("api");
+ app.useGlobalPipes(
+ new ValidationPipe({
+ transform: true,
+ })
+ );
+
+ const document = SwaggerModule.createDocument(app, swaggerDocumentOptions);
+
+ /** check if there is Public decorator for each path (action) and its method (findMany / findOne) on each controller */
+ Object.values((document as OpenAPIObject).paths).forEach((path: any) => {
+ Object.values(path).forEach((method: any) => {
+ if (
+ Array.isArray(method.security) &&
+ method.security.includes("isPublic")
+ ) {
+ method.security = [];
+ }
+ });
+ });
+
+ SwaggerModule.setup(swaggerPath, app, document, swaggerSetupOptions);
+
+ const { httpAdapter } = app.get(HttpAdapterHost);
+ app.useGlobalFilters(new HttpExceptionFilter(httpAdapter));
+
+ void app.listen(PORT);
+
+ return app;
+}
+
+module.exports = main();
diff --git a/platform/serv/src/prisma.util.spec.ts b/platform/serv/src/prisma.util.spec.ts
new file mode 100644
index 0000000..0aa308e
--- /dev/null
+++ b/platform/serv/src/prisma.util.spec.ts
@@ -0,0 +1,23 @@
+import {
+ isRecordNotFoundError,
+ PRISMA_QUERY_INTERPRETATION_ERROR,
+} from "./prisma.util";
+
+describe("isRecordNotFoundError", () => {
+ test("returns true for record not found error", () => {
+ expect(
+ isRecordNotFoundError(
+ Object.assign(
+ new Error(`Error occurred during query execution:
+ InterpretationError("Error for binding '0': RecordNotFound("Record to update not found.")")`),
+ {
+ code: PRISMA_QUERY_INTERPRETATION_ERROR,
+ }
+ )
+ )
+ ).toBe(true);
+ });
+ test("returns false for any other error", () => {
+ expect(isRecordNotFoundError(new Error())).toBe(false);
+ });
+});
diff --git a/platform/serv/src/prisma.util.ts b/platform/serv/src/prisma.util.ts
new file mode 100644
index 0000000..8e0779c
--- /dev/null
+++ b/platform/serv/src/prisma.util.ts
@@ -0,0 +1,30 @@
+export const PRISMA_QUERY_INTERPRETATION_ERROR = "P2016";
+export const PRISMA_RECORD_NOT_FOUND = "RecordNotFound";
+
+export function isRecordNotFoundError(
+ error: Error & { code?: string }
+): boolean {
+ return (
+ "code" in error &&
+ error.code === PRISMA_QUERY_INTERPRETATION_ERROR &&
+ error.message.includes(PRISMA_RECORD_NOT_FOUND)
+ );
+}
+
+export async function transformStringFieldUpdateInput<
+ T extends undefined | string | { set?: string }
+>(input: T, transform: (input: string) => Promise): Promise {
+ if (typeof input === "object" && typeof input?.set === "string") {
+ return { set: await transform(input.set) } as T;
+ }
+ if (typeof input === "object") {
+ if (typeof input.set === "string") {
+ return { set: await transform(input.set) } as T;
+ }
+ return input;
+ }
+ if (typeof input === "string") {
+ return (await transform(input)) as T;
+ }
+ return input;
+}
diff --git a/platform/serv/src/prisma/prisma.module.ts b/platform/serv/src/prisma/prisma.module.ts
new file mode 100644
index 0000000..1edbf95
--- /dev/null
+++ b/platform/serv/src/prisma/prisma.module.ts
@@ -0,0 +1,9 @@
+import { Global, Module } from "@nestjs/common";
+import { PrismaService } from "./prisma.service";
+
+@Global()
+@Module({
+ providers: [PrismaService],
+ exports: [PrismaService],
+})
+export class PrismaModule {}
diff --git a/platform/serv/src/prisma/prisma.service.ts b/platform/serv/src/prisma/prisma.service.ts
new file mode 100644
index 0000000..3fb4081
--- /dev/null
+++ b/platform/serv/src/prisma/prisma.service.ts
@@ -0,0 +1,15 @@
+import { Injectable, OnModuleInit, INestApplication } from "@nestjs/common";
+import { PrismaClient } from "@prisma/client";
+
+@Injectable()
+export class PrismaService extends PrismaClient implements OnModuleInit {
+ async onModuleInit() {
+ await this.$connect();
+ }
+
+ async enableShutdownHooks(app: INestApplication) {
+ this.$on("beforeExit", async () => {
+ await app.close();
+ });
+ }
+}
diff --git a/platform/serv/src/providers/secrets/base/secretsManager.service.base.spec.ts b/platform/serv/src/providers/secrets/base/secretsManager.service.base.spec.ts
new file mode 100644
index 0000000..0b5a709
--- /dev/null
+++ b/platform/serv/src/providers/secrets/base/secretsManager.service.base.spec.ts
@@ -0,0 +1,39 @@
+import { ConfigService } from "@nestjs/config";
+import { mock } from "jest-mock-extended";
+import { SecretsManagerServiceBase } from "./secretsManager.service.base";
+
+describe("Testing the secrets manager base class", () => {
+ const SECRET_KEY = "SECRET_KEY";
+ const SECRET_VALUE = "SECRET_VALUE";
+ const configService = mock();
+ const secretsManagerServiceBase = new SecretsManagerServiceBase(
+ configService
+ );
+ beforeEach(() => {
+ configService.get.mockClear();
+ });
+ it("should return value from env", async () => {
+ //ARRANGE
+ configService.get.mockReturnValue(SECRET_VALUE);
+ //ACT
+ const result = await secretsManagerServiceBase.getSecret(SECRET_KEY);
+ //ASSERT
+ expect(result).toBe(SECRET_VALUE);
+ });
+ it("should return null for unknown keys", async () => {
+ //ARRANGE
+ configService.get.mockReturnValue(undefined);
+ //ACT
+ const result = await secretsManagerServiceBase.getSecret(SECRET_KEY);
+ //ASSERT
+ expect(result).toBeNull();
+ });
+ it("should throw error if dont get key", () => {
+ //@ts-ignore
+ return expect(secretsManagerServiceBase.getSecret()).rejects.toThrow();
+ });
+ it("should throw an exeption if getting null key", () => {
+ //@ts-ignore
+ return expect(secretsManagerServiceBase.getSecret(null)).rejects.toThrow();
+ });
+});
diff --git a/platform/serv/src/providers/secrets/base/secretsManager.service.base.ts b/platform/serv/src/providers/secrets/base/secretsManager.service.base.ts
new file mode 100644
index 0000000..18a340b
--- /dev/null
+++ b/platform/serv/src/providers/secrets/base/secretsManager.service.base.ts
@@ -0,0 +1,19 @@
+import { ConfigService } from "@nestjs/config";
+
+export interface ISecretsManager {
+ getSecret: (key: string) => Promise;
+}
+
+export class SecretsManagerServiceBase implements ISecretsManager {
+ constructor(protected readonly configService: ConfigService) {}
+ async getSecret(key: string): Promise {
+ if (!key) {
+ throw new Error("Didn't got the key");
+ }
+ const value = this.configService.get(key);
+ if (value) {
+ return value;
+ }
+ return null;
+ }
+}
diff --git a/platform/serv/src/providers/secrets/secretsManager.module.ts b/platform/serv/src/providers/secrets/secretsManager.module.ts
new file mode 100644
index 0000000..3a621e4
--- /dev/null
+++ b/platform/serv/src/providers/secrets/secretsManager.module.ts
@@ -0,0 +1,8 @@
+import { Module } from "@nestjs/common";
+import { SecretsManagerService } from "./secretsManager.service";
+
+@Module({
+ providers: [SecretsManagerService],
+ exports: [SecretsManagerService],
+})
+export class SecretsManagerModule {}
diff --git a/platform/serv/src/providers/secrets/secretsManager.service.ts b/platform/serv/src/providers/secrets/secretsManager.service.ts
new file mode 100644
index 0000000..89907c3
--- /dev/null
+++ b/platform/serv/src/providers/secrets/secretsManager.service.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@nestjs/common";
+import { ConfigService } from "@nestjs/config";
+import { SecretsManagerServiceBase } from "./base/secretsManager.service.base";
+
+@Injectable()
+export class SecretsManagerService extends SecretsManagerServiceBase {
+ constructor(protected readonly configService: ConfigService) {
+ super(configService);
+ }
+}
diff --git a/platform/serv/src/serveStaticOptions.service.ts b/platform/serv/src/serveStaticOptions.service.ts
new file mode 100644
index 0000000..390248b
--- /dev/null
+++ b/platform/serv/src/serveStaticOptions.service.ts
@@ -0,0 +1,39 @@
+import * as path from "path";
+import { Injectable, Logger } from "@nestjs/common";
+import { ConfigService } from "@nestjs/config";
+import {
+ ServeStaticModuleOptions,
+ ServeStaticModuleOptionsFactory,
+} from "@nestjs/serve-static";
+
+const SERVE_STATIC_ROOT_PATH_VAR = "SERVE_STATIC_ROOT_PATH";
+const DEFAULT_STATIC_MODULE_OPTIONS_LIST: ServeStaticModuleOptions[] = [
+ {
+ serveRoot: "/swagger",
+ rootPath: path.join(__dirname, "swagger"),
+ },
+];
+
+@Injectable()
+export class ServeStaticOptionsService
+ implements ServeStaticModuleOptionsFactory
+{
+ private readonly logger = new Logger(ServeStaticOptionsService.name);
+
+ constructor(private readonly configService: ConfigService) {}
+
+ createLoggerOptions(): ServeStaticModuleOptions[] {
+ const serveStaticRootPath = this.configService.get(
+ SERVE_STATIC_ROOT_PATH_VAR
+ );
+ if (serveStaticRootPath) {
+ const resolvedPath = path.resolve(serveStaticRootPath);
+ this.logger.log(`Serving static files from ${resolvedPath}`);
+ return [
+ ...DEFAULT_STATIC_MODULE_OPTIONS_LIST,
+ { rootPath: resolvedPath, exclude: ["/api*", "/graphql"] },
+ ];
+ }
+ return DEFAULT_STATIC_MODULE_OPTIONS_LIST;
+ }
+}
diff --git a/platform/serv/src/swagger.ts b/platform/serv/src/swagger.ts
new file mode 100644
index 0000000..a085a45
--- /dev/null
+++ b/platform/serv/src/swagger.ts
@@ -0,0 +1,20 @@
+import { DocumentBuilder, SwaggerCustomOptions } from "@nestjs/swagger";
+
+export const swaggerPath = "api";
+
+export const swaggerDocumentOptions = new DocumentBuilder()
+ .setTitle("The Platform")
+ .setDescription(
+ "The Bouncer-AI Controlled Creativity Wonderland\nCongratulations! You have stumbled upon the promised land of ideas - The Platform.\n\nI've always believed that creativity should never be held back by the constant need to clean up digital clutter.\nThat's why I built The Platform. It's a bustling space for ideas and their offspring,\nwrapped in an AI-controlled environment that's as clean as a freshly starched shirt.\n\nIt's essentially the sanctum where I can continue my customary chaotic creativity, while an army of diligent AI agents (think of them as charming, dutiful butlers) ensure that all the ensuing mess is taken care of. The main AI is the Bouncer, a robust system tasked with keeping the order intact while I dive headfirst into the sea of my ideas.\n\n## Congratulations! Your service resource is ready.\n \nPlease note that all endpoints are secured with JWT Bearer authentication.\nBy default, your service resource comes with one user with the username \"admin\" and password \"admin\".\nLearn more in [our docs](https://docs.amplication.com)"
+ )
+ .addBearerAuth()
+ .build();
+
+export const swaggerSetupOptions: SwaggerCustomOptions = {
+ swaggerOptions: {
+ persistAuthorization: true,
+ },
+ customCssUrl: "../swagger/swagger.css",
+ customfavIcon: "../swagger/favicon.png",
+ customSiteTitle: "The Platform",
+};
diff --git a/platform/serv/src/swagger/favicon.png b/platform/serv/src/swagger/favicon.png
new file mode 100644
index 0000000..a79882d
Binary files /dev/null and b/platform/serv/src/swagger/favicon.png differ
diff --git a/platform/serv/src/swagger/logo-amplication-white.svg b/platform/serv/src/swagger/logo-amplication-white.svg
new file mode 100644
index 0000000..0054cd4
--- /dev/null
+++ b/platform/serv/src/swagger/logo-amplication-white.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/serv/src/swagger/swagger.css b/platform/serv/src/swagger/swagger.css
new file mode 100644
index 0000000..3ff8e74
--- /dev/null
+++ b/platform/serv/src/swagger/swagger.css
@@ -0,0 +1,320 @@
+html,
+body {
+ background-color: #f4f4f7;
+}
+
+body {
+ margin: auto;
+ line-height: 1.6;
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+ color: #121242;
+}
+
+.swagger-ui {
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+}
+
+.swagger-ui button,
+.swagger-ui input,
+.swagger-ui optgroup,
+.swagger-ui select,
+.swagger-ui textarea,
+.swagger-ui .parameter__name,
+.swagger-ui .parameters-col_name > *,
+.swagger-ui label {
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+ font-weight: normal;
+ font-size: 12px;
+ outline: none;
+}
+
+.swagger-ui textarea {
+ border: 1px solid #d0d0d9;
+ min-height: 100px;
+}
+
+.swagger-ui input[type="email"],
+.swagger-ui input[type="file"],
+.swagger-ui input[type="password"],
+.swagger-ui input[type="search"],
+.swagger-ui input[type="text"],
+.swagger-ui textarea {
+ border-radius: 3px;
+}
+
+.swagger-ui input[disabled],
+.swagger-ui select[disabled],
+.swagger-ui textarea[disabled] {
+ background: #f4f4f7;
+ color: #b8b8c6;
+}
+
+.swagger-ui .btn {
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+ font-weight: 500;
+ box-shadow: none;
+ border: 1px solid #d0d0d9;
+ height: 28px;
+ border-radius: 14px;
+ background-color: #fff;
+ color: #7950ed;
+}
+
+.swagger-ui .btn:hover {
+ box-shadow: none;
+}
+
+/* topbar */
+
+.swagger-ui .topbar {
+ background-color: #7950ed;
+ height: 80px;
+ padding: 0;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.swagger-ui .topbar-wrapper a {
+ display: block;
+ width: 206px;
+ height: 35px;
+ background-image: url("logo-amplication-white.svg");
+ background-repeat: no-repeat;
+ background-size: contain;
+}
+
+.swagger-ui .topbar-wrapper img {
+ display: none;
+}
+
+/* title */
+.swagger-ui .info {
+ margin: 0;
+}
+
+.swagger-ui .info .title {
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+ font-size: 32px;
+ font-weight: 600;
+}
+
+.swagger-ui .information-container {
+ padding-top: 50px;
+ padding-bottom: 20px;
+ position: relative;
+}
+
+.swagger-ui .info .title small.version-stamp {
+ display: none;
+}
+
+.swagger-ui .info .title small {
+ background-color: #a787ff;
+}
+
+.swagger-ui .info .description p {
+ max-width: 1000px;
+ margin: 0;
+}
+
+.swagger-ui .info .description p,
+.swagger-ui .info .description a {
+ font-size: 1rem;
+}
+
+.swagger-ui .information-container section {
+ position: relative;
+}
+
+.swagger-ui .scheme-container {
+ box-shadow: none;
+ background-color: transparent;
+ position: relative;
+ margin: 0;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ padding: 0;
+}
+
+.swagger-ui .scheme-container .auth-wrapper {
+ justify-content: flex-start;
+}
+
+.swagger-ui .btn.authorize {
+ box-shadow: none;
+ border: 1px solid #d0d0d9;
+ height: 40px;
+ border-radius: 20px;
+ background-color: #fff;
+ color: #7950ed;
+}
+
+.swagger-ui .btn.authorize svg {
+ fill: #7950ed;
+}
+
+/* content */
+
+.swagger-ui .opblock-tag {
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+ font-size: 28px;
+ font-weight: 600;
+}
+
+.swagger-ui .opblock.is-open .opblock-summary {
+ border-color: #e7e7ec !important;
+ border-bottom: none;
+}
+
+.swagger-ui .opblock .opblock-section-header {
+ background-color: #fff;
+ border: none;
+ border-top: 1px solid #e7e7ec;
+ border-bottom: 1px solid #e7e7ec;
+ box-shadow: none;
+}
+
+.swagger-ui .opblock .tab-header .tab-item.active h4 span:after {
+ display: none;
+}
+
+.swagger-ui .opblock.opblock-post {
+ border: 1px solid #e7e7ec;
+ background: #f9f9fa;
+ box-shadow: none;
+ color: #fff;
+}
+
+.swagger-ui .opblock.opblock-post:hover,
+.swagger-ui .opblock.opblock-post.is-open {
+ border-color: #31c587;
+}
+
+.swagger-ui .opblock.opblock-post .opblock-summary-method {
+ background-color: #31c587;
+}
+
+.swagger-ui .opblock.opblock-get {
+ border: 1px solid #e7e7ec;
+ background: #f9f9fa;
+ box-shadow: none;
+}
+.swagger-ui .opblock.opblock-get:hover,
+.swagger-ui .opblock.opblock-get.is-open {
+ border-color: #20a4f3;
+}
+.swagger-ui .opblock.opblock-get .opblock-summary-method {
+ background-color: #20a4f3;
+}
+
+.swagger-ui .opblock.opblock-delete {
+ border: 1px solid #e7e7ec;
+ background: #f9f9fa;
+ box-shadow: none;
+}
+.swagger-ui .opblock.opblock-delete:hover,
+.swagger-ui .opblock.opblock-delete.is-open {
+ border-color: #e93c51;
+}
+.swagger-ui .opblock.opblock-delete .opblock-summary-method {
+ background-color: #e93c51;
+}
+
+.swagger-ui .opblock.opblock-patch {
+ border: 1px solid #e7e7ec;
+ background: #f9f9fa;
+ box-shadow: none;
+}
+.swagger-ui .opblock.opblock-patch:hover,
+.swagger-ui .opblock.opblock-patch.is-open {
+ border-color: #41cadd;
+}
+.swagger-ui .opblock.opblock-patch .opblock-summary-method {
+ background-color: #41cadd;
+}
+
+.swagger-ui .opblock-body pre {
+ background-color: #121242 !important;
+}
+
+.swagger-ui select,
+.swagger-ui .response-control-media-type--accept-controller select {
+ border: 1px solid #d0d0d9;
+ box-shadow: none;
+ outline: none;
+}
+
+/* models */
+
+.swagger-ui section.models {
+ background-color: #fff;
+ border: 1px solid #e7e7ec;
+}
+
+.swagger-ui section.models.is-open h4 {
+ border-bottom: 1px solid #e7e7ec;
+}
+
+.swagger-ui section.models .model-container,
+.swagger-ui section.models .model-container:hover {
+ background-color: #f4f4f7;
+ color: #121242;
+}
+
+.swagger-ui .model-title {
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+ font-weight: normal;
+ font-size: 15px;
+ color: #121242;
+}
+
+/* modal */
+
+.swagger-ui .dialog-ux .modal-ux-header h3,
+.swagger-ui .dialog-ux .modal-ux-content h4,
+.swagger-ui .dialog-ux .modal-ux-content h4 code {
+ font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
+ font-weight: normal;
+ font-size: 15px;
+ color: #121242;
+}
+
+.swagger-ui .dialog-ux .modal-ux-content .btn.authorize {
+ height: 28px;
+ border-radius: 14px;
+}
+
+.swagger-ui .auth-btn-wrapper {
+ display: flex;
+ flex-direction: row-reverse;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.swagger-ui .auth-btn-wrapper .btn-done {
+ border: none;
+ color: #121242;
+ margin-right: 0;
+}
+
+.swagger-ui .authorization__btn {
+ fill: #414168;
+}
diff --git a/platform/serv/src/tests/auth/basic/basic.strategy.spec.ts b/platform/serv/src/tests/auth/basic/basic.strategy.spec.ts
new file mode 100644
index 0000000..29ae042
--- /dev/null
+++ b/platform/serv/src/tests/auth/basic/basic.strategy.spec.ts
@@ -0,0 +1,37 @@
+import { UnauthorizedException } from "@nestjs/common";
+import { mock } from "jest-mock-extended";
+import { AuthService } from "../../../auth/auth.service";
+import { BasicStrategyBase } from "../../../auth/basic/base/basic.strategy.base";
+import { TEST_USER } from "../constants";
+
+describe("Testing the basicStrategyBase.validate()", () => {
+ const TEST_PASSWORD = "gabay";
+ const authService = mock();
+ const basicStrategy = new BasicStrategyBase(authService);
+ beforeEach(() => {
+ authService.validateUser.mockClear();
+ });
+ beforeAll(() => {
+ //ARRANGE
+ authService.validateUser
+ .calledWith(TEST_USER.username, TEST_PASSWORD)
+ .mockReturnValue(Promise.resolve(TEST_USER));
+ });
+ it("should return the user", async () => {
+ //ACT
+ const result = await basicStrategy.validate(
+ TEST_USER.username,
+ TEST_PASSWORD
+ );
+ //ASSERT
+ expect(result).toBe(TEST_USER);
+ });
+ it("should throw error if there is not valid user", async () => {
+ //ARRANGE
+ authService.validateUser.mockReturnValue(Promise.resolve(null));
+ //ACT
+ const result = basicStrategy.validate("noUsername", TEST_PASSWORD);
+ //ASSERT
+ return expect(result).rejects.toThrowError(UnauthorizedException);
+ });
+});
diff --git a/platform/serv/src/tests/auth/constants.ts b/platform/serv/src/tests/auth/constants.ts
new file mode 100644
index 0000000..98e4887
--- /dev/null
+++ b/platform/serv/src/tests/auth/constants.ts
@@ -0,0 +1,19 @@
+import { Credentials } from "../../auth/Credentials";
+import { UserInfo } from "../../auth/UserInfo";
+
+export const VALID_ID = "1";
+
+export const TEST_USER: UserInfo = {
+ id: "cl7qmjh4h0000tothyjqapgj5",
+ roles: ["User"],
+ username: "ofek",
+};
+export const SIGN_TOKEN = "SIGN_TOKEN";
+export const VALID_CREDENTIALS: Credentials = {
+ username: "Valid User",
+ password: "Valid User Password",
+};
+export const INVALID_CREDENTIALS: Credentials = {
+ username: "Invalid User",
+ password: "Invalid User Password",
+};
diff --git a/platform/serv/src/tests/auth/jwt/jwt.strategy.spec.ts b/platform/serv/src/tests/auth/jwt/jwt.strategy.spec.ts
new file mode 100644
index 0000000..cc701e1
--- /dev/null
+++ b/platform/serv/src/tests/auth/jwt/jwt.strategy.spec.ts
@@ -0,0 +1,27 @@
+import { UnauthorizedException } from "@nestjs/common";
+import { mock } from "jest-mock-extended";
+import { JwtStrategyBase } from "../../../auth/jwt/base/jwt.strategy.base";
+import { UserService } from "../../../user/user.service";
+import { TEST_USER } from "../constants";
+
+describe("Testing the jwtStrategyBase.validate()", () => {
+ const userService = mock();
+ const jwtStrategy = new JwtStrategyBase(userService, "Secrete");
+ beforeEach(() => {
+ userService.findOne.mockClear();
+ });
+ it("should throw UnauthorizedException where there is no user", async () => {
+ //ARRANGE
+ userService.findOne
+ .calledWith({ where: { username: TEST_USER.username } })
+ .mockReturnValue(Promise.resolve(null));
+ //ACT
+ const result = jwtStrategy.validate({
+ id: TEST_USER.id,
+ username: TEST_USER.username,
+ roles: TEST_USER.roles,
+ });
+ //ASSERT
+ return expect(result).rejects.toThrowError(UnauthorizedException);
+ });
+});
diff --git a/platform/serv/src/tests/auth/token.service.spec.ts b/platform/serv/src/tests/auth/token.service.spec.ts
new file mode 100644
index 0000000..5768a23
--- /dev/null
+++ b/platform/serv/src/tests/auth/token.service.spec.ts
@@ -0,0 +1,42 @@
+import { TokenServiceBase } from "../../auth/base/token.service.base";
+import {
+ INVALID_USERNAME_ERROR,
+ INVALID_PASSWORD_ERROR,
+} from "../../auth/constants";
+import { SIGN_TOKEN, VALID_CREDENTIALS, VALID_ID } from "./constants";
+
+describe("Testing the TokenServiceBase", () => {
+ let tokenServiceBase: TokenServiceBase;
+ beforeEach(() => {
+ tokenServiceBase = new TokenServiceBase();
+ });
+ describe("Testing the BasicTokenService.createToken()", () => {
+ it("should create valid token for given username and password", async () => {
+ expect(
+ await tokenServiceBase.createToken({
+ id: VALID_ID,
+ username: "admin",
+ password: "admin",
+ })
+ ).toBe("YWRtaW46YWRtaW4=");
+ });
+ it("should reject when username missing", () => {
+ const result = tokenServiceBase.createToken({
+ id: VALID_ID,
+ //@ts-ignore
+ username: null,
+ password: VALID_CREDENTIALS.password,
+ });
+ return expect(result).rejects.toBe(INVALID_USERNAME_ERROR);
+ });
+ it("should reject when password missing", () => {
+ const result = tokenServiceBase.createToken({
+ id: VALID_ID,
+ username: VALID_CREDENTIALS.username,
+ //@ts-ignore
+ password: null,
+ });
+ return expect(result).rejects.toBe(INVALID_PASSWORD_ERROR);
+ });
+ });
+});
diff --git a/platform/serv/src/tests/health/health.service.spec.ts b/platform/serv/src/tests/health/health.service.spec.ts
new file mode 100644
index 0000000..270b5a2
--- /dev/null
+++ b/platform/serv/src/tests/health/health.service.spec.ts
@@ -0,0 +1,36 @@
+import { mock } from "jest-mock-extended";
+import { PrismaService } from "../../prisma/prisma.service";
+import { HealthServiceBase } from "../../health/base/health.service.base";
+
+describe("Testing the HealthServiceBase", () => {
+ //ARRANGE
+ let prismaService: PrismaService;
+ let healthServiceBase: HealthServiceBase;
+
+ describe("Testing the isDbReady function in HealthServiceBase class", () => {
+ beforeEach(() => {
+ prismaService = mock();
+ healthServiceBase = new HealthServiceBase(prismaService);
+ });
+ it("should return true if allow connection to db", async () => {
+ //ARRANGE
+ prismaService.$queryRaw
+ //@ts-ignore
+ .mockReturnValue(Promise.resolve(true));
+ //ACT
+ const response = await healthServiceBase.isDbReady();
+ //ASSERT
+ expect(response).toBe(true);
+ });
+ it("should return false if db is not available", async () => {
+ //ARRANGE
+ prismaService.$queryRaw
+ //@ts-ignore
+ .mockReturnValue(Promise.reject(false));
+ //ACT
+ const response = await healthServiceBase.isDbReady();
+ //ASSERT
+ expect(response).toBe(false);
+ });
+ });
+});
diff --git a/platform/serv/src/types.ts b/platform/serv/src/types.ts
new file mode 100644
index 0000000..f762a5d
--- /dev/null
+++ b/platform/serv/src/types.ts
@@ -0,0 +1,3 @@
+import type { JsonValue } from "type-fest";
+
+export type InputJsonValue = Omit;
diff --git a/platform/serv/src/user/base/AiGatekeeperCreateNestedManyWithoutUsersInput.ts b/platform/serv/src/user/base/AiGatekeeperCreateNestedManyWithoutUsersInput.ts
new file mode 100644
index 0000000..749123f
--- /dev/null
+++ b/platform/serv/src/user/base/AiGatekeeperCreateNestedManyWithoutUsersInput.ts
@@ -0,0 +1,28 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { AiGatekeeperWhereUniqueInput } from "../../aiGatekeeper/base/AiGatekeeperWhereUniqueInput";
+import { ApiProperty } from "@nestjs/swagger";
+
+@InputType()
+class AiGatekeeperCreateNestedManyWithoutUsersInput {
+ @Field(() => [AiGatekeeperWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [AiGatekeeperWhereUniqueInput],
+ })
+ connect?: Array;
+}
+
+export { AiGatekeeperCreateNestedManyWithoutUsersInput as AiGatekeeperCreateNestedManyWithoutUsersInput };
diff --git a/platform/serv/src/user/base/AiGatekeeperUpdateManyWithoutUsersInput.ts b/platform/serv/src/user/base/AiGatekeeperUpdateManyWithoutUsersInput.ts
new file mode 100644
index 0000000..ba1b6fa
--- /dev/null
+++ b/platform/serv/src/user/base/AiGatekeeperUpdateManyWithoutUsersInput.ts
@@ -0,0 +1,46 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { AiGatekeeperWhereUniqueInput } from "../../aiGatekeeper/base/AiGatekeeperWhereUniqueInput";
+import { ApiProperty } from "@nestjs/swagger";
+
+@InputType()
+class AiGatekeeperUpdateManyWithoutUsersInput {
+ @Field(() => [AiGatekeeperWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [AiGatekeeperWhereUniqueInput],
+ })
+ connect?: Array;
+
+ @Field(() => [AiGatekeeperWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [AiGatekeeperWhereUniqueInput],
+ })
+ disconnect?: Array;
+
+ @Field(() => [AiGatekeeperWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [AiGatekeeperWhereUniqueInput],
+ })
+ set?: Array;
+}
+
+export { AiGatekeeperUpdateManyWithoutUsersInput as AiGatekeeperUpdateManyWithoutUsersInput };
diff --git a/platform/serv/src/user/base/CreateUserArgs.ts b/platform/serv/src/user/base/CreateUserArgs.ts
new file mode 100644
index 0000000..24817ac
--- /dev/null
+++ b/platform/serv/src/user/base/CreateUserArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { UserCreateInput } from "./UserCreateInput";
+
+@ArgsType()
+class CreateUserArgs {
+ @Field(() => UserCreateInput, { nullable: false })
+ data!: UserCreateInput;
+}
+
+export { CreateUserArgs as CreateUserArgs };
diff --git a/platform/serv/src/user/base/DeleteUserArgs.ts b/platform/serv/src/user/base/DeleteUserArgs.ts
new file mode 100644
index 0000000..3649def
--- /dev/null
+++ b/platform/serv/src/user/base/DeleteUserArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { UserWhereUniqueInput } from "./UserWhereUniqueInput";
+
+@ArgsType()
+class DeleteUserArgs {
+ @Field(() => UserWhereUniqueInput, { nullable: false })
+ where!: UserWhereUniqueInput;
+}
+
+export { DeleteUserArgs as DeleteUserArgs };
diff --git a/platform/serv/src/user/base/IdeaCollaboratorDevCreateNestedManyWithoutUsersInput.ts b/platform/serv/src/user/base/IdeaCollaboratorDevCreateNestedManyWithoutUsersInput.ts
new file mode 100644
index 0000000..8e48adb
--- /dev/null
+++ b/platform/serv/src/user/base/IdeaCollaboratorDevCreateNestedManyWithoutUsersInput.ts
@@ -0,0 +1,28 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { IdeaCollaboratorDevWhereUniqueInput } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDevWhereUniqueInput";
+import { ApiProperty } from "@nestjs/swagger";
+
+@InputType()
+class IdeaCollaboratorDevCreateNestedManyWithoutUsersInput {
+ @Field(() => [IdeaCollaboratorDevWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [IdeaCollaboratorDevWhereUniqueInput],
+ })
+ connect?: Array;
+}
+
+export { IdeaCollaboratorDevCreateNestedManyWithoutUsersInput as IdeaCollaboratorDevCreateNestedManyWithoutUsersInput };
diff --git a/platform/serv/src/user/base/IdeaCollaboratorDevUpdateManyWithoutUsersInput.ts b/platform/serv/src/user/base/IdeaCollaboratorDevUpdateManyWithoutUsersInput.ts
new file mode 100644
index 0000000..65472c4
--- /dev/null
+++ b/platform/serv/src/user/base/IdeaCollaboratorDevUpdateManyWithoutUsersInput.ts
@@ -0,0 +1,46 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { IdeaCollaboratorDevWhereUniqueInput } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDevWhereUniqueInput";
+import { ApiProperty } from "@nestjs/swagger";
+
+@InputType()
+class IdeaCollaboratorDevUpdateManyWithoutUsersInput {
+ @Field(() => [IdeaCollaboratorDevWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [IdeaCollaboratorDevWhereUniqueInput],
+ })
+ connect?: Array;
+
+ @Field(() => [IdeaCollaboratorDevWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [IdeaCollaboratorDevWhereUniqueInput],
+ })
+ disconnect?: Array;
+
+ @Field(() => [IdeaCollaboratorDevWhereUniqueInput], {
+ nullable: true,
+ })
+ @ApiProperty({
+ required: false,
+ type: () => [IdeaCollaboratorDevWhereUniqueInput],
+ })
+ set?: Array;
+}
+
+export { IdeaCollaboratorDevUpdateManyWithoutUsersInput as IdeaCollaboratorDevUpdateManyWithoutUsersInput };
diff --git a/platform/serv/src/user/base/UpdateUserArgs.ts b/platform/serv/src/user/base/UpdateUserArgs.ts
new file mode 100644
index 0000000..342f128
--- /dev/null
+++ b/platform/serv/src/user/base/UpdateUserArgs.ts
@@ -0,0 +1,24 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { UserWhereUniqueInput } from "./UserWhereUniqueInput";
+import { UserUpdateInput } from "./UserUpdateInput";
+
+@ArgsType()
+class UpdateUserArgs {
+ @Field(() => UserWhereUniqueInput, { nullable: false })
+ where!: UserWhereUniqueInput;
+ @Field(() => UserUpdateInput, { nullable: false })
+ data!: UserUpdateInput;
+}
+
+export { UpdateUserArgs as UpdateUserArgs };
diff --git a/platform/serv/src/user/base/User.ts b/platform/serv/src/user/base/User.ts
new file mode 100644
index 0000000..5f7b782
--- /dev/null
+++ b/platform/serv/src/user/base/User.ts
@@ -0,0 +1,122 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ObjectType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, IsDate, ValidateNested, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+import { AiGatekeeper } from "../../aiGatekeeper/base/AiGatekeeper";
+import { IsJSONValue } from "@app/custom-validators";
+import { GraphQLJSON } from "graphql-type-json";
+import { JsonValue } from "type-fest";
+import { IdeaCollaboratorDev } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDev";
+
+@ObjectType()
+class User {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ company!: string;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ createdAt!: Date;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ email!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ firstName!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ lastName!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ location!: string;
+
+ @ApiProperty({
+ required: false,
+ type: () => [AiGatekeeper],
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeper)
+ @IsOptional()
+ ownership?: Array;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsJSONValue()
+ @Field(() => GraphQLJSON)
+ roles!: JsonValue;
+
+ @ApiProperty({
+ required: false,
+ type: () => [IdeaCollaboratorDev],
+ })
+ @ValidateNested()
+ @Type(() => IdeaCollaboratorDev)
+ @IsOptional()
+ teamOwner?: Array;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsDate()
+ @Type(() => Date)
+ @Field(() => Date)
+ updatedAt!: Date;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ username!: string;
+}
+
+export { User as User };
diff --git a/platform/serv/src/user/base/UserCreateInput.ts b/platform/serv/src/user/base/UserCreateInput.ts
new file mode 100644
index 0000000..564b6a6
--- /dev/null
+++ b/platform/serv/src/user/base/UserCreateInput.ts
@@ -0,0 +1,112 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, ValidateNested, IsOptional } from "class-validator";
+import { AiGatekeeperCreateNestedManyWithoutUsersInput } from "./AiGatekeeperCreateNestedManyWithoutUsersInput";
+import { Type } from "class-transformer";
+import { IsJSONValue } from "@app/custom-validators";
+import { GraphQLJSON } from "graphql-type-json";
+import { InputJsonValue } from "../../types";
+import { IdeaCollaboratorDevCreateNestedManyWithoutUsersInput } from "./IdeaCollaboratorDevCreateNestedManyWithoutUsersInput";
+
+@InputType()
+class UserCreateInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ company!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ email!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ firstName!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ lastName!: string;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ location!: string;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperCreateNestedManyWithoutUsersInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperCreateNestedManyWithoutUsersInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperCreateNestedManyWithoutUsersInput, {
+ nullable: true,
+ })
+ ownership?: AiGatekeeperCreateNestedManyWithoutUsersInput;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ password!: string;
+
+ @ApiProperty({
+ required: true,
+ })
+ @IsJSONValue()
+ @Field(() => GraphQLJSON)
+ roles!: InputJsonValue;
+
+ @ApiProperty({
+ required: false,
+ type: () => IdeaCollaboratorDevCreateNestedManyWithoutUsersInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaCollaboratorDevCreateNestedManyWithoutUsersInput)
+ @IsOptional()
+ @Field(() => IdeaCollaboratorDevCreateNestedManyWithoutUsersInput, {
+ nullable: true,
+ })
+ teamOwner?: IdeaCollaboratorDevCreateNestedManyWithoutUsersInput;
+
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ username!: string;
+}
+
+export { UserCreateInput as UserCreateInput };
diff --git a/platform/serv/src/user/base/UserFindManyArgs.ts b/platform/serv/src/user/base/UserFindManyArgs.ts
new file mode 100644
index 0000000..11525da
--- /dev/null
+++ b/platform/serv/src/user/base/UserFindManyArgs.ts
@@ -0,0 +1,53 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { UserWhereInput } from "./UserWhereInput";
+import { Type } from "class-transformer";
+import { UserOrderByInput } from "./UserOrderByInput";
+
+@ArgsType()
+class UserFindManyArgs {
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereInput,
+ })
+ @Field(() => UserWhereInput, { nullable: true })
+ @Type(() => UserWhereInput)
+ where?: UserWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: [UserOrderByInput],
+ })
+ @Field(() => [UserOrderByInput], { nullable: true })
+ @Type(() => UserOrderByInput)
+ orderBy?: Array;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ skip?: number;
+
+ @ApiProperty({
+ required: false,
+ type: Number,
+ })
+ @Field(() => Number, { nullable: true })
+ @Type(() => Number)
+ take?: number;
+}
+
+export { UserFindManyArgs as UserFindManyArgs };
diff --git a/platform/serv/src/user/base/UserFindUniqueArgs.ts b/platform/serv/src/user/base/UserFindUniqueArgs.ts
new file mode 100644
index 0000000..b7810d2
--- /dev/null
+++ b/platform/serv/src/user/base/UserFindUniqueArgs.ts
@@ -0,0 +1,21 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { ArgsType, Field } from "@nestjs/graphql";
+import { UserWhereUniqueInput } from "./UserWhereUniqueInput";
+
+@ArgsType()
+class UserFindUniqueArgs {
+ @Field(() => UserWhereUniqueInput, { nullable: false })
+ where!: UserWhereUniqueInput;
+}
+
+export { UserFindUniqueArgs as UserFindUniqueArgs };
diff --git a/platform/serv/src/user/base/UserListRelationFilter.ts b/platform/serv/src/user/base/UserListRelationFilter.ts
new file mode 100644
index 0000000..0ff7d94
--- /dev/null
+++ b/platform/serv/src/user/base/UserListRelationFilter.ts
@@ -0,0 +1,56 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { UserWhereInput } from "./UserWhereInput";
+import { ValidateNested, IsOptional } from "class-validator";
+import { Type } from "class-transformer";
+
+@InputType()
+class UserListRelationFilter {
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereInput)
+ @IsOptional()
+ @Field(() => UserWhereInput, {
+ nullable: true,
+ })
+ every?: UserWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereInput)
+ @IsOptional()
+ @Field(() => UserWhereInput, {
+ nullable: true,
+ })
+ some?: UserWhereInput;
+
+ @ApiProperty({
+ required: false,
+ type: () => UserWhereInput,
+ })
+ @ValidateNested()
+ @Type(() => UserWhereInput)
+ @IsOptional()
+ @Field(() => UserWhereInput, {
+ nullable: true,
+ })
+ none?: UserWhereInput;
+}
+export { UserListRelationFilter as UserListRelationFilter };
diff --git a/platform/serv/src/user/base/UserOrderByInput.ts b/platform/serv/src/user/base/UserOrderByInput.ts
new file mode 100644
index 0000000..9240136
--- /dev/null
+++ b/platform/serv/src/user/base/UserOrderByInput.ts
@@ -0,0 +1,121 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { SortOrder } from "../../util/SortOrder";
+
+@InputType({
+ isAbstract: true,
+ description: undefined,
+})
+class UserOrderByInput {
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ company?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ createdAt?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ email?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ firstName?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ id?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ lastName?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ location?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ password?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ roles?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ updatedAt?: SortOrder;
+
+ @ApiProperty({
+ required: false,
+ enum: ["asc", "desc"],
+ })
+ @Field(() => SortOrder, {
+ nullable: true,
+ })
+ username?: SortOrder;
+}
+
+export { UserOrderByInput as UserOrderByInput };
diff --git a/platform/serv/src/user/base/UserUpdateInput.ts b/platform/serv/src/user/base/UserUpdateInput.ts
new file mode 100644
index 0000000..77b8bd0
--- /dev/null
+++ b/platform/serv/src/user/base/UserUpdateInput.ts
@@ -0,0 +1,136 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString, IsOptional, ValidateNested } from "class-validator";
+import { AiGatekeeperUpdateManyWithoutUsersInput } from "./AiGatekeeperUpdateManyWithoutUsersInput";
+import { Type } from "class-transformer";
+import { IsJSONValue } from "@app/custom-validators";
+import { GraphQLJSON } from "graphql-type-json";
+import { InputJsonValue } from "../../types";
+import { IdeaCollaboratorDevUpdateManyWithoutUsersInput } from "./IdeaCollaboratorDevUpdateManyWithoutUsersInput";
+
+@InputType()
+class UserUpdateInput {
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ company?: string;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ email?: string;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ firstName?: string;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ lastName?: string;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ location?: string;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperUpdateManyWithoutUsersInput,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperUpdateManyWithoutUsersInput)
+ @IsOptional()
+ @Field(() => AiGatekeeperUpdateManyWithoutUsersInput, {
+ nullable: true,
+ })
+ ownership?: AiGatekeeperUpdateManyWithoutUsersInput;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ password?: string;
+
+ @ApiProperty({
+ required: false,
+ })
+ @IsJSONValue()
+ @IsOptional()
+ @Field(() => GraphQLJSON, {
+ nullable: true,
+ })
+ roles?: InputJsonValue;
+
+ @ApiProperty({
+ required: false,
+ type: () => IdeaCollaboratorDevUpdateManyWithoutUsersInput,
+ })
+ @ValidateNested()
+ @Type(() => IdeaCollaboratorDevUpdateManyWithoutUsersInput)
+ @IsOptional()
+ @Field(() => IdeaCollaboratorDevUpdateManyWithoutUsersInput, {
+ nullable: true,
+ })
+ teamOwner?: IdeaCollaboratorDevUpdateManyWithoutUsersInput;
+
+ @ApiProperty({
+ required: false,
+ type: String,
+ })
+ @IsString()
+ @IsOptional()
+ @Field(() => String, {
+ nullable: true,
+ })
+ username?: string;
+}
+
+export { UserUpdateInput as UserUpdateInput };
diff --git a/platform/serv/src/user/base/UserWhereInput.ts b/platform/serv/src/user/base/UserWhereInput.ts
new file mode 100644
index 0000000..abe5ba9
--- /dev/null
+++ b/platform/serv/src/user/base/UserWhereInput.ts
@@ -0,0 +1,147 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { StringFilter } from "../../util/StringFilter";
+import { Type } from "class-transformer";
+import { IsOptional, ValidateNested } from "class-validator";
+import { DateTimeFilter } from "../../util/DateTimeFilter";
+import { AiGatekeeperListRelationFilter } from "../../aiGatekeeper/base/AiGatekeeperListRelationFilter";
+import { IdeaCollaboratorDevListRelationFilter } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDevListRelationFilter";
+
+@InputType()
+class UserWhereInput {
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ company?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: DateTimeFilter,
+ })
+ @Type(() => DateTimeFilter)
+ @IsOptional()
+ @Field(() => DateTimeFilter, {
+ nullable: true,
+ })
+ createdAt?: DateTimeFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ email?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ firstName?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ id?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ lastName?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ location?: StringFilter;
+
+ @ApiProperty({
+ required: false,
+ type: () => AiGatekeeperListRelationFilter,
+ })
+ @ValidateNested()
+ @Type(() => AiGatekeeperListRelationFilter)
+ @IsOptional()
+ @Field(() => AiGatekeeperListRelationFilter, {
+ nullable: true,
+ })
+ ownership?: AiGatekeeperListRelationFilter;
+
+ @ApiProperty({
+ required: false,
+ type: () => IdeaCollaboratorDevListRelationFilter,
+ })
+ @ValidateNested()
+ @Type(() => IdeaCollaboratorDevListRelationFilter)
+ @IsOptional()
+ @Field(() => IdeaCollaboratorDevListRelationFilter, {
+ nullable: true,
+ })
+ teamOwner?: IdeaCollaboratorDevListRelationFilter;
+
+ @ApiProperty({
+ required: false,
+ type: DateTimeFilter,
+ })
+ @Type(() => DateTimeFilter)
+ @IsOptional()
+ @Field(() => DateTimeFilter, {
+ nullable: true,
+ })
+ updatedAt?: DateTimeFilter;
+
+ @ApiProperty({
+ required: false,
+ type: StringFilter,
+ })
+ @Type(() => StringFilter)
+ @IsOptional()
+ @Field(() => StringFilter, {
+ nullable: true,
+ })
+ username?: StringFilter;
+}
+
+export { UserWhereInput as UserWhereInput };
diff --git a/platform/serv/src/user/base/UserWhereUniqueInput.ts b/platform/serv/src/user/base/UserWhereUniqueInput.ts
new file mode 100644
index 0000000..0bcea12
--- /dev/null
+++ b/platform/serv/src/user/base/UserWhereUniqueInput.ts
@@ -0,0 +1,27 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { InputType, Field } from "@nestjs/graphql";
+import { ApiProperty } from "@nestjs/swagger";
+import { IsString } from "class-validator";
+
+@InputType()
+class UserWhereUniqueInput {
+ @ApiProperty({
+ required: true,
+ type: String,
+ })
+ @IsString()
+ @Field(() => String)
+ id!: string;
+}
+
+export { UserWhereUniqueInput as UserWhereUniqueInput };
diff --git a/platform/serv/src/user/base/user.controller.base.spec.ts b/platform/serv/src/user/base/user.controller.base.spec.ts
new file mode 100644
index 0000000..cd0b0a2
--- /dev/null
+++ b/platform/serv/src/user/base/user.controller.base.spec.ts
@@ -0,0 +1,219 @@
+import { Test } from "@nestjs/testing";
+import {
+ INestApplication,
+ HttpStatus,
+ ExecutionContext,
+ CallHandler,
+} from "@nestjs/common";
+import request from "supertest";
+import { MorganModule } from "nest-morgan";
+import { ACGuard } from "nest-access-control";
+import { DefaultAuthGuard } from "../../auth/defaultAuth.guard";
+import { ACLModule } from "../../auth/acl.module";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { map } from "rxjs";
+import { UserController } from "../user.controller";
+import { UserService } from "../user.service";
+
+const nonExistingId = "nonExistingId";
+const existingId = "existingId";
+const CREATE_INPUT = {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ firstName: "exampleFirstName",
+ id: "exampleId",
+ lastName: "exampleLastName",
+ location: "exampleLocation",
+ password: "examplePassword",
+ updatedAt: new Date(),
+ username: "exampleUsername",
+};
+const CREATE_RESULT = {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ firstName: "exampleFirstName",
+ id: "exampleId",
+ lastName: "exampleLastName",
+ location: "exampleLocation",
+ password: "examplePassword",
+ updatedAt: new Date(),
+ username: "exampleUsername",
+};
+const FIND_MANY_RESULT = [
+ {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ firstName: "exampleFirstName",
+ id: "exampleId",
+ lastName: "exampleLastName",
+ location: "exampleLocation",
+ password: "examplePassword",
+ updatedAt: new Date(),
+ username: "exampleUsername",
+ },
+];
+const FIND_ONE_RESULT = {
+ company: "exampleCompany",
+ createdAt: new Date(),
+ email: "exampleEmail",
+ firstName: "exampleFirstName",
+ id: "exampleId",
+ lastName: "exampleLastName",
+ location: "exampleLocation",
+ password: "examplePassword",
+ updatedAt: new Date(),
+ username: "exampleUsername",
+};
+
+const service = {
+ create() {
+ return CREATE_RESULT;
+ },
+ findMany: () => FIND_MANY_RESULT,
+ findOne: ({ where }: { where: { id: string } }) => {
+ switch (where.id) {
+ case existingId:
+ return FIND_ONE_RESULT;
+ case nonExistingId:
+ return null;
+ }
+ },
+};
+
+const basicAuthGuard = {
+ canActivate: (context: ExecutionContext) => {
+ const argumentHost = context.switchToHttp();
+ const request = argumentHost.getRequest();
+ request.user = {
+ roles: ["user"],
+ };
+ return true;
+ },
+};
+
+const acGuard = {
+ canActivate: () => {
+ return true;
+ },
+};
+
+const aclFilterResponseInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle().pipe(
+ map((data) => {
+ return data;
+ })
+ );
+ },
+};
+const aclValidateRequestInterceptor = {
+ intercept: (context: ExecutionContext, next: CallHandler) => {
+ return next.handle();
+ },
+};
+
+describe("User", () => {
+ let app: INestApplication;
+
+ beforeAll(async () => {
+ const moduleRef = await Test.createTestingModule({
+ providers: [
+ {
+ provide: UserService,
+ useValue: service,
+ },
+ ],
+ controllers: [UserController],
+ imports: [MorganModule.forRoot(), ACLModule],
+ })
+ .overrideGuard(DefaultAuthGuard)
+ .useValue(basicAuthGuard)
+ .overrideGuard(ACGuard)
+ .useValue(acGuard)
+ .overrideInterceptor(AclFilterResponseInterceptor)
+ .useValue(aclFilterResponseInterceptor)
+ .overrideInterceptor(AclValidateRequestInterceptor)
+ .useValue(aclValidateRequestInterceptor)
+ .compile();
+
+ app = moduleRef.createNestApplication();
+ await app.init();
+ });
+
+ test("POST /users", async () => {
+ await request(app.getHttpServer())
+ .post("/users")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("GET /users", async () => {
+ await request(app.getHttpServer())
+ .get("/users")
+ .expect(HttpStatus.OK)
+ .expect([
+ {
+ ...FIND_MANY_RESULT[0],
+ createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(),
+ updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(),
+ },
+ ]);
+ });
+
+ test("GET /users/:id non existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/users"}/${nonExistingId}`)
+ .expect(HttpStatus.NOT_FOUND)
+ .expect({
+ statusCode: HttpStatus.NOT_FOUND,
+ message: `No resource was found for {"${"id"}":"${nonExistingId}"}`,
+ error: "Not Found",
+ });
+ });
+
+ test("GET /users/:id existing", async () => {
+ await request(app.getHttpServer())
+ .get(`${"/users"}/${existingId}`)
+ .expect(HttpStatus.OK)
+ .expect({
+ ...FIND_ONE_RESULT,
+ createdAt: FIND_ONE_RESULT.createdAt.toISOString(),
+ updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(),
+ });
+ });
+
+ test("POST /users existing resource", async () => {
+ let agent = request(app.getHttpServer());
+ await agent
+ .post("/users")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CREATED)
+ .expect({
+ ...CREATE_RESULT,
+ createdAt: CREATE_RESULT.createdAt.toISOString(),
+ updatedAt: CREATE_RESULT.updatedAt.toISOString(),
+ })
+ .then(function () {
+ agent
+ .post("/users")
+ .send(CREATE_INPUT)
+ .expect(HttpStatus.CONFLICT)
+ .expect({
+ statusCode: HttpStatus.CONFLICT,
+ });
+ });
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+});
diff --git a/platform/serv/src/user/base/user.controller.base.ts b/platform/serv/src/user/base/user.controller.base.ts
new file mode 100644
index 0000000..a37e149
--- /dev/null
+++ b/platform/serv/src/user/base/user.controller.base.ts
@@ -0,0 +1,439 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as common from "@nestjs/common";
+import * as swagger from "@nestjs/swagger";
+import { isRecordNotFoundError } from "../../prisma.util";
+import * as errors from "../../errors";
+import { Request } from "express";
+import { plainToClass } from "class-transformer";
+import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator";
+import * as nestAccessControl from "nest-access-control";
+import * as defaultAuthGuard from "../../auth/defaultAuth.guard";
+import { UserService } from "../user.service";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { UserCreateInput } from "./UserCreateInput";
+import { UserWhereInput } from "./UserWhereInput";
+import { UserWhereUniqueInput } from "./UserWhereUniqueInput";
+import { UserFindManyArgs } from "./UserFindManyArgs";
+import { UserUpdateInput } from "./UserUpdateInput";
+import { User } from "./User";
+import { AiGatekeeperFindManyArgs } from "../../aiGatekeeper/base/AiGatekeeperFindManyArgs";
+import { AiGatekeeper } from "../../aiGatekeeper/base/AiGatekeeper";
+import { AiGatekeeperWhereUniqueInput } from "../../aiGatekeeper/base/AiGatekeeperWhereUniqueInput";
+import { IdeaCollaboratorDevFindManyArgs } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDevFindManyArgs";
+import { IdeaCollaboratorDev } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDev";
+import { IdeaCollaboratorDevWhereUniqueInput } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDevWhereUniqueInput";
+
+@swagger.ApiBearerAuth()
+@common.UseGuards(defaultAuthGuard.DefaultAuthGuard, nestAccessControl.ACGuard)
+export class UserControllerBase {
+ constructor(
+ protected readonly service: UserService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Post()
+ @swagger.ApiCreatedResponse({ type: User })
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "create",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: UserCreateInput,
+ })
+ async create(@common.Body() data: UserCreateInput): Promise {
+ return await this.service.create({
+ data: data,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ firstName: true,
+ id: true,
+ lastName: true,
+ location: true,
+ roles: true,
+ updatedAt: true,
+ username: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get()
+ @swagger.ApiOkResponse({ type: [User] })
+ @ApiNestedQuery(UserFindManyArgs)
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "read",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findMany(@common.Req() request: Request): Promise {
+ const args = plainToClass(UserFindManyArgs, request.query);
+ return this.service.findMany({
+ ...args,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ firstName: true,
+ id: true,
+ lastName: true,
+ location: true,
+ roles: true,
+ updatedAt: true,
+ username: true,
+ },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get("/:id")
+ @swagger.ApiOkResponse({ type: User })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "read",
+ possession: "own",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async findOne(
+ @common.Param() params: UserWhereUniqueInput
+ ): Promise {
+ const result = await this.service.findOne({
+ where: params,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ firstName: true,
+ id: true,
+ lastName: true,
+ location: true,
+ roles: true,
+ updatedAt: true,
+ username: true,
+ },
+ });
+ if (result === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @common.Patch("/:id")
+ @swagger.ApiOkResponse({ type: User })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ @swagger.ApiBody({
+ type: UserUpdateInput,
+ })
+ async update(
+ @common.Param() params: UserWhereUniqueInput,
+ @common.Body() data: UserUpdateInput
+ ): Promise {
+ try {
+ return await this.service.update({
+ where: params,
+ data: data,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ firstName: true,
+ id: true,
+ lastName: true,
+ location: true,
+ roles: true,
+ updatedAt: true,
+ username: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.Delete("/:id")
+ @swagger.ApiOkResponse({ type: User })
+ @swagger.ApiNotFoundResponse({ type: errors.NotFoundException })
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "delete",
+ possession: "any",
+ })
+ @swagger.ApiForbiddenResponse({
+ type: errors.ForbiddenException,
+ })
+ async delete(
+ @common.Param() params: UserWhereUniqueInput
+ ): Promise {
+ try {
+ return await this.service.delete({
+ where: params,
+ select: {
+ company: true,
+ createdAt: true,
+ email: true,
+ firstName: true,
+ id: true,
+ lastName: true,
+ location: true,
+ roles: true,
+ updatedAt: true,
+ username: true,
+ },
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get("/:id/ownership")
+ @ApiNestedQuery(AiGatekeeperFindManyArgs)
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "any",
+ })
+ async findManyOwnership(
+ @common.Req() request: Request,
+ @common.Param() params: UserWhereUniqueInput
+ ): Promise {
+ const query = plainToClass(AiGatekeeperFindManyArgs, request.query);
+ const results = await this.service.findOwnership(params.id, {
+ ...query,
+ select: {
+ AIStatus: true,
+ createdAt: true,
+
+ createdBy: {
+ select: {
+ id: true,
+ },
+ },
+
+ id: true,
+ roles: true,
+ TasksCompleted: true,
+ updatedAt: true,
+ },
+ });
+ if (results === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return results;
+ }
+
+ @common.Post("/:id/ownership")
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ async connectOwnership(
+ @common.Param() params: UserWhereUniqueInput,
+ @common.Body() body: AiGatekeeperWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ ownership: {
+ connect: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+
+ @common.Patch("/:id/ownership")
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ async updateOwnership(
+ @common.Param() params: UserWhereUniqueInput,
+ @common.Body() body: AiGatekeeperWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ ownership: {
+ set: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+
+ @common.Delete("/:id/ownership")
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ async disconnectOwnership(
+ @common.Param() params: UserWhereUniqueInput,
+ @common.Body() body: AiGatekeeperWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ ownership: {
+ disconnect: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @common.Get("/:id/teamOwner")
+ @ApiNestedQuery(IdeaCollaboratorDevFindManyArgs)
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "read",
+ possession: "any",
+ })
+ async findManyTeamOwner(
+ @common.Req() request: Request,
+ @common.Param() params: UserWhereUniqueInput
+ ): Promise {
+ const query = plainToClass(IdeaCollaboratorDevFindManyArgs, request.query);
+ const results = await this.service.findTeamOwner(params.id, {
+ ...query,
+ select: {
+ createdAt: true,
+ email: true,
+ id: true,
+
+ inATeam: {
+ select: {
+ id: true,
+ },
+ },
+
+ location: true,
+ updatedAt: true,
+ },
+ });
+ if (results === null) {
+ throw new errors.NotFoundException(
+ `No resource was found for ${JSON.stringify(params)}`
+ );
+ }
+ return results;
+ }
+
+ @common.Post("/:id/teamOwner")
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ async connectTeamOwner(
+ @common.Param() params: UserWhereUniqueInput,
+ @common.Body() body: IdeaCollaboratorDevWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ teamOwner: {
+ connect: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+
+ @common.Patch("/:id/teamOwner")
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ async updateTeamOwner(
+ @common.Param() params: UserWhereUniqueInput,
+ @common.Body() body: IdeaCollaboratorDevWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ teamOwner: {
+ set: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+
+ @common.Delete("/:id/teamOwner")
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ async disconnectTeamOwner(
+ @common.Param() params: UserWhereUniqueInput,
+ @common.Body() body: IdeaCollaboratorDevWhereUniqueInput[]
+ ): Promise {
+ const data = {
+ teamOwner: {
+ disconnect: body,
+ },
+ };
+ await this.service.update({
+ where: params,
+ data,
+ select: { id: true },
+ });
+ }
+}
diff --git a/platform/serv/src/user/base/user.module.base.ts b/platform/serv/src/user/base/user.module.base.ts
new file mode 100644
index 0000000..76d29fe
--- /dev/null
+++ b/platform/serv/src/user/base/user.module.base.ts
@@ -0,0 +1,20 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { Module, forwardRef } from "@nestjs/common";
+import { MorganModule } from "nest-morgan";
+import { ACLModule } from "../../auth/acl.module";
+import { AuthModule } from "../../auth/auth.module";
+@Module({
+ imports: [ACLModule, forwardRef(() => AuthModule), MorganModule],
+ exports: [ACLModule, AuthModule, MorganModule],
+})
+export class UserModuleBase {}
diff --git a/platform/serv/src/user/base/user.resolver.base.ts b/platform/serv/src/user/base/user.resolver.base.ts
new file mode 100644
index 0000000..5917e74
--- /dev/null
+++ b/platform/serv/src/user/base/user.resolver.base.ts
@@ -0,0 +1,181 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import * as graphql from "@nestjs/graphql";
+import * as apollo from "apollo-server-express";
+import { isRecordNotFoundError } from "../../prisma.util";
+import { MetaQueryPayload } from "../../util/MetaQueryPayload";
+import * as nestAccessControl from "nest-access-control";
+import * as gqlACGuard from "../../auth/gqlAC.guard";
+import { GqlDefaultAuthGuard } from "../../auth/gqlDefaultAuth.guard";
+import * as common from "@nestjs/common";
+import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor";
+import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor";
+import { CreateUserArgs } from "./CreateUserArgs";
+import { UpdateUserArgs } from "./UpdateUserArgs";
+import { DeleteUserArgs } from "./DeleteUserArgs";
+import { UserFindManyArgs } from "./UserFindManyArgs";
+import { UserFindUniqueArgs } from "./UserFindUniqueArgs";
+import { User } from "./User";
+import { AiGatekeeperFindManyArgs } from "../../aiGatekeeper/base/AiGatekeeperFindManyArgs";
+import { AiGatekeeper } from "../../aiGatekeeper/base/AiGatekeeper";
+import { IdeaCollaboratorDevFindManyArgs } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDevFindManyArgs";
+import { IdeaCollaboratorDev } from "../../ideaCollaboratorDev/base/IdeaCollaboratorDev";
+import { UserService } from "../user.service";
+@common.UseGuards(GqlDefaultAuthGuard, gqlACGuard.GqlACGuard)
+@graphql.Resolver(() => User)
+export class UserResolverBase {
+ constructor(
+ protected readonly service: UserService,
+ protected readonly rolesBuilder: nestAccessControl.RolesBuilder
+ ) {}
+
+ @graphql.Query(() => MetaQueryPayload)
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "read",
+ possession: "any",
+ })
+ async _usersMeta(
+ @graphql.Args() args: UserFindManyArgs
+ ): Promise {
+ const results = await this.service.count({
+ ...args,
+ skip: undefined,
+ take: undefined,
+ });
+ return {
+ count: results,
+ };
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => [User])
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "read",
+ possession: "any",
+ })
+ async users(@graphql.Args() args: UserFindManyArgs): Promise {
+ return this.service.findMany(args);
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.Query(() => User, { nullable: true })
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "read",
+ possession: "own",
+ })
+ async user(@graphql.Args() args: UserFindUniqueArgs): Promise {
+ const result = await this.service.findOne(args);
+ if (result === null) {
+ return null;
+ }
+ return result;
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => User)
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "create",
+ possession: "any",
+ })
+ async createUser(@graphql.Args() args: CreateUserArgs): Promise {
+ return await this.service.create({
+ ...args,
+ data: args.data,
+ });
+ }
+
+ @common.UseInterceptors(AclValidateRequestInterceptor)
+ @graphql.Mutation(() => User)
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "update",
+ possession: "any",
+ })
+ async updateUser(@graphql.Args() args: UpdateUserArgs): Promise {
+ try {
+ return await this.service.update({
+ ...args,
+ data: args.data,
+ });
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @graphql.Mutation(() => User)
+ @nestAccessControl.UseRoles({
+ resource: "User",
+ action: "delete",
+ possession: "any",
+ })
+ async deleteUser(@graphql.Args() args: DeleteUserArgs): Promise {
+ try {
+ return await this.service.delete(args);
+ } catch (error) {
+ if (isRecordNotFoundError(error)) {
+ throw new apollo.ApolloError(
+ `No resource was found for ${JSON.stringify(args.where)}`
+ );
+ }
+ throw error;
+ }
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.ResolveField(() => [AiGatekeeper], { name: "ownership" })
+ @nestAccessControl.UseRoles({
+ resource: "AiGatekeeper",
+ action: "read",
+ possession: "any",
+ })
+ async resolveFieldOwnership(
+ @graphql.Parent() parent: User,
+ @graphql.Args() args: AiGatekeeperFindManyArgs
+ ): Promise {
+ const results = await this.service.findOwnership(parent.id, args);
+
+ if (!results) {
+ return [];
+ }
+
+ return results;
+ }
+
+ @common.UseInterceptors(AclFilterResponseInterceptor)
+ @graphql.ResolveField(() => [IdeaCollaboratorDev], { name: "teamOwner" })
+ @nestAccessControl.UseRoles({
+ resource: "IdeaCollaboratorDev",
+ action: "read",
+ possession: "any",
+ })
+ async resolveFieldTeamOwner(
+ @graphql.Parent() parent: User,
+ @graphql.Args() args: IdeaCollaboratorDevFindManyArgs
+ ): Promise {
+ const results = await this.service.findTeamOwner(parent.id, args);
+
+ if (!results) {
+ return [];
+ }
+
+ return results;
+ }
+}
diff --git a/platform/serv/src/user/base/user.service.base.ts b/platform/serv/src/user/base/user.service.base.ts
new file mode 100644
index 0000000..a96ee0d
--- /dev/null
+++ b/platform/serv/src/user/base/user.service.base.ts
@@ -0,0 +1,101 @@
+/*
+------------------------------------------------------------------------------
+This code was generated by Amplication.
+
+Changes to this file will be lost if the code is regenerated.
+
+There are other ways to to customize your code, see this doc to learn more
+https://docs.amplication.com/how-to/custom-code
+
+------------------------------------------------------------------------------
+ */
+import { PrismaService } from "../../prisma/prisma.service";
+import {
+ Prisma,
+ User,
+ AiGatekeeper,
+ IdeaCollaboratorDev,
+} from "@prisma/client";
+import { PasswordService } from "../../auth/password.service";
+import { transformStringFieldUpdateInput } from "../../prisma.util";
+
+export class UserServiceBase {
+ constructor(
+ protected readonly prisma: PrismaService,
+ protected readonly passwordService: PasswordService
+ ) {}
+
+ async count(
+ args: Prisma.SelectSubset
+ ): Promise {
+ return this.prisma.user.count(args);
+ }
+
+ async findMany(
+ args: Prisma.SelectSubset