feat: 新增文档Tab(📚文档)——开源项目式文档体系(VERSIONS.md运营者版本变更+INDEX.md目录树+docs.json spec),让知微通过文档理解系统变化
This commit is contained in:
@@ -1834,6 +1834,80 @@ def api_evolution_combo():
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
# ── 📚 文档 Tab 端点(2026-08-11 新增,开源项目式文档体系)──
|
||||
|
||||
@app.route("/api/docs/index")
|
||||
def api_docs_index():
|
||||
"""文档目录树:扫描 docs/ 返回分类结构(README/VERSIONS/INDEX + 按主题)"""
|
||||
try:
|
||||
if not DOCS_DIR.exists():
|
||||
return jsonify({"ok": False, "error": "docs/ not found"})
|
||||
index = []
|
||||
# 核心文档(置顶)
|
||||
core = ["README.md", "VERSIONS.md", "INDEX.md"]
|
||||
for f in core:
|
||||
p = DOCS_DIR / f
|
||||
if p.exists():
|
||||
index.append({"path": f, "title": f.replace(".md", ""), "category": "📖 核心", "core": True})
|
||||
# 按主题分类
|
||||
cats = {
|
||||
"运维参考": ["QUICKSTART", "DEPLOY", "DASHBOARD", "HEALTH-PIPELINE", "doc-audit", "system-audit"],
|
||||
"策略研究": ["strategy_research", "predictive_oversold", "deployment-plan", "cron-", "research/"],
|
||||
"系统机制": ["dev-spec", "DEVELOPMENT_STANDARDS", "SELF_GROWTH", "lifecycle", "strategy-review", "morning-health", "zhiwei-ops", "portfolio-data-model"],
|
||||
"决策记录": ["decisions/"],
|
||||
}
|
||||
for md in sorted(DOCS_DIR.rglob("*.md")):
|
||||
rel = str(md.relative_to(DOCS_DIR))
|
||||
if rel in core or "archive" in rel or "backup" in rel:
|
||||
continue
|
||||
cat = "📚 其他"
|
||||
for cname, kws in cats.items():
|
||||
if any(kw in rel for kw in kws):
|
||||
cat = cname
|
||||
break
|
||||
index.append({"path": rel, "title": rel.replace(".md", "").replace("/", " / "), "category": cat})
|
||||
return jsonify({"ok": True, "index": index, "count": len(index)})
|
||||
except Exception as e:
|
||||
return jsonify({"ok": False, "error": str(e)[:100]})
|
||||
|
||||
|
||||
@app.route("/api/docs/versions")
|
||||
def api_docs_versions():
|
||||
"""版本变更列表:解析 VERSIONS.md 的每个变更条目"""
|
||||
try:
|
||||
f = DOCS_DIR / "VERSIONS.md"
|
||||
if not f.exists():
|
||||
return jsonify({"ok": False, "error": "VERSIONS.md not found"})
|
||||
content = f.read_text(encoding="utf-8")
|
||||
versions = []
|
||||
# 解析 "## 2026-08-11 — 标题" 格式
|
||||
import re
|
||||
parts = re.split(r"^##\s+", content, flags=re.M)
|
||||
for p in parts:
|
||||
if not p.strip() or p.startswith("阅读指南") or p.startswith("维护说明"):
|
||||
continue
|
||||
lines = p.strip().split("\n", 1)
|
||||
title = lines[0].strip()
|
||||
body = lines[1] if len(lines) > 1 else ""
|
||||
versions.append({"title": title, "body": body[:4000]})
|
||||
return jsonify({"ok": True, "versions": versions, "count": len(versions)})
|
||||
except Exception as e:
|
||||
return jsonify({"ok": False, "error": str(e)[:100]})
|
||||
|
||||
|
||||
@app.route("/api/docs/read")
|
||||
def api_docs_read():
|
||||
"""读取指定文档内容(markdown)"""
|
||||
from flask import request
|
||||
path = request.args.get("path", "")
|
||||
if not path or ".." in path or path.startswith("/"):
|
||||
return jsonify({"ok": False, "error": "invalid path"})
|
||||
f = DOCS_DIR / path
|
||||
if not f.exists() or not f.suffix == ".md":
|
||||
return jsonify({"ok": False, "error": "doc not found"})
|
||||
return jsonify({"ok": True, "content": f.read_text(encoding="utf-8")})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
port = int(os.environ.get("PORT", 8899))
|
||||
print(f"🚀 MoFin Dashboard → http://0.0.0.0:{port}")
|
||||
|
||||
Reference in New Issue
Block a user