Skip to content

Commit de2f253

Browse files
committed
docs(frontend): CLAUDE.md 면접·OpenAPI·테스트 도입 반영
1 parent b70171b commit de2f253

5 files changed

Lines changed: 56 additions & 10 deletions

File tree

frontend/CLAUDE.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
| Language | TypeScript | 5.9.x |
1616
| Lint | ESLint 9 (flat config) + Prettier | |
1717
| Module | ESM (`"type": "module"`) | |
18+
| Router | React Router | 7.x (도입) |
19+
| Server State | TanStack Query | 5.x (도입) |
20+
| Styling | Tailwind CSS v4 (`@theme` 토큰) | 4.x (도입) |
21+
| API 타입 | openapi-typescript → `shared/api/generated.ts` | (도입, §7.1) |
22+
| 테스트 | Vitest + Testing Library (jsdom) | (도입) |
1823

19-
### 미정 (Phase 1 도입 시점에 결정)
20-
- Router: 후보 — React Router v7 / TanStack Router
21-
- Server State: TanStack Query
22-
- Form: React Hook Form + Zod
23-
- Styling: CSS Variables 기반 + Tailwind 또는 vanilla-extract
24-
- 테스트: Vitest + Testing Library + Playwright(E2E)
24+
### 미정 (도입 시점에 결정)
25+
- Form: React Hook Form + Zod (현재 controlled `useState` 검증으로 충분 — 폼 복잡도 증가 시 도입)
26+
- E2E: Playwright
2527

2628
> 신규 의존성 추가 시 [`/docs/coding-conventions.md §6`](../docs/coding-conventions.md) 절차를 따르고 본 표를 갱신.
2729
@@ -274,8 +276,9 @@ npm run lint # ESLint
274276

275277
---
276278

277-
## 16. 현재 상태 메모 (2026-04 기준)
279+
## 16. 현재 상태 메모 (2026-06 기준)
278280

279-
- `App.tsx`는 Vite 기본 데모 상태 → 첫 페이지(Login) 구현 시 교체 예정
280-
- 라이브러리 결정 전 (라우터, server state, styling) → 첫 PR 시 의사결정 + 본 문서 §1 갱신
281-
- 디자인 시스템 토큰 파일 미생성 → 디자인 시스템 첫 적용 PR에서 `app/styles/tokens.css` 생성
281+
- 라이브러리 결정 완료: React Router v7, TanStack Query v5, Tailwind v4, Vitest+Testing Library (§1).
282+
- 디자인 토큰 `app/styles/tokens.css` 생성됨. `shared/ui` 프리미티브: StatusBadge, Button, Spinner, TextArea, RadioCardGroup, Stepper.
283+
- **텍스트 면접 세션 구현됨**: `/sessions/new`(생성 설정), `/sessions/:id`(라이브 진행). `features/interview` + `domain/session`. 라이브는 WS(`useInterviewSocket`) 알림 + `GET messages` 쿼리 본문 소유 + 낙관적 답변 (`useLiveInterview`). TTS 재생·음성 답변(RT3)은 범위 밖.
284+
- **OpenAPI 타입 파이프라인**: 백엔드가 `OpenApiSpecExportTest``backend/openapi.json` 산출·커밋 → 프론트 `npm run openapi`(= `openapi-typescript ../backend/openapi.json …`)로 `shared/api/generated.ts` 생성. 프론트는 백엔드 런타임에 무의존. 계약 변경 시 백엔드 테스트 재실행으로 갱신.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './ui/SessionFeedbackPage'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Link, useParams } from 'react-router-dom'
2+
import { Button } from '@/shared/ui/Button'
3+
4+
// 피드백 리포트 화면(features/feedback)은 아직 범위 밖. feedback.ready 리다이렉트가
5+
// 빈 화면으로 끝나지 않도록 임시 안내 스텁을 제공한다.
6+
export default function SessionFeedbackPage() {
7+
const { id } = useParams<{ id: string }>()
8+
return (
9+
<div className="mx-auto flex max-w-readable flex-col items-center gap-4 px-4 py-16 text-center">
10+
<h1 className="text-h4 text-fg">피드백 준비 완료</h1>
11+
<p className="text-body text-fg-muted">
12+
세션 #{id}의 면접이 종료되어 피드백이 준비되었습니다. 상세 리포트 화면은 준비 중입니다.
13+
</p>
14+
<Link to="/workspace">
15+
<Button variant="secondary">워크스페이스로</Button>
16+
</Link>
17+
</div>
18+
)
19+
}

frontend/src/pages/Workspace/ui/WorkspacePage.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { Link } from 'react-router-dom'
12
import { SiteNav } from '@/widgets/site-nav'
23
import { SiteFooter } from '@/widgets/site-footer'
34
import { WorkspaceProfileCard } from '@/widgets/workspace-profile-card'
45
import { WorkspaceSection } from '@/widgets/workspace-section'
56
import { ResumeList, ResumeUploader } from '@/features/resume'
67
import { RepoList, RepoPicker } from '@/features/repo'
78
import { DocumentList } from '@/features/analysis'
9+
import { Button } from '@/shared/ui/Button'
810
import { useWorkspaceAnalysisStream } from '../model/useWorkspaceAnalysisStream'
911

1012
export default function WorkspacePage() {
@@ -17,6 +19,20 @@ export default function WorkspacePage() {
1719
<main className="flex-1 mx-auto w-full max-w-content px-6 lg:px-12 py-10 space-y-10">
1820
<WorkspaceProfileCard />
1921

22+
<WorkspaceSection
23+
title="모의 면접"
24+
description="분석된 이력서·레포를 바탕으로 맞춤 모의 면접을 시작하세요."
25+
action={
26+
<Link to="/sessions/new">
27+
<Button size="lg">새 면접 시작</Button>
28+
</Link>
29+
}
30+
>
31+
<p className="text-body text-fg-muted">
32+
면접 모드와 직군을 고르면 AI가 질문을 생성하고, 실시간으로 답변을 주고받습니다.
33+
</p>
34+
</WorkspaceSection>
35+
2036
<WorkspaceSection
2137
title="내 이력서"
2238
description="PDF 이력서를 업로드하면 AI가 분석해 면접 질문 풀에 반영합니다."

frontend/src/test/setup.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import '@testing-library/jest-dom/vitest'
2+
import { afterEach } from 'vitest'
3+
import { cleanup } from '@testing-library/react'
4+
5+
afterEach(() => {
6+
cleanup()
7+
})

0 commit comments

Comments
 (0)