feat: P1 풀빌드 — React 프론트 7화면 + 백엔드 상담루프·평가·음성·RAG
web (Vite+React19+TS, Cloudflare Pages 배포): - 디자인토큰(세이지틸/테라코타 SSOT), 앱셸, 공통 UI 프리미티브 - 7화면: 로그인/학습자홈/상담세션/회기리뷰/교수자/관리자/설정 - ClientAvatar: SVG 반구상 흉상 4상태 + RMS 립싱크 + 6파라미터 정서 - 회기리뷰는 외부 레퍼런스 디자인을 Vignette 토큰으로 리스킨 api (FastAPI): - 게이트웨이 /v1/generate·/v1/stream 어댑터(상주풀/EngineSession 보존) - services: 페르소나 L0~L6 빌더 / 결정론 상태머신 / 가드레일 / 턴 오케스트레이터 / 회기간 메모리 / 평가AI / 음성 / RAG - store: DB off 폴백(in-memory), sessions 실구현 검증: - web: node22 tsc+vite build 통과(node23 segfault 회피), Pages 배포 200 - api: app.main import 통과 - 핫픽스: Topbar initials undefined-safe (undefined.trim 크래시) - E2E: 서연(P1) 상담 1턴 — 좋은/나쁜 상담에 차등 반응 실증
This commit is contained in:
parent
859ab26314
commit
24b1b7a6e1
84 changed files with 19645 additions and 107 deletions
|
|
@ -1,4 +1,88 @@
|
|||
# apps/web
|
||||
# apps/web — Vignette 프론트엔드
|
||||
|
||||
React 19 프론트엔드 (Vignette). 3역할 페이지 + 상담 세션 UI + 아바타.
|
||||
스택: React 19 + Vite + SSE. 추후 React Native 공유 코어.
|
||||
React 19 + Vite + TypeScript + react-router v6. 상태는 Context(AuthContext) 중심.
|
||||
3역할(학습자/교수자/관리자) 공통 앱 셸 + 상담 세션 UI + 가상 내담자 아바타.
|
||||
디자인 단일진실원본: `docs/DESIGN_CONCEPT.md` + `docs/dev_dashboard.html`(토큰).
|
||||
|
||||
## 실행
|
||||
|
||||
```bash
|
||||
cd apps/web
|
||||
npm install
|
||||
npm run dev # http://localhost:5173 (개발 서버, /api → :8000 프록시)
|
||||
```
|
||||
|
||||
기타 스크립트:
|
||||
|
||||
```bash
|
||||
npm run build # tsc -b + vite build → dist/
|
||||
npm run preview # 빌드 결과 미리보기
|
||||
npm run typecheck # tsc --noEmit (타입 체크만)
|
||||
```
|
||||
|
||||
백엔드(FastAPI)는 `apps/api`에서 `uvicorn app.main:app --port 8000`으로 띄운다.
|
||||
미가동이어도 프론트는 동작한다(개발용 mock 로그인으로 진입 가능).
|
||||
|
||||
### 환경변수
|
||||
|
||||
| 변수 | 기본값 | 설명 |
|
||||
|---|---|---|
|
||||
| `VITE_API_BASE` | `/api` | API 베이스. 개발은 vite proxy, 프로덕션은 nginx가 백엔드로 라우팅 |
|
||||
|
||||
## 라우트
|
||||
|
||||
| 경로 | 페이지 | 역할 | 비고 |
|
||||
|---|---|---|---|
|
||||
| `/login` | Login | — | 완성. OAuth(한신대/구글) mock + 역할 선택 |
|
||||
| `/learn` | LearnerHome | learner | 스텁 (Features 단계 교체) |
|
||||
| `/learn/session/:sessionId` | Session | learner | 스텁 + 동작하는 아바타 미리보기 |
|
||||
| `/learn/session/:sessionId/review` | SessionReview | learner | 스텁 |
|
||||
| `/teach` | Professor | teacher | 스텁. `data-role=instructor` accent |
|
||||
| `/admin` | Admin | admin | 스텁. `data-role=admin` accent |
|
||||
| `/settings` | Settings | 전체 | 스텁 |
|
||||
| `/` | → 역할 홈 | — | 미인증이면 `/login` |
|
||||
|
||||
보호 라우트는 `AuthContext` 기반 `RequireAuth` 가드(미인증 → `/login`,
|
||||
역할 불일치 → 자신의 역할 홈). 과설계 없음.
|
||||
|
||||
## 구조
|
||||
|
||||
```
|
||||
src/
|
||||
main.tsx 엔트리. 스타일 import 1회.
|
||||
App.tsx 라우터 + 역할 가드.
|
||||
vite-env.d.ts import.meta.env 타입.
|
||||
styles/
|
||||
tokens.css ★ 디자인 토큰 (라이트/다크/역할 accent). dev_dashboard 계승.
|
||||
global.css reset + body + 스크롤바 + 유틸.
|
||||
lib/
|
||||
api.ts fetch wrapper(credentials:include) + SSE 헬퍼 + 세션 API + 백엔드 타입.
|
||||
auth.tsx AuthContext(user/role/login/logout). body[data-role] 반영.
|
||||
format.ts 시간/타이머/숫자 포맷(tabular).
|
||||
components/
|
||||
ui/ 프리미티브: Button Card Panel Kicker Badge StatLine
|
||||
ProgressBar Field/Input Dot Icon(inline svg) SectionHead.
|
||||
배럴: index.ts → import { Button, ... } from "../components/ui"
|
||||
shell/ AppShell Sidebar Topbar (§6.3 공통 셸).
|
||||
avatar/ClientAvatar.tsx 가상 내담자 SVG 아바타(동작 placeholder).
|
||||
pages/ Login(완성) + 6개 스텁.
|
||||
```
|
||||
|
||||
## 디자인 철칙 (위반 시 재작업)
|
||||
|
||||
- border-left 강조선·좌측 사이드바 강조줄 금지
|
||||
- 이모지 금지 — 아이콘은 전부 inline SVG(`components/ui/Icon.tsx`, stroke=currentColor)
|
||||
- 카드 격자 덤프 금지 (한 화면 한 메시지, 위계는 weight+여백)
|
||||
- 순흑(#000)/순백(#fff) 금지 — `--paper`/`--ink` 토큰만
|
||||
- 모서리 절제: 카드/버튼 8px, 입력 6px. 원형은 dot/아바타/음성오브만
|
||||
- 강조 = weight(400→600) + accent 텍스트 + accent-tint 배경 + 상단 kicker(+dot)
|
||||
- 빨강(`--crit-*`)은 진짜 위급/리스크에만
|
||||
|
||||
## Features 단계 인계 노트
|
||||
|
||||
- UI 프리미티브는 `components/ui` 배럴에서 가져온다. props/타입이 안정 계약이다.
|
||||
- `ClientAvatar` props(`persona`/`state`/`affect`/`analyser`)는 확정 인터페이스.
|
||||
avatar 에이전트는 이 파일 내부 SVG/모션만 고도화하고 시그니처는 유지.
|
||||
- 세션 데이터는 `lib/api.ts`의 `sessionApi`(start/turn/end/stream) 사용.
|
||||
SSE 토큰 수신은 `openSessionStream(sessionId, { onToken, onDone, ... })`.
|
||||
- 페이지는 `default export`. `AppShell`로 감싸면 톱바/네비/역할 accent가 자동 적용.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue