FrontEnd Develop/Project : AI TUTOR

STT 라우팅과 비동기 처리 분리하기: 실전 리팩토링 사례

Frisbeen 2025. 5. 5. 01:58

"2025년 5월 4일, 라우팅 흐름부터 API 처리까지, 실전 개발 중 맞닥뜨린 문제들과 그 해결 과정"

 


✨ 문제의 시작: 비동기 처리와 라우팅이 엉킨다

처음엔 단순한 흐름이라고 생각했다.

 

기획자와 논의한 유저 플로우:

  1. 사용자가 수업 영상 파일을 업로드하고 "다음" 버튼을 누른다.
  2. 노트를 생성한다 (createNote).
  3. STT 변환을 시작한다 (createSTT).
  4. STT가 끝나면 다음 페이지로 router.push() 한다.
  5. 다음 페이지에서 STT 결과를 기반으로 요약문을 생성한다.

⚠️ 기존 코드 구조 (문제 있는 구조)

const handleNoteNextBtn = async () => {
  const createdNote = await createNote(folderId, { title: noteName });
  const noteId = createdNote.noteId;

  await createSTT(folderId, noteId, file); // 🔴 문제: 오래 걸림
  router.push(`/notes/${folderId}/${noteId}/confirm`);
};

문제점

  • STT는 수십 초 이상 걸리는 연산이므로 사용자는 화면이 멈춘 것처럼 인지한다.
  • STT 실패 시 화면 전환도 되지 않고 에러도 제대로 표시되지 않는다.
  • 버튼 하나에 너무 많은 역할 (note 생성 + STT 처리 + 페이지 이동)을 부여함 

내가 생각했던  해결 전략: 3단계 분리

1. 노트 생성은 현재 페이지 (NotesPage) 에서 수행

const handleNoteNextBtn = async () => {
  const createdNote = await createNote(folderId, { title: noteName });
  const noteId = createdNote.noteId;

  router.push(`/notes/${folderId}/${noteId}/confirm`); // 🚀 빠르게 이동
};
  • createSTT는 실행하지 않고, 오직 노트 생성만 책임짐
  • file, noteId 는 글로벌 컨텍스트로 넘김 (예: usePracticeContext)

2. STT 처리: ConfirmNotePage 에서 useEffect로 처리

useEffect(() => {
  const runSTT = async () => {
    if (file) {
      await createSTT(Number(folderId), Number(noteId), file);
      setSttLoading(false);
    }
  };
  runSTT();
}, []);
  • 이 페이지는 STT 처리만 수행
  • 로딩 중이면 Lottie 기반 <Loader /> 보여줌 

3. STT 완료 후 요약문 생성 → 다음 페이지 이동

const handleNoteFinalBtn = async () => {
  await summaryNote(folderId, noteId, keywords, requirement);
  router.push(`/notes/${folderId}/${noteId}/create-practice`);
};
  • 핵심 키워드와 요구사항은 TabComponent 를 통해 입력받음
  • 버튼 클릭 시 요약 요청 API 호출 후 최종 페이지 이동

 결과적으로 얻은 이점

  • 비동기 요청과 화면 전환을 분리하여 사용자 경험 향상
  • 각 페이지가 하나의 명확한 책임만 갖도록 단일 책임 원칙을 지킴
  • 로딩 UI를 통해 사용자의 불안 감소
  • 컨텍스트 API와 useParams를 통해 라우팅 상태와 앱 상태를 유기적으로 연결

회고

이번 개선은 단순히 코드 리팩토링 그 이상이었다. 백엔드 API 구조를 바꾸지 않고도, Next.js의 페이지 단위 설계 철학을 따르는 것만으로도 UX를 크게 향상시킬 수 있었다.

"비동기는 다음 페이지에 위임하라."

복잡한 처리일수록 현재 컴포넌트에서 해결하려 하지 말고, 다음 단계로 책임을 분산시카는 태도를 갖는게 좋을 것 같았다.