Skip to content

Commit 00f6078

Browse files
authored
Fix: gql 셋팅 및 마이그레이션 (#47)
* Fix: gcl 셋팅 및 swagger 이중 참조 삭제
1 parent 8baf7e4 commit 00f6078

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+942
-967
lines changed

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,25 @@
2828
"preinstall": "npx only-allow pnpm"
2929
},
3030
"dependencies": {
31+
"@apollo/server": "^4.11.2",
3132
"@aws-sdk/client-dynamodb": "^3.540.0",
3233
"@aws-sdk/client-ses": "^3.549.0",
3334
"@aws-sdk/lib-dynamodb": "^3.549.0",
35+
"@nestjs/apollo": "^12.2.1",
3436
"@nestjs/common": "^10.0.0",
3537
"@nestjs/config": "^3.1.1",
3638
"@nestjs/core": "^10.0.0",
39+
"@nestjs/graphql": "^12.2.1",
3740
"@nestjs/jwt": "^10.2.0",
3841
"@nestjs/passport": "^10.0.3",
3942
"@nestjs/platform-express": "^10.0.0",
40-
"@nestjs/swagger": "^7.3.0",
4143
"@supabase/supabase-js": "^2.45.3",
4244
"bcrypt": "^5.1.1",
4345
"class-transformer": "^0.5.1",
4446
"class-validator": "^0.14.1",
4547
"commander": "^12.1.0",
4648
"cookie-parser": "^1.4.6",
49+
"graphql": "^16.9.0",
4750
"mysql2": "^3.9.1",
4851
"passport": "^0.7.0",
4952
"passport-google-oauth20": "^2.0.0",
@@ -52,7 +55,6 @@
5255
"pm2": "^5.3.1",
5356
"reflect-metadata": "^0.1.14",
5457
"rxjs": "^7.8.1",
55-
"swagger-ui-express": "^5.0.0",
5658
"typeorm": "^0.3.20",
5759
"uuid": "^9.0.1"
5860
},

pnpm-lock.yaml

Lines changed: 758 additions & 55 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app.module.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
import { Module } from '@nestjs/common';
2+
import { GraphQLModule } from '@nestjs/graphql';
3+
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
4+
import { ConfigModule } from '@nestjs/config';
25
import { HealthCheckController } from './modules/health-check/health-check.controller';
36
import { DynamoDBModule } from './database/dynamodb/dynamodb.module';
47
import { UserModule } from './modules/user/user.module';
58
import { AuthModule } from './modules/auth/auth.module';
69
import { TestModule } from './modules/test/test.module';
10+
import { join } from 'path';
711

812
@Module({
9-
imports: [DynamoDBModule, UserModule, AuthModule, TestModule],
13+
imports: [
14+
ConfigModule.forRoot({
15+
isGlobal: true,
16+
}),
17+
GraphQLModule.forRoot<ApolloDriverConfig>({
18+
driver: ApolloDriver,
19+
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
20+
sortSchema: true,
21+
}),
22+
DynamoDBModule,
23+
UserModule,
24+
AuthModule,
25+
TestModule
26+
],
1027
controllers: [HealthCheckController],
1128
providers: [],
1229
})
Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
import { ApiProperty } from '@nestjs/swagger';
2-
31
export class UnauthorizedError {
4-
@ApiProperty({
5-
example: ['No token', 'Invalid token', 'Token expired'],
6-
})
72
message: string[];
83

9-
@ApiProperty({
10-
example: 'Unauthorized',
11-
})
124
error: 'Unauthorized';
135
}

src/main.ts

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,16 @@
1-
import 'dotenv/config';
2-
import { NestFactory, Reflector } from '@nestjs/core';
1+
import { ValidationPipe } from '@nestjs/common';
2+
import { NestFactory } from '@nestjs/core';
33
import { AppModule } from './app.module';
4-
import { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common';
5-
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
6-
import * as cookieParser from 'cookie-parser';
7-
import { BaseExceptionFilter } from 'src/core/filters/base-exception-filter';
8-
import { writeFileSync } from 'fs';
9-
import { join } from 'path';
104

115
async function bootstrap() {
126
const app = await NestFactory.create(AppModule);
13-
// set CORS
7+
app.useGlobalPipes(new ValidationPipe());
148
app.enableCors({
15-
origin: true,
9+
origin: process.env.CORS_ORIGIN,
1610
credentials: true,
17-
exposedHeaders: ['Authorization'],
1811
});
19-
// set swagger module
20-
const config = new DocumentBuilder()
21-
.setTitle('Meta Test API')
22-
.setDescription('The Meta Test API')
23-
.setVersion('1.0.0')
24-
.addBearerAuth()
25-
.build();
26-
const document = SwaggerModule.createDocument(app, config);
27-
const swaggerJson = JSON.stringify(document, null, 2);
28-
writeFileSync(join(process.cwd(), 'swagger-spec.json'), swaggerJson);
29-
SwaggerModule.setup('api', app, document);
30-
31-
app.useGlobalPipes(
32-
new ValidationPipe({
33-
transform: true,
34-
}),
35-
);
36-
37-
app.useGlobalFilters(new BaseExceptionFilter());
38-
39-
app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));
40-
app.use(cookieParser());
41-
// set port
42-
const port =
43-
process.env.NODE_ENV === 'dev'
44-
? 8000
45-
: process.env.NODE_ENV === 'production'
46-
? 8080
47-
: 3000;
48-
49-
console.log('server start at', port);
5012

13+
const port = process.env.PORT || 3000;
5114
await app.listen(port);
5215
}
5316
bootstrap();

src/modules/auth/auth.controller.ts

Lines changed: 2 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -11,66 +11,28 @@ import {
1111
Res,
1212
UseGuards,
1313
} from '@nestjs/common';
14-
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
1514
import { Response } from 'express';
1615
import { KakaoAuthGuard } from 'src/auth/guard/kakao.auth.guard';
1716
import { AuthService } from './auth.service';
1817
import { CreateTokenRequestDto } from './dto/create-token-request.dto';
19-
import { CreateTokenResponseDto } from './dto/create-token-response.dto';
2018
import { RefreshTokenRequestDto } from './dto/refresh-token-request.dto';
21-
import { RefreshTokenResponseDto } from './dto/refresh-token-response.dto';
2219
import { SocialLoginRequestDto } from './dto/social-login-request.dto';
2320
import { GoogleAuthGuard } from 'src/auth/guard/google.auth.guard';
2421
import { ResetPasswordRequestDto } from './dto/reset-password-request.dto';
2522
import { EmailVerificationRequestDto } from './dto/email-verification-request.dto';
2623
import { UpdateEmailVerificationRequestDto } from './dto/update-email-verification-request.dto';
2724
import { UserType } from 'src/types/userType';
28-
import { CreateTokenRequestBodyError } from './error/create-token-error';
29-
import { RefreshTokenRequestBodyError } from './error/refresh-token-error';
30-
import { ResetPasswordRequestBodyError } from './error/reset-password-error';
31-
import { EmailVerificationRequestBodyError } from './error/email-verification-error';
32-
import { UpdateEmailVerificationRequestBodyError } from './error/update-email-verification-error';
33-
import { EmailVerificationResponseDto } from './dto/email-verification-response.dto';
3425

35-
@ApiTags('auth')
3626
@Controller({ path: 'auth' })
3727
export class AuthController {
3828
constructor(private readonly authService: AuthService) {}
3929

4030
@Post('token')
41-
@ApiOperation({ summary: '로그인', description: '토큰 발급' })
42-
@ApiResponse({
43-
status: 201,
44-
description: 'Created',
45-
type: CreateTokenResponseDto,
46-
})
47-
@ApiResponse({
48-
status: 400,
49-
description: 'Bad request',
50-
type: CreateTokenRequestBodyError,
51-
})
52-
@ApiResponse({
53-
status: 401,
54-
description: 'Unauthorized',
55-
content: {
56-
'application/json': {
57-
example: {
58-
message: 'User not found or password does not match',
59-
error: 'Unauthorized',
60-
},
61-
},
62-
},
63-
})
64-
@ApiResponse({
65-
status: 500,
66-
description: 'Internal Server Error',
67-
})
6831
@HttpCode(HttpStatus.CREATED)
6932
async createToken(
7033
@Body() createTokenInfoDto: CreateTokenRequestDto,
7134
@Res() res: Response,
7235
) {
73-
//NOTE: 이 API가 호출되는 유저는 일반 유저이므로 userType = NORMAL
7436
const tokens = await this.authService.create(
7537
createTokenInfoDto,
7638
UserType.NORMAL,
@@ -86,36 +48,6 @@ export class AuthController {
8648
}
8749

8850
@Post('token/refresh')
89-
@ApiOperation({
90-
summary: '토큰 재발급',
91-
description: '토큰 재발급',
92-
})
93-
@ApiResponse({
94-
status: 201,
95-
description: 'Created',
96-
type: RefreshTokenResponseDto,
97-
})
98-
@ApiResponse({
99-
status: 400,
100-
description: 'Bad request',
101-
type: RefreshTokenRequestBodyError,
102-
})
103-
@ApiResponse({
104-
status: 401,
105-
description: 'Unauthorized',
106-
content: {
107-
'application/json': {
108-
example: {
109-
message: 'Invalid token',
110-
error: 'Unauthorized',
111-
},
112-
},
113-
},
114-
})
115-
@ApiResponse({
116-
status: 500,
117-
description: 'Internal Server Error',
118-
})
11951
@HttpCode(HttpStatus.CREATED)
12052
async refreshToken(
12153
@Body() refreshTokenInfoDto: RefreshTokenRequestDto,
@@ -132,14 +64,6 @@ export class AuthController {
13264
res.status(HttpStatus.CREATED).send();
13365
}
13466

135-
@ApiOperation({
136-
summary: '카카오 소셜로그인',
137-
description: '기가입 유저는 로그인, 신규 유저는 회원가입 진행',
138-
})
139-
@ApiResponse({
140-
status: 201,
141-
description: 'Created',
142-
})
14367
@UseGuards(KakaoAuthGuard)
14468
@Get('login/kakao')
14569
async loginWithKakao(
@@ -158,14 +82,6 @@ export class AuthController {
15882
res.status(HttpStatus.CREATED).send();
15983
}
16084

161-
@ApiOperation({
162-
summary: '구글 소셜로그인',
163-
description: '기가입 유저는 로그인, 신규 유저는 회원가입 진행',
164-
})
165-
@ApiResponse({
166-
status: 201,
167-
description: 'Created',
168-
})
16985
@UseGuards(GoogleAuthGuard)
17086
@Get('login/google')
17187
async loginWithGoogle(
@@ -185,61 +101,13 @@ export class AuthController {
185101
}
186102

187103
@Patch('password')
188-
@ApiOperation({
189-
summary: '비밀번호 초기화',
190-
description: '비밀번호 변경하고 이메일로 전송합니다.',
191-
})
192-
@ApiResponse({
193-
status: 200,
194-
description: 'OK',
195-
})
196-
@ApiResponse({
197-
status: 400,
198-
description: 'Bad request',
199-
type: ResetPasswordRequestBodyError,
200-
})
201-
@ApiResponse({
202-
status: 404,
203-
description: 'Not Found',
204-
content: {
205-
'application/json': {
206-
example: {
207-
message: 'User does not exist',
208-
error: 'Not Found',
209-
},
210-
},
211-
},
212-
})
213-
@ApiResponse({
214-
status: 500,
215-
description: 'Internal Server Error',
216-
})
217104
@HttpCode(HttpStatus.OK)
218105
async updateUserPassword(@Body() body: ResetPasswordRequestDto) {
219106
const email = body.email;
220-
//NOTE: reset password는 일반유저만 가능(소셜로그인 유저 X)
221107
return await this.authService.resetUserPassword(email, UserType.NORMAL);
222108
}
223109

224110
@Post('email-verification')
225-
@ApiOperation({
226-
summary: '이메일 인증 요청',
227-
description: '이메일 인증 요청 메일을 발송',
228-
})
229-
@ApiResponse({
230-
status: 201,
231-
description: 'Created',
232-
type: EmailVerificationResponseDto,
233-
})
234-
@ApiResponse({
235-
status: 400,
236-
description: 'Bad request',
237-
type: EmailVerificationRequestBodyError,
238-
})
239-
@ApiResponse({
240-
status: 500,
241-
description: 'Internal Server Error',
242-
})
243111
@HttpCode(HttpStatus.CREATED)
244112
async createEmailVerificaiton(
245113
@Body() body: EmailVerificationRequestDto,
@@ -251,62 +119,13 @@ export class AuthController {
251119
}
252120

253121
@Patch('email-verification')
254-
@ApiOperation({
255-
summary: '이메일 인증 검증',
256-
description: '임시토큰으로 이메일 인증을 검증',
257-
})
258-
@ApiResponse({
259-
status: 200,
260-
description: 'OK',
261-
})
262-
@ApiResponse({
263-
status: 400,
264-
description: 'Bad request',
265-
type: UpdateEmailVerificationRequestBodyError,
266-
})
267-
@ApiResponse({
268-
status: 401,
269-
description: 'Unauthorized',
270-
content: {
271-
'application/json': {
272-
examples: {
273-
UpdateEmailVerificationUnauthorizedError: {
274-
value: {
275-
message: 'Invalid request_id',
276-
error: 'Unauthorized',
277-
},
278-
description: 'request_id가 유효하지 않음',
279-
},
280-
UpdateEmailVerificationUnauthorizedError2: {
281-
value: {
282-
message: 'Invalid code',
283-
error: 'Unauthorized',
284-
},
285-
description: 'code가 유효하지 않음',
286-
},
287-
UpdateEmailVerificationUnauthorizedError3: {
288-
value: {
289-
message: 'Expired request_id',
290-
error: 'Unauthorized',
291-
},
292-
description: 'request_id가 만료됨',
293-
},
294-
},
295-
},
296-
},
297-
})
298-
@ApiResponse({
299-
status: 500,
300-
description: 'Internal Server Error',
301-
})
302122
@HttpCode(HttpStatus.OK)
303123
async updateEmailVerificaiton(
304124
@Body() body: UpdateEmailVerificationRequestDto,
305125
@Res({ passthrough: true }) res: Response,
306126
) {
307-
const id = body.request_id;
308-
const code = body.code;
309-
await this.authService.updateEmailVerificaiton(id, code);
127+
const { request_id, code } = body;
128+
await this.authService.updateEmailVerificaiton(request_id, code);
310129
res.status(HttpStatus.OK).send();
311130
}
312131
}

0 commit comments

Comments
 (0)