Skip to content

1.0.0 (2025. 01. 16)

Choose a tag to compare

@cjeongmin cjeongmin released this 16 Jan 09:14
· 58 commits to main since this release

Release 1.0.0 (2025. 01. 16)

프로젝트 전반적으로 성능 개선과 유지보수성과 확장 가능한 설계를 위한 작업을 주로 이뤘습니다.

BE

RBAC 도입 (PR #9) (Wiki)

[배경]

Ask-It 각 사용자에게 아래와 같은 역할을 부여합니다

  • 슈퍼호스트

    • Q&A 세션 페이지를 생성한 사용자
  • 서브호스트

    • SuperHost에 의해 host가 되어 Q&A 세션페이지의 관리(댓글 삭제 등)를 맡는 사용자
  • 참가자

    • 세션 페이지에 참여하여 질문과 채팅을 남기는 일반 참여자

각 참가자는 아래와 같은 권한을 행사할 수 있습니다.

권한 슈퍼 호스트 서브 호스트 참가자
1. 세션 종료 O X X
2. 타인에게 호스트 권한 부여 O X X
3. 타인의 호스트 권한 해제 O X X
4. 질문 삭제 O O X
5. 답변 삭제 O O X
6. 질문 고정 O O X
7. 질문에 대한 답변 완료 기능 O O X

[문제]

기존의 권한 처리 로직은 IF 분기문을 통해 처리하였습니다.

예를 들어 사용자가 질문 삭제를 요청하였다면 아래와 같이 처리합니다.

async deleteQuestion(questionId: number, question: Question, { token }: BaseDto) { 
const { isHost } = await this.sessionAuthRepository.findByToken(token);

if(!isHost)
  throw new ForbiddenException('권한이 없습니다.');
	// 이하 생략...
}

그러나 서비스의 권한정책이 다음과 같이 변한다고 가정해봅니다.

  • 서브호스트가 서브서브호스트를 생성합니다.
  • 질문의 삭제는 서브서브호스트만이 가능합니다.

그렇다면 다음과 같은 추가 처리가 필요합니다.

  • DB 수정
  • DB 수정에 따른 DB 접근 로직 변경(어떤 테이블에서 어떤 데이터를 가져올 것인가)
  • 서비스 로직 변경(사용자가 서브서브호스트일때만 질문 삭제가 가능하도록)

즉, 서비스의 정책이 변경되어 역할과 권한이 수정 및 확대된다면 많은 코드가 변경되어야 하며, 이는 유지보수 및 확장에 장애가 됩니다.

[해결]

  • 기존에 퍼져있는 권한 조건을 DB 스키마 변경을 통해 RBAC기반 권한 관리로 수정했습니다.
  • 역할과 권한 테이블을 만든 후에 다대다 관계를 맺어줬습니다.
  • 이를 통해 다음과 같은 권한 관리를 구현했습니다.
async deleteQuestion(questionId: number, question: Question, { token }: BaseDto) {
  const { role } = await this.sessionAuthRepository.findByTokenWithPermissions(token);
  const granted = role.permissions.some(
    ({ permissionId }) => permissionId === Permissions.DELETE_QUESTION,
  );

  if (!granted)
	throw new ForbiddenException('권한이 없습니다.');
  // 이하 생략...
}

[결과]

  • 단순 분기문을 통한 기존의 권한 관리를 RBAC 기반의 권한 관리로 변경하였습니다.
  • 차후 서비스 정책상 권한이 수정되어도 코드의 변경 없이 DB 데이터만을 변경하여 해결할 수 있습니다.
  • 이를 통해 권한의 수정과 역할의 확장이 용이해지는 결과를 얻을 수 있었습니다.

FE

모달 애니메이션 추가 (PR #11)

$RS81H3R

모달을 이용한 사용자 경험이 많은 Ask-It 서비스 특성상 모달의 사용자 경험은 중요합니다.

모달이 열리고 닫히는 부분에 자연스러운 애니메이션을 추가하여 사용자 경험을 향상시켰습니다.

Lighthouse 성능 개선 (PR #19)

개선 전 개선 후
image image

랜딩페이지에서 초기 렌더링 부분에서 아쉬운 성능을 보이는 것을 확인했습니다.

폰트 로딩 최적화와 코드 스플리팅을 통한 초기에 다운로드 해야하는 번들 크기가 감소되어 초기 렌더링 부분에서 성능을 향상시킬 수 있었습니다.

렌더링 성능 최적화 (PR #22, PR #24)

개선 전 개선 후
개선 전 개선 후

부하테스트 과정 중, 채팅창의 변화가 다른 컴포넌트의 렌더링에 영향을 미치는 것을 확인했습니다.

질문이 많아 질문 목록의 컴포넌트가 굉장히 커져있는 상태에서 새로운 채팅이 올라와 새롭게 렌더링되는 것은 사용자 경험에도 부정적인 영향을 미치는 것을 확인했습니다.

zustand 이용하여 전역 상태를 관리하고 있는 상황에서, 많은 부분에서 스토어의 특정 상태, 액션만을 구독하는 것이 아닌 객체 자체를 구독하고 있어 객체의 변경에 쉽게 영향을 받는 것을 확인할 수 있었습니다.

이를 스토어의 특정 상태를 가져오는 selector 함수를 메모이제이션하는 useShallow 라는 훅을 이용하여 렌더링을 최적화하였습니다.

- const { sessionId, sessionToken, expired, addQuestion, updateQuestion } = useSessionStore();
+ const { sessionId, sessionToken, expired, addQuestion, updateQuestion } = useSessionStore(
+  useShallow((state) => ({
+    sessionId: state.sessionId,
+    sessionToken: state.sessionToken,
+    expired: state.expired,
+    addQuestion: state.addQuestion,
+    updateQuestion: state.updateQuestion,
+  })),
+ );

현재, 질문 목록, 답변 목록, 채팅창 부분에서 굉장히 많은 요소들이 렌더링 되는 것에 대해서는 현재 아무런 처리가 되어 있지 않아 가상 스크롤과 같은 기법을 추가하여 성능 최적화를 추가적으로 진행하고자 하고 있습니다.

What's Changed

New Contributors

Full Changelog: https://github.com/boostcampwm-2024/refactor-web07-Ask-It/commits/v1.0.0