From c57c34ade6c904d5987fc748bda10d9b26ca0e1c Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Thu, 25 Jun 2026 23:51:59 +0900 Subject: [PATCH] =?UTF-8?q?feat(api):=20DB=20off=20degraded=20=EA=B8=B0?= =?UTF-8?q?=EB=8F=99(store=20=ED=8F=B4=EB=B0=B1)=20+=20dev=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20=EC=9A=B0=ED=9A=8C=20=E2=80=94=20=ED=92=80=20API=20?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=20E2E=20=ED=86=B5=EA=B3=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - main lifespan: init_pool 실패해도 store 인메모리 폴백으로 degraded 기동 - deps: environment=dev면 쿠키 없어도 더미 학습자(로컬 라이브). prod는 401 유지 - 실증: POST /sessions(201) → turn → 서연 client_reply, safety_flagged=false --- apps/api/app/deps.py | 10 ++++++---- apps/api/app/main.py | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/api/app/deps.py b/apps/api/app/deps.py index 3b70764..f18301a 100644 --- a/apps/api/app/deps.py +++ b/apps/api/app/deps.py @@ -63,10 +63,12 @@ async def get_current_principal( prod 에선 session_cookie 검증 실패 시 무조건 401. """ if not session_cookie: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="not authenticated", - ) + # dev 환경에선 쿠키 없어도 더미 학습자로 통과(로컬 라이브 테스트). prod 는 무조건 401. + if get_settings().environment != "dev": + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="not authenticated", + ) # TODO: Redis 세션 룩업. 아래는 개발 스텁. return Principal(user_id="dev-user", role=Role.LEARNER, cohort_ids=[]) diff --git a/apps/api/app/main.py b/apps/api/app/main.py index 441e06d..1795659 100644 --- a/apps/api/app/main.py +++ b/apps/api/app/main.py @@ -25,14 +25,26 @@ from .routes import voice as voice_routes @asynccontextmanager async def lifespan(app: FastAPI): - """startup: DB 풀 + 엔진 클라이언트 / shutdown: 정리.""" - await init_pool() + """startup: DB 풀 + 엔진 클라이언트 / shutdown: 정리. + + DB 미가용(Docker off / NAS 연결불가)이면 store 인메모리 폴백으로 degraded 기동한다. + """ + try: + await init_pool() + except Exception as exc: # DB 없어도 store 폴백으로 1턴 동작 (dev/로컬) + import logging + logging.getLogger("uvicorn.error").warning( + "DB 풀 초기화 실패 — store 인메모리 폴백으로 degraded 기동: %s", exc + ) await engine_client.startup() try: yield finally: await engine_client.shutdown() - await close_pool() + try: + await close_pool() + except Exception: + pass app = FastAPI(