Skip to content

#592 room.js, report.js 를 ts로 변환 #593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
19 changes: 0 additions & 19 deletions src/routes/docs/schemas/reportsSchema.js

This file was deleted.

19 changes: 19 additions & 0 deletions src/routes/docs/schemas/reportsSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { z } from "zod";
import { zodToSchemaObject } from "../utils";
import patterns from "@/modules/patterns";

export const reportsZod = {
createHandler: z
.object({
reportedId: z.string().regex(patterns.objectId),
type: z.enum(["no-settlement", "no-show", "etc-reason"]),
etcDetail: z.string().max(30).default(""),
time: z.string().datetime(),
roomId: z.string().regex(patterns.objectId),
})
.partial({ etcDetail: true }),
};

export const reportsSchema = zodToSchemaObject(reportsZod);

export type ReportsCreate = z.infer<typeof reportsZod.createHandler>;
44 changes: 0 additions & 44 deletions src/routes/docs/schemas/roomsSchema.js

This file was deleted.

52 changes: 52 additions & 0 deletions src/routes/docs/schemas/roomsSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { z } from "zod";
import patterns from "@/modules/patterns";
import { zodToSchemaObject } from "../utils";

export const roomsZod = {
searchRooms: z
.object({
name: z.string().regex(patterns.room.name),
from: z.string().regex(patterns.objectId),
to: z.string().regex(patterns.objectId),
time: z.string().refine((val) => !isNaN(Date.parse(val)), {
message: "Invalid ISO date format",
}),
withTime: z.coerce.boolean(),
maxPartLength: z.coerce.number().int().min(2).max(4),
isHome: z.coerce.boolean(),
})
.partial(),

roomIdQuery: z.object({
id: z.string().regex(patterns.objectId),
}),

createRoom: z.object({
name: z.string().regex(patterns.room.name),
from: z.string().regex(patterns.objectId),
to: z.string().regex(patterns.objectId),
time: z.string().refine((val) => !isNaN(Date.parse(val)), {
message: "Invalid ISO date format",
}),
maxPartLength: z.number().int().min(2).max(4),
}),

roomIdBody: z.object({
roomId: z.string().regex(patterns.objectId),
}),

commitSettlement: z.object({
roomId: z.string().regex(patterns.objectId),
}),

commitPayment: z.object({
roomId: z.string().regex(patterns.objectId),
}),
};

export const roomsSchema = zodToSchemaObject(roomsZod);

export type SearchRoomsParams = z.infer<typeof roomsZod.searchRooms>;
export type RoomIdQueryParams = z.infer<typeof roomsZod.roomIdQuery>;
export type CreateRoomBody = z.infer<typeof roomsZod.createRoom>;
export type RoomIdBody = z.infer<typeof roomsZod.roomIdBody>;
18 changes: 0 additions & 18 deletions src/routes/reports.js

This file was deleted.

20 changes: 20 additions & 0 deletions src/routes/reports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import express from "express";
import { validateBody } from "@/middlewares/zod";
import { reportsZod } from "./docs/schemas/reportsSchema";
import * as reportHandlers from "@/services/reports";
import { authMiddleware } from "@/middlewares";

const router = express.Router();

// 라우터 접근 시 로그인 필요
router.use(authMiddleware);

router.post(
"/create",
validateBody(reportsZod.createHandler),
reportHandlers.createHandler
);

router.get("/searchByUser", reportHandlers.searchByUserHandler);

export default router;
60 changes: 16 additions & 44 deletions src/routes/rooms.js → src/routes/rooms.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,57 @@
const express = require("express");
const { query, body } = require("express-validator");
const { validateBody } = require("../middlewares/zod");
const { roomsZod } = require("./docs/schemas/roomsSchema");
const router = express.Router();
import express from "express";
import { validateBody, validateQuery } from "../middlewares/zod";
import { roomsZod } from "./docs/schemas/roomsSchema";
import * as roomHandlers from "@/services/rooms";
import { authMiddleware, banMiddleware } from "@/middlewares";

const roomHandlers = require("@/services/rooms");
const validator = require("@/middlewares/validator").default;
const patterns = require("@/modules/patterns").default;
const router = express.Router();

// 조건(이름, 출발지, 도착지, 날짜)에 맞는 방들을 모두 반환한다.
router.get(
"/search",
[
query("name").optional().matches(patterns.room.name),
query("from").optional().isMongoId(),
query("to").optional().isMongoId(),
query("time").optional().isISO8601(),
query("withTime").toBoolean().optional().isBoolean(),
query("maxPartLength").optional().isInt({ min: 2, max: 4 }),
query("isHome").toBoolean().isBoolean(),
],
validator,
validateQuery(roomsZod.searchRooms),
roomHandlers.searchHandler
);

// 특정 id 방의 정산 정보를 제외한 세부사항을 반환한다.
router.get(
"/publicInfo",
query("id").isMongoId(),
validator,
validateQuery(roomsZod.roomIdQuery),
roomHandlers.publicInfoHandler
);

// 이후 API 접근 시 로그인 필요
router.use(require("@/middlewares/auth").default);
router.use(authMiddleware);

// 방 생성/참여전 ban 여부 확인
router.use(require("@/middlewares/ban").default);
router.use(banMiddleware);

// 특정 id 방 세부사항 보기
router.get(
"/info",
query("id").isMongoId(),
validator,
validateQuery(roomsZod.roomIdQuery),
roomHandlers.infoHandler
);

// JSON으로 받은 정보로 방을 생성한다.
router.post(
"/create",
[
body("name").matches(patterns.room.name),
body("from").isMongoId(),
body("to").isMongoId(),
body("time").isISO8601(),
body("maxPartLength").isInt({ min: 2, max: 4 }),
],
validator,
validateBody(roomsZod.createRoom),
roomHandlers.createHandler
);

// 방을 생성하기 전, 생성하고자 하는 방이 실제로 택시 탑승의 목적성을 갖고 있는지 예측한다.
router.post(
"/create/test",
[
body("from").isMongoId(),
body("to").isMongoId(),
body("time").isISO8601(),
body("maxPartLength").isInt({ min: 2, max: 4 }),
],
validator,
validateBody(roomsZod.createRoom),
roomHandlers.createTestHandler
);

// 새로운 사용자를 방에 참여시킨다.
// FIXME: req.body.users 검증할 때 SSO ID 규칙 반영하기
router.post(
"/join",
[body("roomId").isMongoId()],
validator,
validateBody(roomsZod.roomIdQuery),
roomHandlers.joinHandler
);

Expand All @@ -88,8 +61,7 @@ router.post(
// 모든 사람이 나갈 경우에도 방을 삭제하지 않는다.
router.post(
"/abort",
body("roomId").isMongoId(),
validator,
validateBody(roomsZod.roomIdQuery),
roomHandlers.abortHandler
);

Expand Down Expand Up @@ -130,4 +102,4 @@ router.post(
// roomHandlers.editHandler
// );

module.exports = router;
export default router;
44 changes: 28 additions & 16 deletions src/services/reports.js → src/services/reports.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
const { userModel, reportModel, roomModel } = require("@/modules/stores/mongo");
const { reportPopulateOption } = require("@/modules/populates/reports");
const { sendReportEmail } = require("@/modules/email");
const logger = require("@/modules/logger").default;
const reportEmailPage = require("@/views/reportEmailPage").default;
const { notifyReportToReportChannel } = require("@/modules/slackNotification");
import { RequestHandler } from "express";
import { userModel, reportModel, roomModel } from "@/modules/stores/mongo";
import { reportPopulateOption } from "@/modules/populates/reports";
import { sendReportEmail } from "@/modules/email";
import logger from "@/modules/logger";
import reportEmailPage from "@/views/reportEmailPage";
import { notifyReportToReportChannel } from "@/modules/slackNotification";
import { ReportsCreate } from "@/routes/docs/schemas/reportsSchema";

const createHandler = async (req, res) => {
export const createHandler: RequestHandler = async (req, res) => {
try {
const { reportedId, type, etcDetail, time, roomId } = req.body;
const { reportedId, type, etcDetail, time, roomId }: ReportsCreate =
req.body;
const user = await userModel.findOne({ _id: req.userOid, withdraw: false });

if (!user) {
return res
.status(400)
.json({ error: "User/report: no corresponding user" });
}

const creatorId = user._id;

const reported = await userModel.findOne({
Expand Down Expand Up @@ -43,9 +53,9 @@ const createHandler = async (req, res) => {

if (report.type === "no-settlement" || report.type === "no-show") {
const emailRoomName = room ? room.name : "";
const emailRoomId = room ? room._id : "";
const emailRoomId = room ? room._id.toString() : "";
const emailHtml = reportEmailPage[report.type](
req.origin,
req.origin ?? "https://taxi.sparcs.org",
reported.name,
reported.nickname,
emailRoomName,
Expand All @@ -64,10 +74,17 @@ const createHandler = async (req, res) => {
}
};

const searchByUserHandler = async (req, res) => {
export const searchByUserHandler: RequestHandler = async (req, res) => {
try {
// 해당 user가 신고한 사람인지, 신고 받은 사람인지 기준으로 신고를 분리해서 응답을 전송합니다.
const user = await userModel.findOne({ _id: req.userOid, withdraw: false });

if (!user) {
return res
.status(400)
.json({ error: "User/report: no corresponding user" });
}

const response = {
reporting: await reportModel
.find({ creatorId: user._id })
Expand All @@ -86,8 +103,3 @@ const searchByUserHandler = async (req, res) => {
});
}
};

module.exports = {
createHandler,
searchByUserHandler,
};
Loading