Skip to content

Commit e176836

Browse files
authored
Merge pull request #9 from chan000518/feat_chan
Feat chan
2 parents 2c23530 + 8c2b23b commit e176836

18 files changed

+518
-356
lines changed

src/app.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const morgan = require('morgan');
33
const cors = require('cors');
44
const api = require("./routers/index");
55
const setupSwagger = require('./config/swagger');
6-
const { errorHandler } = require("./middlewares/errorHandler");
6+
const { errorMiddleware } = require("./middlewares/errorMiddleware");
77

88
const app = express();
99

@@ -19,6 +19,6 @@ app.use("/api", api);
1919
setupSwagger(app);
2020

2121
// 에러 핸들러 등록
22-
app.use(errorHandler);
22+
app.use(errorMiddleware);
2323

2424
module.exports = app;

src/config/swagger.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const swaggerJSDoc = require('swagger-jsdoc');
22
const swaggerUi = require('swagger-ui-express');
3+
const path = require('path');
34

45
const options = {
56
definition: {
@@ -16,7 +17,9 @@ const options = {
1617
},
1718
],
1819
},
19-
apis: ['./src/routers/*.js'], // 라우트 파일에서 Swagger 주석을 가져옴
20+
apis: ['./src/routers/*.js',
21+
path.resolve(__dirname, 'swaggerComponents.yaml'),
22+
], // 라우트 파일에서 Swagger 주석을 가져옴
2023
};
2124

2225
const swaggerSpec = swaggerJSDoc(options);

src/config/swaggerComponents.yaml

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Project PTLink API
4+
version: 1.0.0
5+
description: API documentation for PTLink
6+
servers:
7+
- url: "/"
8+
description: API server
9+
10+
components:
11+
schemas:
12+
SuccessResponse:
13+
type: object
14+
properties:
15+
success:
16+
type: boolean
17+
description: "요청 성공 여부"
18+
example: true
19+
message:
20+
type: string
21+
description: "응답 메시지"
22+
example: "요청이 성공적으로 처리되었습니다."
23+
data:
24+
type: object
25+
description: "응답 데이터"
26+
27+
ErrorResponse:
28+
type: object
29+
properties:
30+
success:
31+
type: boolean
32+
example: false
33+
errorCode:
34+
type: integer
35+
description: "에러 코드"
36+
example: 400
37+
message:
38+
type: string
39+
description: "에러 메시지"
40+
example: "요청이 잘못되었습니다."
41+
42+
Schedule:
43+
type: object
44+
properties:
45+
id:
46+
type: integer
47+
description: "스케줄 ID"
48+
example: 1
49+
date:
50+
type: string
51+
format: date-time
52+
description: "스케줄 날짜 및 시간"
53+
example: "2025-01-01T10:00:00Z"
54+
location:
55+
type: string
56+
description: "스케줄 장소"
57+
example: "Gym A"
58+
trainingTarget:
59+
type: string
60+
description: "운동 부위"
61+
example: ""
62+
status:
63+
type: string
64+
enum:
65+
- MEMBER_PROPOSED
66+
- TRAINER_PROPOSED
67+
- SCHEDULED
68+
- REJECTED
69+
- CANCELED
70+
description: "스케줄 상태"
71+
example: "TRAINER_PROPOSED"
72+
memberId:
73+
type: integer
74+
description: "멤버 ID"
75+
example: 1
76+
trainerId:
77+
type: integer
78+
description: "트레이너 ID"
79+
example: 2
80+
81+
ScheduleArrayResponse:
82+
type: object
83+
properties:
84+
success:
85+
type: boolean
86+
example: true
87+
message:
88+
type: string
89+
example: "스케줄 조회 성공"
90+
data:
91+
type: array
92+
items:
93+
$ref: "#/components/schemas/Schedule"
94+
95+
TrainersResponse:
96+
type: object
97+
properties:
98+
success:
99+
type: boolean
100+
example: true
101+
message:
102+
type: string
103+
example: "트레이너 조회 성공"
104+
data:
105+
type: array
106+
items:
107+
type: object
108+
properties:
109+
id:
110+
type: integer
111+
description: "트레이너 ID"
112+
example: 2
113+
name:
114+
type: string
115+
description: "트레이너 이름"
116+
example: "Jane Doe"
117+
email:
118+
type: string
119+
description: "트레이너 이메일"
120+
example: "[email protected]"
121+
phoneNumber:
122+
type: string
123+
description: "트레이너 전화번호"
124+
example: "010-1234-5678"
125+
126+
Member:
127+
type: object
128+
properties:
129+
id:
130+
type: integer
131+
description: "회원 ID"
132+
example: 1
133+
user:
134+
type: object
135+
properties:
136+
name:
137+
type: string
138+
description: "회원 이름"
139+
example: "김철수"
140+
email:
141+
type: string
142+
description: "회원 이메일"
143+
example: "[email protected]"
144+
phoneNumber:
145+
type: string
146+
description: "회원 전화번호"
147+
example: "010-1234-5678"
148+
149+
MemberArrayResponse:
150+
type: object
151+
properties:
152+
success:
153+
type: boolean
154+
example: true
155+
message:
156+
type: string
157+
example: "회원 리스트 조회 성공"
158+
data:
159+
type: object
160+
properties:
161+
members:
162+
type: array
163+
items:
164+
$ref: "#/components/schemas/Member"
165+
total:
166+
type: integer
167+
description: "총 회원 수"
168+
example: 100
169+
170+
MemberResponse:
171+
type: object
172+
properties:
173+
success:
174+
type: boolean
175+
example: true
176+
message:
177+
type: string
178+
example: "회원 조회 성공"
179+
data:
180+
$ref: "#/components/schemas/Member"
181+
182+
User:
183+
type: object
184+
properties:
185+
id:
186+
type: integer
187+
description: "사용자 ID"
188+
example: 1
189+
username:
190+
type: string
191+
description: "사용자 고유 이름"
192+
example: "john_doe"
193+
email:
194+
type: string
195+
description: "사용자 이메일"
196+
example: "[email protected]"
197+
name:
198+
type: string
199+
description: "사용자 이름"
200+
example: "John Doe"
201+
role:
202+
type: string
203+
enum: [MEMBER, TRAINER]
204+
description: "사용자 역할"
205+
example: "MEMBER"
206+
createdAt:
207+
type: string
208+
format: date-time
209+
description: "사용자 생성 날짜"
210+
example: "2025-01-01T10:00:00Z"
211+
212+
CreateUser:
213+
type: object
214+
properties:
215+
username:
216+
type: string
217+
description: "사용자 고유 이름"
218+
password:
219+
type: string
220+
description: "사용자 비밀번호"
221+
email:
222+
type: string
223+
description: "사용자 이메일"
224+
name:
225+
type: string
226+
description: "사용자 이름"
227+
role:
228+
type: string
229+
enum: [MEMBER, TRAINER]
230+
description: "사용자 역할"
231+
required:
232+
- username
233+
- password
234+
- email
235+
- name
236+
- role
237+
238+
LoginUser:
239+
type: object
240+
properties:
241+
username:
242+
type: string
243+
description: "사용자 고유 이름"
244+
password:
245+
type: string
246+
description: "사용자 비밀번호"
247+
required:
248+
- username
249+
- password
250+
251+
securitySchemes:
252+
BearerAuth:
253+
type: http
254+
scheme: bearer
255+
bearerFormat: JWT

src/controllers/memberController.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ const {
88
} = require("../services/memberService");
99

1010
const asyncHandler = require('../utils/asyncHandler');
11-
11+
const { successResponse} = require('../utils/responseHelper');
12+
const { CustomError, ErrorCodes } = require('../utils/error');
13+
1214
// 멤버가 자신의 스케줄 조회 (특정 한 달)
1315
const getMemberSchedulesByMonthController = asyncHandler(async (req, res) => {
1416
const { month } = req.query;
@@ -25,46 +27,46 @@ const getMemberSchedulesByMonthController = asyncHandler(async (req, res) => {
2527

2628
const schedules = await getMemberSchedulesByMonth(member.id, monthDate);
2729

28-
res.status(200).json(schedules);
30+
res.status(200).json(successResponse(schedules, "스케줄 조회 성공"));
2931
});
3032

3133
// 멤버가 자신과 관련 있는 트레이너 조회
3234
const getRelatedTrainersController = asyncHandler(async (req, res) => {
3335
const member = req.role;
3436
const trainers = await getRelatedTrainers(member.id);
35-
res.status(200).json(trainers);
37+
res.status(200).json(successResponse(trainers, "트레이너 조회 성공"));
3638
});
3739

3840
// 스케줄 제안 (멤버)
3941
const proposeScheduleByMemberController = asyncHandler(async (req, res) => {
4042
const { trainerId, date, location } = req.body;
4143
const member = req.role;
4244
const schedule = await proposeScheduleByMember(trainerId, member.id, new Date(date), location);
43-
res.status(201).json(schedule);
45+
res.status(201).json(successResponse(schedule, "스케줄 제안 성공"));
4446
});
4547

4648
// 스케줄 수락 (멤버)
4749
const acceptScheduleByMemberController = asyncHandler(async (req, res) => {
4850
const member = req.role;
4951
const { scheduleId } = req.params;
5052
const schedule = await acceptScheduleByMember(member.id, parseInt(scheduleId));
51-
res.status(200).json(schedule);
53+
res.status(200).json(successResponse(schedule, "스케줄 수락 성공"));
5254
});
5355

5456
// 스케줄 거절 (멤버)
5557
const rejectScheduleByMemberController = asyncHandler(async (req, res) => {
5658
const member = req.role;
5759
const { scheduleId } = req.params;
5860
const schedule = await rejectScheduleByMember(member.id, parseInt(scheduleId));
59-
res.status(200).json(schedule);
61+
res.status(200).json(successResponse(schedule, "스케줄 거절 성공"));
6062
});
6163

6264
// 스케줄 취소/삭제 (멤버)
6365
const cancelScheduleByMemberController = asyncHandler(async (req, res) => {
6466
const member = req.role;
6567
const { scheduleId } = req.params;
6668
const result = await cancelScheduleByMember(member.id, parseInt(scheduleId));
67-
res.status(200).json(result);
69+
res.status(200).json(successResponse(result, "스케줄 취소 성공"));
6870
});
6971

7072
module.exports = {
@@ -74,4 +76,4 @@ module.exports = {
7476
acceptScheduleByMemberController,
7577
rejectScheduleByMemberController,
7678
cancelScheduleByMemberController,
77-
};
79+
};

0 commit comments

Comments
 (0)