
     Ijv                       d dl mZ 	 d dlZd dlZd dlZd dlZd dlmZ  ed       ed      dddf	 	 	 	 	 	 	 	 	 	 	 dd	Ze	d
k(  r ej                  d      Zej                  dddd       ej                  ddd       ej                  ddd       ej                         Z e eej                         eej                         ej"                        Z e ej(                  edd             yy)    )annotationsN)Pathzmemory/task-timers.jsonzmemory/eventsl   L5: )z
2026-05-08z
2026-05-09Fc                   t        |       } t        |      }|\  }}t        |      }| j                         r,t        | d      5 }t	        j
                  |      }	ddd       ndi i}		j                  di       }
|g}|dz  }|j                         r|j                  |       d}d}d}d}g }|D ]  }|j                         st        |j                               D ]  }|j                         s|j                  j                  d      s7|j                  j                  d      s|j                  j                  d	      sg	 t        |d      5 }t	        j
                  |      }ddd       t        t               s|j#                  d
      xs$ |j#                  d      xs |j#                  d      }|s|dz  }t        |      dd }||cxk  r|k  sn |j#                  d      }|t        |      |k7  r|dz  }'|j#                  d      }|sC|j                  }dD ]$  }|j                  |      s|dt%        |        } n |s|j&                  }||
v r|dz  }|j#                  d      xs |j#                  d      xs d}t        |      }||d||ddddd	}||
|<   |j                  |       |dz  }  |||||d}|s|dkD  r| j(                  }|j+                  dd       t-        j.                  |d      \  } }!	 t1        j2                  | dd      5 }"t	        j4                  |	|"dd !       ddd       t1        j6                  |!|        |S |S # 1 sw Y   xY w# 1 sw Y   	xY w# t        j                  t        f$ r Y w xY w# 1 sw Y   ]xY w# t8        $ r' 	 t1        j:                  |!        # t8        $ r Y  w xY ww xY w)"uT  
    결과 dict: {
        "backfilled": int,
        "skipped_existing": int,
        "skipped_other_chat": int,
        "skipped_no_timestamp": int,
        "tasks_added": list[str],
    }

    동작:
      1. events_dir (루트 + archive/ 모두)의 done event 파일을 스캔
         지원 변종: *.done, *.merge-done, *.done.acked (helpers _resolve_end_time_priority 와 동일)
      2. 각 .done JSON 로드 후 시각 우선순위: completed_at -> end_time -> merged_at
      3. 시각 date(첫 10자) 가 target_date_range 양쪽 경계 포함이면 후보
      4. chat_id 필드가 존재하고 chat_id_filter 와 다르면 silently skip
      5. task-timers.json tasks[task_id] 가 이미 존재하면 silently skip (idempotent)
      6. 누락 entry 추가
      7. dry_run=False 이면 원자적 쓰기(임시파일 → rename)
    zutf-8)encodingNtasksarchiver   .done.merge-done.done.ackedcompleted_atend_time	merged_at   
   chat_idtask_id)r   r
   r	   team_idteam z(reconcile from done event)	completedu   0초T)	r   r   description
start_timer   statusduration_secondsduration_humanreconciled_from_done_event_2543)
backfilledskipped_existingskipped_other_chatskipped_no_timestamptasks_added)parentsexist_okz.tmp)dirsuffixwF   )ensure_asciiindent)r   strexistsopenjsonload
setdefaultappendsortediterdiris_filenameendswithJSONDecodeErrorOSError
isinstancedictgetlenstemparentmkdirtempfilemkstemposfdopendumpreplace	Exceptionunlink)#timers_path
events_dirchat_id_filtertarget_date_rangedry_rundate_lodate_hichat_id_filter_strftimers_datar   	scan_dirsarchive_dirr   r   r   r    r!   	scan_basepdatatsdate_strraw_chat_idtidr4   suf
team_or_idts_strentryresult
timers_dirfdtmp_pathtmp_fs#                                      9/home/jay/workspace/scripts/reconcile_task_timers_2543.pyreconcile_from_done_eventsrd      s   4 {#Kj!J(GW^, +0 	'A))A,K	' 	' m(("5E Iy(K%JK P	!	))+, M	A99;(66??=166??=1!g. (!99Q<D( dD) .)ZTXXj-AZTXXkEZB$)$ 2ws|Hx272 ((9-K&{#'99&!+& ((9%CvvB C}}S)";c#hY/ &&C e| A%  ),F0@FBJ WF %<$"%$%"(37
E E#Js#!OJ[M	Pf !,0 4"F zA~ ''
5''JvFH		2sW5 L		+u5KLJJx- M6My	' 	'D( ((('2 \L L  			(#   	s~   M!M;M.'M;N' %N?N' !M+.M83M;;NNN$ N' '	O1OO	OOOO__main__z8task-timers.json reconcile from done events (idempotent))r   z	--dry-run
store_trueu   변경 없이 결과만 출력)actiondefaulthelpz--timers-pathu9   task-timers.json 경로 (기본: memory/task-timers.json))rh   ri   z--events-diru0   done events 디렉토리 (기본: memory/events))rG   rH   rK   r'   )r)   r(   )rG   r   rH   r   rI   intrJ   ztuple[str, str]rK   boolreturnr9   )
__future__r   argparser-   rA   r?   pathlibr   rd   __name__ArgumentParserparseradd_argument
parse_argsargsrG   rH   rK   r^   printdumps     rc   <module>rz      sT   "    	   67O,$)E]]] ] '	]
 ] 
]@ z$X$$NF -	   )H  
 ?  
 D'))*(F
 
*$**VAE
:;7 ry   