-
Notifications
You must be signed in to change notification settings - Fork 0
기술 기획서
Dohyeon Han edited this page Dec 14, 2022
·
35 revisions
- 팀원들 모두가 TypeScript를 사용해본 경험이 있어서 별도 학습이 많이 요구되지 않았습니다.
- 프론트와 백에 같은 언어를 사용함으로써, 기본적인 문법을 통일함으로써 더욱 원활한 소통을 할 수 있습니다.
- 코드 작성 시 매번 타입을 결정해야 하기 때문에 번거롭고 코드량이 증가하지만, 정적 타입 언어로 코드 작성 단계에서 에러를 체크할 수 있습니다. 이 장점으로 버그를 발견하고, 해결하는 시간을 단축시킬 수 있습니다.
- yarn berry와 npm 사이에 고민을 했으나, 팀원들 모두 yarn berry 경험이 없어서 짧은 개발기간을 고려하여 기존에 익숙한 npm을 사용하기로 하였습니다.
- 프로젝트 기간이 짧아, 팀원들이 모두 이미 잘 알고 있는 React를 사용하는 것이 생산성을 높일 수 있다고 생각했습니다.
- 커뮤니티가 큽니다.
- Best practice 를 찾기가 쉽다고 생각합니다.
- 상용화된 라이브러리가 많습니다.
- Angular, Vue 와 달리 React 는 라이브러리기 때문에, JavaScript 언어를 알고 있다면 프론트엔드 지식이 부족해도 이해하기 수월합니다. -> 풀스택 작업이 더 수월해집니다.
- JSX 문법 덕분에 HTML 과 JS 코드 작성이 효율적입니다.
- Why use react
- 현재 중앙상태로 관리할 값들의 형태가 단순하고, Type에 따라 다르게 동작하거나 별도 로직이 필요한 상황이 아니기 때문에, 상대적으로 구조가 간단한 recoil을 사용하기로 함.
- recoil vs redux
- HTML 태그를 직관적으로 인지하기 쉽습니다. 따라서 Semantic 하게 태그를 작성할 수 좋습니다.
- Javascript (또는 Typescript) 파일 내에 CSS를 작성할 수 있어 편리합니다
- 팀원 중 한 명은 이미 emotion 경험이 있고 다른 팀원의 경우에 다른 css 프레임워크를 사용해왔지만, 새로운 css 도구에 대한 경험을 하고 싶어해서 emotion을 선택함.
- 백엔드 서버를 구현하기 위한 기능이 Nest.js 프레임워크 자체에 포함되어 있습니다. -> 짧은 기간에 서버를 만들기 수월하다고 생각했습니다.
- Nest.js 는 구조가 정해져 있어서 협업을 진행할 때 일관성을 유지할 수 있습니다.
- 새로운 학습을 해야되서 시간적 손해가 있을 수 있지만, 공식 문서가 잘 정리되어있는 편이기 때문에 그 부분에 대한 부담을 해소할 수 있다고 생각합니다.
- Why use Nest.js
- Nest.js DOCS
- MongoDB
- Mongoose
- Github Action
- 배포하는 클라우드(NCloud)
API 주소 | API 유형 | 기능 | 그룹 | 비고 |
---|---|---|---|---|
/api/auth/logout | GET | 로그아웃 | 회원관리 (auth) | |
/api/auth/check | GET | 로그인 여부 확인 | 회원관리 (auth) | 현재 로그인이 되어 있는지 여부를 쿠키를 통해 확인 |
/api/users/validate?id=ABC | GET | 아이디 중복 및 유효성 확인 | 회원관리 (user) | 아이디는 쿼리스트링으로 전송, 아이디 유효성 및 중복 체크 |
/api/users/register | POST | 회원가입 | 회원관리 (user) | |
/api/users/withdraw | DELETE | 회원 탈퇴 | 회원관리 (user) | DB에서도 데이터 아예 삭제 |
/api/users/edit | PUT | 상세프로필 수정 | 프로필 | |
/api/users/:id | GET | 상세프로필 열람 | 프로필 | 아이디나 고유값은 쿼리스트링으로 전송 |
/api/users?interest=frontend&skill1=A&skill2=B&skill3=C&liked=true&pages=1 | GET | 간략한 프로필 리스트 열람 | 프로필 리스트 | 쿼리가 있으면 쿼리 내용에 맞춰 필터링, 쿼리가 없을 경우 전체 리스트 가져오기, 페이지네이션 적용 |
/api/like | POST | 좋아요 추가 | 좋아요 | 새로운 좋아요 정보가 DB에 저장되므로, POST |
/api/like | DELETE | 좋아요 삭제 | 좋아요 | 기존의 좋아요 정보가 DB에서 삭제되므로 DELETE |
- client 에서 바로 OAuth 인증 서버로 a 태그 이용
- 리디렉션이 깃허브 또는 구글에서 오므로, 데이터를 보낼 수 없어 쿠키만을 전달
- 성공 시
res.cookie(token).redirect('localhost:3000');
- 실패 시
res.status(401).redirect('localhost:3000').error(400);
-
아이디와 같은 내용물은 쿠키 안에 들어있는 토큰에서 읽어들이기
-
성공 시
res.status(200);
- 실패 시
res.status(400);
- 성공 시
res.status(200).send({
code: 10000,
message: '성공',
data: {
id, // 로그인 상태 체크 성공
},
}
- 실패 시
res.status(401).send({
code: 20003,
message: '로그인 상태가 아닙니다.'
});
- 성공 시
res.status(200).send({
code: 10000,
message: '유효한 ID 입니다.',
});
- 실패 시
// 아이디 유효성 체크 실패
res.status(401).send({
code: 10001,
message: '유효하지 않은 ID 입니다.',
});
// 아이디 중복 체크 실패
res.status(401).send({
code: 10002,
message: '중복된 ID 입니다.',
});
- 보내는 데이터
{
username: 'limited-hyeon', // 입력한 유저 이름
interest: INTERESTS.FRONTEND, // 관심 분야, 상수값 => 프론트엔드, 백엔드에서 공용으로 사용
techStack: [SKILLS.REACT, SKILLS.VUE] // 기술 스택, 상수값 => 프론트엔드, 백엔드에서 공용으로 사용
}
- 성공 시
res.status(200).send({
code: 10000,
message: '성공.'
});
// 회원가입 성공 후 리디렉션 처리는 프론트엔드에서 분기를 나누어 진행
- 실패 시
res.status(400).send({
code: 20004,
message: '회원가입 실패'
});
-
아이디와 같은 내용물은 쿠키 안에 들어있는 토큰에서 읽어들이기
-
성공 시
res.status(200).send({
code: 200,
message: '탈퇴 성공'
});
- 실패 시
res.status(400).send({
code: 400,
message: '탈퇴 실패'
});
- 보내는 데이터
{
username: 'limited-hyeon',
code: `console.log('hello world');\nreturn(0);`,
interest: INTERESTS.FRONTEND,
techStack: [SKILLS.REACT, SKILLS.TYPESCRIPT],
worktype: '페어 프로그래밍, 잠실역 근처'
worktime: '새벽은 타협 가능하고 오후 1시부터 항상 비어있어요'
email: '[email protected]'
requirements: ['잠실사는사람만', '소통좋아해요'],
}
- 성공 시
res.status(200).send({
code: 200,
message: '정보 변경 성공'
});
- 실패 시
res.status(400).send({
code: 400,
message: '정보 변경 실패'
});
// 정보 변경 실패할 경우 프론트엔드에서 alert 띄워주기
- 성공 시
res.status(200).send({
code: 200,
message: '정보 변경 성공',
data: {
username: 'limited-hyeon',
code: `console.log('hello world');\nreturn(0);`,
interest: INTERESTS.FRONTEND,
techStack: [SKILLS.REACT, SKILLS.TYPESCRIPT],
worktype: '페어 프로그래밍, 잠실역 근처'
worktime: '새벽은 타협 가능하고 오후 1시부터 항상 비어있어요'
email: '[email protected]'
requirements: ['잠실사는사람만', '소통좋아해요'],
liked: true
}
});
- 실패 시
res.status(400).send({
code: 400,
message: '정보 수신 실패'
})
// 정보 수신 실패할 경우 프론트엔드에서 alert 띄워주고, 리스트 화면으로 리디렉션
- 성공 시
res.status(200).send({
code: 200,
message: '정보 변경 성공',
data: {
totalPage: 10, // 전체 페이지 수
currentPage: 5, // 현재 페이지 번호
totalNumOfData: 63, // 총 데이터 개수
list: [
{
id: '', // 상세 페이지 조회 및 좋아요 용도
language: 'JavaScript',
code: `console.log('hello world');\nreturn(0);`, // 프론트엔드에서 잘라서 사용
techStack: [SKILLS.REACT, SKILLS.TYPESCRIPT],
requirements: ['잠실사는사람만', '소통좋아해요'],
liked: true
},
{
id: '',
language: 'JavaScript',
code: `console.log('hello world');\nreturn(0);`,
techStack: [SKILLS.REACT, SKILLS.TYPESCRIPT],
requirements: ['잠실사는사람만', '소통좋아해요'],
liked: true
},
...
]
}
});
- 실패 시
res.status(400).send({
code: 400,
message: '정보 수신 실패'
})
// 정보 수신 실패할 경우 프론트엔드에서 alert 띄워주기
- 보내는 데이터
{
likedId: '' // 좋아요한 상대방의 아이디
}
- 성공 시
res.status(200).send({
code: 200,
message: '좋아요 성공'
});
- 실패 시
res.status(400).send({
code: 400,
message: '좋아요 실패'
});
// 좋아요 실패할 경우 프론트엔드에서 alert 띄워주기?
- 보내는 데이터
{
likedId: '' // 좋아요한 상대방의 아이디
}
- 성공 시
res.status(200).send({
code: 200,
message: '좋아요 취소 성공'
});
- 실패 시
res.status(400).send({
code: 400,
message: '좋아요 취소 실패'
});
// 좋아요 실패할 경우 프론트엔드에서 alert 띄워주기?
- 10000번대 성공 코드
- 20000번대는 auth 관련 실패 코드
- 30000번대는 프로필 관련 실패 코드
- 40000번대는 좋아요 관련 실패 코드
code | description |
---|---|
10000 | 성공 |
20001 | 유효하지 않은 ID 입니다. |
20002 | 중복된 ID 입니다. |
20003 | 로그인 상태가 아닙니다. |
20004 | 회원가입 실패 |
20005 | 유효하지 않은 authorization code입니다. |
40001 | 이미 좋아요 리스트에 존재하는 사용자입니다. |
페이지 주소 | 기능 | 비고 |
---|---|---|
/ | 메인 페이지 | /main 으로 리디렉션 |
/?stack=frontend&filter1=A&filter2=B&filter3=C&liked=true | 메인 페이지 (필터와 함께) | 쿼리가 있으면 쿼리 내용에 맞춰 필터링, 쿼리가 없을 경우 전체 리스트 렌더링 |
/login | 로그인 페이지 | |
/detail/ABC | 유저의 상세페이지 열람 | id는 주소에 붙이기 |
/mypage | 유저 자신의 페이지 열람 |
- 📃 기획서
- 📂 Backlog
- 📊 ERD, 폴더 구조
- 🗓️ 회의록