Codex
e4af367609
docs(brand): 补提交遗漏文件 —— 部署架构运维文档的 Codex 署名
...
上一提交 60eeb8a 的 staging 通配符未覆盖根目录这份文件名以「部」开头的文档,
其 11 处 Codex 署名(生成者/执行者标注)已是 WorkBuddy,但未入库。本次补齐。
2026-09-16 14:38:05 +08:00
Codex
60eeb8aef5
docs(brand): 全仓库 Codex 署名统一为 WorkBuddy + 5 个文件重命名
...
## 背景
用户指令:「先将 codex 的任务一并改为 workbuddy 的任务」。
Codex 已不再运行,当前由 WorkBuddy 承担开发执行,文档署名需同步。
## 判定规则(用大小写精确区分)
| 类别 | 写法 | 处置 |
|---|---|---|
| 工具署名 | 大写 Codex | → WorkBuddy |
| 分支名 | codex/ui-v11-fidelity | → workbuddy-ui-v11-fidelity(去斜杠,规避本仓库 ref 清理) |
| 已删除文件的历史路径 | 小写 2026-09-11-codex-baseline-cleanup* | 保持原样(记录真实曾存在的文件名,改了即失真) |
结果:26 个文件、126 处署名替换。残留小写 codex 仅 8 处,全部是历史路径。
## 文件重命名(git mv,保留历史)
- Codex开发执行总指令、项目规则与任务拆解.md → WorkBuddy 同名
- Codex首轮启动提示词 + Phase 01~Phase 26 Jira级任务清单 + 每阶段验收条件.md → WorkBuddy 同名
- docs/善缘丹阳 V1.1 Codex 开发执行计划修订版.md → docs/善缘丹阳 V1.1 WorkBuddy 开发执行计划修订版.md
- docs/善缘丹阳 V1.1 Codex-Jira 最终开发任务增量清单.md → docs/善缘丹阳 V1.1 WorkBuddy-Jira 最终开发任务增量清单.md
- docs/善缘丹阳 V1.1 Codex最终主启动提示词(整合版).md → docs/善缘丹阳 V1.1 WorkBuddy最终主启动提示词(整合版).md
引用已同步:AGENTS.md 6 处、AGENTS_SUMMARY.md、以及 4 份计划/规格文档。
## AGENTS.md 两处特别处理
- 「git config user.name = Codex」一句改为不点名工具的表述
- 「feature/ fix/ codex/ ui/ 前缀」示例去掉 codex/
## 有意未改动
- ui-tests/ui-document-baseline-contracts.mjs 的废弃清单仍列 codex-baseline-cleanup*
那是「必须不存在」的断言目标,改了会让哨兵失去意义
- 仓库 git config user.name 仍是 Codex —— 未擅自改动环境身份。
如需彻底交接:git config user.name WorkBuddy && git config user.email workbuddy@local
验证:UI 契约门禁 13/13;AGENTS.md 零 Codex 残留;5 个新文件名与全部引用一致
2026-09-16 14:37:44 +08:00
Codex
6ae08b89fb
docs(agents): 新增「版本控制约定」强制节 + 修正 UI 验收口径
...
## 背景:refs/heads 嵌套分支名被实时清理,导致 HEAD 悬空
提交 bc4531a 后,refs/heads/codex/ui-v11-fidelity 被某个常驻监听进程删除(连 codex/ 目录一起),
HEAD 悬空 → `git log` 报 does not have any commits yet,`git status` 把全仓库文件标成新增。
`git update-ref` 重建返回退出码 0,但 0.2 秒内文件又消失(假成功)。
定向实验(14:06~14:10)定位的真实规则,与最初判断完全不同:
| ref 位置 | 结果 |
|---------------------------------|--------------------------|
| refs/heads/<单段名> | 存活(连续观测 30s 稳定)|
| refs/heads/<任意>/<子名> | 0.2s 内删除(连父目录) |
| refs/tags/<任意深度> | 存活 |
| .git 下非 refs 的普通子目录 | 存活 |
→ 删除器只针对 refs/heads 的子目录,且是事件驱动(0.2s),不是定时轮询(schtasks 无匹配项)。
→ 推论:标准 Git Flow 的 feature/ fix/ codex/ ui/ 前缀在本仓库全部不可用。
## 更正一处此前的错误结论
refs/codex/turn-diffs/checkpoints/... 是 09-11 / 09-14 的存量 ref,不代表有活跃 Codex 进程;
且仓库 git config user.name 本来就是 Codex,故 reflog 中所有条目都署名 Codex
(包括非 Codex 工具产生的提交)→ **reflog 署名不能用来判断是否存在并发进程**。
## 仓库处置
- HEAD 由悬空的 refs/heads/codex/ui-v11-fidelity 改为有效的 refs/heads/main
(symbolic-ref + reset -q,仅同步索引,未触碰任何工作区文件)
- main 由 b8c33b9(09-11)快进至 bc4531a —— 纯快进:main 是 bc4531a 的严格祖先,
`git rev-list --left-right --count main...bc4531a` = 0 58,无分叉、零冲突、零文件变化
- 保留顶层分支 feat-ui-v11 与 tag ui-v11-accepted-and-me-routes 作为冗余锚点
## AGENTS.md 变更
- 新增「版本控制约定(本机环境强制,务必先读)」一节:
分支命名约束(禁用斜杠)、提交后自保清单(tag + bundle + 回读验证)、悬空 HEAD 的恢复方式
- 修正 UI 口径:首批范围(小程序 11 页 + 管理端框架/工作台)已于 2026-09-16 通过用户验收
(基本达标),关闭「视觉否决 / REOPENED」判定;管理端桌面端目视复验仍待用户执行
- 头部日期更新为 2026-09-16
## STATUS.md
- 分支引用由已不存在的 codex/ui-v11-fidelity 改为 main
验证:UI 契约门禁 13/13;工作区 vs bc4531a 差异 0 行
2026-09-16 14:31:26 +08:00
Codex
bc4531a734
feat(api): 补齐 /me/* 命名空间,恢复 17 个 404 调用 + 修 /me/status 过期桩
...
背景:小程序 services/*.js 按 REST 规范(§16 / §22-§40 / §80 / §83-§84)统一调用
/me/*,但后端从未注册 /me 基路径,个人资料、照片、择偶条件、隐私设置、关系状态、
我的举报/申诉等约 17 个调用全部 404。
后端
- 新增 me/controller/MeController:把既有 service 能力暴露到规范路径(纯委托,不复制
业务规则,AGENTS.md #26)。旧路径(/profile/*、/photos、/relationship/*、
/account/privacy-settings、/risk/reports/my、/appeals/my)全部保留。
- 响应形状按小程序 JSDoc 适配(小程序被 86 页引用,是权威契约):
· /me/relationship-status 返回 status(旧 /relationship/status 返回 relationshipStatus,
字段名不同,前端读的是 result.status)
· /me/profile/review-status 返回 {status, items, submittedAt, reviewedAt},时间统一 epoch 毫秒
· /me/profile/submit-review 返回 {reviewStatus, submittedAt}
- 小程序三条历史写法一并兼容:/me/privacy-settings、/me/photos/{id}/main、/me/appeals
修复
- AuthService.getMeStatus:verified / profileStatus / reviewStatus 三项写死为
false / not_started / not_submitted,注释标注"Phase 03/04/05 填充",但那三个 Phase
早已交付,导致 /me/status 长期返回错误的实名与审核状态。改为 capabilityService
+ userProfileMapper + reviewTaskMapper 的真实来源(与首页聚合同一判定)。
- PhotoController.deletePhoto:原用 ((Map<?,?>) p).get("id") 强转 UserPhoto 实体,
必然抛 ClassCastException,删除照片恒定 500。改用实体主键比对。
- PhotoService.setMainAvatar(新增):数据模型以 photo_type='avatar' 标识头像(见
UserPhotoMapper#findAvatar),无 is_main 字段,故"设主图"= 换类型并保证至多一张。
注意:插入该方法时曾把 deletePhoto 原有的 @Transactional 挤到新方法上,导致
"Transactional is not a repeatable annotation" 并引发 Lombok 全面停摆(满屏
找不到 getter/setter),已修正注解归属。
验证
- 后端全量:299 tests / 0 failures / 0 errors / 3 skipped / BUILD SUCCESS(+2 为新增契约测试)
- 新增 MeRouteContractTest(2 例):同时断言 HTTP 方法,锁定 21 条 /me/* 与 13 条旧路径
- 小程序 tsc --noEmit 通过;UI 契约门禁 13/13
文档
- STATUS.md:/me/* 从"待裁决"改为"已完成";核心待清债务 1 项 → 0 项
- API_INVENTORY.md:顶部"待收敛"警告改为"已收敛",补全 /me/* 端点表
2026-09-16 12:54:39 +08:00
Codex
ce172ffd4f
feat(ui): activity 页迁 TS + 修复过期契约 + 新增 11 页静态预览器
...
## 背景
2026-09-13 UI 重设计方案的 13 个契约门禁中 3 个为红,逐一查明性质后分类处理。
## 1. activity 页迁移 TypeScript(11/11 页现已全 TS)
- activity.js → activity.ts(139 行),业务逻辑零改动,仅补类型
- 此前 STATUS.md 记「9/11 TS-only、3 页待迁」,但 messages/matchmaker
已在 4f91be0 迁完,实际只剩 activity 一页,本提交后清零
## 2. miniapp-reference-contracts 契约自身过期(非代码问题)
- 契约引用 messages.js / matchmaker.js / activity.js,但页面已 TS 化,
readFileSync 抛裸 ENOENT 栈,看不出「契约引用了陈旧文件名」这一真实原因
- 改为统一走 readPageLogic(page):断言 .ts 存在 + .js 不存在(锁单一运行源),
找不到文件时给出可读断言而非崩溃
- 核心 11 页循环内统一加 TS-only 校验,防止 JS 回流
## 3. phase07-home-contracts 契约断言架构写反(非代码问题)
- 契约要求 HomeApplicationService 字面出现 userIdentityMapper.findByUserId,
但实际是 capabilityService.isIdentityVerified(userId)(HomeApplicationService:116)
- 这符合 AGENTS.md #26「前端入口可见性由服务端 CapabilityService 返回决定」,
让首页穿透 Capability 直接持有 mapper 反而是架构重复
- 且契约自身另一条已断言 CapabilityService 必须有 isIdentityVerified,
两条要求互相矛盾
- 改为:查库断言落在 caps 侧;首页断言必须委托 capabilityService.isIdentityVerified;
新增 doesNotMatch(home, /userIdentityMapper/) 禁止首页绕过 Capability
- 保留原有 doesNotMatch(home, /setVerified\(true\)/) 防硬编码断言
## 4. 新增 11 页静态预览器(本机无微信开发者工具)
- scripts/preview-miniapp.mjs:把 WXML + WXSS 转成可浏览器打开的静态 HTML
- 能力:wx:if/wx:elif/wx:else 链、wx:for 列表、嵌套三元、比较/取反运算、
自定义组件按属性展开、slot 替换、rpx→px 换算、组件样式收集
- mock 数据严格对齐 types/index.d.ts 与各页 WXML 实际读取字段
(如 regionName/heightCm/educationCode、status: registration_open),
不用想象字段,避免误导验收判断
- 产出 artifacts/ui-redesign/miniapp/preview.html(11 页可切换,284K)
- 明确边界:非真机渲染、不执行页面 JS、不连后端,
只用于视觉走查,不得作为功能验收证据
## 验证
- 契约门禁 12/13 通过(唯一红的 ui-document-baseline-contracts 涉及
STATUS.md 验收口径,待用户看真机效果后裁决,本轮不动)
- 11 页渲染体量:116/70/47/56/94/68/39/39/41/37/38 个类名元素,
零残留 {{}} 插值、零残留原始组件标签
- 小程序 tsc --noEmit 通过
2026-09-16 12:33:48 +08:00
Codex
3244e02e7e
refactor(api): 关系/匹配域采用 2026-09-14 canonical 路径,消除三代并存
...
## 问题:同一能力存在三代路径,前端指向的是已废止的一代
按 mtime 排查后发现"最新"并非上一轮以为的 /relations/*,而是 2026-09-14 的 match 模块:
| 代际 | 位置 | 日期 | 路径 |
|---|---|---|---|
| canonical | platform.match: Like/Block/MatchController | 09-14 12:13~12:14 | /likes /blocks /matches |
| 二代 | platform.relationship: Relationship(Status)Controller | 09-10 10:59 | /relations/* /relationship/* |
| 一代(规范) | REST API 接口详细设计规范.md | 08-28 | /relationships/*(多一个 hips) |
| 前端 | miniapp/services/matchService.js | 08-29 | 混用二代 + 一代 |
后果:缘分三榜、黑名单页、成功牵手流程全部 404;另有两份重复 success 实现 + 一份桩实现。
## 裁决:采用 2026-09-14 最新路径,前端与二代让位(用户指令)
### 补齐 canonical 模块缺口(此前只有 javadoc 声明或服务方法,无控制器)
- RelationService.unlike() + LikeController `DELETE /likes/{targetUserId}`
- 新增 PassController `POST /passes`(RelationService.pass 在 09-14 模块内却无控制器,补齐与 /likes、/blocks 对称)
- BlockController `GET /blocks`(javadoc 早声明"我的 Block 列表"但未实现,mapper findBlockedByUser 已就绪)
- MatchController `POST /matches/{id}/success/request|confirm|decline`(javadoc 标"Phase 12 预留"),
委派真实实现 RelationshipStatusService;authorizedMatch 对"不存在"与"无权"统一回 404,避免探测他人 Match
- LikeResponse 对齐前端 LikeResult:{ relationStatus, mutualMatch, matchedConversationId, matchId }
Mutual 时调 ChatService.getOrCreateConversation 取会话 id → "双向喜欢→跳聊天"链路真正打通
- LikeController/PassController/BlockController 补 targetUserId 空值校验
### 移除被取代的路由与桩实现
- RelationshipController 移除 like/cancelLike/pass/block/unblock/matches/unmatch/success,仅保留 /fate/*
- RelationshipStatusController 移除 /success/*(已由 /matches/{id}/success/* 取代),保留关系状态生命周期
- RelationshipService 删除 requestSuccess/confirmSuccess 桩 ——
前者自述 "TODO: 查询 relationship_success_requests 表" 却返回硬编码 status="pending",
等于绕过 AGENTS 硬规则 6「成功牵手必须双确认」
- 注意:RelationshipService.like/block/pass 被 P0FixVerificationTest /
RelationshipBlockPriorityPhase08Test 直接测试,方法体保留
### 列表信封统一
- CursorPage 从 chat.dto 提升到 shared.dto(消除 match 模块反向依赖 chat DTO)
- /relations/fate/mutual|liked|likers 与 GET /matches 改返回 { items, nextCursor }
### 前端对齐
- matchService.js 全部路径改到 canonical;补 declineSuccess
- matchStore 补 _decorateBlockedList,修复"模板渲染 blockedAtText 但全仓从未计算"的缺陷
(与上一轮 lastMessageAtText 同源,同类字段一律在 store 装饰一次)
### 文档
- docs/api/API_INVENTORY.md 关系/缘分/匹配三节重写为 canonical 路径;
顶部加 /me/* 路径族显式警告(小程序按规范写 /me/*,后端实为 /profile/*、/photos、/relationship/*,
约 15 个端点会 404,收敛方向未裁决,防止后续照抄踩坑)
- docs/STATUS.md:Backend 回归债务由「待清(277 tests 4F/8E)」更新为「已清偿(297 tests 全绿)」
## 验证
- 新增 CanonicalRouteContractTest(3 例):用 RequestMappingHandlerMapping 断言
canonical 路径已注册、被取代的旧路径不再注册、关系状态生命周期保留 —— 路由再漂移即红
- 后端 297 tests, 0 failures, 0 errors, 3 skipped, BUILD SUCCESS
- 小程序 tsc --noEmit 通过
2026-09-15 23:16:27 +08:00
Codex
687a156350
fix(chat): 会话/消息响应契约对齐小程序,修复聊天页字段断链
...
## 问题(三处真实断链)
后端 chat 模块字段名与小程序契约不一致,但自动化测试此前未覆盖,故一直未被发现:
1. 会话 DTO 用 otherUserId/otherDisplayName/otherAvatarUrl,
而前端(types/index.d.ts + pages/chat/chat.ts + components/conversation-item)
只读 targetUserId/targetDisplayName/targetAvatarUrl。
→ chat.ts 取不到对方 userId(无兜底,落到空串),
导致"查看资料 / 拉黑 / 举报"点击后提示"暂无更多信息"并失效。
2. 消息响应只给 createdAt(ISO 字符串),前端读 Message.sentAt: number(epoch 毫秒)。
→ chat.ts 时间分隔 ts 恒为 0,消息时间分隔与时间文案不显示。
3. 会话对象缺 relationStatus,前端 conversation-item 依赖它做灰显与"已拉黑"提示。
## 裁决依据
按"以文件修改时间为准"的裁决统一到前端约定:
- 前端 types/index.d.ts 被 86 个页面引用,是声明式契约
- pages/chat/chat.ts(09-04)是最新的真实消费者
- targetUserId 已是项目内既有惯例(ActivityMatchItemDTO)
- admin-web 不消费 /conversations,无第二方受影响
## 变更
- ConversationDTO:字段改名 target*;新增 relationStatus;lastMessageAt 改 epoch 毫秒
- ChatService.toConversationDTO:同步映射;relationStatus 按 Block > unmatched > mutual_match > neutral 推导
- Constants:新增 RELATION_STATUS_NEUTRAL / MUTUAL_MATCH / UNMATCHED(不硬编码)
- MessageResponse:新增 sentAt(epoch 毫秒)
- miniapp/utils/datetime.js(新增):收敛时间格式化,
补上模板依赖但全仓从未计算的 lastMessageAtText
- messageStore:会话进入 store 时统一装饰 lastMessageAtText
- chat.ts:_formatTime 改为复用共享工具;移除已失效的 otherDisplayName 兜底
## 验证
- 新增 ChatContractJsonTest(4 例)锁定字段名、sentAt 数值类型、
并断言 other*/status 旧字段名不再出现
- 后端 294 tests, 0 failures, 0 errors(原 290 + 新增 4)
- 小程序 tsc --noEmit 通过
遗留(未在本轮处理):平台尚未实现头像 URL 解析(user_photos 只存 fileKey),
targetAvatarUrl 保持 null,前端 ui-avatar 回退昵称首字,不影响展示。
2026-09-15 22:45:46 +08:00
Codex
eaf8fdf195
refactor(backend): P0 阻断修复 + 按最新修改时间收敛重复模块与契约
...
## P0 阻断修复
- 编译:修复实体类与服务类同名导致 Lombok 注解轮次中止的问题
(MatchmakerService/CounselingService -> *Record),196 个编译错误归零
- 权限矩阵:platform_admin 按设计文档收紧为拒绝 5 项高危权限(不改测试阈值)
- 启动:修复 8 组 MyBatis-Plus 同名 bean 冲突(ConflictingBeanDefinition)
与 URL 路由歧义(Ambiguous mapping),应用可正常启动
## 模块收敛(裁决规则:以文件修改时间为准)
- messaging 包整体删除,能力迁移至 chat 包
* 会话列表/详情/未读端点、ConversationDTO、CursorPage
* 消息游标分页统一为 { items, nextCursor }
- relationship 的 Match/UserRelation entity 与 mapper 合并进 match 包
- MatchmakerUserController 合并进 MatchmakerController,删除冗余 Controller
- 补齐 INV-004:chat sendText 增加双向 Block 校验,拉黑后禁止发送
## 契约对齐
- 红娘服务提交请求兼容前端 { requirement } 字段
- 消息与会话分页契约前后端统一
## 测试
- 迁移 6 个风控用例至 ChatSafetyServiceTest
- 清理 messaging 测试包遗留:6 个真实常量断言归位 chat 包,
移除 2 个 assertTrue(true) 占位假测试(Block 真实行为已由
P0FixVerificationTest / RelationshipBlockPriorityPhase08Test 覆盖)
- schema-h2.sql 对齐 PostgreSQL 真实表结构(matches 补列、
conversation_members 改复合主键)
结果:290 tests, 0 failures, 0 errors, 3 skipped, BUILD SUCCESS
2026-09-15 22:29:26 +08:00
Codex
9d73087eb0
feat(admin-web): matchmaker management view — D3 debt cleared
...
New module admin-web/src/modules/matchmaker/MatchmakerManagementView.vue (2 tabs):
- Service request queue: assign operator / create recommendation
- Recommendations list: pending_view / viewed / liked / passed / confirmed_mutual
Route added: /matchmaker -> MatchmakerManagementView.vue (permissions: matchmaker.service.view)
D3 debt cleared: admin-web matchmaker recommendation now has a real view.
vue-tsc --noEmit -> 0 errors.
2026-09-14 15:02:51 +08:00
Codex
4f91be0cab
feat(miniapp): final 3 pages migrated to TypeScript (matchmaker/messages/mine)
...
D1 debt cleared: all 11 miniapp core pages now TS-only.
tsc --noEmit -> 0 errors. JS sources deleted.
2026-09-14 14:59:28 +08:00
Codex
918368159c
feat(phase-13A): CounselingService — INV-012/013 + 婚恋咨询 + 婚前辅导
...
Phase 13A Counseling — ADD new domain module per AGENTS.md rule #21/#22.
counseling module (5 files):
- Entity: CounselingService -> counseling_services
- Entity: CounselingFollowup -> counseling_followups
- Mapper: CounselingServiceMapper (findFull + findSanitized INV-013)
- Service: CounselingService
INV-012: assertAssigned() guards schedule/complete
INV-013: getDetail() returns sanitized for matchmaker/operator,
full for user/assigned-counselor/manager
- Controller: 7 endpoints (user/apply/list/detail, counselor/assigned/schedule/complete, manager/assign)
Permission model (Service layer guarded):
User(self) -> full detail
Assigned Counselor -> full detail
counseling_manager -> full detail
Matchmaker/Operator -> sanitized only (no user_request_summary)
service_type: counseling(婚恋咨询) / premarital(婚前辅导)
2026-09-14 14:51:25 +08:00
Codex
5cbd931fa2
feat(phase-13): MatchmakerService — referral + manual recommendation + user confirmation
...
Phase 13 Matchmaker — EXTEND per JIRA. P13-V11-T01 through P13-V11-T05.
New matchmaker module (5 files):
- Entity: MatchmakerService (request), MatchmakerRecommendation (manual rec)
- Mapper: MatchmakerServiceMapper, MatchmakerRecommendationMapper
- Service: MatchmakerService
T01 createReferral(type=counseling) — referral only, does NOT submit on behalf
T02 createReferral(type=activity)
T03 createReferral(type=service_station)
T04 referral_source追溯: every referral carries operator_id + service_id + type
T05 用户拥有最终决定权: acceptRecommendation() calls RelationService.like()
as the USER, not the matchmaker. Matchmaker NEVER creates Match directly.
If mutual, updates Match.source='matchmaker' for traceability.
- Controller: user endpoints (submit/list/pending-recommendations/accept/pass/viewed)
Core AGENTS.md #5 compliance:
- Matchmaker can only 'recommend', NEVER 'like on behalf of'
- User must actively accept recommendation (calls acceptRecommendation -> RelationService.like)
- createRecommendation creates pending_view record + notification, nothing else
- confirm mutual only when BOTH users independently Like (existing Like flow)
Status machines:
- matchmaker_services: submitted -> assigned -> processing -> completed
- matchmaker_recommendations: pending_view -> viewed -> liked/passed/confirmed_mutual
2026-09-14 14:48:23 +08:00
Codex
0418856ce3
feat(phase-12): RelationshipStageService — home service suggestions
...
Phase 12 Relationship — KEEP/EXTEND per JIRA. 不增加复杂状态.
New RelationshipStageService (match module):
P12-V11-T01 Successful match -> premarital_suggestion
P12-V11-T02 GettingToKnow match -> matchmaker + counseling
P12-V11-T03 7-day silence in GettingToKnow -> counseling_recommendation
Rules are simple, based on existing Match.status + lastActivityAt:
- successful -> 婚前辅导建议
- getting_to_know -> 红娘服务 + 婚恋咨询建议
- getting_to_know + 7d silence -> 婚恋咨询促活建议
- no Match -> 默认红娘 + 婚恋课堂
Integration point: HomeApplicationService.buildRecommendations()
just inject RelationshipStageService and append suggestions to home DTO.
2026-09-14 14:40:13 +08:00
Codex
e2a8a8c85f
feat(phase-11): NotificationService — 10 business templates + privacy-safe external copy
...
Phase 11 Notification — EXTEND per JIRA. P11-V11-T01 through P11-V11-T11.
New notification module (4 files):
- Entity: Notification -> notifications (existing DB table)
- Mapper: findByUser/countUnread/markRead/markAllRead + findExisting(idempotent)
- Service: NotificationService with 10 business templates
T01 appointmentSubmitted T02 appointmentConfirmed T03 appointmentChanged
T04 counselingAssigned T05 counselingScheduled T06 counselingCompleted
T07 premaritalScheduled T08 leNeedEvidence T09 leVerified
T10 leRejected
T11 buildPrivacySafeCopy -> external lock-screen copy NEVER reveals
sensitive counseling type names (INV-010 compliance)
- Controller: GET list, GET unread, PUT markRead/{id}, PUT readAll
Design invariants:
- sendExternal() wrapped in try/catch -> failure does NOT rollback core service
- Idempotency via (user, type, business_type, business_id, content) dedup
- External copy uses neutral words '服务/预约' for counseling events, not '咨询'
2026-09-14 14:33:37 +08:00
Codex
cf3a84e725
feat(phase-10): Chat Safety — content scan + rate limit + RiskNotice
...
Phase 10 Chat Safety — KEEP per JIRA. P10-V11-T01/P10-V11-T02.
New ChatSafetyService (chat module):
- scanContent(): HIGH_RISK keyword + CONTACT regex (phone/wechat/QQ/scan)
- checkRateLimit(): Redis counter + fail-open fallback, stricter for new Match (first 5 min)
- buildRiskNoticeBody(): system message JSON with anti-fraud targetPage
ChatService.sendText() integrated Phase 10:
1. Redis rate limit check (newMatch-aware)
2. Content scan -> risk_level on Message
3. high/critical -> throw, block send
4. warning -> peer gets RiskNotice system message (P10-V11-T01: anti-fraud entry)
(P10-V11-T02: RiskNotice -> anti-fraud content page)
5. Log enriched with risk_level
Constants already had RISK_LEVEL_* and MESSAGE_TYPE_SYSTEM — no new constants needed.
2026-09-14 14:16:47 +08:00
Codex
eda2ce19a8
feat(phase-09): Text Chat full backend + WebSocket
...
Phase 09 Chat — KEEP per JIRA. P09-V11-T01 Activity Match source compatibility.
New chat module (11 files):
- Entity: Conversation, ConversationMember (复合主键), Message
- Mapper: ConversationMapper, ConversationMemberMapper, MessageMapper
- Service: ChatService (getOrCreateConversation/sendText/loadMessages/markAsRead/syncFromMatch)
- Controller: ConversationController (POST /from-match, GET /{id}, GET list)
MessageController (POST send, GET load history, PUT mark read)
- WebSocket: WebSocketConfig + ChatWebSocketHandler (/ws/chat, JSON protocol)
Core invariants:
- INV-005: ChatService requires Match status active/getting_to_know
- Conversation.status sync with Match.status (syncFromMatch)
- Member.canSend + Conversation.status + sender membership all validated
- Client-side idempotency via client_message_id
- P09-V11-T01: Conversation binds only match_id — works identically for
user_like / activity_mutual / matchmaker Match sources
WebSocket note: Memory-based session map; multi-node will need Redis Pub/Sub.
2026-09-14 14:00:04 +08:00
Codex
8b62b5b5df
feat(phase-08): Like / Match / Block full backend implementation
...
Phase 08 Like/Match/Block — KEEP per JIRA, incremental P08-V11-T01.
New entities (match module):
- UserRelation -> user_relations (liked/passed/blocked)
- Match -> matches (source: user_like/activity_mutual/matchmaker, episode-aware)
New mappers:
- UserRelationMapper: findOne/countBlockedEitherWay/countReverseLike
- MatchMapper: findActiveBetween/findLatestBetween/findActiveByUser/findHistoryByUser
New services:
- RelationService: like/pass/block/unblock + mutual detection + capability guard
- INV-004: Block priority highest (auto-unmatch, mutual block check)
- INV-005: Like only creates Match on Mutual
- MatchService (static): createOrReuseMatch factory
- AGENTS.md #19 : existing active Match -> reuse
- AGENTS.md #20 : prior unmatched -> new Match with episode+1
- source-aware: user_like / activity_mutual / matchmaker
New controllers:
- POST /api/v1/likes
- POST /api/v1/blocks, DELETE /api/v1/blocks/{target}
- GET /api/v1/matches, GET /api/v1/matches/{id}, POST /api/v1/matches/{id}/unmatch
Integrates with CapabilityService for base eligibility checks on Like.
2026-09-14 12:15:27 +08:00
Codex
0da82c9914
docs(gate): add phase 4 gate output artifacts
2026-09-14 11:44:02 +08:00
Codex
984827f415
docs: phase 4 acceptance report + STATUS sync
...
- STATUS.md updated: 阶段0-4全部完成, Ready for User Acceptance
- New acceptance report: 三端构建/13契约/源码健康度/债务清单
- CapabilityService independentized (AGENTS.md #26 compliance)
- discover 筛选完整重设计 (5 chip + 4 section + bottom sheet)
- miniapp C组 content/anti-fraud/service-station TS-only
- 三端构建全绿: miniapp tsc=0, admin-web vue-tsc=0, vite build OK
- 13/13 contracts all green
2026-09-14 11:43:46 +08:00
Codex
dd58ab6eae
feat(capability): extract CapabilityService — AGENTS.md rule #26 compliance
...
New module backend/capability/:
- CapabilityService: getCapabilities(entry point for frontend),
plus public helpers (isAccountNormal/isIdentityVerified/isProfileApproved/
isSearching/isBaseEligible/hasLocalEligibility/entry builder)
- CapabilityController: GET /api/v1/capabilities endpoint
HomeApplicationService refactored:
- Injects CapabilityService, delegates buildCapabilities()
and QuickEntry construction + recommendation eligibility checks
- Removes duplicated private methods (isSearching/isIdentityVerified/
isProfileApproved/entry) — single source of truth now in CapabilityService
Contracts updated to check CapabilityService.java for capability-related
assertions (setDisabledReason/isIdentityVerified/ACCOUNT_STATUS_NORMAL)
2026-09-14 11:38:30 +08:00
Codex
22325ec2b0
feat(discover): chip-targeted filter panel — scroll to + highlight target section
...
- Each filter chip (年龄/学历/婚姻) carries data-target pointing to its section
- openFilterPanel receives TouchEvent, maps target to section id, sets panelScrollTo + panelHighlight
- Panel uses scroll-view scroll-into-view with scroll-with-animation for smooth scroll
- Targeted section gets pink outline highlight via .hl class
- Non-targeted sections remain normally visible for context
2026-09-14 11:27:52 +08:00
Codex
adfa4ff31e
fix(discover): filter panel as bottom sheet with mask, add debug log
...
- Changed filter panel from in-flow to fixed bottom drawer with semi-transparent mask
- Mask click closes panel (closeFilterPanel)
- Added console.log in openFilterPanel for debugging event firing
- Panel now z-index:11 above mask z-index:10, guaranteeing visibility
2026-09-14 11:19:25 +08:00
Codex
3e5d2314aa
fix(discover): restore discover-filter-chips class for contract
2026-09-14 11:09:53 +08:00
Codex
146ebab61d
feat(discover): rewrite filter UI to align with backend DiscoverController 5 params
...
- Top chips: 推荐(重置) / 丹阳本地(regionCode=321181) / 年龄 / 学历 / 婚姻
- Each chip has real active state bound to applied filter value
- Panel expanded to 4 sections: age slider + region + education + maritalStatus
- Param names fixed: minAge/maxAge/regionCode/educationCode/maritalStatus
- Data flow: panel temp -> onApplyFilter -> applied -> _buildParams -> API
- Panel opens with current applied values, closes with openFilterPanel/closeFilterPanel
2026-09-14 11:09:23 +08:00
Codex
0f06d82a92
fix(discover): filter chips use applied state and apply immediately on top-chip tap
...
- Top chip '推荐' now active only when no active filter (was hardcoded)
- Top chip '丹阳本地' uses applied.region (was tempRegion)
- Top chip '年龄' uses applied age range
- New onTopRegionTap applies region filter immediately and refreshes results
- Panel onRegionTap preserved for filter-panel multi-select flow
2026-09-14 10:59:43 +08:00
Codex
7009ec079c
fix(miniapp): delete redundant api.ts to avoid build conflict with CommonJS api.js
...
WeChat DevTools TypeScript compilation overwrites the CommonJS api.js
output with the ES-module api.ts compiled output, breaking require()
consumers (authStore.js getToken, authService.js post). The remaining
api.js has the identical ApiClient class plus extra patch() method.
2026-09-14 10:29:15 +08:00
Codex
751f14d5ee
chore: remove obsolete .js sources for migrated C-group pages
2026-09-14 10:14:27 +08:00
Codex
93fc9b0d88
feat(miniapp): migrate C-group pages to TypeScript, update contracts
2026-09-14 10:14:05 +08:00
Codex
e59038790c
docs(status): sync with phase 0 gate results, V035 migration and clean git tree
2026-09-14 10:04:08 +08:00
Codex
fd5f4d6e80
chore: add artifacts/backups to gitignore
2026-09-14 10:02:58 +08:00
Codex
ea2bb2439d
chore: complete infrastructure config, contracts, reference images and ui redesign artifacts
2026-09-14 10:02:34 +08:00
Codex
63cbbff2de
feat: implement miniapp C-group pages with real API calls and design tokens
2026-09-14 10:02:22 +08:00
Codex
bb380d40f6
feat: enhance home aggregate, review atomicity, local eligibility and match engine (phase 04-07)
2026-09-14 10:02:07 +08:00
Codex
10887f40ed
feat: add V034-V035 flyway migrations and phase 04-07 test classes
2026-09-14 10:01:50 +08:00
Codex
0518cda95c
docs: add phase 04-06 recovery reports, gate outputs and execution plan
2026-09-14 10:01:41 +08:00
Codex
1aea6f7791
feat: redesign public relationship services
2026-09-14 08:51:26 +08:00
Codex
a6037ded59
feat: redesign activity and profile tabs
2026-09-14 07:05:20 +08:00
Codex
b7dc52b517
feat: redesign discovery and messages tabs
2026-09-14 06:49:49 +08:00
Codex
36b15d9ca8
feat: rebuild miniapp reference home
2026-09-14 06:45:36 +08:00
Codex
df47543501
feat: add miniapp reference assets and primitives
2026-09-14 06:38:44 +08:00
Codex
311f251609
test: lock miniapp reference page scope
2026-09-14 06:19:11 +08:00
Codex
8b8972a77b
test: verify admin reference UI fidelity
2026-09-13 22:09:15 +08:00
Codex
72b0758e8c
feat: recreate admin dashboard from reference
2026-09-13 21:50:44 +08:00
Codex
fbafe693b6
feat: add admin dashboard data adapter
2026-09-13 21:44:58 +08:00
Codex
9279359678
feat: rebuild admin shell from reference
2026-09-13 21:39:32 +08:00
Codex
ad9d32f544
feat: establish admin reference design foundation
2026-09-13 21:34:43 +08:00
Codex
3a634b4ef2
docs: finalize UI cleanup report
2026-09-13 21:26:30 +08:00
Codex
097c4c4778
chore: finalize miniapp page source cleanup
2026-09-13 21:25:50 +08:00
Codex
61ca737e02
docs: record UI cleanup checkpoint
2026-09-13 21:24:54 +08:00
Codex
eed4400611
refactor: remove duplicate miniapp page sources
2026-09-13 21:19:05 +08:00