Files
danyang-match/AGENTS.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

212 lines
12 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.
# 善缘丹阳 V1.1 - AGENTS.md
> 本文件为项目最高执行规则摘要,WorkBuddy 每次启动时必须首先阅读。
> 版本:V1.1 | 最后更新:2026-09-16 | 基线:v1.0.0-RC.2
---
# V1.1 客户修订文档共同基线
以下文件共同构成当前 V1.1 需求,不得只读取其中一份:
1. `docs/善缘丹阳 V1.1 WorkBuddy最终主启动提示词(整合版).md`:执行纪律、产品红线、不变量和阶段门禁;
2. `docs/善缘丹阳 V1.1 页面级功能清单与交互流程修订版.md`:页面、功能、状态和用户路径;
3. `docs/superpowers/specs/2026-09-13-reference-driven-dual-client-ui-redesign-design.md`:当前唯一 UI 视觉、组件、响应式和前端验收基线;
4. `docs/善缘丹阳 V1.1 数据库与API增量设计.md`:数据模型、API、事务、幂等和权限契约;
5. `docs/善缘丹阳 V1.1 WorkBuddy 开发执行计划修订版.md`:Phase 顺序和增量实施策略;
6. `docs/善缘丹阳 V1.1 WorkBuddy-Jira 最终开发任务增量清单.md`:任务粒度、依赖和验收条件。
冲突时先服从用户最新明确指令,再由上述文件各自在其专业域内裁决。文档中的“已完成、已部署、✅”是历史进度声明,不是需求本身;只有当前代码、测试和人工验收可以证明完成。
V1.1 是 V1.0 的增量升级。正确的 V1.0 核心按 KEEP 处理,不得因为重新审查而推倒重写;错误首页和活动互选规则必须替换,新增业务按 EXTEND / REFACTOR / REPLACE / ADD 执行。
业务 Phase 唯一执行计划:`docs/善缘丹阳 V1.1 客户需求基线增量开发与修复计划.md`。
当前 UI 重设计唯一总计划:`docs/superpowers/plans/2026-09-13-reference-driven-dual-client-ui-redesign.md`。首批范围(小程序 11 个核心页面 + 管理端框架/工作台)已于 **2026-09-16 通过用户验收(结论:基本达标)**,此前"视觉否决 / REOPENED"的判定随之关闭,UI 契约门禁 **18/18** 全绿(2026-09-16 时为 13 项,此后新增端口与 `/admin/` 子路径一致性门禁;2026-09-19 连补 4 项 —— 第 15 项 **WXML 结构守卫**:此前全绿时小程序实际有两个页面 `service-history` / `service-program` 因多一个 `</view>` **编译失败**;第 16 项 **私有方法调用守卫**:`this._x()` 无定义会抛 TypeError,且该调用位于 `resolve` 之前时会让**所有请求**的 Promise 永不 settle;第 17 项 **组件 WXSS 选择器守卫**;第 18 项 **api.js 请求层行为契约**(桩掉 `wx.request` 真跑)。前三项说明既有门禁全是源码内容断言、没有一条会解析 WXML/WXSS 或符号)。管理端桌面端目视复验仍待用户执行。
---
# 不可改变的核心规则
以下规则继承自 V1.0 核心规则,并扩展至 V1.1 新增业务。
## 用户基础规则(继承 V1.0)
1. **用户永久免费** — 禁止任何 VIP/会员/金币/付费功能
2. **Required 不可自动放宽** — 用户"必须符合"的择偶条件是 Hard Constraint
3. **Mutual Match 后才能聊天** — 陌生人不能私信
4. **Block 优先级最高** — 拉黑后聊天停止、推荐排除、搜索不可见
5. **红娘不可替用户操作** — 只能辅助推荐,不能代 Like
6. **活动单向意向保密** — A 选 B 但 B 没选 → B 不知道
7. **普通工作人员不能查看私人聊天** — 仅案件上下文可有限访问
8. **敏感数据默认拒绝** — 身份证/手机号需特殊权限 + 审计
9. **PostgreSQL 是 Source of Truth** — Redis/前端 Store 不可覆盖 DB
10. **使用模块化单体** — 暂不引入微服务/Kubernetes/Kafka
11. **V1 不引入微服务/K8s** — 仅在后述必要性明确时再考虑
12. **所有未确认数量参数配置化** — 不得硬编码业务常量
13. **新功能不得擅自扩大 V1 范围** — 遵循 Phase 顺序开发
## V1.1 新增硬规则
14. **首页 V1.1 结构固定** — 顶部品牌 + 用户状态 + Banner + 8个核心入口 + 今日推荐 + 善缘公益服务 + 近期公益活动 + 善缘服务站 + 婚恋课堂 + 安全提醒。顺序不可更改,运营不可重排
15. **首页 8 核心入口固定** — 第一排:找对象/公益红娘/公益活动/婚恋咨询;第二排:婚恋课堂/婚前辅导/婚恋反诈/善缘服务站
16. **Banner 仅内部跳转** — 不支持外部 URL 跳转,target_type 仅限 activity/matchmaker/counseling/premarital/service_location/article/internal_page/none
17. **本地资格与实名认证分离** — 本地资格(丹阳户籍/工作/居住)独立于实名认证,不得塞入 user_identities 字段
18. **活动互选二阶段同意** — Activity Mutual Interest 不能直接创建 Match/Chat。必须经过:互选结果 → 双方分别确认开启沟通 → 才创建 Match Episode
19. **活动 Mutual 已有 Match 则复用** — 如果双方已有 active Match,活动互选确认后不创建新 Match,直接引导已有聊天
20. **活动 Mutual 曾 Unmatch 则新建** — 如果双方以前已 Unmatch,本次重新形成沟通时创建新 Match Episode
21. **咨询与红娘业务边界分离** — 婚恋咨询不得塞进红娘 Notes,两者权限、数据范围、服务记录必须分离
22. **Counselor 只能访问 Assigned Service** — 咨询人员默认只看到明确分配给自己的服务,不浏览全平台
23. **Content Editor 零用户数据权限** — 内容编辑员默认无用户婚恋数据访问权限
24. **Service Station Operator 不可浏览全用户库** — 服务站人员只能处理现场预约和指定任务
25. **主办单位关系不自动授予数据权限** — Organization relationship ≠ 用户数据访问权限,权限由 Role+Permission+DataScope 控制
26. **前端 Capability 控制入口** — 用户端各功能入口可见性由服务端 CapabilityService 返回决定,前端不自行拼状态判断
27. **配置与规则治理(V1.0.1 纠偏基线)** — 技术默认值 ≠ 产品正式确认规则。所有未经产品确认的数量/阈值/时间/比例/权重/容量/开关/冷却期,一律按「`DEFAULT + CONFIG`」管理:可配置化(`@ConfigurationProperties`/Feature Flag)、**不得**作为 `LOCKED` 业务规则写死;每个配置有唯一 canonical key,登记 `docs/governance/config-register.md`,未确认项登记 `docs/governance/open-questions.md`,已确认项才入 `docs/governance/decision-register.md`。涉及并发的上限必须有服务器端强校验 + 并发突破测试。详见 `docs/governance/`(config-register / open-questions / decision-register / hardcoded-rule-audit / config-drift-audit)。
---
# 产品定位
面向丹阳市成年单身人士,由公益组织参与运营,集实名认证、本地资格核验、人工资料审核、双向婚恋匹配、安全沟通、公益红娘、线下公益活动、固定服务阵地、婚恋咨询、婚前辅导、婚恋课堂、婚恋反诈和婚俗新风于一体的本地公益婚恋综合服务平台。
---
# 技术栈
- Backend: Java 21 + Spring Boot 3.x + PostgreSQL + Redis + WebSocket + Flyway + S3-Compatible Private Object Storage
- Miniapp: 微信小程序原生 + TypeScript
- Admin Web: Vue 3 + TypeScript + Vite + Pinia + Element Plus
- Deployment: Docker + Docker Compose + Nginx
---
# API 规范
- Base URL: `/api/v1`
- 统一响应: `{ success, code, message, data }`
- 认证: `Authorization: Bearer <token>`
- 幂等: 关键接口支持 `Idempotency-Key`
- 新增 V1.1 聚合接口: `GET /api/v1/home`(HomeApplicationService 聚合)
---
# 核心 Invariant(V1.0 + V1.1)
## V1.0 不变量
- 未 Mutual 不可聊天
- Required 不可自动放宽
- Block 即时禁止互动
- 工作人员不能替用户 Like
- 成功牵手必须双确认
- 单向活动意向不泄露
- 敏感身份默认脱敏
- 跨组织默认拒绝
## V1.1 新增不变量
- INV-011: 未授权不能查看本地资格佐证
- INV-012: Counselor 只能读取 Assigned Service
- INV-013: Matchmaker 不能读取 Counseling 正文
- INV-014: Activity Mutual 不能直接创建 Match
- INV-015: 双方确认后才创建 Activity Match
- INV-016: Banner 不能任意外链
- INV-017: 首页 8 核心入口顺序固定
- INV-018: ServiceStationOperator 不能浏览全用户库
- INV-019: ContentEditor 不能访问用户婚恋档案
- INV-020: Sponsor 组织关系不自动赋予用户访问权限
---
# 新增领域模块
V1.1 在 V1.0 基础上新增以下领域模块:
```
banner/ — HomeBanner 管理
service_location/ — 善缘服务站
appointment/ — 服务预约
counseling/ — 婚恋咨询与婚前辅导
content/ — 婚恋课堂/反诈内容管理
service_program/ — 专项公益服务项目
local_eligibility/ — 本地资格核验
home/ — 首页聚合 API
```
---
# 新增 Operator 角色
```
service_station_operator — 服务站运营人员
counselor — 婚恋咨询人员
counseling_manager — 咨询管理人员
content_editor — 内容编辑员
```
---
# 开发流程
每阶段必须:
```
读取本阶段规则 → 确认数据模型 → 建立测试 → 实现后端 → 实现前端 → 运行测试 → 验证核心流程 → 更新文档 → 进入下阶段
```
Phase 完成后必须输出 Completion Report,不得自动进入下一阶段。
---
# 版本控制约定(本机环境强制,务必先读)
## 分支命名:禁止使用带 `/` 的嵌套名
本机存在一个**常驻监听进程**,会**即时(< 0.2 秒)删除 `refs/heads/` 下的嵌套子目录**。
2026-09-16 定向实验结果:
| ref 位置 | 结果 |
|---|---|
| `refs/heads/<单段名>`(如 `feat-ui-v11`) | **存活**(连续观测 30s 稳定) |
| `refs/heads/<任意>/<子名>`(嵌套) | **0.2s 内被删除**(连父目录一起) |
| `refs/tags/<任意深度>` | **存活** |
| `.git/` 下非 refs 的普通子目录 | **存活** |
**后果**:分支指针被删后 **HEAD 会悬空**(`ref: refs/heads/<被删分支>`)。此时
任何 `git commit` 会生成**根提交**,切断全部历史;`git status` 还会把全仓库文件标成新增。
**因此标准 Git Flow 的 `feature/`、`fix/`、`ui/` 等带斜杠前缀在本仓库一律不可用**,
必须使用**顶层单段名**(如 `feat-ui-v11`、`ui-acceptance`)。
## 提交后自保(本机环境必做)
```bash
git tag <name> <sha> # tag 不受清理影响,让提交变为可达,免被 gc 回收
git bundle create <file>.bundle <tag-name> # 参数必须是 ref 名;传裸 sha 会报 empty bundle
sleep 2 && ls .git/refs/heads/ && git log --oneline -1 # 回读验证,别信退出码
```
- `git update-ref` **返回退出码 0 不代表持久化成功**,必须回读验证。
- 判断是否有并发进程**不能看 reflog 署名**:本仓库 `git config user.name` 是一个与真实执行工具无关的固定占位值,
所有 reflog 条目都署名同一个名字,与该条目实际由谁产生无关。
- 若发现 HEAD 悬空(`git log` 报 `does not have any commits yet`),按以下方式恢复,
**不要触碰任何工作区文件**:
```bash
git symbolic-ref HEAD refs/heads/<顶层单段分支>
git reset -q # 仅同步索引,不改工作区
git status --short # 应干净
```
---
# 文档
- 主启动提示词: `docs/善缘丹阳 V1.1 WorkBuddy最终主启动提示词(整合版).md`
- Jira 任务清单: `docs/善缘丹阳 V1.1 WorkBuddy-Jira 最终开发任务增量清单.md`
- 开发执行计划: `docs/善缘丹阳 V1.1 WorkBuddy 开发执行计划修订版.md`
- 数据库/API设计: `docs/善缘丹阳 V1.1 数据库与API增量设计.md`
- 前端 UI/UX: `docs/superpowers/specs/2026-09-13-reference-driven-dual-client-ui-redesign-design.md`
- 页面级功能: `docs/善缘丹阳 V1.1 页面级功能清单与交互流程修订版.md`
- 状态跟踪: `docs/STATUS.md`
- 待确认项: `docs/PENDING_DECISIONS.md`
- 任务清单: `docs/JIRA_BACKLOG.md`
- 版本基线: `docs/ARCHITECTURE_BASELINE_V1.1.md`