
    Gi"                        d Z ddlmZmZ ddlmZ ddlmZ ddlmZm	Z	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mZmZ  ed
dg      Zej3                  dee   d      	 	 	 	 	 d2dededeedz   e
d      f   dedz  deedz   e
d      f   dededee   fd       Zej=                  deej>                  d      d edededefd!       Z ej3                  d"d#$      d%ededede!fd&       Z"d%ededefd'Z#ej3                  d(ed)      d%edededefd*       Z$ejK                  d(ed+      d%ed edededef
d,       Z&d-edefd.Z'ejQ                  d(ejR                  d/0      d%edededdfd1       Z*y)3u  
任務 API。

階段 2a 提供基本 CRUD:
  - GET    /api/tasks                     ─ 列任務(支援 filter)
  - POST   /api/tasks                     ─ 建立任務
  - GET    /api/tasks/{id}                ─ 取得單一任務
  - PATCH  /api/tasks/{id}                ─ 更新任務(改狀態、優先順序、指派、due_date 都走這)
  - DELETE /api/tasks/{id}                ─ 軟刪除任務

filter 參數:
  - status      ─ 只看某狀態的(用 Kanban 看板時會用)
  - assignee_id ─ 只看指派給某人的
  - project_id  ─ 只看某專案的(可填 "null" 表示 inbox)
  - mine        ─ 只看指派給「我」的(用「我的任務」分頁時用)

設計重點:
  1. status 變 done 時自動填入 completed_at,變回其他狀態自動清空
  2. 任何人(team member)都能建/改/刪任務(微型團隊不需要複雜權限)
  3. 但只有 task creator / assignee / 公司 owner 能刪任務
    )datetimetimezone)	Annotated)UUID)	APIRouterHTTPExceptionQuerystatus)or_select)CurrentUser	DBSession)Task)TaskCreateRequest
TaskPublicTaskUpdateRequestz
/api/taskstasks)prefixtags u   列出任務(支援 filter))response_modelsummaryNcurrent_userdbstatus_filterr
   )aliasassignee_id
project_idu(   專案 ID,或填 'null' 看 inbox 任務)descriptionmineinclude_donereturnc                   K   t        t              j                  t        j                  j	                  d            }|r#|j                  t        j
                  |k(        }n6|s4|j                  t        j
                  dk7  t        j
                  dk7        }|r,|j                  t        j                  | j                  k(        }|r"|j                  t        j                  |k(        }|b|dk(  r/|j                  t        j                  j	                  d            }n.	 t        |      }|j                  t        j                  |k(        }|j                  t        j                  j                         t        j                   j#                               }|j%                  |       d{   }
t'        |
j)                         j+                               S # t        $ r!}	t        t
        j                  d      |	d}	~	ww xY w7 Xw)uh   列出符合 filter 的任務。

    預設回傳全部未軟刪的任務,按建立時間倒序。
    Ndone	cancellednullu   project_id 不是合法 UUIDstatus_codedetail)r   r   where
deleted_atis_r
   r   idr   r   
ValueErrorr   HTTP_422_UNPROCESSABLE_ENTITYorder_byorder_indexasc
created_atdescexecutelistscalarsall)r   r   r   r   r   r    r!   stmtpideresults              1/volume1/homes/robertsu/coba/app/app/api/tasks.py
list_tasksr>   &   s    " $<doo11$78Dzz$++67zz$++/1KL zz$**loo=>zz$**k9:::doo11$78D:& ::doo45D ==))--/1E1E1GHD::d##F $$&''  # & D D9  $s7   DH"G -B H-H.+H	H"G>>HHu   建立任務)r   r(   r   payloadc           
        K   t        | j                  | j                  | j                  | j                  | j
                  | j                  | j                  |j                        }| j                  dk(  r(t        j                  t        j                        |_        |j                  |       |j                          d {    |j!                  |       d {    |S 7 7 w)N)titler   r   r
   prioritydue_dater   
created_byr$   )r   rA   r   r   r
   rB   rC   r   r-   r   nowr   utccompleted_ataddcommitrefresh)r?   r   r   tasks       r=   create_taskrL   Z   s      mm''%%~~!!!!''??	D ~~$LL6FF4L
))+
**T
K s$   B?C%C!C%C#C%#C%z/{task_id}/relatedu<   找跟這個任務相關的過去討論 / 任務(階段 8 E))r   task_idc                   K   ddl m} |j                  t        t              j                  t        j                  | k(  t        j                  j                  d                   d{   j                         }|t        dd      |j                  }|j                  r| d|j                  dd  } ||d	
       d{   }|D cg c]  }|j                  dd      dk\  ri|j                  d      |j                  d      xs ddd |j                  d      xs g |j                  d      t        |j                  dd      d      d }}g }	|j                  xs dj                         D ]%  }
t!        |
      dk\  s|	j#                  |
dd        ' |j                  r|	s|j                  dd g}	g }|	rjddlm} |	dd D cg c]!  }t        j                  j)                  |      # }}t        t              j                  t        j                  j                  d      t        j                  | k7   ||       j+                  t        j,                  j/                               j1                  d      }|j                  |       d{   j3                         j5                         }|D ]p  }|j#                  t7        |j                        |j                  |j8                  |j:                  |j<                  r|j<                  j?                         ndd       r t7        |       ||dS 7 7 wc c}w c c}w 7 w)uI   RAG 找相關的過去訊息 + 字串相似度找相關的其他任務。r   )search_relevantNi  u   找不到任務r'          )limitscoreg?
message_idcontentr   r   r3      )rU   rV   r   r3   rT         )r      )r-   rA   r
   rB   rC   )rM   related_messagesrelated_tasks) app.services.coba_memoryrO   r5   r   r   r*   r-   r+   r,   scalar_one_or_noner   rA   r   getroundsplitlenappend
sqlalchemyr   containsr0   r3   r4   rS   r7   r8   strr
   rB   rC   	isoformat)rM   r   r   rO   rK   querymsgs_rawmr[   keywordswr\   r   klike_clausesr9   rowsts                     r=   get_relatedrq   x   s     9**t477g-t/B/B4/HI  	 |4EFF JJE'4++DS123$U!44H 
 A55!# %%-i(.B5EE&M'R%%-155!,a0	
   
 HjjB%%'q6Q;OOAbqE" ( zz(JJrN#M"8@!E1

++A.E4LU##D)7"\"
 Xdoo**,-U1X 	 jj&&//1557A  !$$i((JJ67jjAJJ002d"   w<,& s 5
2 F 'sY   A&M	(L7)AM	L:M	BL=3M	AM	&M1B!M	MB%M	:M	=M	c                 4  K   t        t              j                  t        j                  | k(  t        j                  j                  d             }|j                  |       d {   j                         }|t        t        j                  d      |S 7 1w)Nu   找不到此任務r'   )r   r   r*   r-   r+   r,   r5   r^   r   r
   HTTP_404_NOT_FOUND)rM   r   r9   rK   s       r=   _get_task_or_404rt      sq     $<dgg0$//2E2Ed2KLD**T""668D|(A(AJ^__K #s   A"B$B%2Bz
/{task_id}u   取得單一任務c                 6   K   t        | |       d {   S 7 w)N)rt   )rM   r   r   s      r=   get_taskrv      s      "'2....s   u   更新任務c                   K   t        | |       d {   }|j                  }|j                  d      }|j                         D ]  \  }}t	        |||        ||j                  k7  rD|j                  dk(  r)t        j                  t        j                        |_	        n|dk(  rd |_	        |j                          d {    |j                  |       d {    |S 7 7 !7 
w)NT)exclude_unsetr$   )rt   r
   
model_dumpitemssetattrr   rE   r   rF   rG   rI   rJ   )	rM   r?   r   r   rK   
old_statusupdate_datafieldvalues	            r=   update_taskr      s      "'2..D J $$4$8K#))+ueU# , T[[ ;;&  (X\\ :D6! $D
))+
**T
K- /( s4   C&C B-C& C"C&C$C&"C&$C&rK   c                     | j                   dk(  xs4 |j                  | j                  k(  xs |j                  | j                  k(  S )uF   誰能刪這個任務?建立者、被指派的人、或公司 owner。owner)rolerD   r-   r   )userrK   s     r=   _can_delete_taskr      sA     			W 	'??dgg%	'tww&    u   軟刪除任務)r(   r   c                 
  K   t        | |       d {   }t        ||      st        t        j                  d      t        j                  t        j                        |_	        |j                          d {    y 7 l7 w)Nu4   只有建立者、負責人或公司 owner 能刪除r'   )rt   r   r   r
   HTTP_403_FORBIDDENr   rE   r   rF   r+   rI   )rM   r   r   rK   s       r=   delete_taskr      sj      "'2..DL$/11I
 	
 ll8<<0DO
))+ / s"   BA?A&B9B:BB)NNNFT)+__doc__r   r   typingr   uuidr   fastapir   r   r	   r
   rd   r   r   app.core.depsr   r   app.models.taskr   app.schemas.taskr   r   r   routerr_   r6   rf   boolr>   postHTTP_201_CREATEDrL   dictrq   rt   rv   patchr   r   deleteHTTP_204_NO_CONTENTr    r   r=   <module>r      s  , (   ; ; " 0   M M 
,gY	7 BtJ/9VW CG# 	0(0(0( S4ZX)>>?0( 	0(
 d
DE	G0( 0( 0( 
$Z0( X0(f ''	   	 
	0  *hiAt A; AI ARV A jAHD i D  L=QR/// 	/ 
	/ S/ l:~N  		
 
 O> $  **  
 	 
	
r   