과제를 시작하기 전 유의사항
•
기술 과제의 제한 시간은 총 기능 개발 6시간 입니다.
•
•
디테일을 챙길 수 있도록 과제를 꼼꼼히 읽어주세요.
사전 설정
과제를 진행하기 전, 아래 안내사항에 따라 사전 설정을 진행 해주세요.
Git 저장소 만들기
1.
아래 파일을 다운로드 받은 후, 압축 파일을 풀어주세요
프로젝트 파일
이후, 깃 저장소를 만들어주세요
$ git init
Bash
복사
2.
$ yarn install
$ yarn dev
Shell
복사
Github 원격 저장소 만들기
1.
a.
Repository name: toss-invest-profile
b.
Public/Private: Private
2.
레포지토리 화면에서 [Settings] > [Collaborators] 로 이동하고, [Add people] 를 클릭해주세요.
3.
toss-fe-interview 계정을 Collaborator로 초대해주세요.
작업 준비하기
다시 로컬 레포지토리가 있는 디렉토리로 돌아와서 아래 작업을 진행해주세요.
1.
로컬 레포지토리와 GitHub 원격 저장소를 연결합니다.
로컬 레포지토리에서 git remote add 명령어를 이용하여 방금 생성한 GitHub 원격 레포지토리를 연결합니다. origin 에 현재 로컬 레포지토리의 main 브랜치를 푸시합니다.
$ git push -u origin main
Shell
복사
필요하다면 GitHub 계정의 ID/PW로 로그인을 진행해주세요.
2.
작업용 브랜치 feature 를 생성합니다.
$ git checkout -b feature
# (또는 Git 2.23 이상인 경우, git switch -c feature)
Shell
복사
3.
생성한 feature 브랜치가 과제를 제출할 브랜치가 됩니다.
과제 개요
투자자들이 자신의 투자 성향을 쉽게 파악할 수 있도록 설문 기반의 “투자성향 진단 서비스”를 구현해주세요.
이 서비스는 서버에서 설문 목록을 불러와서 사용자가 응답을 입력할 때마다 클라이언트에서 실시간으로 점수를 계산해서 표시해요. 사용자가 마지막 설문에 응답하면 서버에 결과를 제출하여 진단 결과와 개별 질문 점수를 함께 받아와 화면에 표시해요.
또한, 사용자가 설문 도중에 나가면 “이어서 하기” 기능을 통해 저장된 응답을 불러와 이어서 진행할 수 있어요.
과제 요구사항
문제를 푸는 시간이 제한되어 있습니다. 기한 안에 과제를 제출할 수 있도록 시간에 유의해주세요.
•
마크업과 스타일은 이미 대부분 구현되어 있지만 기능이 구현되어 있지 않아요. 요구사항에 맞게 서비스를 완성해주세요.
•
사용자 경험을 개선하고 싶은 지점이 있다면 구현에 포함시키거나 README 등에 문서로 남겨주세요.
•
의문점이 있다면 스스로 합리적인 가설을 세우고 계속 진행해주세요.
•
완성을 위해 필요한 라이브러리가 있다면 자유롭게 사용해주세요.
•
실행 환경은 node 22와 Google Chrome 등 모던 브라우저를 권장해요.
•
화려한 방법보다는 평소에 하던 가장 익숙한 방법으로 문제를 해결할 것을 권장합니다.
1. 인트로 페이지 (src/pages/IntroPage.tsx)
1.
“진단 시작하기” 버튼을 누르면 설문 퍼널로 이동해주세요.
2. 설문 퍼널 (src/pages/QuestionPage.tsx)
1.
설문 목록은 설문지 받아오기 (GET) API 를 통해 불러올 수 있어요.
a.
응답을 설문지 id 값을 기준으로 오름차순으로 정렬한 후, 이 순서에 맞춰 설문을 진행해주세요.
2.
각 설문에 대해서 응답 값에 있는 설문 유형(type)에 따라 알맞은 컴포넌트를 구현해주세요.
a.
binary (<BinaryQuestion />)
b.
multiple (<MultipleQuestion />)
c.
scale (<ScaleQuestion />)
3.
사용자가 각 설문에 답할 때마다 상단 중앙의 스코어 영역에 누적 점수(totalScore)와, 이를 기반으로 한 예상 투자 성향을 실시간으로 계산하여 업데이트 해주세요.
a.
예상 투자 성향의 기준 totalScore 값은 아래와 같아요.
i.
안정형: 0 ~ 10점
ii.
균형형: 10점 ~ 20점
iii.
공격형: 20점 이상
b.
프로그레스 바에는 최대 20점을 기준으로 현재 점수를 표시해주세요.
4.
“다음” 버튼을 누르면 다음 설문을 보여주세요.
a.
만약 현재 설문 유형이 binary 이고, 사용자가 응답한 옵션 하위에 subQuestions 가 있다면, 해당 설문 목록을 페이지를 넘어가며 순서대로 보여주세요. (단, subQuestions 에는 중첩된 하위 설문은 없어요)
b.
만약 설문에 모두 응답했다면 결과 페이지로 이동해주세요.
3. 이어서 하기 기능
[설문 페이지]
1.
“이어서 하기” 저장 기능을 구현해주세요. 상단 네비게이션 바의 “<(뒤로가기)” 버튼을 누르면 “저장하기 모달”을 보여주세요.
a.
“저장하고 나가기” 버튼을 누르면 지금까지 입력한 응답을 이어하기 저장 (PUT) API 로 서버에 저장하고 인트로 페이지로 이동해주세요.
b.
“닫기” 버튼을 누르면 모달을 닫아주세요.
[인트로 페이지]
1.
이어하기 정보 가져오기 (GET) API 로 이전 정보를 받아온 후, “이어서 하기” 유무에 따라 CTA(버튼) 문구를 변경하여 이어서 진행하도록 분기 처리해주세요.
a.
이어서 하기가 저장되어 있지 않은 경우: [진단 시작하기]
b.
이어서 하기가 저장되어 있는 경우: [이어서 하기]
c.
이어서 하기 저장 기능은 2. 설문 퍼널 에서 구현할 예정이에요.
2.
“이어서 하기” 버튼을 누르면 이전에 진행하던 설문 단계 부터 시작할 수 있도록 처리해주세요.
4. 결과 페이지 (src/pages/ResultPage.tsx)
1.
사용자가 마지막 질문에 응답하면 클라이언트에서 계산한 값을 최종 제출 (POST) API를 활용해 서버에 보내주세요.
2.
결과 페이지에서는 서버 응답을 기반으로 다음을 화면에 표시해주세요.
a.
총점(totalScore) 및 내 투자 성향(type)
3.
“다시 시작하기” 버튼을 누르면 서버에 저장된 이어서 하기 데이터를 초기 상태로 리셋하고 인트로 페이지로 보내주세요.
API 문서
yarn dev 로 개발 서버를 실행시켜 API를 테스트할 수 있어요.
손쉬운 API 사용을 위해 http client 구현체를 미리 제공하고 있어요. tosslib 패키지에서 아래와 같이 import 해서 사용할 수 있어요.
import { http, isHttpError } from 'tosslib';
// GET /api/continue
const { answers } = await http.get<{ answers: Answer[] | null }>(
'/api/continue',
);
console.log(answers);
// PUT /api/continue
await http.put('/api/continue', {
json: {
answers: [
// ...
]
},
});
// API 오류 캐치하기
try {
await http.post(...);
} catch (e) {
if (isHttpError(e)) {
console.log(e.message);
}
}
TypeScript
복사
1.
설문지 받아오기 (GET)
export type Question = {
id: number;
type: "binary" | "multiple" | "scale";
question: string;
options?:
Array<{ label: string; score: number }> | // multiple 일 때만
{
yes: BinaryOption;
no: BinaryOption;
}; // binary 일 때만
maxSelect?: number; // multiple 일 때만
scaleRange?: { min: number; max: number; minLabel: string; maxLabel: string; scoreUnit: number }; // scale 일 때만
};
export type BinaryOption = {
label: string;
score: number;
subQuestions?: Question[];
};
GET /api/questions
Response:
[
{
"id": 1,
"type": "binary",
"question": "상위 질문 텍스트",
"options": {
"yes": {
"label": "예",
"score": 1,
"subQuestions": [
{
"id": 2,
"type": "binary",
"question": "하위 질문 (yes 선택 시)",
"options": {
"yes": {
"label": "예",
"score": 0.5
},
"no": {
"label": "아니오",
"score": 0
}
}
},
{
"id": 3,
"type": "multiple",
"question": "또 다른 하위 질문",
"options": [
{ "label": "옵션 A", "score": 1 },
{ "label": "옵션 B", "score": 0.5 }
],
"maxSelect": 2
}
]
},
"no": {
"label": "아니오",
"score": 0
}
}
},
{
"id": 4,
"type": "multiple",
"question": "다중 선택 질문 예시",
"options": [
{ "label": "옵션 1", "score": 1 },
{ "label": "옵션 2", "score": 0.5 }
],
"maxSelect": 2
},
{
"id": 5,
"type": "scale",
"question": "슬라이더 질문 예시",
"scaleRange": { "min": 1, "max": 5, "scoreUnit": 1 }
}
]
TypeScript
복사
2.
이어하기 저장 (PUT)
PUT /api/continue
Request Body:
{
"answers": Array<{
questionId: number,
answer:
| "yes" // binary type 질문에서 “예” 선택
| "no" // binary type 질문에서 “아니오” 선택
| string[] // multiple type 질문에서 선택된 label 배열
| number // scale type 질문에서 슬라이더 값
}> | null
}
Response:
{
"answers": [...] // 저장한 답변값
}
TypeScript
복사
3.
이어하기 정보 가져오기 (GET)
GET /api/continue
Response:
{
"answers": Array<{
questionId: number,
answer:
| "yes" // binary type 질문에서 “예” 선택
| "no" // binary type 질문에서 “아니오” 선택
| string[] // multiple type 질문에서 선택된 label 배열
| number // scale type 질문에서 슬라이더 값
}> | null
}
TypeScript
복사
4.
최종 제출 (POST)
POST /api/submit
Request Body:
{
"answers": Array<{
questionId: number,
answer:
| "yes" // binary type 질문에서 “예” 선택
| "no" // binary type 질문에서 “아니오” 선택
| string[] // multiple type 질문에서 선택된 label 배열
| number // scale type 질문에서 슬라이더 값
score: number;
}>
}
Response:
{
// 서버에서 계산한 총점.
// 만약, 답변 내용이 유효하지 않거나 답변에서 계산된 점수의 합이 서버에서 계산한 총점과
// 일치하지 않다면 오류가 발생해요.
"totalScore": number,
// 서버에서 산출한 투자 유형
"type": "안정형" | "균형형" | "공격형",
}
TypeScript
복사
제출 방법
변경점 Pull Request 생성 하기
1.
작업이 완료되면 feature 브랜치를 GitHub 원격 저장소에 푸시해주세요.
2.
제한 시간 안에 브랜치를 GitHub에 푸시해주세요.
3.
작업이 잘 되었다면 GitHub에 다시 접속했을 때 [Compare & Pull Request] 초록색 버튼이 보여요.
4.
[Compare & Pull Request] 버튼을 누르고 Pull Request를 생성해주세요. Pull Request의 제목이나 내용은 자유롭게 작성해주세요.
과제 링크 제출하기 (필수)
1.
발송된 [2025 토스 NEXT] OO님 사전 과제 안내드립니다. 메일 하단의 링크로 접속해주세요.
2.
과제를 수행하신 GitHub 저장소 링크를 가장 하단 textarea에 입력하신 후 Submit 버튼을 눌러주세요.
3.
정상적으로 과제가 제출되었으면 Submit 버튼을 누른 후 이동하는 페이지에서 Thanks for your submission. 문구가 보여요.
이 문제의 저작권은 주식회사 비바리퍼블리카에 있으며, 지원자는 오로지 채용을 위한 목적으로만 이 문제를 활용할 수 있습니다. 이 문제의 전부 또는 일부를 공개, 게재, 배포, 제3자에게 제공하는 등의 일체의 “누설 행위”에 대해서는 저작권법에 의해 민・형사상의 책임을 질 수 있습니다. 이 "누설 행위"에는 문제의 문구를 변형하여 그 취지를 알 수 있도록 하는 경우도 포함됩니다.















