Skip to content

Commit

Permalink
Merge pull request #10 from waterbustech/fix/chat
Browse files Browse the repository at this point in the history
Fix/chat
  • Loading branch information
lambiengcode authored Oct 26, 2024
2 parents 75f7f26 + b3be79c commit f07b340
Show file tree
Hide file tree
Showing 51 changed files with 3,007 additions and 1,295 deletions.
Binary file added bun.lockb
Binary file not shown.
45 changes: 0 additions & 45 deletions example.env

This file was deleted.

15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,25 @@
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"migration:run": "npm run typeorm -- --dataSource=src/core/database/data-source.ts migration:run",
"migration:rollback": "npm run typeorm -- --dataSource=src/core/database/data-source.ts migration:revert",
"pm2": "yarn build && yarn pm2:start",
"pm2:start": "pm2 start ecosystem.config.js"
},
"dependencies": {
"@fastify/static": "^7.0.3",
"@grpc/grpc-js": "^1.10.6",
"@grpc/proto-loader": "^0.7.12",
"@nestjs/common": "^10.3.8",
"@nestjs/common": "^10.4.4",
"@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.3.8",
"@nestjs/core": "^10.4.4",
"@nestjs/jwt": "^10.2.0",
"@nestjs/microservices": "^10.3.8",
"@nestjs/microservices": "^10.4.4",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-fastify": "^10.3.8",
"@nestjs/platform-fastify": "^10.4.4",
"@nestjs/schedule": "^4.1.1",
"@nestjs/swagger": "^7.3.1",
"@nestjs/typeorm": "^10.0.2",
"amqplib": "^0.10.4",
"aws-sdk": "^2.1603.0",
"axios": "^1.7.2",
"bcryptjs": "^2.4.3",
Expand All @@ -56,15 +59,15 @@
"rxjs": "^7.8.1",
"typeorm": "^0.3.20",
"typesense": "^1.8.2",
"waterbus-proto": "^1.1.5"
"waterbus-proto": "^1.1.18"
},
"resolutions": {
"inquirer": "^8.0.0"
},
"devDependencies": {
"@nestjs/cli": "^10.3.2",
"@nestjs/schematics": "^10.1.1",
"@nestjs/testing": "^10.3.8",
"@nestjs/testing": "^10.4.4",
"@swc/cli": "^0.3.12",
"@swc/core": "^1.4.16",
"@types/bcryptjs": "^2.4.6",
Expand Down
9 changes: 9 additions & 0 deletions src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Controller, Get } from '@nestjs/common';

@Controller('health')
export class HealthCheckController {
@Get()
healthCheck(): { status: string } {
return { status: 'ok' };
}
}
5 changes: 5 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { UserModule } from './features/user/user.module';
import { MeetingModule } from './features/meeting/meeting.module';
import { ChatModule } from './features/chat/chat.module';
import { EnvironmentConfigModule } from './core/config/environment/environment.module';
import { HealthCheckController } from './app.controller';
import { NotFoundController } from './notfound.controller';
import { VideoProcessingModule } from './features/video-processing/video-processing.module';

@Module({
imports: [
Expand All @@ -21,6 +24,8 @@ import { EnvironmentConfigModule } from './core/config/environment/environment.m
UserModule,
MeetingModule,
ChatModule,
VideoProcessingModule,
],
controllers: [HealthCheckController, NotFoundController],
})
export class AppModule {}
17 changes: 16 additions & 1 deletion src/core/client-proxy/client-proxy.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export const getGrpcClientOptions = (
case EPackage.CHAT:
url = config.getWsGrpcUrl();
break;
case EPackage.RECORD:
url = config.getRecordGrpcUrl();
break;
}
return {
transport: Transport.GRPC,
Expand All @@ -36,6 +39,7 @@ export const getGrpcClientOptions = (
})
export class ClientProxyModule {
static chatClientProxy = 'chatClientProxy';
static recordClientProxy = 'recordClientProxy';
static register(): DynamicModule {
return {
module: ClientProxyModule,
Expand All @@ -48,8 +52,19 @@ export class ClientProxyModule {
getGrpcClientOptions(config, EPackage.CHAT),
),
},
{
provide: ClientProxyModule.recordClientProxy,
inject: [EnvironmentConfigService],
useFactory: (config: EnvironmentConfigService) =>
ClientProxyFactory.create(
getGrpcClientOptions(config, EPackage.RECORD),
),
},
],
exports: [
ClientProxyModule.chatClientProxy,
ClientProxyModule.recordClientProxy,
],
exports: [ClientProxyModule.chatClientProxy],
};
}
}
25 changes: 25 additions & 0 deletions src/core/config/environment/environments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@ export class EnvironmentConfigService {
return this.configService.get<string>('TYPESENSE_API_KEY');
}

// RabbitMQ
getRabbitMQHost(): string {
return this.configService.get<string>('RABBITMQ_HOST');
}

getRabbitMQPort(): number {
return this.configService.get<number>('RABBITMQ_PORT');
}

getRabbitMQUser(): string {
return this.configService.get<string>('RABBITMQ_USER');
}

getRabbitMQPassword(): string {
return this.configService.get<string>('RABBITMQ_PASSWORD');
}

// GRPC
getWsGrpcUrl(): string {
return this.configService.get<string>('WEBSOCKET_GRPC_ADDRESS');
Expand All @@ -49,6 +66,14 @@ export class EnvironmentConfigService {
return this.configService.get<string>('AUTH_GRPC_URL');
}

getWhiteBoardGrpcUrl(): string {
return this.configService.get<string>('WHITE_BOARD_GRPC_URL');
}

getRecordGrpcUrl(): string {
return this.configService.get<string>('RECORD_GRPC_URL');
}

getMeetingGrpcUrl(): string {
return this.configService.get<string>('MEETING_GRPC_URL');
}
Expand Down
6 changes: 4 additions & 2 deletions src/core/config/typesense/typesense.config.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
// typesense.config.ts

import { Injectable } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common';
import { Client } from 'typesense';
import { EnvironmentConfigService } from '../environment/environments';

@Injectable()
export class TypesenseConfig {
constructor(private readonly environment: EnvironmentConfigService) {}

private readonly logger: Logger = new Logger(TypesenseConfig.name);

async createSchema() {
const client = this.getClient();

try {
await client.collections('users').delete();
} catch (error) {
console.log();
this.logger.error(error);
}

await client.collections().create({
Expand Down
4 changes: 2 additions & 2 deletions src/core/database/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ export const AppDataSource = new DataSource({
keepConnectionAlive: true,
logging: process.env.NODE_ENV !== 'production',
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
migrations: [__dirname + '/migrations/**/*{.ts,.js}'],
migrations: [__dirname + '/migrations/*{.ts,.js}'],
cli: {
entitiesDir: 'src',
migrationsDir: 'src/database/migrations',
migrationsDir: 'src/core/database/migrations',
subscribersDir: 'subscriber',
},
extra: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class UpdateLatestMessageCreatedAt1727342279462
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
const meetings = await queryRunner.query(`
SELECT "meeting"."id" AS "meeting_id", "meeting"."title" AS "meeting_title", "meeting"."password" AS "meeting_password", "meeting"."status" AS "meeting_status", "meeting"."latestMessageCreatedAt" AS "meeting_latestMessageCreatedAt", "meeting"."code" AS "meeting_code", "meeting"."createdAt" AS "meeting_createdAt", "meeting"."updatedAt" AS "meeting_updatedAt", "meeting"."deletedAt" AS "meeting_deletedAt", "latestMessage"."id" AS "latestMessage_id", "latestMessage"."data" AS "latestMessage_data", "latestMessage"."type" AS "latestMessage_type", "latestMessage"."status" AS "latestMessage_status", "latestMessage"."createdAt" AS "latestMessage_createdAt", "latestMessage"."updatedAt" AS "latestMessage_updatedAt", "latestMessage"."deletedAt" AS "latestMessage_deletedAt", "latestMessage"."createdById" AS "latestMessage_createdById", "latestMessage"."meetingId" AS "latestMessage_meetingId" FROM "meetings" "meeting" LEFT JOIN "messages" "latestMessage" ON "latestMessage"."meetingId"="meeting"."id" AND ("latestMessage"."deletedAt" IS NULL) WHERE "meeting"."deletedAt" IS NULL
`);

for (const meeting of meetings) {
const meetingId = meeting.meeting_id;

let latestMessageCreatedAt = meeting.latestMessage_createdAt
? meeting.latestMessage_createdAt
: meeting.meeting_createdAt;

await queryRunner.query(
`UPDATE "meetings" SET "latestMessageCreatedAt" = $1 WHERE "id" = $2`,
[latestMessageCreatedAt, meetingId],
);
}
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
UPDATE "meetings"
SET "latestMessageCreatedAt" = NULL
WHERE "deletedAt" IS NULL
`);
}
}
2 changes: 1 addition & 1 deletion src/core/database/typeorm-config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class TypeOrmConfigService implements TypeOrmOptionsFactory {
migrations: [__dirname + '/migrations/**/*{.ts,.js}'],
cli: {
entitiesDir: 'src',
migrationsDir: 'src/database/migrations',
migrationsDir: 'src/core/database/migrations',
subscribersDir: 'subscriber',
},
extra: {
Expand Down
10 changes: 9 additions & 1 deletion src/core/dtos/meetings/update-meeting.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNotEmpty, IsNumber } from 'class-validator';
import { IsString, IsNotEmpty, IsNumber, IsOptional } from 'class-validator';

export class UpdateMeetingDto {
@ApiProperty()
Expand All @@ -10,9 +10,17 @@ export class UpdateMeetingDto {
@ApiProperty()
@IsString()
@IsNotEmpty()
@IsOptional()
title: string;

@ApiProperty()
@IsString()
@IsOptional()
password: string;

@ApiProperty()
@IsString()
@IsNotEmpty()
@IsOptional()
avatar: string;
}
8 changes: 4 additions & 4 deletions src/core/dtos/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,25 @@ export interface IPagination {
}

export class PaginationListQuery implements IPagination {
@ApiProperty({ required: false })
@ApiProperty({ required: false, default: 0 })
@Transform(({ value }) => parseInt(value))
@IsNumber()
@IsOptional()
readonly skip: number = 0;

@ApiProperty({ required: false })
@ApiProperty({ required: false, default: 5 })
@Transform(({ value }) => parseInt(value))
@IsNumber()
@IsOptional()
readonly limit: number = 5;

@ApiProperty({ required: false })
@ApiProperty({ required: false, default: 1 })
@Transform(({ value }) => parseInt(value))
@IsNumber()
@IsOptional()
readonly page: number = 1;

@ApiProperty({ required: false })
@ApiProperty({ required: false, default: 10 })
@Transform(({ value }) => parseInt(value))
@IsNumber()
@IsOptional()
Expand Down
Loading

0 comments on commit f07b340

Please sign in to comment.