Files
danyang-match/docs/governance/config-register.md
T
WorkBuddy 60c591fc68 V1.0.1 纠偏 DoD 补齐:canonical key 字面化(V051+KEY_ALIASES)+ 照片并发突破实测(锁用户行+锁后计数)+ AGENTS 规则27 + known-risks
按文档 DoD/约束逐条复查后补齐的差距(承接 438b38d 主体纠偏):
- CFG-001 字面化:FeatureFlagConfig.KEY_ALIASES(identity.liveness.enabled / 遗留
  livenessVerification.enabled → 实现字段 livenessEnabled,读兼容)+ Controller PUT/DELETE
  落库归一到 canonical 键 + V051 迁移(删遗留键、写入 identity.liveness.enabled=false);
  MigrationValidationTest 基线 50→51。
- PHOTO-004 真实并发突破:新增 PhotoLimitConcurrencyGuardTest(3 线程 H2 并发冲顶)——
  实测咬住「锁照片行+读时计数」在 H2 MVCC 快照漏读、3/3 全成功突破上限的缺陷;
  并发控制改为锁用户行(UserMapper.lockUserRow FOR UPDATE)+ 锁后新语句 COUNT,
  0 张照片亦有锁可加(补首张并发缺口);UserPhotoMapper 计数方法同步替换。
- FF-LIVENESS-003 + canonical 持久化:FeatureFlagPersistenceGuardTest +4
  (canonical 加载 / 遗留别名读兼容 / PUT 落 canonical 键 / 切换即生效无旧缓存)、
  FeatureFlagControllerTest +3(canonical/legacy/reset)。
- 文档同步:AGENTS.md 规则 27(配置治理纪律);docs/governance/known-risks.md
  (7 项含本机 WSL/Docker 故障 KR-07);config-register / open-questions 更新 canonical 口径;
  STATUS rc.21 行补 ⑥⑦⑧。

全量回归 741/0/0/3(基线 717 + 25 新增 − 1 删死测试,宿主机 JDK21+Maven 3.9.9 实测,
本机 WSL/Docker 引擎故障期间);UI 契约门禁 18/18
2026-09-21 11:13:14 +08:00

57 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 配置登记表 — config-register.md
> **版本**:V1.0.1 配置与规则纠偏基线 · **生效**:2026-09-20 · **owner**:WorkBuddy
> **代码载体**:`FeatureFlagConfig`(feature flag,前缀 `features`)/ `MatchRuleConfigProperties`(前缀 `match`)/ `ProfileProperties`(前缀 `profile`)/ `AccountConfig`(前缀 `account`)
> **一致性守卫**:`FeatureFlagPersistenceGuardTest`、`MatchRuleConfigPropertiesTest`、`EntityMigrationParityTest`、`MigrationValidationTest`
>
> **核心纪律**(AGENTS.md #12 + V1.0.1 纠偏):**技术默认值 ≠ 产品正式确认规则。**
> 未确认的数量/阈值/时间/比例/权重/开关,一律按 `DEFAULT + CONFIG` 管理,禁止作为 `LOCKED` 业务规则写死;
> 所有配置必须有**唯一 canonical key**,禁止同一业务含义存在多套 key(seed / yml / 字段 / 前端各写一套)。
---
## 一、分类图例
| 分类 | 含义 | 是否可硬编码 |
|------|------|:---:|
| `LOCKED` | 产品负责人已确认的业务/安全硬约束 | 原则上不可随意变更 |
| `DEFAULT` | 当前技术实现默认值,可经配置/ADR 替换 | 不应散落硬编码 |
| `CONFIG` | 需配置化管理的业务参数/开关 | 禁止写死 |
| `TBD` | 产品尚未正式确认 | 禁止当成产品规则 |
| `FUTURE` | 明确不属于当前 V1 范围 | 不实现主链路 |
| `LEGAL_VERIFY` | 上线前需依最新官方/法律要求核验 | 不得自行假设 |
---
## 二、配置登记表
| canonical 配置键 | 实现键(yml / flag 字段) | 分类 | 当前默认值 | 产品正式确认 | 是否可配置 | 代码载体 / 说明 |
|------------------|--------------------------|------|:---------:|:---:|:---:|----------------|
| `identity.liveness.enabled` | **DB 键即 canonical 名**(`feature_flag_overrides.flag_key = 'identity.liveness.enabled'`,V051 写入;Java 字段 `livenessEnabled`,yml `features.liveness-enabled`) | CONFIG / TBD | `false` | 否 | 是 | `FeatureFlagConfig.KEY_ALIASES` 承担「canonical 键 ↔ 实现字段」映射(`identity.liveness.enabled` / 遗留 `livenessVerification.enabled` → `livenessEnabled`);写库归一(Controller PUT/DELETE 落 canonical 键);`IdentityPolicy` + `GET /verification/liveness-status` 真实判定点(FF-LIVENESS-002)。**活体不是 V1 强制规则**;默认关闭不阻断实名主流程;fail-safe:配置缺失默认 false。 |
| `identity.liveness.provider` | `features.livenessProvider`(yml `features.liveness-provider`) | CONFIG / TBD | `none` | 否 | 是 | `FeatureFlagConfig`;`none`=尚未接入合规第三方,人脸 Provider 选型未定(OQ-IDENTITY-001)。 |
| `profile.photo.maxCount` | `profile.photo.max-count` | CONFIG / TBD | `6` | 否 | 是 | `ProfileProperties` + `ProfilePolicy`;**6 仅为技术默认**;服务器端 `PhotoService.ensureWithinPhotoLimit`(FOR UPDATE 并发安全)强制校验;前端经 `GET /app/config` → `businessLimits.maxProfilePhotos` 动态读取,不再写死。 |
| `matching.recommendation.minScore` | `match.default-score-threshold` | CONFIG / TBD | `60` | 否 | 是 | `MatchRuleConfigProperties` + `MatchingPolicy`;**60 仅为技术默认,非产品确认**(消解 PENDING :43 vs :75 矛盾);引擎/资格判定读配置;推荐记录 V050 起写 `threshold_snapshot` 支持追溯。 |
| `matching.rule.version` | `match.rule-version` | CONFIG | `1` | 否 | 是 | `MatchRuleConfigProperties`;写入 `recommendation_records.rule_version`,与阈值快照配合构成规则版本。 |
| `matching.daily.limit` | `match.default-daily-limit` | CONFIG | `6` | 是(每日 6 人,见 decision-register) | 是 | `MatchRuleConfigProperties`。 |
| `matching.cooldown.days` | `match.default-cooldown-days` | CONFIG | `180` | 是(Pass 冷却 180 天) | 是 | `MatchRuleConfigProperties`。 |
| `matching.weights.*`(10 维) | `match.*-weight`(age 15 / region 15 / marital 10 / children 10 / education 5 / height 5 / marriagePlan 15 / settlement 10 / lifestyle 10 / interest 5) | CONFIG / TBD | 见左 | 否 | 是 | `MatchRuleConfigProperties`;yml 未覆盖,全用类内默认;**打分公式仍为 V1 占位**(见 audit 未来项)。 |
| `matching.local-eligibility.required` | `match.local-eligibility-required` | CONFIG | `false` | 否 | 是(仅 docker yml) | 本地资格是否作为推荐硬性门禁;默认关。 |
| `account.data-retention.months` | `account.data-retention-months` | LOCKED | `36` | 是(2026-09-19 产品确认下限 36 个月) | 是 | `AccountConfig`;注销后保留期下限,到期人工审核匿名化(V049)。 |
| `account.feature-flags.*`(活动/红娘/图片聊天/申诉/转介/互选/专项 开关) | `features.*` | CONFIG | 见 `FeatureFlagConfig` | 部分 | 是 | `FeatureFlagConfig`;`feature_flag_overrides`(V048)持久化覆盖。 |
| `idempotency.ttl` | 应用层 `idempotency_records`(TTL 默认 86400s) | CONFIG / LEGAL_VERIFY | `86400s` | 否 | 是 | 幂等去重窗口;开放第三方时需决定是否按调用方分级(OQ,见 open-questions)。 |
---
## 三、已消除的 key 漂移(本轮)
| 漂移 | 处置 |
|------|------|
| seed `livenessVerification.enabled` vs 实现键 `livenessEnabled` vs 治理名 `identity.liveness.enabled`(三套 key 同义) | **已删** `demo-seed-final.sql` 的死 seed 行;**V051 迁移**把 `feature_flag_overrides` 收敛为只写 canonical 键 `identity.liveness.enabled`(删除遗留 `livenessVerification.enabled`/`livenessEnabled` 行 + 写入 canonical 行);`FeatureFlagConfig.KEY_ALIASES` 承担「canonical/遗留键 → 实现字段 `livenessEnabled`」读兼容映射,Controller PUT/DELETE 落库归一到 canonical 键。Java 内部字段保持 `livenessEnabled`(文档允许内部变量如此命名)。 |
| `MatchConfig`(`shared/config`)与 `MatchRuleConfigProperties`(`match/config`)同前缀 `match` 双 bean | **已删** 死类 `MatchConfig`(0 业务引用),统一读 `MatchRuleConfigProperties`。 |
| 前端 `mergeAppConfig` 平铺合并 → 服务端嵌套 `businessLimits.*` 从不生效 | **已修** 显式节-键映射,`maxProfilePhotos` 等真正下发到前端。 |
---
*最后更新: 2026-09-21 — V1.0.1 配置与规则纠偏 + canonical key 字面化:登记 identity.liveness.enabled / profile.photo.maxCount / matching.recommendation.minScore 三项 canonical 键;V051 把活体键收敛为 `feature_flag_overrides` 唯一正式键(KEY_ALIASES 读兼容遗留键);消除 MatchConfig 双 bean 与前后端照片上限失同步。*