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

Phase 0는 검증 가능한 운영 안전장치와 E2E 안정화까지 마무리됐다.

이번 세션은 seed persona 결합 제거, 비개발 fail-closed 설정, compose OAuth 주입, admin 모바일 overflow 수정, persona 인증 경계 보강, 전체 Playwright 재통과, 공개 API prod 전환까지 완료했다. 이후 로컬 5175 런타임 재기동, admin 사용자 관리 E2E 안정화, 학습자 홈 0회 기록 UX, active session 실제 SSE 스트림 전환, 텍스트/음성 실패 턴 미저장, 직접 URL persona 우회 차단, Live2D demo fallback 제거, AI 운영 fail-closed 보강까지 전체 Playwright로 확인했다. 2026-06-26 14:53 KST 기준 공개 API 터널을 복구한 뒤 전체 Playwright 72개가 desktop/mobile/single-run 모두 통과했다. Cloudflare Pages production 배포 `b5e22068`도 완료했고, 커스텀 도메인이 새 asset을 서빙하는 것을 확인했다. 공개 Google OAuth 실제 `/turn` 증명만 storageState 캡처 후 남아 있다.

Full Playwright72 passed
Pages Productionb5e22068
Public APIprod OK
Backend unittest20 OK
App Commit188e899
Decision조건부 GO

팀장 판정

이 HTML만 보고 판단해야 하는 항목

go

로컬 회귀와 공개 prod-safe 게이트 통과

백엔드 unittest 20개, Python compile, 웹 production build, 전체 Playwright 72개가 통과했다. 공개 API도 `environment:"prod"`, `db:true`, `engine:true`로 응답한다.

deployed

커스텀 도메인 운영 반영 완료

Cloudflare Pages production `b5e22068`이 `188e899`로 배포됐고, `https://vignette.chanpaca.net`이 `index-BKpoLhfw.js`와 `index-BA9-xxfn.css`를 서빙한다.

conditional

운영 반영 전 남은 증거 1개

실제 Google 로그인 쿠키가 필요한 공개 `/turn` smoke는 아직 storageState가 없어 미완이다. 로그인 가능한 계정으로 한 번 캡처하면 바로 검증 가능하다.

mock audit

런타임 목업 제거 기준

프론트 페이지는 실제 API/DB 경로를 탄다. 남은 `mock` 표기는 테스트 코드의 `unittest.mock` 또는 의도적 fixture이며, seed fallback은 prod/staging에서 fail-closed 된다.

완료

새 세션에서 반복하지 않아도 되는 작업

E2E persona decoupled

DB persona 기반 테스트

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

fail-closed

비개발 런타임 보호

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

infra

compose OAuth 주입

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

admin UX

모바일 overflow 수정

긴 readiness detail을 안정화했고, 사용자 변경은 DB 저장소가 durable할 때만 허용한다. AI 운영은 실제 어댑터명과 health 상태를 표시한다.

test isolation

global engine config 분리

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

docs

handoff 갱신

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

public prod

공개 API prod 전환

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

ops script

공개 런타임 재기동

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

auth boundary

persona catalog 인증화

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

public web

API base fallback 보강

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

learner UX

0회 기록 상태 보강

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

local login

5175 로컬 재기동 검증

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

session UX

dense viewport 보정

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

real stream

텍스트 턴 SSE 전환

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

voice turn

음성 실패 턴 미저장

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

ops copy

비영구 상태 문구 정리

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

route guard

직접 URL persona 차단

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

avatar

demo Live2D fallback 제거

Mao/Haru 샘플은 공용 fallback으로 쓰지 않는다. 실제 persona별 `live2dModelUrl`이 있을 때만 Live2D를 렌더링한다.

검증

마지막으로 직접 실행한 결과

범위명령결과
Web typechecknpm run typecheckPassed
Backendpython -m unittest app.test_runtime_policy app.test_session_turn_persistence engine_gateway.test_gateway_model20 tests OK
Compilepython -m compileall app engine_gatewayPassed
Web buildnpm run buildPassed
Pages production deploywrangler pages deploy dist --project-name vignette --branch main`b5e22068`, source `188e899`
Custom domain assetshttps://vignette.chanpaca.net/`index-BKpoLhfw.js`, `index-BA9-xxfn.css`
Composedocker compose --env-file .env.example config --quietPassed with dummy required env
Focused E2Eadmin + db-persistence + voice-success10 passed
Admin manage-usersadmin.spec.ts --grep manage real server-known usersdesktop/mobile 2 passed
Full E2EPLAYWRIGHT_HOST=127.0.0.1 npx playwright test72 passed
Public auth discoveryE2E_PUBLIC_AUTH=1 npx playwright test --list --project=chromium-public-auth2 tests listed
Public readinesspublic-auth-turn.spec.ts --grep production-safe1 passed
Persona auth boundaryGET /personaslocal/public unauth 401
Public loginauth.spec.ts --grep public login1 passed
Public runtime scriptscripts\start-public-runtime.ps1API 8001 + cloudflared running
Public API healthhttps://api-vignette.chanpaca.net/healthprod, db true, engine true
Local 5175 loginPLAYWRIGHT_BASE_URL=http://127.0.0.1:5175 auth.spec.tsdesktop/mobile passed
Learner/readiness E2Elearner.spec.ts + readiness.spec.ts desktop/mobile14 passed
Learner screenshotslearn-empty-desktop.png / learn-empty-mobile-compact.pngdocument overflow 0, empty history visible
Session layout/turnsession-layout.spec.ts desktop/mobile8 passed
Voice/session focusedvoice + voice-success + session-layout15 passed
Latest focused E2Elearner + session-layout + settings + admin37 passed

남은 리스크

다음 세션 첫 작업

blocker

public `/turn` proof 없음

2026-06-26 14:53 KST 기준 Google 로그인 storageState가 없어 공개 API `/turn` 실제 성공 증거가 아직 없다.

ops

공개 API 프로세스 유지

터널은 `127.0.0.1:8001` prod API를 본다. 재부팅 후에는 prod API와 cloudflared를 같이 재기동해야 한다.

check before deploy

engine config 재확인

E2E가 admin engine config를 건드린다. 배포 전 의도한 model/url/mode인지 다시 확인해야 한다.

다음 명령

공개 OAuth smoke

cd D:\workspace\vignette\apps\web
npx playwright codegen https://vignette.chanpaca.net/login --save-storage=.\node_modules\.tmp\public-auth.json

$env:E2E_PUBLIC_AUTH="1"
$env:E2E_PUBLIC_STORAGE_STATE=".\node_modules\.tmp\public-auth.json"
.\node_modules\.bin\playwright.cmd test e2e/public-auth-turn.spec.ts --project=chromium-public-auth
cd D:\workspace\vignette
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start-public-runtime.ps1

주의

작업 방식