{ "title": "NAS vignette-prod 정식 배포 (A 경로)", "date": "2026-09-01", "source": { "forgejo_master": "dce85620", "deploy_commits": [ "72353ecd 회기 연속성과 멀티 케이스 계약을 영속화", "f1b80676 케이스 이어하기 UI와 공통 탭·이미지 복구를 반영", "d6d9dc5f NAS 정식 스택과 배포 파이프라인 도구를 고정", "ed3252ed 상태판·가이드와 검증 증거를 동기화", "8931e64b NAS compose를 운영 실물 정의로 동기화", "5a74302e 마이그레이션 22의 name 배열 비교 캐스트를 교정", "dce85620 게이트웨이 openai provider 경로를 정식 소스로 복원" ], "build_host": "yunchan-nas (Forgejo http clone, git container)", "clone_verification": "HEAD dce85620 == Forgejo master" }, "pre_deploy_backup": { "db_dump": "/volume1/docker/vignette-prod/backups/pre-deploy-8931e64b-20260901-114915.dump", "dump_bytes": 11036928, "dump_sha256": "cab6826b6f4b09d7dc87c68103310daa38d367db4e05791fd925d79c0c1e53e2", "dump_toc_entries": 1783, "env_backup": "private/env.nas.before-deploy-8931e64b-20260901", "rollback_images": { "api": "vignette-nas-api:goal-nas-ssot-20260830 (sha256:7d39d211...)", "web": "vignette-nas-web:goal-nas-ssot-20260830 (sha256:3998d90b...)" } }, "db_migrations": { "duplicate_active_cleanup": { "closed_rows": 30, "policy": "learner-persona 쌍마다 최신 활성 회기만 유지, 이전 활성은 ended_at=now()로 종료 (데이터 삭제 없음)", "receipt": "/volume1/docker/vignette-prod/receipts/stale-active-cleanup-20260901.csv", "remaining_duplicate_pairs": 0 }, "applied": ["20_public_bootstrap_ticket_events.sql", "21_single_active_session.sql", "22_case_profile_multi_case.sql"], "mig21_index_valid": true, "mig22_fix": "attname name[] vs text[] 비교 캐스트 결함을 발견·교정 (5a74302e)" }, "deployed_runtime": { "api_engine_image": "vignette-nas-api:dce85620 (sha256:b0ea1ce8a047d36b63b45b1bca795d1f5687e7c9fc0deafea0827684d1de6ffc)", "web_image": "vignette-nas-web:8931e64b (sha256:8040a6541285a95e180d81c9f06c5b22711849fa02029e824104ac7fac057f5c)", "db_container": "미교체 (Up 45h 연속, pgdata 외부 볼륨 보존)", "gateway_regression_found": "master에 openai provider 구현이 없어 첫 컷오버가 degraded — 구 운영 이미지에서 코드 이식·테스트 71 passed 후 재배포로 해소" }, "post_deploy_readiness": { "public_health": "status=ok, db=true, engine=true, engine_mode=openai, provider OK", "openapi": 200, "auth_me_unauthenticated": 401, "dev_login": 404, "internal_loopback_18080": 200, "containers": "api/engine/db healthy, web/proxy up" }, "data_preservation": { "before": {"app_user": 1380, "sessions": 618, "turns": 1743, "case_profile": 565, "active_sessions": 437}, "after": {"app_user": 1380, "sessions": 618, "turns": 1743, "case_profile": 565}, "note": "active_sessions는 중복 정리 30행 종료로 437→407 (행 삭제 0)" }, "public_web_pages": { "deployment": "9224a64b.vignette-b1q.pages.dev (production, branch main)", "new_entry": "index-BFKGXJQi.js / index-DT8YbZqu.css (200, application/javascript)", "previous_entry_preserved": "index-Bm30Ozeb.js = 200", "preserved_prior_assets": 175 }, "browser_e2e_readonly": { "login_screen": "렌더 정상 (단일 Google CTA)", "console_errors": "비로그인 /auth/me 401 1건뿐 (예상 동작)", "oauth_redirect": "accounts.google.com, redirect_uri=https://api-vignette.chanpaca.net/auth/callback, PKCE S256, scope openid email profile" } }