
    [giP                        d Z ddlmZ ddlZddlZddlmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZ  ej"                  e      ZddZdd	Z	 	 	 	 	 	 	 	 dd
Zy)u  Step Read-Model Service — `/steps` read view 계산.

W1-F11: `api/v1/steps.py.get_all_steps` 본문을 이관. route는 이 함수 호출 한 줄.

책임:
- step_run DB 조회
- ordered step catalog 순회
- gate/blocked 판정
- model override 해석
- consumed_by(drift stale 표시용) 조회
- 응답 dict 구성

비책임:
- HTTP 파싱 / response envelope / auth — route 담당
    )annotationsN)AnyDictList)text)Session)get_consumers_ofget_ordered_entriesc                B   ddl m} | j                  |      j                  |j                  |k(        j                         }|r|j                  si S 	 t        j                  |j                        S # t        $ r#}t        j                  d||       i cY d}~S d}~ww xY w)uF   ProjectSettings.llm_config_json → dict. 파싱 실패 시 {} + warn.r   )ProjectSettingsuD   llm_config_json parse failed for project %s: %s — 기본 {} 사용N)app.models.projectr   queryfilter
project_idfirstllm_config_jsonjsonloads	Exceptionloggerwarning)dbr   r   psexcs        Y/Users/manta/Documents/Projects/TheRoad-I1/backend/app/services/step_readmodel_service.py_load_project_configr      s    2	/	"	)	)/*D*D
*R	S	Y	Y	[BR''	zz",,-- R	
 	s   A2 2	B;BBBc                    | j                  t        d      ||d      j                         }|D ci c]5  }|d   |d   |d   |d   |d   |d   |d	   |d
   |d   |d   |d   |d   d7 c}S c c}w )u   step_run 테이블에서 에피소드별 단일 조회 후 step_id→row 매핑.

    W4 P3-4: sync_status/sync_error/synced_at 컬럼도 포함 (P3-2/P3-3 관측성 UI 연동).
    zSELECT step_id, status, resolved_model, completed_count, applicable_count, failed_count, started_at, completed_at, error_message, sync_status, sync_error, synced_at FROM step_run WHERE project_id = :pid AND episode_id = :eid)pideidr                           	   
      )statusresolved_modelcompleted_countapplicable_countfailed_count
started_atcompleted_aterror_messagesync_status
sync_error	synced_at)executer   fetchall)r   r   
episode_idrunsrs        r   _load_step_run_mapr;   /   s    
 ::d	F
 *-/
 08xz 	  ! aDA$!A$Q4QqT!AaD!qtt1R5qu    s   :A.c           	        ddl m} t        | |      }t        | ||      }g }t	               D ]  }|j
                  }|j                  |i       }	|	j                  dd      }
|j                  }d}g }|D ]<  }|j                  |i       j                  dd      }|dvs*d}|j                  |       > |
dk(  r|sd}
 |||      }t        |      }i d	|d
|j                  d|j                  d|j                  d|j                  d|dt        |      d|j                  d|j                   d|
d|d|d|d|	j                  d      d|	j                  d      d|	j                  d      d|	j                  d      |	j                  d      |	j                  d      |	j                  d      |	j                  d      |	j                  d      d}|j"                  r|j"                  |d<   |j                  |        |S ) uG   전체 단계 read-model. route의 `get_all_steps`가 이것만 호출.r   )_resolve_modelr+   pendingT)	completednot_applicablepartialFblockedstep_idlabelcategoryorderprovidermodel
depends_onfan_outapplicabilitycan_run
blocked_byconsumed_byr-   r.   r/   r0   r1   r2   r3   r4   r5   )r1   r2   r3   r4   r5   	sub_steps)app.modules.llm.llm_clientr=   r   r;   r
   rC   getrI   appendr	   rD   rE   rF   rG   listrJ   rK   rO   )r   r   r8   r=   project_configrun_mapstepsentrysidrunr+   depsrL   rM   dep
dep_statusrH   rN   	step_datas                      r   get_all_steps_viewr^   C   sa    :)"j9N Z<G"$E$&mmkk#r"9-  "
C S"-11(IFJ!KK!!#&	  YwFsN3
 's+%
s%
U[[%
 %
 U[[	%

 %
 U%
 $t*%
 u}}%
 U00%
 f%
 w%
 *%
 ;%
 sww'89%
 (: ;%
  CGGN3!%
" #'',/#%
$  GGN3 WW_577=1'',/-/%
	4 ??%*__Ik"Ym 'p L    )r   
OrmSessionr   strreturnzDict[str, Any])r   r`   r   ra   r8   ra   rb   zDict[str, Dict[str, Any]])r   r`   r   ra   r8   ra   rb   zList[Dict[str, Any]])__doc__
__future__r   r   loggingtypingr   r   r   
sqlalchemyr   sqlalchemy.ormr   r`   app.core.step_catalogr	   r
   	getLogger__name__r   r   r;   r^    r_   r   <module>rm      sn    #   " "  0 G			8	$"(DDD D 	Dr_   