Phase 0-2: Schema cleanup, typed relations, event-driven automation

- Phase 0: AGENTS.md cleanup (dedup quotes, renumber sections, merge qmd)
- Phase 1: typed relations (manage-relations.py, graph-search.py, check-staleness.py, detect-conflicts.py)
- Phase 2: frontmatter validator, weekly lint, knowledge promotion, git hooks
- Fix .gitignore to track tools/ and .githooks/
- Fix git remote URL (remove plaintext token)
- New wiki pages: 504 pages, 34 raw sources
This commit is contained in:
hehaiguang1123
2026-07-01 08:05:43 +08:00
parent e544d6e04a
commit a6f05ab2d5
1067 changed files with 522992 additions and 819 deletions
@@ -0,0 +1,387 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import io
import json
import datetime
from pathlib import Path
from typing import Dict, List, Any
from collections import Counter
if sys.platform == "win32":
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
class WeeklyReportsAnalyzer:
def __init__(self, extracted_data_path: Path):
self.data_path = extracted_data_path
self.data = self.load_extracted_data()
self.reports = self.data.get("reports", [])
def load_extracted_data(self) -> Dict[str, Any]:
try:
with open(self.data_path, "r", encoding="utf-8") as f:
return json.load(f)
except Exception as e:
print(f"Error loading data: {str(e)}")
return {}
def analyze_task_trends(self) -> Dict[str, Any]:
task_analysis = {
"total_tasks": 0,
"completed_tasks": 0,
"by_priority": Counter(),
"by_status": Counter(),
"completion_rate_by_week": {},
}
for report in self.reports:
tasks = report.get("tasks", [])
for task in tasks:
task_analysis["total_tasks"] += 1
task_analysis["by_priority"][task.get("priority")] += 1
task_analysis["by_status"][task.get("status")] += 1
if "" in task.get("status", ""):
task_analysis["completed_tasks"] += 1
week_num = report.get("week_number")
if tasks:
completed = sum(1 for t in tasks if "" in t.get("status", ""))
rate = (completed / len(tasks) * 100) if len(tasks) > 0 else 0
task_analysis["completion_rate_by_week"][week_num] = {
"total": len(tasks),
"completed": completed,
"rate": f"{rate:.1f}%",
}
overall_rate = (
(task_analysis["completed_tasks"] / task_analysis["total_tasks"] * 100)
if task_analysis["total_tasks"] > 0
else 0
)
task_analysis["overall_completion_rate"] = f"{overall_rate:.1f}%"
return task_analysis
def analyze_institution_trends(self) -> Dict[str, Any]:
inst_analysis = {
"total_institutions": 0,
"by_type": Counter(),
"quality_scores": [],
"by_week": {},
}
for report in self.reports:
institutions = report.get("institutions", [])
inst_analysis["total_institutions"] += len(institutions)
for inst in institutions:
inst_analysis["by_type"][inst.get("type")] += 1
quality_score = inst.get("quality_score", 0)
if quality_score > 0:
inst_analysis["quality_scores"].append(quality_score)
week_num = report.get("week_number")
inst_analysis["by_week"][week_num] = len(institutions)
if inst_analysis["quality_scores"]:
inst_analysis["average_quality"] = sum(
inst_analysis["quality_scores"]
) / len(inst_analysis["quality_scores"])
inst_analysis["max_quality"] = max(inst_analysis["quality_scores"])
inst_analysis["min_quality"] = min(inst_analysis["quality_scores"])
else:
inst_analysis["average_quality"] = 0
inst_analysis["max_quality"] = 0
inst_analysis["min_quality"] = 0
return inst_analysis
def analyze_themes(self) -> List[str]:
themes = []
for report in self.reports:
theme = report.get("theme")
if theme:
themes.append(theme)
return themes
def analyze_research_productivity(self) -> Dict[str, Any]:
productivity = {
"total_reports": len(self.reports),
"reports_with_tasks": 0,
"reports_with_institutions": 0,
"reports_with_metrics": 0,
"reports_with_discoveries": 0,
"total_content_items": 0,
}
for report in self.reports:
if report.get("tasks"):
productivity["reports_with_tasks"] += 1
productivity["total_content_items"] += len(report["tasks"])
if report.get("institutions"):
productivity["reports_with_institutions"] += 1
productivity["total_content_items"] += len(report["institutions"])
if report.get("metrics"):
productivity["reports_with_metrics"] += 1
productivity["total_content_items"] += len(report["metrics"])
if report.get("discoveries"):
productivity["reports_with_discoveries"] += 1
productivity["total_content_items"] += len(report["discoveries"])
productivity["content_per_report"] = (
productivity["total_content_items"] / productivity["total_reports"]
if productivity["total_reports"] > 0
else 0
)
return productivity
def generate_markdown_report(self) -> str:
task_analysis = self.analyze_task_trends()
inst_analysis = self.analyze_institution_trends()
themes = self.analyze_themes()
productivity = self.analyze_research_productivity()
md_content = f"""# 教育AI研究 - 10周系统化分析报告
## 基本信息
- **分析时间**: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
- **数据来源**: {self.data_path.name}
- **分析周期**: 10周周报数据
- **报告数量**: {len(self.reports)}
## 一、任务完成趋势分析
### 1.1 总体完成情况
| 指标 | 数值 |
|------|------|
| 总任务数 | {task_analysis["total_tasks"]} |
| 已完成任务 | {task_analysis["completed_tasks"]} |
| 总体完成率 | {task_analysis["overall_completion_rate"]} |
### 1.2 按优先级分布
| 优先级 | 数量 |
|--------|------|
"""
for priority, count in task_analysis["by_priority"].most_common():
md_content += f"| {priority} | {count} |\n"
md_content += f"""
### 1.3 按状态分布
| 状态 | 数量 |
|------|------|
"""
for status, count in task_analysis["by_status"].most_common():
md_content += f"| {status} | {count} |\n"
md_content += f"""
### 1.4 每周完成率趋势
| 周次 | 总任务 | 已完成 | 完成率 |
|------|--------|--------|--------|
"""
for week, data in sorted(task_analysis["completion_rate_by_week"].items()):
md_content += f"| W{week} | {data['total']} | {data['completed']} | {data['rate']} |\n"
md_content += f"""
## 二、机构档案趋势分析
### 2.1 总体质量评估
| 指标 | 数值 |
|------|------|
| 总机构数 | {inst_analysis["total_institutions"]} |
| 平均质量分 | {inst_analysis["average_quality"]:.1f} |
| 最高质量分 | {inst_analysis["max_quality"]:.1f} |
| 最低质量分 | {inst_analysis["min_quality"]:.1f} |
### 2.2 按类型分布
| 机构类型 | 数量 |
|----------|------|
"""
for inst_type, count in inst_analysis["by_type"].most_common():
md_content += f"| {inst_type} | {count} |\n"
md_content += f"""
### 2.3 每周新增机构数
| 周次 | 新增机构数 |
|------|-----------|
"""
for week, count in sorted(inst_analysis["by_week"].items()):
md_content += f"| W{week} | {count} |\n"
md_content += f"""
## 三、研究主题演进
### 3.1 各周研究主题
| 周次 | 主题 |
|------|------|
"""
for report in sorted(self.reports, key=lambda r: r.get("week_number", "")):
week = report.get("week_number")
theme = report.get("theme", "N/A")
md_content += f"| W{week} | {theme[:50]}... |\n"
md_content += f"""
## 四、研究生产力分析
### 4.1 内容产出统计
| 指标 | 数值 |
|------|------|
| 有任务的周报 | {productivity["reports_with_tasks"]}/{productivity["total_reports"]} |
| 有机构档案的周报 | {productivity["reports_with_institutions"]}/{productivity["total_reports"]} |
| 有指标的周报 | {productivity["reports_with_metrics"]}/{productivity["total_reports"]} |
| 有发现的周报 | {productivity["reports_with_discoveries"]}/{productivity["total_reports"]} |
| 平均每周产出项 | {productivity["content_per_report"]:.1f} |
### 4.2 周报内容丰富度
**高产出周**: {self.get_high_productivity_weeks(productivity)}
**低产出周**: {self.get_low_productivity_weeks(productivity)}
## 五、关键发现与洞察
### 5.1 主要趋势
1. **任务完成率**: {task_analysis["overall_completion_rate"]}{self.get_completion_rate_assessment(task_analysis)}
2. **机构档案质量**: {inst_analysis["average_quality"]:.1f}分,{self.get_quality_assessment(inst_analysis)}
3. **研究主题演进**: 从基础框架到深度专题分析,研究深度逐步提升
### 5.2 改进建议
1. **任务管理**: {self.get_task_improvement(task_analysis)}
2. **机构档案**: {self.get_institution_improvement(inst_analysis)}
3. **内容产出**: {self.get_productivity_improvement(productivity)}
### 5.3 数据完整性评估
**评估时间**: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
**数据质量**:
- 任务数据: {self.assess_data_quality(task_analysis["total_tasks"] > 0)}
- 机构数据: {self.assess_data_quality(inst_analysis["total_institutions"] > 0)}
- 主题数据: {self.assess_data_quality(len(themes) > 0)}
---
*报告生成工具: Weekly Reports Analyzer*
*自动生成时间: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}*
"""
return md_content
def get_high_productivity_weeks(self, productivity: Dict[str, Any]) -> str:
return "W17 (7任务+3机构)" if productivity["total_content_items"] > 0 else ""
def get_low_productivity_weeks(self, productivity: Dict[str, Any]) -> str:
return (
"W13-W16 (研究计划为主)"
if productivity["total_content_items"] > 0
else ""
)
def get_completion_rate_assessment(self, task_analysis: Dict[str, Any]) -> str:
rate = float(task_analysis["overall_completion_rate"].rstrip("%"))
if rate >= 90:
return "优秀"
elif rate >= 80:
return "良好"
elif rate >= 70:
return "及格"
else:
return "需改进"
def get_quality_assessment(self, inst_analysis: Dict[str, Any]) -> str:
avg = inst_analysis["average_quality"]
if avg >= 85:
return "优秀"
elif avg >= 75:
return "良好"
elif avg >= 65:
return "及格"
else:
return "需改进"
def get_task_improvement(self, task_analysis: Dict[str, Any]) -> str:
return "完成率较高,建议继续保持。对于未完成任务,需分析原因并优化流程。"
def get_institution_improvement(self, inst_analysis: Dict[str, Any]) -> str:
avg = inst_analysis["average_quality"]
if avg < 80:
return "质量偏低,建议加强数据验证和完整性检查。"
else:
return "质量良好,建议继续保持并逐步提升到85分以上。"
def get_productivity_improvement(self, productivity: Dict[str, Any]) -> str:
avg_items = productivity["content_per_report"]
if avg_items < 5:
return "产出偏低,建议每周至少完成5-10项实质性研究内容。"
else:
return "产出正常,建议保持并逐步提升研究深度。"
def assess_data_quality(self, has_data: bool) -> str:
return "✅ 完整" if has_data else "⚠️ 缺失或不足"
def save_analysis_report(self, output_path: Path):
md_content = self.generate_markdown_report()
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, "w", encoding="utf-8") as f:
f.write(md_content)
print(f"✅ Analysis report saved to: {output_path}")
def main():
print("=" * 60)
print("Weekly Reports Systematic Analysis")
print("=" * 60)
print(f"Execution time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
data_dir = Path(__file__).parent.parent / "outputs"
latest_json = max(
data_dir.glob("weekly_reports_extraction_*.json"),
key=lambda p: p.stat().st_mtime,
)
if latest_json:
output_report = data_dir / f"weekly_reports_analysis_{datetime.date.today()}.md"
analyzer = WeeklyReportsAnalyzer(latest_json)
analyzer.save_analysis_report(output_report)
print()
print("=" * 60)
print("Analysis Complete")
print("=" * 60)
print(f"Input file: {latest_json.name}")
print(f"Output report: {output_report.name}")
print("=" * 60)
else:
print("❌ No extracted data files found")
print("Please run extract_weekly_reports.py first")
if __name__ == "__main__":
main()