V1.0.1 配置与规则纠偏:照片上限配置化+强校验 / 活体开关闭环 / 推荐阈值快照+规则版本化 / governance 三表+漂移审计
根治三类工程治理问题(技术默认值≠产品规则、配置存在但未闭环、文档代码漂移): - PROFILE-001:profile.photo.maxCount(默认6未确认)+ ProfilePolicy + 服务器端 FOR UPDATE 并发强校验(PHOTO_LIMIT_EXCEEDED,拒绝先于 S3 不留孤儿)+ 前端 mergeAppConfig 嵌套键修复 - CFG-001/IDENTITY-001:IdentityPolicy + GET /verification/liveness-status 真实判定点 (默认关不阻断,开则 enhancedVerified 变化,消除假开关)+ 删死 seed livenessVerification.enabled - MATCH-001:阈值60定为技术默认(消解 PENDING 矛盾)+ V050 recommendation_records.threshold_snapshot 规则版本化 + 删死重复配置类 MatchConfig - DOC-001:新增 docs/governance/(config-register/open-questions/decision-register/ hardcoded-rule-audit/config-drift-audit) - TEST-001:新增守卫 PhotoLimitGuardTest(8)/IdentityLivenessGuardTest(5)/ RecommendationThresholdSnapshotGuardTest(4),均经负向注入可红 全量回归 733/0/0/3(基线717+17新增-1删死测试);UI 契约门禁 18/18;STATUS 升 rc.21
This commit is contained in:
+15
-10
@@ -1,6 +1,11 @@
|
||||
# 待确认决策项 — PENDING_DECISIONS.md
|
||||
|
||||
> 以下参数尚未由产品负责人确认。已确认项请参见已确认列表。
|
||||
>
|
||||
> **治理结构(V1.0.1 配置与规则纠偏,2026-09-20)**:本文件不再同时承担「已确认决策 / 技术默认值 / 待确认事项」。
|
||||
> 已拆分到 `docs/governance/`:**配置登记表** `config-register.md`(canonical 键 + 分类 + 是否产品确认)、
|
||||
> **开放问题** `open-questions.md`(OQ-*,待产品裁决)、**决策登记表** `decision-register.md`(仅已确认项)。
|
||||
> 本文件保留历史待确认区与「已确认列表」,并与上述三表互链;**矛盾以 governance 三表为准**。
|
||||
|
||||
---
|
||||
|
||||
@@ -10,8 +15,8 @@
|
||||
|
||||
| 决策项 | 选项 | 状态 |
|
||||
|--------|------|------|
|
||||
| 人脸核验是否V1.1首发强制 | 否(Feature Flag 控制) | ⏳ 待确认 |
|
||||
| 人脸核验 Provider | 待定 | ⏳ 待确认 |
|
||||
| 人脸核验是否V1.1首发强制 | 否(Feature Flag 控制,`identity.liveness.enabled` 默认 `false`) | ⏳ 待确认(CONFIG/TBD,**非 V1 强制**;本轮已接 `IdentityPolicy` 真实业务判定点,见 config-register / OQ-IDENTITY-001) |
|
||||
| 人脸核验 Provider | 待定(`identity.liveness.provider` 默认 `none`) | ⏳ 待确认(选型未定,见 OQ-IDENTITY-001) |
|
||||
|
||||
### 本地资格
|
||||
|
||||
@@ -38,11 +43,11 @@
|
||||
|
||||
| 决策项 | 技术默认值 | 状态 |
|
||||
|--------|-----------|------|
|
||||
| Banner最大活跃数量 | 待定 | ⏳ 待确认 |
|
||||
| 推荐每日数量 | 6人 | ✅ 已完成 |
|
||||
| 推荐阈值/最终权重 | 待定 | ⏳ 待确认 |
|
||||
| Pass冷却时间 | 180天 | ✅ 已完成 |
|
||||
| 照片上限 | 6张 | ✅ 已完成 |
|
||||
| Banner最大活跃数量 | 待定(**真缺口**:代码无此限制,仅 seed 死值 5) | ⏳ 待确认(OQ-BANNER-001,需产品定值后实现 active-count 校验) |
|
||||
| 推荐每日数量 | 6人 | ✅ 已完成(LOCKED,`match.default-daily-limit`) |
|
||||
| 推荐阈值/最终权重 | **技术默认 60,未产品确认**(`matching.recommendation.minScore`,可配置 + V050 阈值快照) | ⏳ 待确认(OQ-MATCH-001;消解本文 :「阈值60分已确认」矛盾 —— 60 只是默认值) |
|
||||
| Pass冷却时间 | 180天 | ✅ 已完成(LOCKED,`match.default-cooldown-days`) |
|
||||
| 照片上限 | **技术默认 6,未产品确认**(`profile.photo.maxCount`,已配置化 + 服务器端强校验) | ⏳ 待确认(OQ-PROFILE-001;原标「✅ 已确认 6」有误,6 非产品正式确认值) |
|
||||
|
||||
### 数据统计
|
||||
|
||||
@@ -72,8 +77,8 @@
|
||||
| 内容 | 婚恋课堂 + 婚恋反诈进入V1.1首发 |
|
||||
| 活动 | 多类型公益活动 + 活动双向沟通确认进入V1.1首发 |
|
||||
| 核心规则 | Required不可放宽 / Mutual后才Chat / Block优先 |
|
||||
| 推荐 | 每日6人 / 阈值60分 / Pass冷却180天 |
|
||||
| 资料 | 照片上限6张 / 兴趣标签上限8个 / 自我介绍500字符 |
|
||||
| 推荐 | 每日6人(LOCKED)/ Pass冷却180天(LOCKED);**阈值60分仅为技术默认值,未产品确认**(OQ-MATCH-001) |
|
||||
| 资料 | 兴趣标签上限8个 / 自我介绍500字符(LOCKED);**照片上限6张仅为技术默认值,未产品确认**(OQ-PROFILE-001) |
|
||||
| 隐私 | Privacy默认全TRUE |
|
||||
| 活动规则 | 需审核 / 男女名额独立配置 / 互选最大3人 / 截止后48小时 |
|
||||
| 关系状态 | searching/getting_to_know/paused/matched_successfully/service_exited |
|
||||
@@ -124,5 +129,5 @@
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2026-09-19 — 新增「数据保留」已确认项(2026-09-19 产品确认:注销后数据保留不得低于 36 个月);历史部署声明 10 项已按各 Phase 复验证据回写处置结果;第三方开放遗留 7 项待决策*
|
||||
*最后更新: 2026-09-20 — V1.0.1 配置与规则纠偏:消解「推荐阈值 60 已确认 / 待定」矛盾(60 为技术默认,OQ-MATCH-001);照片上限 6 由「已确认」降级为「技术默认 / 未确认」(OQ-PROFILE-001);活体核验补 CONFIG/TBD 并接 IdentityPolicy 真实判定点(OQ-IDENTITY-001);拆分出 docs/governance/(config-register / open-questions / decision-register)。*
|
||||
|
||||
|
||||
+3
-2
@@ -1,10 +1,10 @@
|
||||
# 项目状态跟踪 — STATUS.md
|
||||
|
||||
> **2026-09-20 当前有效结论:`V1.1 RECOVERY PHASE 01~22 CLOSED / PHASE 23 CLOSEOUT FULLY DONE (BATCH 1-3 CLEARED, DATA RETENTION FLOW LANDED) / HORIZONTAL HARDENING DONE / UI REDESIGN ACCEPTED BY USER / REMAINING: CI GREEN RUN (needs GitHub Actions) + BATCH 4 (USER) / PHASE 24 (UAT) AWAITING USER GO`。**
|
||||
> **2026-09-20 当前有效结论:`V1.1 RECOVERY PHASE 01~22 CLOSED / PHASE 23 CLOSEOUT FULLY DONE (BATCH 1-3 CLEARED, DATA RETENTION FLOW LANDED) / HORIZONTAL HARDENING DONE / UI REDESIGN ACCEPTED BY USER / REMAINING: CI GREEN RUN (needs GitHub Actions) + BATCH 4 (USER) / PHASE 24 (UAT) AWAITING USER GO`。** **V1.0.1 配置与规则纠偏已完成**(照片上限配置化 + 服务器端强校验 / 活体开关闭环 / 推荐阈值纠偏 + 规则版本化快照 / governance 三表 + 漂移审计):全量回归 **733 / 0 / 0 / 3**(基线 717 + 17 新增 − 1 删死测试),UI 契约门禁 **18/18**。
|
||||
>
|
||||
> 阶段 0(在途收口)、阶段 1(小程序 C 组 + discover 筛选重设计)、阶段 2(管理端 Vue 新框架适配)、阶段 3(CapabilityService 独立化)、阶段 4(双端总验收)全部完成。三端构建通过、**13/13 契约全绿**(阶段 4 验收时点值;当前 UI 契约门禁为 **18/18**)、核心 11 页面**全部 TS-only(11/11)**。**UI 重设计首批 11 页已于 2026-09-16 通过用户验收(结论:基本达标)**;`/me/*` 前后端契约同轮收敛,17 个 404 调用已恢复。**Phase 08(Like / Match / Block)、Phase 09(Text Chat)、Phase 10(Image & Chat Safety)、Phase 11(Notification)、Phase 12(Relationship Progress)、Phase 13(公益红娘转介)、Phase 13A(婚恋咨询与婚前辅导)、Phase 14(多类型公益活动)、Phase 15(活动报名、审核与签到)、Phase 16(活动互选与双方开启沟通确认)、Phase 17(举报与风控)、Phase 18(申诉)、Phase 19(统一运营后台 + 用户端公益服务页面)、Phase 20(Analytics 数据统计与管理驾驶舱)复验已关闭**,十四轮共修复 130+ 处真实缺陷(含 3 处隐藏编译缺陷),并各自补齐测试保真度与守卫。**Phase 21、22 复验已关闭(2026-09-18)**;**Phase 23 为「部分关闭」(2026-09-18)** —— 已清除 44 个 `pass` 空壳与 14 个只断言常量的假不变量测试,新增 4 个经负向注入验证的真实行为守卫与空壳阻断闸门,后端回归 655 全绿;但 **E2E 进入 CI 因需「活栈供给方式」基础设施决策而列为遗留,故不宣布「失败为零可进入 UAT」**。**Phase 23B(E2E 测试基建重建,33→49 passed)、HTTP 语义检修(失败响应携带真实状态码)、幂等键检修(`Idempotency-Key` 30 端点落地,V045/V046)均已于 2026-09-18 完成**,后端全量回归 **669 / 0 failures / 0 errors / 3 skipped**。**管理端入口已收敛到 `/admin/` 子路径(vite base + router base + 三处 nginx 接线),staging 端口 13521;UI 契约门禁 18/18 全绿(第 15~18 项为 2026-09-19 新增)。Phase 24(UAT)启动需用户确认。** **2026-09-19 收尾推进(批 2/3,已全部完成)**:Phase 23 Task 2.1(互选 8 + 预约 8 场景真实实现,本机 E2E **65 passed**,负向注入 2 轮精准变红)与 Task 2.2(INV-011 显式行为守卫 9 用例)完成;批 3 处置 Phase 21/22 遗留——隐私设置接真实落库(**V047** 补列 + upsert 修复,守卫 8 用例含解析小程序源码的契约守卫)、5 个死开关 + 2 个私有桶死配置移除(产品裁定)、`PUT /feature-flags` 真持久化(**V048**,守卫 11 用例)、补 5 个「只有声明无 SQL」的 Mapper 方法并新增绑定守卫;**Task 3.3 四项 + 红娘服务拦截接线完成**(P16-T13 `expires_at` 写入接线、P13A-T31 随访审计、P13A-T33 随访正文风险检测、P04-T10 确认 Onboarding 本地资格早已实现、`checkCanWithdraw` 红娘 blocker 首次生效 + 注销竞态兜底),各项均带真实落库守卫并经负向注入验证。**全量回归 712 / 0 failures / 0 errors / 3 skipped(BUILD SUCCESS,2026-09-19 实测)→ 717(2026-09-20 实测,数据保留流程 +5)**;UI 契约门禁 **18/18**;**E2E 本机模拟 CI 序列实测 65/65 全绿(2026-09-20,宿主机 Python 3.11 + 活栈,GitHub Actions 流水线实测仍待一次推送)**。批 3 仅余:E2E 入 CI 的 GitHub Actions 实测绿(数据保留流程已于 2026-09-19/20 落地,见 V049 行)。
|
||||
|
||||
最后更新: 2026-09-20 — 分支 `main`(`feat-ui-v11` 保留为冗余锚点)
|
||||
最后更新: 2026-09-20 — 分支 `main`(V1.0.1 配置与规则纠偏落地,回归 733;`feat-ui-v11` 保留为冗余锚点)
|
||||
|
||||
## 当前唯一有效状态
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
| 1.1.0-rc.18 | 2026-09-19 | **小程序两处运行期/编译期缺陷 + 再补 3 项门禁(15 → 18)**。① **P0 运行期崩溃**:`utils/api.js` 成功回调把 `releaseIdempotencyKey` 误写成 `this._releaseIdempotencyKey`(多一个下划线),且调用位于 `resolve()` **之前** → 抛错使 **每一个成功请求的 Promise 永不 settle** → 所有页面永远停在 loading + `App.onError` 刷屏。修复方式不仅是改名:改为**先 `resolve` 再释放**且释放自身 try/catch 兜底 —— 收尾动作不允许挡在响应路径上。② 组件 `recommend-card/index.wxss` 使用标签选择器 `.compact-like image`(组件 wxss 只允许类选择器)→ 改为 `.compact-like__icon` 并同步 WXML 类名。③ 新增门禁:`wxml-structure-contracts`(第 15)、`miniapp-self-method-contracts`(第 16,判据先自证假阳性 —— 首版正则漏认 `this._x = 值` 形式误报 3 个页面)、`wxss-component-selector-contracts`(第 17)、`miniapp-api-client-behavior`(第 18,**桩掉 `wx.request` 真跑 api.js** 的成功/失败/幂等键释放/收尾容错 4 组行为断言)。负向验证:注入「未定义私有方法」「标签选择器」「多余闭合标签」均精准变红且合法样例不被误报;`UI_GUARDS_MIN=99` 拒绝报绿。基线 **PASS 18/18**。**未验证**:微信开发者工具真实编译与真机渲染(本机无该环境) |
|
||||
| 1.1.0-rc.19 | 2026-09-19 | 批 2/3 收尾完成:E2E 互选 8 + 预约 8 场景真实实现(本机活栈 **65 passed**,负向注入 2 轮)+ INV-011 显式守卫(9 用例);隐私设置接真实落库(V047)+ 5 死开关/2 死配置移除(产品裁定)+ `PUT /feature-flags` 真持久化(V048)+ 5 个无 SQL Mapper 方法补齐;**Task 3.3 四项 + 红娘服务拦截接线**(互选 `expires_at`、随访审计、随访风险检测、Onboarding 确认、注销 blocker 接线 + 竞态兜底);UI 契约门禁 **14→18**(WXML 结构 / WXSS 选择器 / api.js 行为 / miniapp 请求层,并修复小程序 P0 请求层崩溃);全量回归 **712 / 0 / 0 / 3** 全绿(B-9 命令实测) |
|
||||
| 1.1.0-rc.20 | 2026-09-20 | **数据保留流程落地**(产品 2026-09-19 确认:注销后数据保留不得低于 36 个月):V049 `users.closed_at` + `account.retention.purge` 权限(仅 super_admin)+ `AccountConfig.dataRetentionMonths`(36,配置化)+ `DataRetentionService`(人工审核:到期清单 + 幂等匿名化清除 + 审计;保留期内服务端拒绝)+ `DataRetentionGuardTest` 5 用例(负向注入摘掉下限判断恰 1 红);顺带清偿测试库缺 `user_photos` 表(照片软删路径 BadSqlGrammar 盲区,补表 + 移出 ParityTest 可选白名单)与 MyBatis-Plus `updateById` null 不进 SQL 陷阱(改 `LambdaUpdateWrapper.set(null)`);隐私政策 §3.3 / PIA §8 「30 天删除」修订为 36 个月;迁移基线 48→49。**全量回归 717 / 0 / 0 / 3 全绿**;**E2E 本机模拟 CI 序列 65/65 全绿**(宿主机 Python 3.11);UAT 用例 V1.1 版 46 用例(9 角色 × 7 路径)编写完成 |
|
||||
| 1.1.0-rc.21 | 2026-09-20 | **V1.0.1 配置与规则纠偏**(根治「技术默认值被误当产品规则 / 配置存在但未闭环 / 文档代码漂移」):① **照片上限配置化** `profile.photo.maxCount`(默认 6 未产品确认)+ `ProfilePolicy` + 服务器端 `FOR UPDATE` 并发强校验(新增 `PHOTO_LIMIT_EXCEEDED` 码,拒绝先于对象存储上传不留孤儿)+ 前端 `mergeAppConfig` 嵌套键修复(服务端值真正下发);② **活体开关闭环** `IdentityPolicy` + `GET /verification/liveness-status` 真实判定点(默认关不阻断实名主流程,开则 `enhancedVerified` 变化,消除假开关)+ 删死 seed `livenessVerification.enabled`;③ **推荐阈值纠偏**(60 为技术默认非产品确认)+ 规则版本化 V050 `recommendation_records.threshold_snapshot` + 删死重复配置类 `MatchConfig`;④ 新增 `docs/governance/`(config-register / open-questions / decision-register / hardcoded-rule-audit / config-drift-audit)并消解 PENDING 阈值/照片矛盾;⑤ 守卫 `PhotoLimitGuardTest` 8 + `IdentityLivenessGuardTest` 5 + `RecommendationThresholdSnapshotGuardTest` 4(均经负向注入可红)。**全量回归 733 / 0 / 0 / 3 全绿(基线 717 + 17 新增 − 1 删死测试);UI 契约门禁 18/18** |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# 配置漂移审计 — config-drift-audit.md
|
||||
|
||||
> **版本**:V1.0.1 配置与规则纠偏 · **日期**:2026-09-20
|
||||
> **判定原则**:同一业务含义只允许**一套 canonical key**;不得出现「seed 写一套、真实系统读另一套」「前端写一套、后端又一套」「文档说一套、代码做一套」。
|
||||
|
||||
---
|
||||
|
||||
## 一、`system_configs` 是**死表**(0 个 Java 读取点)
|
||||
|
||||
- `V001__init_base_tables.sql:131` 建表,`:213-217` seed 了 `match_rule_version / daily_recommendation_limit / match_score_threshold='60' / recommendation_cooldown_days`。
|
||||
- `demo-seed-final.sql` 又 seed 一批 flag 名(`localEligibility.evidencePolicy`、`counseling.enabled`、`premarital.enabled`、`serviceLocation.enabled`、`content.enabled`、`localEligibility.enabled`、`banner.maxActiveCount`)。
|
||||
- **全仓 `backend/src/main/java` 无任何 `SystemConfig` 实体 / Mapper / 读取**(仅 `EntityMigrationParityTest` 把它列入 H2 白名单)。
|
||||
- **后果**:真实系统读的是 `MatchRuleConfigProperties`(yml `match.*`)+ `FeatureFlagConfig`(`features.*` / `feature_flag_overrides`),**不是** `system_configs`。于是 `match_score_threshold='60'` 在死表里躺著,与活键 `match.default-score-threshold` 各写一份 → **seed 与 migration 漂移、seed 与代码漂移**。
|
||||
- **处置**:本轮删除 `demo-seed-final.sql` 的死 key `livenessVerification.enabled`(与活键 `livenessEnabled` 同义双 key)。其余 `system_configs` 死行**未删**(表整体退役需单独迁移裁定,避免越界)——登记为未来项:整体退役 `system_configs` 或把它接成真实配置源。
|
||||
|
||||
## 二、`match_rule_configs` 是**未接线的规则版本化雏形**(死表)
|
||||
|
||||
- `V006` 建 `match_rule_configs`(version/status/10 权重/`minimum_score DEFAULT 60`),`MatchRuleConfigMapper.findActive/findByVersion` **无任何调用方**。
|
||||
- 真实规则版本化本轮走轻量路线:`recommendation_records.rule_version` + 新列 `threshold_snapshot`(V050)+ `match.rule-version`。
|
||||
- **处置**:登记为未来项 —— 要么把 `match_rule_configs` 接成「规则版本唯一读取源」(配合 open-questions 的 10 维权重配置化),要么删除该死表。本轮未动(避免越界)。
|
||||
|
||||
## 三、本轮已消除的 key/类漂移
|
||||
|
||||
| 漂移 | 处置 |
|
||||
|------|------|
|
||||
| seed `livenessVerification.enabled` vs 活键 `livenessEnabled`(双 key 同义) | 已删 seed 行;canonical `identity.liveness.enabled` 映射到唯一实现键 `livenessEnabled`(见 config-register)。 |
|
||||
| `shared/config/MatchConfig` 与 `match/config/MatchRuleConfigProperties` 同前缀 `match` 双 bean(前者 0 业务引用) | 已删死类 `MatchConfig`,统一读 `MatchRuleConfigProperties`。 |
|
||||
| 前端 `mergeAppConfig` 平铺合并 → 服务端嵌套 `businessLimits.maxProfilePhotos` 等**从不生效**(前端 6 写死、后端也不强校验) | 已修前端显式节-键映射 + 后端 `ProfilePolicy` 强校验 + `/app/config` 读 `ProfilePolicy`。前后端现共用同一配置源。 |
|
||||
| 活体开关「假开关」(`livenessEnabled` 无业务强制点,0 读取点) | 已建 `IdentityPolicy` + `GET /verification/liveness-status` 真实判定点,开关开则 `enhancedVerified` 变化(FF-LIVENESS-002)。 |
|
||||
|
||||
## 四、剩余待登记漂移(未来项,勿本轮扩大)
|
||||
|
||||
| 项 | 说明 |
|
||||
|----|------|
|
||||
| `AppController` 剩余硬编码(dailyRecommendationLimit / maxInterestTags / selfIntroMaxLength / recommendationCooldownDays / reviewConfig / features) | 与 `MatchRuleConfigProperties` / 各配置源各写一份;待统一为「读配置源 + 经 `/app/config` 下发」(见 hardcoded-rule-audit 第二节)。 |
|
||||
| 前端 `BUSINESS_LIMITS` 本地默认值 vs 服务端 | `maxProfilePhotos` 已打通;`DAILY_RECOMMENDATION_LIMIT / MAX_INTEREST_TAGS` 等仍为本地 fallback,服务端值经 `/app/config` 下发后应全部以服务端为准(前端只作失败兜底)。 |
|
||||
| 打分公式占位(0.6/0.4、80/60、恒 50.0) | 非漂移,属 V1 占位未产品化;正式化时随规则版本一起配置化。 |
|
||||
|
||||
---
|
||||
|
||||
*结论:本轮消除了文档点名的 4 类漂移(liveness 双 key、MatchConfig 重复、前后端照片上限失同步、活体假开关)。
|
||||
`system_configs` 死表、`match_rule_configs` 死表、AppController 剩余硬编码为已登记的未来项。*
|
||||
@@ -0,0 +1,55 @@
|
||||
# 配置登记表 — 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` | `features.livenessEnabled`(flag 字段 `livenessEnabled`;yml `features.liveness-enabled`) | CONFIG / TBD | `false` | 否 | 是 | `FeatureFlagConfig` + `IdentityPolicy`;**活体不是 V1 强制规则**;默认关闭不阻断实名主流程;打开后经 `GET /verification/liveness-status` 真实驱动 `enhancedVerified`(FF-LIVENESS-002)。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`(两套 key 同义) | **已删** `demo-seed-final.sql` 的死 seed 行;canonical 名 `identity.liveness.enabled` 映射到唯一实现键 `livenessEnabled`(见上表)。 |
|
||||
| `MatchConfig`(`shared/config`)与 `MatchRuleConfigProperties`(`match/config`)同前缀 `match` 双 bean | **已删** 死类 `MatchConfig`(0 业务引用),统一读 `MatchRuleConfigProperties`。 |
|
||||
| 前端 `mergeAppConfig` 平铺合并 → 服务端嵌套 `businessLimits.*` 从不生效 | **已修** 显式节-键映射,`maxProfilePhotos` 等真正下发到前端。 |
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2026-09-20 — V1.0.1 配置与规则纠偏:登记 identity.liveness.enabled / profile.photo.maxCount / matching.recommendation.minScore 三项 canonical 键,消除 liveness 双 key 与 MatchConfig 重复。*
|
||||
@@ -0,0 +1,43 @@
|
||||
# 决策登记表 — decision-register.md
|
||||
|
||||
> **版本**:V1.0.1 配置与规则纠偏基线 · **生效**:2026-09-20 · **owner**:产品负责人
|
||||
> **只登记产品负责人已正式确认的决策**(LOCKED / 已确认默认)。未确认项一律在
|
||||
> `open-questions.md`,**不得**出现在本表(消解 PENDING「同一事项既待确认又已确认」矛盾)。
|
||||
> 确认值同步记入 `config-register.md` 的「产品正式确认」列。
|
||||
|
||||
---
|
||||
|
||||
## 已确认决策
|
||||
|
||||
| 类别 | 确认项 | 分类 | 代码载体 / 备注 |
|
||||
|------|--------|:---:|----------------|
|
||||
| 品牌 | 善缘丹阳品牌正式启用 | LOCKED | 品牌资源统一走 `admin-web/src/brand.ts` 的 `BASE_URL` 拼接 |
|
||||
| 首页 | Banner 运营 + 8 个核心入口 + 固定顺序 | LOCKED | INV-017 顺序固定,运营不可重排;Banner 仅内部跳转(INV-016) |
|
||||
| 数据保留 | **注销后用户数据保留不得低于 36 个月**(2026-09-19 产品确认) | LOCKED | `account.data-retention-months`(默认 36);到期人工审核匿名化清除(V049 `users.closed_at` + `DataRetentionService` + `account.retention.purge`);隐私政策 §3.3 / PIA §8 已修订 |
|
||||
| 服务站 | 万善公园婚姻登记处为固定阵地 | LOCKED | `service_locations` 种子数据 |
|
||||
| 服务 | 婚恋咨询 + 婚前辅导进入 V1.1 首发 | LOCKED | counseling / premarital 模块 |
|
||||
| 内容 | 婚恋课堂 + 婚恋反诈进入 V1.1 首发 | LOCKED | content 模块 |
|
||||
| 活动 | 多类型公益活动 + 活动双向沟通确认进入 V1.1 首发 | LOCKED | 二阶段同意(INV-014/015) |
|
||||
| 核心规则 | Required 不可放宽 / Mutual 后才 Chat / Block 优先 | LOCKED | 匹配/聊天不变量 |
|
||||
| 推荐 | 每日 6 人 / Pass 冷却 180 天 | LOCKED | `match.default-daily-limit=6`、`match.default-cooldown-days=180` |
|
||||
| 资料 | 兴趣标签上限 8 个 / 自我介绍 500 字符 | LOCKED | 前端常量 + 后端校验 |
|
||||
| 隐私 | Privacy 默认全 TRUE | LOCKED | `user_privacy_settings` |
|
||||
| 活动规则 | 需审核 / 男女名额独立配置 / 互选最大 3 人 / 截止后 48 小时 | LOCKED | activity 模块 |
|
||||
| 关系状态 | searching / getting_to_know / paused / matched_successfully / service_exited | LOCKED | 关系状态枚举 |
|
||||
| 推荐重置 | 每日 00:00 Asia/Shanghai | LOCKED | 时区统一 Asia/Shanghai |
|
||||
|
||||
---
|
||||
|
||||
## 明确「非」已确认(防止误登记,OQ 见 open-questions.md)
|
||||
|
||||
| 事项 | 正确定位 | 参见 |
|
||||
|------|----------|------|
|
||||
| 照片上限 6 | **技术默认,未产品确认**(OQ-PROFILE-001) | open-questions |
|
||||
| 推荐阈值 60 | **技术默认,未产品确认**(OQ-MATCH-001) | open-questions |
|
||||
| 活体核验强制 | **V1.1 首发不强制**,Flag 默认关(OQ-IDENTITY-001) | open-questions |
|
||||
| Banner 最大活跃数量 | **未定 + 代码未实现**(OQ-BANNER-001,真缺口) | open-questions |
|
||||
| 有效匹配报送口径 | **PROVISIONAL,未产品裁决**(OQ-ANALYTICS-001) | open-questions |
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2026-09-20 — 登记 15 项已确认决策;照片 6 / 阈值 60 / 活体 / Banner / 报送口径 明确划为非确认项,转入 open-questions。*
|
||||
@@ -0,0 +1,45 @@
|
||||
# 硬编码规则审计 — hardcoded-rule-audit.md
|
||||
|
||||
> **版本**:V1.0.1 配置与规则纠偏 · **日期**:2026-09-20 · **扫描**:业务代码数值/常量 + `MAX_/LIMIT_/THRESHOLD_/COOLDOWN_/TIMEOUT_/COUNT_/SCORE_`
|
||||
> **定级**:LOCKED(产品确认)/ DEFAULT(技术默认)/ CONFIG(应配置化)/ TBD(未确认)/ FUTURE(非 V1 范围)
|
||||
> **判定原则**:未确认数量参数不得作为固定业务常量写死(AGENTS.md #12);必须存在运行初值时,定义为 `DEFAULT + CONFIG` 并登记 `config-register.md`。
|
||||
|
||||
---
|
||||
|
||||
## 一、已配置化且被真实读取(本轮/历史已合规)
|
||||
|
||||
| 规则 | 载体 | 值 | 定级 |
|
||||
|------|------|----|------|
|
||||
| 每日推荐上限 | `MatchRuleConfigProperties.defaultDailyLimit`(yml `match.default-daily-limit`) | 6 | LOCKED(已确认每日 6 人) |
|
||||
| Pass 冷却天数 | `match.default-cooldown-days` | 180 | LOCKED(已确认) |
|
||||
| 推荐最低阈值 | `match.default-score-threshold` → `MatchingPolicy` | 60 | CONFIG / **TBD**(技术默认,未确认,OQ-MATCH-001) |
|
||||
| 匹配规则版本 | `match.rule-version` | 1 | CONFIG |
|
||||
| 10 维推荐权重 | `match.*-weight` | age15/region15/… | CONFIG / TBD(yml 未覆盖,全用类内默认) |
|
||||
| 照片上限 | `profile.photo.max-count` → `ProfilePolicy` | 6 | CONFIG / **TBD**(技术默认,未确认,OQ-PROFILE-001;服务器端强校验) |
|
||||
| 注销保留期 | `account.data-retention-months` | 36 | LOCKED(2026-09-19 产品确认) |
|
||||
| 本地资格佐证参数 | `features.localEvidence*`(保留 365 天/5 文件/10MB/jpg,png) | 见左 | CONFIG(保留期 LEGAL_VERIFY,OQ-LOCAL-ELIG-001) |
|
||||
| 活体开关 | `features.livenessEnabled/livenessProvider` → `IdentityPolicy` | false / none | CONFIG / TBD(OQ-IDENTITY-001) |
|
||||
| 幂等 TTL | `idempotency_records`(默认 86400s) | 86400s | CONFIG / LEGAL_VERIFY(第三方分级待定) |
|
||||
|
||||
## 二、仍为硬编码 —— 本轮**未纳入**,登记为「待统一」未来项
|
||||
|
||||
> 本轮按约束 12 只纠偏文档点名的 3 项(活体键 / 照片上限 / 推荐阈值)。以下为同族但**未动**,避免越界:
|
||||
|
||||
| 位置 | 硬编码 | 建议 |
|
||||
|------|--------|------|
|
||||
| `AppController` `/app/config` | `dailyRecommendationLimit=6`、`maxInterestTags=8`、`selfIntroMaxLength=500`、`recommendationCooldownDays=180`、`reviewConfig{autoApproveAfterDays=7,maxResubmitCount=3}`、`features` 全 true | 统一改读 `MatchRuleConfigProperties` / 对应配置,前端经 `/app/config` 下发;值确认后转 LOCKED |
|
||||
| `RecommendationEngineService` / `MatchEligibilityService` | 互选公式系数 `0.6*min + 0.4*avg`(:230/:122)、level 分档 `>=80 high / >=60 medium`(:392-396/:262-266)、`calculateScore` 恒返回 `50.0`(V1 占位) | **打分是 V1 占位**,公式/分档/系数尚未产品化;正式化时一并配置化 + 记入规则版本 |
|
||||
| `PhotoService` | 图片大小上限 10MB、签名 URL 24h、上传凭证 1h(`SIGNED_URL_EXPIRE_HOURS`) | 属对象存储/S3 参数,非业务规则;如需可调再配置化(低优先级) |
|
||||
|
||||
## 三、常量类扫描(非业务数值,多为校验/分页,合规)
|
||||
|
||||
| 常量 | 说明 |
|
||||
|------|------|
|
||||
| `MAX_LENGTH`(42 处) | 字段长度校验上限,属校验约束,非「未确认业务数量」 |
|
||||
| `MAX_PAGE_SIZE` / `MAX_VALUE` / `MAX_PER_MINUTE*` / `MAX_LOGIN_ATTEMPTS` | 分页/速率/登录防爆破,合理技术上限 |
|
||||
| `PHOTO_LIMIT_EXCEEDED`(本轮新增业务码) | 照片超限业务错误码,非数值 |
|
||||
|
||||
---
|
||||
|
||||
*结论:本轮已将文档点名的 3 项(活体键、照片上限、推荐阈值)落实为「配置源唯一 + 真实读取 + 默认值受控」。
|
||||
上表第二节为同族未动项,建议在后续 Phase 按同一纪律统一(勿一次性扩大重构)。*
|
||||
@@ -0,0 +1,76 @@
|
||||
# 开放问题 — open-questions.md
|
||||
|
||||
> **版本**:V1.0.1 配置与规则纠偏基线 · **生效**:2026-09-20 · **owner**:产品负责人
|
||||
> 未决项在此登记;**产品正式确认后**移入 `decision-register.md`,并同步更新
|
||||
> `config-register.md` 的「产品正式确认」列与 `PENDING_DECISIONS.md`。
|
||||
> 状态:`TBD`(待产品裁决)/ `IN_PROGRESS` / `RESOLVED`。
|
||||
|
||||
---
|
||||
|
||||
## OQ-IDENTITY-001 · 是否在正式运营阶段启用人脸/活体核验?
|
||||
|
||||
- **状态**:TBD
|
||||
- **当前技术默认**:`identity.liveness.enabled = false`(`features.livenessEnabled`),provider = `none`
|
||||
- **说明**:活体**不是 V1.1 首发强制规则**。默认关闭时不得阻断实名主流程、不得误提示「必须人脸」。
|
||||
本轮已把开关接到真实业务判定点(`GET /verification/liveness-status` → `enhancedVerified`),
|
||||
消除「假开关」。是否启用、选用哪家合规第三方 Provider(`OQ` 选型未定)由产品/合规裁决。
|
||||
- **关联**:`IdentityPolicy`、`UserIdentity.livenessVerificationStatus`、V016。
|
||||
|
||||
## OQ-PROFILE-001 · 用户最多可上传多少张个人照片?
|
||||
|
||||
- **状态**:TBD
|
||||
- **当前技术默认**:`profile.photo.maxCount = 6`(头像 + 生活照合计)
|
||||
- **说明**:6 仅作为技术默认值,**必须保持配置化**(已配置化 + 服务器端强校验 + 并发安全)。
|
||||
不得写死;产品确认正式值后改配置即可,无需改代码。
|
||||
- **关联**:`ProfileProperties` / `ProfilePolicy` / `PhotoService.ensureWithinPhotoLimit`。
|
||||
|
||||
## OQ-MATCH-001 · 推荐最低评分阈值最终采用多少?
|
||||
|
||||
- **状态**:TBD
|
||||
- **当前技术默认**:`matching.recommendation.minScore = 60`(`match.default-score-threshold`)
|
||||
- **说明**:60 **不代表产品正式确认**。阈值已配置化;推荐记录自 V050 起携带
|
||||
`threshold_snapshot` + `rule_version`,未来 60→65 可追溯历史推荐依据。
|
||||
前端不得把 score/threshold 包装为「匹配成功率 / 合适概率」等对外承诺。
|
||||
- **关联**:`MatchRuleConfigProperties` / `MatchingPolicy` / V050。
|
||||
|
||||
## OQ-LOCAL-ELIG-001 · 本地资格佐证文件保留期限?
|
||||
|
||||
- **状态**:TBD(需合规审核)
|
||||
- **当前技术默认**:`features.localEvidenceRetentionDays = 365`(可配置,非永久)
|
||||
- **说明**:与「注销后 36 个月数据保留」(LOCKED)是**两套独立机制**。
|
||||
配套清理作业尚未实现(已挂 Phase 22 运维任务,Phase-04 报告 :46 登记)。
|
||||
|
||||
## OQ-SERVICE-LOC-001 · 善缘服务站正式开放时间?
|
||||
|
||||
- **状态**:TBD
|
||||
- **当前实现**:`service_locations.opening_hours_text` 自由文本(数据驱动、非硬编码),
|
||||
种子值「周一至周五 9:00-17:00 / 周六 9:00-12:00」。属产品文案决策,挂起不动代码。
|
||||
|
||||
## OQ-COUNSEL-001 · 咨询人员实际资质要求 / 预约时段规则?
|
||||
|
||||
- **状态**:TBD
|
||||
- **当前实现**:代码中**无资质字段/校验**(现状即「无资质要求」安全默认);预约时段为自由输入
|
||||
+ 运营手工确认(无自动时段校验,不违反 AGENTS #12)。未来需资质/自动时段才需产品出规则并配置化。
|
||||
|
||||
## OQ-BANNER-001 · Banner 最大活跃数量?
|
||||
|
||||
- **状态**:TBD(**真缺口**)
|
||||
- **当前实现**:代码**无**该限制,仅 demo seed 里一个从未被读取的死值 `banner.maxActiveCount='5'`
|
||||
(`system_configs` 为死表,0 个 Java 读取点)。需产品定值后**实现** active-count 校验。
|
||||
|
||||
## OQ-ANALYTICS-001 · 有效交友匹配正式报送口径?
|
||||
|
||||
- **状态**:TBD
|
||||
- **当前实现**:`match.effective` 为 `PROVISIONAL` 保守近似(`min(有真人消息会话, Match 总数)`),
|
||||
文档已标「禁止对外」。建议口径(Mutual Match + Two-Way Chat)未实现;升 `OFFICIAL` 前需产品裁决。
|
||||
|
||||
## OQ-THIRD-PARTY-* · 第三方开放 / 平台化遗留(7 项)
|
||||
|
||||
- **状态**:TBD(范围扩张,需产品决策,本轮未擅自实施)
|
||||
- 详见 `PENDING_DECISIONS.md`「第三方开放 / 平台化遗留待决策项」:第三方凭据机制、限流是否真实生效、
|
||||
OpenAPI 对外发布面、`POST /activities/{id}/interests` 语义、第三方调用审计与配额计量、
|
||||
敏感字段脱敏边界(第三方场景)、幂等键 TTL 是否按调用方分级。
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2026-09-20 — 登记 OQ-IDENTITY/PROFILE/MATCH-001 及本地资格保留期、服务站时间、咨询资质、Banner 数量、报送口径、第三方开放遗留。*
|
||||
Reference in New Issue
Block a user