
    $6j*                     8   d Z ddlmZ ddlmZ ddlmZmZmZ ddl	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 ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  ddlm!Z" ddlm#Z$ ddlm%Z& ddlm'Z( ddlm)Z* ddl+m,Z, edefd       Z- eddde-ddi      Z.e,j^                  dk(  rdgng Z0e.jc                  e
e0ddgdg        e.je                  ejf                         e.je                  e&jf                         e.je                  e jf                         e.je                  e$jf                         e.je                  ejf                         e.je                  ejf                         e.je                  ejf                         e.je                  e"jf                         e.je                  ejf                         e.je                  ejf                         e.je                  ejf                         e.je                  e(jf                         e.je                  e*jf                         e.ji                  d!d"g#      d$e5e6e6f   fd%       Z7e.ji                  d&d'(       ed)d*+      fd,e6fd-       Z8 ee9      ju                         jv                  jv                  d.z  Z<e<j{                         rNe.j}                  d/ ee<0      d.1       e.ji                  d2d'(      d3        Z?e.ji                  d4d'(      d5        Z@y7e.ji                  d2d"g#      d$e5e6e6f   fd6       ZAy7)8u  
FastAPI 入口檔。

`uvicorn app.main:app` 會載入這個檔的 `app` 變數作為 ASGI 應用程式。

職責:
  1. 建立 FastAPI 實例
  2. 設定 CORS(允許前端跨域呼叫)
  3. 掛載各路由模組(auth, users, ...)
  4. 提供 /health 健康檢查 endpoint
    )asynccontextmanager)Path)FastAPIHTTPExceptionQuery)CORSMiddleware)FileResponseHTMLResponse)StaticFiles)agent)auth)channels)coba)line_webhook)meetings)messages)projects)search)tasks)users)ws)rdash)settingsappc                  K   ddl fd}j                   |             | j                  _        	 ddlm} j                   |             | j                  _        	 ddlm} j                   |             | j                  _        	 dd	lm fd
}j                   |             | j                  _        d t#        | j                  dd      r$| j                  j                  j%                          t#        | j                  dd      r$| j                  j                  j%                          	 dd	lm j'                          d{    y# t        $ r9 ddl}|j                  d      j                  d       d| j                  _        Y 9w xY w# t        $ r9 ddl}|j                  d      j                  d       d| j                  _        Y Rw xY w# t        $ r( ddl}|j                  d      j                  d       Y Uw xY w7 # t        $ r' ddl}|j                  d      j                  d       Y yw xY ww)u!   應用程式生命週期掛勾。r   Nc                     K   	 ddl m}  j                  |        d {    ddl m}  |        d {    y 7 7 # t        $ r/}dd l}|j                  d      j                  d|       Y d }~y d }~ww xY ww)Nr   )_get_embedding_model)backfill_existing_messageszcoba.warmupu   warmup 失敗:%s)app.services.coba_memoryr   	to_threadr   	Exceptionlogging	getLogger	exception)r   r   er"   asyncios       ,/volume1/homes/robertsu/coba/app/app/main.py_warmupzlifespan.<locals>._warmup-   sr     	NE##$8999K,... : / 	Nm,667I1MM	NsC   A9> :> <> A9> > 	A6%A1,A91A66A9)scheduler_loop	coba.mainu   scheduler 啟動失敗)funnel_watchdog_loopu   funnel_watchdog 啟動失敗)cooper_client_managerc                     K   	 j                          d {    y 7 # t        $ r' dd l} | j                  d      j	                  d       Y y w xY ww)Nr   r*   uP   Cooper SDK client 暖機失敗(LINE 對話會 fallback 到 query()-spawn 模式))startupr!   r"   r#   r$   )r"   r,   s    r'   _cooper_warmupz lifespan.<locals>._cooper_warmupR   sR     M+33555 M!!+.88  :L  MMs1   A    A  -AAAAu+   Cooper SDK client startup task 建立失敗_scheduler_task_funnel_watchdog_tasku!   Cooper SDK client shutdown 失敗)r&   create_taskstate_warmup_taskapp.services.schedulerr)   r0   r!   r"   r#   r$   app.services.funnel_watchdogr+   r1   app.services.cooper_clientr,   _cooper_warmup_taskgetattrcancelshutdown)r   r(   r)   r"   r+   r/   r&   r,   s         @@r'   lifespanr<   %   s     	N %00;CII)9$+$7$78H$I		!/E*1*=*=>R>T*U		'`D	M )0(;(;N<L(M		%
 
syy+T2		!!((*syy148		''..0VD#,,...O  )+&001IJ$(		!)  /+&001OP*.		'/"  `+&001^_` 	/ V+&001TUVs   /I
+E  +F 0G! <A;I
8H HH I
>FI
FI
>GI
GI
!-HI
HI
H -II
II
u9   山水話菁英團隊 · 行程規畫系統 · 後端 APIu   山水話菁英團隊的行程規畫系統。提供任務、對話、會議、知識庫等功能,由 AI 同事「庫柏(Cooper)」串連各模組。z0.1.0-stage1persistAuthorizationT)titledescriptionversionr<   swagger_ui_parametersdevelopment*)allow_originsallow_credentialsallow_methodsallow_headers/healthsystem)tagsreturnc                  2   K   ddt         j                  dS w)u=   供 Docker / NAS / 監控系統呼叫,確認 API 還活著。okzcoba-api)statusserviceenvironment)r   ENVIRONMENT     r'   health_checkrT      s      z(BVBVWWs   z/auth-from-lineF)include_in_schema.u   一次性 magic token)r?   tc           
        K   ddl m} ddlm}m} ddlm} ddlm} ddl	m
} 	  ||       } |       4 d{   }	|	j                   ||      j                  |j                  |k(  |j                   j#                  d      |j$                  j#                  d                   d{   j'                         }
|
t)        dd      ddd      d{     |
j                        } ||
j                        }t        d|
j*                   d| d| d      S # t        $ r}t        d| dd	
      cY d}~S d}~ww xY w7 7 7 s# 1 d{  7  sw Y   xY ww)ug   驗 magic token → 發 access/refresh JWT → 回 HTML 把 token 寫入 localStorage 後跳轉到 /。r   )consume_magic_token)create_access_tokencreate_refresh_token)AsyncSessionLocal)User)selectu  <!DOCTYPE html><html lang="zh-TW"><head><meta charset="utf-8"><title>連結失效</title>
            <style>body{font-family:sans-serif;background:#0a0a14;color:#f1f5f9;display:grid;place-items:center;min-height:100vh;margin:0;padding:20px;text-align:center}
            h1{color:#C8A86A;font-size:24px} p{color:#94a3b8} a{color:#7C6BF0}</style></head>
            <body><div><h1>連結失效</h1><p>u8   </p><p><a href="/">回首頁</a></p></div></body></html>i  )status_codeNTi  u   使用者不存在或已停用)r^   detailuc  <!DOCTYPE html>
<html lang="zh-TW"><head>
<meta charset="utf-8"><title>登入中...</title>
<style>body{font-family:'Noto Sans TC',sans-serif;background:#0a0a14;color:#f1f5f9;
display:grid;place-items:center;min-height:100vh;margin:0;text-align:center}
.spinner{width:40px;height:40px;border:3px solid #1e293b;border-top-color:#C8A86A;
border-radius:50%;animation:s 0.8s linear infinite;margin:20px auto}
@keyframes s{to{transform:rotate(360deg)}}
h1{color:#C8A86A;font-size:20px;letter-spacing:0.18em}</style></head>
<body><div><h1>進入工作台中...</h1><div class="spinner"></div><p style="color:#94a3b8">uN   ,稍等一下</p></div>
<script>
  localStorage.setItem('coba_access_token', 'z2');
  localStorage.setItem('coba_refresh_token', 'zK');
  setTimeout(() => location.replace('/'), 600);
</script></body></html>)app.services.magic_linkrX   app.core.securityrY   rZ   app.databaser[   app.models.userr\   
sqlalchemyr]   
ValueErrorr
   executewhereid	is_activeis_
deleted_atscalar_one_or_noner   display_name)rV   rX   rY   rZ   r[   r\   r]   user_idr%   dbuseraccessrefreshs                r'   auth_from_liners      sc     <K.$!	
%a( !""bjj4Ltww'14>>3E3Ed3KT__M`M`aeMfg
 
 	 <C8XYY #" !)F"477+G  	^ _c^o^o]p q..4X 6//6i 8  )  
0 12s2jn 
 	

 #
 #"""s   !ED EEEA+E	&E'!E	EEAE	D?$D:4D?5E:D??EE	E	EEEEstaticz/static)	directory)name/c                  .   K   t        t        dz        S w)u   首頁回傳登入頁面。z
index.htmlr	   _STATIC_DIRrR   rS   r'   serve_indexr{      s      K,677s   z/sw.jsc                  :   K   t        t        dz  dddd      S w)Nzsw.jszapplication/javascriptrw   zno-cache)zService-Worker-AllowedzCache-Control)
media_typeheadersry   rR   rS   r'   serve_swr      s&     '!//2ZP
 	
s   c                     K   ddddS w)Nu   Cooper 後端 APIz/docsrH   )rO   docshealthrR   rR   rS   r'   rootr      s     .9UUs   	N)B__doc__
contextlibr   pathlibr   fastapir   r   r   fastapi.middleware.corsr   fastapi.responsesr	   r
   fastapi.staticfilesr   app.apir   agent_routesr   auth_routesr   channels_routesr   coba_routesr   line_webhook_routesr   meetings_routesr   messages_routesr   projects_routesr   search_routesr   tasks_routesr   users_routesr   	ws_routesr   rdash_routes
app.configr   r<   r   rQ   _cors_originsadd_middlewareinclude_routerroutergetdictstrrT   rs   __file__resolveparentrz   existsmountr{   r   r   rR   rS   r'   <module>r      s  
 +  1 1 2 8 + ) ' / ' 7 / / / + ) ) # )  CV CV CVL 
E	r 148
" "--> E
   %%     ;%% &   <&& '   ?)) *   <&& '   ?)) *   ?)) *   ?)) *   ='' (   ;%% &   &-- .   <&& '   9## $   <&& ' ($XDcN X %X 	e4"'9P"Q ,C , 5,n 8n$$&--44x?IIi{;(IKWWSEW*8 +8
 	WWXW/
 0
 	WWSzW"VS#X V #VrS   