모바일 메뉴와 주요 화면 UX 개선 및 시각 검수

This commit is contained in:
Yun Chan 2026-09-12 17:57:59 +09:00
parent 89b5093ec7
commit e8b770e4d9
50 changed files with 3189 additions and 457 deletions

View file

@ -716,9 +716,10 @@ body[data-role="admin"] { --accent:#5B5F6B; --accent-bright:#7D818E; --acce
같은 골격 공유, 좌측 네비 항목 + 좌상단 컨텍스트 라벨만 차이. 역할 전환 시 화면 리셋이 아니라 메뉴·accent만 바뀜.
- 톱바 56px `background:var(--surface); border-bottom:1px solid var(--hair);` (그림자 없음).
- 좌측 네비 기본 72px 아이콘 전용(Lucide stroke 1.75), hover/포커스 시 220px 슬라이드(160ms). 활성 = 아이콘 `color:var(--accent)` + **3px 강조바 금지** → 아이콘 배경 `var(--accent-tint)` `border-radius:8px` 알약형(네비 알약만 8px 관용).
- 좌측 네비는 넓은 화면에서 항목 텍스트를 항상 함께 보이고, 7211024px에서는 168px 레일로 줄여도 라벨을 숨기지 않는다. 모바일에는 역할별 주요 3개 목적지와 `전체 메뉴`를 고정해 현재 위치와 추가 경로를 모두 찾을 수 있게 한다. `전체 메뉴`는 불투명 표면의 native dialog로 열고 Escape·Tab·호출자 포커스 복원을 보장한다. 활성 = 아이콘 `color:var(--accent)` + **3px 강조바 금지** → 아이콘 배경 `var(--accent-tint)` `border-radius:8px` 알약형(네비 알약만 8px 관용).
- 앱 셸은 뷰포트 높이의 고정 프레임이다. 톱바와 GNB는 화면에 남고, 라우트 콘텐츠를 담는 메인 영역만 독립적으로 세로 스크롤한다. GNB 장식은 네비 자체의 `background` 레이어로만 합성하며 문서 위에 절대 위치 의사요소로 띄우지 않는다.
- **역할 컨텍스트 라벨**: 톱바 좌측, `font-family:var(--font-num); font-size:13px; letter-spacing:0.04em; color:var(--accent);` — "학습 대시보드"/"교수 콘솔"/"운영 콘솔". "지금 누구로 보고 있나"의 유일하고 조용한 신호.
- 모바일 역할 전환은 현재 역할명이 보이는 native select(접근성 이름: `공간 선택`)로 제공하며, 조작면과 인접 아이콘 버튼은 각각 최소 44×44px을 유지한다. `Ctrl+W`·`Ctrl+N`·`Ctrl+T`의 브라우저 예약 단축키는 가로채지 않고, 기존 Alt 단축키를 보존하며 `Alt+H`는 역할 홈으로 이동한다.
- **권한 표현 원칙: 권한 없으면 DOM에서 제거.** disabled 회색처리도 안 함 — 존재를 숨김. 화면이 깨끗해지고 "내가 못 하는 것" 노이즈 제거. 임상 데이터 프라이버시(관리자는 학생 개별 성장곡선·transcript 기본 접근 불가, 메뉴 자체 렌더 안 함).
### 6.4 학습자 대시보드 (홈 = "당신은 나아지고 있다")

View file

@ -20,6 +20,7 @@
|---|---|
| [`guides/local-development.md`](./guides/local-development.md) | Windows 로컬 개발 환경·dev 스택 실행 |
| [`guides/testing.md`](./guides/testing.md) | pytest·typecheck·Playwright 검증 명령 |
| [`ops/ux-audit-2026-09-12.md`](./ops/ux-audit-2026-09-12.md) | 로컬 전 화면 UX·시각 감사의 수용 범위·남은 결함·증거 경계 (진행 중) |
| [`guides/architecture.md`](./guides/architecture.md) | API·web·engine·데이터 흐름 |
| [`ops/deployment-pipeline.md`](./ops/deployment-pipeline.md) | production NAS 배포 절차·승인·rollback 경계 |

View file

@ -302,6 +302,7 @@
<span class="eyebrow">project pulse</span>
<h1>지금 위치: <em>개선관리 원본 14개 재점검</em> — 2026-09-09 읽기 전용 확인에서 완료 13·검토 1(C-001)이다. REQ-009~011의 로컬 재검증은 수용했고, SHA `1306c524` 운영 배포 뒤 H09를 새 live 검증으로 PASS 확인했다. 2026-09-01·09-08 배포는 역사 증거이며, 9/9 배포가 기존 PASS 전체의 새 검증을 뜻하지는 않는다.</h1>
<p class="pulse-state"><b>실배포 CUA 128:</b> 카탈로그는 생성됐지만 전체 검증은 미완료다. H09(기록 검색·필터 복귀)는 SHA `1306c524`에서 PASS로 재확인했고 T18(감독·연구 drilldown)은 수정 배포 뒤에도 learner 브라우저만 있어 RED를 종결하지 않았다. 관리자와 일반 학습자 로그인에서 학습자의 `/admin`·`/teach`→`/learn` 차단, P4 추천·R09 잠금·R14 워크시트 보존을 확인했다. 순수 teacher·OFF 계정, 교수자 쓰기, 모바일과 독립 관찰자 공개 검증은 남아 있다.</p>
<p class="pulse-state"><b>2026-09-12 비넷 UX 감사:</b> <b>DONE · 로컬 시각 검수 수용</b>. 역할별 메뉴·모바일 라벨, 학습자 정보 위계와 긴 목록, 상담 시작 버튼 겹침, 교수·관리자 표의 넘침, 설정과 약관 배치를 수정했다. 전체 레이아웃 15 passed, 마지막 관리자 폭 보정 후 2 passed, 회기 8 passed, 접근성 44개(38+6) 통과와 직접 이미지 검수를 수용했다. 상세 판정·반려 기록·실제 API와 fixture 증거 경계는 <a href="./ops/ux-audit-2026-09-12.md">감사 기록</a>에 있다. 로컬 web 5273·API 8200 기준이며 운영 배포·전체 기능 출시 판정은 포함하지 않는다.</p>
<p class="pulse-state"><b>2026-08-31 배포 파이프라인 재정립(역사 기록):</b> git 관리·배포는 <code>git.chanpaca.net</code>(Forgejo) 중심으로 이관했고, <code>github.com</code>(origin)은 private 백업/미러로 유지한다. 배포 대상은 NAS Production(<code>docker-compose.nas.yml</code>, <code>vignette-prod</code>)이며 이 PC는 개발용이다. Cloudflare tunnel은 NAS ingress의 현재 경로이므로 대체 ingress 검증 전에는 제거하지 않는다. 문서 <a href="./ops/deployment-pipeline.md">deployment-pipeline.md</a>.</p>
<p class="pulse-state"><b>최근 확인된 배포 증거(2026-09-01 당시):</b> Forgejo master <code>dce85620</code>를 NAS에서 직접 clone·빌드해 <code>vignette-prod</code> api/engine/web을 교체했고, Cloudflare Pages production도 새 빌드(<code>index-BFKGXJQi.js</code>, 이전 세대 자산 보존)로 배포했다. 사전 dump <code>cab6826b…</code>(11.0MB·TOC 1783)·env 백업·구 이미지 보존으로 롤백 경로를 고정했다. 중복 활성 회기 14쌍 30행은 최신 유지 정책으로 종료(영수증 보존·삭제 0)하고 마이그레이션 20/21/22를 온라인 적용했다. 이 과정에서 mig22의 <code>name[]=text[]</code> 캐스트 결함과 master의 게이트웨이 openai provider 누락 회귀를 발견해 즉시 교정했다(테스트 71 passed). 배포 당시 public health <code>ok·db/engine true</code>, OpenAPI 200, <code>/auth/me</code> 401, dev-login 404, 데이터 집계 전후 동일(app_user 1380/sessions 618/turns 1743)을 확인했다. 증거: <a href="./ops/evidence/nas-prod-deploy-2026-09-01.json">nas-prod-deploy-2026-09-01.json</a>. <b>headful 실계정 폐루프도 당시 완료:</b> NAS env의 OAuth secret 오류(<code>invalid_client</code>)를 교정한 뒤 소유자 실계정 로그인→기존 회기 20건 표시(데이터 보존)→새 사례 회기 생성(mig22 실증)→실턴 SSE·AI 응답→종료→리뷰 생성까지 GREEN(sessions 619·turns 1745·case_profile 566). 일일 검증형 DB 백업 sidecar 첫 덤프도 11.2MB로 성공했다. <b>남은 운영·외부 게이트:</b> C-001 외부 임상 검수, NAS 재부팅 자동복구 smoke, 백업 실패 알림·off-host 복제.</p>
<details class="pulse-details">
@ -1136,7 +1137,7 @@
<tbody>
<tr><td>Web typecheck</td><td><code>npm run typecheck</code></td><td>Passed</td></tr>
<tr><td>Design SSOT / auth visual</td><td><code>npm run check:design-ssot</code> / <code>npx playwright test e2e/auth-visual.spec.ts --project=chromium-single-run --reporter=line</code> / <code>npx playwright test e2e/layout-visual-gate.spec.ts --project=chromium-single-run --reporter=line</code></td><td>SSOT checker passed; login/onboarding light-dark desktop-mobile 1 passed; 14 core screens × 7 widths visual gate 14 passed.</td></tr>
<tr><td>Full Playwright E2E baseline</td><td><code>npm run e2e:parallel</code> / <code>npm run e2e:single-run</code> / <code>npm run e2e:list</code></td><td>2026-09-09 현재 수집은 <b>1188 tests / 66 files</b>다. 이 숫자는 수집량이며 현 작업트리 전체 GREEN과 동일하지 않다. G8 clean-head release gate는 candidate 112/112와 실제 NAS-origin 112/112를 통과했다. 이전 단일 120/120과 2026-07-15의 fixture desktop/mobile 166/166 + DB/engine/provider 직렬 49/49 = 215/215는 범위가 다른 역사 기준선으로 보존한다.</td></tr>
<tr><td>Full Playwright E2E baseline</td><td><code>npm run e2e:parallel</code> / <code>npm run e2e:single-run</code> / <code>npm run e2e:list</code></td><td>2026-09-12 <code>.devlogs/playwright-accepted-list.out.log</code> 기준 현재 수집은 <b>1219 tests / 70 files</b>다. 이 숫자는 수집량이며 현 작업트리 전체 GREEN과 동일하지 않다. G8 clean-head release gate는 candidate 112/112와 실제 NAS-origin 112/112를 통과했다. 이전 단일 120/120과 2026-07-15의 fixture desktop/mobile 166/166 + DB/engine/provider 직렬 49/49 = 215/215는 범위가 다른 역사 기준선으로 보존한다.</td></tr>
<tr><td>Refactor governance P1~P8</td><td><code>ruff check app</code> / <code>pytest -q app</code> / <code>pytest -q engine_gateway</code> / <code>npm run typecheck</code> / <code>npm run check:api-types</code> / <code>npm run check:design-ssot</code> / <code>npm run check:dead-code</code> / <code>npm run check:duplication</code> / <code>npm run build</code> / <code>npm audit --audit-level=high</code> / full Playwright</td><td>Backend 400 passed, gateway 29 passed, web gates/build/audit passed, vulnerabilities 0, production duplication 1 clone/15 lines/0.03%, Playwright 215/215 passed. 상세 근거는 <code>archive/project-cleanup-2026-09-07/refactor-governance-2026-07-15.md</code>.</td></tr>
<tr><td>API typegen SSOT</td><td><code>npm run check:api-types</code></td><td>Passed; FastAPI OpenAPI → <code>src/lib/api.gen.ts</code> stale check</td></tr>
<tr><td>Outcome &amp; Alliance OS G0</td><td><code>py -3.11 -X utf8 -m pytest -p no:cacheprovider apps/api/app/test_measurement_contract.py apps/api/app/test_runtime_schema_ssot.py -q</code> / <code>scripts/check-measurement-ledger.sql</code> / measurement·API contract checks / web typecheck / DB-backed <code>session-persistence</code> focused E2E 3종</td><td>G0 contract/schema 11 passed, 기존 backend 100 passed, auth 39 passed. Python→JSON Schema→TypeScript→PostgreSQL enum·필수필드 계약이 일치하고 8개 deterministic benchmark가 검증됐다. Live PostgreSQL에서 learner/client/evaluator 가시 행 1/1/2, 교차 누수 0, append-only guard 2를 확인했다. 학습자 턴→교수자 대시보드, 워크시트 검수, 종료 deep 평가→durable 리뷰 E2E는 각각 1 passed. G0/AOS-001~004 완료.</td></tr>

View file

@ -20,7 +20,7 @@ Vignette 저장소의 모든 검증 수단(백엔드 단위 테스트, 웹 타
| API 타입 생성 체크 | `apps/web` | `npm run check:api-types` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | pass |
| 웹 타입체크 | `apps/web` | `npm run typecheck` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | pass |
| 웹 빌드 | `apps/web` | `npm run build` | 불필요 | 불필요 | 불필요 | 불필요 | 불필요 | pass |
| Playwright E2E(전체) | `apps/web` | `npm run e2e` | **필요(+시드)** | **필요** | 자동기동 | 일부만 | **필요** | 현재 수집 1188 tests / 66 files · 현 작업트리 전체 GREEN 미검증 |
| Playwright E2E(전체) | `apps/web` | `npm run e2e` | **필요(+시드)** | **필요** | 자동기동 | 일부만 | **필요** | 현재 수집 1219 tests / 70 files · 현 작업트리 전체 GREEN 미검증 |
핵심 원칙: **단위 테스트(pytest)와 타입체크/빌드는 외부 서비스 없이 단독 실행된다.**
**E2E만 풀스택(DB+API+웹+브라우저)을 요구한다.** 아래 각 절에서 근거와 절차를 설명한다.
@ -321,7 +321,7 @@ VITE_API_BASE=http://127.0.0.1:8000 npm run e2e # 프록시 대신 API
### 3.6 실측 테스트 개수 (현재)
2026-09-09 `npx playwright test --list` 기준 **현재 수집 1188 tests / 66 files**다
2026-09-12 `.devlogs/playwright-accepted-list.out.log``npx playwright test --list` 기준 **현재 수집 1219 tests / 70 files**다
(유스케이스 16테마 `uc-*.spec.ts` 239 시나리오 포함).
이 숫자는 수집량이지 통과량이 아니다. 현 작업트리 전체 1109개 완주는 아직 증거가 없으며,
과거 전체 GREEN 기록과 이번 focused/release gate 결과를 구분해 적는다.

View file

@ -0,0 +1,33 @@
# 2026-09-12 비넷 UX·시각 감사
> 판정: **DONE · 로컬 시각 검수 수용**. 업그레이드된 designpaca와 설치된 디자인 스킬을 검토하고 비넷의 기존 디자인 SSOT에 맞춰 수정했다. 로컬 web 5273 / API 8200 기준이며 운영 배포는 포함하지 않는다.
## 수용한 변경
| 영역 | 수정과 직접 검수 결과 |
|---|---|
| 공통 메뉴 | 역할별 주요 목적지 3개와 전체 메뉴, 명확한 한글 라벨, 태블릿 텍스트 레일, 모바일 역할 선택, 불투명 메뉴와 포커스 복원을 확인했다. 브라우저 예약 Ctrl 단축키를 보존하고 Alt+H를 역할 홈에 연결했다. |
| 로그인·온보딩 | 상담 훈련 목적의 문구, 잘리지 않는 약관 제목·버전과 44px 조작면을 확인했다. 법률 본문과 동의 절차는 유지했다. |
| 학습자 홈·연습·기록 | 통계 정의와 정보 위계를 정리했다. 선택한 P4의 초기·리사이즈 가시성, 빈 기록 안내, 2열 모바일 통계, 기록 조작면을 확인했다. 긴 내담자 목록은 내부에서 스크롤하며 요약만 3줄로 제한하고 상세 본문은 유지한다. 768/1024/1440의 카드 비중첩·선택 항목 hit-test·시작 CTA를 확인했다. |
| 상담 시작·리뷰 | 긴 호소 본문을 읽기 좋게 배치했다. 모바일 시작 버튼을 내비게이션 위에 고정하고 중간 카드가 덮지 않도록 조상 stacking을 수정했다. 320/390의 상·중·하단 hit-test와 실제 이미지를 확인했다. 리뷰 자기평가 제출 버튼도 44px로 보정했다. |
| 교수자·내담자 설정 | 분석 표가 페이지 전체를 넓히던 문제를 고쳐 표 내부 가로 스크롤을 유지했다. 전체 목록·정렬·상세 버튼을 보정했다. 내담자 작성 4단계를 가로 한 줄로 복원하고 모바일 탭을 확인했다. |
| 관리자·감독 | 감독·연구와 개선안 검토 문구, 긴 ID 줄바꿈, 접근 관리 탭, 지원 요청 필터를 정리했다. 사용자 관리의 모바일 제목·탭·검색은 뷰포트 안에 두고 표만 내부 스크롤한다. AI 제공자 조회 실패는 확인 중으로 남지 않고 실패와 다시 확인을 표시한다. |
| 설정 | 320px 최소 폭 문제, 지원 요청과 동의의 좁은 배치, sticky 메뉴의 투명 배경을 수정했다. 역할에 맞는 메뉴 줄바꿈과 버튼·토글 조작면을 확인했다. |
## 검증 근거
- 전체 레이아웃: `.devlogs/layout-accepted.out.log` **15 passed (2.7m)**. 마지막 사용자 관리 폭 보정 후 관리자 관련 재검사도 `.devlogs/admin-final-geometry.out.log` **2 passed (18.2s)**.
- 회기: `.devlogs/session-final-v3.out.log` **8 passed (28.8s)**.
- 접근성·모바일: `.devlogs/a11y-final.out.log`의 38 passed와 구 제목을 새 제목으로 맞춘 `.devlogs/a11y-home-final.out.log`의 **6 passed**로 44개 모두 통과했다. 검사 기준은 완화하지 않았다.
- 학습자: 독립 40 passed, 마지막 긴 목록 focused 1 passed와 P4/resize/빈 기록 회귀 6 passed. `learner-long-list-final5`의 768/1440 원본을 직접 수용했다.
- 감독·관리자: 독립 **18 passed**. AI 제공자 실패→재시도 성공은 `.devlogs/provider-retry-accepted.out.log` **2 passed**.
- 타입 검사 포함 프로덕션 빌드와 디자인 SSOT 검사 통과: `.devlogs/ux-accepted-build.out.log`, `.devlogs/ux-accepted-design.out.log`.
- 전체 Playwright 수집은 **1219 tests / 70 files**다. 전체 1219개를 실행했다는 의미는 아니다.
## 시각 증거와 판정 경계
`outputs/ux-audit-2026-09-12/`에 수정 전·실패·수정 후 증거를 보존했다. `surfaces-final`은 추가 8개 경로 × 5개 폭의 내부 스크롤 캡처 113개다. `layout-accepted`, `session-prestart-fixed-v5`, `learner-long-list-final5`, 설정·셸·교수자·관리자 focused 캡처로 최종 상태를 확인했다. 목록 수집량만으로 합격을 판정하지 않았으며, 오케스트레이터가 화면과 diff를 직접 보고 수용했다.
카드가 겹친 첫 목록 수정, 반투명 메뉴, 시작 버튼 가림, 초기 로딩 화면을 완료 화면으로 찍던 캡처는 반려했다. 캡처 도구의 stale owner ID와 native 스크롤 끝점 오차도 수정했다. 빈 회기 fixture는 정확한 API 빈 상태 계약으로 보강했으며 실제 API 증거와 구분한다. `practice-real-api-final`의 후속 전체 화면 캡처는 로딩 중이어서 무효로 보존했다. 해당 배치의 수용 근거는 안정된 긴 목록 fixture 원본과 동작 검사다.
로컬 AI 게이트웨이는 비가용이고 제공자 조회 API는 500을 반환한다. 이번 감사는 이 상태를 숨기지 않고 실패·재시도 화면을 검수했다. 운영 서버 정상성, 실제 모델 생성·음성 연결, 전체 기능 출시 판정과 배포는 이 디자인 감사의 완료 범위에 포함하지 않는다. 소스 변경은 커밋·push·배포하지 않았다.