diff --git a/app/main.py b/app/main.py index 9710ae2..99320d0 100644 --- a/app/main.py +++ b/app/main.py @@ -240,21 +240,27 @@ SETUP_BYPASS_PREFIXES = ( "/api/setup", "/api/config", "/setup", "/health", "/docs", "/openapi.json", "/redoc", ) +# R10: 셋업 완료(user 존재)는 단조(monotonic) — 한 번 확인되면 영구. 매 요청 COUNT 쿼리 +# 대신 캐시 플래그로 전환 (setup 후 모든 요청이 users COUNT 하던 per-request 비용 제거). +_setup_complete = False + @app.middleware("http") async def setup_redirect_middleware(request: Request, call_next): + global _setup_complete # 함수 내 read+assign 둘 다 모듈 전역 참조 (UnboundLocalError 방지) path = request.url.path - # 바이패스 경로는 항상 통과 - if any(path.startswith(p) for p in SETUP_BYPASS_PREFIXES): + # 셋업 완료됐거나 바이패스 경로면 즉시 통과 (DB 쿼리 없음) + if _setup_complete or any(path.startswith(p) for p in SETUP_BYPASS_PREFIXES): return await call_next(request) - # 유저 존재 여부 확인 + # 유저 존재 여부 확인 (셋업 완료 전 1회성 — 완료 확인되면 플래그 set 후 영구 skip) try: async with async_session() as session: result = await session.execute(select(func.count(User.id))) user_count = result.scalar() if user_count == 0: return RedirectResponse(url="/setup") + _setup_complete = True except Exception: pass # DB 연결 실패 시 통과 (health에서 확인 가능)