Skip to content

Commit d81a9dc

Browse files
authored
Merge pull request #32 from codeit-moving/dev
Dev -> main 20241216 13:58 formData 테스트
2 parents c7ac7c1 + 40443fb commit d81a9dc

21 files changed

+504
-54
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ deploy.sh
1010

1111
.main.yml
1212

13-
.http
13+
.http
14+
15+
ERD.md

package-lock.json

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

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"jsonwebtoken": "^9.0.2",
2929
"multer": "^1.4.5-lts.1",
3030
"multer-s3": "^3.0.1",
31+
"node-cron": "^3.0.3",
3132
"passport": "^0.7.0",
3233
"passport-custom": "^1.1.1",
3334
"passport-jwt": "^4.0.1",
@@ -44,6 +45,7 @@
4445
"@mermaid-js/mermaid-cli": "^11.4.0",
4546
"@types/dompurify": "^3.2.0",
4647
"@types/jest": "^29.5.14",
48+
"@types/node-cron": "^3.0.11",
4749
"babel-jest": "^29.7.0",
4850
"jest": "^29.7.0",
4951
"nodemon": "^3.1.4",

prisma/ERD.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ erDiagram
1818
}
1919
"Customer" {
2020
Int id PK
21-
String imageUrl "nullable"
2221
Int services
2322
Int regions
2423
DateTime createAt
@@ -28,7 +27,6 @@ erDiagram
2827
"Mover" {
2928
Int id PK
3029
String nickname
31-
String imageUrl "nullable"
3230
Int services
3331
Int regions
3432
Int career
@@ -112,6 +110,15 @@ erDiagram
112110
Int reviewId FK
113111
Int moverId FK
114112
}
113+
"ProfileImage" {
114+
Int id PK
115+
String imageUrl
116+
Boolean status
117+
DateTime createAt
118+
DateTime updateAt
119+
Int customerId FK "nullable"
120+
Int moverId FK "nullable"
121+
}
115122
"_CustomerToMover" {
116123
String A FK
117124
String B FK
@@ -135,6 +142,8 @@ erDiagram
135142
"notification" }o--|| "User" : user
136143
"ReviewComment" }o--|| "Review" : review
137144
"ReviewComment" }o--|| "Mover" : mover
145+
"ProfileImage" }o--o| "Customer" : customer
146+
"ProfileImage" }o--o| "Mover" : mover
138147
"_CustomerToMover" }o--|| "Customer" : Customer
139148
"_CustomerToMover" }o--|| "Mover" : Mover
140149
"_MoverToMovingRequest" }o--|| "Mover" : Mover
@@ -157,7 +166,6 @@ erDiagram
157166

158167
**Properties**
159168
- `id`:
160-
- `imageUrl`:
161169
- `services`:
162170
- `regions`:
163171
- `createAt`:
@@ -169,7 +177,6 @@ erDiagram
169177
**Properties**
170178
- `id`:
171179
- `nickname`:
172-
- `imageUrl`:
173180
- `services`:
174181
- `regions`:
175182
- `career`:
@@ -269,6 +276,17 @@ erDiagram
269276
- `reviewId`:
270277
- `moverId`:
271278

279+
### `ProfileImage`
280+
281+
**Properties**
282+
- `id`:
283+
- `imageUrl`:
284+
- `status`:
285+
- `createAt`:
286+
- `updateAt`:
287+
- `customerId`:
288+
- `moverId`:
289+
272290
### `_CustomerToMover`
273291
Pair relationship table between [Customer](#Customer) and [Mover](#Mover)
274292

src/app.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import userRouter from "./controllers/userController";
1818
import notificationRouter from "./controllers/notificationController";
1919

2020
import confirmedQuoteRouter from "./controllers/confirmedQuoteController";
21+
import { initNotification } from "./schedules/notifications";
2122
const app = express();
2223

2324
//CORS 설정
@@ -40,6 +41,7 @@ const corsOptions: CorsOptions = {
4041

4142
// Express app에 CORS 적용
4243
app.use(cors(corsOptions));
44+
app.use(express.urlencoded({ extended: true }));
4345

4446
//미들웨어
4547
app.use(express.json()); //json parse
@@ -57,6 +59,9 @@ app.use(
5759
app.use(passport.initialize());
5860
app.use(passport.session());
5961

62+
//알림 스케줄 등록
63+
initNotification();
64+
6065
//라우터 모음 -> 컨트롤러
6166
app.use("/services", serviceRouter);
6267
app.use("/regions", regionRouter);

src/controllers/confirmedQuoteController.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,18 @@ router.post(
1616
quoteId: parseInt(id),
1717
customerId,
1818
});
19-
res.status(201).json(confirmedQuote);
19+
20+
const resData = {
21+
message: "견적서 확정 완료",
22+
data: {
23+
id: confirmedQuote.id,
24+
movingRequestId: confirmedQuote.movingRequest.id,
25+
quoteId: confirmedQuote.quote.id,
26+
moverId: confirmedQuote.mover.id,
27+
},
28+
};
29+
30+
res.status(201).send(resData);
2031
} catch (error) {
2132
next(error);
2233
}

src/controllers/moverController.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { asyncHandle } from "../utils/asyncHandler";
33
import express from "express";
44
import checkBoolean from "../utils/checkBoolean";
55
import passport from "passport";
6+
import { optionalJwtAuth } from "../middlewares/authMiddleware";
67

78
interface queryString {
89
nextCursorId: string;
@@ -19,7 +20,7 @@ const router = express.Router();
1920
//기사 목록 조회
2021
router.get(
2122
"/",
22-
passport.authenticate("jwt-optional", { session: false }),
23+
optionalJwtAuth,
2324
asyncHandle(async (req, res, next) => {
2425
try {
2526
let customerId: number | null = null;
@@ -64,7 +65,7 @@ router.get(
6465
//기사 상세 조회
6566
router.get(
6667
"/:id",
67-
passport.authenticate("jwt-optional", { session: false }),
68+
optionalJwtAuth,
6869
asyncHandle(async (req, res, next) => {
6970
try {
7071
let customerId: number | null = null;

src/controllers/movingRequestController.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,39 @@ const router = express.Router();
1010
//이사요청 목록 조회
1111
router.get(
1212
"/",
13-
passport.authenticate("jwt", { session: false }),
13+
// passport.authenticate("jwt", { session: false }),
1414
asyncHandle(async (req, res, next) => {
1515
try {
16-
const { customerId } = req.user as { customerId: number };
16+
// const { customerId } = req.user as { customerId: number };
1717

18-
const { limit = "10", isCompleted = "", cursor = "0" } = req.query;
18+
const {
19+
limit = "10",
20+
isDesignated = "",
21+
cursor = "0",
22+
keyword = "",
23+
smallMove = "false",
24+
houseMove = "false",
25+
officeMove = "false",
26+
orderBy = "resent",
27+
} = req.query;
1928
const parseLimit = parseInt(limit as string);
2029
const parseCursor = parseInt(cursor as string);
21-
const parseIsCompleted = checkBoolean(isCompleted as string);
30+
const parseIsDesignated = checkBoolean(isDesignated as string);
31+
const parseSmallMove = checkBoolean(smallMove as string);
32+
const parseHouseMove = checkBoolean(houseMove as string);
33+
const parseOfficeMove = checkBoolean(officeMove as string);
2234

2335
const movingRequestList = await movingRequestService.getMovingRequestList(
24-
customerId,
36+
1,
2537
{
2638
limit: parseLimit,
27-
isCompleted: parseIsCompleted,
39+
isDesignated: parseIsDesignated,
2840
cursor: parseCursor,
41+
keyword: keyword as string,
42+
smallMove: parseSmallMove || false,
43+
houseMove: parseHouseMove || false,
44+
officeMove: parseOfficeMove || false,
45+
orderBy: orderBy as string,
2946
}
3047
);
3148
return res.status(200).send(movingRequestList);

src/controllers/quoteController.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,23 @@ router.get(
173173
})
174174
);
175175

176+
//견적서 상세 조회
177+
router.get(
178+
"/:id",
179+
passport.authenticate("jwt", { session: false }),
180+
asyncHandle(async (req, res, next) => {
181+
try {
182+
const { customerId } = req.user as { customerId: number };
183+
const { id: quoteId } = req.params;
184+
const quote = await quoteService.getQuoteById(
185+
customerId,
186+
parseInt(quoteId)
187+
);
188+
return res.status(200).send(quote);
189+
} catch (error) {
190+
next(error);
191+
}
192+
})
193+
);
194+
176195
export default router; // 설정한 라우터를 내보내서 다른 파일에서 사용할 수 있게 해요.

src/middlewares/authMiddleware.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
// 테스트를 위한 임시 파일
22

33
import { Request, Response, NextFunction } from "express";
4+
import passport from "passport";
5+
import CustomError from "../utils/interfaces/customError";
6+
7+
interface authUser {
8+
id: number;
9+
customerId: number;
10+
moverId: number;
11+
}
412

513
export interface AuthenticatedRequest extends Request {
614
user?: {
@@ -18,3 +26,30 @@ export const authenticate = (
1826
(req as AuthenticatedRequest).user = { id: 1 };
1927
next();
2028
};
29+
30+
export const optionalJwtAuth = (
31+
req: Request,
32+
res: Response,
33+
next: NextFunction
34+
) => {
35+
passport.authenticate(
36+
"jwt-optional",
37+
{ session: false },
38+
(err: CustomError, user: authUser) => {
39+
// 토큰이 없는 경우 (user가 null)이거나 정상적인 경우 통과
40+
if (!user || (user && !err)) {
41+
req.user = user;
42+
return next();
43+
}
44+
45+
// 토큰이 유효하지 않은 경우에만 에러 반환
46+
if (err) {
47+
err.status = 401;
48+
err.data = {
49+
message: "유효하지 않는 토큰입니다.",
50+
};
51+
return next(err);
52+
}
53+
}
54+
)(req, res, next);
55+
};

0 commit comments

Comments
 (0)