페이지 구조가 아래와 같이 모두 분리되어있다.
챌린지>단어문제
챌린지>단어오답노트
챌린지>문법문제
챌린지>문법오답노트
문제페이지는 AI를 통해 생성하고 questions 테이블(supabase)에 넣어주고,
오답노트 페이지는 questions 테이블과 user_answer 테이블의 is_corrected가 false인 문제의 정답을 뿌려주면 된다.
이게 말은 쉬운데 테이블 구성을 계획하고, 데이터를 받아오는 로직을 탠스택쿼리를 사용하여 작성하는 것이 어려웠다.

question 테이블 1개, user_answer 테이블 1개 = 총 2개user_info 테이블의 ‘user_id’가 user_answer 테이블의 user_id 같은 question_iduser_answer 테이블의 ‘question_id’는 question 테이블의 문제유형(type)이 단어/문법 나눠서 각 페이지에 보여주기
- questions 테이블 : AI로 생성된 문제 데이터를 넣음(데이터 저장)
- user_answer 테이블 : 오답 리스트를 불러오기 위한 테이블
// 'user_answer' 테이블에서 틀린문제만 가져오는 함수 정의
const fetchUserWrongAnswers = async (userId: string): Promise<UserAnswer[]> => {
const { data, error } = await supabase
.from("user_answer")
.select("*")
if (error) {
throw new Error(error.message);
}
return data;
};
// 'questions' 테이블에서 단어문제만 가져오는 함수
const fetchWordQuestions = async (): Promise<Questions[]> => {
const { data, error } = await supabase.from("questions").select("*");
if (error) {
throw new Error(error.message);
}
return data;
};
// TanStack Query - 유저의 오답 데이터 가져오기
const {
data: userAnswers,
error: userAnswersError,
isLoading: userAnswersLoading
} = useQuery({
queryKey: ["userAnswers", userId],
queryFn: () => fetchUserWrongAnswers(userId)
});
// TanStack Query로 단어문제 데이터 가져오기
const {
data: questions,
error: questionsError,
isLoading: questionsLoading
} = useQuery({
queryKey: ["questions"],
queryFn: () => fetchWordQuestions()
});
// 콘솔로 확인
console.log("userAnswers", userAnswers); // 오답
console.log("questions", questions); // 단어문제