
    Oj0                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddl
mZmZ ddlmZmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZ ddlmZ  ej6                  e      Zedd       ZddZ e       Z ddZ!y)u  FastAPI app factory.

W2-F13/F14: import-time `init_db()` 제거 + `on_event("startup")` → `lifespan` 전환.
W2-F15: default-user bootstrap을 `backend/scripts/bootstrap_default_users.py` CLI로 이관.
  - dev/test 환경: lifespan이 자동 호출 (기존 편의 유지).
  - prod 환경: 자동 호출 생략 — CLI로 명시적 초기화 필요.
W2-F17: insecure default credentials는 prod에서 Settings가 fail-fast로 거부.
  dev/test에서는 경고만 남긴다.
    )annotationsN)asynccontextmanager)FastAPI)text)has_insecure_defaultssettings)SessionLocalinit_db)AppErrorapp_error_handler)setup_logging)load_strings)bootstrap_default_users)APP_VERSIONc                 K   t                t                t               }|r%t        j	                  ddj                  |             t                t               }	 ddlm	}  ||      }|rt        j	                  d|       t        j                  r'ddlm} 	  ||      }|rt        j	                  d|       t        j                   d
v rt#        |       n$t        j%                  dt        j                          |j'                          ddlm}m}	 	  |t        t        j,                         d	 	  |	        y	# t        $ r }t        j                  d|       Y d	}~d	}~ww xY w# |j'                          w xY w# t        $ r }t        j                  d|       Y d	}~sd	}~ww xY w# t        $ r }t        j	                  d|       Y d	}~y	d	}~ww xY ww)uH   startup + shutdown. 전역 side effect는 모두 이곳에서만 수행.uh   SECURITY: insecure default credentials in use — %s. Override via env vars before exposing this server.z, r   )recover_stale_progressz7Recovered %d stale pipeline progress entries on startup)reclaim_dead_locks_on_startupuG   기동 시 스텝 락 %d개 풀기 — 소유 프로세스가 없었다u7   기동 시 스텝 락 풀기 실패 (계속 진행): %sN)devtestul   ENVIRONMENT=%s — skipping automatic bootstrap. Run `backend/scripts/bootstrap_default_users.py` if needed.)start_heartbeatstop_heartbeat)interval_secondsu9   스텝 락 하트비트 시작 실패 (계속 진행): %su)   스텝 락 하트비트 정지 실패: %s)r   r   r   loggerwarningjoinr
   r	   app.core.task_registryr   r   step_lock_startup_reclaimapp.core.step_lockr   	Exceptionerrorenvironmentr   infocloser   r   step_lock_heartbeat_seconds)
appissuesdbr   	recoveredr   	reclaimedexcr   r   s
             >/Users/manta/Documents/Projects/TheRoad-I1/backend/app/main.pylifespanr,      s     ON"$FAIIf	
 I 
B'A*2.	NNI9 --H	]9"=	NNacl ?2#B'KKN$$ 	

 CW%AA	
 

IG  ] VX[\\] 	
  WPRUVVW  IBCHHIs   AG<E+  D? :AE+ <GF  1G7F, >G?	E(E#E+ #E((E+ +E==G 	F)	F$G$F))G,	G5GGGGc                 t   t        t        j                  ddt              } | j	                  t
        t               ddlm} ddl	m} ddl
m}m} ddlm} ddlm} ddlm} ddlm}m}	 ddlm}
 ddlm} ddlm} ddlm} ddlm} ddlm} | j/                  |       | j/                  |       | j/                  |       | j/                  |       | j/                  |       | j/                  |       | j/                  |       | j/                  |       | j/                  |	       | j/                  |
       | j/                  |       | j/                  |       | j/                  |       | j/                  |       | j/                  |       | j1                  d      | j1                  d	      d
               }| S )Nz	/api/docsz/api/openapi.json)titledocs_urlopenapi_urlr,   r   )router)r1   activity_router)r1   import_routerz/api/v1/healthz/api/healthc                     ddl m}  d}	 t               }|j                  t	        d             d}|j                          |rdndt        |rdnd |        t        t                     d	S # t        $ r Y 5w xY w)
Nr   )	key_countFzSELECT 1Tokdegradedr    )statusversionr'   gemini_keys
openai_key)
app.modules.llm.gemini_key_poolr5   r	   executer   r#   r   r   bool_active_openai_key)r5   db_okr'   s      r+   health_checkz create_app.<locals>.health_check   sy     	>	BJJtJ'(EHHJ
 $d"$W$;134
 	
  		s   6A* *	A65A6)r   r   app_namer,   add_exception_handlerr   r   app.api.v1.authr1   app.api.v1.usersapp.api.v1.projectsr2   app.api.v1.episodesapp.api.v1.entitiesapp.api.v1.imagesapp.api.v1.exportsr3   app.api.v1.operationsapp.api.v1.promptsapp.api.v1.stepsapp.api.v1.pipelineapp.api.v1.settingsapp.api.v1.grounding_fidelityinclude_routerget)r%   auth_routerusers_routerprojects_routerr2   episodes_routerentities_routerimages_routerexports_routerproject_import_routeroperations_routerprompts_routersteps_routerpipeline_routersettings_routergrounding_fidelity_routerrA   s                    r+   
create_appra   p   se   
'	C h(9: 67N==9cA;7==-{#|$''''}%~&,-()~&|$''01WWWW]
  
& J    c                     ddl m}   |        S )uO   활성 키 슬롯 — 1차 필드를 직접 보면 보조 키가 안 쓰인다.r   
active_key)app.core.openai_keysre   rd   s    r+   r?   r?      s    /<rb   )r%   r   )returnr   )rg   str)"__doc__
__future__r   logging
contextlibr   fastapir   
sqlalchemyr   app.core.configr   r   app.core.databaser	   r
   app.core.errorsr   r   app.core.logging_configr   app.i18n.loaderr   app.startup.default_usersr   app.versionr   	getLogger__name__r   r,   ra   r%   r?    rb   r+   <module>ry      so    #  *   ; 3 7 1 ( = #			8	$ OI OId>B lrb   