[ 2024.09.10 TIL ] 아이템 시뮬레이터

박지영·2024년 9월 10일
0

Today I Learned

목록 보기
42/67
post-thumbnail

🎮 아이템 시뮬레이터

🧍‍♂️ 캐릭터 관련 기능

아이템 판매 API

  1. char_id를 url 파라미터로 전달받고 req에 item_code와 count를 전달받으며 인증 미들웨어를 거친다.

  2. 캐릭터 존재 여부, 아이템 존재 여부를 검증한다.

  3. 소지금 변경, 아이템 소지 여부에 따라 아이템 수량을 갱신한다.

  • 판매금 정산시 60%만 돌려받고 실수 연산을 회피하기 위해 60을 곱하고 100으로 나눴다.


4. 예시

  • 아이템 수량이 0이되면 컬럼이 삭제되게 구현했다.

📌 캐릭터의 인벤토리 내 아이템 목록 조회 API

  1. char_id를 url 파라미터로 전달받고 인증 받은 user 데이터 저장 후 캐릭터 존재 여부 판별

  2. 인벤토리 내 아이템 목록을 조회 후 반환

  • 이 부분을 좀 애먹었는데, inventory 테이블에 item_name 속성을 저장하고 있지 않다보니

    item 테이블을 join해서 가져와야하는 건 알고 있었지만 보여지는 데이터가

     {
       "item_code": 1,
       "item": {
         "item_name": "파멸의 반지"
       },
       "count": 2
     },

    이런식이여서 가공이 필요했다. map 함수를 이용해서 각 데이터마다 가공을 진행하고

    const result = inventory.map((x) => ({
       item_code: x.item_code,
       item_name: x.item.item_name,
       count: x.count,
    }));
    // result 
    {
       "item_code": 1,
       "item_name": "파멸의 반지",
       "count": 2
     }

    결과를 얻을 수 있었다.

캐릭터가 장착한 아이템 목록 조회 API

  1. 캐릭터의 id를 url 파라미터로 전달받고 인증 미들웨어를 거친 후 검증을 받는다.

  2. 장착한 아이템의 목록을 가져온 후 데이터를 가공하고 반환

  3. 예시

    인벤토리 내 아이템 목록 조회에서 약간 수정해서 구현했다.

게임 머니 얻는 API

  1. 캐릭터의 id를 url 파라미터로 전달받고 인증 미들웨어를 거친 후 캐릭터 검증을 받는다.

  2. 캐릭터의 현재 보유 머니에 + 100을 한 후 결과를 반환한다.

  3. 예시

🧥 아이템 관련 기능

📌 아이템 장착 API

  1. 장착할 캐릭터의 id를 url 파라미터로 전달받고 장착할 아이템을 req로 전달받으며 인증 미들웨어를 거친다.

  2. 캐릭터, 아이템, 착용 여부를 검증한다.

  3. 캐릭터 스탯 갱신, 착용 여부, 인벤토리 내 아이템 수량을 갱신하고 변경된 정보를 반환한다.

  4. 예시

  • 요구사항에 적힌 그대로 구현하니 잘 작동했다.

    한가지 걱정인 점은 아이템 수정으로 아이템의 스탯이 변경됐을 경우에

    캐릭터의 스탯에는 수정된 내용이 반영되지 못한다는 점이다.

    차후에 해결 방안을 생각해보도록 하겠다.

  • 아이템 장착 해제 테스트 중에 문제가 생겼는데 아이템을 장착하면

    수량에 상관없이 인벤토리 내 아이템이 삭제되는 것이다.

    뭐가 문제지 하고 테스트를 반복해보니 삭제 로직에 문제가 있다는 것을 깨닫고

    수량이 남아 있을 때도 삭제 분기로 넘어가는 inventory.count < 1 이 분기문이 문제가 있었다.

    조건을 실수로 inventory.count > 1으로 해야하는데 잘못 적었던 것이 문제였다.

📌 아이템 장착 해제 API

  1. 장착할 캐릭터의 id를 url 파라미터로 전달받고 장착 해제할 아이템을 req로 전달받으며 인증 미들웨어를 거친다.

  2. 캐릭터, 착용 여부를 검증한다.

  3. 캐릭터 스탯 갱신, 착용 여부, 인벤토리 내 아이템 수량을 갱신하고 변경된 정보를 반환한다.

  4. 예시

  • 아이템 장착 로직에서 몇가지만 수정하니 뚝딱 만들어졌다.

    테스트 중에 장착 로직에 문제가 있는 것을 발견했었는데

    분기문 조건을 잘못준 문제라서 간단히 해결되었다.

🎸 기타

세션스토리지 제거

세션스토리지에 토큰이 저장된다고 생각을 했었는데 DB를 전체적으로 확인해보니

하나도 저장되고 있지 않았다. 그래서 이유를 좀 찾아보니 세션스토리지는 보통 쿠키를 저장하는데

지금 사용하는 방식은 jwt 토큰을 authorization header를 통해서 전달하고 전달 받기 때문에

클라이언트든 서버든 jwt 토큰을 따로 저장해서 관리할 필요가 없기 때문이다.

express-session, express-mysql-session 라이브러리 제거

app.js 수정

에러 생성 함수 구현

중복된 코드를 줄이고 변경을 용이하게 하기위해 에러 처리를 모듈화

검증 로직 모듈화

검증 로직을 모듈화해놓은 함수들을 모은 파일 validations.js 생성

  1. 캐릭터 존재 여부 검증

     const char = await prisma.characters.findFirst({
       where: { char_id: +char_id, user_id: user },
     });
     if (!char) throw throwError("캐릭터가 존재하지 않습니다.", 404);

    중복된 코드가 많아서 모듈화

    export async function checkChar(prisma, char_id, user_id) {
    // 본인 계정의 캐릭터가 맞는지 검증
    const char = await prisma.characters.findFirst({
      where: { char_id: +char_id, user_id: +user_id },
    });
    // 본인 계정이 아닐 경우 에러 처리를 위한 분기
    if (!char) {
      const exist = await prisma.characters.findUnique({
        where: { char_id: +char_id },
      });
      if (!exist) {
        throw throwError("캐릭터를 찾을 수 없습니다.", 404);
      } else {
        throw throwError("권한이 없습니다.", 403);
      }
    }
    return char;
    }
    
    // 캐릭터 존재 여부
    await checkChar(prisma, char_id, user);
  2. 아이템 존재 여부

     const item = await prisma.items.findFirst({
       where: { item_code: +item_code },
     });
    
     if (!item) throw throwError("아이템이 존재하지 않습니다.", 404);

    중복된 코드가 많아서 모듈화

    export async function checkItem(prisma, item_code) {
     const item = await prisma.items.findFirst({
       where: { item_code: +item_code },
     });
    
     if (!item) throw throwError("아이템이 존재하지 않습니다.", 404);
     return item;
    }
    
    // 아이템 존재 여부
    const item = await checkItem(prisma, item_code);
  3. 인벤토리 내 아이템 소지 여부

     const isExistItem = await prisma.character_inventory.findFirst({
       where: { char_id: +char_id, item_code: +item_code },
     });
    export async function checkInventory(prisma, char_id, item_code) {
     const isExistItem = await prisma.character_inventory.findFirst({
       where: { char_id: +char_id, item_code: +item_code },
     });
     return isExistItem;
    }
    
    //  인벤토리에 아이템 소지 여부
    const inventory = await checkInventory(prisma, char_id, item_code);
  4. 아이템 착용 여부

    export async function checkEquip(prisma, char_id, item_code) {
     const alreadyEquip = await prisma.character_item.findFirst({
       where: { char_id: +char_id, item_code: +item_code },
     });
     return alreadyEquip;
    }
    
    // 아이템 착용 여부
    const alreadyEquip = await checkEquip(prisma, char_id, item_code);
    if (alreadyEquip) throw throwError("이미 착용 중인 아이템입니다.", 409);

    여러 기능들을 구현하면서 같은 코드를 계속 치고 있다는 느낌을 많이 받았다. 그래서 요구하는 것이 같은 코드들을 함수화해서 모듈로 따로 구현해보았다. 추후 필요할때마다 추가할 예정이다.

📌 commit 취소

인증 미들웨어에서 받아오는 user 객체의 사용례를 통일시킬려고 했는데 바꾸니까

캐릭터 상세 조회, 아이템 구매, 판매 등에서 문제가 생겨서 원래대로 되돌리는 이슈가 있었다.

git log --oneline 으로 commit 내역을 확인하고

git reset --soft HEAD~1로 최신 commit 내역을 되돌렸다.

profile
신입 개발자

0개의 댓글