[2024.06.21 TIL] 내일배움캠프 47일차 (팀프로젝트 마무리, 개인 KPT 회고)

My_Code·2024년 6월 21일
0

TIL

목록 보기
60/112
post-thumbnail

본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.


💻 TIL(Today I Learned)

📌 Today I Done

✏️ Keep - 현재 만족하고 있는 부분

  • 팀원들이 모르는 부분을 혼자만 앓고 있는 게 아니라 적극적으로 질문하는 점

  • 문제가 발생했을 때 팀원들과 공휴하면서 해결하는 점

  • 늦은 시간까지 과제를 진행해도 끝까지 열심히 노력하는 점

  • 서로 존중하면서 적극적으로 의견을 나누는 점


✏️ Problem - 불편하게 느끼는 부분

  • 프로젝트 파일 관리의 부족

  • 코드 양식에 대해 조금 더 구체적인 설계 부족


✏️ Try - Problem에 대한 해결책, 당장 실행 가능한 것

  • 프로젝트 파일 관리의 부족은 아무래도 각자의 작업 파일을 조금 더 카테고리화 시켜서 분리해서 작업하는 방법을 생각해볼 수 있음. 즉, 설계 단계에서 기능별로 폴더를 생성시켜서 폴더 구조를 정형화 시킬 필요가 있어 보임

  • 이번에 프로젝트를 하면서 각자가 맡은 부분을 진행할 때, 변수나 메서드의 형식이 너무나도 달라서 서로 혼동이 있었음. 그렇기에 서로 조금 더 구체적인 규칙(양식)을 만들 필요가 있어 보임. 예를 들면, 데이터베이스에서 데이터를 조회할 때는 get~, 생성할 때는 create~, 수정할 때는 update~, 삭제할 때는 delete~ 와 같이 정할 필요가 있어 보임



📌 Tomorrow's Goal

✏️ 피로 누적으로 인한 휴식 예정



📌 Today's Goal I Done

✔️ 팀프로젝트 개인 KPT 회고

  • 드디어 이번에 진행한 팀프로젝트가 끝났음

  • 조금 더 난이도 있는 과제를 하고 싶었지만, 혼자만의 욕심으로 팀원들을 힘들게 할 수 없었기에 지금까지의 과제에 대한 약간의 복습이라고 생각하면서 진행함

  • 특히 팀원들이 에러에 대한 질문을 하면 나도 에러를 해결하는 능력을 기를 수 있고, 다른 사람들에게 나의 생각을 설명하는 것을 연습하는 좋은 기회가 되었음



⚠️ 구현 시 발생한 문제

✔️ AWS의 S3에 데이터가 쌓이기만 하는 문제

  • 이번 과제에서 AWS의 S3와 Multer를 이용해서 이미지를 업로드하는 코드를 구현했음

  • Insomnia에서 이미지를 업로드하면 S3에 가서 이미지에 대한 URL를 받아옴

  • 이 때, 이미지의 데이터는 S3에 쌓이게 됨

  • 데이터베이스에서 이미지를 삭제하는 것과는 무관하게 계속 쌓이기만 함

  • 그렇게 쌓이면 안된다고 느꼈기에 삭제하는 방법을 찾아봄

  • 찾아보니 S3에 저장된 이미지를 삭제하는 기능을 추가하려면 AWS SDK를 이용하여 deleteObject 메서드를 사용하면 된다고 함

  • 우선 버킷에서 데이터를 삭제할 함수를 만듦

// S3 이미지 삭제 함수
export const deleteImage = async (key) => {
  try {
    const params = {
      Bucket: process.env.AWS_BUCKET,
      Key: key,
    };

    await s3.deleteObject(params);
  } catch (err) {
    console.log(err);
    throw new HttpError.InternalServerError(PETSITTERMESSAGES.PETSITTER.SERVICE.ERROR);
  }
};
  • 자격증 삭제할 때 S3에 있는 이미지도 삭제하기 위해서 아래와 같이 작성
  ...
  
  // 펫시터 자격증 삭제
  deleteCertificate = async (petsitterId, certificateId) => {
    const deletedCertificate = await this.prisma.certificate.delete({
      where: { petsitterId, certificateId },
    });

    const existingImageKey = extractKeyFromUrl(deletedCertificate.imageUrl);
    await deleteImage(existingImageKey);

    return deletedCertificate.certificateId;
  };
}

// URL에서 S3 key 추출 함수
const extractKeyFromUrl = (url) => {
  const urlParts = url.split('/');
  // URL의 마지막 부분이 key가 됩니다.
  const key = urlParts.slice(3).join('/');
  return key;
};
  • 위에서 작성한 코드는 단일 객체, 즉 한 장의 이미지를 삭제할 때의 코드임

  • 그럼 여러 장의 이미지(객체)를 삭제하려면 어떻게 해야 할까?

  • 아래는 기존에 S3의 객체를 삭제하지 않고 데이터베이스의 이미지 URL만 삭제하는 코드

  // 펫시터 정보 수정
  updatePetsitter = async (
    petsitterId,
    petsitterName,
    petsitterCareer,
    petsitterProfileImage,
    title,
    content,
    region,
    price,
    images,
    petsitter
  ) => {
    const updatedPetsitter = await this.prisma.$transaction(async (tx) => {
      const updatedData = await tx.petsitter.update({
        where: { petsitterId },
        data: {
          // 입력된 데이터가 있으면 수정하고 없으면 생략
          ...(petsitterName && { petsitterName }),
          ...(petsitterCareer && { petsitterCareer }),
          ...(petsitterProfileImage && { petsitterProfileImage }),
          ...(title && { title }),
          ...(content && { content }),
          ...(region && { region }),
          ...(price && { price }),
        },
      });

      // 비밀번호는 제외하고 반환
      updatedData.password = undefined;

      // 사진이 있는 펫시터 정보
      let houseImage = petsitter.houseImage;

      // 이미지 수정
      if (images.length !== 0) {
        await tx.houseImage.deleteMany({ where: { petsitterId: petsitter.petsitterId } });
        houseImage = await Promise.all(
          images.map(async (image) => {
            return await tx.houseImage.create({
              data: { petsitterId: petsitter.petsitterId, imageUrl: image.location },
            });
          })
        );
      }
      return [updatedData, houseImage];
    });

    return updatedPetsitter;
  };
  • 여러 장의 이미지(객체)를 삭제하려면 아래와 같이 작성해야 함
  // 펫시터 정보 수정
  updatePetsitter = async (
    petsitterId,
    petsitterName,
    petsitterCareer,
    petsitterProfileImage,
    title,
    content,
    region,
    price,
    images,
    petsitter
  ) => {
    const updatedPetsitter = await this.prisma.$transaction(async (tx) => {
      const updatedData = await tx.petsitter.update({
        where: { petsitterId },
        data: {
          // 입력된 데이터가 있으면 수정하고 없으면 생략
          ...(petsitterName && { petsitterName }),
          ...(petsitterCareer && { petsitterCareer }),
          ...(petsitterProfileImage && { petsitterProfileImage }),
          ...(title && { title }),
          ...(content && { content }),
          ...(region && { region }),
          ...(price && { price }),
        },
      });

      // 비밀번호는 제외하고 반환
      updatedData.password = undefined;

      // 기존 이미지 URL을 가져옴
      const existingImages = await tx.houseImage.findMany({
        where: { petsitterId: petsitter.petsitterId },
      });

      // 사진이 있는 펫시터 정보
      let houseImage = petsitter.houseImage;

      // 이미지 수정
      if (images.length !== 0) {
        // S3에 있는 기존 이미지 삭제
        for (const img of existingImages) {
          const existingImageKey = extractKeyFromUrl(img.imageUrl);
          if (existingImageKey) {
            await deleteImage(existingImageKey);
          }
        }
        // 데이터베이스에 있는 기존 이미지 삭제
        await tx.houseImage.deleteMany({ where: { petsitterId: petsitter.petsitterId } });
        houseImage = await Promise.all(
          images.map(async (image) => {
            return await tx.houseImage.create({
              data: { petsitterId: petsitter.petsitterId, imageUrl: image.location },
            });
          })
        );
      }
      return [updatedData, houseImage];
    });

    return updatedPetsitter;
  };

참고자료

profile
조금씩 정리하자!!!

0개의 댓글