
    .if
                    v    d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZ ddd	 	 	 	 	 	 	 	 	 dd	Zdd
Zy)u   체크포인트 파일 I/O 공통 유틸.

Phase 1.4 (architecture-refactor-final/02-final-roadmap.md §Phase 1).

체크포인트는 크래시 시 부분 쓰기 방지를 위해 항상 원자적으로 기록해야 한다.
여러 소비자(api/v1/steps.py, core/step_runner.py, core/steps/t2i_review_step.py 등)에서
동일 패턴이 중복되어 있었던 것을 단일 헬퍼로 통합.

tmp 파일명에 uuid 8자 추가하여 같은 경로에 동시 쓰기가 있어도 tmp가 충돌하지 않도록 함
(Codex Phase 1 리뷰 P1 반영).
    )annotationsN)Path)AnyDictOptional   F)indentensure_asciic                  t        |       } | j                  j                  dd       dt        j                         j
                  dd  d}| j                  | j                  |z         }	 |j                  t        j                  |||      d	       t        j                  t        |      t        |              y# t        $ r2 	 |j                         r|j!                           # t"        $ r Y  w xY ww xY w)
u<  JSON을 대상 경로에 원자적으로 쓴다.

    per-call unique tmp 파일(`{path}.{uuid8}.tmp`)에 먼저 기록한 뒤 `os.replace`로 교체.
    호출 전에 부모 디렉토리를 생성한다.

    Args:
        path: 최종 저장 경로 (파일명은 임의, 확장자 무관).
        payload: JSON 직렬화 가능한 dict.
        indent: json.dumps indent. 기본 2.
        ensure_ascii: False면 UTF-8 그대로 저장 (한글 유지).

    Raises:
        OSError: 파일 쓰기 실패 시.
        TypeError: payload가 직렬화 불가일 때.
    T)parentsexist_ok.N   z.tmp)r
   r	   utf-8encoding)r   parentmkdiruuiduuid4hexwith_suffixsuffix
write_textjsondumpsosreplacestr	ExceptionexistsunlinkOSError)pathpayloadr	   r
   
tmp_suffixtmps         L/Users/manta/Documents/Projects/TheRoad-I1/backend/app/core/checkpoint_io.pyatomic_write_jsonr)      s    , :DKKdT2TZZ\%%bq)*$/J


4;;3
4CJJw\&I 	 	
 	

3s8SY' 	zz|

 	  		s1   -AB? ?	C:	 C*)C:*	C63C:5C66C:c                    t        |       } | j                         sy	 t        j                  | j	                  d            S # t        j
                  t        f$ r Y yw xY w)u  경로에서 JSON을 읽고 실패 시 None 반환.

    파일 미존재 / 파싱 오류 / OS 오류 모두 None으로 수렴.
    호출자는 `None` 분기로 처리.

    Args:
        path: 읽을 파일 경로.

    Returns:
        파싱된 dict 또는 None.
    Nr   r   )r   r!   r   loads	read_textJSONDecodeErrorr#   )r$   s    r(   read_json_safer.   @   sU     :D;;=zz$..'.:;;  '* s   $A AA)
r$   r   r%   zDict[str, Any]r	   intr
   boolreturnNone)r$   r   r1   zOptional[Dict[str, Any]])__doc__
__future__r   r   r   r   pathlibr   typingr   r   r   r)   r.        r(   <module>r9      sb   
 #  	   & & (
(( 	(
 ( 
(Vr8   