1차 프로젝트 회고

서동희·2023년 7월 7일
0

팀명: SJG

기획

  • 클론 코딩 사이트 선정과정
  • pet분석
  • 구현하고 싶었던 기능
  • ERD 작성

클론 코딩 사이트 선정 과정
우리 팀원은 기본적으로 "제품"에 초점을 맞추기보다는
그 회사가 잠재적 소비자를 "구매자" 또는 "우리가 서비스를 제공할 수 있는 고객" 둘중에 어떤 식으로 보고 있는지에 집중했다. 또한 사이트에서 제공되는 서비스를 재화로 한정하지 않고 회사가 추구하고자 하는 가치를 제품에 녹이기 것 까지 하나의 제공되는 서비스로 보고 기업이 어떤 가치를 추구하고 제공하는 지 분석했다.

이솝이라는 사이트는 "화장품"은 그저 단순 재화가 아닌 친환경적인 제품을 만들겠다는 철학을 담아 여러가지 피부타입을 가진 사람들에게 제공될 수 있는 하나의 가치를 담고 있는 제품으로 보았고 소비자, 잠재적 유저를 "우리가 서비스를 제공 할수 있는" 고객으로 보는
이솝이라는 사이트의 철학과 유입되는 유저 플로워를 클론하기로 하였다

PET분석

이솝
P(product): 친환경적인 물품
E(end-user): 선택폭이 넓은 사이트에서 구매하려는 고객, 화장품의 특성상 매일 사러 오는것보다는 가끔사는 유저, 선물하려는 유저(대리구매)
T(tech): 상세페이지 필터링 , 장바구니 기능 , 결제기능 , 마이페이지

우리는 이솝의 PET를 클론하여 우리의 가치를 담은 물품을 가상으로 판매하고자 했고
PET가 일치하는 친환경타일이라는 새로운 제품을 팔아보기로 했다

친환경타일
P(product) :친환경 , 라돈이 검출되지 않는 타일
E(end-user): 인테리어의 선택폭이 넓은 사이트에서 구매하려는 고객, 타일의 특성상 가끔 사는 유저, 대량 구매를 하는 법인 구매자 (이솝의 대리 구매 형태로 보았음)
T(tech): 아래 상의 내용에 따름

구현하고자 했던 기능
기획단계에서는 모든 팀원이 여러가지 기능에 대한 의견을 나왔지만 2주라는 한정적인 시간안에 구현해야 하므로 구현 사항에 우선순위를 두고 프로젝트를 시작하기로 협의 했다 우리팀의 구현사항 우선순위는 다음과 같다

  1. 사업자 개인을 따로 관리하는 회원가입 로그인
  2. 장바구니 사용기능 (수량추가, 수량삭제, 제품삭제 )
  3. 상품리스트 pagination sorting filtering으로 구현
  4. 포인트기반으로 결제 시스템 구현
  5. 마이페이지로 계정정보와 주문내역 불러오기

백엔드 입장에서 위의 기능들을 구현하기 위한 기술들은 다음과 같았다

  • 회원가입&로그인 - 유효성검사 : 사업자는 10자리, 개인은 이메일 형식만 받을 수 있도록하고 비밀번호는 8~20자이상 특수문자 필수 작성→ 조건 불충족 시 버튼 비활성화
    → 비밀번호 유효성 검사 구현
  • 회원가입을 할 때 사업자 or 개인으로 회원가입을 할 수 있게 한다.
    여기서 type을 1,2로 나눠서 저장한다.
    메인페이지, 카테고리에 제품과 해당하는 정보들을 불러들일 수 있도록 데이터베이스를 연결한다.
  • 로그인 할 시 token 발급 api 발급
  • 물품 장바구니에 넣을 때 수량 +,-로 정할 시 정한 수량 들어가는 API 구현
  • 물건 상품 세부 정보를 데이터베이스에서 GET 메소드를 활용하여, 제품별 해당하는 정보들을 불러옴.
  • 장바구니에 담긴 물품을 +,-버튼을 누르면 수량변경 가능한 api 구현
  • 결제하기에 들어갈 때 인증되지 않은 비회원은 로그인을해서 토큰을 받아 들어올 수 있게 구현한다

ERD작성

개발과정과 회고
-내가 맡은 역활및 기능, 사용한 기술
-구현하면서 새롭게 배운점
-공유하고 싶은 나의 코드
-스스로에게 만족했거나 아쉬웠던점
-팀프로젝트시 좋았던점과 중요하다고 생각되는것
-시연영상

내가 맡은 역활,기능 사용한 기술

1.회원가입
-> 사업자 개인을 따로 관리하는 회원가입 API구현
2.장바구니 불러오기
-> mysql join 문을 이해하여 프론트에게 양질의 정보 제공
3.마이페이지 계정정보, 주문내역 불러오기
4.회원가입 성공후 해당 유저에게 웰컴 이메일 보내기
-> nodemailer라는 모듈을 이용하여 회원가입 유저에게 웰컴이메일 보내기

구현하면서 새롭게 배운점

1.유지보수 중요성 - 프로젝트는 내 코드는 다른 팀원이 보기에도 가독성이 좋고 유지보수가 편리해야한다는 것을 깨달았다
2.구조분해할당개념 -해당 구문은 배열이나 객체의 속성을 분해해서 그 값을 변수에 담을 수 있게 하는 표현식으로 내가 원하는 값을
효율 적으로 도출할 수 있게 되었다
3.mysql 문 응용 - join 문의 특성을 활용하여 여러 테이블을 연결해 데이터 추출이 가능하도록 구현할 수 있게 되었다

공유하고 싶은 나의 코드

1.회원가입

const signUp = async (typeId, name, email, password, account) => {
  const emailRegex =
    /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;
  const passwordRegex = /^(?=.*[a-z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})/;
  const accountRegex = /^[0-9]{10}$/;

  if (typeId === 1) {
    if (!emailRegex.test(email)) {
      const error = new Error('INVALID_USER_EMAIL');
      error.statusCode = 400;
      throw error;
    }

    if (!passwordRegex.test(password)) {
      const error = new Error('INVALID_USER_PASSWORD');
      error.statusCode = 400;
      throw error;
    }
  } else {
    if (account && !accountRegex.test(account)) {
      const error = new Error('INVALID_USER_ACCOUNT');
      error.statusCode = 400;
      throw error;
    }
  }

사업자 유형이 1번이면이메일 ,패스워드 유효성검사
그외 유형이라면 사업자번호 추가적으로 유효성검사를 하는 service 단의 코드

  1. 장바구니 불러오기
const queryCartItems = async (userId) => {
  try {
    const data = await dataSource.query(
      `
      SELECT
      users.id AS userId,
      users.name,
      users.email,
      carts.product_id AS productId,
      categories.title AS kindId,
      products.name AS tileName,
      products.sub_category_id AS sizeId,
      products.surface_type_id AS surfaceTypeId,
      products.price AS price,
      products.weight AS weight,
      products.image_url AS imageUrl,
      SUM(carts.quantity) AS quantity
    FROM
      carts
    JOIN
      users ON carts.user_id = users.id
    LEFT JOIN
      products ON carts.product_id = products.id
    JOIN
      sub_categories ON products.sub_category_id = sub_categories.id
    JOIN
      categories ON sub_categories.category_id = categories.id
    WHERE
      users.id = ?
    GROUP BY
      users.id,
      users.name,
      users.email,
      carts.product_id,
      categories.title,
      products.name,
      products.sub_category_id,
      products.surface_type_id,
      products.price,
      products.weight,
      products.image_url
        `,
      [userId]
    );
    return data;
  } catch (err) {
    const error = new Error('DATABASE_QUERY_ERROR');
    error.statusCode = 400;
    throw error;
  }

JOIN문과 GROUP문을 이용하여 효율적으로 정보를 프론트에 전달할수 있는 dao의 코드

3.웰컴이메일

;
 sendEmail(email);
  return createUser;
};

const transporter = nodemailer.createTransport({
  service: process.env.EMAIL_SERVICE,
  auth: {
    user: process.env.EMAIL_USER,
    pass: process.env.EMAIL_PASSWORD,
  },
});

const sendEmail = function (userEmail) {
  console.log(userEmail);
  const mailOptions = {
    from: 'Sujeongwa6@gmail.com',
    to: userEmail,
    subject: 'WELCOME TO SJG',
    html: `<div
    style="
      width: 70vw;
      height: 70vh;
      background: #fffef2;
      border: 3px solid #333;
      padding: 1em;
      margin: 2em auto;
    "
  >
    <div
      style="
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        border: 2px solid #331;
        width: 70vw;
        height: 70vh;
      "
    >
      <p style="font-size: 30px; border-bottom: 1px solid #333">
        <strong>WELCOME TO SJG TILE!</strong>
      </p>
      <div style="line-height: 10px; text-align: center">
        <div style="margin-bottom: 50px; font-size: 16px; line-height: 15px">
          <p>ENJOY YOUR NEVER-EXPIRING WELCOME GIFT OF</p>
          <u style="font-weight: 800; font-size: 18px">10,000,000 WON</u>
          <p>YOU CAN USE IT AT ANY TIME.</p>
        </div>
        <div style="line-height: 15px">
          <p>SJG타일에 가입하신 것을 환영합니다!!.</p>
          <p>
            유효기간이 없는
            <u style="font-weight: 800; font-size: 18px">10,000,000포인트</u
            >를 지급했습니다.
          </p>
          <p>언제든 사용하세요!</p>
        </div>
      </div>
    </div>
  </div>`,
  };
  try {
    const info = transporter.sendMail(mailOptions);
    console.log('EMAIL_SENT ' + info.response);
  } catch (error) {
    console.log(error);
    throw error;
  }
};

nodeemailer를 통해 자동으로 이메일을 보내는 기능
본기능은 https://www.youtube.com/watch?v=klDTBiW6iiM 해당 유튜브를 참고했습니다

스스로에게 만족하거나 아쉬운점

만족한부분 - 부트캠트에서 가장 중요한것은 개발자로써의 자세를 가져가는 것이라고 말씀해주셨는데, 정말 못하겠다 싶을 때 한번 더 보거나, 팀원들과 공유해서 오류를 찾고 코드가 작동하게 하는 태도를 배워서 뿌듯했습니다
아쉬운부분 - 같은 매소드의 티켓이 할당되어서 여러가지 매소드 API를 다루지 못한 것이 아쉬웠습니다

팀프로젝트시 좋았던점과 중요하다고 생각되는것

우리 팀은 서로 안되는 부분을 같이 공유하고 서로 도와주는 분위기에서 프로젝트가 진행되서 좋았습니다
아쉬웠던 점은 기획에서 더 많은 부분이 협의후 진행하지 못하고, 중간에 협의되고 진행된 부분이 많아 아쉬웠습니다
다음 프로젝트에서는 더 꼼꼼히 기획하여 진행되고 있는 프로젝트의 사이클을 멈추는 일이 없도록 해야겠다는 생각을 했습니다
제가 느끼는 팀프로젝트에서 가장중요하다고 느끼는 것은 소통입니다
팀내 소통이 잘되면 일을 두번 할일 없이 효율적으로 진행할수 있기 때문에 팀내 소통이 가장 중요한 요소라고 생각됩니다

시연영상링크
https://youtu.be/5nZVLyE-FF4

profile
백엔드개발자

0개의 댓글