Vignette 개발 대시보드
2026-06-26 16:15 KST
team lead review

전체 로드맵 기준 현재 위치는 Phase 0 종료 직전이다.

이번 세션은 seed persona 결합 제거, 비개발 fail-closed 설정, compose OAuth 주입, admin 모바일 overflow 수정, persona 인증 경계 보강, 전체 Playwright 재통과, 공개 API prod 전환까지 완료했다. 이후 로컬 5175 런타임 재기동, admin 사용자 관리 E2E 안정화, 학습자 홈 0회 기록 UX, active session 실제 SSE 스트림 전환, 텍스트/음성 실패 턴 미저장, 직접 URL persona 우회 차단, Live2D demo 자산 제거, AI 운영 fail-closed 보강까지 전체 Playwright로 확인했다. 2026-06-26 15:18 KST 기준 공개 API 터널을 복구한 뒤 전체 Playwright 72개가 desktop/mobile/single-run 모두 통과했다. Cloudflare Pages production 배포 `0fe8f3cc`도 완료했고, 커스텀 도메인이 새 asset을 서빙하는 것을 확인했다. 과거 Mao/Haru Live2D demo 자산은 repo와 번들에서 제거했고, `/live2d/*` 운영 경로는 404로 차단했다. 로컬 프로세스는 prod API 8001, engine gateway 9099, cloudflared tunnel 1개만 남기고 dev API와 임시 Vite preview를 내렸다. 다만 이 HTML은 지금까지 Phase 0 상태판처럼 쓰였고, 아래에 Phase 1 이후 전체 계획을 보강했다. 공개 Google OAuth 실제 `/turn` 증명만 storageState 캡처 후 남아 있다.

Full Playwright72 passed
Pages Production0fe8f3cc
Public APIprod OK
Backend unittest20 OK
RoadmapP0-P3
DecisionP0 조건부

전체 개발 로드맵

`docs/MASTERPLAN.md`와 `docs/redteam/MASTERPLAN_REVISIONS.md`를 합친 팀장 판단용 단계표

Phase 0closing

기반 정렬 / 운영 안전장치

인프라, 인증 경계, fail-closed, 공개 배포, 회귀 테스트 안정화.

  • 상태: 대부분 완료, 공개 `/turn` proof만 남음
  • 검증: build + backend 20 + Playwright 72
  • 운영: prod API 8001, engine 9099, tunnel 1개
Phase 1next

MVP 코어 루프

1 페르소나 상담, 실제 턴 저장, 회기말 피드백, 저항 엔진 검증.

  • DoD: 로그인 → P1 상담 완주 → 피드백 수신
  • 추가: 음성 왕복 1턴 PoC 포함
  • 증거: cost/turn DB 적재 + openness 곡선 대조
Phase 2aplanned

3역할 / OAuth / 페르소나

학습자, 교수자, 관리자 권한 분리와 페르소나 확장.

  • DoD: 타인 session 직접 접근 403
  • 범위: OAuth BFF, RBAC, 교수 검수 루프
  • 주의: visible_to와 인간 권한은 별도 레이어
Phase 2bplanned

음성 캐스케이드

STT → 엔진 → TTS 왕복, WSS/터널 안정성, barge-in 로깅.

  • DoD: 50분 WSS 끊김 실측
  • 범위: Deepgram STT, OpenAI TTS, voice preset
  • 리스크: 실시간 레이턴시는 실측 전 완료 표기 금지
Phase 3planned

교육용 파일럿 / 효과성

수련생 파일럿, 사전사후 효과 측정, 재귀학습 데이터셋 산출.

  • DoD: 20명 완주 + KPI 충족
  • 측정: SUS, 자기효능감, κ/ICC, 환각률
  • 정정: IRB 게이트가 아니라 데이터 활용동의/개인정보 게이트
정정 기준: `MASTERPLAN` 원본의 IRB 신청/승인 게이트는 `MASTERPLAN_REVISIONS` 기준으로 제거한다. Phase 2는 2a(3역할/OAuth/페르소나)와 2b(음성 캐스케이드)로 분리하고, Phase 1 DoD에는 얇은 음성 왕복 1턴 PoC를 포함한다.

상세 페이지

탭별 할 일, 산출물, 검증 기준. 팀장 리뷰는 여기서 다음 작업을 고르면 된다.

Phase 0 마감 상세

지금 단계는 구현을 더 벌리는 단계가 아니라, 운영 증거를 닫고 P1 진입 조건을 고정하는 단계다.

상태: 조건부우선순위: P0블로커: public /turn
BLOCK
공개 Google OAuth 실제 `/turn` proof 확보

로그인 가능한 계정으로 storageState를 저장한 뒤 public-auth-turn E2E를 실행한다.

산출물

`apps/web/node_modules/.tmp/public-auth.json`, public `/turn` 성공 로그

검증

`E2E_PUBLIC_AUTH=1` + `chromium-public-auth` 1회 통과

CHECK
engine config 운영값 재확인

E2E가 admin engine config를 만질 수 있으므로 배포 전 `mode/url/model` 값을 확인한다.

산출물

admin AI 운영 화면 캡처 또는 config API 응답

검증

`claude_cli / http://127.0.0.1:9099 / gateway-default` 의도값 대조

DONE
과거 Live2D demo 자산 제거

Mao/Haru 샘플, Pixi/Cubism 런타임, 공개 `/live2d/*` 캐시 잔여 접근을 차단했다.

산출물

`apps/web/functions/live2d/[[path]].js`, SVG-only avatar

검증

운영 `/live2d/mao/*`, Cubism core `404`

DONE
프로세스 난립 정리

임시 Vite preview와 dev API를 내리고 운영 확인용 프로세스만 유지한다.

산출물

9099 engine, 8001 prod API, cloudflared tunnel 1개

검증

`Get-NetTCPConnection`에서 8000/517x/5537 비어 있음

GATE
한신대 공문/데이터 거버넌스 게이트 정리

SSO 클레임, 추가 축어록 수급, 미성년 원본 활용동의, 개인정보 처리방침을 P1 진입 전 외부 의존성으로 명확히 둔다.

산출물

공문 질의서, 동의 범위 체크리스트, SSO claim 표

검증

IRB 게이트가 아니라 데이터/SSO 게이트로 문서 전수 정합

팀장 판정: 로컬 회귀와 공개 prod-safe 게이트는 통과했다. Cloudflare Pages production `0fe8f3cc`이 `543d48c` 소스로 배포됐고, 운영 반영 전 남은 핵심 증거는 공개 Google OAuth 실제 `/turn` smoke다. 런타임 mock/demo 자산은 운영 번들에서 제거하고 테스트 fixture만 남긴다.

Phase 0 완료 상세 목록

이전 “완료” 카드 내용을 탭 안에서 항목별로 보존한다.

DONE
DB persona 기반 테스트

`session-persistence`, `teacher`, `voice`는 `/api/personas`에서 실제 DB persona를 가져온다.

산출물

seed persona 직접 결합 제거, 실제 persona catalog 기반 E2E

검증

persona 관련 E2E가 DB-backed persona로 통과

DONE
비개발 런타임 보호

prod/staging에서 dev login, seed fallback, OAuth 누락, 기본 secret, localhost CORS를 거부한다.

산출물

fail-closed runtime config validation

검증

backend runtime policy unittest 통과

DONE
compose OAuth 주입

`ENVIRONMENT`, Google OAuth vars, `CORS_ORIGINS`, `OPENAI_BASE_URL`을 API 컨테이너에 명시했다.

산출물

compose 환경 주입 정리

검증

`docker compose --env-file .env.example config --quiet` 통과

DONE
admin 모바일 overflow 수정

긴 readiness detail을 안정화했고, 사용자 변경은 DB 저장소가 durable할 때만 허용한다.

산출물

admin responsive layout, durable store gate, AI health copy

검증

admin manage-users desktop/mobile 2 passed

DONE
global engine config 테스트 분리

`db-persistence`는 전역 engine config를 바꾸므로 `@single-run`으로 분리했다.

산출물

Playwright single-run tagging

검증

전체 Playwright 72 passed

DONE
handoff와 문서 갱신

`docs/HANDOFF.md`, `docs/dev_dashboard.html`, `apps/web/e2e/README.md`를 최신 상태로 맞췄다.

산출물

handoff, dashboard, E2E README

검증

최신 커밋 기준 상태/검증/운영 포트 일치

DONE
공개 API prod 전환

`cloudflared` ingress를 `127.0.0.1:8001` prod API로 돌렸고 public readiness gate가 통과했다.

산출물

prod API 8001, tunnel config

검증

`https://api-vignette.chanpaca.net/health` prod/db/engine OK

DONE
공개 런타임 재기동 스크립트

`scripts/start-public-runtime.ps1`와 `scripts/stop-public-runtime.ps1`로 API 8001과 cloudflared를 재현 가능하게 만들었다.

산출물

public runtime start/stop scripts

검증

engine 9099 + API 8001 + cloudflared only

DONE
persona catalog 인증화

`/personas`는 이제 비로그인 401이다. 로컬과 공개 API 모두 직접 확인했고 E2E 회귀를 추가했다.

산출물

authenticated persona catalog boundary

검증

local/public unauth `GET /personas` 401

DONE
public API base fallback 보강

public 웹에서 `/api/auth/config`가 SPA HTML로 떨어지지 않도록 public API origin fallback을 추가했다.

산출물

public API origin fallback

검증

public login screen E2E 1 passed

DONE
학습자 홈 0회 기록 상태

학습자 홈은 fake 기록 없이 실제 서버 세션 0개를 `기존 회기` 빈 상태와 0 카운트로 표시한다.

산출물

empty history UX, zero count, no fake stats

검증

learner screenshots: document overflow 0, empty history visible

DONE
로컬 5175 로그인 재기동 검증

`127.0.0.1:5175` web, `8000` API, `9099` engine을 재기동하고 dev-login 서버 세션과 `/learn` redirect를 확인했다.

산출물

local dev-login flow proof

검증

desktop/mobile auth flow passed

DONE
active session dense viewport 보정

375px급 active session에서 stage 내부가 1px 넘게 잘리던 문제를 avatar/padding 조정으로 제거했다.

산출물

session layout responsive adjustment

검증

session-layout desktop/mobile 8 passed

DONE
텍스트 턴 SSE 전환

`POST /sessions/{id}/stream` token 이벤트로만 내담자 자막을 쌓고, HTTP 거절과 SSE error 모두 실패 턴을 transcript와 저장소에 남기지 않는다.

산출물

real SSE stream turn path, failed turn discard

검증

session layout/turn E2E passed

DONE
음성 실패 턴 미저장

음성 회기도 엔진 응답 생성 성공 후에만 learner/client turn을 저장한다. 실패한 transcript는 pending 상태에서 제거한다.

산출물

voice failure persistence guard

검증

voice + voice-success + session-layout 15 passed

DONE
비영구 상태 문구 정리

admin health와 voice degraded reason은 내부 fallback/seed 표현 대신 비영구 런타임 상태를 사용자용 문구로 표시한다.

산출물

operator-facing copy cleanup

검증

settings/admin focused E2E 통과

DONE
직접 URL persona 차단

`/learn/session/:code`로 직접 들어와도 DB 원본 persona가 아니면 회기 시작을 막는다.

산출물

route guard, degraded/seed fallback regression

검증

unavailable persona code E2E 통과

DONE
demo Live2D 자산 제거

Mao/Haru 샘플과 Pixi/Cubism 런타임을 공개 배포물에서 제거했다. 세션 화면은 SVG persona avatar만 렌더링한다.

산출물

SVG-only avatar, legacy `/live2d/*` 404 function

검증

Mao/Haru/Cubism core routes 404, no Live2D/Pixi chunks