feat(management): 指标元数据+试算评分配置v1.0+种子CLI——权重校验/幂等落库
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
"""管理域评分配置/引擎判别测试(批次B)。"""
|
||||
import json
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from app.db.models import EmployeeScoreConfig
|
||||
from app.management.metric_definitions import (
|
||||
DEFAULT_SCORE_CONFIG,
|
||||
METRIC_DEFINITIONS,
|
||||
validate_config,
|
||||
)
|
||||
|
||||
|
||||
def test_config_weights_sum_and_structure():
|
||||
dims = DEFAULT_SCORE_CONFIG["dimensions"]
|
||||
assert sum(d["weight"] for d in dims.values()) == 100
|
||||
# 一期 pending_data 的维度不参与试算
|
||||
available = [d for d in dims.values() if d.get("status") != "pending_data"]
|
||||
assert sum(d["weight"] for d in available) == 70 # 30+25+15
|
||||
assert dims["action"]["status"] == "pending_data"
|
||||
assert dims["risk"]["status"] == "pending_data"
|
||||
|
||||
|
||||
def test_config_normalization_declared():
|
||||
assert DEFAULT_SCORE_CONFIG["normalization"] == "available_only_rescale"
|
||||
|
||||
|
||||
def test_validate_config_rejects_bad_weight_sum():
|
||||
bad = json.loads(json.dumps(DEFAULT_SCORE_CONFIG)) # deep copy
|
||||
bad["dimensions"]["service"]["weight"] = 26 # 总和 101
|
||||
problems = validate_config(bad)
|
||||
assert any("权重" in p for p in problems)
|
||||
|
||||
|
||||
def test_metric_definitions_cover_scored_metrics():
|
||||
# 每个参与评分的 metric_code 都有元数据(名称/单位/方向)
|
||||
for dim in DEFAULT_SCORE_CONFIG["dimensions"].values():
|
||||
for code in dim.get("metrics", {}):
|
||||
md = METRIC_DEFINITIONS[code if code in METRIC_DEFINITIONS else "active_share"]
|
||||
# band 型指标的 key 带 _band 后缀,spec 里有 metric 字段:
|
||||
spec = dim["metrics"][code]
|
||||
src = spec.get("metric", code)
|
||||
assert src in METRIC_DEFINITIONS
|
||||
m = METRIC_DEFINITIONS[src]
|
||||
assert m["name"] and m["unit"] and m["direction"] in (1, -1)
|
||||
|
||||
|
||||
async def test_seed_and_idempotent(make_session):
|
||||
from app.sync.cli import _seed_score_config # 纯会话函数
|
||||
s = make_session
|
||||
v1 = await _seed_score_config(s)
|
||||
await s.commit()
|
||||
assert v1 == "v1.0"
|
||||
rows = (await s.execute(sa.select(EmployeeScoreConfig))).scalars().all()
|
||||
assert len(rows) == 1 and rows[0].status == "active"
|
||||
# 幂等:已存在同版本返回 None 不新建
|
||||
assert await _seed_score_config(s) is None
|
||||
await s.commit()
|
||||
assert len((await s.execute(sa.select(EmployeeScoreConfig))).scalars().all()) == 1
|
||||
Reference in New Issue
Block a user