From b94f0233bc133474437a9d0f4d300ef04aea76f7 Mon Sep 17 00:00:00 2001 From: jonmatthis Date: Tue, 9 Jan 2024 11:45:08 -0500 Subject: [PATCH 1/2] ignore openai env --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f718383..45c2b11 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,5 @@ lerna-debug.log* !.vscode/extensions.json .env.slack -.env.discord \ No newline at end of file +.env.discord +/.env.openai From 8209d36b9e7ad22f9156f8cac6f6109f9c762634 Mon Sep 17 00:00:00 2001 From: jonmatthis Date: Sat, 13 Jan 2024 14:28:48 -0500 Subject: [PATCH 2/2] fix duplicating user db entries bug --- package-lock.json | 29 +++++++++++++++ package.json | 1 + src/core/database/schema/users/user.dto.ts | 34 +++++++++++++++--- src/core/database/schema/users/user.schema.ts | 35 +++++++------------ .../database/schema/users/users.service.ts | 31 +++++++--------- 5 files changed, 85 insertions(+), 45 deletions(-) diff --git a/package-lock.json b/package-lock.json index e71a24e..1f9fe7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@slack/bolt": "^3.17.0", "bson": "^6.2.0", "bufferutil": "^4.0.8", + "class-validator": "^0.14.1", "discord.js": "^14.14.1", "langchain": "^0.0.209", "mongodb": "^5.9.2", @@ -3232,6 +3233,11 @@ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==" }, + "node_modules/@types/validator": { + "version": "13.11.8", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.8.tgz", + "integrity": "sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ==" + }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", @@ -4530,6 +4536,16 @@ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", "dev": true }, + "node_modules/class-validator": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz", + "integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==", + "dependencies": { + "@types/validator": "^13.11.8", + "libphonenumber-js": "^1.10.53", + "validator": "^13.9.0" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -8984,6 +9000,11 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.10.53", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.53.tgz", + "integrity": "sha512-sDTnnqlWK4vH4AlDQuswz3n4Hx7bIQWTpIcScJX+Sp7St3LXHmfiax/ZFfyYxHmkdCvydOLSuvtAO/XpXiSySw==" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -12361,6 +12382,14 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index a432713..e6fa9f0 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@slack/bolt": "^3.17.0", "bson": "^6.2.0", "bufferutil": "^4.0.8", + "class-validator": "^0.14.1", "discord.js": "^14.14.1", "langchain": "^0.0.209", "mongodb": "^5.9.2", diff --git a/src/core/database/schema/users/user.dto.ts b/src/core/database/schema/users/user.dto.ts index 1fba53f..e77122d 100644 --- a/src/core/database/schema/users/user.dto.ts +++ b/src/core/database/schema/users/user.dto.ts @@ -1,6 +1,32 @@ +import { IS_UUID, IsOptional, IsString, IsUUID } from 'class-validator'; + +class DiscordIdentifierDto { + @IsString() + @IsOptional() + id?: string; + + @IsString() + @IsOptional() + username?: string; +} + +class SlackIdentifierDto { + @IsString() + @IsOptional() + id?: string; + + @IsString() + @IsOptional() + username?: string; +} + export class UserDto { - readonly favoriteColor?: string; - readonly slackID?: string; - readonly discordId?: string; - readonly metadata?: object; + @IsOptional() + identifiers?: { + discord?: DiscordIdentifierDto; + slack?: SlackIdentifierDto; + }; + + @IsOptional() + metadata?: Record; } diff --git a/src/core/database/schema/users/user.schema.ts b/src/core/database/schema/users/user.schema.ts index f64b24a..d45464d 100644 --- a/src/core/database/schema/users/user.schema.ts +++ b/src/core/database/schema/users/user.schema.ts @@ -1,35 +1,26 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { IsUUID } from 'class-validator'; @Schema({ timestamps: true }) export class User { @Prop({ required: true, unique: true }) + @IsUUID() uuid: string; - @Prop({ required: true }) - favoriteColor: string; - - @Prop({ unique: true }) - discordId: string; - - @Prop({ unique: true }) - slackId: string; + @Prop({ type: Object }) + identifiers?: { + discord?: { + id: string; + username: string; + }; + slack?: { + id: string; + username: string; + }; + }; @Prop({ type: Object }) metadata: Record; } export const UserSchema = SchemaFactory.createForClass(User); - -function validateFavoriteColor(color: string) { - const regex = /^([A-Fa-f0-9]{6})$/; - return regex.test(`${color}`); -} - -UserSchema.pre('save', function (next) { - if (!validateFavoriteColor(this.favoriteColor)) { - throw new Error( - 'User.favoriteColor should be a valid 6 digit hex color code (e.g. FF00FF)', - ); - } - next(); -}); diff --git a/src/core/database/schema/users/users.service.ts b/src/core/database/schema/users/users.service.ts index 90bd524..6c62787 100644 --- a/src/core/database/schema/users/users.service.ts +++ b/src/core/database/schema/users/users.service.ts @@ -18,46 +18,39 @@ export class UsersService { async findOne(userDto: UserDto): Promise { let user: User; - if (userDto.discordId) { + if ('discord' in userDto.identifiers && userDto.identifiers.discord.id) { user = await this.userModel - .findOne({ discordId: userDto.discordId }) + .findOne({ 'identifiers.discord.id': userDto.identifiers.discord.id }) + .exec(); + } + if ('slack' in userDto.identifiers && userDto.identifiers.slack.id) { + user = await this.userModel + .findOne({ 'identifiers.slack.id': userDto.identifiers.slack.id }) .exec(); - } else if (userDto.slackID) { - user = await this.userModel.findOne({ slackID: userDto.slackID }).exec(); } return user; } - async getOrCreate(userDto: UserDto): Promise { + public async getOrCreateUser(userDto: UserDto): Promise { const existingUser = await this.findOne(userDto); if (existingUser) { return existingUser; } - return this.create(userDto); - } - - _generateHexColorId() { - const letters = '0123456789ABCDEF'; - let color = ''; - const digits = 6; - for (let i = 0; i < digits; i++) { - color += letters[Math.floor(Math.random() * 16)]; - } - return color; + return this._createUser(userDto); } - async create(userDto: UserDto): Promise { + async _createUser(userDto: UserDto): Promise { if (await this.findOne(userDto)) { throw new HttpException('User ID already exists', HttpStatus.CONFLICT); } const createdUser = new this.userModel({ - ...userDto, + identifiers: userDto.identifiers, + metadata: userDto.metadata || {}, uuid: uuidv4(), - favoriteColor: this._generateHexColorId() || userDto.favoriteColor, }); return createdUser.save(); }