Skip to content

Commit

Permalink
Merge branch 'develop' into feat/#293/record-one-audio
Browse files Browse the repository at this point in the history
  • Loading branch information
begong313 authored Dec 2, 2024
2 parents a54214f + e772b19 commit aadfe0e
Show file tree
Hide file tree
Showing 69 changed files with 3,197 additions and 292 deletions.
197 changes: 155 additions & 42 deletions README.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.700.0",
"@nestjs/common": "^10.4.6",
"@nestjs/config": "^3.3.0",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/schedule": "^4.1.1",
"@nestjs/swagger": "^8.0.1",
"@nestjs/throttler": "^6.2.1",
"@nestjs/typeorm": "^10.0.2",
Expand All @@ -39,6 +41,7 @@
"eslint-import-resolver-typescript": "^3.6.3",
"jsonwebtoken": "^9.0.2",
"mysql2": "^3.11.3",
"nest-winston": "^1.9.7",
"passport": "^0.7.0",
"passport-github2": "^0.1.12",
"passport-google-oauth20": "^2.0.0",
Expand All @@ -47,6 +50,8 @@
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"typeorm": "^0.3.20",
"winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0",
"zod": "^3.23.8"
},
"devDependencies": {
Expand Down
13 changes: 11 additions & 2 deletions apps/api/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Module } from '@nestjs/common';
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { ThrottlerModule } from '@nestjs/throttler';
import { TypeOrmModule } from '@nestjs/typeorm';

import { TypeOrmConfigService } from '@/config/typeorm.config';

import { AuthModule } from './auth/auth.module';
import { LoggerMiddleware } from './common/log/logger.middleware';
import { LoggerModule } from './common/log/logger.module';
import { NcpModule } from './common/ncp/ncp.module';
import { DashboardModule } from './dashboard/dashboard.module';
import { StreamModule } from './stream/stream.module';
import { TicleModule } from './ticle/ticle.module';
Expand All @@ -32,6 +35,12 @@ import { UserModule } from './user/user.module';
useClass: TypeOrmConfigService,
}),
DashboardModule,
LoggerModule,
NcpModule,
],
})
export class AppModule {}
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
}
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion apps/api/src/common/filter/http-exception.filter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Response } from 'express';

import { ErrorResponse } from '@/response.interface';
import { ErrorResponse } from '@/common/Interceptor/response.interface';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
Expand Down
33 changes: 33 additions & 0 deletions apps/api/src/common/log/logger.batch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import path from 'path';

import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

import { LoggerService } from './logger.service';
import { NcpService } from '../ncp/ncp.service';

@Injectable()
export class LogBatchService {
constructor(
private readonly ncpService: NcpService,
private readonly loggerService: LoggerService
) {}

@Cron(CronExpression.EVERY_DAY_AT_1AM)
async uploadLogToObjectStorage() {
const logsDir = path.join(__dirname, '../../../logs');
const today = new Date();
today.setHours(today.getHours() + 9);
today.setDate(today.getDate() - 1);

const logFileName = `application-${today.toISOString().split('T')[0]}.log`;
const localFilePath = path.join(logsDir, logFileName);
try {
const remoteFileName = `logs/${logFileName}`;
const result = await this.ncpService.uploadFile(localFilePath, remoteFileName);
this.loggerService.log(`Log file uploaded successfully: ${result}`, 'logBatchService');
} catch (error) {
this.loggerService.log(`Failed to upload log file: ${error}`, 'logBatchService');
}
}
}
26 changes: 26 additions & 0 deletions apps/api/src/common/log/logger.middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

import { LoggerService } from './logger.service';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
constructor(private readonly logger: LoggerService) {}

use(req: Request, res: Response, next: NextFunction) {
const { method, originalUrl } = req;
const userAgent = req.headers['user-agent'] || 'Unknown';

res.on('finish', () => {
const { statusCode } = res;
const contentLength = res.get('content-length') || 0;

this.logger.log(
`[${method}] ${originalUrl} - ${statusCode} - ${contentLength} bytes - UserAgent: ${userAgent}`,
'HTTP'
);
});

next();
}
}
17 changes: 17 additions & 0 deletions apps/api/src/common/log/logger.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Global, Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
import { WinstonModule } from 'nest-winston';

import { WinstonConfig } from '@/config/winston.confing';

import { LogBatchService } from './logger.batch';
import { LoggerService } from './logger.service';
import { NcpModule } from '../ncp/ncp.module';

@Global()
@Module({
imports: [WinstonModule.forRoot(WinstonConfig), ScheduleModule.forRoot(), NcpModule],
providers: [LoggerService, LogBatchService],
exports: [LoggerService],
})
export class LoggerModule {}
28 changes: 28 additions & 0 deletions apps/api/src/common/log/logger.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Inject, Injectable, LoggerService as NestLoggerService } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';

@Injectable()
export class LoggerService implements NestLoggerService {
constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {}

log(message: string, context: string) {
this.logger.info(message, { context });
}

error(message: string, trace: string, context: string) {
this.logger.error(message, { trace, context });
}

warn(message: string, context: string) {
this.logger.warn(message, { context });
}

debug(message: string, context: string) {
this.logger.debug(message, { context });
}

verbose(message: string, context: string) {
this.logger.verbose(message, { context });
}
}
11 changes: 11 additions & 0 deletions apps/api/src/common/ncp/ncp.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';

import { NcpConfig } from '@/config/ncp.config';

import { NcpService } from './ncp.service';

@Module({
providers: [NcpService, NcpConfig],
exports: [NcpService],
})
export class NcpModule {}
40 changes: 40 additions & 0 deletions apps/api/src/common/ncp/ncp.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as fs from 'fs';

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { ErrorMessage } from '@repo/types';

import { NcpConfig } from '@/config/ncp.config';

@Injectable()
export class NcpService {
private s3: S3Client;

constructor(
private ncpConfig: NcpConfig,
private configService: ConfigService
) {
this.s3 = ncpConfig.s3Client;
}

async uploadFile(localFilePath: string, remoteFileName: string): Promise<string> {
const bucketName = this.configService.get<string>('NCP_OBJECT_STORAGE_BUCKET');
const endpoint = this.configService.get<string>('NCP_OBJECT_STORAGE_ENDPOINT');

const fileStream = fs.createReadStream(localFilePath);
const params = {
Bucket: bucketName,
Key: remoteFileName,
Body: fileStream,
};

try {
const uploadResponse = await this.s3.send(new PutObjectCommand(params));

Check warning on line 33 in apps/api/src/common/ncp/ncp.service.ts

View workflow job for this annotation

GitHub Actions / check

'uploadResponse' is assigned a value but never used
const url = `${endpoint}/${bucketName}/${remoteFileName}`;

Check warning on line 34 in apps/api/src/common/ncp/ncp.service.ts

View workflow job for this annotation

GitHub Actions / check

'url' is assigned a value but never used
return remoteFileName;
} catch (error) {

Check warning on line 36 in apps/api/src/common/ncp/ncp.service.ts

View workflow job for this annotation

GitHub Actions / check

'error' is defined but never used
throw new Error(ErrorMessage.FILE_UPLOAD_FAILED);
}
}
}
File renamed without changes.
25 changes: 25 additions & 0 deletions apps/api/src/config/ncp.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { S3Client } from '@aws-sdk/client-s3';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class NcpConfig {
s3Client: S3Client;

constructor(private configService: ConfigService) {
const accessKeyId = this.configService.get<string>('NCP_ACCESS_KEY');
const secretAccessKey = this.configService.get<string>('NCP_SECRET_KEY');
const region = this.configService.get<string>('NCP_OBJECT_STORAGE_REGION');
const endpoint = this.configService.get<string>('NCP_OBJECT_STORAGE_ENDPOINT');

this.s3Client = new S3Client({
region: region,
credentials: {
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
},
endpoint: endpoint,
forcePathStyle: true,
});
}
}
26 changes: 26 additions & 0 deletions apps/api/src/config/winston.confing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import path from 'path';

import * as winston from 'winston';
import 'winston-daily-rotate-file';

export const WinstonConfig = {
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.colorize(),
winston.format.printf(({ level, message, timestamp }) => {
return `[${timestamp}] ${level}: ${message}`;
})
),
}),
new winston.transports.DailyRotateFile({
dirname: path.join(__dirname, '../../logs'),
filename: 'application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d',
}),
],
};
17 changes: 14 additions & 3 deletions apps/api/src/dashboard/dashboard.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { GetDashboardListQuerySchema } from '@repo/types';

import { JwtAuthGuard } from '@/auth/jwt/jwt-auth.guard';
import { GetUserId } from '@/common/decorator/get-userId.decorator';
import { ZodValidationPipe } from '@/zodValidationPipe';
import { ZodValidationPipe } from '@/common/pipe/zodValidationPipe';

import { DashboardService } from './dashboard.service';
import { GetDashboardListQueryDto } from './dto/getDashboardListQueryDto';
Expand Down Expand Up @@ -31,8 +31,19 @@ export class DashboardController {
return await this.dashboardService.getApplicants(ticleId);
}

@Post('start')
startTicle(@Param('ticleId') ticleId: number) {}
@Post(':ticleId/start')
@UseGuards(JwtAuthGuard)
async startTicle(@GetUserId() userId: number, @Param('ticleId') ticleId: number) {
await this.dashboardService.startTicle(userId, ticleId);
return 'success ticle start';
}

@Post(':ticleId/end')
@UseGuards(JwtAuthGuard)
async endTicle(@GetUserId() userId: number, @Param('ticleId') ticleId: number) {
await this.dashboardService.endTicle(userId, ticleId);
return 'success ticle end';
}

@Post('join')
joinTicle(@Param('ticleId') ticleId: number) {}

Check warning on line 49 in apps/api/src/dashboard/dashboard.controller.ts

View workflow job for this annotation

GitHub Actions / check

'ticleId' is defined but never used
Expand Down
Loading

0 comments on commit aadfe0e

Please sign in to comment.