Skip to content

Commit

Permalink
feat : presigned url 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
kangjuhyup committed Oct 24, 2024
1 parent 074ab83 commit ba4b385
Show file tree
Hide file tree
Showing 11 changed files with 258 additions and 92 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"swagger-ui-express": "^5.0.1",
"typeorm": "^0.3.20"
"typeorm": "^0.3.20",
"uuid": "^10.0.0"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
Expand All @@ -45,6 +46,7 @@
"@types/multer": "^1.4.12",
"@types/node": "^20.3.1",
"@types/supertest": "^6.0.0",
"@types/uuid": "^10",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
Expand Down
3 changes: 1 addition & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ const modules = [
},
}),
StorageModule,
//TODO : 운영환경 데이터베이스 세팅 완료 후 운영환경에서도 모듈 주입
process.env.NODE_ENV !== 'production ' && DatabaseModule,
DatabaseModule,
].filter(Boolean);

@Module({
Expand Down
30 changes: 14 additions & 16 deletions src/database/database.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,27 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { LetterDataSource } from './datasource/letter.datasource';
import { Enviroments } from '@app/domain/dto/env';
import { plainToClass, plainToInstance } from 'class-transformer';
import { validateSync } from 'class-validator';
import { plainToInstance } from 'class-transformer';

@Global()
@Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (config:ConfigService) => {

const env = plainToInstance(Enviroments,process.env, {
enableImplicitConversion : true,
useFactory: async (config: ConfigService) => {
const env = plainToInstance(Enviroments, process.env, {
enableImplicitConversion: true,
});
const ds = LetterDataSource({
type: env.DB_TYPE,
host: env.DB_HOST,
port: env.DB_PORT,
database: env.DB_NAME,
username: env.DB_USER,
password: env.DB_PWD,
synchronize: false,
});
const ds = LetterDataSource({
type: env.DB_TYPE,
host: env.DB_HOST,
port: env.DB_PORT,
database: env.DB_NAME,
username: env.DB_USER,
password: env.DB_PWD,
synchronize : false,
})
await ds.initialize();
await ds.initialize();
return ds.options;
},
inject: [ConfigService],
Expand Down
27 changes: 14 additions & 13 deletions src/database/datasource/letter.datasource.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { DataSource } from 'typeorm';

export const LetterDataSource =(param : {
type : any,
host : string,
port : number,
username : string,
password : string,
database : string,
synchronize : boolean
}) => new DataSource({
...param,
entities: [__dirname + '/../entity/*.{ts,js}'],
migrations: [__dirname + '/../migration/*.{ts,js}'],
});
export const LetterDataSource = (param: {
type: any;
host: string;
port: number;
username: string;
password: string;
database: string;
synchronize: boolean;
}) =>
new DataSource({
...param,
entities: [__dirname + '/../entity/*.{ts,js}'],
migrations: [__dirname + '/../migration/*.{ts,js}'],
});
18 changes: 11 additions & 7 deletions src/domain/dto/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export class Enviroments {
@IsUrl()
WASABI_ENDPOINT: string;

@IsNotEmpty()
@IsString()
WASABI_SIGN_KEY: string;

@IsNotEmpty()
@IsString()
THUMB_BUCKET: string;
Expand All @@ -36,26 +40,26 @@ export class Enviroments {

@IsNotEmpty()
@IsString()
DB_TYPE : string;
DB_TYPE: string;

@IsNotEmpty()
@IsString()
DB_HOST : string;
DB_HOST: string;

@Transform(({value}) => Number(value))
@Transform(({ value }) => Number(value))
@IsNotEmpty()
@IsNumber()
DB_PORT : number;
DB_PORT: number;

@IsNotEmpty()
@IsString()
DB_NAME : string;
DB_NAME: string;

@IsNotEmpty()
@IsString()
DB_USER : string;
DB_USER: string;

@IsNotEmpty()
@IsString()
DB_PWD : string;
DB_PWD: string;
}
46 changes: 30 additions & 16 deletions src/domain/letter/dto/request/add.letter.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import { LetterCategory, LetterCategoryCode } from "@util/category";
import { Transform } from "class-transformer";
import { IsDefined, IsIn, IsOptional, IsString, MaxLength } from "class-validator";
import { LetterCategoryCode } from '@util/category';
import {
IsBoolean,
IsDefined,
IsIn,
IsOptional,
IsString,
MaxLength,
} from 'class-validator';

export class AddLetterRequest {
@IsDefined()
@IsString()
@IsIn(Object.values(LetterCategoryCode))
category : LetterCategoryCode
@IsDefined()
@IsString()
@IsIn(Object.values(LetterCategoryCode))
category: LetterCategoryCode;

@IsDefined()
@IsString()
@MaxLength(20)
title : string
@IsDefined()
@IsString()
@MaxLength(20)
title: string;

@IsOptional()
@IsString()
@MaxLength(255)
body : string;
}
@IsOptional()
@IsString()
@MaxLength(255)
body?: string;

@IsOptional()
@IsBoolean()
commentYn?: boolean;

@IsOptional()
@IsBoolean()
attendYn?: boolean;
}
9 changes: 9 additions & 0 deletions src/domain/letter/dto/request/prepare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Transform } from 'class-transformer';
import { IsNumber, Max } from 'class-validator';

export class PrepareRequest {
@Transform(({ value }) => Number(value))
@IsNumber()
@Max(10)
componentCount: number;
}
46 changes: 46 additions & 0 deletions src/domain/letter/dto/response/prepare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsArray,
IsNotEmpty,
IsNumber,
IsOptional,
IsUrl,
} from 'class-validator';

export class PrepareResponse {
@ApiProperty({
description: '썸네일 업로드 권한이 열려있는 url',
example:
'https://s3.ap-northeast-1.wasabisys.com/bucket/file.txt?AWSAccessKeyId=...',
})
@IsNotEmpty()
@IsUrl()
thumbnailUrl: string;

@ApiProperty({
description: '배경 업로드 권한이 열려있는 url',
example:
'https://s3.ap-northeast-1.wasabisys.com/bucket/file.txt?AWSAccessKeyId=...',
})
@IsNotEmpty()
@IsUrl()
backgroundUrl: string;

@ApiProperty({
description: '아이템 업로드 권한이 열려있는 url',
example:
'[https://s3.ap-northeast-1.wasabisys.com/bucket/file.txt?AWSAccessKeyId=...]',
})
@IsOptional()
@IsArray()
@IsUrl({},{each:true})
componentUrls: string[];

@ApiProperty({
description: 'url 만료 기간',
example: 60,
})
@IsNotEmpty()
@IsNumber()
expires: number;
}
97 changes: 61 additions & 36 deletions src/domain/letter/letter.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Controller, Get, Param, Query, UseInterceptors } from '@nestjs/common';
import {
Controller,
Get,
Param,
Post,
Query,
UseInterceptors,
} from '@nestjs/common';
import { GetLetterDetailRequest } from './dto/request/get.detail';
import { HttpResponse } from '../dto/response';
import { ResponseValidationInterceptor } from 'src/interceptor/response.validation';
Expand All @@ -8,6 +15,8 @@ import { GetLetterPageRequest } from './dto/request/get.page';
import { GetLetterPageResponse } from './dto/response/get.page';
import { LetterService } from './letter.service';
import { LetterCategory } from '@util/category';
import { PrepareResponse } from './dto/response/prepare';
import { PrepareRequest } from './dto/request/prepare';

@Controller('letter')
export class LetterController {
Expand Down Expand Up @@ -40,43 +49,59 @@ export class LetterController {
};
}

@Get(':id')
@ApiOperation({ summary: '초대장 상세 정보 조회' })
@ApiOkResponse({
status: 200,
description: '성공',
type: GetLetterDetailResponse,
})
@UseInterceptors(new ResponseValidationInterceptor(GetLetterDetailResponse))
async getLetterDetail(
@Param() dto: GetLetterDetailRequest,
): Promise<HttpResponse<GetLetterDetailResponse>> {
@Get('prepare-add')
@UseInterceptors(new ResponseValidationInterceptor(PrepareResponse))
async prepareAddLetter(
@Query() dto: PrepareRequest,
): Promise<HttpResponse<PrepareResponse>> {
return {
result: true,
data: {
background: {
path: 'https://s3.ap-northeast-1.wasabisys.com/bgr/mock01',
width: 800,
height: 1600,
},
image: [
{
path: 'https://s3.ap-northeast-1.wasabisys.com/cpn/mock01',
width: 100,
height: 80,
x: 200,
y: 800,
},
],
text: [
{
body: 'MOCK',
size: 18,
x: 200,
y: 600,
},
],
},
data: await this.letterService.prepareAddLetter(dto),
};
}

// @Get(':id')
// @ApiOperation({ summary: '초대장 상세 정보 조회' })
// @ApiOkResponse({
// status: 200,
// description: '성공',
// type: GetLetterDetailResponse,
// })
// @UseInterceptors(new ResponseValidationInterceptor(GetLetterDetailResponse))
// async getLetterDetail(
// @Param() dto: GetLetterDetailRequest,
// ): Promise<HttpResponse<GetLetterDetailResponse>> {
// return {
// result: true,
// data: {
// background: {
// path: 'https://s3.ap-northeast-1.wasabisys.com/bgr/mock01',
// width: 800,
// height: 1600,
// },
// image: [
// {
// path: 'https://s3.ap-northeast-1.wasabisys.com/cpn/mock01',
// width: 100,
// height: 80,
// x: 200,
// y: 800,
// },
// ],
// text: [
// {
// body: 'MOCK',
// size: 18,
// x: 200,
// y: 600,
// },
// ],
// },
// };
// }



@Post()
async addLetter() {}
}
Loading

0 comments on commit ba4b385

Please sign in to comment.