fix: 批量匹配跳过画像待补录教师 + render-html 按行重建 + 金标准 fixtures 业务化(P0+P1)
- run_match 新增 skip_incomplete:批量缺省跳过画像不完整教师并记录 skipped,指定单教师仍 PROFILE_INCOMPLETE;汇总页出"画像待补录"行 - render-html 补 --report-id 行上下文(inputMapping $row.$pk),CLI 容错解析回退最近 10 份 - report_service 日志改容错 _log(),修复未 setup 时单跑测试崩溃的顺序依赖 - fixtures 替换为教师画像/赛道/期望结论金标准样例,新增 sample_tracks.json - 新增 4 个批量跳过用例(314 项,除 3 个已知 jsonschema 环境失败外全绿) - tests/README 增补本机无共享 runtime 的测试方式;TUTORIAL/ACTIONS.md 同步表述
This commit is contained in:
@@ -18,6 +18,14 @@ _TEMPLATE_REL = "assets/html/match-report.html"
|
||||
_TIER_BADGE = {"强烈推荐": "tier-strong", "可尝试": "tier-try", "不建议": "tier-not"}
|
||||
|
||||
|
||||
def _log():
|
||||
"""容错取 logger:未 setup_skill_logging(如单测直调 service)时返回 None。"""
|
||||
try:
|
||||
return get_skill_logger()
|
||||
except RuntimeError:
|
||||
return None
|
||||
|
||||
|
||||
def _esc(value: Any) -> str:
|
||||
return html_escape(str(value if value is not None else "—"))
|
||||
|
||||
@@ -106,9 +114,10 @@ def build_match_html(result: dict[str, Any], batch_no: str = "") -> str:
|
||||
|
||||
def write_report_for_kernel(*, result: dict[str, Any], batch_no: str) -> str:
|
||||
html_text = build_match_html(result, batch_no)
|
||||
log = get_skill_logger()
|
||||
log = _log()
|
||||
path = write_html_page(f"report-{result['report_id']}.html", html_text)
|
||||
log.info("match_report_written report_id=%s path=%s stage=report", result["report_id"], path)
|
||||
if log:
|
||||
log.info("match_report_written report_id=%s path=%s stage=report", result["report_id"], path)
|
||||
return path
|
||||
|
||||
|
||||
@@ -116,8 +125,9 @@ def build_report_for_report_id(report_id: int) -> str:
|
||||
"""按报告 id 从库中取数并重写 HTML(重建入口用)。"""
|
||||
from db.connection import get_conn
|
||||
|
||||
log = get_skill_logger()
|
||||
log.info("report_render_start report_id=%s stage=render", report_id)
|
||||
log = _log()
|
||||
if log:
|
||||
log.info("report_render_start report_id=%s stage=render", report_id)
|
||||
conn = get_conn()
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
@@ -139,13 +149,20 @@ def build_report_for_report_id(report_id: int) -> str:
|
||||
result["top3"] = result.get("top") or []
|
||||
html_text = build_match_html(result)
|
||||
path = write_html_page(f"report-{report_id}.html", html_text)
|
||||
log.info("report_render_done report_id=%s path=%s stage=render", report_id, path)
|
||||
if log:
|
||||
log.info("report_render_done report_id=%s path=%s stage=render", report_id, path)
|
||||
return path
|
||||
|
||||
|
||||
def build_batch_brief(*, batch_no: str, results: list[dict[str, Any]], season: str) -> str:
|
||||
"""批量匹配汇总页:各教师 Top 1 一览。"""
|
||||
log = get_skill_logger()
|
||||
def build_batch_brief(
|
||||
*,
|
||||
batch_no: str,
|
||||
results: list[dict[str, Any]],
|
||||
season: str,
|
||||
skipped: list[dict[str, Any]] | None = None,
|
||||
) -> str:
|
||||
"""批量匹配汇总页:各教师 Top 1 一览;被跳过(画像待补录)教师单列。"""
|
||||
log = _log()
|
||||
rows = []
|
||||
for result in results:
|
||||
top3 = result.get("top3") or []
|
||||
@@ -163,6 +180,13 @@ def build_batch_brief(*, batch_no: str, results: list[dict[str, Any]], season: s
|
||||
)
|
||||
else:
|
||||
rows.append(f"<tr><td>{_esc(result.get('teacher_name'))}</td><td colspan='4' class='muted'>无可推荐赛道(画像待补全)</td></tr>")
|
||||
for entry in skipped or []:
|
||||
rows.append(
|
||||
"<tr>"
|
||||
f"<td>{_esc(entry.get('teacher_name'))}</td>"
|
||||
f"<td colspan='4' class='muted'>画像待补录,本期未匹配({_esc(entry.get('reason'))})</td>"
|
||||
"</tr>"
|
||||
)
|
||||
if not rows:
|
||||
rows.append('<tr><td colspan="5" class="muted">本期无匹配结果。</td></tr>')
|
||||
|
||||
@@ -181,5 +205,6 @@ def build_batch_brief(*, batch_no: str, results: list[dict[str, Any]], season: s
|
||||
{"TITLE": "申报赛道匹配汇总", "GENERATED_AT": str(season), "BODY": body},
|
||||
)
|
||||
path = write_html_page(f"brief-{batch_no}.html", page)
|
||||
log.info("match_brief_written batch_no=%s path=%s stage=report", batch_no, path)
|
||||
if log:
|
||||
log.info("match_brief_written batch_no=%s path=%s stage=report", batch_no, path)
|
||||
return path
|
||||
|
||||
Reference in New Issue
Block a user