-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
431c83f
commit 4ed9d3c
Showing
102 changed files
with
1,691 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import { database } from '~/common/database/database.js'; | ||
export default database.environmentsConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { userSignInValidationSchema, } from '~/bundles/users/users.js'; | ||
import { userSignUpValidationSchema } from '~/bundles/users/users.js'; | ||
import { BaseController, } from '~/common/controller/controller.js'; | ||
import { ApiPath } from '~/common/enums/enums.js'; | ||
import { HttpCode } from '~/common/http/http.js'; | ||
import { AuthApiPath } from './enums/enums.js'; | ||
class AuthController extends BaseController { | ||
authService; | ||
constructor(logger, authService) { | ||
super(logger, ApiPath.AUTH); | ||
this.authService = authService; | ||
this.addRoute({ | ||
path: AuthApiPath.SIGN_IN, | ||
method: 'POST', | ||
validation: { | ||
body: userSignInValidationSchema, | ||
}, | ||
handler: (options) => this.signIn(options), | ||
}); | ||
this.addRoute({ | ||
path: AuthApiPath.SIGN_UP, | ||
method: 'POST', | ||
validation: { | ||
body: userSignUpValidationSchema, | ||
}, | ||
handler: (options) => this.signUp(options), | ||
}); | ||
} | ||
/** | ||
* @swagger | ||
* /auth/sign-in: | ||
* post: | ||
* description: Sign in user into the application | ||
* requestBody: | ||
* description: User auth data | ||
* required: true | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* required: [email, password] | ||
* properties: | ||
* email: | ||
* type: string | ||
* format: email | ||
* password: | ||
* type: string | ||
* responses: | ||
* 200: | ||
* description: Successful operation | ||
* content: | ||
* application/json: | ||
* schema: | ||
* $ref: '#/components/schemas/User' | ||
* 401: | ||
* description: Failed operation. Unauthorized. | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* $ref: '#/components/schemas/Error' | ||
*/ | ||
async signIn(options) { | ||
return { | ||
payload: await this.authService.signIn(options.body), | ||
status: HttpCode.OK, | ||
}; | ||
} | ||
/** | ||
* @swagger | ||
* /auth/sign-up: | ||
* post: | ||
* description: Sign up user into the application | ||
* requestBody: | ||
* description: User auth data | ||
* required: true | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* required: [fullName, email, password, confirmPassword] | ||
* properties: | ||
* fullName: | ||
* type: string | ||
* email: | ||
* type: string | ||
* format: email | ||
* password: | ||
* type: string | ||
* confirmPassword: | ||
* type: string | ||
* responses: | ||
* 201: | ||
* description: Successful operation | ||
* content: | ||
* application/json: | ||
* schema: | ||
* $ref: '#/components/schemas/User' | ||
* 400: | ||
* description: Failed operation | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* $ref: '#/components/schemas/Error' | ||
*/ | ||
async signUp(options) { | ||
return { | ||
status: HttpCode.CREATED, | ||
payload: await this.authService.signUp(options.body), | ||
}; | ||
} | ||
} | ||
export { AuthController }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { userService } from '~/bundles/users/users.js'; | ||
import { logger } from '~/common/logger/logger.js'; | ||
import { AuthController } from './auth.controller.js'; | ||
import { AuthService } from './auth.service.js'; | ||
const authService = new AuthService(userService); | ||
const authController = new AuthController(logger, authService); | ||
export { authController, authService }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { HttpCode, HttpError } from '~/common/http/http.js'; | ||
import { cryptService, tokenService } from '~/common/services/services.js'; | ||
import { UserValidationMessage } from './enums/enums.js'; | ||
class AuthService { | ||
userService; | ||
constructor(userService) { | ||
this.userService = userService; | ||
} | ||
async signIn(userRequestDto) { | ||
const { email, password } = userRequestDto; | ||
const user = await this.userService.findByEmail(email); | ||
if (!user) { | ||
throw new HttpError({ | ||
message: UserValidationMessage.WRONG_CREDENTIALS, | ||
status: HttpCode.BAD_REQUEST, | ||
}); | ||
} | ||
const { passwordHash } = user.toNewObject(); | ||
const isPwdCorrect = cryptService.compareSyncPassword(password, passwordHash); | ||
if (!isPwdCorrect) { | ||
throw new HttpError({ | ||
message: UserValidationMessage.WRONG_CREDENTIALS, | ||
status: HttpCode.BAD_REQUEST, | ||
}); | ||
} | ||
const userObject = user.toObject(); | ||
const { id } = userObject; | ||
const token = await tokenService.createToken(id); | ||
return { ...userObject, token }; | ||
} | ||
async signUp(userRequestDto) { | ||
const { email } = userRequestDto; | ||
const emailExists = await this.userService.findByEmail(email); | ||
if (emailExists) { | ||
throw new HttpError({ | ||
message: UserValidationMessage.EMAIL_ALREADY_EXISTS, | ||
status: HttpCode.BAD_REQUEST, | ||
}); | ||
} | ||
const user = await this.userService.create(userRequestDto); | ||
const { id } = user; | ||
const token = await tokenService.createToken(id); | ||
return { ...user, token }; | ||
} | ||
} | ||
export { AuthService }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { AuthApiPath, UserValidationMessage } from 'shared'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { BaseController, } from '~/common/controller/controller.js'; | ||
import { ApiPath } from '~/common/enums/enums.js'; | ||
import { HttpCode, HTTPMethod } from '~/common/http/http.js'; | ||
import { MAX_TOKEN } from '~/common/services/open-ai/libs/constants/constants.js'; | ||
import { ChatPath, OpenAIRole, } from '~/common/services/open-ai/libs/enums/enums.js'; | ||
import { textGenerationValidationSchema } from './libs/validation-schemas/validation-schemas.js'; | ||
class ChatController extends BaseController { | ||
openAIService; | ||
chatService; | ||
constructor(logger, openAIService, chatService) { | ||
super(logger, ApiPath.CHAT); | ||
this.openAIService = openAIService; | ||
this.chatService = chatService; | ||
this.addRoute({ | ||
path: ChatPath.ROOT, | ||
method: HTTPMethod.POST, | ||
validation: { | ||
body: textGenerationValidationSchema, | ||
}, | ||
handler: (options) => this.generateChatAnswer(options), | ||
}); | ||
this.addRoute({ | ||
path: ChatPath.ROOT, | ||
method: HTTPMethod.DELETE, | ||
handler: (options) => this.deleteSession(options), | ||
}); | ||
} | ||
/** | ||
* @swagger | ||
* /chat/: | ||
* post: | ||
* description: Returns generated text by Open AI | ||
* requestBody: | ||
* description: User message | ||
* required: true | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* message: | ||
* type: string | ||
* responses: | ||
* 200: | ||
* description: Successful operation | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* generatedText: | ||
* type: string | ||
*/ | ||
async generateChatAnswer(options) { | ||
const { body, session } = options; | ||
session.chatHistory = this.chatService.addMessageToHistory(session.chatHistory, body.message, OpenAIRole.USER); | ||
session.chatHistory = this.chatService.deleteOldMessages(session.chatHistory, MAX_TOKEN); | ||
const generatedText = await this.openAIService.generateText(session.chatHistory); | ||
session.chatHistory = this.chatService.addMessageToHistory(session.chatHistory, generatedText, OpenAIRole.ASSISTANT); | ||
return { | ||
payload: { generatedText }, | ||
status: HttpCode.OK, | ||
}; | ||
} | ||
/** | ||
* @swagger | ||
* /chat/: | ||
* delete: | ||
* description: Clears chat history | ||
* requestBody: | ||
* description: User message | ||
* required: false | ||
* responses: | ||
* 200: | ||
* description: Successful operation | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* isDeleted: | ||
* type: boolean | ||
* 500: | ||
* description: Failed operation | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* isDeleted: | ||
* type: boolean | ||
*/ | ||
deleteSession(options) { | ||
const { session } = options; | ||
session.destroy((error) => { | ||
if (error) { | ||
return { | ||
payload: { isDeleted: false }, | ||
status: HttpCode.INTERNAL_SERVER_ERROR, | ||
}; | ||
} | ||
}); | ||
return { | ||
payload: { isDeleted: true }, | ||
status: HttpCode.OK, | ||
}; | ||
} | ||
} | ||
export { ChatController }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { logger } from '~/common/logger/logger.js'; | ||
import { openAIService } from '~/common/services/services.js'; | ||
import { ChatController } from './chat.controller.js'; | ||
import { ChatService } from './chat.service.js'; | ||
const chatService = new ChatService(); | ||
const chatController = new ChatController(logger, openAIService, chatService); | ||
export { chatController }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { encoding_for_model } from 'tiktoken'; | ||
import { CHAT_MODEL } from '~/common/services/open-ai/libs/constants/constants.js'; | ||
class ChatService { | ||
modelEncoding; | ||
constructor() { | ||
this.modelEncoding = encoding_for_model(CHAT_MODEL); | ||
} | ||
addMessageToHistory(chatHistory, userMessage, role) { | ||
const newUserMessage = { | ||
content: userMessage, | ||
role, | ||
}; | ||
return [...chatHistory, newUserMessage]; | ||
} | ||
countTokens(messages) { | ||
return messages.reduce((sum, message) => sum + this.modelEncoding.encode(message.content).length, 0); | ||
} | ||
deleteOldMessages(messages, maxTokens) { | ||
let totalTokens = this.countTokens(messages); | ||
let updatedMessages = [...messages]; | ||
while (totalTokens > maxTokens && updatedMessages.length > 0) { | ||
const [removedMessage, ...rest] = updatedMessages; | ||
updatedMessages = rest; | ||
if (!removedMessage) { | ||
break; | ||
} | ||
totalTokens -= this.modelEncoding.encode(removedMessage.content).length; | ||
} | ||
return updatedMessages; | ||
} | ||
} | ||
export { ChatService }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
1 change: 1 addition & 0 deletions
1
backend/src/bundles/chat/libs/validation-schemas/validation-schemas.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { textGenerationValidationSchema } from 'shared'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { UsersApiPath } from 'shared'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { BaseController, } from '~/common/controller/controller.js'; | ||
import { ApiPath } from '~/common/enums/enums.js'; | ||
import { HttpCode } from '~/common/http/http.js'; | ||
import { UsersApiPath } from './enums/enums.js'; | ||
/** | ||
* @swagger | ||
* components: | ||
* schemas: | ||
* User: | ||
* type: object | ||
* properties: | ||
* id: | ||
* type: string | ||
* format: uuid | ||
* email: | ||
* type: string | ||
* format: email | ||
* fullName: | ||
* type: string | ||
*/ | ||
class UserController extends BaseController { | ||
userService; | ||
constructor(logger, userService) { | ||
super(logger, ApiPath.USERS); | ||
this.userService = userService; | ||
this.addRoute({ | ||
path: UsersApiPath.ROOT, | ||
method: 'GET', | ||
handler: () => this.findAll(), | ||
}); | ||
} | ||
/** | ||
* @swagger | ||
* /users: | ||
* get: | ||
* description: Returns an array of users | ||
* responses: | ||
* 200: | ||
* description: Successful operation | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* items: | ||
* type: array | ||
* items: | ||
* $ref: '#/components/schemas/User' | ||
*/ | ||
async findAll() { | ||
return { | ||
status: HttpCode.OK, | ||
payload: await this.userService.findAll(), | ||
}; | ||
} | ||
} | ||
export { UserController }; |
Oops, something went wrong.