diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 81d456c..63a8d59 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -1,6 +1,6 @@ # Vignette Handoff -> Updated: 2026-06-27 17:06 KST. 새 세션은 이 문서와 `docs/DESIGN_CONCEPT.md`를 먼저 읽고 이어가면 된다. +> Updated: 2026-06-27 17:25 KST. 새 세션은 이 문서와 `docs/DESIGN_CONCEPT.md`를 먼저 읽고 이어가면 된다. ## 현재 상태 @@ -10,8 +10,8 @@ - 로컬 engine gateway 기본 포트: `http://127.0.0.1:9099` - 공개 웹: `https://vignette.chanpaca.net` - 공개 API: `https://api-vignette.chanpaca.net` -- 직전 기록된 앱 배포 소스 commit: `6bd91b0d` (`현재 작업 상태 저장`) -- 직전 기록된 Cloudflare Pages production deploy: `2a58ca49`, source `6bd91b0d` + dirty worktree, branch `main`. 최신 배포 ID는 `wrangler pages deploy` 실행 로그와 최종 작업 보고를 기준으로 확인한다. +- 최신 앱 배포 소스 commit: `0ec266a` (`동의 게이트와 런타임 안정화`) +- 최신 Cloudflare Pages production deploy: `12da49f3`, source `0ec266a`, branch `main`. - Google OAuth 허용 이메일 도메인: `hs.ac.kr`, `twentyoz.kr` - 최신 백엔드 회귀: `python -m pytest app/ -q` → `125 passed` - X1 재귀학습 export 1차: `scripts/export-recursive-dataset.py` 기본 read-only dry-run, `--write-dataset` 명시 시에만 `ds.*` write, approved export는 steward/legal/IAA gate 없으면 거부. @@ -26,10 +26,10 @@ - `frontenddesign` 스킬은 현재 세션의 사용 가능 스킬 목록에 없었다. 대신 `docs/DESIGN_CONCEPT.md`를 SSOT로 사용했다. - 공개 API 터널은 현재 `C:\Users\encep\.cloudflared\vignette-config.yml`에서 `http://127.0.0.1:8001`을 본다. - 공개용 API 프로세스는 `127.0.0.1:8001`에서 `ENVIRONMENT=prod`로 떠 있다. 로컬 개발 API `127.0.0.1:8000`과 Tailnet 개발 API `127.0.0.1:8010`도 `ENVIRONMENT=dev`로 떠 있다. -- 2026-06-27 05:34:32 UTC 모바일 502는 cloudflared 로그상 `127.0.0.1:8001` origin connection refused와 일치한다. 현재 public API는 복구됐고, watchdog 기본 검사에서 아직 DNS가 없는 `api-vnet.18ka.net`을 제외해 향후 설치 시 불필요한 restart loop를 막았다. 2026-06-27 17:00 KST 재확인: `https://vignette.chanpaca.net/login` 200, `https://api-vignette.chanpaca.net/health` prod/db/engine true. +- 2026-06-27 05:34:32 UTC 모바일 502는 cloudflared 로그상 `127.0.0.1:8001` origin connection refused와 일치한다. 현재 public API는 복구됐고, watchdog 기본 검사에서 아직 DNS가 없는 `api-vnet.18ka.net`을 제외해 향후 설치 시 불필요한 restart loop를 막았다. 2026-06-27 17:25 KST 재확인: `https://vignette.chanpaca.net/login` 200, `https://api-vignette.chanpaca.net/health` prod/db/engine true, 공개 로그인 버튼 클릭 시 `accounts.google.com` OAuth URL로 이동. - `GET /personas`는 이제 인증 필요다. 검증 당시 로컬 `http://127.0.0.1:8000/personas`와 현재 공개 `https://api-vignette.chanpaca.net/personas` 모두 비로그인 401 확인 완료. - 로컬 웹이 `http://127.0.0.1:5175`처럼 다른 Vite 포트로 떠도 로그인은 `로컬 테스트 계정으로 계속` 버튼을 사용한다. Google OAuth 버튼은 로컬에서는 disabled로 둔다. 현재 OAuth callback이 공개 API로 돌아가기 때문에 로컬 Google OAuth는 로컬 세션에 붙을 수 없다. -- 현재 확인용 프로세스는 `127.0.0.1:9099` engine gateway, `127.0.0.1:8001` prod public API, `127.0.0.1:8000` dev API, `127.0.0.1:8010` Tailnet dev API, `127.0.0.1:5173` Vite web, `cloudflared` tunnel 1개다. Tailnet URL은 `https://alpaca-home.taile93291.ts.net/login`이다. stale Vite allowedHosts로 403이 났던 상태는 `scripts/start-tailscale-runtime.ps1` 재기동 후 `login` 200, `/api/health` dev/db/engine true, direct Google start → `local_oauth_unavailable`로 재검증됐다. +- 현재 확인용 프로세스는 `127.0.0.1:9099` engine gateway, `127.0.0.1:8001` prod public API, `127.0.0.1:8000` dev API, `127.0.0.1:8010` Tailnet dev API, `127.0.0.1:5173` Vite web, `cloudflared` tunnel 1개다. Tailnet URL은 `https://alpaca-home.taile93291.ts.net/login`이다. stale Vite allowedHosts로 403이 났던 상태는 `scripts/start-tailscale-runtime.ps1` 재기동 후 `login` 200, `/api/health` dev/db/engine true, direct Google start → `local_oauth_unavailable`, dev-login → `/learn` + `/api/auth/me` 200으로 재검증됐다. - `scripts/dev-up.ps1 -NoGateway -NoWeb`는 이제 gateway/web stale 정리를 건너뛰고 지정 `-ApiPort`의 API만 재기동한다. 검증 당시 8000 API-only 재기동 후 8001/8010/5173/9099/20241 listener가 보존됐다. - Docker `vignette-dev-db`는 실행 중이고 DB는 accepting connections다. 단, 기존 컨테이너라 healthcheck가 없고 `POSTGRES_USER=vignette` 기반이다. `vignette_app` role은 NOBYPASSRLS로 존재하지만 현재 API startup DDL이 owner 권한을 요구하므로 런타임 app-role 전환은 마이그레이션 owner/런타임 role 분리 후 진행한다. - 공개 런타임 재기동 스크립트: @@ -157,8 +157,8 @@ - API 8001 health and public `https://api-vignette.chanpaca.net/health` both returned `environment:"prod"`, `db:true`, `engine:true` - Public web deployment: - `wrangler pages deploy dist --project-name vignette --branch main --commit-dirty=true` - - Production deployment `2a58ca49` - - `https://vignette.chanpaca.net/` serves `assets/index-BzQmv-jU.js` and `assets/index-CCZ1bDA9.css` + - Production deployment `12da49f3` + - `https://vignette.chanpaca.net/` serves `assets/index-DEgzFAUm.js` and `assets/index-BGRtWhu_.css` - `https://vignette.chanpaca.net/live2d/mao/Mao.model3.json`, Haru model, and Cubism core routes return 404 - Public login screen: - `npx playwright test e2e/auth.spec.ts --project=chromium-desktop --grep "public login"` diff --git a/docs/dev_dashboard.html b/docs/dev_dashboard.html index 4840c2e..fd6c99d 100644 --- a/docs/dev_dashboard.html +++ b/docs/dev_dashboard.html @@ -288,7 +288,7 @@ Full Playwright 72 통과 Backend pytest 122 통과 Layout 시각게이트 7/7 accept - Pages prod 2a58ca49 + Pages prod 12da49f3 Public API prod OK 원천문서 갭 critical 3 Decision P0 조건부 @@ -695,7 +695,7 @@
운영 확인용 프로세스와 로컬/Tailnet 검증용 dev 프로세스를 의도적으로 분리해 유지한다.
9099 engine, 8001 prod API, 8000/8010 dev API, 5173 web, cloudflared tunnel 1개
Get-NetTCPConnection에서 대상 포트별 listener 확인
SSO 클레임, 추가 축어록 수급, 미성년 원본 활용동의, 개인정보 처리방침을 P1 진입 전 외부 의존성으로 명확히 둔다. 로컬 문서 골격은 준비됐지만 한신대/데이터 steward의 written evidence는 아직 필요하다.
docs/ops/hanshin-data-governance-gate.md, 공문 질의 항목, 동의 범위 체크리스트, SSO claim mapping 표
문서 artifact 작성 완료; IRB 게이트가 아니라 데이터/SSO 게이트로 외부 증거 필요 상태 유지
2a58ca49이 현재 워킹트리 dist로 배포됐고, 운영 반영 전 남은 핵심 증거는 공개 Google OAuth 실제 /turn smoke다. 런타임 mock/demo 자산은 운영 번들에서 제거하고 테스트 fixture만 남긴다.12da49f3이 commit 0ec266a dist로 배포됐고, 운영 반영 전 남은 핵심 증거는 공개 Google OAuth 실제 /turn smoke다. 런타임 mock/demo 자산은 운영 번들에서 제거하고 테스트 fixture만 남긴다.이전 "완료" 카드 내용을 탭 안에서 항목별로 보존한다.
session-persistence, teacher, voice는 /api/personas에서 실제 DB persona를 가져온다.
seed persona 직접 결합 제거, 실제 persona catalog 기반 E2E
persona 관련 E2E가 DB-backed persona로 통과
실제 운영 도메인에 반영됐는지, 서버가 하나로 정리됐는지, 완료라고 말할 증거가 있는지 확인하는 탭이다.
커스텀 도메인이 최신 JS/CSS asset을 서빙한다.
index-BzQmv-jU.js, index-CCZ1bDA9.css
Invoke-WebRequest https://vignette.chanpaca.net/login?probe=deploy-20260627
커스텀 도메인이 최신 JS/CSS asset을 서빙한다.
index-DEgzFAUm.js, index-BGRtWhu_.css
Invoke-WebRequest https://vignette.chanpaca.net/login
터널은 prod API 8001을 보고, API는 DB와 engine을 모두 확인한다.
environment:"prod", db:true, engine:true
https://api-vignette.chanpaca.net/health
로컬 web/api/engine을 Tailscale Serve로 묶어 같은 Tailnet PC·모바일에서 HTTPS로 접근한다. Vite proxy와 API 포트가 어긋나지 않도록 dev-up.ps1에서 VITE_API_PROXY_TARGET을 ApiPort와 동기화한다. Tailnet dev-origin에서는 public OAuth redirect_uri가 로컬/Tailnet 세션이 아니라 공개 API 세션으로 돌아가므로 Google 버튼과 직접 Google 시작 URL을 local_oauth_unavailable로 차단하고 dev-login만 사용한다. Vite proxy는 원래 프론트 host/proto를 X-Forwarded-Host/X-Forwarded-Proto로 넘긴다.
scripts/start-tailscale-runtime.ps1, AUTH_DEV_LOGIN_EXTRA_ORIGINS, VITE_ALLOWED_HOSTS, Login.tsx, vite.config.ts, auth.py
https://alpaca-home.taile93291.ts.net/login 200, /api/auth/config dev_login true, dev-login 후 /api/auth/me 200, direct Google start → /login?oauth=local_oauth_unavailable, Tailnet auth/dev-login E2E 2 passed.
vnet.18ka.net과 api-vnet.18ka.net을 정식 공개 도메인으로 허용하도록 코드 경로는 보강했다.
FRONTEND_ORIGIN_MAP, 공개 host별 API 매핑, scripts/start-public-runtime.ps1 vnet ingress 옵션
현재 DNS 미해결, Cloudflare credential의 18ka.net zone 권한 불일치, Google OAuth redirect URI 등록 필요.
python -m compileall app engine_gatewaypython scripts\check-phase3-artifacts.py --helpnpm run buildwrangler pages deploy dist --project-name vignette --branch main --commit-dirty=true2a58ca49, source 6bd91b0d + dirty worktreehttps://vignette.chanpaca.net/login?probe=deploy-20260627index-BzQmv-jU.js, index-CCZ1bDA9.csswrangler pages deploy dist --project-name vignette --branch main --commit-dirty=true12da49f3, source 0ec266ahttps://vignette.chanpaca.net/loginindex-DEgzFAUm.js, index-BGRtWhu_.css/live2d/mao/* / /live2d/haru/* / /live2d/live2dcubismcore.min.jsdocker compose -f infra\docker-compose.yml --env-file infra\.env.example config --quietadmin + db-persistence + voice-successauth.spec.ts --grep public loginstart/watch/install-public-runtime*.ps1api-vnet.18ka.net; add future domains explicitly with -AdditionalPublicHealthUrls.https://api-vignette.chanpaca.net/healthhttps://vignette.chanpaca.net/login / http://localhost:5173/login / https://alpaca-home.taile93291.ts.net/login127.0.0.1:8001 origin refused였고 현재 public login 200, public API health prod/db/engine true. Tailnet 403은 stale Vite allowedHosts 문제였고 start-tailscale-runtime.ps1 재기동 후 login 200 + `/api/health` dev/db/engine true. public Google auth redirect 302 with HttpOnly state cookie, local/Tailnet Google direct → local_oauth_unavailable.https://vignette.chanpaca.net/login / http://localhost:5173/login / https://alpaca-home.taile93291.ts.net/login127.0.0.1:8001 origin refused였고 현재 public login 200, public API health prod/db/engine true. Public login button click reaches accounts.google.com with HttpOnly state cookie. Tailnet 403은 stale Vite allowedHosts 문제였고 start-tailscale-runtime.ps1 재기동 후 login 200 + /api/health dev/db/engine true + dev-login /learn 진입 + /api/auth/me 200. local/Tailnet Google direct → local_oauth_unavailable.PLAYWRIGHT_BASE_URL=http://127.0.0.1:5175 auth.spec.tslearner.spec.ts + readiness.spec.ts desktop/mobilelearn-empty-desktop.png / learn-empty-mobile-compact.png