diff --git a/BE/src/app.module.ts b/BE/src/app.module.ts index 62133d9..117631b 100644 --- a/BE/src/app.module.ts +++ b/BE/src/app.module.ts @@ -4,40 +4,24 @@ import { AppService } from './app.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { StudyLogsModule } from './study-logs/study-logs.module'; -import { StudyLogs } from './study-logs/study-logs.entity'; -import { Categories } from './categories/categories.entity'; import { CategoriesModule } from './categories/categories.module'; import { MatesModule } from './mates/mates.module'; import { UsersModule } from './users/users.module'; -import { UsersModel } from './users/entity/users.entity'; import { PassportModule } from '@nestjs/passport'; import { AuthModule } from './auth/auth.module'; import { ServeStaticModule } from '@nestjs/serve-static'; -import { join } from 'path'; -import { Mates } from './mates/mates.entity'; -import { LoggingMiddleware } from './common/logging.middleware'; +import { LoggingMiddleware } from './common/middleware/logging.middleware'; +import { typeormConfig } from './common/config/typeorm.config'; +import { staticConfig } from './common/config/static.config'; @Module({ imports: [ - ServeStaticModule.forRoot({ - rootPath: join(__dirname, '../../..', 'apps'), - serveRoot: '/', - renderPath: '/', - }), + ServeStaticModule.forRoot(staticConfig), ConfigModule.forRoot({ isGlobal: true, }), TypeOrmModule.forRootAsync({ - useFactory: (config: ConfigService) => ({ - type: 'mysql', - host: config.get('DATABASE_HOST'), - port: config.get('DATABASE_PORT'), - username: config.get('DATABASE_USERNAME'), - password: config.get('DATABASE_PASSWORD'), - database: config.get('DATABASE_NAME'), - entities: [StudyLogs, Categories, UsersModel, Mates], - synchronize: true, - }), + useFactory: typeormConfig, inject: [ConfigService], }), StudyLogsModule, diff --git a/BE/src/auth/auth.controller.ts b/BE/src/auth/auth.controller.ts index 1d026cb..00caead 100644 --- a/BE/src/auth/auth.controller.ts +++ b/BE/src/auth/auth.controller.ts @@ -29,7 +29,7 @@ import { UpdateUserDto } from 'src/users/dto/update-user.dto'; import { FileInterceptor } from '@nestjs/platform-express'; import { ConfigService } from '@nestjs/config'; import { ENV } from 'src/common/const/env-keys.const'; -import { getImageUrl } from 'src/common/utils'; +import { getImageUrl } from 'src/common/utils/utils'; @ApiTags('로그인 페이지') @Controller('auth') diff --git a/BE/src/auth/auth.module.ts b/BE/src/auth/auth.module.ts index f362504..d5a8c0e 100644 --- a/BE/src/auth/auth.module.ts +++ b/BE/src/auth/auth.module.ts @@ -6,17 +6,15 @@ import { UsersModule } from 'src/users/users.module'; import { JwtModule } from '@nestjs/jwt'; import { GoogleStrategy } from './google.strategy'; import { MulterModule } from '@nestjs/platform-express'; -import { multerConfig } from 'src/common/multer.config'; +import { multerConfig } from 'src/common/config/multer.config'; +import { jwtConfig } from 'src/common/config/jwt.config'; @Module({ imports: [ JwtModule.registerAsync({ imports: [ConfigModule], inject: [ConfigService], - useFactory: async (configService: ConfigService) => ({ - secret: configService.get('JWT_SECRET'), - signOptions: { expiresIn: configService.get('JWT_EXPIRES_IN') }, - }), + useFactory: jwtConfig, }), MulterModule.registerAsync({ imports: [ConfigModule], diff --git a/BE/src/common/config/jwt.config.ts b/BE/src/common/config/jwt.config.ts new file mode 100644 index 0000000..0e666a1 --- /dev/null +++ b/BE/src/common/config/jwt.config.ts @@ -0,0 +1,7 @@ +import { ConfigService } from '@nestjs/config'; +import { ENV } from '../const/env-keys.const'; + +export const jwtConfig = (configService: ConfigService) => ({ + secret: configService.get(ENV.JWT_SECRET), + signOptions: { expiresIn: configService.get(ENV.JWT_EXPIRES_IN) }, +}); diff --git a/BE/src/common/logging.config.ts b/BE/src/common/config/logging.config.ts similarity index 96% rename from BE/src/common/logging.config.ts rename to BE/src/common/config/logging.config.ts index 01e8581..3dce542 100644 --- a/BE/src/common/logging.config.ts +++ b/BE/src/common/config/logging.config.ts @@ -1,4 +1,4 @@ -import winston from 'winston'; +import winston from 'winston'; const customFormat = winston.format.printf( ({ level, message, timestamp, context }) => { diff --git a/BE/src/common/multer.config.ts b/BE/src/common/config/multer.config.ts similarity index 92% rename from BE/src/common/multer.config.ts rename to BE/src/common/config/multer.config.ts index 5d43740..d360e5b 100644 --- a/BE/src/common/multer.config.ts +++ b/BE/src/common/config/multer.config.ts @@ -1,7 +1,7 @@ -import path from 'path'; +import path from 'path'; import { BadRequestException } from '@nestjs/common'; import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface'; -import multer from 'multer'; +import multer from 'multer'; export const multerConfig = (): MulterOptions => { const storage = multer.memoryStorage(); @@ -15,7 +15,6 @@ export const multerConfig = (): MulterOptions => { } return callback(null, true); }; - const limits = { fileSize: 1024 * 1024 * 10 }; //10MB return { diff --git a/BE/src/common/config/static.config.ts b/BE/src/common/config/static.config.ts new file mode 100644 index 0000000..091789e --- /dev/null +++ b/BE/src/common/config/static.config.ts @@ -0,0 +1,7 @@ +import path from 'path'; + +export const staticConfig = { + rootPath: path.join(__dirname, '../../../../..', 'apps'), + serveRoot: '/', + renderPath: '/', +}; diff --git a/BE/src/common/config/swagger.config.ts b/BE/src/common/config/swagger.config.ts new file mode 100644 index 0000000..36a79fc --- /dev/null +++ b/BE/src/common/config/swagger.config.ts @@ -0,0 +1,8 @@ +import { DocumentBuilder } from '@nestjs/swagger'; + +export const swaggerConfig = new DocumentBuilder() + .setTitle('StudyLog API') + .setDescription('StudyLog 애플리케이션 API 문서') + .setVersion('2.0') + .addBearerAuth() + .build(); diff --git a/BE/src/common/config/typeorm.config.ts b/BE/src/common/config/typeorm.config.ts new file mode 100644 index 0000000..6813447 --- /dev/null +++ b/BE/src/common/config/typeorm.config.ts @@ -0,0 +1,19 @@ +import { ConfigService } from '@nestjs/config'; +import { TypeOrmModuleOptions } from '@nestjs/typeorm'; +import { Categories } from 'src/categories/categories.entity'; +import { Mates } from 'src/mates/mates.entity'; +import { StudyLogs } from 'src/study-logs/study-logs.entity'; +import { UsersModel } from 'src/users/entity/users.entity'; +import { ENV } from '../const/env-keys.const'; + +export const typeormConfig = (config: ConfigService): TypeOrmModuleOptions => ({ + type: 'mysql', + host: config.get(ENV.DATABASE_HOST), + port: config.get(ENV.DATABASE_PORT), + username: config.get(ENV.DATABASE_USERNAME), + password: config.get(ENV.DATABASE_PASSWORD), + database: config.get(ENV.DATABASE_NAME), + entities: [StudyLogs, Categories, UsersModel, Mates], + timezone: 'Z', + synchronize: true, +}); diff --git a/BE/src/common/const/env-keys.const.ts b/BE/src/common/const/env-keys.const.ts index 771559d..f13fefb 100644 --- a/BE/src/common/const/env-keys.const.ts +++ b/BE/src/common/const/env-keys.const.ts @@ -5,4 +5,17 @@ export enum ENV { IMAGE_REGION = 'IMAGE_REGION', IMAGE_BUCKET = 'IMAGE_BUCKET', CDN_ENDPOINT = 'CDN_ENDPOINT', + JWT_SECRET = 'JWT_SECRET', + JWT_EXPIRES_IN = 'JWT_EXPIRES_IN', + DATABASE_HOST = 'DATABASE_HOST', + DATABASE_PORT = 'DATABASE_PORT', + DATABASE_USERNAME = 'DATABASE_USERNAME', + DATABASE_PASSWORD = 'DATABASE_PASSWORD', + DATABASE_NAME = 'DATABASE_NAME', + SSL = 'SSL', + HTTPS_KEY_PATH = 'HTTPS_KEY_PATH', + HTTPS_CERT_PATH = 'HTTPS_CERT_PATH', + PORT = 'PORT', + GREENEYE_URL = 'GREENEYE_URL', + GREENEYE_SECRET = 'GREENEYE_SECRET', } diff --git a/BE/src/common/exception-filter/http-exception-filter.ts b/BE/src/common/exception-filter/http-exception-filter.ts index 3ef1228..dd052e5 100644 --- a/BE/src/common/exception-filter/http-exception-filter.ts +++ b/BE/src/common/exception-filter/http-exception-filter.ts @@ -5,7 +5,7 @@ import { HttpException, Logger, } from '@nestjs/common'; -import { LoggingInterceptor } from '../logging.interceptor'; +import { LoggingInterceptor } from '../interceptor/logging.interceptor'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { diff --git a/BE/src/common/logging.interceptor.ts b/BE/src/common/interceptor/logging.interceptor.ts similarity index 100% rename from BE/src/common/logging.interceptor.ts rename to BE/src/common/interceptor/logging.interceptor.ts diff --git a/BE/src/common/logging.middleware.ts b/BE/src/common/middleware/logging.middleware.ts similarity index 100% rename from BE/src/common/logging.middleware.ts rename to BE/src/common/middleware/logging.middleware.ts diff --git a/BE/src/common/utils.ts b/BE/src/common/utils/utils.ts similarity index 94% rename from BE/src/common/utils.ts rename to BE/src/common/utils/utils.ts index 8a71a0b..4535479 100644 --- a/BE/src/common/utils.ts +++ b/BE/src/common/utils/utils.ts @@ -1,4 +1,4 @@ -import path from 'path'; +import path from 'path'; export function transformDate(date: Date): string { const year = date.getFullYear(); diff --git a/BE/src/main.ts b/BE/src/main.ts index b43f626..6cf92fb 100644 --- a/BE/src/main.ts +++ b/BE/src/main.ts @@ -1,23 +1,25 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; -import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; +import { SwaggerModule } from '@nestjs/swagger'; import { ValidationPipe } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { readFileSync } from 'fs'; import { WinstonModule } from 'nest-winston'; -import { loggerConfig } from './common/logging.config'; -import { LoggingInterceptor } from './common/logging.interceptor'; +import { loggerConfig } from './common/config/logging.config'; +import { LoggingInterceptor } from './common/interceptor/logging.interceptor'; import { HttpExceptionFilter } from './common/exception-filter/http-exception-filter'; +import { swaggerConfig } from './common/config/swagger.config'; +import { ENV } from './common/const/env-keys.const'; async function bootstrap() { const configService = new ConfigService(); - const ssl = configService.get('SSL'); + const ssl = configService.get(ENV.SSL); let httpsOptions = null; if (ssl == 'true') { httpsOptions = { - key: readFileSync(configService.get('HTTPS_KEY_PATH')), - cert: readFileSync(configService.get('HTTPS_CERT_PATH')), + key: readFileSync(configService.get(ENV.HTTPS_KEY_PATH)), + cert: readFileSync(configService.get(ENV.HTTPS_CERT_PATH)), }; } @@ -25,20 +27,14 @@ async function bootstrap() { httpsOptions, logger: WinstonModule.createLogger(loggerConfig), }); - const config = new DocumentBuilder() - .setTitle('StudyLog API') - .setDescription('StudyLog 애플리케이션 API 문서') - .setVersion('2.0') - .addBearerAuth() - .build(); - const document = SwaggerModule.createDocument(app, config); + const document = SwaggerModule.createDocument(app, swaggerConfig); SwaggerModule.setup('api', app, document); app.useGlobalPipes(new ValidationPipe()); app.useGlobalInterceptors(new LoggingInterceptor()); app.useGlobalFilters(new HttpExceptionFilter()); - await app.listen(configService.get('PORT') || 3000); + await app.listen(configService.get(ENV.PORT) || 3000); } bootstrap(); diff --git a/BE/src/mates/mates.service.ts b/BE/src/mates/mates.service.ts index d9f936e..de9aebb 100644 --- a/BE/src/mates/mates.service.ts +++ b/BE/src/mates/mates.service.ts @@ -9,7 +9,7 @@ import { Repository } from 'typeorm'; import { MatesDto } from './dto/response/mates.dto'; import { UsersModel } from 'src/users/entity/users.entity'; import { RedisService } from 'src/common/redis.service'; -import { getImageUrl } from 'src/common/utils'; +import { getImageUrl } from 'src/common/utils/utils'; import { ConfigService } from '@nestjs/config'; import { ENV } from 'src/common/const/env-keys.const'; import { StudyLogsService } from 'src/study-logs/study-logs.service'; diff --git a/BE/src/study-logs/study-logs.service.ts b/BE/src/study-logs/study-logs.service.ts index f83c73d..6d9fa92 100644 --- a/BE/src/study-logs/study-logs.service.ts +++ b/BE/src/study-logs/study-logs.service.ts @@ -6,7 +6,7 @@ import { StudyLogsCreateDto } from './dto/request/create-study-logs.dto'; import { UsersModel } from 'src/users/entity/users.entity'; import { Categories } from 'src/categories/categories.entity'; import { StudyLogsDto } from './dto/response/study-logs.dto'; -import { transformDate } from 'src/common/utils'; +import { transformDate } from 'src/common/utils/utils'; import { RedisService } from 'src/common/redis.service'; import moment from 'moment'; @@ -49,6 +49,7 @@ export class StudyLogsService { } calculateStartDay(created_at: Date, learning_time: number): Date { + console.log(created_at.toLocaleString()); const STANDARD = 0; const standardMS = STANDARD * 60 * 60 * 1000; const millisecond = diff --git a/BE/src/users/users.service.ts b/BE/src/users/users.service.ts index f76ffec..0fa5ce3 100644 --- a/BE/src/users/users.service.ts +++ b/BE/src/users/users.service.ts @@ -8,7 +8,7 @@ import { GreenEyeResponse } from './interface/greeneye.interface'; import { S3Service } from 'src/common/s3.service'; import { ENV } from 'src/common/const/env-keys.const'; import { UpdateUserDto } from './dto/update-user.dto'; -import { getImageUrl } from 'src/common/utils'; +import { getImageUrl } from 'src/common/utils/utils'; @Injectable() export class UsersService { @@ -115,8 +115,8 @@ export class UsersService { async requestClovaGreenEye( image: Express.Multer.File, ): Promise { - const APIURL = this.config.get('GREENEYE_URL'); - const CLIENT_SECRET = this.config.get('GREENEYE_SECRET'); + const APIURL = this.config.get(ENV.GREENEYE_URL); + const CLIENT_SECRET = this.config.get(ENV.GREENEYE_SECRET); const UUID = v4(); try { const response = await fetch(APIURL, { diff --git a/BE/test/app.e2e-spec.ts b/BE/test/app.e2e-spec.ts index 299bb5d..dbbd23b 100644 --- a/BE/test/app.e2e-spec.ts +++ b/BE/test/app.e2e-spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; -import request from 'supertest'; +import request from 'supertest'; import { AppModule } from '../src/app.module'; describe('AppController (e2e)', () => {