From 31da3a60f2f5235cdb42e85f2135a03b7dd8dbd2 Mon Sep 17 00:00:00 2001 From: gituser Date: Mon, 19 Oct 2026 13:25:57 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=A2=85=ED=95=A9=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=ED=8F=89=EA=B0=80=20=EC=B6=95=EA=B3=BC=20=EB=A9=B4?= =?UTF-8?q?=EC=A0=91=EB=B3=84=20=EC=84=B9=EC=85=98=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#168)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/feedback-visibility.md | 47 +++++++++ .../feedback-visibility/solo-text-pdf.png | Bin 0 -> 58236 bytes docs/images/feedback-visibility/solo-text.png | Bin 0 -> 51263 bytes .../feedback-page/api/getAudioAnalysis.ts | 16 +++ .../feedback-list/api/getAllInterviews.ts | 11 +- .../feedback-page/model/feedbackAudio.ts | 18 ++++ .../feedback-page/model/feedbackDisplay.ts | 20 +--- .../feedback-page/model/feedbackMetrics.ts | 28 +++++ .../model/useFeedbackAudioAnalysis.ts | 47 +++++++++ .../interview/api/create-interview/index.ts | 2 + .../interview/api/type/create-interview.ts | 4 + .../interview/api/type/index.ts | 1 + .../setting-company/model/draftStore.ts | 6 +- .../setting-company/model/prepareView.ts | 2 +- .../setting-company/model/submitDraft.ts | 2 +- .../model/useInterviewEntry.ts | 2 +- .../feedback-page/feedback-overall/index.tsx | 4 + .../feedback-overall/bottom-section/index.tsx | 28 ++--- .../feedback-overall/middle-section/index.tsx | 8 +- .../feedback-page/feedback-overall/style.ts | 13 +++ .../feedback-overall/top-section/index.tsx | 8 +- .../feedback-page/feedback-overall/type.ts | 11 +- tests/feedback-visibility-fixture.mjs | 39 +++++++ tests/feedback-visibility.test.mjs | 97 ++++++++++++++++++ 24 files changed, 366 insertions(+), 48 deletions(-) create mode 100644 docs/feedback-visibility.md create mode 100644 docs/images/feedback-visibility/solo-text-pdf.png create mode 100644 docs/images/feedback-visibility/solo-text.png create mode 100644 src/features/feedback-page/api/getAudioAnalysis.ts create mode 100644 src/features/feedback-page/model/feedbackAudio.ts create mode 100644 src/features/feedback-page/model/feedbackMetrics.ts create mode 100644 src/features/feedback-page/model/useFeedbackAudioAnalysis.ts create mode 100644 tests/feedback-visibility-fixture.mjs create mode 100644 tests/feedback-visibility.test.mjs diff --git a/docs/feedback-visibility.md b/docs/feedback-visibility.md new file mode 100644 index 00000000..a2aca289 --- /dev/null +++ b/docs/feedback-visibility.md @@ -0,0 +1,47 @@ +# 종합 피드백 점수·섹션 표시 (#168) + +`scoreBreakdown.axes`를 축 이름으로 연결합니다. 순서는 의도 충족(INTENT), 깊이(DEPTH), 구체성(SPECIFICITY), 정확성(ACCURACY)이며, 종합 점수는 기존 `totalScore`를 그대로 씁니다. + +- 0점은 0점입니다. `score:null, weight:null`이 명시된 축은 “해당 없음”, 누락·잘못된 값·중복 축은 “미제공”입니다. +- 옛 응답의 의도 점수만 `intentAlignmentScore`로 보완합니다. 해당 없음은 덮어쓰지 않습니다. +- 분석 완료 결과에 고정 “분석 대기”를 만들지 않습니다. 점수 없는 결과를 조회한다고 재채점하지 않습니다. + +| 유형 | 답변 방식 | 면접관별 코멘트 | 음성 영역 | +|---|---|---|---| +| SOLO | TEXT | 숨김 | 숨김·음성 요청 없음 | +| SOLO | VOICE | 숨김 | 표시 | +| MULTI | TEXT | 표시 | 숨김·음성 요청 없음 | +| MULTI | VOICE | 표시 | 표시 | + +면접 유형은 면접 조회의 mode 우선, 누락 시 피드백 mode를 씁니다. 둘 다 없으면 면접관별 섹션을 숨깁니다. 빈 personas 개수로 유형을 추측하지 않습니다. + +답변 방식은 [API 이슈 #107](https://github.com/Alpha-origin/Repit-api-server/issues/107)의 `answerMode: TEXT | VOICE | null` 계약입니다. 새 제출에만 설정 값을 추가하며 저장된 UNKNOWN/SUBMITTING 본문·요청키에는 새 필드를 주입하지 않습니다. 생성·재진입에서도 서버 값을 보존합니다. + +기존 null 기록은 `/api/interviews/{id}/audio-analysis`의 녹음 답변 목록을 보조 근거로 씁니다. 완료 응답의 빈 녹음 목록은 섹션을 숨기지만 기록 자체를 TEXT로 보정하지 않습니다. 업로드가 전부 실패한 옛 VOICE 기록도 구분할 수 없는 한계가 있습니다. 조회 오류는 텍스트로 단정하지 않고 재확인 버튼을 표시합니다. + +음성 조회는 PENDING에만 5초 간격·최대 5분 진행하며 화면 이탈·ID 변경 시 취소합니다. 완료/부분/결과 없음/실패/조회 오류를 구분합니다. 원시 지표에서 임의 100점 점수를 만들지 않고 음성 점수·코멘트는 준비 중으로 안내합니다. 본문 채점은 음성 조회를 기다리지 않습니다. 키워드·신뢰성·PDF 기능은 TEXT에서도 유지합니다. + +## 검증 (2026-10-19) + +- `node --test tests/*.test.mjs`: 40개 통과. +- `npm run lint`: 오류 0, 기존 router.tsx unused eslint-disable 경고 1개. +- `npm run build`: 통과. +- 실제 브라우저 + 독립 HTTP fixture: SOLO/MULTI × TEXT/VOICE, 새로고침, null 기록의 녹음 있음/없음, 503 및 재확인, PENDING→READY 자동 갱신, PENDING 도중 이탈 확인. +- fixture 요청 기록: TEXT 4201·4203의 음성 API 0회, VOICE 4202·4204 각 1회, 오류 4207 재확인 포함 2회, PENDING→READY 4208은 2회, 화면 이탈한 4209는 1회에서 중단. +- SOLO TEXT PDF 다운로드 후 Poppler로 A4 1쪽 렌더링: 네 축과 키워드·신뢰성 유지, 면접관·음성 섹션 없음, 겹침·잘림 없음. +- 자체 리뷰: 축 null/0 구분, 필드 없는 구형 제출 본문 불변, effect 취소와 stale 응답 차단, PDF의 숨김 조건 확인. + +fixture 실행: + +```sh +node tests/feedback-visibility-fixture.mjs +# http://127.0.0.1:5183/__feedback-fixture +``` + +실제 서버·유료 모델을 사용하지 않는 테스트 데이터입니다. 실서버를 연결한 별도 포트에서 기존 56번 결과를 열었으나 로그인 화면으로 이동하여 **수정 후 실서버 재면접·실모델 연동은 미검증**입니다. 실행 중 localhost:5173과 DB를 변경하지 않았습니다. + +선행 Web #167, API #106·#107 변경 통합 후 실제 환경에서 새 텍스트 면접을 확인해야 합니다. 점수 생성·가중치·Analysis·Chat 계약은 변경하지 않습니다. + +![SOLO TEXT 화면](images/feedback-visibility/solo-text.png) + +![내보낸 PDF 렌더링](images/feedback-visibility/solo-text-pdf.png) diff --git a/docs/images/feedback-visibility/solo-text-pdf.png b/docs/images/feedback-visibility/solo-text-pdf.png new file mode 100644 index 0000000000000000000000000000000000000000..76f72c93311f7300047718ad5d1c56aaf16a63f6 GIT binary patch literal 58236 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 W52S83>6alU%WXN88(10r-~Sif6df%9 literal 0 HcmV?d00001 diff --git a/docs/images/feedback-visibility/solo-text.png b/docs/images/feedback-visibility/solo-text.png new file mode 100644 index 0000000000000000000000000000000000000000..590c46651f76f4699fd32d509001981fa2e3e090 GIT binary patch literal 51263 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 => { + const { data } = await apiInstance.get(`/api/interviews/${interviewId}/audio-analysis`, { signal, timeout: 15_000 }); + const result = data?.data; + if (data?.success !== true || !result || + !["PENDING", "READY", "PARTIAL", "UNAVAILABLE", "FAILED"].includes(result.status) || + !Array.isArray(result.answers)) throw new Error("음성 분석 정보를 확인하지 못했습니다."); + return { status: result.status, answers: result.answers }; +}; diff --git a/src/features/feedback-page/feedback-list/api/getAllInterviews.ts b/src/features/feedback-page/feedback-list/api/getAllInterviews.ts index 58207196..c4612259 100644 --- a/src/features/feedback-page/feedback-list/api/getAllInterviews.ts +++ b/src/features/feedback-page/feedback-list/api/getAllInterviews.ts @@ -24,7 +24,8 @@ export interface InterviewSummary { id?: number; interviewId?: number; userId?: number; - mode?: "SOLO" | "MULTI"; + mode?: "SOLO" | "MULTI" | null; + answerMode?: "TEXT" | "VOICE" | null; personaId?: number | null; personaIds?: number[]; persona?: InterviewPersona | null; @@ -71,7 +72,15 @@ export interface FeedbackPersona { questionCount?: number; } +export interface ScoreBreakdown { + scoringVersion?: string; + axes?: { axis: string; score: number | null; weight: number | null }[]; + consistencyScore?: number | null; +} + export interface FeedbackData { + mode?: "SOLO" | "MULTI" | null; + scoreBreakdown?: ScoreBreakdown | null; company?: CompanyBadge | null; companyFit?: unknown; feedbackId?: number; diff --git a/src/features/feedback-page/model/feedbackAudio.ts b/src/features/feedback-page/model/feedbackAudio.ts new file mode 100644 index 00000000..41962f98 --- /dev/null +++ b/src/features/feedback-page/model/feedbackAudio.ts @@ -0,0 +1,18 @@ +import type { AudioAnalysis } from "../api/getAudioAnalysis"; +import type { FeedbackSpeechAnalysis } from "@/widgets/feedback-page/feedback-overall/type"; + +export const HIDDEN_SPEECH: FeedbackSpeechAnalysis = { visible: false, message: "", canRetry: false }; +export const LOADING_SPEECH: FeedbackSpeechAnalysis = { visible: true, message: "음성 분석 정보를 확인하고 있어요.", canRetry: false }; + +export const buildSpeechAnalysis = (result: AudioAnalysis, answerMode?: "TEXT" | "VOICE" | null): FeedbackSpeechAnalysis => { + if (answerMode === "TEXT") return HIDDEN_SPEECH; + if (answerMode !== "VOICE" && result.status !== "PENDING" && result.answers.length === 0) return HIDDEN_SPEECH; + const messages = { + PENDING: "음성을 분석 중입니다. 완료되면 자동으로 표시됩니다.", + READY: "음성 분석이 완료되었습니다. 음성 점수와 코멘트 제공은 준비 중입니다.", + PARTIAL: "일부 답변의 음성 분석 결과만 있습니다. 음성 점수와 코멘트 제공은 준비 중입니다.", + UNAVAILABLE: "제공할 수 있는 음성 분석 결과가 없습니다.", + FAILED: "음성 분석에 실패했습니다.", + }; + return { visible: true, message: messages[result.status], canRetry: false }; +}; diff --git a/src/features/feedback-page/model/feedbackDisplay.ts b/src/features/feedback-page/model/feedbackDisplay.ts index 79373715..1452f49c 100644 --- a/src/features/feedback-page/model/feedbackDisplay.ts +++ b/src/features/feedback-page/model/feedbackDisplay.ts @@ -1,3 +1,4 @@ +import { buildFeedbackMetrics } from "./feedbackMetrics"; import type { InterviewAnswer } from "@/features/feedback-page/api/getInterviewAnswers"; import type { FeedbackData, @@ -113,14 +114,7 @@ export const buildFeedbackOverallContent = ( score: totalScore, description: summarySentences.slice(0, 2).map((sentence) => sentence.trim()), }, - // The current feedback API only supplies the intent score; other criteria - // remain unscored until dedicated analysis results are available. - metrics: [ - { label: "의도 충족", score: getOptionalScore(feedback.intentAlignmentScore) }, - { label: "깊이", score: null }, - { label: "구체성", score: null }, - { label: "정확성", score: null }, - ], + metrics: buildFeedbackMetrics(feedback), evaluation: summary, }, middleSection: { @@ -140,6 +134,7 @@ export const buildFeedbackOverallContent = ( previousScore: getOptionalScore(previousFeedback?.totalScore), currentScore: totalScore, }, + showPersonaFeedback: (interview?.mode ?? feedback.mode) === "MULTI", personaFeedbacks: (feedback.personas ?? []).map((persona, index) => ({ title: persona.personaRole?.trim() || `면접관 ${index + 1}`, imageUrl: @@ -147,21 +142,16 @@ export const buildFeedbackOverallContent = ( (persona.personaId === interview?.persona?.id ? interview?.persona?.imageUrl : undefined), - comment: persona.comment?.trim() || "면접관 코멘트가 아직 등록되지 않았습니다.", + comment: persona.comment?.trim() || "면접관 코멘트가 제공되지 않았습니다.", score: getOptionalScore(persona.score), hasNoAnswer: persona.answeredCount === 0, })), }, bottomSection: { - speechMetrics: ["발화 속도", "발음 명료도", "침묵 비율", "음량 안정성"].map((label) => ({ - label, - score: null, - description: "음성 분석 결과가 아직 없습니다.", - })), reliability: { title: "응답 신뢰성", scoreLabel: reliabilityScore === null ? "—" : `${reliabilityScore}%`, - levelLabel: reliabilityScore === null ? "분석 대기" : getReliabilityLevel(reliabilityScore), + levelLabel: reliabilityScore === null ? "미제공" : getReliabilityLevel(reliabilityScore), }, keywords: { items: keywords.map((item, index) => ({ diff --git a/src/features/feedback-page/model/feedbackMetrics.ts b/src/features/feedback-page/model/feedbackMetrics.ts new file mode 100644 index 00000000..ebd66981 --- /dev/null +++ b/src/features/feedback-page/model/feedbackMetrics.ts @@ -0,0 +1,28 @@ +import type { FeedbackData } from "../feedback-list/api/getAllInterviews"; +import type { FeedbackOverallMetric } from "@/widgets/feedback-page/feedback-overall/type"; + +const AXES = [ + ["INTENT", "의도 충족"], ["DEPTH", "깊이"], + ["SPECIFICITY", "구체성"], ["ACCURACY", "정확성"], +] as const; + +const validScore = (value: unknown): value is number => + typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 100; + +export const buildFeedbackMetrics = (feedback: FeedbackData): FeedbackOverallMetric[] => { + const axes = Array.isArray(feedback.scoreBreakdown?.axes) ? feedback.scoreBreakdown.axes : []; + return AXES.map(([axis, label]) => { + const entries = axes.filter((entry) => entry?.axis === axis); + if (entries.length === 1) { + const entry = entries[0]; + if (validScore(entry.score)) return { label, score: entry.score }; + if (entry.score === null && entry.weight === null) { + return { label, score: null, emptyLabel: "해당 없음" }; + } + } + if (entries.length === 0 && axis === "INTENT" && validScore(feedback.intentAlignmentScore)) { + return { label, score: feedback.intentAlignmentScore }; + } + return { label, score: null, emptyLabel: "미제공" }; + }); +}; diff --git a/src/features/feedback-page/model/useFeedbackAudioAnalysis.ts b/src/features/feedback-page/model/useFeedbackAudioAnalysis.ts new file mode 100644 index 00000000..f08d3f41 --- /dev/null +++ b/src/features/feedback-page/model/useFeedbackAudioAnalysis.ts @@ -0,0 +1,47 @@ +import { useEffect, useState } from "react"; +import { getAudioAnalysis } from "../api/getAudioAnalysis"; +import { buildSpeechAnalysis, HIDDEN_SPEECH, LOADING_SPEECH } from "./feedbackAudio"; +import type { FeedbackSpeechAnalysis } from "@/widgets/feedback-page/feedback-overall/type"; + +export const useFeedbackAudioAnalysis = ( + interviewId: number | undefined, + answerMode: "TEXT" | "VOICE" | null | undefined, + enabled: boolean, +) => { + const [attempt, setAttempt] = useState(0); + const [result, setResult] = useState<{ key: string; view: FeedbackSpeechAnalysis } | null>(null); + const key = JSON.stringify([interviewId, answerMode ?? null, enabled, attempt]); + const shouldLoad = enabled && Number.isSafeInteger(interviewId) && (interviewId ?? 0) > 0 && answerMode !== "TEXT"; + + useEffect(() => { + if (!shouldLoad || interviewId === undefined) return; + const controller = new AbortController(); + const deadline = Date.now() + 5 * 60_000; + let timer: number; + const update = (view: FeedbackSpeechAnalysis) => { + if (!controller.signal.aborted) setResult({ key, view }); + }; + const poll = async () => { + if (controller.signal.aborted) return; + if (Date.now() >= deadline) { + update({ visible: true, message: "음성 분석이 지연되고 있습니다. 잠시 후 다시 확인해주세요.", canRetry: true }); + return; + } + try { + const data = await getAudioAnalysis(interviewId, controller.signal); + if (controller.signal.aborted) return; + update(buildSpeechAnalysis(data, answerMode)); + if (data.status === "PENDING") timer = window.setTimeout(() => void poll(), Math.min(5_000, Math.max(0, deadline - Date.now()))); + } catch { + update({ visible: true, message: "음성 분석 정보를 확인하지 못했습니다.", canRetry: true }); + } + }; + timer = window.setTimeout(() => void poll(), 0); + return () => { controller.abort(); window.clearTimeout(timer); }; + }, [interviewId, answerMode, key, shouldLoad]); + + return { + view: !shouldLoad ? HIDDEN_SPEECH : result?.key === key ? result.view : LOADING_SPEECH, + retry: () => setAttempt((value) => value + 1), + }; +}; diff --git a/src/features/interview-page/interview/api/create-interview/index.ts b/src/features/interview-page/interview/api/create-interview/index.ts index 825d62ff..507d96f3 100644 --- a/src/features/interview-page/interview/api/create-interview/index.ts +++ b/src/features/interview-page/interview/api/create-interview/index.ts @@ -142,6 +142,8 @@ const normalizeCreatedInterview = ( personaId, personaIds: normalizedPersonaIds, mode, + answerMode: sourceRecord?.answerMode === "TEXT" || sourceRecord?.answerMode === "VOICE" + ? sourceRecord.answerMode : null, sessionId, status: isInterviewLifecycleStatus(sourceRecord?.status) ? sourceRecord.status diff --git a/src/features/interview-page/interview/api/type/create-interview.ts b/src/features/interview-page/interview/api/type/create-interview.ts index 1b3977c3..01888bd6 100644 --- a/src/features/interview-page/interview/api/type/create-interview.ts +++ b/src/features/interview-page/interview/api/type/create-interview.ts @@ -11,6 +11,7 @@ export type CreateInterviewPersonaType = InterviewPersonality; export type InterviewPersonaGender = "MALE" | "FEMALE"; export type InterviewPersonaRole = "TECH" | "HR" | "CEO" | "PM" | "DESIGN"; export type InterviewTone = "GENTLE" | "DIRECT" | "PRESSURING"; +export type InterviewAnswerMode = "TEXT" | "VOICE"; export type InterviewMode = "SOLO" | "MULTI"; export type InterviewLifecycleStatus = | "IN_PROGRESS" @@ -19,6 +20,7 @@ export type InterviewLifecycleStatus = export interface CreateSoloInterviewParams { companyId?: number; + answerMode?: InterviewAnswerMode | null; personaName: string; major?: InterviewPersonaMajor; type: CreateInterviewPersonaType; @@ -28,6 +30,7 @@ export interface CreateSoloInterviewParams { export interface CreateMultiInterviewParams { companyId?: number; + answerMode?: InterviewAnswerMode | null; personaIds: number[]; } @@ -40,6 +43,7 @@ export interface CreatedInterviewData { interviewId: number; userId: number; mode: InterviewMode; + answerMode?: InterviewAnswerMode | null; personaId: number | null; personaIds: number[]; sessionId: string; diff --git a/src/features/interview-page/interview/api/type/index.ts b/src/features/interview-page/interview/api/type/index.ts index a39e52a2..8dbc204c 100644 --- a/src/features/interview-page/interview/api/type/index.ts +++ b/src/features/interview-page/interview/api/type/index.ts @@ -6,6 +6,7 @@ export type { CreatedInterviewData, InterviewLifecycleStatus, InterviewMode, + InterviewAnswerMode, InterviewPersonaGender, InterviewPersonaMajor, InterviewPersonaRole, diff --git a/src/features/interview-page/setting-company/model/draftStore.ts b/src/features/interview-page/setting-company/model/draftStore.ts index e7302e79..c9e5d17f 100644 --- a/src/features/interview-page/setting-company/model/draftStore.ts +++ b/src/features/interview-page/setting-company/model/draftStore.ts @@ -33,10 +33,12 @@ export const currentOwnerKey = () => { const validBody = (body: unknown, draft: SetupDraft): body is CreateInterviewParams => { if (!record(body) || (draft.companyId === null && "companyId" in body) || (body.companyId !== undefined && body.companyId !== draft.companyId) || (draft.companyId !== null && body.companyId !== draft.companyId)) return false; - if (draft.mode === "MULTI") return Object.keys(body).every((key) => ["personaIds", "companyId"].includes(key)) && + if (body.answerMode !== undefined && body.answerMode !== null && + body.answerMode !== (draft.settings.answerMode === "text" ? "TEXT" : "VOICE")) return false; + if (draft.mode === "MULTI") return Object.keys(body).every((key) => ["personaIds", "companyId", "answerMode"].includes(key)) && Array.isArray(body.personaIds) && body.personaIds.length === (draft.settings.mode === "MULTI" ? draft.settings.slots.length : 0) && body.personaIds.every(positiveId) && new Set(body.personaIds).size === body.personaIds.length; - return Object.keys(body).every((key) => ["personaName", "major", "type", "career", "gender", "companyId"].includes(key)) && + return Object.keys(body).every((key) => ["personaName", "major", "type", "career", "gender", "companyId", "answerMode"].includes(key)) && typeof body.personaName === "string" && body.personaName.length > 0 && body.personaName.length < 200 && ["FRIENDLY", "REALISTIC", "METICULOUS"].includes(String(body.type)) && typeof body.career === "number" && Number.isFinite(body.career) && body.career >= 0 && diff --git a/src/features/interview-page/setting-company/model/prepareView.ts b/src/features/interview-page/setting-company/model/prepareView.ts index 11616513..53b3930e 100644 --- a/src/features/interview-page/setting-company/model/prepareView.ts +++ b/src/features/interview-page/setting-company/model/prepareView.ts @@ -13,7 +13,7 @@ export const buildPreparedView = (settings: InterviewDraft, data: CreatedIntervi const first = interviewers[0]; return { interviewId: data.interviewId, userId: data.userId, sessionId: data.sessionId, - company: data.company, mode: data.mode, answerMode: settings.answerMode, + company: data.company, mode: data.mode, answerMode: data.answerMode === "TEXT" ? "text" : data.answerMode === "VOICE" ? "voice" : settings.answerMode, personaId: data.personaIds[0], personaName: first.name, role: first.role, major: null, type: first.personality, personaType: first.personality, level: LEVEL_BY_DIFFICULTY[settings.difficulty], career: settings.mode === "SOLO" ? ({ 쉬움: 0, 보통: 3, 어려움: 5 }[settings.difficulty]) : first.career, diff --git a/src/features/interview-page/setting-company/model/submitDraft.ts b/src/features/interview-page/setting-company/model/submitDraft.ts index 33bfaab3..33ce79c7 100644 --- a/src/features/interview-page/setting-company/model/submitDraft.ts +++ b/src/features/interview-page/setting-company/model/submitDraft.ts @@ -28,7 +28,7 @@ export const submitSetupDraft = (draftId: string): Promise => { } draft = saveSetupDraft({ ...latest, updatedAt: new Date().toISOString(), submission: { idempotencyKey: crypto.randomUUID(), - requestBody: { ...body, ...(latest.companyId !== null ? { companyId: latest.companyId } : {}) }, + requestBody: { ...body, answerMode: latest.settings.answerMode === "text" ? "TEXT" : "VOICE", ...(latest.companyId !== null ? { companyId: latest.companyId } : {}) }, interviewId: null, state: "SUBMITTING", } }); } diff --git a/src/features/interview-page/setting-company/model/useInterviewEntry.ts b/src/features/interview-page/setting-company/model/useInterviewEntry.ts index edefc471..37ca69a4 100644 --- a/src/features/interview-page/setting-company/model/useInterviewEntry.ts +++ b/src/features/interview-page/setting-company/model/useInterviewEntry.ts @@ -32,7 +32,7 @@ export const useInterviewEntry = ( return; } if (data.status === "ABANDONED") throw new Error("종료된 면접입니다. 새 면접을 만들어주세요."); - setEntry({ key, data: { ...prepared, sessionId: data.sessionId, company: data.company, status: data.status }, error: null }); + setEntry({ key, data: { ...prepared, answerMode: data.answerMode === "TEXT" ? "text" : data.answerMode === "VOICE" ? "voice" : prepared.answerMode, sessionId: data.sessionId, company: data.company, status: data.status }, error: null }); } catch (error) { if (!controller.signal.aborted) setEntry({ key, data: null, error: extractErrorMessage(error, "면접 정보를 확인하지 못했습니다.") }); } diff --git a/src/pages/feedback-page/feedback-overall/index.tsx b/src/pages/feedback-page/feedback-overall/index.tsx index 2697f73f..e6d87a9f 100644 --- a/src/pages/feedback-page/feedback-overall/index.tsx +++ b/src/pages/feedback-page/feedback-overall/index.tsx @@ -1,3 +1,4 @@ +import { useFeedbackAudioAnalysis } from "@/features/feedback-page/model/useFeedbackAudioAnalysis"; import CompanyFeedback from "@/widgets/feedback-page/company-feedback"; import { buildFeedbackOverallContent } from "@/features/feedback-page/model/feedbackDisplay"; import { useFeedbackInterview } from "@/features/feedback-page/model/useFeedbackInterview"; @@ -29,6 +30,7 @@ const FeedbackOverallPage = () => { feedback && !isAnalysisPending && !isAnalysisFailed ? buildFeedbackOverallContent(feedback, interview, previousFeedback) : null; + const audio = useFeedbackAudioAnalysis(interview?.interviewId ?? interview?.id, interview?.answerMode, content !== null); const panelRef = useRef(null); const [isDownloadingPdf, setIsDownloadingPdf] = useState(false); @@ -88,6 +90,8 @@ const FeedbackOverallPage = () => { diff --git a/src/widgets/feedback-page/feedback-overall/bottom-section/index.tsx b/src/widgets/feedback-page/feedback-overall/bottom-section/index.tsx index 242a43b5..f2226e07 100644 --- a/src/widgets/feedback-page/feedback-overall/bottom-section/index.tsx +++ b/src/widgets/feedback-page/feedback-overall/bottom-section/index.tsx @@ -3,30 +3,22 @@ import type { FeedbackOverallBottomSectionProps } from "../type"; const FeedbackOverallBottomSection = ({ content, + speechAnalysis, + onRetrySpeechAnalysis, isDownloadingPdf = false, onDownloadPdf, }: FeedbackOverallBottomSectionProps) => { - const { keywords, reliability, speechMetrics } = content; + const { keywords, reliability } = content; return ( - - 음성 분석 결과 - - {speechMetrics.map((metric) => ( - - - {metric.label} - {metric.score === null ? "분석 대기" : `${metric.score}점`} - - - {metric.description} - - ))} - - + {speechAnalysis.visible ? ( + + 음성 분석 결과 + {speechAnalysis.message} + {speechAnalysis.canRetry ? 음성 정보 다시 확인 : null} + + ) : null} diff --git a/src/widgets/feedback-page/feedback-overall/middle-section/index.tsx b/src/widgets/feedback-page/feedback-overall/middle-section/index.tsx index 9669600f..d9b0f209 100644 --- a/src/widgets/feedback-page/feedback-overall/middle-section/index.tsx +++ b/src/widgets/feedback-page/feedback-overall/middle-section/index.tsx @@ -70,7 +70,7 @@ const FeedbackOverallMiddleSection = ({ content }: FeedbackOverallMiddleSectionP - + {content.showPersonaFeedback ? {content.personaFeedbacks.length > 0 ? content.personaFeedbacks.map((persona, index) => ( {persona.comment} - {persona.hasNoAnswer ? "담당 답변 없음" : persona.score === null ? "분석 대기" : `${persona.score}점`} + {persona.hasNoAnswer ? "담당 답변 없음" : persona.score === null ? "미제공" : `${persona.score}점`} )) : ( - 면접관별 코멘트가 아직 없습니다. + 면접관별 코멘트가 제공되지 않았습니다. )} - + : null} ); }; diff --git a/src/widgets/feedback-page/feedback-overall/style.ts b/src/widgets/feedback-page/feedback-overall/style.ts index 3b8d9bb7..576b1583 100644 --- a/src/widgets/feedback-page/feedback-overall/style.ts +++ b/src/widgets/feedback-page/feedback-overall/style.ts @@ -419,6 +419,19 @@ export const PersonaEmpty = styled(EmptyText)` padding: 1.5rem; `; +export const SpeechRetryButton = styled.button` + align-self: flex-start; + padding: 0.5rem 0.75rem; + border: 1px solid currentColor; + border-radius: 0.375rem; + color: ${({ theme }) => theme.colors.brand.blue}; + background: ${({ theme }) => theme.colors.white}; + font: inherit; + cursor: pointer; + + &:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; } +`; + export const SpeechCard = styled.article` ${cardSurface} display: flex; diff --git a/src/widgets/feedback-page/feedback-overall/top-section/index.tsx b/src/widgets/feedback-page/feedback-overall/top-section/index.tsx index 6b1b8f94..9bec3ec7 100644 --- a/src/widgets/feedback-page/feedback-overall/top-section/index.tsx +++ b/src/widgets/feedback-page/feedback-overall/top-section/index.tsx @@ -41,16 +41,16 @@ const FeedbackOverallTopSection = ({ content }: FeedbackOverallTopSectionProps)
종합 점수 - 아래 4가지 평가 기준을 종합해 산출한 최종 점수입니다. + 평가 가능한 항목의 점수와 가중치를 반영한 결과입니다.
{metrics.map((metric) => ( {metric.label} - {metric.score === null ? "분석 대기" : `${metric.score}점`} - : null} ))} diff --git a/src/widgets/feedback-page/feedback-overall/type.ts b/src/widgets/feedback-page/feedback-overall/type.ts index 156dcb86..e31c806c 100644 --- a/src/widgets/feedback-page/feedback-overall/type.ts +++ b/src/widgets/feedback-page/feedback-overall/type.ts @@ -2,6 +2,7 @@ export interface FeedbackOverallMetric { label: string; score: number | null; description?: string; + emptyLabel?: "해당 없음" | "미제공"; } export interface FeedbackOverallPersonaFeedback { @@ -44,11 +45,11 @@ export interface FeedbackOverallMiddleSectionData { previousScore: number | null; currentScore: number | null; }; + showPersonaFeedback: boolean; personaFeedbacks: readonly FeedbackOverallPersonaFeedback[]; } export interface FeedbackOverallBottomSectionData { - speechMetrics: readonly FeedbackOverallMetric[]; reliability: { title: string; scoreLabel: string; @@ -68,7 +69,15 @@ export interface FeedbackOverallMiddleSectionProps { content: FeedbackOverallMiddleSectionData; } +export interface FeedbackSpeechAnalysis { + visible: boolean; + message: string; + canRetry: boolean; +} + export interface FeedbackOverallBottomSectionProps { + speechAnalysis: FeedbackSpeechAnalysis; + onRetrySpeechAnalysis: () => void; content: FeedbackOverallBottomSectionData; isDownloadingPdf?: boolean; onDownloadPdf?: () => void; diff --git a/tests/feedback-visibility-fixture.mjs b/tests/feedback-visibility-fixture.mjs new file mode 100644 index 00000000..ab6389a4 --- /dev/null +++ b/tests/feedback-visibility-fixture.mjs @@ -0,0 +1,39 @@ +// 브라우저 수동 회귀용 독립 fixture. 실제 서버/로그인/유료 모델을 사용하지 않는다. +import { createServer } from "vite"; + +const port = Number(process.env.FEEDBACK_FIXTURE_PORT ?? 5183); +process.env.VITE_AUTH_URL = `http://127.0.0.1:${port}`; +process.env.VITE_API_URL = `http://127.0.0.1:${port}`; +const calls = new Map(); +const scenarios = [ + [4201,"SOLO","TEXT"], [4202,"SOLO","VOICE"], [4203,"MULTI","TEXT"], [4204,"MULTI","VOICE"], + [4205,"SOLO",null], [4206,"MULTI",null], [4207,"SOLO",null], [4208,"SOLO","VOICE"], [4209,"SOLO",null], +]; +const interviews = scenarios.map(([interviewId,mode,answerMode]) => ({interviewId,userId:7,mode,answerMode,status:"COMPLETED",createdAt:"2026-10-19T01:00:00Z",personaIds:mode==="MULTI"?[1,2]:[1]})); +const feedback = (id) => ({ interviewId:id,mode:interviews.find(x=>x.interviewId===id)?.mode,status:"SUCCEEDED",totalScore:89,intentAlignmentScore:100,reliabilityScore:98, + summary:"테스트 답변에서 기술 선택의 근거와 대안을 확인했습니다.",scoreBreakdown:{scoringVersion:"axis-v1",axes:[{axis:"INTENT",score:100,weight:35},{axis:"DEPTH",score:60,weight:25},{axis:"SPECIFICITY",score:95,weight:25},{axis:"ACCURACY",score:100,weight:15}]}, + strengths:["테스트 강점"],improvements:["테스트 보완점"],frequentWords:[{word:"서버",count:3}], + personas:[{personaId:1,personaRole:"TECH",score:90,comment:"기술 면접관의 테스트 코멘트",answeredCount:1},{personaId:2,personaRole:"HR",score:88,comment:"인사 면접관의 테스트 코멘트",answeredCount:1}], + feedbacks:[{questionId:21,questionContent:"테스트 질문",intention:"테스트 의도",userAnswer:"테스트 답변",modelAnswer:"테스트 모범 답변",comment:"테스트 문항 코멘트"}], +}); +const server = await createServer({server:{host:"127.0.0.1",port,strictPort:true},plugins:[{name:"feedback-visibility-fixture",configureServer(vite){vite.middlewares.use((req,res,next)=>{ + const url = new URL(req.url,"http://fixture.invalid"); + const json=(data,code=200)=>{res.statusCode=code;res.setHeader("Content-Type","application/json");res.end(JSON.stringify(data));}; + if(url.pathname==="/__feedback-fixture") {res.setHeader("Content-Type","text/html; charset=utf-8");res.end('

피드백 표시 회귀 fixture

'+scenarios.map(([id,mode,answer])=>`

${id} ${mode} ${answer??"LEGACY"}

`).join(''));return;} + if(url.pathname==="/__feedback-calls") return json(Object.fromEntries(calls)); + if(!url.pathname.startsWith("/api/")) return next(); + calls.set(url.pathname,(calls.get(url.pathname)??0)+1); + if(url.pathname.endsWith("/refresh")) return json({accessToken:"fixture-only-token"}); + if(url.pathname.endsWith("/me")) return json({data:{id:7,name:"회귀 테스트",nickname:"회귀 테스트",email:"test@example.com"}}); + if(url.pathname==="/api/interviews/getAll") return json({success:true,data:interviews}); + if(url.pathname==="/api/feedbacks/getAll") return json({success:true,data:[]}); + if(url.pathname==="/api/answer/getAll") return json({success:true,data:[]}); + if(url.pathname==="/api/feedbacks") return json({success:true,data:feedback(Number(url.searchParams.get("interviewId")))}); + const match=url.pathname.match(/^\/api\/interviews\/(\d+)\/audio-analysis$/); + if(match){const id=Number(match[1]);if(id===4207)return json({message:"fixture 조회 실패"},503); + const reads=calls.get(url.pathname);const status=id===4208?(reads===1?"PENDING":"READY"):id===4209?"PENDING":[4202,4205].includes(id)?"UNAVAILABLE":"READY"; + return json({success:true,data:{status,answers:[4202,4205,4209].includes(id)?[]:[{questionId:"21",recordingId:"1"}],canRetry:false}});} + return json({message:"fixture에서 정의하지 않은 API"},404); +});}}]}); +await server.listen(); +console.log(`Fixture: http://127.0.0.1:${port}/__feedback-fixture`); diff --git a/tests/feedback-visibility.test.mjs b/tests/feedback-visibility.test.mjs new file mode 100644 index 00000000..b8a53811 --- /dev/null +++ b/tests/feedback-visibility.test.mjs @@ -0,0 +1,97 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { test } from "node:test"; +import ts from "typescript"; + +const load = async (file, replacements = {}) => { + let source = readFileSync(new URL(`../src/${file}`, import.meta.url), "utf8"); + for (const [from, to] of Object.entries(replacements)) source = source.replace(from, to); + const { outputText } = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ESNext } }); + const url = `data:text/javascript;base64,${Buffer.from(outputText).toString("base64")}`; + return { url, module: await import(url) }; +}; +const metrics = await load("features/feedback-page/model/feedbackMetrics.ts"); +const { buildFeedbackMetrics } = metrics.module; +const { module: { buildFeedbackOverallContent } } = await load("features/feedback-page/model/feedbackDisplay.ts", { '"./feedbackMetrics"': JSON.stringify(metrics.url) }); +const { module: { buildSpeechAnalysis } } = await load("features/feedback-page/model/feedbackAudio.ts"); +const axes = [ + { axis: "INTENT", score: 100, weight: 35 }, { axis: "DEPTH", score: 60, weight: 25 }, + { axis: "SPECIFICITY", score: 95, weight: 25 }, { axis: "ACCURACY", score: 100, weight: 15 }, +]; + +test("서버 점수는 축 이름으로 연결하고 종합 89점을 유지한다", () => { + const feedback = { totalScore: 89, scoreBreakdown: { axes: [...axes].reverse() } }; + const result = buildFeedbackOverallContent(feedback); + assert.deepEqual(result.topSection.metrics.map(x => [x.label, x.score]), [["의도 충족",100],["깊이",60],["구체성",95],["정확성",100]]); + assert.equal(result.topSection.summary.score, 89); +}); +test("0점·해당 없음·누락·잘못된 값·중복을 구분한다", () => { + const result = buildFeedbackMetrics({ intentAlignmentScore: 90, scoreBreakdown: { axes: [ + { axis: "INTENT", score: 0, weight: 35 }, { axis: "DEPTH", score: null, weight: null }, + { axis: "ACCURACY", score: 50, weight: 15 }, { axis: "ACCURACY", score: 80, weight: 15 }, + ] } }); + assert.deepEqual(result.map(x => [x.score, x.emptyLabel]), [[0,undefined],[null,"해당 없음"],[null,"미제공"],[null,"미제공"]]); + for (const score of [-1, 101, NaN, Infinity, "60", undefined]) { + assert.equal(buildFeedbackMetrics({ scoreBreakdown: { axes: [{ axis: "DEPTH", score, weight: 25 }] } })[1].emptyLabel, "미제공"); + } +}); +test("옛 결과는 의도만 보완하고 명시적 null은 덮어쓰지 않는다", () => { + assert.deepEqual(buildFeedbackMetrics({ intentAlignmentScore: 80 }).map(x => x.score), [80,null,null,null]); + assert.equal(buildFeedbackMetrics({ intentAlignmentScore: 80, scoreBreakdown: { axes: [{ axis:"INTENT",score:null,weight:null }] } })[0].emptyLabel,"해당 없음"); +}); +test("면접관 코멘트는 면접 mode를 우선해 MULTI에서만 노출한다", () => { + const feedback = { mode:"MULTI", personas:[{score:80,comment:"기술 코멘트"}] }; + assert.equal(buildFeedbackOverallContent(feedback,{mode:"SOLO"}).middleSection.showPersonaFeedback,false); + assert.equal(buildFeedbackOverallContent(feedback,{mode:"MULTI"}).middleSection.showPersonaFeedback,true); + assert.equal(buildFeedbackOverallContent(feedback).middleSection.showPersonaFeedback,true); + assert.equal(buildFeedbackOverallContent({}).middleSection.showPersonaFeedback,false); +}); +test("TEXT 음성 영역은 항상 숨기며 VOICE는 녹음 실패에도 표시한다", () => { + for (const status of ["PENDING","READY","PARTIAL","UNAVAILABLE","FAILED"]) { + assert.equal(buildSpeechAnalysis({status,answers:[]},"TEXT").visible,false); + assert.equal(buildSpeechAnalysis({status,answers:[]},"VOICE").visible,true); + } +}); +test("옛 기록은 녹음 없음·분석 중을 구분한다", () => { + assert.equal(buildSpeechAnalysis({status:"UNAVAILABLE",answers:[]},null).visible,false); + assert.equal(buildSpeechAnalysis({status:"PENDING",answers:[]},null).visible,true); + assert.equal(buildSpeechAnalysis({status:"FAILED",answers:[{}]},null).visible,true); +}); + +const stubUrl = `data:text/javascript;base64,${Buffer.from(` +export let draft; +export const calls=[]; +export const reset = value => {draft=value;calls.length=0;}; +export const currentOwnerKey=()=>"7"; +export const loadSetupDraft=()=>draft; +export const saveSetupDraft=value=>(draft=value); +export const buildSoloInterviewPayload=async()=>({personaName:"test",type:"FRIENDLY",career:0,gender:"MALE"}); +export const buildMultiInterviewPayload=async()=>({personaIds:[1,2]}); +export const createInterview=async(body,key)=>{calls.push({body:structuredClone(body),key});return {data:{interviewId:56,userId:7}};}; +`).toString("base64")}`; +const stub = await import(stubUrl); +const { module: { submitSetupDraft } } = await load("features/interview-page/setting-company/model/submitDraft.ts", Object.fromEntries([ + '"@/features/interview-page/interview/api"', + '"@/features/interview-page/setting-interview/model/submitSoloInterview"', + '"@/features/interview-page/setting-multi-interview/model/submitMultiInterview"', + '"./draftStore"', +].map(path => [path, JSON.stringify(stubUrl)]))); + +test("새 SOLO/MULTI 제출은 선택한 답변 방식을 본문에 고정한다", async () => { + for (const mode of ["SOLO","MULTI"]) for (const answerMode of ["text","voice"]) { + const draftId=crypto.randomUUID(); + stub.reset({draftId,ownerKey:"7",mode,settings:{mode,answerMode},companyId:null,submission:null}); + await submitSetupDraft(draftId); + assert.equal(stub.calls[0].body.answerMode,answerMode==="text"?"TEXT":"VOICE"); + } +}); +test("옛 UNKNOWN 본문·요청키는 답변 방식 주입 없이 그대로 재전송한다", async () => { + const draftId=crypto.randomUUID(); + const body={personaName:"old",type:"FRIENDLY",career:0,gender:"MALE"}; + const idempotencyKey=crypto.randomUUID(); + stub.reset({draftId,ownerKey:"7",mode:"SOLO",settings:{mode:"SOLO",answerMode:"text"},companyId:null, + submission:{requestBody:body,idempotencyKey,interviewId:null,state:"UNKNOWN"}}); + await submitSetupDraft(draftId); + assert.deepEqual(stub.calls,[{body,key:idempotencyKey}]); + assert.equal("answerMode" in stub.calls[0].body,false); +});