diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 19460c3..35cb959 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -10,8 +10,8 @@ - 로컬 engine gateway 기본 포트: `http://127.0.0.1:9099` - 공개 웹: `https://vignette.chanpaca.net` - 공개 API: `https://api-vignette.chanpaca.net` -- 최신 앱 배포 소스: 2026-07-03 commit `287029f2`. -- 최신 Cloudflare Pages production deploy: 2026-07-03 manual deploy `https://ef6bb270.vignette-b1q.pages.dev`, branch `main`, custom domain assets `assets/index-R5KK7hZI.js` + `assets/index-DzdAkRsn.css`. +- 최신 앱 배포 소스: 2026-07-03 commit `b67fd5d4`. +- 최신 Cloudflare Pages production deploy: 2026-07-03 manual deploy `https://8f6aba1c.vignette-b1q.pages.dev`, branch `main`, custom domain assets `assets/index-R5KK7hZI.js` + `assets/index-DzdAkRsn.css`, boot diagnostic HTML 포함. - Google OAuth 허용 이메일 도메인: `hs.ac.kr`, `twentyoz.kr` - 최신 백엔드 회귀: `C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -m pytest app/ -q` → `305 passed` - X1 재귀학습 export 1차: `scripts/export-recursive-dataset.py` 기본 read-only dry-run, `--write-dataset` 명시 시에만 `ds.*` write, approved export는 steward/legal/IAA gate 없으면 거부. @@ -34,7 +34,7 @@ - `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-07-03 KST 재확인 대상: `https://vignette.chanpaca.net/admin/users?deploy=287029f2` 200 with `assets/index-R5KK7hZI.js` + `assets/index-DzdAkRsn.css`, `https://api-vignette.chanpaca.net/health` prod/db/engine true, public unauth `GET /personas` 401. +- 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-07-03 KST 재확인 대상: `https://vignette.chanpaca.net/admin/users?deploy=b67fd5d4` 200 with `assets/index-R5KK7hZI.js` + `assets/index-DzdAkRsn.css` and `vignette-boot-diagnostic` HTML, `https://api-vignette.chanpaca.net/health` prod/db/engine true, public unauth `GET /personas` 401. - `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 dev web, `127.0.0.1:5174` public preview, `cloudflared` tunnel 1개다. Tailnet URL은 `https://alpaca-home.taile93291.ts.net/login`이다. stale Vite allowedHosts로 403이 났던 상태는 재검증 시 `login` 200, `/api/health` dev/db/engine true, `/api/auth/config` 200이었다. `alpaca-home.taile93291.ts.net`는 Vite 기본 `allowedHosts`에도 포함했다. @@ -170,8 +170,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` - - 2026-07-03 manual deployment, preview `https://ef6bb270.vignette-b1q.pages.dev` - - `https://vignette.chanpaca.net/admin/users?deploy=287029f2` serves `assets/index-R5KK7hZI.js` and `assets/index-DzdAkRsn.css` + - 2026-07-03 manual deployment, preview `https://8f6aba1c.vignette-b1q.pages.dev` + - `https://vignette.chanpaca.net/admin/users?deploy=b67fd5d4` serves `assets/index-R5KK7hZI.js`, `assets/index-DzdAkRsn.css`, and boot diagnostic HTML - `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 2363293..f58d2f4 100644 --- a/docs/dev_dashboard.html +++ b/docs/dev_dashboard.html @@ -964,7 +964,7 @@ Admin access delegationC:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 -m pytest -p no:cacheprovider app/test_admin_ops.py app/test_auth_providers.py::AuthProviderScaffoldTest::test_admin_role_can_enter_admin_console_even_with_stale_access_flag app/test_auth_providers.py::AuthProviderScaffoldTest::test_admin_role_can_enter_all_role_spaces_without_super_admin app/test_auth_providers.py::AuthProviderScaffoldTest::test_admin_access_flag_without_admin_role_does_not_enter_learner_space -q / npx playwright test e2e/admin.spec.ts --project=chromium-desktop --project=chromium-mobile --workers=1 --grep "approved admin without onboarding" / npx playwright test e2e/admin.spec.ts --project=chromium-desktop --workers=1 --grep "admin route guards" / npm run typecheck13 backend focused passed + admin onboarding guard E2E 2 passed + latest admin route guards 5 passed + web typecheck/build passed. 실제 admin role은 admin_access=false 세션이어도 can_access_role(Role.ADMIN)으로 관리자 API를 열고, 승인된 관리자 또는 admin_access 계정은 /admin*에서 학습자 온보딩으로 우회하지 않는다. 최초 진입 경로도 initialPathForUser가 소유해 primary role이 learner/teacher인 관리자 권한 계정이 / 또는 로그인 완료 후 /admin으로 들어간다. 관리자 sidebar와 기존 workspace 전환 계약은 유지된다. SPA route scroll resetnpm run typecheck / npx playwright test e2e/admin.spec.ts --project=chromium-desktop --workers=1 --grep "resets scroll" / Pages deployTypecheck passed and focused E2E 1 passed. App.tsx resets document scroll to top on pathname changes, so moving from a long admin page to short /admin/access no longer preserves stale scrollY and shows only the sticky topbar/sidebar over an empty main area. Probe proof: previous scrollY=1000, after clicking 권한 scrollY=0, heading 역할, 그룹, 접근 범위 in viewport. Live custom domain now serves assets/index-R5KK7hZI.js/assets/index-DzdAkRsn.css. Admin silent-blank diagnosticsnpm run typecheck / npx playwright test e2e/admin.spec.ts --project=chromium-desktop --workers=1 --grep "admin route guards" / dist watchdog smokeTypecheck passed and route-guard E2E 5 passed. Admin now normalizes malformed /admin/users payload fields such as cohort_ids=null, active_sessions=null, and created_at=null, plus malformed /admin/tickets payloads such as summary=null, instead of throwing during render. The screen shows 관리자 데이터 진단 with section/path/asset and broken field keys. App-level route render errors now fall back to a full-page diagnostic instead of a white screen, and zero-height main content still falls back to the admin diagnostic panel. If the React module itself fails before mount, index.html boot watchdog appends Vignette 화면 진단 directly to body; file-based JS-missing smoke confirmed the panel appears with path/asset/bodyText/visibleNodes. - OAuth/SAML admin landingC:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 -m pytest -p no:cacheprovider app/test_auth_providers.py -q / public runtime restart36 passed; OAuth/SAML callback now normalizes generic saved next paths such as /learn and /teach to /admin for admin-entitled users while preserving deep links such as /learn/session/.... Live proof after commits 998acb44/6b6241f4 and latest route-boundary deploy 287029f2: local/public /health returned prod, db=true, engine=true; custom domain now serves assets/index-R5KK7hZI.js/assets/index-DzdAkRsn.css; unauthenticated /personas remains 401. + OAuth/SAML admin landingC:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe -X utf8 -m pytest -p no:cacheprovider app/test_auth_providers.py -q / public runtime restart36 passed; OAuth/SAML callback now normalizes generic saved next paths such as /learn and /teach to /admin for admin-entitled users while preserving deep links such as /learn/session/.... Live proof after commits 998acb44/6b6241f4 and latest boot-diagnostic deploy b67fd5d4: local/public /health returned prod, db=true, engine=true; custom domain now serves assets/index-R5KK7hZI.js/assets/index-DzdAkRsn.css plus boot diagnostic HTML; unauthenticated /personas remains 401. Session read-model DB readinesspython scripts\check-deploy-preflight.py --skip-db --env-file infra\.env.example --allow-placeholder-secrets / https://api-vignette.chanpaca.net/health2026-06-29 prod 503 원인은 운영 DB의 app.turns.provider_events 컬럼 누락이었다. 운영 DB hotfix 후 /teacher/dashboard code path는 source=database로 복구됐다. 현재 db.healthcheck(), runtime table readiness, deploy preflight DB mode는 app.turns 음성 메타 컬럼 5개(audio_ref, silence_ms, speech_rate, barge_in, provider_events), app.session_review_status worksheet 컬럼, app.safety_events 필수 컬럼을 함께 검증한다. 2026-06-30에는 Docker Desktop/DB 중단으로 public API 530/error code 1033이 재발했지만, Docker Desktop/DB 재기동 뒤 public health가 environment=prod, db=true, engine=true로 복구됐다. Admin usage persistencepython -m pytest app/test_admin_ops.py app/test_runtime_policy.py -q / authenticated local public-API smoke26 passed; /admin/usage returns 200 with source=database, durable=true. Cloudflare blocked raw Python public smoke with 1010, so app-level HTTP was verified against 127.0.0.1:8001 using the same prod process. Synthetic health samplerrecord_admin_health_sample(), record-admin-health-sample.py, install-health-sampler-task.ps1Backend focused 31 passed. Python compile/help passed; PowerShell parser + -PrintOnly passed. Local one-shot appended 5 service rows to app.admin_health_event: status ok, engine_mode claude_cli. This remains sample history, not an SLA claim. @@ -993,7 +993,7 @@ Python compilepython -m compileall app engine_gatewayPassed Phase 3 artifact gatespy -3.11 -X utf8 scripts\check-phase3-artifacts.py --help + py -3.11 -X utf8 -m pytest -p no:cacheprovider app/test_dataset_export.py app/test_phase3_artifact_checker.py -q16 passed; checker now enforces CSV enums, KPI metric required fields/status, approved export PII/agreement/consent/withdrawal/file-hash gates, and approved/dry-run dataset JSONL required keys, row count, privacy, and PII shape. Actual pilot evidence still external. Web buildnpm run buildPassed - Pages production deploywrangler pages deploy dist --project-name vignette --branch main --commit-dirty=true2026-07-03 production deploy from commit 287029f2; preview https://ef6bb270.vignette-b1q.pages.dev; custom domain serves assets/index-R5KK7hZI.js/assets/index-DzdAkRsn.css. + Pages production deploywrangler pages deploy dist --project-name vignette --branch main --commit-dirty=true2026-07-03 production deploy from commit b67fd5d4; preview https://8f6aba1c.vignette-b1q.pages.dev; custom domain serves assets/index-R5KK7hZI.js/assets/index-DzdAkRsn.css and includes vignette-boot-diagnostic HTML. Custom domain assetshttps://vignette.chanpaca.net/login?dev_dashboard_redteam=20260630-recovered2026-06-30 recheck: login HTML HEAD 200. Public API 복구 후에도 web custom domain은 정상이다. Legacy Live2D routes/live2d/mao/* / /live2d/haru/* / /live2d/live2dcubismcore.min.js404 Compose templatedocker compose -f infra\docker-compose.yml config --quietTemplate path is valid with dummy required env. API build context now uses repo root; stale rag.server sidecar removed.