Skip to content

Commit 57931b9

Browse files
authored
[#99] 터보레포 공통 패키지 스키마 zod 적용 (#105)
* feat: 스키마 zod 모노레포 패키지 추가 * fix: 회원가입 에러 메세지 수정
1 parent 33ff8e7 commit 57931b9

File tree

10 files changed

+82
-36
lines changed

10 files changed

+82
-36
lines changed

.eslintrc.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
11
module.exports = {
2-
extends: '@medi-map/eslint-config'
2+
root: true,
3+
env: {
4+
node: true,
5+
es2021: true
6+
},
7+
parser: '@typescript-eslint/parser',
8+
plugins: ['@typescript-eslint'],
9+
extends: [
10+
'eslint:recommended',
11+
'plugin:@typescript-eslint/recommended'
12+
],
13+
rules: {
14+
'semi': 'error',
15+
'@typescript-eslint/no-unused-vars': 'error'
16+
}
317
};

apps/express-server/src/controllers/signupController.ts

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,27 @@ import { createUser, findUserByEmail } from '@/services/authService';
44
import { generateAccessToken, generateRefreshToken } from '@/utils/generateToken';
55
import { AUTH_MESSAGES } from '@/constants/auth_message';
66
import { storeRefreshToken } from '@/services/refreshTokenService';
7-
8-
// 유효성 검사 함수
9-
const validateSignupInput = (username: string, email: string, password: string): string | null => {
10-
if (!username || username.length < 3 || username.length > 30) {
11-
return AUTH_MESSAGES.USERNAME_INVALID;
12-
}
13-
14-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
15-
if (!email || !emailRegex.test(email)) {
16-
return AUTH_MESSAGES.EMAIL_INVALID;
17-
}
18-
19-
if (!password || password.length < 8) {
20-
return AUTH_MESSAGES.PASSWORD_INVALID;
21-
}
22-
23-
return null;
24-
};
7+
import { validateUser } from '@medi-map/validation';
258

269
// 회원가입 처리
2710
export const signup = async (req: Request, res: Response): Promise<Response> => {
2811
const { username, email, password } = req.body;
2912

3013
try {
3114
// 유효성 검사
32-
const validationError = validateSignupInput(username, email, password);
33-
if (validationError) {
34-
console.error('Validation error:', validationError);
35-
return res.status(400).json({ message: validationError });
15+
const validationResult = validateUser(req.body);
16+
17+
if (!validationResult.success) {
18+
const flattenedErrors = validationResult.error.flatten().fieldErrors;
19+
20+
console.error('Validation error:', flattenedErrors);
21+
22+
const [firstField, firstMessages] = Object.entries(flattenedErrors)[0];
23+
24+
return res.status(400).json({
25+
message: firstMessages[0],
26+
field: firstField
27+
});
3628
}
3729

3830
// 이메일 중복 확인

apps/next-client/src/app/auth/signup/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ export default function SignupPage() {
5959
</Link>
6060
</>
6161
);
62-
}
62+
}

apps/next-client/src/hooks/useSignupActions.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,6 @@ export const useSignupActions = ({
2020
const router = useRouter();
2121

2222
const handleSignup = async () => {
23-
if (!username || !email || !password) {
24-
setError(
25-
!username
26-
? '사용자명을 입력해 주세요.'
27-
: !email
28-
? '이메일을 입력해 주세요.'
29-
: '비밀번호를 입력해 주세요.'
30-
);
31-
return;
32-
}
33-
3423
try {
3524
const response = await signup({ username, email, password });
3625

cloud_sql_proxy

-19.1 MB
Binary file not shown.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@
2929
"prettier --write --ignore-unknown"
3030
]
3131
},
32-
"packageManager": "yarn@1.22.19"
32+
"packageManager": "yarn@1.22.19",
33+
"main": "index.js",
34+
"repository": "git@github.com:f-lab-edu/medi_map.git",
35+
"license": "MIT"
3336
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const AUTH_MESSAGES = {
2+
USERNAME_REQUIRED: '사용자명을 입력해 주세요.',
3+
USERNAME_INVALID: '사용자 이름은 3자 이상 30자 이하여야 합니다.',
4+
5+
EMAIL_REQUIRED: '이메일을 입력해 주세요.',
6+
EMAIL_INVALID: '유효한 이메일 주소를 입력해주세요.',
7+
8+
PASSWORD_REQUIRED: '비밀번호를 입력해 주세요.',
9+
PASSWORD_INVALID: '비밀번호는 최소 8자 이상이어야 합니다.',
10+
};

packages/validation/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "@medi-map/validation",
3+
"version": "1.0.0",
4+
"main": "src/index.ts",
5+
"types": "src/index.ts",
6+
"dependencies": {
7+
"zod": "^3.24.1"
8+
}
9+
}

packages/validation/src/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { z } from 'zod';
2+
import { AUTH_MESSAGES } from '../auth_message';
3+
4+
const userSchema = z.object({
5+
username: z
6+
.string()
7+
.min(1, AUTH_MESSAGES.USERNAME_REQUIRED)
8+
.min(3, AUTH_MESSAGES.USERNAME_INVALID)
9+
.max(30, AUTH_MESSAGES.USERNAME_INVALID),
10+
11+
email: z
12+
.string()
13+
.min(1, AUTH_MESSAGES.EMAIL_REQUIRED)
14+
.email(AUTH_MESSAGES.EMAIL_INVALID),
15+
16+
password: z
17+
.string()
18+
.min(1, AUTH_MESSAGES.PASSWORD_REQUIRED)
19+
.min(8, AUTH_MESSAGES.PASSWORD_INVALID),
20+
});
21+
22+
export const validateUser = (data: unknown) => {
23+
return userSchema.safeParse(data);
24+
};

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6563,6 +6563,11 @@ yocto-queue@^0.1.0:
65636563
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
65646564
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
65656565

6566+
zod@^3.24.1:
6567+
version "3.24.1"
6568+
resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.1.tgz#27445c912738c8ad1e9de1bea0359fa44d9d35ee"
6569+
integrity sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==
6570+
65666571
zustand@^5.0.0-rc.2:
65676572
version "5.0.0"
65686573
resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.0.tgz#71f8aaecf185592a3ba2743d7516607361899da9"

0 commit comments

Comments
 (0)