
    mi"                         d Z ddlmZ ddlmZmZ ddlmZmZmZm	Z	m
Z
mZmZmZmZ ddlmZmZmZ ddlmZ ddlmZmZ  G d d	ee      Z G d
 dee      Z G d dee      Z G d de      Zy)u  
頻道 / 訊息資料表 Model(階段 3 切片 a)。

階段 3a 先建四張核心表:
  - channels         ─ 頻道(公告、靈感、求助、會議紀錄、庫柏動態、閒聊)
  - channel_members  ─ 誰在哪個頻道(LINE 群組概念)
  - messages         ─ 對話訊息
  - message_reactions ─ 表情回應(👍❤️😂)

延後到 3c 之後:
  - message_reads        ─ 已讀回執(等 WebSocket 完才有意義)
  - message_attachments  ─ 附件(等檔案上傳功能)
  - coba_conversations   ─ 庫柏一對一對話(切片 3e)
  - coba_memory_summaries ─ 庫柏長期記憶摘要(切片 3f)

設計重點:
  1. channels 有特殊型別 'public' / 'private' / 'direct'(1對1)/ 'coba_dm'(跟庫柏私聊)
  2. messages 的 user_id 可為 NULL → 庫柏發的訊息(系統訊息)
  3. message_type 採用字串而非 enum,方便擴充新類型
  4. reply_to_id 支援引用回覆(LINE 風格的 thread)
    )datetime)UUIDuuid4)	JSONBooleanDateTime
ForeignKeyIndexStringTextUuidfunc)Mappedmapped_columnrelationship)Base)TimestampMixinUserc                   r   e Zd ZU dZdZ e ed      de      Ze	e
   ed<    e ed      d	      Ze	e   ed
<    e ed      dd      Ze	e   ed<    eed	      Ze	edz     ed<    e ed      ddd      Ze	e   ed<    eedd      Ze	e   ed<    edd      Ze	e   ed<    e ed       edd      d	      Ze	e
dz     ed<    e ed      d	      Ze	edz     ed<    e ed      ddd      Ze	edz     ed<    ed d!d"#      Ze	ed$      ed%<    ed d!d&#      Ze	ed'      ed(<   d)efd*Z y)+Channelu  頻道:對話的容器。

    channel_type:
      - public   : 公開頻道,所有人都能加入(公告、閒聊等)
      - private  : 私密頻道,owner 邀請才能加入
      - direct   : 1 對 1 私訊
      - coba_dm  : 跟庫柏的私聊(每個使用者一個)
    channelsTas_uuidprimary_keydefaultidd   Fnullablename
   u   💬r    r   iconNdescription   public)r    r   indexchannel_type
is_default)r   r    
sort_orderusers.idSET NULLondelete
created_byline_source_type@   )r    uniquer(   line_source_idchannelall, delete-orphanselectinback_populatescascadelazyChannelMembermembersnoloadMessagemessagesreturnc                 T    d| j                    | j                   d| j                   dS )Nz	<Channel z type=>)r$   r!   r)   selfs    6/volume1/homes/robertsu/coba/app/app/models/channel.py__repr__zChannel.__repr__S   s*    499+dii[t7H7H6IKK    )!__name__
__module____qualname____doc____tablename__r   r   r   r   r   r   __annotations__r   r!   strr$   r   r%   r)   r   r*   boolr+   intr	   r0   r1   r4   r   r=   listr@   rG    rH   rF   r   r   !   s    M$T$%7TSXYBtY%fSkEBD&+B%fRj5&QD&+Q&3D4&HKd
#H -r
UHD!L&+   -WueTJtT+C%HJsH&3T:
3'Jtd{#  ,9d+SfS4Z(S)6r
T$d*NF3:& 
 .: $.GVD)* 
 )5 $)HfT)_% L# LrH   r   c                      e Zd ZU dZdZ e ed      de      Ze	e
   ed<    e ed       edd	      d
d      Ze	e
   ed<    e ed       edd	      d
d      Ze	e
   ed<    e ed      d
d      Ze	e   ed<    e ed      d      Ze	edz     ed<    ed      Ze	e   ed<    ed      Ze	e   ed<    edddd      fZdefd Zy)!r<   u   頻道成員 = LINE 群組成員。

    public 頻道:預設「全公司」都會自動加入(seed 時建立)
    private 頻道:由 owner 邀請才能加入
    coba_dm:每個 user 一個,只有 user 自己跟庫柏在裡面
    channel_membersTr   r   r   channels.idCASCADEr.   Fr    r(   
channel_idr,   user_idr&   allr#   notification_leveltimezoner   Nlast_read_atr=   r9   r5   joinedr;   userux_channel_member_uniquer3   rA   c                 <    d| j                    d| j                   dS )Nz<ChannelMember channel=z user=rC   )rY   rZ   rD   s    rF   rG   zChannelMember.__repr__   s     ((9~QOOrH   )rI   rJ   rK   rL   rM   r   r   r   r   r   r   rN   r	   rY   rZ   r   r\   rO   r   r_   r   r   r5   r   rc   r   r
   __table_args__rG   rS   rH   rF   r<   r<   W   s    &M$T$%7TSXYBtY,T=95	 Jt  *T:	2	GVD\  '4r
UE's  -:$$-L&D) 
  ,9EGVG_E%84D&,4 	(,	$ON
P# PrH   r<   c                      e Zd ZU dZdZ e ed      de      Ze	e
   ed<    e ed       edd	      d
d      Ze	e
   ed<    e ed       edd	      dd      Ze	e
dz     ed<    eed
      Ze	e   ed<    e ed      d
d      Ze	e   ed<    e ed       edd	      d      Ze	e
dz     ed<    eed
d
      Ze	e   ed<    eed
d
      Ze	e   ed<    eed      Ze	ee   dz     ed<    e ed      dd      Ze	edz     ed<    ed      Ze	e   ed<    ed !      Z e	e!dz     ed"<    ed#d $      Z"e	d%   ed&<    ed'd(d)*      Z#e	ed+      ed,<   d-efd.Z$y)/r?   u  訊息。

    user_id 可為 NULL,代表這是「庫柏」或系統訊息。

    message_type:
      - text    : 純文字(目前主要用這個)
      - image   : 圖片(階段 3+)
      - file    : 檔案
      - audio   : 語音
      - sticker : 貼圖
      - system  : 系統訊息(誰加入、誰離開等)
      - coba_action : 庫柏的特殊動作(轉任務、推薦等)
    r@   Tr   r   r   rV   rW   r.   FrX   rY   r,   r-   NrZ   r   contentr&   textr#   message_typemessages.idreply_to_id	is_pinned	is_editedtagsr2   line_message_idr`   r5   ra   rb   rc   z
Message.id)remote_sider;   zMessage | Nonereply_tomessager6   r7   r8   MessageReaction	reactionsrA   c                 z    | j                   dnt        | j                         d d }d| d| j                  d d dS )NCoba   z	<Message z:    rC   )rZ   rO   ri   )rE   senders     rF   rG   zMessage.__repr__   sC    <</S5Fr5J6("T\\#2%6$9;;rH   )%rI   rJ   rK   rL   rM   r   r   r   r   r   r   rN   r	   rY   rZ   r   ri   rO   r   rk   rm   r   rn   rP   ro   r   rp   rR   rq   r   r5   r   rc   r   rs   rv   rG   rS   rH   rF   r?   r?      s    M$T$%7TSXYBtY,T=95	 Jt  $1T:
3	$GVD4K   )>GVC[> -fRj5RX YL&+Y (5T=:6(Kt$  ,GeUSIvd|S+GeUSIvd|S
 &34$%GD&cT!
"G +8r
TY]*^OVC$J'^  ,:FGVG_F ,( ;D&
;)5 x*Hf%&  2> $2Ivd,-. <# <rH   r?   c                      e Zd ZU dZdZ e ed      de      Ze	e
   ed<    e ed       edd	      d
d      Ze	e
   ed<    e ed       edd	      d
      Ze	e
   ed<    e ed      d
      Ze	e   ed<    e ed       ej(                         d
      Ze	e   ed<    ed      Ze	e   ed<    eddddd      fZdefdZy)ru   u   訊息表情回應(👍❤️😂)。

    一個使用者可以對同一則訊息加多個不同的 emoji,
    但同一個 emoji 只能加一次。
    message_reactionsTr   r   r   rl   rW   r.   FrX   
message_idr,   r   rZ   r&   emojir]   )server_defaultr    
created_atrv   r`   rt   ux_reaction_uniquere   rA   c                 T    d| j                    dt        | j                        d d  dS )Nz
<Reaction z by ry   rC   )r   rO   rZ   rD   s    rF   rG   zMessageReaction.__repr__   s,    DJJ<tC,=bq,A+B!DDrH   N)rI   rJ   rK   rL   rM   r   r   r   r   r   r   rN   r	   r~   rZ   r   r   rO   r   r   nowr   r   r   rt   r?   r
   rg   rG   rS   rH   rF   ru   ru      s    (M$T$%7TSXYBtY,T=95	 Jt  *T:	2GVD\ 
 'vbzEBE6#;B#0$
U$Jx  
  ,;GGVG_G 	"L)WTRN
E# ErH   ru   N)rL   r   uuidr   r   
sqlalchemyr   r   r   r	   r
   r   r   r   r   sqlalchemy.ormr   r   r   app.databaser   app.models.userr   r   r   r<   r?   ru   rS   rH   rF   <module>r      sh   ,   [ [ [ > >  03LdN 3Ll/PD. /PdF<dN F<R#Ed #ErH   