Skip to content

기술 기획서

Dohyeon Han edited this page Dec 14, 2022 · 35 revisions

기술 기획서

기술 스택

언어 - TypeScript

  • 팀원들 모두가 TypeScript를 사용해본 경험이 있어서 별도 학습이 많이 요구되지 않았습니다.
  • 프론트와 백에 같은 언어를 사용함으로써, 기본적인 문법을 통일함으로써 더욱 원활한 소통을 할 수 있습니다.
  • 코드 작성 시 매번 타입을 결정해야 하기 때문에 번거롭고 코드량이 증가하지만, 정적 타입 언어로 코드 작성 단계에서 에러를 체크할 수 있습니다. 이 장점으로 버그를 발견하고, 해결하는 시간을 단축시킬 수 있습니다.

패키지 매니저

npm

  • yarn berry와 npm 사이에 고민을 했으나, 팀원들 모두 yarn berry 경험이 없어서 짧은 개발기간을 고려하여 기존에 익숙한 npm을 사용하기로 하였습니다.

FE

React

  • 프로젝트 기간이 짧아, 팀원들이 모두 이미 잘 알고 있는 React를 사용하는 것이 생산성을 높일 수 있다고 생각했습니다.
  • 커뮤니티가 큽니다.
    • Best practice 를 찾기가 쉽다고 생각합니다.
    • 상용화된 라이브러리가 많습니다.
  • Angular, Vue 와 달리 React 는 라이브러리기 때문에, JavaScript 언어를 알고 있다면 프론트엔드 지식이 부족해도 이해하기 수월합니다. -> 풀스택 작업이 더 수월해집니다.
    • JSX 문법 덕분에 HTML 과 JS 코드 작성이 효율적입니다.
  • Why use react

recoil

  • 현재 중앙상태로 관리할 값들의 형태가 단순하고, Type에 따라 다르게 동작하거나 별도 로직이 필요한 상황이 아니기 때문에, 상대적으로 구조가 간단한 recoil을 사용하기로 함.
  • recoil vs redux

emotion css

  • HTML 태그를 직관적으로 인지하기 쉽습니다. 따라서 Semantic 하게 태그를 작성할 수 좋습니다.
  • Javascript (또는 Typescript) 파일 내에 CSS를 작성할 수 있어 편리합니다
  • 팀원 중 한 명은 이미 emotion 경험이 있고 다른 팀원의 경우에 다른 css 프레임워크를 사용해왔지만, 새로운 css 도구에 대한 경험을 하고 싶어해서 emotion을 선택함.

BE

Nest.js

  • 백엔드 서버를 구현하기 위한 기능이 Nest.js 프레임워크 자체에 포함되어 있습니다. -> 짧은 기간에 서버를 만들기 수월하다고 생각했습니다.
  • Nest.js 는 구조가 정해져 있어서 협업을 진행할 때 일관성을 유지할 수 있습니다.
  • 새로운 학습을 해야되서 시간적 손해가 있을 수 있지만, 공식 문서가 잘 정리되어있는 편이기 때문에 그 부분에 대한 부담을 해소할 수 있다고 생각합니다.
  • Why use Nest.js
  • Nest.js DOCS

Jest + Cypress

DB

  • MongoDB
  • Mongoose

Production

  • Github Action
  • 배포하는 클라우드(NCloud)

ERD

image

디자인 및 기능 상세

Figma

API 명세

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

데이터 명세

Github, Google 로그인

  • client 에서 바로 OAuth 인증 서버로 a 태그 이용
  • 리디렉션이 깃허브 또는 구글에서 오므로, 데이터를 보낼 수 없어 쿠키만을 전달
  • 성공 시
res.cookie(token).redirect('localhost:3000');
  • 실패 시
res.status(401).redirect('localhost:3000').error(400);

/api/auth/logout

  • 아이디와 같은 내용물은 쿠키 안에 들어있는 토큰에서 읽어들이기

  • 성공 시

res.status(200);
  • 실패 시
res.status(400);

/api/auth/check

  • 성공 시
res.status(200).send({
  code: 10000,
  message: '성공',
  data: {
    id, // 로그인 상태 체크 성공
  },
}
  • 실패 시
res.status(401).send({
  code: 20003,
  message: '로그인 상태가 아닙니다.'
});

/api/auth/validate

  • 성공 시
res.status(200).send({
  code: 10000,
  message: '유효한 ID 입니다.',
});
  • 실패 시
// 아이디 유효성 체크 실패
res.status(401).send({
  code: 10001,
  message: '유효하지 않은 ID 입니다.',
});

// 아이디 중복 체크 실패
res.status(401).send({
  code: 10002,
  message: '중복된 ID 입니다.',
});

/api/auth/register

  • 보내는 데이터
{
  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: '회원가입 실패'
});

/api/auth/withdraw

  • 아이디와 같은 내용물은 쿠키 안에 들어있는 토큰에서 읽어들이기

  • 성공 시

res.status(200).send({
  code: 200,
  message: '탈퇴 성공'
});
  • 실패 시
res.status(400).send({
  code: 400,
  message: '탈퇴 실패'
});

/api/users/edit

  • 보내는 데이터
{
  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 띄워주기

/api/users/:id

  • 성공 시
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 띄워주고, 리스트 화면으로 리디렉션

/api/users?interest=frontend&skill1=A&skill2=B&skill3=C&liked=true&pages=1

  • 성공 시
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 띄워주기

/api/like (POST)

  • 보내는 데이터
{
  likedId: '' // 좋아요한 상대방의 아이디
}
  • 성공 시
res.status(200).send({
  code: 200,
  message: '좋아요 성공'
});
  • 실패 시
res.status(400).send({
  code: 400,
  message: '좋아요 실패'
});
// 좋아요 실패할 경우 프론트엔드에서 alert 띄워주기?

/api/like (DELETE)

  • 보내는 데이터
{
  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 유저 자신의 페이지 열람  

얼리버드

프로젝트

개발일지

스프린트 계획

멘토링

데일리 스크럼

데일리 개인 회고

위클리 그룹 회고

스터디

Clone this wiki locally