Skip to content

[JDDEV-82] [JDDEV-65] 자소서 제출 구현#61

Merged
yiyoonseo merged 1 commit into
developfrom
feature/JDDEV-82-cl_save-api
May 22, 2026
Merged

[JDDEV-82] [JDDEV-65] 자소서 제출 구현#61
yiyoonseo merged 1 commit into
developfrom
feature/JDDEV-82-cl_save-api

Conversation

@yiyoonseo
Copy link
Copy Markdown
Contributor

@yiyoonseo yiyoonseo commented May 22, 2026

🔗 관련 이슈

  • Close #

📝 개요

  • 자소서 제출 API 연동

⌨️ 작업 상세 내용

버그 수정

  • saveApply에서 스코프에 없는 변수 questions를 참조하던 문제 수정
  • 답변 제출 시 배열 인덱스(0, 1, 2…)를 questionId로 사용해 QUESTION_4041 에러가 발생하던 문제 수정

API 연동

  • PATCH /mock-applies/{id}/questions/answers 요청 바디를 스펙에 맞게 변경
    • 기존: 잘못된 필드 매핑 / 수정: { answers: [{ questionId, answer }] }
  • GET /questions/candidates, GET /questions 응답에서 백엔드 question ID(questionId / id)를 파싱해 저장하도록 수정

컴포넌트 수정

  • InputSectionHandlegetAnswers() 메서드 추가 — ref를 통해 부모에서 작성된 답변 수집 가능
  • WritePageClient 제출 시 saveApply 호출 추가
    • "제출하기", 글자 수 부족 모달의 "확정하기" 모두 적용

💡 코드 설명 및 참고사항

변경 사항

  • saveApply 함수 버그 수정 — 존재하지 않는 변수 questions 참조 → answers 파라미터로 교체
  • PATCH /questions/answers 요청 바디를 API 스펙에 맞게 수정 ({ answers: [{ questionId, answer }] })
  • QuestionApiItem / QuestionItemquestionId 필드 추가 — 인덱스 대신 DB ID를 답변 제출 시 사용
  • fetchQuestions (candidates), fetchSelectedQuestions 모두 백엔드 question ID를 매핑하도록 수정
  • InputSectionHandlegetAnswers() 추가 — 부모 컴포넌트에서 답변 수집 가능
  • WritePageClient에서 제출 시 saveApply 호출 연동 (글자 수 부족 모달의 "확정하기"도 동일하게 처리)

📸 스크린샷 (UI 변경 시)

🔍 리뷰 요구사항 (Reviewers)

  • [ ]

⚠️ 로컬 실행 시 유의사항

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

The PR adds answer persistence to the virtual application write flow. It introduces an AnswerItem type and saveApply() API function, extends InputSection to expose answers via an imperative getAnswers() handle, and updates WritePageClient to gather and save answers before navigating to the result page.

Changes

Virtual Apply Answer Persistence

Layer / File(s) Summary
Answer persistence API contract and question mapping
jobdri/src/lib/api/questions.ts
QuestionItem includes optional questionId; new exported AnswerItem interface (questionId, answer); fetchQuestions and fetchSelectedQuestions populate questionId from API responses; new saveApply(mockApplyId, answers) function PATCHes answers to the backend.
Answer extraction from InputSection
jobdri/src/components/apply/InputSection.tsx
StoredQuestion extends with optional questionId field; InputSectionHandle interface adds getAnswers(): AnswerItem[] method; useImperativeHandle implementation maps stored questions to answer objects with questionId and current text.
Page submission with answer persistence
jobdri/src/app/apply/virtual/[id]/write/WritePageClient.tsx
saveApply imported and integrated; new internal submit() async function reads answers via inputRef.getAnswers(), calls saveApply(Number(id), answers), then navigates; handleSubmit and modal's primary action delegate to submit() instead of direct navigation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • JobDri-Developer/FrontEnd#57: Both PRs modify jobdri/src/components/apply/InputSection.tsx write-flow data/imperative ref API, with this PR extending it to expose getAnswers + questionId so WritePageClient can call saveApply.

Suggested reviewers

  • minnngo

Poem

🐰 A form that saves with grace so fine,
Answers gathered, packed in line,
PATCH requests off they go,
To persistence down below,
Navigation waits to glow ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly reflects the main objective of the PR: implementing self-introduction submission API integration and bug fixes related to question ID mapping.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/JDDEV-82-cl_save-api

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jobdri/src/components/apply/InputSection.tsx`:
- Around line 125-129: The getAnswers mapping currently falls back to the loop
index for questionId, which can produce non-DB IDs and recreate QUESTION_4041;
update the getAnswers implementation in InputSection.tsx to use only
question.questionId (no index fallback) and fail-fast when it's missing—e.g.,
throw an error or set/return a validation failure that blocks submit if
question.questionId is undefined for any question; ensure answersById is still
used for answer values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a85fba20-67c8-45a3-a9d6-7aa211e257f6

📥 Commits

Reviewing files that changed from the base of the PR and between e91569d and 3a6e0a1.

📒 Files selected for processing (3)
  • jobdri/src/app/apply/virtual/[id]/write/WritePageClient.tsx
  • jobdri/src/components/apply/InputSection.tsx
  • jobdri/src/lib/api/questions.ts

Comment on lines +125 to +129
getAnswers: () =>
questions.map((question, index) => ({
questionId: question.questionId ?? index,
answer: answersById[question.id] ?? "",
})),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove index fallback for questionId in answer payload.

Line 127 falling back to index can send non-DB IDs and bring back the same submission failure (QUESTION_4041) this PR is fixing. Fail fast (or block submit) when a question lacks a backend questionId.

💡 Suggested fix
       getAnswers: () =>
-        questions.map((question, index) => ({
-          questionId: question.questionId ?? index,
-          answer: answersById[question.id] ?? "",
-        })),
+        {
+          const invalid = questions.find(
+            (question) => typeof question.questionId !== "number",
+          );
+          if (invalid) {
+            throw new Error("질문 ID가 누락되어 제출할 수 없습니다.");
+          }
+
+          return questions.map((question) => ({
+            questionId: question.questionId as number,
+            answer: answersById[question.id] ?? "",
+          }));
+        },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
getAnswers: () =>
questions.map((question, index) => ({
questionId: question.questionId ?? index,
answer: answersById[question.id] ?? "",
})),
getAnswers: () => {
const invalid = questions.find(
(question) => typeof question.questionId !== "number",
);
if (invalid) {
throw new Error("질문 ID가 누락되어 제출할 수 없습니다.");
}
return questions.map((question) => ({
questionId: question.questionId as number,
answer: answersById[question.id] ?? "",
}));
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jobdri/src/components/apply/InputSection.tsx` around lines 125 - 129, The
getAnswers mapping currently falls back to the loop index for questionId, which
can produce non-DB IDs and recreate QUESTION_4041; update the getAnswers
implementation in InputSection.tsx to use only question.questionId (no index
fallback) and fail-fast when it's missing—e.g., throw an error or set/return a
validation failure that blocks submit if question.questionId is undefined for
any question; ensure answersById is still used for answer values.

@yiyoonseo yiyoonseo merged commit 0980755 into develop May 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants