#!/usr/bin/env python3 """PostToolUse hook: 编辑 backend service 后检查是否引回 CURRENT_DATE / date.today() F1-5b A1 决策(2026-05-05): apps/backend/app/services/ 下涉及业务时间的查询应走 RuntimeContext.business_date (sandbox 模式取虚拟日,live 取真实今天),不应直接用 SQL CURRENT_DATE 或 Python date.today()。 例外:全局聚合(无 site_id 上下文)允许保留 CURRENT_DATE,需在该行附近加 `# RUNTIME_CTX_BYPASS: <理由>` 注释明确标注。 本 hook 仅 soft warning(additionalContext),不强阻断,允许必要 fallback。 """ import json import re import sys try: data = json.load(sys.stdin) except Exception: sys.exit(0) tool_input = data.get("tool_input") or {} fp = tool_input.get("file_path", "") if not fp: sys.exit(0) rel = re.sub(r"^.*?NeoZQYY[/\\]", "", fp.replace("\\", "/")) # 只关注 backend service 层 if not re.search(r"^apps/backend/app/services/.*\.py$", rel): sys.exit(0) # 提取本次写入/改动的内容 content = tool_input.get("new_string") or tool_input.get("content") or "" if not content: sys.exit(0) # grep CURRENT_DATE / date.today() lines = content.split("\n") hits = [] for i, line in enumerate(lines, 1): if "RUNTIME_CTX_BYPASS" in line: continue # 排除注释行的纯文本提及 stripped = line.lstrip() if stripped.startswith("#") or stripped.startswith('"""') or stripped.startswith('"'): continue if re.search(r"\bCURRENT_DATE\b", line) or re.search(r"\bdate\.today\(\)", line): hits.append((i, line.strip()[:80])) if not hits: sys.exit(0) hint_lines = [ f"[business-date-check] 检测到 {rel} 含 {len(hits)} 处 CURRENT_DATE / date.today():", ] for ln, code in hits[:5]: hint_lines.append(f" L{ln}: {code}") if len(hits) > 5: hint_lines.append(f" ... (+{len(hits) - 5} 处)") hint_lines.append( "F1-5b A1 决策:有 site_id 上下文应走 RuntimeContext.business_date。" "全局聚合(无 site_id)允许保留,但需加 `# RUNTIME_CTX_BYPASS: <理由>` 注释。" ) print(json.dumps({ "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "\n".join(hint_lines), } }))