feat: OKR模板库P2治理 — owner字段/防重复/校准文档/缺口清单
- 模型+DB: okr_templates.owner (CMA标准库/行业包/用户自定义) - API: create同名去重(409) + list/get返回owner + apply透传metric_kpi - 前端: 模板卡片展示owner标签 - 文档: kpi-dictionary-gap-list.md(33条缺口+建议补KPI) + okr-template-calibration.md(酣客/博海校准表) - 回归: 模板API验证通过
This commit is contained in:
@@ -68,6 +68,7 @@ def list_okr_templates(
|
||||
"industry_tag": t.industry_tag,
|
||||
"preset_krs": t.preset_krs,
|
||||
"source": t.source,
|
||||
"owner": t.owner,
|
||||
"use_count": t.use_count,
|
||||
"sort_order": t.sort_order,
|
||||
"is_active": t.is_active,
|
||||
@@ -93,6 +94,7 @@ def get_okr_template(template_id: int, db: Session = Depends(get_db)):
|
||||
"industry_tag": t.industry_tag,
|
||||
"preset_krs": t.preset_krs,
|
||||
"source": t.source,
|
||||
"owner": t.owner,
|
||||
"use_count": t.use_count,
|
||||
"sort_order": t.sort_order,
|
||||
"is_active": t.is_active,
|
||||
@@ -101,7 +103,7 @@ def get_okr_template(template_id: int, db: Session = Depends(get_db)):
|
||||
|
||||
@router.post("")
|
||||
def create_okr_template(data: dict, db: Session = Depends(get_db)):
|
||||
"""用户自定义 OKR 模板"""
|
||||
"""用户自定义 OKR 模板(治理: 同名去重 + owner 标记)"""
|
||||
name = data.get("name", "").strip()
|
||||
if not name:
|
||||
raise HTTPException(400, "模板名称不能为空")
|
||||
@@ -111,6 +113,14 @@ def create_okr_template(data: dict, db: Session = Depends(get_db)):
|
||||
preset_krs = data.get("preset_krs", [])
|
||||
if not isinstance(preset_krs, list) or len(preset_krs) == 0:
|
||||
raise HTTPException(400, "至少需要一个预设KR")
|
||||
# P2治理: 同名+同维度去重(防止 id=33 式重复模板,2026-08-21)
|
||||
dup = db.query(OKRTemplate).filter(
|
||||
OKRTemplate.name == name,
|
||||
OKRTemplate.dimension == dimension,
|
||||
OKRTemplate.is_active == 1,
|
||||
).first()
|
||||
if dup:
|
||||
raise HTTPException(409, f"已存在同名模板「{name}」(#{dup.id}, source={dup.source}),请改用现有模板或改名")
|
||||
|
||||
t = OKRTemplate(
|
||||
name=name,
|
||||
@@ -120,6 +130,7 @@ def create_okr_template(data: dict, db: Session = Depends(get_db)):
|
||||
industry_tag=data.get("industry_tag", "general"),
|
||||
preset_krs=preset_krs,
|
||||
source="user",
|
||||
owner="用户自定义",
|
||||
sort_order=data.get("sort_order", 0),
|
||||
)
|
||||
db.add(t)
|
||||
@@ -164,6 +175,8 @@ def apply_okr_template(template_id: int, data: dict, db: Session = Depends(get_d
|
||||
"name": kr.get("name", ""),
|
||||
"target_value": kr.get("target_value", ""),
|
||||
"weight": kr.get("weight", 33),
|
||||
"metric_kpi_id": kr.get("metric_kpi_id"),
|
||||
"metric_kpi_code": kr.get("metric_kpi_code"),
|
||||
}
|
||||
for kr in preset_krs
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user