
    oi              	           d Z ddlZddlZddlZddlmZ dddddddddZd	Zd
ede	e
ef   fdZd
ede	e
ef   fdZd
ede	e
ef   fdZd
edefdZy)uT  
health_score.py - 0-100 Health Score verifier

8개 카테고리 × 가중치로 종합 점수 산출.
초기 버전: 코드 기반 정적 분석 가능 항목만 (Console, Functional, Performance).
나머지는 NA 또는 수동 입력.

출처: gstack /qa 스킬 Health Score 패턴 (MIT 라이선스, https://github.com/garrytan/gstack)
    N)Optional   
         )ConsoleLinksVisual
FunctionalUXPerformanceContentAccessibilityz"/home/jay/workspace/memory/reportstask_idreturnc                    t         j                  j                  dd      }t         j                  j	                  |dd|  d      }t         j                  j                  |      rR	 ddl}t        |dd	
      5 }|j                  |      }ddd       j                  dd      }|dk(  ry|dk(  ry|dk(  ry	 t         j                  j	                  t        |  d      }t         j                  j                  |      rJ	 t        |dd	
      5 }|j                         }ddd       dv sd|j                         v ryd|v sd|v ry	 yy# 1 sw Y   xY w# t        t        f$ r Y w xY w# 1 sw Y   MxY w# t        $ r Y yw xY w)u<   기능 테스트 결과 기반 점수. pytest 결과 활용.WORKSPACE_ROOTz/home/jay/workspacememoryeventsz.doner   Nrutf-8encoding	qc_result PASS)      Y@zQC PASS (tests passed)WARN)     Q@zQC WARN (partial issues)FAIL)g      >@zQC FAIL.mdu   전체 통과z
all passed)g     V@z"Tests reported as passed in reportu   실패)      D@z!Test failures mentioned in report)      zNA (no test data available))osenvirongetpathjoinexistsjsonopenloadOSError
ValueErrorDEFAULT_REPORTS_DIRreadlower)	r   	workspace	done_pathr*   f	done_datar   report_pathcontents	            ?/home/jay/workspace/teams/dev5/qc/verifiers.bak/health_score.py_score_functionalr9       sy   

/1FGI Y(wiu<MNI	ww~~i 	iw7 )1 IIaL	)!k26IF"6f$7f$& % '',,2wisODK	ww~~k"	k39 #Q&&(#')\W]]_-LA H$7@ %8
 /3) ) $ 		# #  	.	sf   &E 8E
E *E 0E >E5 E)E5 <E5 EE E&%E&)E2.E5 5	F Fc                    t         j                  j                  t        |  d      }t         j                  j	                  |      sy	 t        |dd      5 }|j                         }ddd       t        t        j                  dt        j                              }|dk(  ry	|d
k  rd| dfS d| dfS # 1 sw Y   PxY w# t        $ r Y yw xY w)uE   콘솔 에러 기반 점수. 보고서에서 에러 키워드 추출.r!   r#   zNA (no report)r   r   r   Nu$   (?:error|에러|exception|traceback)r   )r   zNo errors detected in report   r   z error mention(s) in reportr"   )r#   zNA (report read failed))r$   r'   r(   r/   r)   r+   r0   lenrefindall
IGNORECASEr-   )r   r6   r4   r7   error_counts        r8   _score_consolerB   E   s    '',,2wisODK77>>+&%/+sW5 	ffhG	"**%LgWYWdWdef!8AK=(CDDDK=(CDDD	 	  /./s6   	C B7(;C $C 0C 7C <C 	CCc                     t         j                  j                  t        |  d      }t         j                  j	                  |      sy	 t        |dd      5 }|j                         }ddd       t        j                  dt        j                        }|r8t        |j                  d            }|d	k(  ry
t        d	d|dz  z
        d| dfS d|j                         v rd|j                         v ry
y# 1 sw Y   xY w# t        $ r Y yw xY w)u,   성능 기반 점수. pyright 결과 활용.r!   r;   r   r   r   Nzpyright.*?(\d+)\s*error   r   )r   zpyright 0 errorsd   r   zpyright z	 error(s)pyrightz0 error)r#   zNA (no performance data))r$   r'   r(   r/   r)   r+   r0   r>   searchr@   intgroupmaxr1   r-   )r   r6   r4   r7   pyright_matcherrorss         r8   _score_performancerM   Y   s    '',,2wisODK77>>+&%+sW5 	ffhG	 		"<gr}}U,,Q/0F{01cFRK/0HVHI2NNN'I,H, ,	 	  +s7   	D C5(AD 7D $D 5C>:D 	DDc                 "   | sddgdS i }t        |       |d<   t        |       |d<   t        |       |d<   dD ]  }d||<   	 d	}d
}g }|j                         D ]\  \  }\  }}t        |   }	|d	k  r|j                  d| d|	 d|        2||	z  }|||	z  z  }|j                  d| d|	 d|dd|        ^ |d	k(  r|j                  d	d       d|dS ||z  }
|j                  d	d|
dd| d       |
dk\  rd}nd}||d}t        |
d      |d<   |S )u;  
    Health Score 산출.

    0-100 점수를 8개 카테고리 가중 평균으로 계산.
    NA 카테고리는 가중치에서 제외하고 나머지로 재분배.

    Args:
        task_id: 검증할 task ID

    Returns:
        {"status": "PASS"|"WARN"|"SKIP", "details": [...], "health_score": float}
    SKIPzNo task_id provided)statusdetailsr   r   r   )r	   r
   r   r   r   )r#   zNA (manual input required)r   g        z  z (u   %): NA — z%): z.0fu	   /100 — z,Health Score: N/A (no measurable categories)zHealth Score: z/100 (based on z% of categories)P   r   r   rD   health_score)rB   r9   rM   items
CATEGORIESappendinsertround)r   kwargsscorescattotal_weightweighted_sumrQ   scorereasonweightrS   rP   results                r8   verifyrb   r   s     .C-DEE+-F 'w/F9,W5F<.w7F= E ;:s; LLG & Q_eVC19NNRuBvhk&BCF"LEFN*LNNRuBvhd5+YvhOPQ qqHI W55,.LNN1|C&8~Uefg r73F"<3F>M    )__doc__r$   r>   
subprocesstypingr   rU   r/   strtuplefloatr9   rB   rM   dictrb    rc   r8   <module>rl      s    
 	  
 
	
 ; "/s "/uUCZ'8 "/J/C /E%*$5 /(, ,eSj(9 ,28C 8d 8rc   