feat(achievement): 添加按难度的 AC 题数指标,删除 min_ac_code_chars

新增 mid_ac_count / hard_ac_count,去重统计中等和困难难度的 AC 题数。
在此之前所有成就对水题和难题一视同仁,这是最缺的一个维度。
增量走 build_ctx 新增的 problem_difficulty,它只在首次 AC 时才查库——
绝大多数提交都不是首次 AC,无条件预查等于给每次判题白加一条 SQL。

删除 min_ac_code_chars:线上实测 1314 个用户的分布,最小值 8、p5=10,
有道题 8 个字符就能通过,这个指标测的是"谁做过那道水题"而不是
"谁写得简洁",配不出有意义的成就。

自检里写死 min_ac_code_chars 的两处改成按 lte 成就自动发现:
_check_registry 不再要求某个具体指标存在,_check_min_metric_absent
改为遍历所有上架的 lte 成就检查其指标。没有 lte 成就时 SKIP,
将来配了自动开始检查。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 11:02:16 -06:00
parent c50f7b7269
commit e9c7793714
5 changed files with 63 additions and 30 deletions

View File

@@ -40,7 +40,7 @@ python manage.py check_achievement_deploy
只读,可反复跑,七项检查。此刻大部分是 `[SKIP]`(还没配成就、还没重算),**但这两项必须现在就 PASS**
- **极小值指标对零 AC 用户返回 None** —— 不 PASS 就别配任何 `lte` 类成就。`min_ac_code_chars` 若返回 `0`,「最短 AC 代码 ≤ 50 字符」会白送给每一个从没做出过题的新生。
- **极小值指标对零 AC 用户返回 None** —— 不 PASS 就别配任何 `lte` 类成就。这类指标若返回 `0`,「最短 AC 代码 ≤ 50 字符」之流会白送给每一个从没做出过题的新生。线上目前没有 `lte` 成就,本项会 SKIP配了才开始检查。
- **JSONB 阈值比较按整数** —— 不 PASS 的话以后在后台调低阈值触发的补发会发给错误的人群。JSONB 里的数字若不显式 castPostgres 按字符串序比较,`"9" > "50"` 成立。
### 第三步 单人试跑重算