Phase 3 KPI 계약 상수 분리

This commit is contained in:
Yun Chan 2026-06-29 00:01:24 +09:00
parent d9458d0e40
commit d18e4b6b4b
7 changed files with 69 additions and 53 deletions

View file

@ -13,6 +13,18 @@ from dataclasses import dataclass
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parents[1]
API_ROOT = REPO_ROOT / "apps" / "api"
sys.path.insert(0, str(API_ROOT))
from app.services.phase3_kpi_contract import ( # noqa: E402
KPI_METRIC_REQUIRED_KEYS,
KPI_METRIC_STATUSES,
KPI_REPORT_PATH,
PHASE3_KPI_METRICS,
PREPOST_CSV_PATH,
)
FORBIDDEN_HEADER_TERMS = {
"address",
@ -116,7 +128,7 @@ CSV_SPECS = (
),
),
CsvSpec(
"02-measures/prepost_measures.csv",
PREPOST_CSV_PATH,
("participant_id", "measure_name", "timepoint", "score", "collected_at"),
),
CsvSpec(
@ -131,18 +143,6 @@ CSV_SPECS = (
REQUIRED_MARKDOWN = ("04-privacy/privacy_audit.md",)
KPI_METRICS = {
"embedding_consistency",
"hallucination_rate",
"icc",
"inter_rater_kappa",
"pilot_completion",
"self_efficacy_prepost",
"session_completion",
"sus",
"top1",
}
KPI_REPORT_KEYS = {
"cohort_size",
"exclusions",
@ -154,21 +154,6 @@ KPI_REPORT_KEYS = {
"source_window",
}
KPI_METRIC_REQUIRED_KEYS = {
"denominator",
"method",
"numerator",
"pass",
"source_files",
"status",
"threshold",
"value",
}
KPI_METRIC_STATUSES = {
"computed_prepost",
"design_pending",
}
MANIFEST_KEYS = {
"agreement",
"anonymization",
@ -317,7 +302,7 @@ def read_json(path: Path, report: Report) -> dict[str, Any] | None:
def validate_kpi_report(root: Path, report: Report) -> None:
rel_path = "02-measures/kpi_report.json"
rel_path = KPI_REPORT_PATH
path = root / rel_path
if not path.exists():
report.error(f"missing required file: {rel_path}")
@ -334,7 +319,7 @@ def validate_kpi_report(root: Path, report: Report) -> None:
if not isinstance(metrics, dict):
report.error(f"{rel_path}: missing object key 'metrics'")
return
missing = sorted(KPI_METRICS - set(metrics))
missing = sorted(set(PHASE3_KPI_METRICS) - set(metrics))
if missing:
report.error(f"{rel_path}: missing metric keys: {', '.join(missing)}")