chore: remove obsolete project documentation
@@ -1,175 +0,0 @@
|
||||
# M09 VIP 与订单:设计核验
|
||||
|
||||
## 对比对象
|
||||
|
||||
- Source visual truth: `C:\Users\Administrator\.codex\generated_images\019fa647-03b4-7901-9b6a-175d07d56512\exec-f3e0331f-59c3-4f01-a48f-d069bdab2d58.png`
|
||||
- 同状态真机截图:`tmp/vip-redesign-audit/20-uniform-footer-cards.png`
|
||||
- 下单面板真机截图:`tmp/vip-redesign-audit/21-uniform-footer-sheet.png`
|
||||
- 并排对比:`tmp/vip-redesign-audit/22-uniform-main-reference-and-implementation.png`
|
||||
- 设备:MuMu Android 基座,720 × 1280(360 × 640 CSS px,device scale factor 2)。参考图裁去底部已露出的面板后,按同一高度归一化进行并排检查。
|
||||
|
||||
## 视觉验收
|
||||
|
||||
- 顶部:水墨山景、竹影、留白与居中的标题层级已落地;新增背景资产为 `static/assets/modules/profile/opaque/m09-vip-hero-landscape.png`。
|
||||
- 套餐:基础版、宗族版、永久纪念版使用同一主推卡片规格,均有同样的朱砂描边、庭院水墨资产、底部价格/期限栏与圆角“立即开通”按钮。
|
||||
- 卡片资产:使用 `static/assets/modules/profile/opaque/m09-featured-courtyard.png`,在三张卡上保持统一的透明度和裁切方式,文字与按钮在真实窄屏上保持可读。
|
||||
- 下单:原居中装饰弹窗替换为底部确认单;套餐、有效期、应付金额、微信支付方式和取消入口均清晰可见。
|
||||
|
||||
## 交互验收
|
||||
|
||||
- MuMu 真机已点击“立即开通”,成功打开“确认下单”底部面板。
|
||||
- 已点击“暂不购买”安全关闭面板;关闭后确认页面仍保留 3 个“立即开通”入口,未由这次视觉验收新增订单。
|
||||
- 套餐和订单数据仍由现有接口读取;本次只改页面结构、样式与图片资产,不改接口字段或订单创建逻辑。
|
||||
|
||||
## 已知合同边界
|
||||
|
||||
- 当前 OpenAPI 未提供第三方支付调起参数或支付结果回调,因此主操作保持“创建订单”,不虚假宣称已完成微信支付。
|
||||
|
||||
## 结果
|
||||
|
||||
final result: passed
|
||||
|
||||
---
|
||||
|
||||
# T01 世系谱:设计核验
|
||||
|
||||
## 对比对象
|
||||
|
||||
- Source visual truth:用户在本次会话提供的 `Jiapu-App` 世系谱截图(408 × 936 px),并已核对参考源码 `C:\Users\Administrator\Desktop\job\Jiapu-App\pages\index\tree\index.vue`。
|
||||
- Implementation screenshot:`tmp/t01-pedigree-paged-order-final2.png`(720 × 1280 px,MuMu Android;360 × 640 CSS px,density 2)。
|
||||
- 当前真实数据状态:已授权的“真机联调10159371”仅有 1 位成员;页面已显示一列始祖资料与右侧世代切换,不能据此核验多人横向滚动。
|
||||
|
||||
## Findings
|
||||
|
||||
- [P1] 当前授权家谱只有一位成员,无法以真实数据复核参考图的“多位同世成员横向展开”状态。
|
||||
- 影响:实际单列、世代切换和纵向文字已验证,但多人列宽、横向滚动和同代排序仍缺少真机证据。
|
||||
- 修复:使用至少 5 位同世成员的测试家谱再次打开 T01;不应以本地伪造数据替代真实家谱数据。
|
||||
|
||||
## 已完成的源码核验
|
||||
|
||||
- T01 使用现有 `appApi.getTree` 单一数据 owner,按 `generation` 分组后每 5 人补齐空列并使用 `swiper` 横向分页;不引入参考项目的旧 `getGenealogyUserByParentsId` 接口。
|
||||
- 列结构为关系、姓名、资料三段纵向阅读;同世人员位于横向滚动容器,右侧切换上一世/下一世。
|
||||
- 静态合同、关系布局合同、人物操作合同和树接口运行时 smoke 均已通过。
|
||||
|
||||
final result: blocked
|
||||
|
||||
---
|
||||
|
||||
# T01 relationship-compass redesign: MuMu comparison rerun
|
||||
|
||||
## Evidence
|
||||
|
||||
- Source visual truth: `C:\Users\Rain\.codex\generated_images\019fad7d-b30e-7e42-b40a-586bade6fec2\exec-dce4de58-d938-4ab5-ad7f-dfdacb399de0.png` (853 × 1844 px).
|
||||
- Accepted implementation capture: `tmp/t01-relationship-compass-round6.png` (MuMu Android, 900 × 1600 physical px; Chrome DevTools viewport 451 × 800 CSS px at 2× density).
|
||||
- Full-view comparison: `tmp/t01-relationship-compass-round6-comparison.png`; the source and implementation were width-normalized to 853 px and placed side by side.
|
||||
- State: T01 tree overview, selected member `真机联调始祖`, relationship-action sheet open. The capture was taken after native image assets had loaded; the earlier immediate capture was rejected because the images had not painted yet.
|
||||
|
||||
## Comparison history
|
||||
|
||||
1. Earlier comparison (`tmp/t01-relationship-compass-audit-compare.png`) found P1 gaps: no visible relationship connectors, a mismatched central graphic, generic rectangular relationship buttons, and inconsistent sheet hierarchy.
|
||||
- Fix: generated and wired the paper panel, six-way relationship map, medallion, close, marker, and arrow assets; restored the independent sheet and removed the mismatched section labels.
|
||||
2. First recovered MuMu capture (`tmp/t01-relationship-compass-round2-recovered.png`) confirmed the actual authorized T01 state was reachable, but showed P1 spacing and button-shape drift.
|
||||
- Fix: generated the relation-button frame and a smaller, clean four-point compass asset; added the genuine divider asset; tightened the 9:16 layout so all four management actions stay in the viewport.
|
||||
3. Final MuMu capture (`tmp/t01-relationship-compass-round6.png`) was compared in the same composite input. No actionable P0/P1/P2 mismatch remains.
|
||||
|
||||
## Fidelity review
|
||||
|
||||
- Typography and copy: the live member name and generation remain readable; relationship and management labels do not wrap. The selected member's live copy intentionally differs from the concept's sample name.
|
||||
- Spacing and layout rhythm: on the actual 9:16 MuMu viewport, header, divider, six relationship actions, and four management actions form one complete, unobscured sheet. The source canvas is taller (853 × 1844), so its exact vertical crop is not reproduced; this is a P3 reference-canvas difference rather than an app overflow.
|
||||
- Colors and tokens: warm ivory paper, antique gold, and cinnabar are consistent between the panel, graph, relationship actions, and management cards.
|
||||
- Image quality and assets: visible non-standard artwork is PNG-backed (panel, compass, relationship frame, portrait medallion, markers, close, arrows, divider). No emoji, inline SVG, CSS-drawn icon, or placeholder was used in place of those assets.
|
||||
- Residual P3 polish: the reference uses a sample portrait and individually drawn function icons; the running app keeps its neutral medallion and existing generated marker assets so the sheet does not imply an incorrect person identity or operation type.
|
||||
|
||||
## Verification
|
||||
|
||||
- Opened the selected T01 member in MuMu and accepted the delayed native capture.
|
||||
- Passed: `tests/t01-person-action-panel-contract.ps1`, `tests/t01-relation-layout-contract.ps1`, `tests/t01-all-states-visual-contract.ps1`, and `tests/t01-tree-state-contract.ps1`.
|
||||
- Passed: `git diff --check` (only existing CRLF conversion warnings).
|
||||
|
||||
final result: passed
|
||||
|
||||
---
|
||||
|
||||
# T01 人物操作面板:关系罗盘重设计核验
|
||||
|
||||
## 对比对象
|
||||
|
||||
- Source visual truth:本次会话选择的第 2 张「关系罗盘」设计图,`C:\Users\Rain\.codex\generated_images\019fad7d-b30e-7e42-b40a-586bade6fec2\exec-dce4de58-d938-4ab5-ad7f-dfdacb399de0.png`。
|
||||
- Implementation screenshot:`tmp/jiapu-t01-panel-mumu-final.png`,MuMu Android 真机运行时的面板打开状态(900 × 1600 px)。
|
||||
- 同画布对比:`tmp/t01-relationship-compass-reference-vs-mumu-final.png`;左侧为设计稿面板裁切,右侧为 MuMu 实现面板裁切,并将二者归一至 853 × 1254 px 的同一面板画布。
|
||||
|
||||
## 真机视觉对比
|
||||
|
||||
- 信息层级:实机的成员头部、6 个围绕罗盘的亲属入口及下方 2 × 2 人物管理区,与设计稿的阅读顺序一致;四个管理入口在 900 × 1600 实机截图中均完整可见。
|
||||
- 资产与对比:实机使用纸张底图、人物徽章、关系标记、管理标记、关闭图标、箭头及关系罗盘等生成 PNG 资产;罗盘和边框在真机上没有空白、拉伸或替代图形。
|
||||
- 有意保留的 P3 差异:设计稿为贴边并带拖拽把手的轻量面板;实现保留当前家谱页面的左右留白、纸张边框及更细密的罗盘插画,以和已存在的朱红/宣纸视觉系统一致。这不影响层级、可读性或操作入口。
|
||||
|
||||
## 真机交互验收
|
||||
|
||||
- 初次实机核验发现 `scroll-view` 与头部同层,关闭按钮会被内容层遮挡。已将 `.member-action-panel__head` 提升至 `z-index: 2`;MuMu WebView 点击关闭按钮后,面板节点已消失。
|
||||
- MuMu 点击第一个关系入口“父亲”后,已进入“新增亲属 / 为真机联调始祖添加父亲”页面,见 `tmp/jiapu-t01-father-flow.png`;未填写任何字段,并已放弃草稿返回世系图。
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
- [x] 已落地选中设计的关系罗盘信息架构。
|
||||
- [x] 已生成并引用对应 PNG 资产,未用 emoji、内联 SVG 或 CSS 图形替代。
|
||||
- [x] 已捕获 MuMu 实现截图,并与源设计在同一画布中并排对比。
|
||||
- [x] 已验证关闭和“父亲”关系入口。
|
||||
|
||||
## 第二轮保真收敛(待真机复核)
|
||||
|
||||
- 根据 `tmp/t01-relationship-compass-audit-compare.png` 的 P1 差异,已更换为生成的 `t01-action-panel-paper-v3.png` 宣纸面板和 `t01-relation-map-v3.png` 六向连接罗盘;同时移除与设计稿不符的两段区块标题,收紧头部,并将关系按钮与管理卡片改为米纸/朱红配色。
|
||||
- 已通过 T01 人物操作面板、文档流、全状态视觉、关系布局、树状态合同及编译审计;生成的透明罗盘与面板资产均已检查 alpha。
|
||||
- 复核阻塞:HBuilderX 热更新后 MuMu 返回 A01 登录页,`tmp/t01-relationship-compass-round2.png` 不是人物操作面板,不能用于设计比较。为避免访问或猜测测试账号凭据,本轮没有重新登录。
|
||||
- 解除条件:在 MuMu 恢复已授权测试会话后,打开 T01 人物操作面板并重新截图;随后必须与同一张源设计同画布比较,处理任何残留 P1/P2 后才能改回通过。
|
||||
|
||||
final result: blocked
|
||||
|
||||
---
|
||||
|
||||
# T01 树状图与 T02 世系谱:真机回归
|
||||
|
||||
## 对比对象
|
||||
|
||||
- Source visual truth:本次会话中用户提供的参考项目“世系谱”截图(408 × 936 px)及 `C:\Users\Administrator\Desktop\job\Jiapu-App\pages\index\tree\index.vue` 的交互实现。
|
||||
- Implementation captures:`C:\Users\Administrator\AppData\Local\Temp\t01-entry-verify.png`、`C:\Users\Administrator\AppData\Local\Temp\t02-entry-verify.png`、`C:\Users\Administrator\AppData\Local\Temp\t02-swipe-verify.png`、`C:\Users\Administrator\AppData\Local\Temp\t02-return-after-fix.png`。
|
||||
- Device/state:Android 模拟器 720 × 1280 px;真实家谱“界面大数据回归谱0726”;T01 树状图、T02 第 1/2 世。
|
||||
|
||||
## 真机交互验收
|
||||
|
||||
- T01 右上角“世系谱”可进入独立 T02 表格页;T02 右上角“树状图”可返回 T01 图谱页。
|
||||
- T02 从第 1 世直接左滑可切换到第 2 世,未使用点击箭头替代横向手势。
|
||||
- 点击姓名打开“成员档案”;点击下方生平文字读取人物详情并打开“人物生平”弹窗,两个命中区域和结果不同。
|
||||
- 返回失败的路由根因已修复:可选 `selectedId` 为空时不再传入 `undefined`,以符合导航参数必须为非空字符串的校验。
|
||||
|
||||
## 视觉核验状态
|
||||
|
||||
- 字体与排版、列格、纵向文字、朱红页头、右侧世代标识和背景纹理已在真机截图中检查。
|
||||
- 当前会话里的参考截图没有可供本地重新打开的原始文件路径,因此无法按同一画布把参考图与实现图合成后做逐像素并排对比;不对像素级一致性作虚假通过结论。
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
- [x] 树状图与世系谱拆分为两个路由。
|
||||
- [x] 双向页头跳转与原生横向滑动。
|
||||
- [x] 姓名资料页与生平弹窗的分离点击行为。
|
||||
- [x] HBuilderX 页面诊断、静态路由合约和 Android 真机回归。
|
||||
|
||||
final result: blocked
|
||||
|
||||
---
|
||||
|
||||
# T01 树状图与 T02 世系谱:设计核验
|
||||
|
||||
## 对比对象
|
||||
|
||||
- Source visual truth:用户本次会话提供的参考项目“世系谱”截图,以及 `C:\Users\Administrator\Desktop\job\Jiapu-App\pages\index\tree\index.vue` 的 `swiper` 实现。
|
||||
- Implementation capture:未生成。当前 HBuilderX CLI 未识别已连接模拟器作为可部署设备,无法取得包含新 T01/T02 路由的截图。
|
||||
- 目标状态:从“世系图”进入 T01 树状图;T01 顶部进入 T02 世系谱;T02 顶部返回 T01。
|
||||
|
||||
## 阻塞项
|
||||
|
||||
- [P0] 无法取得新版本的真机或浏览器实现截图,因此不能与参考截图进行同视口视觉比较,也不能把直接左右滑动标为已验收。
|
||||
- 已完成代码核验:T01 恢复横向树状图;T02 使用原生 `swiper` 和页内纵向 `scroll-view`,每页五位成员。
|
||||
- 需要:让 HBuilderX 识别任一已连接模拟器,或提供可运行的 H5 预览,以捕获两页入口和横滑状态。
|
||||
|
||||
final result: blocked
|
||||
@@ -1,84 +0,0 @@
|
||||
# APP 136 接口功能归属与重复关系
|
||||
|
||||
> 历史快照(2026-07-26,136 条 operation),不再作为当前实施依据。当前根目录导出与桌面 Apifox 均为 149 条 operation,请使用 [APP-149接口页面归属与表单字段审计-2026-07-27.md](APP-149接口页面归属与表单字段审计-2026-07-27.md)。
|
||||
|
||||
更新时间:2026-07-26
|
||||
|
||||
## 结论
|
||||
|
||||
Apifox 当前目录共 136 条:128 条 APP 接口、4 条 APP/PC 共用行政区划接口、4 条旧系统兼容验证接口。
|
||||
|
||||
“136 条”不等于 136 个独立页面功能。真正功能重复的只有旧兼容验证/发码链路;列表、分页、详情、选项、管理态接口是同一资源在不同交互下的不同合同,不能擅自删掉或混用。
|
||||
|
||||
字段、必填、枚举、请求/响应 DTO 以桌面 Apifox 为准。根目录 `家谱.openapi.json` 只用于核对目录数量和路径,不用其缺失字段推断前端 DTO。
|
||||
|
||||
## 一、唯一入口与功能重复
|
||||
|
||||
| 分类 | 接口 | 当前唯一使用策略 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| APP 人机验证 | `GET /genealogy/app/auth/verification/{operationCode}/require`、`POST .../challenge`、`POST .../verify` | A01 密码/短信登录、A04 注册、A05 找回密码,通过 `TacVerification` 与 `utils/auth-verification.js` | 当前 APP 唯一验证链路 |
|
||||
| 旧验证码兼容 | `GET /captcha/require`、`POST /captcha/challenge`、`POST /captcha/verify`、`GET /auth/code` | 当前 APP 不调用 | 与 APP 人机验证功能重叠,保留 API 目录记录但不能再接回 A01/A04/A05,避免重复验证 |
|
||||
| APP 场景发码 | `POST /genealogy/app/auth/sms/{operationCode}/code` | A01/A04/A05;`operationCode` 是 `password-login`、`sms-login`、`register`、`forgot-password` | 当前 APP 唯一发码链路 |
|
||||
| 旧短信发码兼容 | `POST /genealogy/app/auth/sms/code` | 仅 `appApi.sendLegacySmsCode` API 层 owner;没有页面入口 | 与上项发码功能重叠。保留兼容方法供后端指定旧调用方,不得在现有认证页重复发短信 |
|
||||
| 行政区划(共享) | `GET /genealogy/region/children`、`/path/{regionCode}`、`/search`、`/{regionCode}` | APP 与 PC 共用;当前 G03/G11 使用 children | 不是旧接口、不是重复接口。其余三条在对应 UI 出现“回填路径/搜索/单项校验”交互后接入 |
|
||||
|
||||
## 二、136 条按功能模块归属
|
||||
|
||||
| Apifox 模块 | 数量 | 应归属页面/组件 | 备注 |
|
||||
| --- | ---: | --- | --- |
|
||||
| 验证中心 | 7 | A01、A04、A05、`TacVerification` | 其中 4 条为旧兼容,见上表 |
|
||||
| 认证登录 | 12 | A01、A04、A05、M01、M02、M04、M05、M10 | 改密、换绑、注销、退出属于敏感写操作,测试不执行 |
|
||||
| 文件上传 | 6 | G03、G11、M02、F02、F06、F07、F09、R04、R07、R08、R10,通过 `resumable-image-upload.js` | 单文件、分片 init/chunk/complete、业务引用绑定/释放各自用途不同 |
|
||||
| 行政区划 | 4 | G03 创建家谱、G11 家谱设置 | APP/PC 共用基础查询 |
|
||||
| 家谱 | 13 | G01、G03、G05、G06、G08、G09、G10、G11 | 配额、options、详情、审核/撤销等要与具体页面按钮逐项接线,不因已有列表接口视为完成 |
|
||||
| 家谱成员 | 6 | 当前没有“家谱成员(账号成员)管理”页面;不要误接到世系人物 T03–T08 | `memberId` 与 `personId` 不是同一 ID。成员管理页/候选 DTO 缺失需单列 |
|
||||
| 字辈谱 | 6 | G12 | 正常列表、维护列表、批量预览、批量保存、单条新增/修改是不同操作 |
|
||||
| 世系人物 | 12 | T01、T03–T08、R01、R02 | 首位成员创建后端 `code:500` 阻塞;不能伪造 personId |
|
||||
| 家族圈 | 14 | F01、F02、F03 | 列表与分页、评论与评论分页、回复与回复分页均非重复;编辑/删除/点赞/回复 UI 需逐项确认 |
|
||||
| 内容文章 | 9 | F04、F05、F06、M06、M08 | 谱文分类、帮助详情目前没有已确认页面入口,不能靠列表代替 |
|
||||
| 相册 | 7 | F07、F08、F09 | 相册本身与相片记录是两级资源;编辑/删除动作需遵守测试禁止删除边界 |
|
||||
| 祭祀 | 8 | R05、R06、R07 | 活动、献礼分别有列表和写入合同 |
|
||||
| 族务记录 | 18 | R03、R04、R08、R10、R11 | 成长/备忘/亲友的详情、修改、删除需有明确详情或编辑入口;R09 人生事件没有独立资源合同 |
|
||||
| 消息通知 | 4 | N01、G01 未读数 | N02 没有单条详情读取接口;标已读/全部已读不能在未授权测试中触发 |
|
||||
| 意见反馈 | 2 | M07 | 列表与提交分别接线 |
|
||||
| VIP | 3 | M09 | 套餐、订单列表可读取;创建订单属于支付链路,不执行 |
|
||||
| 视频 | 1 | F10 | 仅有删除视频接口,缺少视频列表/详情/上传/播放合同,因此 F10 不能假装可用 |
|
||||
| 贺礼邀约 | 4 | R06(活动详情)及“我的活动邀请”入口待产品页面 | 受邀人需要真实 `appUserId`;当前成员/世系 DTO 没有可确认候选来源,不能拿 `memberId` 或 `personId` 猜代 |
|
||||
|
||||
以上数量相加为 136。
|
||||
|
||||
## 三、共享行政区划的实测合同
|
||||
|
||||
桌面 Apifox 已核对:
|
||||
|
||||
| 接口 | 必填 | 可选 | 当前 API owner | 页面状态 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `GET /genealogy/region/children` | 无 | `parentCode`(不传或 `0` 为省级) | `appApi.getRegionChildren` | G03/G11 已真实读取 |
|
||||
| `GET /genealogy/region/path/{regionCode}` | path `regionCode:string` | `clientid` header | `appApi.getRegionPath` | 暂无“按已存地区回填层级路径”控件 |
|
||||
| `GET /genealogy/region/search` | query `keyword:string` | `level: 1..5`、`limit:integer`、`clientid` header | `appApi.searchRegions` | 暂无地区关键字搜索控件 |
|
||||
| `GET /genealogy/region/{regionCode}` | path `regionCode:string` | `clientid` header | `appApi.getRegion` | 暂无单项详情校验控件 |
|
||||
|
||||
后三条返回 DTO 在桌面文档当前显示为通用对象/列表对象,API 层只校验 envelope 与最外层数组/对象,不擅自猜测内部字段。等页面要消费具体字段时,先在桌面 Apifox 展开响应模型并补严字段校验。
|
||||
|
||||
## 四、接线判定标准
|
||||
|
||||
一条接口只有同时满足以下三项才标记“页面完成”:
|
||||
|
||||
1. `utils/api.js` 有唯一方法 owner,按桌面 Apifox 的必填/可选参数组装请求;
|
||||
2. 明确页面按钮、页面加载或组件行为调用该方法,且参数来源不是猜测 ID;
|
||||
3. 用浏览器在测试账号和测试数据上做真实请求验证;写入再做列表或详情回读。
|
||||
|
||||
仅有 API 方法、或仅页面能打开、或只有导出文件字段,均不算页面完成。
|
||||
|
||||
## 五、2026-07-26 浏览器复测结论
|
||||
|
||||
- 从 A01 密码登录进入测试账号后,以真实 `genealogyId`、动态、谱文和相册标识运行 `tests/all-page-route-runtime-smoke.js`,52/52 页面均通过;认证态访问 A01 被守卫重定向到 G01 属于预期行为,测试已明确校验该分支。
|
||||
- G01 的“世系图、成员、字辈诗、申请审核”四个快捷入口均通过浏览器页面点击复测,分别到达 T01、G05、G12、G10,未捕获运行时异常。
|
||||
- T04 再次经页面输入首位成员姓名并提交。请求仍未获服务端确认,页面显示“保存失败 / 发生未知异常,请联系管理员”;未写入本地成员、未生成假 `personId`。该结果继续受“首位成员创建 code:500”阻塞。
|
||||
- 该路由复测只验证真实读取、页面状态和既有测试数据;未执行短信、改密、换绑、退出、删除、审核或支付。
|
||||
|
||||
## 六、桌面 Apifox 与导出目录核对
|
||||
|
||||
桌面 Apifox 本地接口树(2026-07-26 16:56 更新)包含根目录 `家谱.openapi.json` 的全部 136 个 `HTTP method + path`;没有只存在于导出而桌面目录不存在的 operation。导出文件可用于路径、方法和数量的完整审计。
|
||||
|
||||
该核对不扩大为 DTO 字段已完整:页面要消费的 body/response 字段、必填、枚举和示例仍以桌面 Apifox 的接口详情为准。若桌面详情未声明条目 DTO 或枚举,前端继续把该字段标为阻塞,而不从导出占位结构猜测。
|
||||
@@ -1,75 +0,0 @@
|
||||
# APP 136 请求参数字段核对表
|
||||
|
||||
更新时间:2026-07-26
|
||||
|
||||
## 使用规则
|
||||
|
||||
- 路径和 operation 数量以桌面 Apifox 当前 APP 目录为准;本机已核对根目录 `家谱.openapi.json` 的 136 个 `method + path` 均存在于桌面目录。
|
||||
- 下表字段来自该次导出快照,用于逐项核对前端 consumer。桌面 Apifox 若显示更严格的 required、枚举、长度、oneOf 或条目 DTO,以桌面详情覆盖本表并重新导出。
|
||||
- `int64` 在 H5 JSON 中不得强制转换为 JavaScript `number`。真实雪花 ID 超过安全整数范围时,必须由后端改为十进制字符串合同,不能截断或猜测。
|
||||
- “阻塞”表示前端没有安全的参数来源、DTO、operation 或服务端成功响应;不是用本地默认值补齐的许可。
|
||||
|
||||
## 公共路径与查询参数
|
||||
|
||||
| operation 类别 | 必填 | 可选 | 当前页面/状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| 绝大多数 `/genealogy/app/**` | Header `clientid` | 当前登录 bearer | API 请求层统一注入;实际浏览器验证 |
|
||||
| 资源路径 `/{genealogyId}` | path `genealogyId` | — | 所有家谱内页面从真实当前家谱上下文取得 |
|
||||
| 世系资源 `/{personId}` | path `personId` | — | T03–T08、R01–R02 被首位成员 `code:500` 阻塞 |
|
||||
| 动态资源 `/{feedId}` | path `feedId` | — | F01/F03 实际读取;点赞状态 DTO 阻塞 |
|
||||
| 谱文/相册/礼仪/记录资源 ID | 对应 path ID | — | 已有真实测试数据的列表/详情/创建按页面验证;编辑/删除需要产品入口或受测试边界限制 |
|
||||
| 分页 | `pageNum`、`pageSize` 在 Apifox 均为可选 | keyword、generation、status 等按各 operation | 没有页面分页交互时不以默认假分页替代 |
|
||||
| 行政区划搜索 | query `keyword` | `level` 1–5、`limit` | `children` 已在 G03/G11 实读;其余三个尚无对应交互控件 |
|
||||
|
||||
## 写入 body 字段
|
||||
|
||||
星号为当前导出中的 required 字段。没有写入页面、稳定候选 ID 或枚举的字段均明确列为阻塞,不能手填内部 ID。
|
||||
|
||||
| Schema / operation | 页面 | 必填字段 | 可选字段 | 当前消费结论 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `VerificationChallengeBody`(challenge) | A01/A04/A05 | `tenantId`、`subject` | — | 已接验证组件 |
|
||||
| `VerificationCheckBody`(verify) | A01/A04/A05 | `tenantId`、`subject`、`challengeId` | `providerCode`、`captchaType`、`payload` | provider 细节以桌面 TAC DTO 为准 |
|
||||
| `PasswordRegisterBody` | A04 | `grantType`、`tenantId`、`phone`、`password`、`smsCode` | `nickName`、`registerSource` | 短信写入未执行(测试边界) |
|
||||
| `PasswordLoginBody` | A01 | `grantType`、`tenantId`、`phone`、`password` | `validToken` | 已真实登录 |
|
||||
| `SmsLoginBody` | A01 | `grantType`、`tenantId`、`phone`、`smsCode` | — | 短信写入未执行 |
|
||||
| `SmsCodeBody` | A01/A04/A05 | `grantType`、`tenantId`、`phone` | `validToken` | 场景路径已接;未发短信 |
|
||||
| `ProfileUpdateBody` | M02 | — | `nickName`、`avatarOssId`、`sex`、`birthday`、`provinceCode`、`cityCode`、`districtCode` | 头像 `ossId` 类型冲突;字典/地区回填 DTO 需桌面详情确认 |
|
||||
| `PasswordChangeBody` | M04 | `oldPassword`、`newPassword` | — | 敏感操作,不执行 |
|
||||
| `PasswordResetBody` | A05 | `grantType`、`tenantId`、`phone`、`smsCode`、`newPassword` | — | 短信/改密不执行 |
|
||||
| `PhoneChangeBody` | M05 | `phone`、`smsCode` | — | 敏感操作,不执行 |
|
||||
| `AccountDeactivateBody` | M10 | `smsCode` | — | 敏感操作,不执行 |
|
||||
| `ResumableInitBody` | 上传组件 | 实际服务端:`uploadId`、`fileName`、`fileMd5`、`totalSize`、`chunkSize`、`totalChunks` | `contentType` | 导出快照写为 `fileSize` 且漏 `uploadId`;真实请求省略 `uploadId` 返回“上传ID不能为空”,改用 `fileSize` 返回“文件大小不能为空”。前端只按已验证的实际契约发送,等待 Apifox 统一(B17) |
|
||||
| `ResumableCompleteBody` | 上传组件 | 实际已验证链路:`uploadId`、`fileName`、`fileMd5`、`totalSize`、`totalChunks` | — | 导出快照与实际字段冲突待后端统一;回执 `ossId` 仍为不安全 19 位字符串 |
|
||||
| `FileReferenceBody` | 业务附件 | `bizType`、`bizTable`、`bizId`、`bizField` | `bizName`、`ossId`、`ossIds`、`usageScene`、`usageName` | 缺稳定业务表/字段 owner,且 `ossId` 类型冲突;不能猜绑定 |
|
||||
| `GenealogyCreateBody` | G03 | `genealogyName`、`surname`、`regionCode` | `ancestralHall`、`originPlace`、`addressDetail`、`coverOssId`、`intro`、`visibility`、`joinMode` | 已真实创建/回读;封面受 `ossId` 阻塞 |
|
||||
| `GenealogyUpdateBody` | G11 | — | 与创建同名字段 | 读取已接;写入需页面确切 dirty/权限合同 |
|
||||
| `GenealogyJoinApplyBody` | G08 | — | `applicantName`、`phone`、`relationDesc`、`applyReason`、`inviterUserId` | 已真实申请列表回读;内部邀请人 ID 无候选来源 |
|
||||
| `GenealogyJoinAuditBody` | G10 | `status` | `auditRemark` | 审核为敏感操作,不执行 |
|
||||
| `GenealogyMemberUpdateBody` | 无独立成员管理页 | — | `memberName`、`relationName`、`roleType`、`lineagePersonId` | `memberId` 非 `personId`;不得误接世系页 |
|
||||
| `GenealogyOwnerTransferBody` | 无 | `targetMemberId` | — | 缺成员候选与产品入口,不能手填 ID |
|
||||
| `GenerationPoemBody` | G12 | `generationNo`、`generationText` | `description`、`sortOrder`、`status` | 已真实维护/回读 |
|
||||
| `GenerationPoemBatchBody` | G12 | `poemText` | `disableMissing` | 已真实预览/保存回读 |
|
||||
| `LineagePersonBody` | T04/T05/T06、R02 | `name`、`bindingMode` | `appUserId`、`personNo`、`aliasName`、`sex`、`generation`、`generationName`、`fatherId`、`motherId`、`avatarOssId`、`birthDate`、`birthLunar`、`birthPlace`、`deathDate`、`deathLunar`、`deathPlace`、`burialPlace`、`personStatus`、`biography`、`sortOrder`、`remark`、`relationName` | `bindingMode` 固定为 `NONE` / `SELF` / `SPECIFIED`:前两者禁止提交 `appUserId`,后者必须提交;`SELF` 后端从 Token 获取当前用户。页面默认 `NONE`;`SPECIFIED` 仍缺可信候选接口。实测 `NONE` 无 `appUserId` 的新增子女仍返回业务 `code:500`,等待后端排查新版写接口 |
|
||||
| `FamilyFeedBody` | F02/F03 编辑入口缺失 | `feedContent` | `feedType`、`mediaOssIds`、`sortOrder`、`status` | 文本动态已真实创建/回读;媒体受 `ossId` 阻塞;编辑无产品入口 |
|
||||
| `FamilyFeedCommentBody` | F03 | `commentContent` | `parentCommentId` | 一级评论已真实创建/回读;回复 UI 未设计 |
|
||||
| `ArticleBody` | F06 | `articleTitle`、`articleContent` | `categoryId`、`articleSummary`、`coverOssId`、`authorName`、`sortOrder`、`status` | 已真实创建/回读;分类条目 DTO、封面 `ossId` 阻塞 |
|
||||
| `AlbumBody` | F07 | `albumName` | `albumDesc`、`coverOssId`、`sortOrder`、`status` | 已真实创建/回读;封面 `ossId` 阻塞 |
|
||||
| `AlbumPhotoBody` | F09 | `ossId` | `photoTitle`、`photoDesc`、`photographer`、`shootTime`、`sortOrder`、`status` | 上传回执成功,但 `ossId` JSON 类型冲突,不能创建照片记录 |
|
||||
| `CeremonyBody` | R07 | `ceremonyType`、`ceremonyTitle` | `ceremonyDesc`、`ceremonyTime`、`location`、`locationAddress`、`longitude`、`latitude`、`coverOssId`、`sortOrder`、`status` | 已真实创建/回读;封面受 `ossId` 阻塞 |
|
||||
| `CeremonyGiftBody` | R06 | `giftAmount` | `giverName`、`giftMessage` | 礼仪详情/献礼读取已接;写入需从真实礼仪 ID 进入 |
|
||||
| `GrowthRecordBody` | R08 | `recordTitle` | `lineagePersonId`、`recordType`、`recordContent`、`recordDate`、`remindTime`、`mediaOssIds`、`sortOrder`、`status` | 无真实 personId 时人物归属不能填;非人物字段已真实创建/回读 |
|
||||
| `MemoBody` | R10 | `memoTitle` | `memoContent`、`remindTime`、`completed`、`mediaOssIds`、`sortOrder`、`status` | 已真实创建/回读;附件受 `ossId` 阻塞 |
|
||||
| `RelativeRecordBody` | R04 | `relativeName` | `relationName`、`eventName`、`eventTime`、`giftAmount`、`recordContent`、`mediaOssIds`、`sortOrder`、`status` | 已真实创建/回读;附件受 `ossId` 阻塞 |
|
||||
| `MeritRecordBody` | R11 | `donorName`、`meritTitle` | `meritType`、`meritContent`、`amount`、`meritTime`、`sortOrder`、`status` | 已真实创建/回读 |
|
||||
| `FeedbackBody` | M07 | `feedbackContent` | `feedbackType`、`contactInfo` | 已真实提交/读取 |
|
||||
| `VipOrderBody` | M09 | `packageId` | `genealogyId`、`payType` | 创建订单属于支付,不执行 |
|
||||
| `CeremonyInviteesBody` | R07/R06 | `inviteeUserIds` | — | 缺 `appUserId` 候选列表;不能用 member/person ID 猜代 |
|
||||
| `CeremonyInvitationResponseBody` | 我的活动邀请页缺失 | `inviteStatus` | — | 枚举仅 `ACCEPTED`/`DECLINED`;需要产品入口和真实邀请 |
|
||||
|
||||
## 后端需要优先确认的统一规则
|
||||
|
||||
1. 所有 `int64` 在 APP JSON 请求/响应中是否统一为十进制字符串;至少要覆盖 `ossId`、所有资源 ID、`appUserId`、`memberId`、`personId`、`categoryId` 和 `packageId`。
|
||||
2. 所有“建议使用字典值”的字段必须在 Apifox 给出 enum 或独立 options operation,特别是 `sex`、`personStatus`、`roleType`、`status`、`visibility`、`joinMode`、`payType`。
|
||||
3. 任何需要选择内部用户/成员/人物的操作必须返回明确且同类型的候选 ID,禁止要求客户端用不同资源的 ID 猜代。
|
||||
4. 上传完成回执和所有消费 `ossId` 的 DTO 必须同版修复;否则上传成功并不等于业务图片创建成功。
|
||||
5. 分片上传 init/complete 的 Apifox 导出字段必须与实际服务端校验一致:当前实测要求 `uploadId` 与 `totalSize`,而导出写为 `fileSize` 且未声明 `uploadId`;不得要求客户端同时发送两套互斥字段。
|
||||
@@ -1,84 +0,0 @@
|
||||
# APP 149 接口页面归属与表单字段审计
|
||||
|
||||
更新时间:2026-07-27
|
||||
|
||||
## 一、唯一依据与结论
|
||||
|
||||
- 唯一接口源:根目录 `家谱.openapi.json`;桌面 Apifox `APP` 概览同步显示 **149** 条 operation、88 个数据模型。
|
||||
- 这 149 条不是 149 个页面。页面、认证/上传底层流程、管理操作、兼容旧接口共同构成目录,不能因为没有对应按钮就假称“未对接”,也不能把内部 ID、验证码或支付参数渲染成普通表单。
|
||||
- 当前核对结果:已存在页面和 API owner 的资源继续按现有页面操作验证;本次已修复 M02、M07、G08、R07 四个确定的字段控件/适配错误。视频发布已接入 F10;视频和官网内容的读取响应仍没有可安全消费 DTO,因此不能伪造列表或详情卡片。
|
||||
- 所有真实写入验证只允许在页面中选择、输入、提交并做列表/详情回读;不使用后台请求构造数据。短信、改密、换绑、退出、删除、审核、支付、注销不做测试写操作。
|
||||
|
||||
## 二、149 条按 Apifox 模块归属
|
||||
|
||||
| 模块 | 条数 | 页面或唯一 owner | 当前判定 |
|
||||
| --- | ---: | --- | --- |
|
||||
| 验证中心 | 7 | A01/A04/A05,`utils/auth-verification.js` | APP 行为验证为认证流程内部参数;旧 `/captcha/*` 与 `/auth/code` 是兼容链路,无新页面入口。 |
|
||||
| 认证登录 | 12 | A01/A04/A05、M01、M02、M04/M05/M10 | 登录、注册、资料读取/更新有页面;敏感账号写操作保留但不测。 |
|
||||
| 文件上传 | 6 | `utils/resumable-image-upload.js`、各图片选择页 | 上传初始化、分片、完成、引用绑定/释放是技术流程,`ossId` 由回执拥有,不是手填字段。 |
|
||||
| 行政区划 | 8 | G03/G11,`appApi.getRegion*` | `/genealogy/region/*` 是 APP/PC 共享 4 条;`/genealogy/app/region/*` 为同能力 APP 副本,当前统一用共享 owner,不能双接线。 |
|
||||
| 家谱 | 13 | G01、G03、G05–G11 | 列表、详情、公开搜索、申请、审核、配额、options 分属不同交互,不能互相替代。 |
|
||||
| 家谱成员 | 6 | API owner 已有;暂无独立账号成员管理页 | `memberId` 不等于世系 `personId`;成员管理/转让/移除不映射到 T 系页面。 |
|
||||
| 字辈谱 | 6 | G12 | 列表、管理、单条维护、批量预览和批量保存均保留。 |
|
||||
| 世系人物 | 12 | T01、T03–T08、R01/R02 | 首位成员创建仍须以页面实测为准;未得到真实 `personId` 前不伪造成员或关系。 |
|
||||
| 家族圈 | 14 | F01–F03 | 动态、评论、回复、点赞、分页是不同资源动作。删除不测试。 |
|
||||
| 内容文章 | 9 | F04–F06、M06、M08 | 谱文已有创建/读取;分类列表条目 DTO 未声明,分类 ID 不能手输或猜字段。 |
|
||||
| 相册 | 7 | F07–F09 | 相册和照片是两级资源;上传回执后写入,删除不测试。 |
|
||||
| 祭祀 | 8 | R05–R07 | 活动及献礼分别由列表、详情、编辑页拥有。 |
|
||||
| 族务记录 | 20 | R03/R04、R08、R10、R11 | 亲友、成长、备忘、功德是四类独立资源;人生事件没有单独写资源时不伪造。 |
|
||||
| 消息通知 | 5 | N01、G01 未读数 | 读取有 owner;标读为状态写,不在本轮测试。 |
|
||||
| 意见反馈 | 2 | M07 | 已修正为接口枚举 value 提交。 |
|
||||
| VIP | 3 | M09 | 套餐/订单读取可用;下单属于支付链路,不测试。 |
|
||||
| 视频 | 5 | F10 | 已接入上传、创建及 API owner 的 CRUD 路径;列表/详情响应未声明 DTO,页面不假造卡片字段。 |
|
||||
| 贺礼邀约 | 4 | R06 及未来“我的邀请”页 | 受邀人数组必须来自业务用户候选;不能用成员/人物 ID 冒充。 |
|
||||
| 官网内容 | 2 | M10 的协议/说明未来可用 | 见“阻塞”B05:响应体未声明,不能将当前静态说明误报为已接线。 |
|
||||
|
||||
## 三、表单字段的统一处理规则
|
||||
|
||||
| 字段类别 | 页面处理 | 传输规则 |
|
||||
| --- | --- | --- |
|
||||
| `required` 文本/多行文本 | 显示必填标识并做空值校验 | 只传去空白后的真实输入。 |
|
||||
| 有 `enum` 的 string | 中文标签的单选/下拉 | 只提交 enum value,绝不提交中文标签。 |
|
||||
| `date` 或写例 `yyyy-MM-dd` | 日期选择器 | 提交 `yyyy-MM-dd`。 |
|
||||
| 日期时间字符串 | 日期 + 时间选择器 | 只有用户已选择日期时组装 `yyyy-MM-dd HH:mm:ss`。 |
|
||||
| 候选 ID | 由 options/list 返回项选择 | 不显示内部 ID 自由输入;没有候选 DTO/接口则隐藏该字段并记录阻塞。 |
|
||||
| `*OssId`、`mediaOssIds` | 统一上传控件 | 只使用上传回执;不允许键盘输入。 |
|
||||
| `status`、`completed` 等管理/字典字段 | 创建表单默认省略,除非当前页面有明确管理权限且文档给出枚举 | 不把“停用”“完成”猜成前台默认开关。 |
|
||||
| token、`clientid`、`tenantId`、`grantType`、验证码票据、分片 hash | 永不显示 | 由 session、运行时配置、验证或上传 owner 自动生成。 |
|
||||
|
||||
## 四、已有页面的重点 body 字段矩阵
|
||||
|
||||
| 页面/接口 | 必填字段 | 可填写字段 | 选择/自动/隐藏字段 | 当前实现结论 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| M02 `PUT /auth/profile` | 无 | `nickName`、`realName`、`email` | `sex`:男 `0`/女 `1`/未知 `2`;`birthday`:日期;`avatar`:上传回执 | 已修正性别选择器,适配器拒绝非 `0/1/2`。 |
|
||||
| M07 `POST /feedback` | `feedbackContent` | `contactInfo` | `feedbackType`:建议 `advice`/功能问题 `bug`/投诉 `complaint`/其他 `other` | 已修正为中文显示、枚举 value 提交。 |
|
||||
| G03/G11 家谱创建/修改 | 创建:`genealogyName`、`surname`、`regionCode` | 堂号、籍贯、地址、简介 | 地区:三级行政区划选择;封面:上传;可见性/加入方式:枚举选择 | 保留页面已有 owner。 |
|
||||
| G08 `POST .../join-applies` | 无 | 申请人姓名、手机号、关系说明、申请理由 | `inviterUserId`:只有业务用户候选时才可选;当前隐藏 | 已删除“邀请人编号”手输框;适配器保留字段以供未来真实候选使用。 |
|
||||
| T04/T05 与亲属写入 `LineagePersonBody` | `name`、`bindingMode` | 姓名、别名、编号、字辈、地点、生平、备注、排序 | 性别 `0/1/2`、农历 `0/1`、人物状态 `0/1/2`、父母为人物 options、头像上传;`SELF`/`NONE` 不传 `appUserId`,`SPECIFIED` 必须由可信业务用户候选选择 | 页面已有选择器与白名单;首位成员后端业务 `code:500` 曾阻塞,必须用页面重试和回读确认。 |
|
||||
| F02 动态 | `feedContent` | 内容、排序 | 类型固定自动 `text`;多媒体由上传回执;状态不在普通创建页展示 | 页面显示“文字动态”。 |
|
||||
| F06 谱文 | `articleTitle`、`articleContent` | 摘要、作者、正文、排序 | 封面上传;`categoryId` 必须分类候选选择 | 分类列表没有条目 DTO,不能猜 `id/label`,暂不展示分类选择。 |
|
||||
| F07/F09 相册与照片 | 相册名;照片 `ossId` | 描述、标题、摄影者、拍摄时间、排序 | OSS 均来自上传;状态默认省略 | 已有创建后回读路径。 |
|
||||
| R04 亲友往来 | `relativeName` | 关系、事件、时间、金额、正文、排序 | 多媒体上传;状态默认省略 | 可选字段不被前端强制必填。 |
|
||||
| R07 礼仪活动 | `ceremonyType`、`ceremonyTitle` | 说明、日期时间、地点、详细地址、排序 | 封面上传;经纬度仅地图组件成对回填,当前隐藏;状态默认省略 | 适配器已接收 `locationAddress`,若未来传坐标会校验经纬度成对。 |
|
||||
| R08 成长记录 | `recordTitle` | 类型、正文、日期、提醒、排序 | `lineagePersonId` 只可选真实人物;媒体上传;状态默认省略 | 无真实人物前保留为空。 |
|
||||
| R10 备忘 | `memoTitle` | 正文、提醒、排序 | `completed` 无 enum,默认省略;媒体上传 | 不伪造完成开关。 |
|
||||
| R11 功德 | `donorName`、`meritTitle` | 正文、金额、时间、排序 | 类型:`donation`/`repair`/`public`/`other`;状态默认省略 | 现有选择器使用接口 value。 |
|
||||
| F10 视频 | `videoTitle`、`videoOssId` | 视频标题、说明 | 视频文件:上传回执自动填充;封面、时长、排序、状态:创建页隐藏 | 已接入视频选择、分片上传和创建;不允许手填 OSS ID。 |
|
||||
|
||||
## 五、不能直接补成页面的阻塞项
|
||||
|
||||
| 编号 | 接口/字段 | 已知请求或返回事实 | 前端处理与需要后端补充 |
|
||||
| --- | --- | --- | --- |
|
||||
| B01 | 首位成员 `POST .../lineage/persons` | 页面最小合法 body 曾返回 HTTP 200、envelope `code:500`、`发生未知异常,请联系管理员`;没有成功返回 `personId` | 后端修复后,必须从 T04 页面提交并回读 T01/T03,不能后台造成员。 |
|
||||
| B02 | `LineagePersonBody.bindingMode=SPECIFIED` | `appUserId` 条件必填,但现有 APP 没有“可信业务用户候选”读取合同 | 保留 NONE/SELF;补业务用户 options DTO 后才开放指定绑定。 |
|
||||
| B03 | 谱文分类 `GET .../article-categories` | operation 有列表路径,但当前导出没有可消费的条目字段模型 | 后端给出分类项的 `id`、显示名及响应 schema;前端再做选择器。 |
|
||||
| B04 | 视频 GET/GET detail | `VideoBody` 请求要求 `videoTitle`、`videoOssId`;F10 已可选择视频、上传并创建,当前 200 读取响应仍未声明字段 | 后端补 `VideoView`/列表 rows 的完整响应 DTO,并确认播放地址与封面读取合同;前端再展示视频列表、详情和播放。 |
|
||||
| B05 | 官网内容 GET `/site/articles`、`/site/pages/{pageKey}` | 当前 200 响应 schema 未声明 | 后端补文章/页面 key、标题、正文、更新时间等 DTO;M10 才能替换静态说明。 |
|
||||
| B06 | 礼仪坐标 | `longitude`、`latitude` 可选且必须成对;没有地图选点或坐标来源 operation | 提供地图/地理编码集成合同,或明确允许何种受控坐标来源;不让用户手输。 |
|
||||
| B07 | 贺礼邀约 `inviteeUserIds` | 必填业务用户 ID 数组;成员和世系人物 options 不能证明等同业务用户 | 发布受邀业务用户候选接口与 DTO。 |
|
||||
| B08 | `completed`、`payType`、审核 status | 当前 schema 未给可安全映射的全部 value-label 语义 | 后端补 enum 或字典 options;前端保持隐藏/不测。 |
|
||||
|
||||
## 六、验证记录
|
||||
|
||||
- 本轮代码静态/适配器验证通过:`lineage-openapi-contract`、`feedback-openapi-contract`、`profile-pages-contract`、`m07-feedback-submit-contract`、`g08-g10-application-flow-contract`、`r-business-flow-contract`、`form-enum-api-runtime-smoke`、`oss-id-payload-api-runtime-smoke`、`compile-audit`。
|
||||
- 这些验证不替代真实写入。下一阶段在浏览器完成接口详情核对后,仅在测试账号的页面内输入、选择、提交和回读;敏感操作继续跳过。
|
||||
@@ -1,118 +0,0 @@
|
||||
# APP-150 项目接口覆盖与功能缺口总清单
|
||||
|
||||
更新时间:2026-07-28
|
||||
唯一接口依据:仓库根目录 `家谱.openapi.json`(149 个 operation)。
|
||||
|
||||
## 1. 阅读方式与结论
|
||||
|
||||
“没有接口”“接口已接但没功能”“接口不应有单独页面”是三件不同的事。本清单将其分开记录:
|
||||
|
||||
- **后端合同缺口**:OpenAPI 没有足够的请求/响应字段,前端不能猜测实现。
|
||||
- **前端功能缺口**:`utils/api.js` 已有请求 owner,但没有页面入口或用户动作调用它。
|
||||
- **技术/敏感操作**:由登录、上传、会话、确认弹窗等 owner 自动调用;不做独立表单。
|
||||
|
||||
当前结论:149 个 operation 均已完成归属;视频发布已接通。项目仍有 9 项后端合同缺口、14 组 API 已有但页面功能未接通的缺口,详见第 3、4 节。
|
||||
|
||||
## 2. 全量模块归属(149 个 operation)
|
||||
|
||||
| 模块 | 数量 | 当前 owner | 状态 | 说明 |
|
||||
| --- | ---: | --- | --- | --- |
|
||||
| 验证中心 | 7 | A01/A04/A05、`auth-verification.js` | 已归属 | APP 验证是认证内部流程;`/captcha/*`、`/auth/code` 为兼容接口。 |
|
||||
| 认证登录 | 12 | A01/A04/A05、M01/M02/M04/M05/M10 | 部分功能缺口 | 登录、注册、资料、改密、退出有 owner;换绑/注销见第 4 节。 |
|
||||
| 文件上传 | 6 | `resumable-image-upload.js` | 已归属 | 初始化、分片、完成、引用释放均是上传 owner;OSS ID 不可手填。 |
|
||||
| 行政区划 | 8 | G03/G11、`appApi.getRegion*` | 已归属 | APP 与共享版本各 4 条,当前只消费一套,不能双接。 |
|
||||
| 家谱 | 13 | G01/G03/G05–G12 | 部分功能缺口 | 创建、读取、设置、申请流程有 owner;申请审核/撤销需补实际动作。 |
|
||||
| 家谱成员 | 6 | `appApi` | 无页面 owner | `memberId` 是账号成员,不是世系 `personId`;不能放进 T 系页面。 |
|
||||
| 字辈谱 | 6 | G12 | 部分功能缺口 | 读取、创建、批量预览/保存有 owner;单条修改/停用需补页面动作。 |
|
||||
| 世系人物 | 12 | T01、T03–T08、R01/R02 | 后端阻塞 | 页面/API 已有;首位人物创建、指定绑定候选仍受合同阻塞。 |
|
||||
| 家族圈 | 14 | F01–F03 | 部分功能缺口 | 发布、读取、点赞、评论有 owner;编辑/删除与回复发布尚未形成页面流程。 |
|
||||
| 内容文章 | 9 | F04–F06、M06/M08 | 部分功能缺口 | 读取/新增有 owner;分类 DTO、编辑/删除动作待补。 |
|
||||
| 相册 | 7 | F07–F09 | 部分功能缺口 | 创建、读取、上传照片有 owner;相册编辑/删除、照片删除待补。 |
|
||||
| 祭祀 | 8 | R05–R07 | 部分功能缺口 | 创建、读取、献礼新增有 owner;修改/删除、地图与邀请待补。 |
|
||||
| 族务记录 | 20 | R03/R04、R08、R10/R11 | 部分功能缺口 | 新增/读取有 owner;多项编辑、删除、媒体入口待补。 |
|
||||
| 消息通知 | 5 | N01/N02、G01 | 部分功能缺口 | 列表、详情、未读数有 owner;标记已读动作待补。 |
|
||||
| 意见反馈 | 2 | M07 | 部分功能缺口 | 提交有 owner;“我的反馈”列表无页面。 |
|
||||
| VIP | 3 | M09 | 部分功能缺口 | 套餐/订单读取有 owner;创建订单未形成受控支付流程。 |
|
||||
| 视频 | 5 | F10、`appApi` | 后端合同缺口 | 上传、创建和 CRUD API owner 已接;列表/详情 DTO 缺失。 |
|
||||
| 贺礼邀约 | 4 | R06、`appApi` | 后端合同缺口 | API owner 有;缺业务用户候选与“我的邀请”页面。 |
|
||||
| 官网内容 | 2 | M10 | 后端合同缺口 | 响应无 DTO,不能替换当前静态说明。 |
|
||||
|
||||
## 3. 后端 / OpenAPI 必须补充的合同(不能由前端猜)
|
||||
|
||||
| ID | 相关接口/字段 | 现状 | 缺少的合同 | 前端当前处理 | 优先级 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| C01 | `GET /genealogies/{genealogyId}/videos`、`GET .../videos/{videoId}` | 只有通用响应,无可消费视频字段 | `VideoView`:`videoId`、标题、说明、视频播放 URL、封面 URL、时长、创建时间、状态 | F10 可上传并创建,不渲染列表/播放器 | P0 |
|
||||
| C02 | `POST /lineage/persons` 首位成员 | 页面最小合法请求曾收到业务 `code:500` | 后端修复创建逻辑,并返回可回读的 `personId` | T04 不伪造首位人物 | P0 |
|
||||
| C03 | `LineagePersonBody.bindingMode=SPECIFIED` | `appUserId` 条件必填 | 可信业务用户候选接口及 DTO,明确用户 ID 与人物关系 | 仅开放 `NONE` / `SELF` | P1 |
|
||||
| C04 | `GET .../article-categories` | 列表 response 未定义条目字段 | 分类 `id`、显示名、状态、排序 DTO | F06 隐藏分类选择,不能手输 `categoryId` | P1 |
|
||||
| C05 | `GET /site/articles`、`GET /site/pages/{pageKey}` | response 未定义 | 文章/页面 key、标题、正文、更新时间、链接 DTO | M10 保留静态内容 | P1 |
|
||||
| C06 | 礼仪 `longitude`、`latitude` | 两字段须成对,但无位置来源 | 地图选点或地理编码合同;坐标精度/坐标系说明 | R07 隐藏坐标手输 | P2 |
|
||||
| C07 | 活动 `inviteeUserIds` | 需要业务用户 ID 数组 | 可邀请业务用户候选接口、显示名、可邀请条件 DTO | R06 不提交猜测 ID | P1 |
|
||||
| C08 | `completed`、`payType`、部分审核/管理状态 | 字典含义或可用范围不足 | 完整 enum/value-label 与权限规则 | 创建页默认不显示管理开关 | P2 |
|
||||
| C09 | 家族圈评论回复 | 只有回复列表接口,没有声明创建回复的操作或父评论字段 | 回复创建 endpoint 与请求体(至少评论内容、父评论 ID) | F03 仅展示现有评论,不提供假回复提交 | P1 |
|
||||
|
||||
## 4. API 已有,但页面功能尚未接通
|
||||
|
||||
以下项的 `appApi` 已有对应请求 owner;静态检索未发现页面调用,或页面只展示静态/只读状态。实现前需确认权限与交互,不应直接暴露内部 ID。
|
||||
|
||||
| ID | 操作 | 当前缺少的页面功能 | 建议页面/入口 | 前置条件 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| F01 | `PUT/DELETE .../feeds/{feedId}` | 编辑、删除本人动态 | F03 动态详情 | 必须仅显示本人有权操作的按钮。 |
|
||||
| F02 | `DELETE .../comments/{commentId}` | 删除本人评论/删除占位展示 | F03 评论区 | 有回复时按后端返回的删除占位渲染。 |
|
||||
| F03 | `PUT/DELETE .../articles/{articleId}` | 谱文编辑、删除 | F05/F06 | 分类 DTO 到位后,编辑页才开放分类选择。 |
|
||||
| F04 | `PUT/DELETE .../albums/{albumId}` | 相册编辑、删除 | F07/F08 | 删除需二次确认并遵循后端权限。 |
|
||||
| F05 | `DELETE .../albums/{albumId}/photos/{photoId}` | 删除照片 | F08 | 仅作者/管理者显示。 |
|
||||
| F06 | `PUT/DELETE .../ceremonies/{ceremonyId}` | 礼仪编辑、删除 | R06/R07 | 地图字段仍按 C06 处理。 |
|
||||
| F07 | `DELETE .../ceremonies/{ceremonyId}/gifts/{giftId}` | 删除献礼 | R06 | 需明确献礼人/管理员权限。 |
|
||||
| F08 | 成长、备忘、亲友、功德的 `PUT/DELETE` | 记录编辑、删除 | R08/R10/R04/R11 | 目前新建/读取与编辑动作未闭环。 |
|
||||
| F09 | `PUT .../generation-poems/{poemId}` | 修改、停用、恢复单条字辈 | G12 | 需按 `status` 枚举和管理权限显示。 |
|
||||
| F10 | 家谱成员 6 条 | 成员列表、成员资料、移除、退出、转让 | 新建“成员管理”页 | 严格使用 `memberId`,绝不能复用世系人物 UI。 |
|
||||
| F11 | 加入申请审核、撤销 | 审核/撤销提交动作与结果回读 | G09/G10 | 需确认当前用户角色,敏感写操作必须二次确认。 |
|
||||
| F12 | 通知标已读、全部已读 | 单条/全部已读行为 | N01/N02 | 标读应静默回写列表,不弹假成功。 |
|
||||
| F13 | `GET /feedback` | “我的反馈”列表 | M07 或新建 M11 | response DTO 足够时展示,不开放删除。 |
|
||||
| F14 | 换绑、注销、VIP 创建订单 | 安全表单/支付确认链路 | M05/M10/M09 | 短信验证、支付回调、二次确认不可省略。 |
|
||||
|
||||
## 5. 没有可新增接口的页面功能
|
||||
|
||||
| 页面 | 原因 | 需要的后端资源 |
|
||||
| --- | --- | --- |
|
||||
| R09 人生大事 | OpenAPI 149 条中没有人生事件资源的 CRUD | 人生事件列表、详情、新增、修改、删除;需定义归属人物、事件日期、事件类型、内容、媒体字段。 |
|
||||
| F10 视频列表/播放 | 已有路径但读取 DTO 不完整,等同不可安全实现 | 见 C01。 |
|
||||
| “我的活动邀请” | 读取接口有 owner,但没有页面和邀请候选数据 | 邀请页面、C07 候选 DTO;现有 `GET .../ceremony-invitations/mine` 可作为入口。 |
|
||||
| 家谱成员管理 | 后端路径完整但无页面信息架构 | 成员管理页面及权限/成员 DTO展示规则。 |
|
||||
|
||||
## 6. 不是“少页面”的接口(保持自动或受控)
|
||||
|
||||
| 接口类别 | 正确 owner | 不应暴露的字段/原因 |
|
||||
| --- | --- | --- |
|
||||
| 验证挑战、验证校验、短信发送 | `auth-verification.js`、认证页 | `validToken`、challenge、验证码票据由认证流程持有。 |
|
||||
| 文件初始化、分片、完成、引用 | 上传工具 | `uploadId`、MD5、chunkIndex、OSS ID 都是上传回执/技术参数。 |
|
||||
| `clientid`、token、tenantId | `config.js`、session | 运行时认证信息,绝不能做表单字段。 |
|
||||
| 行政区划 APP/共享重复路径 | `appApi.getRegion*` | 只选择一个 owner,避免同一功能双请求。 |
|
||||
| 删除、审核、退出、注销、支付 | 现有页面的明确二次确认流程 | 不应为“接口覆盖率”而自动触发真实写操作。 |
|
||||
|
||||
## 7. 表单字段总规则
|
||||
|
||||
| 字段类型 | 表单处理 |
|
||||
| --- | --- |
|
||||
| OpenAPI `required` 文本 | 显示必填标识,提交前 trim 校验。 |
|
||||
| `enum` 字符串 | 使用中文标签的选择器,仅提交 enum value。 |
|
||||
| 日期/日期时间 | 使用日期或日期+时间选择器;不能自由输入格式。 |
|
||||
| 候选 ID | 必须由 options/list 选择;缺候选 DTO 时隐藏,不允许手输。 |
|
||||
| `*OssId`、`mediaOssIds` | 只从上传回执获取;视频同样适用。 |
|
||||
| `status`、`completed`、排序、审核、支付字段 | 默认不出现在普通创建表单;只在明确管理权限和完整字典合同下出现。 |
|
||||
| 认证、分片、路径 ID | 自动生成/路由携带;不可显示或编辑。 |
|
||||
|
||||
## 8. 推荐实施顺序
|
||||
|
||||
1. 后端先完成 C01、C02:视频可展示播放、世系首位人物可创建,才能闭合两个主要入口。
|
||||
2. 补 C03、C04、C07:所有候选 ID 都能选择而不是手填。
|
||||
3. 实施 F11(成员管理)和 F12(申请审核/撤销),先补清晰的权限和确认流程。
|
||||
4. 实施 F01–F10 的编辑/删除闭环;每一项均先做“当前用户是否有权”的详情回读。
|
||||
5. 处理 C05、C06、C08 与 R09,完成官网内容、地图、字典和人生事件的新增合同。
|
||||
|
||||
## 9. 验证边界
|
||||
|
||||
- 本文是接口和代码静态审计,不代表所有写接口已经在生产环境执行。
|
||||
- 真实写入必须在测试账号、对应页面中操作,再通过列表/详情回读验证;不得用脚本绕过页面构造业务数据。
|
||||
- 当前视频测试文件为 `C:\Users\Rain\Desktop\9d063f4536624f6b1ccb4d2cb9e9786c.mp4`;已确认存在且为非空 MP4。真实上传需在登录态下从 F10 的系统文件选择器选择它。
|
||||
@@ -1,63 +0,0 @@
|
||||
# APP 表单控件与接口字段审计
|
||||
|
||||
更新日期:2026-07-26
|
||||
依据:桌面 Apifox APP 合同、`家谱.openapi.json`、当前页面真实表单代码。
|
||||
|
||||
## 判定规则
|
||||
|
||||
| 字段性质 | 页面控件 |
|
||||
| --- | --- |
|
||||
| 自由文本、标题、说明、地点、姓名 | 文本输入或多行输入 |
|
||||
| `date`、明确日期 | 日期选择器 |
|
||||
| 明确日期时间 | 日期与时间选择器,页面组合后提交标准时间字符串 |
|
||||
| 金额、排序 | 数字输入 |
|
||||
| 地区、分类、人物、业务用户、成员等资源 ID | 从真实候选列表选择;禁止手填内部 ID |
|
||||
| `sex`、`status`、是否农历等字典值 | value-label 选择器;必须有 Apifox enum 或字典 options 来源 |
|
||||
| `ossId`、封面、头像、媒体 | 真实上传组件;禁止手填文件 ID |
|
||||
|
||||
## 已确认需要调整的表单
|
||||
|
||||
| 页面 | 字段 | 当前控件/状态 | 正确控件 | 依赖或阻塞 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| T04、T05 | `birthLunar`、`deathLunar` | 文本输入,且提示为“按家谱记载填写” | “是否农历”选择器 | B15:Apifox 只有字典值描述,无 value-label enum |
|
||||
| T04、T05 | `sex`、`personStatus` | 页面缺入口 | 字典选择器 | B15 |
|
||||
| T04、T05 | `fatherId`、`motherId`、`appUserId` | 页面不能从候选选择 | 人物/业务用户候选选择器 | B06、B09/B13;首位成员不能填父母 |
|
||||
| T04、T05 | `avatarOssId` | 页面未接头像上传 | 真实上传组件 | B08:19 位 `ossId` 类型冲突 |
|
||||
| M02 | `sex` | 文本输入 | 字典选择器 | B15 |
|
||||
| M02 | `provinceCode`、`cityCode`、`districtCode` | 页面缺入口 | 行政区划级联选择器 | B12 的接口 DTO 已可读;需接入页面 |
|
||||
| G08 | `inviterUserId` | 数字输入,要求用户手填内部 ID | 真实邀请人候选选择器 | B09:没有业务用户候选/映射,不能手填 |
|
||||
| F06 | `categoryId` | 页面缺入口 | 谱文分类选择器 | B11:测试谱分类为空,合同没有条目字段定义 |
|
||||
| F02 | `feedType` | 自由文本输入 | 动态类型选择器或固定默认类型 | 合同仅给默认 `text`,没有完整类型 enum;不能让用户随意输入未声明类型 |
|
||||
| F09 | `shootTime` | 手工文本时间 | 日期与时间选择器 | 合同字段是拍摄时间;可直接改页面控件 |
|
||||
| R04 | `eventTime` | 手工文本时间 | 日期与时间选择器 | 合同字段是事项时间;可直接改页面控件 |
|
||||
| R07 | `ceremonyTime` | 手工文本时间 | 日期与时间选择器 | 合同字段是活动时间;可直接改页面控件 |
|
||||
| R08 | `recordDate`、`remindTime` | 手工文本时间 | 日期选择器;提醒用日期与时间选择器 | 合同字段分别是记录日期、提醒时间 |
|
||||
| R11 | `meritTime` | 手工文本时间 | 日期与时间选择器 | 合同字段是功德时间 |
|
||||
|
||||
## 已经正确的控件
|
||||
|
||||
| 页面 | 字段 | 当前控件 |
|
||||
| --- | --- | --- |
|
||||
| G03、G11 | `regionCode` | 行政区划级联选择器 |
|
||||
| G03、G11 | `visibility`、`joinMode` | 已封装为访问规则选择 |
|
||||
| M02 | `birthday` | 日期选择器 |
|
||||
| R10 | `remindTime` | 日期和时间选择器组合 |
|
||||
| 所有上传表单 | `coverOssId`、`mediaOssIds`、`ossId` | 真实上传回执,不提供手填文件 ID |
|
||||
| R04、R11 | 金额 | 数字输入 |
|
||||
| 各编辑页 | `sortOrder` | 数字输入 |
|
||||
|
||||
## 不应为了“字段齐全”强行显示的字段
|
||||
|
||||
| 字段 | 原因 |
|
||||
| --- | --- |
|
||||
| 首位成员的 `fatherId`、`motherId`、`relationName` | 与“首位成员/世系起点”语义冲突;不能伪造已有成员 ID |
|
||||
| `personNo` | 合同明确不传时服务端生成,不应要求用户填写 |
|
||||
| `avatarOssId`、`coverOssId`、`mediaOssIds` | 必须由上传组件产生,不允许文本输入 |
|
||||
| `status`、`completed` 等服务端有默认值的可选字段 | 无业务需求和明确字典时不新增裸代码控件 |
|
||||
|
||||
## 实施顺序
|
||||
|
||||
1. 先把 F09、R04、R07、R08、R11 的明确时间字段改为选择器并进行浏览器真实提交回读。
|
||||
2. 再接入 M02 的地区级联选择。
|
||||
3. B15、B09、B11、B06/B08 由后端补齐枚举、候选或 ID 合同后,再补世系、性别、分类、邀请人等选择器。
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
# Apifox 写接口字段—表单控件映射
|
||||
|
||||
> 当前有效的 149 operation 总表、页面 owner 与阻塞项见 [APP-149接口页面归属与表单字段审计-2026-07-27.md](APP-149接口页面归属与表单字段审计-2026-07-27.md)。本文件保留为字段控件速查表;其中以下修订以根目录最新 `家谱.openapi.json` 为准。
|
||||
|
||||
## 口径与来源
|
||||
|
||||
- 核对时间:2026-07-27。
|
||||
- 主源:桌面 Apifox 当前 `APP` 项目(149 条 operation)及同一时刻导出的根目录 `家谱.openapi.json`;两者的 operation 数量一致。
|
||||
- `必填` 以 Apifox `必需` 标记为准;没有 `必需` 的字段均应允许不填,提交时传空值或省略由当前 API 适配器统一处理。
|
||||
- `枚举选择` 只能提交下表列出的 value,不能把中文标签提交给后端。
|
||||
- `候选选择` 只能从对应选项接口选取,页面不得暴露裸露的内部 ID 输入框。
|
||||
- `上传` 必须先走统一上传,提交上传回执中的 `ossId`;不能让用户手输 OSS ID。
|
||||
- 所有 `sortOrder` 是整数数字框;所有 `amount/giftAmount` 是金额数字框;示例为 `yyyy-MM-dd HH:mm:ss` 的时间字段用“日期 + 时间”控件拼接后提交。
|
||||
|
||||
## 已在 Apifox 字段详情中确认的字典
|
||||
|
||||
| 字段/字典 | value → 中文 | 页面控件 |
|
||||
| --- | --- | --- |
|
||||
| `sys_user_sex` | `0` 男;`1` 女;`2` 未知 | 单选/下拉选择 |
|
||||
| `gen_number_yes_no` | `0` 否;`1` 是 | 单选/下拉选择 |
|
||||
| `gen_lineage_person_status` | `0` 健在;`1` 已故;`2` 未知 | 单选/下拉选择 |
|
||||
| `sys_normal_disable` | `0` 正常;`1` 停用 | 单选/开关;默认 `0` |
|
||||
| `gen_genealogy_visibility` | `0` 私密;`1` 公开;`2` 成员可见 | 单选/下拉选择 |
|
||||
| `gen_genealogy_join_mode` | `0` 关闭加入;`1` 申请审核;`2` 邀请加入 | 单选/下拉选择 |
|
||||
| `gen_merit_type` | `donation` 捐赠;`repair` 修祠;`public` 公益;`other` 其他 | 单选/下拉选择 |
|
||||
| 活动邀请响应 | `ACCEPTED` 接受;`DECLINED` 拒绝 | 二选一 |
|
||||
|
||||
`completed` 在 Apifox 当前详情中是 `string`,只给出示例 `0`,没有挂字典/允许值;因此不能伪造“完成/未完成”的值表。当前页面应默认省略,待后端给出该字段的字典定义后再开启开关。
|
||||
|
||||
## 已有页面:字段到控件映射
|
||||
|
||||
### M02 修改用户资料 — `PUT /genealogy/app/auth/profile`
|
||||
|
||||
| 字段 | 必填 | Apifox 详情 | 正确控件与提交 |
|
||||
| --- | --- | --- | --- |
|
||||
| `nickName` | 否 | string,用户昵称,最多 30 字 | 文本框,最多 30 字 |
|
||||
| `realName` | 否 | string,真实姓名,最多 30 字 | 文本框,最多 30 字 |
|
||||
| `avatar` | 否 | int64,头像文件 OSS ID | 图片上传;仅提交可安全表示的数值 OSS ID |
|
||||
| `sex` | 否 | `sys_user_sex` | 枚举选择 `0/1/2` |
|
||||
| `birthday` | 否 | date,生日,格式 `yyyy-MM-dd` | 日期选择器 |
|
||||
| `email` | 否 | email,最多 100 字 | email 文本框 |
|
||||
|
||||
### G03/G11 创建、修改家谱 — `GenealogyCreateBody` / `GenealogyUpdateBody`
|
||||
|
||||
| 字段 | 创建必填 | 正确控件与提交 |
|
||||
| --- | --- | --- |
|
||||
| `genealogyName` | 是 | 文本框 |
|
||||
| `surname` | 是 | 文本框 |
|
||||
| `ancestralHall` | 否 | 文本框 |
|
||||
| `originPlace` | 否 | 文本框 |
|
||||
| `regionCode` | 是 | 省市区级联候选选择,提交行政区划 code |
|
||||
| `addressDetail` | 否 | 文本框 |
|
||||
| `coverOssId` | 否 | 图片上传,提交字符串 OSS ID |
|
||||
| `intro` | 否 | 多行文本 |
|
||||
| `visibility` | 否 | 枚举选择:私密 `0` / 公开 `1` / 成员可见 `2` |
|
||||
| `joinMode` | 否 | 枚举选择:关闭加入 `0` / 申请审核 `1` / 邀请加入 `2` |
|
||||
|
||||
### T04/T05 录入、修改世系人物 — `LineagePersonBody`
|
||||
|
||||
同一 body 还用于“添加子女、父母、兄弟姐妹、配偶”。`name` 是唯一 body 必填字段;关系路径由 URL 决定,不能把中文关系标签当成接口字段替代。
|
||||
|
||||
| 字段 | 必填 | Apifox 详情/限制 | 正确控件与提交 |
|
||||
| --- | --- | --- | --- |
|
||||
| `bindingMode` | 是 | 身份认领方式:`NONE` / `SELF` / `SPECIFIED` | 固定英文枚举选择:不绑定账号 / 绑定当前账号 / 绑定指定用户;不发送中文值 |
|
||||
| `appUserId` | 视 `bindingMode` 而定 | `NONE` 不绑定账号且不传;`SELF` 绑定当前登录账号且不传,后端从 Token 获取;`SPECIFIED` 绑定指定业务用户且必须传 | 仅 `SPECIFIED` 由管理员选择可信业务用户候选后提交;当前没有候选接口时禁止该选项保存,绝不手输 ID |
|
||||
| `personNo` | 否 | 人物编号;不传由服务端生成 | 可选文本框;留空时省略 |
|
||||
| `name` | 是 | 姓名 | 文本框 + 必填校验 |
|
||||
| `aliasName` | 否 | 别名或曾用名 | 文本框 |
|
||||
| `sex` | 否 | `sys_user_sex` | 枚举选择:男 `0` / 女 `1` / 未知 `2` |
|
||||
| `generation` | 否 | int64,世代序号 | 正整数数字框;首位成员固定为 `1` |
|
||||
| `generationName` | 否 | 字辈或辈分 | 文本框 |
|
||||
| `fatherId` | 否 | 父亲人物 ID,必须属于当前家谱 | 从 `/lineage/persons/options` 选择父亲,提交人物 ID |
|
||||
| `motherId` | 否 | 母亲人物 ID,必须属于当前家谱 | 从 `/lineage/persons/options` 选择母亲,提交人物 ID |
|
||||
| `avatarOssId` | 否 | string/null,头像文件 OSS ID;说明明确要求统一上传组件取得,不允许手工录入 | 图片上传,提交字符串 OSS ID |
|
||||
| `birthDate` | 否 | date-time/null(写接口示例为 `yyyy-MM-dd`) | 日期选择;未录入不传 |
|
||||
| `birthLunar` | 否 | `gen_number_yes_no` | 枚举选择:否 `0` / 是 `1` |
|
||||
| `birthPlace` | 否 | 出生地 | 文本框 |
|
||||
| `deathDate` | 否 | date-time/null(写接口示例为 `yyyy-MM-dd`) | 日期选择;未录入不传 |
|
||||
| `deathLunar` | 否 | `gen_number_yes_no` | 枚举选择:否 `0` / 是 `1` |
|
||||
| `deathPlace` | 否 | 逝世地 | 文本框 |
|
||||
| `burialPlace` | 否 | 安葬地 | 文本框 |
|
||||
| `personStatus` | 否 | `gen_lineage_person_status` | 枚举选择:健在 `0` / 已故 `1` / 未知 `2` |
|
||||
| `biography` | 否 | 人物简介 | 多行文本 |
|
||||
| `sortOrder` | 否 | int64,排序值 | 整数数字框 |
|
||||
| `remark` | 否 | 备注 | 多行文本 |
|
||||
| `relationName` | 否 | 关系名称 | 新增亲属时由关系选择派生;编辑时可作为文本修订 |
|
||||
|
||||
#### 页面实测(2026-07-27)
|
||||
|
||||
- 此接口字段标为 `date-time`,但四个写接口示例使用 `yyyy-MM-dd`。页面此前把日期追加为 `yyyy-MM-dd HH:mm:ss`,会在客户端 `normalizeLineagePersonDate` 校验阶段被拒绝,尚未发起请求;现已改为只传日期。
|
||||
- 后端于 2026-07-27 明确补齐身份认领合同:`NONE`、`SELF` 禁止提交 `appUserId`;`SELF` 由后端从 Token 取当前 APP 用户;仅 `SPECIFIED` 必须提交 `appUserId`。页面默认 `NONE`,不再自动读取或提交 `profile.userId`。
|
||||
- 同日页面实测 `POST .../children`:请求体为 `bindingMode: "NONE"` 且不存在 `appUserId`,后端仍返回 HTTP 200 / envelope `code:500`、`发生未知异常,请联系管理员`;三世数据未落库,需后端确认新版写接口是否已部署并排查该业务异常。
|
||||
|
||||
### F02 家族圈动态 — `FamilyFeedBody`
|
||||
|
||||
| 字段 | 必填 | Apifox 详情 | 正确控件与提交 |
|
||||
| --- | --- | --- | --- |
|
||||
| `feedType` | 否 | 动态类型;未传默认 `text` | 当前页面固定传 `text`,不让用户输入代码 |
|
||||
| `feedContent` | 是 | 动态内容,不允许为空 | 多行文本 + 必填校验 |
|
||||
| `mediaOssIds` | 否 | 多个文件 OSS ID 用英文逗号分隔 | 多图上传;回执 ID 以 `,` 拼接 |
|
||||
| `sortOrder` | 否 | int64;未传默认 `0` | 整数数字框 |
|
||||
| `status` | 否 | `sys_normal_disable` | 正常 `0` / 停用 `1`;创建页默认 `0`,非管理页不暴露停用操作 |
|
||||
|
||||
### F06 谱文、F07 相册、F09 相册照片
|
||||
|
||||
| body.字段 | 必填 | 正确控件与提交 |
|
||||
| --- | --- | --- |
|
||||
| `ArticleBody.categoryId` | 否 | 从“谱文分类”接口候选选择;不手填分类 ID |
|
||||
| `articleTitle` / `articleSummary` / `authorName` | 标题是 | 分别为文本、多行摘要、文本 |
|
||||
| `articleContent` | 是 | 富文本/多行内容编辑 |
|
||||
| `coverOssId` | 否 | 图片上传,字符串 OSS ID |
|
||||
| `ArticleBody.sortOrder` | 否 | 整数数字框 |
|
||||
| `ArticleBody.status` | 否 | `sys_normal_disable` 选择,默认 `0` |
|
||||
| `AlbumBody.albumName` | 是 | 文本框 |
|
||||
| `albumDesc` | 否 | 多行文本 |
|
||||
| `coverOssId` | 否 | 图片上传,字符串 OSS ID |
|
||||
| `AlbumBody.sortOrder` | 否 | 整数数字框 |
|
||||
| `AlbumBody.status` | 否 | `sys_normal_disable` 选择,默认 `0` |
|
||||
| `AlbumPhotoBody.ossId` | 是 | 图片上传;提交字符串 OSS ID |
|
||||
| `photoTitle` / `photoDesc` / `photographer` | 否 | 文本、多行文本、文本 |
|
||||
| `shootTime` | 否 | 拍摄时间;示例按标准时间字符串 | 日期 + 时间选择 |
|
||||
| `AlbumPhotoBody.sortOrder` | 否 | 整数数字框 |
|
||||
| `AlbumPhotoBody.status` | 否 | `sys_normal_disable` 选择,默认 `0` |
|
||||
|
||||
### R07 祭祀活动、R04 献礼
|
||||
|
||||
| body.字段 | 必填 | 正确控件与提交 |
|
||||
| --- | --- | --- |
|
||||
| `CeremonyBody.ceremonyType` | 是 | Apifox 当前为普通 string;文本框,不能自行伪造枚举 |
|
||||
| `ceremonyTitle` | 是 | 文本框 |
|
||||
| `ceremonyDesc` | 否 | 多行文本 |
|
||||
| `ceremonyTime` | 否 | 示例为 `yyyy-MM-dd HH:mm:ss`;日期 + 时间选择 |
|
||||
| `location` / `locationAddress` | 否 | 地点名称、详细地址文本框;两项都应保留 |
|
||||
| `longitude` / `latitude` | 否 | 仅可由地图选点组件成对回填;当前没有地图候选/选点合同,R07 不暴露手输框,也不传这两个字段。API 适配层只接受成对有限数字,供后续真实地图组件使用。 |
|
||||
| `coverOssId` | 否 | 图片上传,字符串 OSS ID |
|
||||
| `sortOrder` | 否 | 整数数字框 |
|
||||
| `status` | 否 | `sys_normal_disable` 选择,默认 `0` |
|
||||
| `CeremonyGiftBody.giverName` | 否 | 文本框 |
|
||||
| `giftAmount` | 是 | 金额数字框 |
|
||||
| `giftMessage` | 否 | 多行文本 |
|
||||
|
||||
### R08 成长记录、R09 亲友记录、R10 备忘、R11 功德
|
||||
|
||||
| body.字段 | 必填 | Apifox 详情/正确控件 |
|
||||
| --- | --- | --- |
|
||||
| `GrowthRecordBody.lineagePersonId` | 否 | 世系人物候选选择,提交人物 ID |
|
||||
| `recordType` | 否 | 当前详情为普通 string,文本框 |
|
||||
| `recordTitle` | 是 | 文本框 |
|
||||
| `recordContent` | 否 | 多行文本 |
|
||||
| `recordDate` / `remindTime` | 否 | 示例均为 `yyyy-MM-dd HH:mm:ss`;日期 + 时间选择 |
|
||||
| `mediaOssIds` | 否 | 多图上传,逗号分隔 OSS ID |
|
||||
| `GrowthRecordBody.sortOrder` / `status` | 否 | 整数数字框;`sys_normal_disable` 选择 |
|
||||
| `MemoBody.memoTitle` | 是 | 文本框 |
|
||||
| `memoContent` | 否 | 多行文本 |
|
||||
| `remindTime` | 否 | 示例为 `yyyy-MM-dd HH:mm:ss`;日期 + 时间选择 |
|
||||
| `completed` | 否 | 当前仅 string 示例 `0`,无字典;默认省略,不能私设枚举 |
|
||||
| `MemoBody.mediaOssIds` / `sortOrder` / `status` | 否 | 多图上传;整数数字框;`sys_normal_disable` 选择 |
|
||||
| `RelativeRecordBody.relativeName` | 是 | 文本框 |
|
||||
| `relationName` / `eventName` | 否 | 文本框 |
|
||||
| `eventTime` | 否 | 示例为 `yyyy-MM-dd HH:mm:ss`;日期 + 时间选择 |
|
||||
| `giftAmount` | 否 | 金额数字框 |
|
||||
| `recordContent` | 否 | 多行文本 |
|
||||
| `RelativeRecordBody.mediaOssIds` / `sortOrder` / `status` | 否 | 多图上传;整数数字框;`sys_normal_disable` 选择 |
|
||||
| `MeritRecordBody.donorName` / `meritTitle` | 是 | 文本框 |
|
||||
| `meritType` | 否 | 枚举选择:捐赠 `donation` / 修祠 `repair` / 公益 `public` / 其他 `other` |
|
||||
| `meritContent` | 否 | 多行文本 |
|
||||
| `amount` | 否 | 金额数字框 |
|
||||
| `meritTime` | 否 | 示例为 `yyyy-MM-dd HH:mm:ss`;日期 + 时间选择 |
|
||||
| `MeritRecordBody.sortOrder` / `status` | 否 | 整数数字框;`sys_normal_disable` 选择 |
|
||||
|
||||
## 其余写接口:同样必须按字段类型建控件
|
||||
|
||||
| 接口 body | 字段映射 |
|
||||
| --- | --- |
|
||||
| `GenealogyJoinApplyBody` | `applicantName`、`phone`、`relationDesc`、`applyReason` 为文本/多行文本;`inviterUserId` 必须是业务用户候选选择,当前缺候选接口时不暴露裸 ID 输入。 |
|
||||
| `GenealogyJoinAuditBody` | `status` 是审核结果,必须由 Apifox 的审核状态字典提供选项后才做选择器;`auditRemark` 多行文本。 |
|
||||
| `GenealogyMemberUpdateBody` | `memberName`、`relationName`、`roleType` 文本;`lineagePersonId` 为世系人物候选选择。 |
|
||||
| `GenealogyOwnerTransferBody` | `targetMemberId` 必填,家谱成员候选选择。 |
|
||||
| `GenerationPoemBody` | `generationNo` 必填正整数;`generationText` 必填文本;`description` 多行文本;`sortOrder` 数字;`status` 用 `sys_normal_disable`。 |
|
||||
| `GenerationPoemBatchBody` | `poemText` 必填多行文本;`disableMissing` 布尔开关。 |
|
||||
| `FamilyFeedCommentBody` | `parentCommentId` 为评论候选/回复上下文,不能输入 ID;`commentContent` 必填多行文本。 |
|
||||
| `FeedbackBody` | `feedbackType` 选填枚举选择:`advice` 建议、`bug` 功能问题、`complaint` 投诉反馈、`other` 其他;界面显示中文标签,提交 value。`feedbackContent` 必填多行文本;`contactInfo` 文本。 |
|
||||
| `VipOrderBody` | `packageId` 必填,VIP 套餐候选选择;`genealogyId` 为当前家谱上下文选择;`payType` 只能使用支付方式字典,不能手填代码。 |
|
||||
| `VideoBody` | `videoTitle` 必填文本,`videoDesc` 多行文本,`coverOssId`/`videoOssId` 为上传,`durationSeconds`/`sortOrder` 为数字,`status` 为 `sys_normal_disable`。 |
|
||||
| `CeremonyInviteesBody` | `inviteeUserIds` 必填多选业务用户候选;无候选接口不能用逗号文本代替数组。 |
|
||||
| `CeremonyInvitationResponseBody` | `inviteStatus` 必填二选一:接受 `ACCEPTED`、拒绝 `DECLINED`。 |
|
||||
|
||||
## 非页面直接填写的底层接口
|
||||
|
||||
认证挑战、验证码、分片上传初始化/完成、文件引用等 body 由登录/上传流程生成,不应渲染为业务表单。`grantType`、`tenantId`、`challengeId`、`validToken`、文件 hash/分片大小等由对应流程拥有,不能让用户在页面中编辑。
|
||||
|
||||
## 当前改造判定
|
||||
|
||||
1. 已经可以立即改为选择控件的字段:`sex`、出生/逝世农历、`personStatus`、`visibility`、`joinMode`、所有 `status`、`meritType`、邀请响应。
|
||||
2. 必须改为候选选择的字段:所有家谱/成员/世系人物/分类/套餐/受邀用户的 ID 字段。
|
||||
3. 必须改为上传的字段:所有 `*OssId`、`mediaOssIds`、头像、封面、照片、视频文件。
|
||||
4. `completed`、`payType`、审核 `status` 等尚未在当前 Apifox 字段详情给出允许值;在后端未提供字典或候选接口前,不增加猜测性选择项。`feedbackType` 已有四个枚举值,已改为选择控件。
|
||||
@@ -1,237 +0,0 @@
|
||||
# Apifox 逐页业务接口与页面展示核对台账
|
||||
|
||||
> 权威取证顺序:用户已打开的 Apifox 桌面端文档页 → 同一部署的脱敏只读响应(仅在获准时)→ 导出文档交叉核验。不得以导出文档缺项否定 Apifox 中已存在的 operation,也不得以 operation 存在推定页面已经完成。
|
||||
>
|
||||
> 记录规则:每一页必须同时给出业务动作、请求合同、响应字段、页面展示字段和完成状态。`已发布`是 Apifox 文档状态,不是客户端完成状态;`DECLARED_UNVERIFIED` 不得写成完成。
|
||||
|
||||
## F 家族内容
|
||||
|
||||
### F01 家族动态列表
|
||||
|
||||
| 核对项 | Apifox 桌面端实读 | 当前页面实情 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| 读取列表 | `GET /genealogy/app/genealogies/{genealogyId}/feeds`;鉴权 `Authorization`;路径 `genealogyId:int64` 必填;Header `clientid:string` 必填 | 页面已删除 `listFamilyFeedFixtures`,不再调用缺 DTO 的列表响应来填充动态卡片 | 读取 owner 存在但展示未接线,等待可消费条目 DTO |
|
||||
| 响应字段 | `200 ListResult` 仅实读到通用 `code`、`msg`、`data[]`,`data` 元素未声明动态 DTO 字段 | 页面不再展示 `id/tag/time/title/content/author` 等本地字段;只提示缺失的字段合同 | 不能建立真实字段映射;不得猜测字段名 |
|
||||
| 页面状态 | 进入发布页与跨模块入口均保留 | 有效家谱下明确显示“动态列表待后端字段合同” | **未完成 / DECLARED_UNVERIFIED**:待 Apifox 补充动态条目 DTO,或在获准的登录只读窗口取得脱敏真实响应后再恢复列表与详情入口 |
|
||||
|
||||
### F02 发布家族动态
|
||||
|
||||
| 核对项 | Apifox 桌面端实读 | 当前页面实情 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| 发布动作 | `POST /genealogy/app/genealogies/{genealogyId}/feeds`;鉴权 `Authorization`;路径 `genealogyId:int64`、Header `clientid:string` 均必填 | `appApi.createFeed` 使用严格请求和离页取消;页面不再生成本地预览 | 已接线,等待真实写入响应核验 |
|
||||
| 请求体 | `application/json`:`feedContent:string` 必填且不能为空;`feedType:string` 可选,未传默认 `text`;`mediaOssIds:string` 可选,多个 OSS ID 用英文逗号分隔;`sortOrder:int64` 可选,未传默认 `0`;`status:string` 可选,未传默认正常状态 `0` | 表单收集并提交内容、动态类型、通过上传回执取得的媒体和排序值;`status` 使用服务端已声明的默认值,不暴露“0”之类状态码输入 | 已接线;真实写入仍待人工响应核验 |
|
||||
| 响应字段 | `200 ObjectResult` 只声明通用 `code`、`msg`、`data:object`,未声明新动态 DTO | 仅在严格成功信封后显示“已提交服务端”;不会在 F01 生成本地列表项 | **未完成 / DECLARED_UNVERIFIED**:接线不等于已验证;真实写入保留人工可观察窗口 |
|
||||
|
||||
### F03 动态详情与评论
|
||||
|
||||
| 核对项 | Apifox 桌面端实读 | 当前页面实情 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| 动态详情 | `GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}`;鉴权 `Authorization`;`genealogyId:int64`、`feedId:int64`、`clientid:string` 必填 | 页面已删除 `findFamilyFeedFixture`;因详情响应仍未声明动态本体 DTO,不读取并展示猜测字段 | 正文展示仍未接线,等待可消费响应字段 |
|
||||
| 详情响应 | `200 ObjectResult` 只有通用 `code`、`msg`、`data:object`,没有动态本体 DTO | 页面不展示 `tag/time/title/content/author` 等正文 fixture 字段,只显示字段合同缺口 | 动态本体字段仍不能映射,不能猜测 |
|
||||
| 一级评论读取 | `GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments`;同样要求鉴权、两个路径 ID 和 `clientid`。接口说明:仅返回正常展示的一级评论,`replyCount` 为直属回复数 | `appApi.getFeedComments` 真实读取;无远端配置或响应不合同时显示错误,不回退 fixture | 已接线,等待真实响应核验 |
|
||||
| 评论响应字段 | `data: FamilyFeedCommentView[]`:`commentId`、`genealogyId`、`feedId`、`parentCommentId`、`appUserId`、`appUserNickName`、`appUserAvatar`、`parentAppUserId`、`parentAppUserNickName`、`commentContent`、`userDeleted`、`replyCount`、`commentLevel`、`status`、`createTime` | 展示 `id ← commentId`、`author ← appUserNickName`、`time ← createTime`、`content ← commentContent`、`replyCount ← replyCount`;归属 ID 与重复 ID 在 API 边界校验 | 已接线,等待真实响应字段核验 |
|
||||
| 发表评论 | `POST /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments`;请求体 `parentCommentId:int64|null` 可选(不传或 `null` 为一级评论)、`commentContent:string` 必填,最大 1000 字符 | 提交 `commentContent`,限制 1000 字;仅在服务端请求成功并刷新评论列表后提示提交成功 | **未完成 / DECLARED_UNVERIFIED**:接口调用已接线,但未在无人值守时发起写入,也没有真实成功响应证据;动态本体仍缺 DTO |
|
||||
|
||||
### F04—F06 谱文列表、详情与编辑
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| F04 列表 | `GET /genealogy/app/genealogies/{genealogyId}/articles`;鉴权、`genealogyId:int64`、`clientid:string` 必填;`200 ListResult` 仅通用 `code/msg/data[]`,条目未声明 DTO | 已删除 fixture、分类和本地搜索;页面明确提示缺失文章 ID、分类、标题、摘要、作者和更新时间投影 | **未完成 / DECLARED_UNVERIFIED**:没有可审计的条目字段映射,不能接线或把本地筛选误称服务端能力 |
|
||||
| F05 详情 | `GET /genealogy/app/genealogies/{genealogyId}/articles/{articleId}`;鉴权、`genealogyId:int64`、`articleId:int64`、`clientid:string` 必填;`200 ObjectResult` 仅通用对象 DTO | 已删除 fixture 正文与编辑跳转;只显示正文 DTO 缺口 | **未完成 / DECLARED_UNVERIFIED**:正文、作者、时间投影均未由详情响应声明 |
|
||||
| F06 新建 | `POST /genealogy/app/genealogies/{genealogyId}/articles`;鉴权、`genealogyId:int64`、`clientid:string` 必填 | `appApi.createArticle` 严格提交标题、摘要、封面上传回执、正文、作者和排序;成功仅表示服务端成功信封,不生成本地文章 | 已接线,等待真实写入响应核验 |
|
||||
| F06 修改 | `PUT /genealogy/app/genealogies/{genealogyId}/articles/{articleId}`;鉴权、两个路径 ID、`clientid:string` 必填 | 已移除 fixture 编辑预填;没有可靠详情 DTO 和文章 ID 列表来源时,编辑入口关闭 | **未完成 / DECLARED_UNVERIFIED** |
|
||||
| 新建/修改请求体 | `categoryId:int64` 可选;`articleTitle:string` 必填;`articleSummary:string` 可选;`coverOssId:int64` 可选;`articleContent:string` 必填;`authorName:string`、`sortOrder:int64`、`status:string` 均可选。返回均为通用 `ObjectResult` | 新建页收集可读字段;封面只接收真实上传回执。`categoryId` 需要分类列表条目 DTO,`status` 需要状态字典,二者均不让用户填写内部 ID/码 | 可写字段已接线;分类与状态选择仍 **DECLARED_UNVERIFIED**,编辑仍需可靠 articleId/详情 owner |
|
||||
|
||||
### F07—F09 相册、照片墙与上传
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| F07 相册列表 | `GET /genealogy/app/genealogies/{genealogyId}/albums`;鉴权、`genealogyId:int64`、`clientid:string` 必填;`200 ListResult` 仅通用数组 DTO | 已删除 fixture 相册卡片和本地预览,页面明确提示缺失相册 ID、封面、名称、照片数、描述和更新时间字段 | **未完成 / DECLARED_UNVERIFIED**:相册条目、封面 URL、照片数和更新时间没有响应字段来源 |
|
||||
| F07 新建相册 | `POST /genealogy/app/genealogies/{genealogyId}/albums`;请求体 `albumName:string` 必填,`albumDesc:string`、`coverOssId:int64`、`sortOrder:int64`、`status:string` 可选;返回通用 `ObjectResult` | 表单提交名称、说明、真实封面上传回执和排序;`status` 缺可读字典,不向用户暴露码值 | 已接线,等待真实写入响应核验 |
|
||||
| F08 照片墙读取 | `GET /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos`;鉴权、`genealogyId:int64`、`albumId:int64`、`clientid:string` 必填;`200 ListResult` 仅通用数组 DTO | 已删除 fixture 相册和照片墙,只显示缺失照片展示字段的状态 | **未完成 / DECLARED_UNVERIFIED**:缺相册与照片展示 DTO,不能猜 OSS URL、标题或说明字段 |
|
||||
| F09 写入照片记录 | `POST /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos`;路径两个 ID、鉴权、`clientid` 必填;`ossId:int64` 必填,`photoTitle/photoDesc/photographer/shootTime/sortOrder/status` 可选 | 已删除 mock 图片库、说明表单和本地预览 | **未完成 / BLOCKED_BY_MEDIA_OWNER**:接口接受的是既有 `ossId`,当前页面没有已核实的文件上传 owner 和真实 OSS 回执,不能把本地图片冒充上传成功 |
|
||||
|
||||
### F10 短视频
|
||||
|
||||
| 核对项 | Apifox 桌面端实读 | 当前页面/结论 |
|
||||
| --- | --- | --- |
|
||||
| 目录检索 | 以 `video` 检索,APP 目录仅返回“删除视频”;未返回视频列表、详情、发布、修改、播放地址、评论、点赞或分享 operation | F10 所需浏览和互动链路没有业务 owner,不能以参考项目或相册接口补造 |
|
||||
| 唯一命中动作 | `DELETE /genealogy/app/genealogies/{genealogyId}/videos/{videoId}`;接口说明为逻辑删除并释放视频文件和封面文件引用;鉴权、`genealogyId:int64`、`videoId:int64`、`clientid:string` 必填,`200 VoidResult` | 单一删除动作不能证明视频页面能读取、播放或发布;**F10 未完成 / MISSING_OPERATION**。不发起删除请求 |
|
||||
|
||||
## G 家谱工作区
|
||||
|
||||
### G01、G03、G05—G11
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面状态与结论 |
|
||||
| --- | --- | --- |
|
||||
| G01 我的家谱 | `GET /genealogy/app/genealogies/mine`;鉴权、`clientid:string` 必填;`200 ListResult` 仅通用 `code/msg/data[]` | 页面要展示当前家谱、可切换家谱、角色与快捷入口;当前 DTO 没有这些字段。**未完成 / DECLARED_UNVERIFIED** |
|
||||
| G03 创建家谱 | `POST /genealogy/app/genealogies`;`genealogyName`、`surname`、`regionCode` 必填;`ancestralHall/originPlace/addressDetail/coverOssId/intro/visibility/joinMode` 可选。`visibility`:`0` 私密、`1` 公开、`2` 成员可见;`joinMode`:`0` 关闭、`1` 审核、`2` 邀请码 | 表单提供全部可读资料字段;地区为三级级联选择器,封面只由真实上传回执产生,访问规则由可读选项映射为 `visibility/joinMode`。已删除本地家谱/首位人物预览。创建后必须从真实响应取得 `genealogyId` 再创建首位人物;当前没有可恢复查询 owner,不能从泛型 mine 列表按名称猜 ID | **未完成 / MISSING_OPERATION**:两阶段创建结果恢复链未闭合;写入与上传已接线,仍待人工真实响应核验 |
|
||||
| G05 家谱概览 | `GET /genealogy/app/genealogies/{genealogyId}/overview`;鉴权、`genealogyId:int64`、`clientid` 必填;`200 ObjectResult` 通用对象 | 页面需要家谱资料、成员/人物等概览显示;响应无 DTO。**未完成 / DECLARED_UNVERIFIED** |
|
||||
| G06 搜索公开家谱 | `GET /genealogy/app/genealogies/public` 已在 Apifox 目录确认;读取结果仍为通用 `ListResult` | 已删除本地搜索结果和申请跳转;名称、籍贯、简介、可加入状态、稳定 genealogyId 均未获声明。**未完成 / DECLARED_UNVERIFIED** |
|
||||
| G08 申请加入 | `POST /genealogy/app/genealogies/{genealogyId}/join-applies`;路径 `genealogyId:int64`、鉴权、`clientid` 必填;body `applicantName/phone/relationDesc/applyReason:string`、`inviterUserId:int64` 均可选 | 已删除本地填写预览;没有公开家谱详情、可申请权限或稳定 ID 投影时,不凭“可选”字段虚构申请上下文。**未完成 / DECLARED_UNVERIFIED**,不发送申请 |
|
||||
| G09 我的申请 | `GET /genealogy/app/genealogies/join-applies/mine`;鉴权、`clientid` 必填;`200 ListResult` 通用数组 DTO | 已删除 fixture 申请列表;申请名称、状态、原因、时间等展示字段无映射。**未完成 / DECLARED_UNVERIFIED** |
|
||||
| G10 审核申请 | `PUT /genealogy/app/genealogies/{genealogyId}/join-applies/{applyId}/audit`;路径两个 ID、鉴权、`clientid` 必填;`status:string` 必填,`auditRemark:string` 可选,返回 `VoidResult` | 已删除本地审核流程;待审核列表 DTO 和稳定 applyId 未声明。**未完成 / DECLARED_UNVERIFIED**,不执行审核写入 |
|
||||
| G11 家谱设置 | `PUT /genealogy/app/genealogies/{genealogyId}`;同一组字段为 `genealogyName/surname/ancestralHall/originPlace/regionCode/addressDetail/coverOssId/intro/visibility/joinMode`,文档均列可选 | 已删除 fixture 预填和本地预览;概览 DTO 不能安全预填,封面仍受上传 owner 阻塞。**未完成 / DECLARED_UNVERIFIED** |
|
||||
|
||||
### G12 字辈谱
|
||||
|
||||
| 核对项 | Apifox 桌面端实读 | 当前页面实情 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| 正常字辈读取 | `GET /genealogy/app/genealogies/{genealogyId}/generation-poems`;鉴权 `Authorization`、路径 `genealogyId:int64`、Header `clientid:string` 均必填。说明为仅返回正常状态字辈,供世系人物录入和展示使用 | 页面通过 `appApi.getGenerationPoems` 真实读取,展示 `generationNo/generationText/status`;响应归属、重复 poemId 和重复世代在 API 边界校验 | 已接线,等待真实响应核验;响应没有“当前世代”字段,页面已删除固定当前世代推断 |
|
||||
| 维护列表读取 | `GET /genealogy/app/genealogies/{genealogyId}/generation-poems/management`;同一鉴权、路径和 `clientid` 要求。说明为家谱内容编辑者访问,返回正常与停用字辈,供恢复、纠错和排序调整 | 点击维护先真实请求 `appApi.getGenerationPoemManagement`,成功才进入编辑;不再用 fixture 或角色推断权限 | 已接线,等待真实响应/权限核验;维护读取失败不伪造“无权限”或本地编辑状态 |
|
||||
| 单条新增/修改/停用恢复 | `POST /genealogy/app/genealogies/{genealogyId}/generation-poems`;`PUT /genealogy/app/genealogies/{genealogyId}/generation-poems/{poemId}`。后者路径另有 `poemId:int64` 必填;两者 body 均为:`generationNo:int64` 必填、`generationText:string` 必填且最大 50 字、`description:string` 可选且最大 500 字、`sortOrder:int64` 可选、`status:string` 可选(`0` 正常、`1` 停用) | 当前编辑器以一段本地文本拆分生成字辈行;没有单条 request mapper 或服务端返回处理 | 单条合同已明确,当前页面交互是批量维护模型;不能把本地状态切换写成停用/恢复成功,**未完成 / DECLARED_UNVERIFIED** |
|
||||
| 批量预览 | `POST /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/preview`;body `poemText:string` 必填、最大 26000 字,最多 500 世,可用空格、逗号、分号、顿号、斜杠或换行分隔;`disableMissing:boolean` 可选 | `appApi.previewGenerationPoemBatch` 只提交 `poemText/disableMissing`;页面展示服务端 `createCount/updateCount/keepCount/disableCount`,草稿或策略变化即使旧预览失效 | 响应 `GenerationPoemBatchPreviewView` 的计数字段和家谱归属已校验,等待真实响应核验;不再使用本地差异作为保存依据 |
|
||||
| 批量保存 | `POST /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/save`;请求体与批量预览相同;接口说明为按当前数据生成差异,停用不删除历史字辈记录;返回 `VoidResult` | 保存仅在当前草稿已有同签名服务端预览时调用,严格成功后读取维护列表;本地不再更新或宣称保存成功 | **未完成 / DECLARED_UNVERIFIED**:写入已接线,但无人值守未触发真实保存;需人工可观察结果和真实回读才能升级状态 |
|
||||
|
||||
## T 世系树与成员
|
||||
|
||||
### T01 世系树与人物操作面板
|
||||
|
||||
| 核对项 | Apifox 桌面端实读 | 当前页面实情 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| 世系树读取 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/tree`;鉴权 `Authorization`、路径 `genealogyId:int64`、Header `clientid:string` 均必填;`200 LineagePersonTreeResult` | `pages/tree/t01-tree-overview.vue` 已调用 `appApi.getTree`,但尚未作真实响应验证 | 不是“无接口”,但不能因代码存在而宣称页面已完成 |
|
||||
| 树节点响应字段 | `data: LineagePersonTreeView[]`:`personId/genealogyId/genealogyName/genealogyNo/appUserId/appUserNickName/personNo/name/aliasName/sex/generation/generationName/fatherId/fatherName/motherId/motherName/spouseNames/avatarOssId/birthDate/birthLunar/birthPlace/deathDate/deathLunar/deathPlace/burialPlace/personStatus/biography/sortOrder/status/remark/relationType/relationName/spouses[]/children[]`;`spouses` 为配偶节点、`children` 为递归子女节点 | 当前 mapper 只投影树布局所需 `id/parentId/name/relation/generation/branch/years/sex/personStatus`;人物卡和操作面板头像固定使用本地占位图,未消费 `avatarOssId`;父母、配偶、子女等可用响应关系也未完整展示 | **未完成 / DECLARED_UNVERIFIED**:必须补头像文件取址与字段投影,并在真实只读响应下核验树形关系,才能满足人物卡要求 |
|
||||
| 点击人物后的动作 | 页面已有“查看资料、添加父亲/母亲/配偶/兄弟姐妹/儿子/女儿、调整排行、编辑信息”动作入口,分别路由 T03/T04/T06/T05 | 父母、子女的 HTTP 动作实际分别共享 `/parents`、`/children`,页面未发送 `sex` 或 `relationName`,因此不能区分“父亲/母亲”“儿子/女儿”;邀请绑定在页面中明确标作不可用 | **未完成**:操作面板存在不等于每个业务动作闭环;性别语义和邀请绑定仍缺合同闭环 |
|
||||
| 邀请绑定 | 在 Apifox APP 目录分别以 `invite`、`bind` 全文检索,均未命中任何邀请签发、受邀人查询、人物绑定、绑定结果查询 operation | 页面也未伪造该流程 | **MISSING_OPERATION**:不以入谱申请或普通人物修改替代“邀请绑定” |
|
||||
|
||||
### T03 成员资料
|
||||
|
||||
| 核对项 | Apifox 桌面端实读 | 当前页面实情 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| 读取详情 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}`;鉴权、`genealogyId:int64`、`personId:int64`、`clientid` 均必填;`200 LineagePersonResult` | 页面调用 `appApi.getPerson` | 读取路径存在,但不是完成依据 |
|
||||
| 详情响应字段 | `data: LineagePersonView`:`personId/genealogyId/genealogyName/genealogyNo/appUserId/appUserNickName/personNo/name/aliasName/sex/generation/generationName/fatherId/fatherName/motherId/motherName/spouseNames/avatarOssId/birthDate/birthLunar/birthPlace/deathDate/deathLunar/deathPlace/burialPlace/personStatus/biography/sortOrder/status/remark` | 已把别名、性别字典值、人物状态字典值、出生/逝世农历、出生/逝世地点、安葬地、配偶名、生平和备注纳入 T03 mapper 与展示;仍未展示头像(缺 `avatarOssId` 取址)、`appUserNickName`、排序/状态原值,亲属仍只可由父母 ID 跳转。 | **未完成 / DECLARED_UNVERIFIED**:T03 仍是半成品,不能计入完成;字段已接线但未用真实只读响应核验,头像、完整亲属投影和字典语义仍未闭环。 |
|
||||
|
||||
### T04 添加亲属、T05 编辑、T06 排行
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面实情与结论 |
|
||||
| --- | --- | --- |
|
||||
| T04 首位成员/新增人物 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons`;鉴权、路径 `genealogyId`、`clientid` 必填;body 只有 `name:string` 必填。可选字段为 `appUserId/personNo/aliasName/sex/generation/generationName/fatherId/motherId/avatarOssId/birthDate/birthLunar/birthPlace/deathDate/deathLunar/deathPlace/burialPlace/personStatus/biography/sortOrder/remark/relationName`;其中 `personNo` 由服务端生成,`avatarOssId` 须来自文件上传组件 | 表单已提供并提交当前可安全映射的 `aliasName/generationName/birthDate/birthLunar/birthPlace/deathDate/deathLunar/deathPlace/burialPlace/biography/remark`;非首位成员同时提交关系选择产生的 `relationName`。性别、人物状态缺字典 owner;关联账号、父母、头像与排行需要独立对象选择、上传或原子排序 owner,不能让用户填写内部 ID 或猜码。真实写入未验证。**未完成 / DECLARED_UNVERIFIED** |
|
||||
| T04 添加父母、子女、兄弟姐妹、配偶 | 分别为 `POST .../lineage/persons/{personId}/parents`、`.../children`、`.../siblings`、`.../spouses`;路径 `genealogyId/personId`、鉴权、`clientid` 均必填,均返回 `LineagePersonResult`,body 与新增人物同合同。实读 `sex:string` 仅写“建议使用系统字典值”,示例为 `"0"`;以“字典/dict/性别”检索 APP/PC 目录均未找到该字典读取 owner 或男/女码值映射。 | 页面现会提交所选亲属的 `relationName`,不再把路由意图丢掉;父亲/母亲共用 `/parents`,儿子/女儿共用 `/children` 仍不能仅凭该显示名获得可靠性别语义。头像仍缺文件上传回执。**未完成 / DECLARED_UNVERIFIED**,不得拿参考项目的旧 `0/1` 码值猜填,也不能执行无人值守写入。 |
|
||||
| T05 修改人物 | `PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}`;两个路径 ID、鉴权、`clientid` 必填,body 与新增人物同合同,返回 `LineagePersonResult` | 已读写 `name/aliasName/generationName/birthDate/birthLunar/birthPlace/deathDate/deathLunar/deathPlace/burialPlace/biography/remark`;静态校验确认表单字段与请求白名单一致。头像仍缺上传回执;性别、人物状态、排行因字典或原子 owner 缺失未写入。 | **未完成 / DECLARED_UNVERIFIED**:已扩展为已声明的安全字段子集,但没有真实保存后的响应/回读,不能称完整人物编辑。 |
|
||||
| T06 调整排行 | Apifox 只有单人物 `PUT .../persons/{personId}` 中的可选 `sortOrder:int64`,没有同辈排行列表、批量重排、原子提交或冲突回显 operation | 页面已明确显示“服务暂未开放”,不逐人写入 | **未完成 / MISSING_OPERATION**:不能以单人 `sortOrder` 伪造同辈原子排行调整 |
|
||||
|
||||
### T07 成员目录、T08 成员状态
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面实情与结论 |
|
||||
| --- | --- | --- |
|
||||
| T07 成员目录分页与搜索 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/page`;query 可选 `pageNum`(默认 1)、`pageSize`(默认 10)、`keyword`(姓名/别名/人物编号)、`generation:int64`、`personStatus:string`;响应 `LineagePersonPageResult` 为 `rows: LineagePersonView[]` 与 `total`。另有 `GET .../lineage/persons/options?keyword=` 供人物选项读取 | 已移除 `listTreeMemberPresentationFixtures`;页面使用实际 `pageNum/pageSize/keyword` 请求、消费 `rows/total`,支持服务端搜索与继续加载;本地预览明确报真实读取不可用,不伪造目录数据。 | **未完成 / DECLARED_UNVERIFIED**:读取合同已接线并经静态检查,尚未用登录态获得一次真实 `rows/total` 响应;世代/人物状态筛选尚未增加页面控件。 |
|
||||
| T08 成员状态说明 | 人物详情、列表和分页都提供 `personStatus`、`status`;停用人物为 `DELETE /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}`,接口说明为逻辑停用且在正常子女时拒绝停用,返回 `VoidResult` | 已移除 `findTreeMemberPresentationFixture` 和 `privacy/deceased/forbidden` 推断;页面读取人物详情,但在无状态字典时不展示原始 `personStatus` 值,也不提供停用写入。 | **未完成 / DECLARED_UNVERIFIED**:读取已接线并经静态检查,仍未用真实只读响应核验;没有字典映射时不得展示内部码或生成隐私/受限/纪念文案。 |
|
||||
|
||||
## R 记录模块
|
||||
|
||||
### R01 人物录、R02 人物档案
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| R01 人物录列表、搜索 | 正确读取 owner 是 `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/page`;query 为 `pageNum/pageSize/keyword/generation/personStatus`,响应为 `rows: LineagePersonView[]/total`。人物选项另有 `GET .../lineage/persons/options?keyword=` | 已移除 `listTreeMemberPresentationFixtures` 和本地“新增预览”;页面用 `pageNum/pageSize/keyword` 请求、消费 `rows/total`,支持服务端搜索和继续加载。新增人物保持从 T01 亲属关系入口进入。 | **未完成 / DECLARED_UNVERIFIED**:读取合同已接线并经静态检查,尚未用登录态获得一次真实响应;世代/人物状态筛选尚未增加页面控件。 |
|
||||
| R02 人物档案读取 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` 返回已在 T03 实读的 `LineagePersonView`,含 `name/generation/generationName/biography/remark`,以及头像、性别、别名、亲属名、地点、生卒、状态等 | 已移除 `findTreeMemberPresentationFixture`、本地预览/编辑;页面读取详情并展示已声明的资料字段,编辑入口改为跳转 T03 的成员档案,再由 T05 完成可写字段维护。成长日志仍跳 R08,人生事仍为待开放。 | **未完成 / DECLARED_UNVERIFIED**:读取已接线并经静态检查,尚未取得真实详情响应;头像取址、性别/状态字典和完整亲属投影仍未闭环。 |
|
||||
| R02 新建/编辑人物 | `POST /lineage/persons`、`PUT /lineage/persons/{personId}` 的完整人物请求合同已在 T04/T05 实读,`name` 必填,其余有世代、头像、亲属、状态、排序、传记、备注等字段 | 表单只收 `name/generationName/generation/biography/remark`,保存仅变成本地预览 | **未完成 / DECLARED_UNVERIFIED**:是可辨认的字段子集但没有远端读写闭环;不得把“生成本地预览”说成新建或修改成功 |
|
||||
|
||||
### R03 贺礼簿、R04 往来详情与编辑
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| R03 列表、R04 详情 | `GET /genealogy/app/genealogies/{genealogyId}/relative-records`、`GET .../relative-records/{relativeId}`;均需鉴权、`genealogyId`、`clientid`,分别返回通用 `ListResult`、`ObjectResult`,未声明条目 DTO | 已删除 R03/R04 fixture 列表、详情和本地编辑预填;页面明确说明缺记录 ID、关系、事项、时间、金额和备注的响应映射 | **未完成 / DECLARED_UNVERIFIED**:接口并非缺失,但响应没有声明 `relativeId` 等展示字段,不能猜字段映射 |
|
||||
| R04 新增/修改 | `POST /genealogy/app/genealogies/{genealogyId}/relative-records`、`PUT .../relative-records/{relativeId}`;body 为 `relativeName:string` 必填,`relationName/eventName/eventTime/giftAmount:number/recordContent/mediaOssIds/sortOrder/status` 可选,返回通用 `ObjectResult` | 创建页提交姓名、关系、事项、时间、金额、备注、真实媒体回执和排序;`status` 无可读字典,不向用户暴露状态码。详情/修改入口因无记录 DTO/ID 来源关闭 | 创建已接线,等待真实写入响应核验;修改仍 **DECLARED_UNVERIFIED** |
|
||||
| R04 删除 | `DELETE .../relative-records/{relativeId}` 已在 Apifox 同一资源目录确认 | 页面明确显示“删除暂未开放” | **未完成 / DECLARED_UNVERIFIED**:不执行删除;存在删除 operation 也不改变其他读写未接线的事实 |
|
||||
|
||||
### R05—R07 礼仪活动与献礼
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| R05 礼仪活动列表、R07 新建 | 在 APP 目录以 `ceremony` 实读到该资源共六个动作:详情、修改、活动献礼列表、新增献礼、删除活动、删除献礼;没有活动列表或新建活动 operation | 已删除 `listCeremonyFixtures`、新建和编辑预览;R05/R07 显示缺 operation 状态并保留返回路径 | **未完成 / MISSING_OPERATION**:不得用详情或修改接口冒充活动列表/新建;R05、R07 的主业务 owner 缺失 |
|
||||
| R06 礼仪详情 | `GET /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}`;需鉴权、路径 `genealogyId/ceremonyId`、`clientid`,返回通用 `ObjectResult`;未声明活动 DTO | 已删除 fixture、受邀人拼装和编辑入口,只提示详情字段缺口 | **未完成 / DECLARED_UNVERIFIED**:详情 operation 存在,但这些展示字段、受邀人及其关系没有响应字段依据 |
|
||||
| R07 修改礼仪 | `PUT .../ceremonies/{ceremonyId}`;body `ceremonyType:string`、`ceremonyTitle:string` 必填,`ceremonyDesc/ceremonyTime/location/coverOssId/sortOrder/status` 可选,返回通用 `ObjectResult` | 无可靠详情 DTO 和活动 ID 来源时关闭修改,且封面另缺上传 owner | 表单字段虽可对应,但没有远端读取、写入和回读;**未完成 / DECLARED_UNVERIFIED** |
|
||||
| R06 献礼 | `GET .../ceremonies/{ceremonyId}/gifts` 返回通用 `ListResult`;`POST .../gifts` 的 body 为 `giverName:string` 可选、`giftAmount:number` 必填、`giftMessage:string` 可选,返回通用对象 | 页面有受邀人展示,不是献礼条目展示或写入 | **未完成 / DECLARED_UNVERIFIED**:献礼接口不能替代受邀信息,且没有条目 DTO 可映射 |
|
||||
|
||||
### R08 成长日志、R09 人生事
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| R08 列表与详情 | `GET /genealogy/app/genealogies/{genealogyId}/growth-records`、`GET .../growth-records/{recordId}`;同一 APP 资源另有新增、修改、删除,共五个动作。列表为通用 `ListResult`、详情为通用 `ObjectResult`,均未声明记录 DTO | 已删除 `listGrowthRecordFixtures` 和本地列表预览;页面只保留创建表单 | **未完成 / DECLARED_UNVERIFIED**:`recordId`、标题、日期、内容没有响应字段声明,不能恢复列表或详情 |
|
||||
| R08 新增/修改 | `POST .../growth-records`、`PUT .../growth-records/{recordId}`;新增 body 已实读:`lineagePersonId/recordType/recordContent/recordDate/remindTime/mediaOssIds/sortOrder/status` 可选,`recordTitle:string` 必填 | 从人物档案进入时自动绑定当前人物,表单提交类型、标题、内容、日期、提醒、真实媒体回执和排序;`status` 无可读字典,不向用户暴露状态码。修改没有记录 ID 来源而关闭 | 创建已接线,等待真实写入响应核验;修改 **DECLARED_UNVERIFIED** |
|
||||
| R09 人生事 | 分别以 `life` 与“人生”在 APP 接口目录检索,均未命中独立人生事件资源;当前文档中不能用成长、备忘或人物资料替代 | 页面已明确提示接口未开放且不展示/提交数据 | **未完成 / MISSING_OPERATION**:保持关闭是正确的,不虚构读写链路 |
|
||||
|
||||
### R10 家族备忘、R11 功德记录
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| R10 备忘列表与详情 | `GET /genealogy/app/genealogies/{genealogyId}/memos`、`GET .../memos/{memoId}`;同一资源另有新增、修改、删除,共五个动作。列表 `ListResult`、详情 `ObjectResult` 都只声明通用包装字段 | 已删除 fixture 列表和本地预览,只保留创建表单 | **未完成 / DECLARED_UNVERIFIED**:不能从泛型响应推导 `memoId` 或 `completedLabel`,状态文案也没有字典依据 |
|
||||
| R10 新增/修改 | `POST .../memos`、`PUT .../memos/{memoId}`;body `memoTitle:string` 必填,`memoContent/remindTime/completed/mediaOssIds/sortOrder/status` 可选 | 表单提交标题、日期与时间选择器生成的提醒时间、内容、真实媒体上传回执和排序。`completed/status` 未声明可读值或字典,均不向用户暴露 `0/1` 码。修改缺 ID 来源关闭 | 创建已接线,等待真实写入响应核验;修改 **DECLARED_UNVERIFIED** |
|
||||
| R11 功德列表 | `GET /genealogy/app/genealogies/{genealogyId}/merit-records`;同资源仅另有新增、删除,共三个动作;列表返回通用 `ListResult`,未声明条目 DTO | 已删除 fixture 列表和本地预览,只保留创建表单 | **未完成 / DECLARED_UNVERIFIED**:列表字段没有合同映射,页面不猜条目字段 |
|
||||
| R11 新增/修改 | `POST .../merit-records`;body `donorName:string`、`meritTitle:string` 必填,`meritType/meritContent/amount:number/meritTime/sortOrder/status` 可选;当前 APP 目录未见修改 operation | 表单提交捐赠人、标题、类型、金额、时间、内容和排序;`status` 缺可读字典,不向用户暴露状态码 | 新增已接线,等待真实写入响应核验;编辑 **MISSING_OPERATION** |
|
||||
|
||||
### 2026-07-24 实际服务端回读补充(覆盖上述 R03—R11 的旧“未验证”结论)
|
||||
|
||||
已用当前测试账号在家谱 2080557121112465409 完成真实创建和列表回读;未执行删除、退出、短信或改密操作。
|
||||
|
||||
| 资源 | 实际返回字段(已回读) | 页面闭环 |
|
||||
| --- | --- | --- |
|
||||
| 亲友往来 | relativeId、relativeName、relationName、eventName、eventTime、giftAmount、recordContent、mediaOssIds、sortOrder | R04 创建后由 R03 列表回读 |
|
||||
| 礼仪活动 | ceremonyId、ceremonyType、ceremonyTitle、ceremonyDesc、ceremonyTime、location、giftCount | R07 创建后由 R05 列表回读 |
|
||||
| 成长记录 | recordId、lineagePersonId、lineagePersonName、recordType、recordTitle、recordContent、recordDate、remindTime、mediaOssIds、sortOrder | R08 先读列表,创建后重新读取 |
|
||||
| 家族备忘 | memoId、memoTitle、memoContent、remindTime、completed、mediaOssIds、sortOrder | R10 先读列表,创建后重新读取;completed 未展示为业务状态 |
|
||||
| 功德记录 | meritId、donorName、meritType、meritTitle、meritContent、amount、meritTime、sortOrder | R11 先读列表,创建后重新读取并计算金额合计 |
|
||||
|
||||
以上五组的列表与创建状态均为 VERIFIED。单条详情、修改和删除仍按页面当前入口及测试范围分别保留,不把未测试能力标记为通过。
|
||||
|
||||
世系首位成员创建于同一测试家谱进行了页面提交和合同最小请求复核:POST lineage/persons 的合法最小 body(name、generation=1)均返回 HTTP 200、业务 code 500、消息“发生未知异常,请联系管理员”;随后 GET 世系树仍为空。该项为服务端业务异常,前端未猜测额外字段或伪造创建成功;T04 首位成员失败文案已明确为“首位成员尚未保存”。
|
||||
|
||||
## N 消息通知
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| N01 消息中心列表 | `GET /genealogy/app/notifications`;鉴权 `Authorization`、Header `clientid:string` 必填;`200 ListResult` 只声明通用 `code/msg/data[]`,条目仍为泛型对象 | 已删除 `listNotificationFixtures`、未读计数和本地业务跳转,只显示缺失通知字段合同 | **未完成 / DECLARED_UNVERIFIED**:没有消息 ID、已读、标题、时间、正文、目标类型和目标参数的响应字段合同;不能把 fixture 的跳转当作通知接口返回能力 |
|
||||
| N02 消息详情 | 在 APP 消息通知目录实读到的仅有列表、单条标已读、全部标已读三个 operation;没有详情读取 operation | 已删除详情 fixture,只显示缺详情 owner 状态 | **未完成 / MISSING_OPERATION**:不能以列表泛型或本地 fixture 冒充单条详情;详情所需正文、来源和跳转字段均无接口 owner |
|
||||
| N01/N02 单条标已读 | `POST /genealogy/app/notifications/{notificationId}/read`;鉴权、`notificationId:int64`、`clientid` 必填,返回 `VoidResult` | 无可消费通知 ID 时页面不显示单条标已读,已删除本地 `unread` 修改 | 正确写入 owner 存在但没有可回读 item/ID,**未完成 / DECLARED_UNVERIFIED** |
|
||||
| N01 全部标已读 | `POST /genealogy/app/notifications/read-all`;鉴权、`clientid` 必填,返回 `VoidResult` | 已删除“全部已读”本地 fixture 修改 | **未完成 / DECLARED_UNVERIFIED**:无列表回读时不把本地状态改动当服务端写入成功 |
|
||||
|
||||
## M 个人中心与账号
|
||||
|
||||
### M01 个人中心、M02 个人资料
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| M01 当前用户资料 | `GET /genealogy/app/auth/profile`;鉴权、`clientid` 必填,返回通用 `ObjectResult`,`data` 未声明用户 DTO | 已删除 `currentUser.name/role/phone` 和 fixture 未读数展示,保留各模块入口 | **未完成 / DECLARED_UNVERIFIED**:用户名、角色、手机号及其脱敏规则没有响应字段合同;不可把 mock 当前用户当作已登录资料 |
|
||||
| M02 读取与修改资料 | 读取为同一 `GET /auth/profile`;修改为 `PUT /genealogy/app/auth/profile`。修改 body 已实读:`nickName/avatarOssId/sex/birthday/provinceCode/cityCode/districtCode/addressDetail` 均可选,返回通用 `ObjectResult` | 已删除 mock 预填和本地保存;当前 UI 的真实姓名/邮箱与更新合同不相交,页面明确关闭编辑 | `nickName` 可对应,但 `realName/email` 不在修改合同;后端的头像、性别、生日、地区、地址未有页面输入或 mapper。**未完成 / DECLARED_UNVERIFIED**;头像另受上传 owner 阻塞 |
|
||||
|
||||
### M03—M05 安全设置、改密、换绑手机
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| M03 账号与安全概览 | 资料读取、改密、换绑均有各自 APP operation,未见独立“安全概览/设备/登录记录”读取 operation | 已删除本地账号摘要,保留改密与换绑入口 | **未完成 / DECLARED_UNVERIFIED**:入口可以保留,但安全状态、设备、会话等没有 owner,不能凭本地提示宣称已核验 |
|
||||
| M04 修改密码 | `PUT /genealogy/app/auth/password`;鉴权、`clientid` 必填;body `oldPassword:string`、`newPassword:string` 均必填且均为 32 位 MD5;返回 `VoidResult` | 页面将当前/新密码 MD5 后以 `oldPasswordHash/newPasswordHash` 传给 api 层,最终字段名映射为 `oldPassword/newPassword` | 请求字段、摘要格式和页面动作可对齐;但尚未在真实账号下接受响应验证,且不得无人值守改密。**未完成 / DECLARED_UNVERIFIED** |
|
||||
| M05 换绑手机号 | `PUT /genealogy/app/auth/phone`;鉴权、`clientid` 必填;body `clientId:string`、`phone:string`、`smsCode:string` 均必填,验证码模式为 4 位;响应为 `ObjectResult`(含 400/200) | 已删除 mock 当前手机号、输入和本地校验,页面明确提示需人工 TAC/短信与资料 DTO | 号码和四位码输入可对应,但缺实际滑动验证、短信发送、`clientId` 来源、写入与回读。**未完成 / DECLARED_UNVERIFIED**;不代用户发验证码或换绑 |
|
||||
|
||||
### M06 帮助、M07 反馈、M08 推广、M09 VIP、M10 关于
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读 | 当前页面展示或输入 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| M06 帮助中心 | `GET /genealogy/app/help-articles`、`GET /genealogy/app/help-articles/{articleId}`;列表为通用 `ListResult`、详情为通用对象,未声明文章 DTO | 页面本地内置分类、问题、答案和搜索 | **未完成 / DECLARED_UNVERIFIED**:帮助读取 owner 存在,但不能从泛型响应推导问题、答案、分类或文章 ID;当前本地说明不是服务端帮助 |
|
||||
| M07 提交反馈 | `POST /genealogy/app/feedback`;鉴权、`clientid` 必填;body `feedbackType:string` 可选、`feedbackContent:string` 必填、`contactInfo:string` 可选,返回通用 `ObjectResult` | 表单与 api 层正好提交这三字段,页面包含成功、失败、结果不确定的提示 | 请求合同已对应;未经真实接受响应验证,不能把 UI 成功态视为后端成功。**未完成 / DECLARED_UNVERIFIED**,不代用户提交反馈 |
|
||||
| M08 应用推广/邀请 | `GET /genealogy/app/promotions` 已存在,但仅为“应用推广列表”,返回通用 `ListResult`;全文检索未发现邀请码签发、归因、奖励、受邀绑定或分享回执 operation | M08 正确保持“推广能力未开放”,没有伪造邀请 | **未完成 / MISSING_OPERATION**:普通推广内容列表不能替代邀请推广业务闭环 |
|
||||
| M09 VIP 与订单 | APP 目录有 `GET /genealogy/app/vip/packages`、`GET /genealogy/app/vip/orders`、`POST /genealogy/app/vip/orders`;前两者列表响应为泛型。创建订单 body 为 `packageId:int64` 必填,`genealogyId:int64`、`payType:string` 可选,返回通用对象 | 页面当前不读取、不会创建订单或扣费 | **未完成 / DECLARED_UNVERIFIED**:套餐与订单 owner 存在但 DTO 未声明、页面未接线;支付调起、支付结果、取消/退款等动作在当前 APP 目录未形成可审计合同,故继续禁用付费流程 |
|
||||
| M10 关于与退出 | 协议、版本为本地静态内容;退出为 `DELETE /genealogy/app/auth/logout`,鉴权、`clientid` 必填,返回 `VoidResult` | M10 调用 api 层退出并且无论远端结果如何都会清本机会话 | 登出路径与合同一致,但未在真实请求下验证;协议/版本没有远端 owner 的需求。退出动作仍标 **DECLARED_UNVERIFIED**,不在无人值守状态触发 |
|
||||
|
||||
## A 认证
|
||||
|
||||
| 页面/动作 | Apifox 桌面端实读:业务接口、请求/响应字段 | 当前页面展示或输入字段 | 完成状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| A01 登录:验证前置与发送短信 | `GET /captcha/require`:查询 `tenantId/clientId/sceneCode/subject`,其中 `sceneCode` 必填;响应 `VerificationRequireResult` 已声明 `required/providerCode/captchaType/sceneCode/ttlSeconds`。`POST /genealogy/app/auth/sms/code`:Header `clientid` 必填;Body `clientId/grantType/tenantId/sceneCode/phone/validToken` 均必填,`sceneCode` 含 `APP_SMS_LOGIN`;响应 `VoidResult`。 | `a01-entry.vue` 以手机号、密码或四位短信码登录;取码先查验证要求,再由内嵌验证组件提交 `validToken`。滑动验证采用服务商组件本身,不增加页面自定义样式。 | **未完成 / DECLARED_UNVERIFIED**:前置响应字段与发送短信字段已逐项对上,但未发送短信;`required=false` 时如何签发可消费票据也未由 Apifox 合同说明,不能把页面本地倒计时当发送成功。 |
|
||||
| A01 账号密码登录 | `POST /genealogy/app/auth/login`:Header `clientid` 必填;Body `clientId/grantType/tenantId/phone/password` 均必填,`grantType=password`,`password` 为 32 位 MD5;响应组件为 `LoginResult`。 | 页面将手机号和 MD5 密码传至 API 层;当前 API 层读取响应 `access_token` 保存会话。登录接口请求体没有 `validToken` 字段,页面仅把滑动验证作为前端完成条件。 | **未完成 / DECLARED_UNVERIFIED**:请求字段对齐;Apifox 当前只标出 `LoginResult` 组件,未在该 operation 展开可核的会话字段,且尚未以测试账号获得一次被接受的响应,不能声明登录已完成。 |
|
||||
| A01 短信登录 | `POST /genealogy/app/auth/login/sms`:Header `clientid` 必填;Body `clientId/grantType/tenantId/phone/smsCode` 均必填,`grantType=sms`,`smsCode` 为四位短信码;响应组件为 `LoginResult`。 | 页面字段为手机号、四位验证码;API 层同样依赖返回的 `access_token` 建立会话。 | **未完成 / DECLARED_UNVERIFIED**:请求合同对齐,但该动作依赖真人收到短信;未发送、未登录,不把页面登录成功提示当成远端成功。 |
|
||||
| A04 注册 | 短信链路同上但 `sceneCode=APP_REGISTER`。`POST /genealogy/app/auth/register`:Header `clientid` 必填;Body 已实读 `clientId/grantType/tenantId/phone/password/smsCode`,`grantType=password`、密码为 32 位 MD5、验证码为四位;响应 `LoginResult`。 | 页面输入手机号、验证码、密码、确认密码和协议勾选;提交时传手机号、MD5 密码、验证码。 | **未完成 / DECLARED_UNVERIFIED**:字段链路可对照,但注册会创建真实账号,按约定不在无人值守时触发;`LoginResult` 的完整展示字段仍待接受响应核实。 |
|
||||
| A05 找回密码 | 短信链路同上但 `sceneCode=APP_FORGOT_PASSWORD`。`PUT /genealogy/app/auth/password/reset`:Header `clientid` 必填;Body `clientId/grantType/tenantId/phone/newPassword/smsCode` 均必填,`grantType=password`、`newPassword` 为 32 位 MD5、验证码为四位;响应 `VoidResult`。 | 页面输入手机号、验证码、新密码、确认密码;提交参数为手机号、MD5 新密码、验证码。 | **未完成 / DECLARED_UNVERIFIED**:请求字段对齐;找回会真实改密,未触发,不能以本地“修改成功”状态当接口完成。 |
|
||||
| A06 账号状态/恢复 | 在 APP 认证目录按 `status`、`frozen`、`disabled`、`risk`、`appeal`、`recovery` 检索,未找到账号状态读取、限制原因、申诉或恢复的独立 operation。 | 页面只读路由参数 `status`,并用本地 `frozen/disabled/risk` 文案展示限制原因和恢复说明;“查看恢复方式”仅打开本地弹层;该文件也未注册进 `pages.json` 的 52 条路由。 | **未完成 / MISSING_OPERATION**:没有后端 owner 提供状态、原因、可恢复路径或申诉结果,不能把静态文案当真实账号状态;未注册时也不能由正常路由到达。 |
|
||||
|
||||
## 本轮累计
|
||||
|
||||
| 范围 | 已逐页实读 | 可实施映射 | 未完成原因 |
|
||||
| --- | ---: | --- | --- |
|
||||
| F01—F10 | 10/10 | F02 发布、F03 评论读取/提交、F06 谱文创建、F07 相册创建已按声明字段接线;F01/F04/F05/F08/F09 已关闭无 DTO 或上传 owner 的 fixture 展示 | F02/F03/F06/F07 等待真实响应核验;动态、谱文和相册展示仍缺 DTO;F09 缺文件上传 owner,F10 缺读取/发布 owner;写入不得在无人值守时触发 |
|
||||
| G01、G03、G05—G12 | 9/9 | G12 正常列表、维护列表、批量预览/保存已按声明字段接线;G03/G06/G08—G11 已删除 fixture 或本地预览 | G12 待真实读取/写入响应核验,当前世代字段仍未声明;G03 两阶段结果恢复链、G06/G08—G11 的 DTO/ID/权限缺口仍未闭环 |
|
||||
| T01、T03—T08 | 7/7 | 树、详情、人物分页/选项、人物与亲属写入合同均已逐项实读;T03、T05、T07、T08 的已声明读取/字段子集已接线 | T03 明确为未完成;T01 头像与邀请绑定未闭环;T04 关系性别语义不完整;T06 缺原子排行 operation;T07/T08 均待真实读取响应核验 |
|
||||
| R01—R11 | 11/11 | R03/R04、R08、R10、R11 创建已按声明字段接线;R05—R07/R09 已删除本地流程 | 所有 R 列表/详情仍缺 DTO;创建待真实响应核验;R05/R07、R09 另有明确 `MISSING_OPERATION` |
|
||||
| N01—N02 | 2/2 | 消息列表、单条标已读、全部标已读 owner 已实读;页面已删除 fixture 消息和本地已读 | 列表条目 DTO 未声明、消息详情 operation 明确缺失,无稳定 ID 时不发送已读 mutation |
|
||||
| M01—M10 | 10/10 | M01—M03/M05 已删除 mock 资料和本地资料流程;改密、反馈、退出已有独立接线 | M02 字段与合同不一致;读取 DTO 多为泛型;M08 缺邀请业务 owner;VIP 还缺可审计支付闭环;敏感写入均未实测 |
|
||||
| A01、A04—A06 | 4/4 | 验证要求、短信发送、密码/短信登录、注册、找回密码的请求合同已逐项实读 | 无人值守不发送短信、不注册、不找回、不真实登录;`LoginResult` 仅见响应组件名,完整会话字段待接受响应;A06 明确缺状态/恢复 owner |
|
||||
@@ -1,57 +0,0 @@
|
||||
# MuMu 全页样式复核(2026-07-26)
|
||||
|
||||
## 范围与方法
|
||||
|
||||
- 设备:MuMu Android(SM-A5560),实际运行中的 APP WebView,900 × 1600 截图。
|
||||
- 范围:`pages.json` 的 52 个页面路由,以及测试账号可进入的列表、空态、错误态、新建表单和原生选择器状态。
|
||||
- 评审:三份独立结论——MuMu 实机逐页评审 1 份、核心表单代码/交互评审 1 份、家族与记录模块代码/交互评审 1 份。只采纳能由真实页面或已声明接口契约证实的结论。
|
||||
- 不使用 mock、fixture 或本地伪造成功。全部截图在 `tmp/mumu-visual-audit-20260726/`。
|
||||
|
||||
## 逐页复核结果
|
||||
|
||||
已逐页打开并复核以下 52 条路由:
|
||||
|
||||
- 认证:A01、A04、A05。
|
||||
- 家谱:G01、G03、G05、G06、G08、G09、G10、G11、G12。
|
||||
- 世系:T01、T03、T04、T05、T06、T07、T08。
|
||||
- 家族:F01、F02、F03、F04、F05、F06、F07、F08、F09、F10。
|
||||
- 记录:R01、R02、R03、R04、R05、R06、R07、R08、R09、R10、R11。
|
||||
- 消息:N01、N02。
|
||||
- 我的:M01、M02、M03、M04、M05、M06、M07、M08、M09、M10。
|
||||
|
||||
结论:已进入的页面均保持朱红、金线、宣纸背景和卷轴按钮这套既有视觉系统;未发现横向页面滚动、标题遮挡、内容与底部导航重叠。长内容、空态、接口错误态和可进入的新建表单均已按实际数据复核。
|
||||
|
||||
## 已落地且在 MuMu 复验的改动
|
||||
|
||||
1. G01 当前家谱的超长名称改为单行省略,避免末尾数字孤立换行。
|
||||
2. G05 长简介限制为两行,恢复被遮挡的世系树、字辈谱、审核、设置四张功能卡;家谱统计信息收回深色头图区域。
|
||||
3. F02 动态类型固定显示为“文字动态”,不再把接口枚举值暴露成可编辑输入框;上传按钮增至可触控尺寸。
|
||||
4. F03 未返回点赞状态时使用中性说明,不再把未知状态渲染成失败样式。
|
||||
5. F10、R09、N02、M03、M05、G12、M08 移除面向用户的接口、operation、Mock 等内部术语,改为可理解的功能状态说明。
|
||||
6. M01 默认头像使用项目真实 `auth-login-outline` 图;性别代码不再直接展示。M02 在没有服务端选项字典时显示“待确认 / 选项待提供”,不伪造选择项。
|
||||
7. R02 的“人生大事”改为明确的“暂未开放”状态,不再提供无效可点击入口。
|
||||
8. F02、F06、F07、F09、R07、R08、R10 的图片上传入口最小高度统一到 88rpx。
|
||||
9. R08 成长日志的记录、提醒时间,R11 功德记录的记录时间,全部改为系统日期/时间选择器;提交时仍使用接口既有 `YYYY-MM-DD HH:mm:ss` 文本字段。
|
||||
10. R08、R10、R11 的表单底部“取消 / 提交”按钮改为容器内的可收缩网格。修复了 MuMu 窄屏上右侧提交按钮被裁切的问题;三页都已实机复验。
|
||||
|
||||
## 选择器与输入原则
|
||||
|
||||
- 日期、时间:使用实际 Android 原生选择器,未改变后端字段名或格式。
|
||||
- 有确定自由文本语义的字段仍使用输入框,例如姓名、标题、地点、人物简介、备注。
|
||||
- 性别、人物状态、农历等需要枚举/字典的字段,当前接口未提供可用选项来源;未猜测中文标签或构造假选项。
|
||||
|
||||
## 不能通过前端补齐的状态
|
||||
|
||||
| 范围 | 真实结果 | 前端处理 |
|
||||
| --- | --- | --- |
|
||||
| 首位成员创建 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons` 使用最小合法 body 仍返回业务 `code:500` | 不伪造成员;T03–T08、R01–R02 的真实成员读取/写入闭环仍需后端修复或提供可读测试成员。 |
|
||||
| 性别、人物状态、农历等选择项 | 接口契约未提供枚举/字典来源 | 保留真实已返回值;未知值显示“待确认”,不将代码当中文含义解释。 |
|
||||
| 消息详情 | 当前测试数据没有可读的消息详情标识 | N02 复核了无详情状态和返回路径,未伪造详情内容。 |
|
||||
|
||||
## 本轮验证
|
||||
|
||||
- `powershell -NoProfile -ExecutionPolicy Bypass -File tests/compile-audit.ps1`:通过。
|
||||
- `powershell -NoProfile -ExecutionPolicy Bypass -File tests/r-business-flow-contract.ps1`:通过。
|
||||
- `powershell -NoProfile -ExecutionPolicy Bypass -File tests/active-page-business-ownership-contract.ps1`:通过。
|
||||
- MuMu 实机复验:R08、R10、R11 新建表单及其底部按钮;R08 日期选择器;G01、G05、F02、F03、F10、G12、N02、M01、M02、M03、M05、M08 的改动后状态。
|
||||
- 最后一轮 MuMu 路由复测:52/52 条路由均已重新截图完成,结果位于 `tmp/mumu-visual-audit-20260726/final-routes/`。
|
||||
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 6.5 MiB |
|
Before Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 354 KiB |
|
Before Width: | Height: | Size: 362 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 635 KiB |
|
Before Width: | Height: | Size: 387 KiB |
|
Before Width: | Height: | Size: 283 KiB |
|
Before Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 325 KiB |
|
Before Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 383 KiB |
|
Before Width: | Height: | Size: 325 KiB |
|
Before Width: | Height: | Size: 391 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 284 KiB |
|
Before Width: | Height: | Size: 433 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 325 KiB |
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 325 KiB |
|
Before Width: | Height: | Size: 387 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 416 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 428 KiB |
|
Before Width: | Height: | Size: 259 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 635 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 324 KiB |
|
Before Width: | Height: | Size: 414 KiB |
|
Before Width: | Height: | Size: 392 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
@@ -1,751 +0,0 @@
|
||||
# 产品参考页面功能映射表
|
||||
|
||||
> 规划日期:2026-07-23(北京时间)
|
||||
> 状态:需求已收口,作为《今晚全量联调与明早测试执行计划》的权威附件,三人交叉评审与用户确认均已完成;用户已明确开始执行,`T_due=2026-07-24 08:00`,55 个候选 PA 本轮维持 `approvedCandidateActions=0`。
|
||||
> 冻结规则:用户确认本附件仍不代表开始实现;只有用户明确说“开始执行”后才允许修改业务代码、接口接线、样式和测试,或运行测试、构建与 MuMu。
|
||||
|
||||
## 一、范围、优先级与计数
|
||||
|
||||
本附件只做产品甄别,不复制参考代码。优先级固定为:
|
||||
|
||||
1. 用户对当前 `jiapuapp` 的明确需求;
|
||||
2. 当前真实后端合同、线上文档和可复现响应;
|
||||
3. 当前项目的路由、架构、安全、国风视觉和无障碍基线;
|
||||
4. `C:\Users\Rain\Desktop\job\app设计`;
|
||||
5. `C:\Users\Rain\Desktop\job\Jiapu-App`。
|
||||
|
||||
基线计数:
|
||||
|
||||
| 对象 | 分母 | 本附件覆盖 |
|
||||
| --- | ---: | ---: |
|
||||
| 当前 `jiapuapp` 活动路由 | 52 | 52,沿用 `docs/接口与页面映射总表.md` 的 A/G/T/F/R/N/M 稳定编号 |
|
||||
| 设计参考文件 | 60=59 PNG+1 单页 PDF | 60,`D001`—`D060` |
|
||||
| 完成项目活动路由 | 78 | 78,`J001`—`J078` |
|
||||
| 完成项目注释路由声明 | 1 | 1,`JX001` |
|
||||
| 完成项目未注册页面文件 | 7 | 7,`JU01`—`JU07` |
|
||||
| 完成项目媒体资产 | 531 | 531 个进入资产候选池;实际采用前另建逐文件 `RAxxx` |
|
||||
| 本轮规划确认前批准的新增当前路由 | 0 | 0;候选先复用现有 owner 或保持关闭/待确认 |
|
||||
|
||||
完成项目 `pages.json` 共有 79 个 `path` 文本,其中 `pages/index/vertical-swiper/vertical-swiper` 整段被注释,因此活动路由分母是 78,不是 79;`pages/render/render` 已计入 78。
|
||||
|
||||
## 二、稳定 ID 与逐动作规则
|
||||
|
||||
- 设计证据的完整格式是 `Dxxx-Pxx-Sxx-Axx`:文件、页面/PDF 页、页面状态、来源证据基记录。当前每张单页 PNG 都作为独立 `S01` 状态证据,表内 `Dxxx-P01-Axx` 是省略 `S01` 的短写,不表示不同文件可以合并。
|
||||
- 完成项目的完整格式是 `Jxxx-Sxx-Axx`。同一路由上的正常、空、管理、编辑、权限等状态先区分,再对查看、创建、删除、邀请、支付等来源证据基记录编号;表内省略默认 `S01`。注释路由用 `JX001`,未注册文件用 `JUxx`。
|
||||
- 通常一个 `Axx` 对应一个独立动作。若旧截图或旧代码分支把多个控件不可分地记在同一物理证据中,基记录后必须追加稳定语义后缀,例如 `J073-A02@comment`、`@reaction`、`@share`;每个后缀分别绑定合同键、六类结论和 PA。341 只统计物理基记录,语义后缀不重复增加来源文件/代码记录,但不能用同一基号合并不同产品动作。
|
||||
- 当前产品 owner:沿用 A01、G01、T01、F01、R01、N01、M01 等编号。共享 owner 使用 `S-ID`、`S-PERM`、`S-FILE`、`S-REGION`、`S-SESSION`。
|
||||
- 一行可列同一页面的多个动作,但每个动作都必须有动作 ID、合同键和结论;不同结论不得合并。
|
||||
- 文件名、画面、路由或源码相似不能单独证明“重复”。它们可能是普通态、管理态、编辑态、空态、错误态、不同角色态或主题态;只有入口、对象、动作、数据、接口、权限和返回行为全部等价后才能共用当前 owner,源状态 ID 始终保留。
|
||||
|
||||
六类甄别结论固定为:`直接采用`、`改造后采用`、`仅参考交互`、`后端缺失,暂时关闭`、`与当前产品冲突,明确舍弃`、`待用户确认`。
|
||||
|
||||
所有动作继承以下门禁:
|
||||
|
||||
1. 正常、加载、空、失败、无权限、提交中、明确失败、结果未知、返回与重进状态按动作性质覆盖。
|
||||
2. 当前 OpenAPI 没有稳定 capability 投影;写入口在权限 owner 确认前只能显示禁用原因,403 不能反推权限。
|
||||
3. 所有 `int64` ID 必须先通过十进制字符串 wire 门禁;不安全 number 解析后禁止继续使用。
|
||||
4. 参考稿的亮红导航、旧 uView 控件、旧图标、固定尺寸和旧数据层不进入视觉目标;只借鉴信息结构,视觉统一回当前国风系统。
|
||||
5. `DECLARED_UNVERIFIED` 只表示受保护 OpenAPI 有声明;收到“开始执行”并取得本轮真实证据前,没有任何动作可预先标 `LIVE_VERIFIED`。
|
||||
|
||||
## 三、当前合同键
|
||||
|
||||
本节是源页面逐动作映射使用的唯一合同索引。每个键只能有一个 `contractState`,每个当前 operation 必须写成 `METHOD + 完整 path`。快照中有 operation 但已知 schema、权限、唯一 owner、结果确认或静态门禁冲突时,状态取更严重的 `CONTRACT_CONFLICT`;门禁脚本期望、但受保护快照没有的路径只能记为“门禁目标”,不能冒充当前 operation。当前没有任何键可预先标 `LIVE_VERIFIED`。
|
||||
|
||||
### 3.1 共享合同
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-S-ID` | OpenAPI 中所有 `genealogyId`、`personId`、`memberId`、`appUserId`、内容 ID、文件 ID、`avatarOssId` 及关系引用;无独立 operation | `CONTRACT_CONFLICT` | 当前 `int64` JSON number 不能满足 JavaScript 安全整数门禁;严格门禁包括 `genealogy-workspace-openapi-contract.ps1`、`g03-bootstrap-openapi-contract.ps1`、`lineage-openapi-contract.ps1`。所有 ID 动作继承本键。 |
|
||||
| `C-S-CAPABILITY` | 家谱、成员、世系等读取 DTO 中的服务端 capability/角色字段;无独立 operation | `CONTRACT_CONFLICT` | 快照没有闭合 `canView/canEdit/canInvite/canAudit/canDelete` owner,不能由前端角色名或一次 403 推测。 |
|
||||
| `C-S-CONTENT-LOCK` | 无跨谱文、成长记录和重要证件的统一访问密码/内容锁 operation | `MISSING_OPERATION` | 不得复用登录密码、A05 重置密码或参考项目三套旧 wrapper;若以后批准,必须先定义独立资源、可见性、校验、重置和限流 owner。 |
|
||||
| `C-S-PLATFORM-SHARE` | 当前 UniApp/Android 系统分享 adapter;无后端 operation | `NOT_APPLICABLE` | 唯一 owner 只负责调起平台分享、取消/失败和返回状态;分享内容必须由对应业务读取 owner 提供,例如 M08 当前活动家谱票据用 `C-G-INVITE-LIST`、APP 推广用 `C-M-PROMO`、宣传视频用 `C-M-PROMO-VIDEO`、F10 家族视频用 `C-F-VIDEO-READ`。未在冻结候选真机验证前产品动作最多为 `PARTIAL`。 |
|
||||
| `C-S-PLATFORM-CLIPBOARD` | 当前 UniApp/Android 系统剪贴板 adapter;无后端 operation | `NOT_APPLICABLE` | 唯一 owner 只负责复制动作、拒绝/失败和返回状态,不拥有被复制的票据或推荐码;业务内容分别来自 `C-G-INVITE-LIST`、`C-M-REFERRAL`。未在冻结候选真机验证前不得宣称复制成功。 |
|
||||
| `C-S-SAFE-EXTERNAL-OPEN` | 当前 UniApp/Android 外部链接打开 adapter 与目标 allowlist;无后端 operation | `NOT_APPLICABLE` | 唯一 owner 只负责 HTTPS、官方域名 allowlist、取消/失败和返回状态,不拥有下载地址内容;任意参考 URL、HTTP 地址或应用市场 scheme 均不得直接迁入。 |
|
||||
| `C-S-NAV` | 当前 `pages.json`、route key、参数 validator、返回与根切换的本地导航 owner;无后端 operation | `NOT_APPLICABLE` | 只拥有导航结构,不拥有目标页数据或权限;所有跨页 PA 自动继承,参考项目菜单不能绕过当前注册路由。 |
|
||||
| `C-LOCAL` | 协议、关于、版本号等经批准的正式本地静态 owner | `NOT_APPLICABLE` | 只适用于无需远端事实的内容,不能用于邀请码、通知详情、支付结果或人物资料。 |
|
||||
|
||||
### 3.2 A 认证与账号
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-A-TAC-API` | `GET /captcha/require`<br>`POST /captcha/challenge`<br>`POST /captcha/verify` | `CONTRACT_CONFLICT` | `auth-tac-openapi-contract.ps1` 是已知红灯;其中“密码登录必须消费 `validToken`”与已确认的“密码登录不接收 `validToken`、TAC 为客户端强制前置”冲突,执行时必须先修订门禁口径。 |
|
||||
| `C-A-TAC-A11Y` | 复用 `GET /captcha/require`、`POST /captcha/challenge`、`POST /captcha/verify`;`VerificationPayload` 声明多种验证码载荷 | `CONTRACT_CONFLICT` | 快照并非完全缺 operation;当前冲突是无拖动替代的服务端可用性、选择/降级语义和真机证据未闭合,`auth-android-accessibility-release-gate.ps1` 仍为红灯。 |
|
||||
| `C-A-LOGIN` | `POST /genealogy/app/auth/login` | `CONTRACT_CONFLICT` | 密码 wire、TAC 口径和会话结果未闭合;关联 `auth-tac-openapi-contract.ps1`、`password-change-openapi-contract.ps1`。 |
|
||||
| `C-A-SMS-SEND` | `POST /genealogy/app/auth/sms/code` | `CONTRACT_CONFLICT` | 公共发码场景、`validToken`、四位/六位 OTP 及换绑场景归属冲突;本键是该 path 的唯一 owner,注册和重置不得重复拥有。 |
|
||||
| `C-A-SMS-LOGIN` | `POST /genealogy/app/auth/login/sms` | `CONTRACT_CONFLICT` | OTP schema 与 TAC 发码闭环未通过 `auth-tac-openapi-contract.ps1`。 |
|
||||
| `C-A-REGISTER` | `POST /genealogy/app/auth/register` | `CONTRACT_CONFLICT` | OTP 和密码唯一 wire owner 未闭合;另依赖 `C-A-SMS-SEND`。 |
|
||||
| `C-A-RESET` | `PUT /genealogy/app/auth/password/reset` | `CONTRACT_CONFLICT` | OTP、密码策略及旧 MD5 路径冲突;另依赖 `C-A-SMS-SEND`。 |
|
||||
| `C-A-WECHAT` | 无 APP 微信登录 operation | `MISSING_OPERATION` | `GET /auth/code` 是遗留接口,不是可确认的当前 APP 微信登录 owner。 |
|
||||
| `C-A-PROFILE-READ` | `GET /genealogy/app/auth/profile` | `CONTRACT_CONFLICT` | 当前响应不能满足严格资料 DTO;关联 `profile-openapi-contract.ps1`。 |
|
||||
| `C-A-PROFILE-WRITE` | `PUT /genealogy/app/auth/profile` | `CONTRACT_CONFLICT` | dirty-only merge、版本/CAS、清空语义和结果未知恢复未闭合;关联 `profile-update-openapi-contract.ps1`。 |
|
||||
| `C-A-PASSWORD-CHANGE` | `PUT /genealogy/app/auth/password` | `CONTRACT_CONFLICT` | 密码 wire、全部会话撤销和稳定错误码未闭合;关联 `password-change-openapi-contract.ps1`。 |
|
||||
| `C-A-PHONE-SEND` | 无当前受保护的换绑专用发码 operation | `MISSING_OPERATION` | 门禁目标 `POST /genealogy/app/auth/phone/sms/code` 未出现在受保护快照;公共发码不得擅自替代。 |
|
||||
| `C-A-PHONE-CHANGE` | `PUT /genealogy/app/auth/phone` | `CONTRACT_CONFLICT` | 当前密码、新号 OTP、会话撤销和结果语义未闭合;关联 `phone-change-openapi-contract.ps1`。 |
|
||||
| `C-A-DEACTIVATE` | `POST /genealogy/app/auth/account/deactivate` | `CONTRACT_CONFLICT` | `AccountDeactivateBody.smsCode` 的四位内联 schema 与 `phone-change-openapi-contract.ps1` 要求的统一短信 Secret/六位口径冲突;另依赖 `C-A-SMS-SEND`。敏感操作仅限人工窗口。 |
|
||||
| `C-A-LOGOUT` | `DELETE /genealogy/app/auth/logout` | `CONTRACT_CONFLICT` | token/client 归属、幂等和终态错误未闭合;关联 `logout-openapi-contract.ps1`。 |
|
||||
|
||||
### 3.3 G 家谱、行政区划、申请与成员
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-S-REGION-CHILDREN` | `GET /genealogy/region/children` | `DECLARED_UNVERIFIED` | 共享行政区划 owner;待线上字段和层级语义验真。 |
|
||||
| `C-S-REGION-PATH` | `GET /genealogy/region/path/{regionCode}` | `DECLARED_UNVERIFIED` | 待祖先路径顺序和缺失码语义验真。 |
|
||||
| `C-S-REGION-SEARCH` | `GET /genealogy/region/search` | `CONTRACT_CONFLICT` | `g03-bootstrap-openapi-contract.ps1` 错把目标写成未声明的 `GET /genealogy/app/region/search`,门禁必须按快照真实路径重订。 |
|
||||
| `C-S-REGION-DETAIL` | `GET /genealogy/region/{regionCode}` | `DECLARED_UNVERIFIED` | 待详情字段验真。 |
|
||||
| `C-G-MINE` | `GET /genealogy/app/genealogies/mine` | `CONTRACT_CONFLICT` | 通用列表响应不能提供稳定 ID、角色和 capability;关联 `genealogy-workspace-openapi-contract.ps1`、`g03-bootstrap-openapi-contract.ps1`。 |
|
||||
| `C-G-PUBLIC` | `GET /genealogy/app/genealogies/public` | `CONTRACT_CONFLICT` | 搜索游标、结果 DTO 和错误语义未满足 `join-application-openapi-contract.ps1`。 |
|
||||
| `C-G-OPTIONS` | `GET /genealogy/app/genealogies/options` | `DECLARED_UNVERIFIED` | 不能在未验真前与 public/mine 列表混用。 |
|
||||
| `C-G-DETAIL-READ` | `GET /genealogy/app/genealogies/{genealogyId}` | `CONTRACT_CONFLICT` | 通用对象响应且与 overview 形成两个单谱读取候选;关联 `genealogy-workspace-openapi-contract.ps1`。 |
|
||||
| `C-G-OVERVIEW` | `GET /genealogy/app/genealogies/{genealogyId}/overview` | `CONTRACT_CONFLICT` | 稳定 DTO、访问状态和 capability 未闭合;关联 workspace、G03、G11 门禁。 |
|
||||
| `C-G-SETTINGS` | `PUT /genealogy/app/genealogies/{genealogyId}` | `CONTRACT_CONFLICT` | dirty-only merge、版本/CAS、权限和 pending 申请保护未闭合;关联 `g11-settings-openapi-contract.ps1`。 |
|
||||
| `C-G-CREATE-GENEALOGY` | `POST /genealogy/app/genealogies` | `CONTRACT_CONFLICT` | G03 第一次写只有通用结果,不能确认稳定 `genealogyId`、幂等和结果未知状态。 |
|
||||
| `C-T-PERSON-CREATE` | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons` | `CONTRACT_CONFLICT` | G03 第二次写兼通用人物创建 owner;根人物保护、稳定 `personId`、ID wire 和权限未闭合。 |
|
||||
| `C-G-CREATE-RECOVERY` | 无可确认的幂等结果查询或创建续办 operation | `MISSING_OPERATION` | mine/overview 的存在不能证明可安全恢复第一次写;门禁目标 `GET /genealogy/app/genealogy-bootstrap-operations/{operationKey}` 未声明。现有 G03 两个门禁仍按原子 bootstrap 设计,与已确认两阶段方案冲突,执行时须先重订。 |
|
||||
| `C-G-JOIN-CREATE` | `POST /genealogy/app/genealogies/{genealogyId}/join-applies` | `CONTRACT_CONFLICT` | 幂等 receipt、稳定申请 ID 和结果语义未闭合;关联 `join-application-openapi-contract.ps1`。 |
|
||||
| `C-G-JOIN-RECOVERY` | 无当前申请提交结果查询 operation | `MISSING_OPERATION` | 门禁目标 `GET /genealogy/app/genealogies/join-apply-requests/{requestKey}` 未声明。 |
|
||||
| `C-G-JOIN-MINE` | `GET /genealogy/app/genealogies/join-applies/mine` | `CONTRACT_CONFLICT` | 游标和 typed item 未闭合。 |
|
||||
| `C-G-JOIN-WITHDRAW` | `DELETE /genealogy/app/genealogies/join-applies/{applyId}` | `CONTRACT_CONFLICT` | 权限、幂等和稳定结果未闭合。 |
|
||||
| `C-G-JOIN-PENDING` | `GET /genealogy/app/genealogies/{genealogyId}/join-applies/pending` | `CONTRACT_CONFLICT` | capability、游标和 typed item 未闭合。 |
|
||||
| `C-G-JOIN-AUDIT` | `PUT /genealogy/app/genealogies/{genealogyId}/join-applies/{applyId}/audit` | `CONTRACT_CONFLICT` | 审核权限、并发、重复审核和结果 receipt 未闭合。 |
|
||||
| `C-G-INVITE-LIST` | 无当前可邀请家谱/活动票据列表或单票据读取 operation | `MISSING_OPERATION` | M08 不得从本地列表推断邀请权限,也不得用静态票据恢复签发/撤销结果。 |
|
||||
| `C-G-INVITE-ISSUE` | 无当前家谱邀请票据签发 operation | `MISSING_OPERATION` | 门禁目标幂等签发 path 未出现在受保护快照;响应未知时只能经权威列表恢复,不得再次盲签。 |
|
||||
| `C-G-INVITE-REVOKE` | 无当前家谱邀请票据撤销 operation | `MISSING_OPERATION` | 门禁目标撤销 path 未出现在受保护快照;撤销竞态与未知结果必须经权威列表收敛。 |
|
||||
| `C-G-INVITE-RESOLVE` | 无当前邀请码解析 operation | `MISSING_OPERATION` | 不得以本地解码、旧 wrapper 或普通搜索代替。 |
|
||||
| `C-G-INVITE-REDEEM` | 无当前邀请码兑换/直接入谱 operation | `MISSING_OPERATION` | 不得借普通加入申请绕过独立邀请语义。 |
|
||||
| `C-G-INVITE-RESULT` | 无当前邀请码兑换结果查询 operation | `MISSING_OPERATION` | 结果未知时不得重复提交。 |
|
||||
| `C-G-POEM` | `GET /genealogy/app/genealogies/{genealogyId}/generation-poems`<br>`POST /genealogy/app/genealogies/{genealogyId}/generation-poems`<br>`POST /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/preview`<br>`POST /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/save`<br>`GET /genealogy/app/genealogies/{genealogyId}/generation-poems/management`<br>`PUT /genealogy/app/genealogies/{genealogyId}/generation-poems/{poemId}` | `CONTRACT_CONFLICT` | `g12-generation-poem-openapi-contract.ps1` 要求另一套唯一 GET/PUT、版本/CAS 和旧入口移除,门禁目标与当前六个 operation 不一致。 |
|
||||
| `C-G-MEMBER-READ` | `GET /genealogy/app/genealogies/{genealogyId}/members`<br>`GET /genealogy/app/genealogies/{genealogyId}/members/options` | `CONTRACT_CONFLICT` | 成员与世系人物身份、typed item 和 capability 未闭合。 |
|
||||
| `C-G-MEMBER-UPDATE` | `PUT /genealogy/app/genealogies/{genealogyId}/members/{memberId}` | `CONTRACT_CONFLICT` | body 中 `lineagePersonId` 同时成为邀请绑定候选,尚无唯一 mutation owner。 |
|
||||
| `C-G-MEMBER-REMOVE` | `DELETE /genealogy/app/genealogies/{genealogyId}/members/{memberId}` | `CONTRACT_CONFLICT` | 移除权限、所有者保护和结果未知处理未闭合。 |
|
||||
| `C-G-MEMBER-LEAVE` | `DELETE /genealogy/app/genealogies/{genealogyId}/members/me` | `CONTRACT_CONFLICT` | 本人退出约束、最后管理员/所有者保护及终态未闭合。 |
|
||||
| `C-G-MEMBER-TRANSFER` | `PUT /genealogy/app/genealogies/{genealogyId}/members/owner-transfer` | `CONTRACT_CONFLICT` | 高风险权限迁移、并发和结果确认未闭合。 |
|
||||
| `C-G-SORT` | 无家谱批量排序或始祖世代安全 operation | `MISSING_OPERATION` | 不能复用人物 `sortOrder` 或字辈接口。 |
|
||||
| `C-G-ADMIN` | 无管理员列表、授权和细粒度 capability operation | `MISSING_OPERATION` | members operation 不能在无明确角色/capability 合同时替代。 |
|
||||
| `C-G-DELETE` | 无当前删除家谱 operation | `MISSING_OPERATION` | 参考项目 `delGenealogy` 不是当前合同;不得借设置 PUT、成员退出或本地移除列表伪装删除。 |
|
||||
|
||||
`invite-ticket-openapi-contract.ps1` 中以下目标路径均未出现在受保护快照,只是门禁目标:`GET /genealogy/app/genealogies/{genealogyId}/invite-tickets/mine`、`POST /genealogy/app/genealogies/{genealogyId}/invite-tickets`、`DELETE /genealogy/app/genealogies/{genealogyId}/invite-tickets/{inviteTicketId}`、`POST /genealogy/app/genealogy-invite-tickets/resolve`、`POST /genealogy/app/genealogy-invite-redemptions`、`GET /genealogy/app/genealogy-invite-redemption-requests/{requestKey}`。
|
||||
|
||||
### 3.4 T 世系与邀请绑定
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-T-TREE` | `GET /genealogy/app/genealogies/{genealogyId}/lineage/tree` | `CONTRACT_CONFLICT` | 当前通用树不能满足头像卡、稳定图关系、窗口化、遮蔽和权限合同;`lineage-openapi-contract.ps1` 的 v2 路径只是未声明目标。 |
|
||||
| `C-T-DETAIL` | `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` | `CONTRACT_CONFLICT` | 通用对象、ID/capability 未闭合,T03 仍是 fixture 半成品;关联 `t03-member-remote-contract.ps1`。 |
|
||||
| `C-T-LIST` | `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons`<br>`GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/page`<br>`GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/options` | `CONTRACT_CONFLICT` | 三个读取 owner 的边界、typed item、ID 和 capability 未闭合。 |
|
||||
| `C-T-PARENT` | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/parents` | `CONTRACT_CONFLICT` | 父/母意图、`sex` enum、重复关系、图版本和权限未闭合。 |
|
||||
| `C-T-SPOUSE` | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/spouses` | `CONTRACT_CONFLICT` | 关系方向、重复/冲突、图版本和权限未闭合。 |
|
||||
| `C-T-SIBLING` | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/siblings` | `CONTRACT_CONFLICT` | 性别、共同父母、排行和关系原子性未闭合。 |
|
||||
| `C-T-CHILD` | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/children` | `CONTRACT_CONFLICT` | 儿/女 `sex` enum、另一父母、排行和关系原子性未闭合。 |
|
||||
| `C-T-EDIT` | `PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` | `CONTRACT_CONFLICT` | 宽 body、字段白名单、并发、头像链及 `appUserId` 绑定混入同一 PUT。 |
|
||||
| `C-T-RANK` | 候选但非独立 owner:`PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` | `CONTRACT_CONFLICT` | 只有单人物 `sortOrder`,没有同辈原子重排、冲突版本或完整结果;正式 PUT owner 仍是 `C-T-EDIT`。 |
|
||||
| `C-T-BIND-INVITE` | 无当前人物邀请签发、送达和接受 operation | `MISSING_OPERATION` | 家谱票据目标也未声明,且不能证明等于“绑定某一人物”。 |
|
||||
| `C-T-BIND-IDENTITY` | 无受邀账号身份查找或安全匹配 operation | `MISSING_OPERATION` | 不得按手机号、昵称或参考本地数据猜 `appUserId/memberId`。 |
|
||||
| `C-T-BIND-MUTATION` | 冲突候选:`PUT /genealogy/app/genealogies/{genealogyId}/members/{memberId}`<br>冲突候选:`PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` | `CONTRACT_CONFLICT` | 一个写 `lineagePersonId`,一个写 `appUserId`;快照没有指定唯一 owner、原子性或禁止双写规则。 |
|
||||
| `C-T-BIND-RESULT` | 无当前人物绑定结果查询 operation | `MISSING_OPERATION` | 结果未知时不得重试或双写。 |
|
||||
| `C-T-DELETE` | `DELETE /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` | `CONTRACT_CONFLICT` | 当前语义更接近停用;根人物、被引用人物、权限及图版本未闭合。 |
|
||||
|
||||
### 3.5 文件链
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-S-FILE-BINARY-WRITE` | `POST /genealogy/app/files/upload`<br>`POST /genealogy/app/files/resumable/init`<br>`POST /genealogy/app/files/resumable/chunk`<br>`POST /genealogy/app/files/resumable/complete` | `CONTRACT_CONFLICT` | 上传成功结果、`ossId` 安全 wire、断点续传幂等及完成后可访问事实未闭合。 |
|
||||
| `C-S-FILE-REFERENCE-WRITE` | `POST /genealogy/app/files/reference`<br>`DELETE /genealogy/app/files/reference` | `CONTRACT_CONFLICT` | 引用对象身份、重复引用、删除引用与删除二进制边界未闭合。 |
|
||||
| `C-S-FILE-READ` | 无按 `ossId`/文件 ID 恢复可访问 URL 或授权读取的 GET operation | `MISSING_OPERATION` | 上传返回值或历史 URL 不能替代冷启动读取 owner。 |
|
||||
|
||||
### 3.6 F 家族内容
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-F-FEED-READ` | `GET /genealogy/app/genealogies/{genealogyId}/feeds`<br>`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}` | `CONTRACT_CONFLICT` | 读 DTO、游标、作者投影和媒体策略未闭合;关联 `family-feed-read-openapi-contract.ps1`。 |
|
||||
| `C-F-FEED-PAGE-LEGACY` | `GET /genealogy/app/genealogies/{genealogyId}/feeds/page` | `CONTRACT_CONFLICT` | 门禁识别为应移除的重复读取 owner。 |
|
||||
| `C-F-FEED-WRITE` | `POST /genealogy/app/genealogies/{genealogyId}/feeds`<br>`PUT /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}`<br>`POST /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/likes`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/likes` | `DECLARED_UNVERIFIED` | 媒体另依赖文件链,所有 ID 另依赖 `C-S-ID`。 |
|
||||
| `C-F-FEED-MODERATION` | 无动态置顶或加精 operation | `MISSING_OPERATION` | 不能用 `sortOrder/status` 猜测管理语义,也不能只改本地列表。 |
|
||||
| `C-F-COMMENT-READ` | `GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments`<br>`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}/replies` | `CONTRACT_CONFLICT` | 根评论/回复投影、删除占位和游标语义未闭合。 |
|
||||
| `C-F-COMMENT-PAGE` | `GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/page`<br>`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}/replies/page` | `CONTRACT_CONFLICT` | `/comments/page` 是重复 owner 候选,回复分页也须与 canonical 读取统一。 |
|
||||
| `C-F-COMMENT-WRITE` | `POST /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}` | `DECLARED_UNVERIFIED` | 回复创建只在 `parentCommentId` 真实语义确认后复用 POST。 |
|
||||
| `C-F-ARTICLE` | `GET /genealogy/app/genealogies/{genealogyId}/article-categories`<br>`GET /genealogy/app/genealogies/{genealogyId}/articles`<br>`POST /genealogy/app/genealogies/{genealogyId}/articles`<br>`GET /genealogy/app/genealogies/{genealogyId}/articles/{articleId}`<br>`PUT /genealogy/app/genealogies/{genealogyId}/articles/{articleId}`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/articles/{articleId}` | `DECLARED_UNVERIFIED` | 分类只有读取;文章字段、富文本和媒体白名单待验真。 |
|
||||
| `C-F-ARTICLE-CATEGORY-WRITE` | 无谱文分类新增、编辑或删除 operation | `MISSING_OPERATION` | 分类读取不能反推分类管理能力,不得借文章 POST/PUT 代替。 |
|
||||
| `C-F-ALBUM` | `GET /genealogy/app/genealogies/{genealogyId}/albums`<br>`POST /genealogy/app/genealogies/{genealogyId}/albums`<br>`PUT /genealogy/app/genealogies/{genealogyId}/albums/{albumId}`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/albums/{albumId}` | `DECLARED_UNVERIFIED` | 封面媒体和删除语义另受文件与权限门禁约束。 |
|
||||
| `C-F-PHOTO-READ` | `GET /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos` | `DECLARED_UNVERIFIED` | 照片访问 URL 仍依赖 `C-S-FILE-READ`。 |
|
||||
| `C-F-PHOTO-WRITE` | `POST /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos/{photoId}` | `DECLARED_UNVERIFIED` | 新增照片是“文件写+照片记录写”两段动作。 |
|
||||
| `C-F-PHOTO-EDIT` | 无照片元数据编辑 operation | `MISSING_OPERATION` | 不得借相册 PUT 或本地数组修改。 |
|
||||
| `C-F-VIDEO-DELETE` | `DELETE /genealogy/app/genealogies/{genealogyId}/videos/{videoId}` | `DECLARED_UNVERIFIED` | 孤立删除没有读取对象来源时不得启用。 |
|
||||
| `C-F-VIDEO-READ` | 无视频列表、详情或播放资源读取 operation | `MISSING_OPERATION` | 不使用参考项目 URL 或全局 store 代替。 |
|
||||
| `C-F-VIDEO-WRITE` | 无视频发布或编辑 operation | `MISSING_OPERATION` | 文件上传不等于视频实体发布。 |
|
||||
| `C-F-VIDEO-COMMENT` | 无家族视频评论读取、发表、回复或删除 operation | `MISSING_OPERATION` | 动态评论 `C-F-COMMENT-*` 只拥有 feed 资源,不能跨资源复用为视频评论。 |
|
||||
| `C-F-VIDEO-REACTION` | 无家族视频点赞/取消点赞 operation | `MISSING_OPERATION` | 不得用本地计数、动画或参考项目裸请求冒充服务端反应状态。 |
|
||||
|
||||
### 3.7 R 族务记录
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-R-RELATIVE` | `GET /genealogy/app/genealogies/{genealogyId}/relative-records`<br>`POST /genealogy/app/genealogies/{genealogyId}/relative-records`<br>`GET /genealogy/app/genealogies/{genealogyId}/relative-records/{relativeId}`<br>`PUT /genealogy/app/genealogies/{genealogyId}/relative-records/{relativeId}`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/relative-records/{relativeId}` | `DECLARED_UNVERIFIED` | 收/送方向、金额精度、人物关联和权限待验真。 |
|
||||
| `C-R-CEREMONY` | `GET /genealogy/app/genealogies/{genealogyId}/ceremonies`<br>`POST /genealogy/app/genealogies/{genealogyId}/ceremonies`<br>`GET /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}`<br>`PUT /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}`<br>`GET /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/gifts`<br>`POST /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/gifts`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/gifts/{giftId}` | `DECLARED_UNVERIFIED` | 祭祀献礼不能直接等同参考“贺礼邀请”。 |
|
||||
| `C-R-GROWTH` | `GET /genealogy/app/genealogies/{genealogyId}/growth-records`<br>`POST /genealogy/app/genealogies/{genealogyId}/growth-records`<br>`GET /genealogy/app/genealogies/{genealogyId}/growth-records/{recordId}`<br>`PUT /genealogy/app/genealogies/{genealogyId}/growth-records/{recordId}`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/growth-records/{recordId}` | `DECLARED_UNVERIFIED` | 人物 ID、分类 enum 和媒体字段待验真。 |
|
||||
| `C-R-MEMO` | `GET /genealogy/app/genealogies/{genealogyId}/memos`<br>`POST /genealogy/app/genealogies/{genealogyId}/memos`<br>`GET /genealogy/app/genealogies/{genealogyId}/memos/{memoId}`<br>`PUT /genealogy/app/genealogies/{genealogyId}/memos/{memoId}`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/memos/{memoId}` | `DECLARED_UNVERIFIED` | 日期、提醒和权限字段待验真。 |
|
||||
| `C-R-MERIT-BASE` | `GET /genealogy/app/genealogies/{genealogyId}/merit-records`<br>`POST /genealogy/app/genealogies/{genealogyId}/merit-records`<br>`DELETE /genealogy/app/genealogies/{genealogyId}/merit-records/{meritId}` | `DECLARED_UNVERIFIED` | 只支持列表、新增和单删;图片另依赖文件链。 |
|
||||
| `C-R-MERIT-DETAIL` | 无功德详情 operation | `MISSING_OPERATION` | 列表项投影不能伪装远端详情。 |
|
||||
| `C-R-MERIT-EDIT` | 无功德编辑 operation | `MISSING_OPERATION` | 不得用再次 POST 猜测新增/编辑复用语义。 |
|
||||
| `C-R-LIFE` | 无人生事件 operation | `MISSING_OPERATION` | 保持关闭。 |
|
||||
| `C-R-DOCUMENT` | 无重要证件 operation | `MISSING_OPERATION` | 隐私敏感,不能迁移参考旧接口或示例数据。 |
|
||||
| `C-R-GREETING` | 无独立“贺礼邀请”列表、详情、增改删 operation | `MISSING_OPERATION` | `relative-records` 是人情往来,`ceremonies/gifts` 是祭祀/献礼;二者都不能因名称接近而冒充本业务。 |
|
||||
|
||||
### 3.8 N 通知
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-N-LIST` | `GET /genealogy/app/notifications` | `CONTRACT_CONFLICT` | 当前是无稳定 item/type/target schema 的通用列表;关联 `notification-read-openapi-contract.ps1`。 |
|
||||
| `C-N-UNREAD-COUNT` | 无当前未读数 operation | `MISSING_OPERATION` | 门禁目标 `GET /genealogy/app/notifications/unread-count` 未声明。 |
|
||||
| `C-N-READ-ONE` | `POST /genealogy/app/notifications/{notificationId}/read` | `CONTRACT_CONFLICT` | 幂等、当前账号归属及稳定结果未闭合。 |
|
||||
| `C-N-READ-ALL` | `POST /genealogy/app/notifications/read-all` | `CONTRACT_CONFLICT` | 当前账号范围、幂等和结果未闭合。 |
|
||||
| `C-N-DETAIL-SAME-SESSION` | 本地 owner:N01 当前会话不可变列表项快照;来源仍是 `GET /genealogy/app/notifications` | `CONTRACT_CONFLICT` | 同会话投影可保留,但列表 item/type/target schema 不稳定;不得猜业务深链。 |
|
||||
| `C-N-DETAIL-COLD-START` | 无通知详情或按通知 ID 重取 operation | `MISSING_OPERATION` | 冷启动、进程重启、深链或快照丢失时诚实关闭。 |
|
||||
| `C-N-TYPED-REMINDER` | 候选复用 `GET /genealogy/app/notifications` | `CONTRACT_CONFLICT` | 现有列表缺稳定生日/疫苗/备忘等 type、目标 route key、参数和权限失效 schema,不能从文案猜类型。 |
|
||||
|
||||
### 3.9 M 我的
|
||||
|
||||
| 合同键 | 当前 operation 或唯一 owner | `contractState` | 当前阻塞和门禁 |
|
||||
| --- | --- | --- | --- |
|
||||
| `C-M-HELP-LIST` | `GET /genealogy/app/help-articles` | `CONTRACT_CONFLICT` | 完整列表 DTO 未满足 `help-center-openapi-contract.ps1`。当前 M06 的文章阅读必须由列表项投影承接。 |
|
||||
| `C-M-HELP-DETAIL` | `GET /genealogy/app/help-articles/{helpId}` | `CONTRACT_CONFLICT` | operation 已声明,但当前门禁指定完整列表为唯一远端 owner;规划不新增独立详情路由,先统一 owner 后才可启用本键。 |
|
||||
| `C-M-FEEDBACK` | `GET /genealogy/app/feedback`<br>`POST /genealogy/app/feedback` | `DECLARED_UNVERIFIED` | 列表范围、提交幂等和结果未知处理待验真。 |
|
||||
| `C-M-PROMO` | `GET /genealogy/app/promotions` | `DECLARED_UNVERIFIED` | 只证明推广内容读取,不代表邀请码、积分、奖励或分享变现。 |
|
||||
| `C-M-PROMO-VIDEO` | 无独立广告/宣传视频列表、详情或播放资源 operation | `MISSING_OPERATION` | `GET /genealogy/app/promotions` 未证明返回稳定可播放媒体;家族视频 `C-F-VIDEO-READ` 不能跨域替代。 |
|
||||
| `C-M-PROMO-VIDEO-COMMENT` | 无广告/宣传视频评论读取、发表、回复或删除 operation | `MISSING_OPERATION` | 不得借动态评论或家族视频评论 owner 冒充。 |
|
||||
| `C-M-PROMO-VIDEO-REACTION` | 无广告/宣传视频点赞/取消点赞 operation | `MISSING_OPERATION` | 不得用本地计数或参考控件冒充服务端状态。 |
|
||||
| `C-M-REFERRAL` | 无 APP 推广推荐码/二维码签发或读取 operation | `MISSING_OPERATION` | 推广推荐码不是家谱邀请票据,不能解析、兑换或直接入谱,也不能借 `C-G-INVITE-ISSUE` 冒充。 |
|
||||
| `C-M-REWARD` | 无邀请奖励、积分余额或奖励明细 operation | `MISSING_OPERATION` | 不得从推广文案、邀请码或本地计数推断奖励。 |
|
||||
| `C-M-VIP-READ` | `GET /genealogy/app/vip/packages`<br>`GET /genealogy/app/vip/orders` | `DECLARED_UNVERIFIED` | 待 typed item、金额单位和订单状态验真。 |
|
||||
| `C-M-VIP-ORDER` | `POST /genealogy/app/vip/orders` | `CONTRACT_CONFLICT` | 通用对象结果没有稳定订单 ID、幂等键、订单详情或结果未知恢复链。 |
|
||||
| `C-M-VIP-PAY` | 无支付、支付结果查询、取消或退款 operation | `MISSING_OPERATION` | 不得由创建订单 HTTP 200 进入成功页。 |
|
||||
| `C-M-MONEY` | 无余额、资金流水、提现提交或提现状态 operation | `MISSING_OPERATION` | 文件上传不能单独启用收款码/提现流程。 |
|
||||
|
||||
未直接出现在某一 PA 合同列的键也有明确用途,不能被误当成漏接动作:`C-S-ID/C-S-CAPABILITY/C-S-NAV` 是全部相关 PA 自动继承的共享门禁;`C-G-DETAIL-READ` 是与 overview 竞争、待退役的诊断键;`C-G-MEMBER-UPDATE` 是 `C-T-BIND-MUTATION` 的冲突候选 operation 证据;`C-F-FEED-PAGE-LEGACY/C-F-COMMENT-PAGE` 是待移除的重复读取 owner;`C-F-PHOTO-EDIT` 记录未获批准产品动作的合同缺口;`C-M-HELP-DETAIL` 记录被 list-only 决策压住的声明 operation。它们不增加 PA 分母,也不能绕过对应 canonical owner。
|
||||
|
||||
## 四、第一参考源:60 个设计文件
|
||||
|
||||
### 4.1 D001—D030
|
||||
|
||||
| 文件 ID / 文件 | 页面与逐动作 ID | 当前合同键与 owner | 甄别结论与改造边界 |
|
||||
| --- | --- | --- | --- |
|
||||
| `D001` `4、族谱网APP端-思维导图.pdf` | `D001-P01-A01` APP 功能树;`A02` 后台/网站/PC 分支 | A/G/T/F/R/N/M;其他端无当前路由 | `A01 仅参考交互`,作为反向覆盖目录;`A02 与当前产品冲突,明确舍弃`,不扩张本仓库 |
|
||||
| `D002` `编辑家族视频.png` | `D002-P01-A01` 选择并删除视频 | `C-F-VIDEO-READ/C-F-VIDEO-DELETE` → F10 | `后端缺失,暂时关闭`;不能因有孤立 DELETE 就启用管理页 |
|
||||
| `D003` `编辑相册.png` | `D003-P01-A01` 改名/描述/封面;`A02` 删除相册 | `C-F-ALBUM`、`C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F07/F08 | 两项均 `改造后采用`;权限、结果未知、封面文件链和删除确认必须重做 |
|
||||
| `D004` `创建家谱 .png` | `D004-P01-A01` 填姓氏/谱名/堂号/地望/祠堂/访问权限并创建 | `C-S-REGION-CHILDREN/C-S-REGION-PATH/C-S-REGION-SEARCH/C-S-REGION-DETAIL`、`C-G-CREATE-GENEALOGY`、`C-T-PERSON-CREATE`、`C-G-CREATE-RECOVERY` → G03 | `改造后采用`;自由文本地望不能代替必填 `regionCode`;固定两阶段顺序,但首写无稳定词法 ID 或结果未知时必须停止,不能从 mine 列表猜回 |
|
||||
| `D005` `登陆.png` | `D005-P01-A01` 密码登录;`A02` 忘记;`A03` 注册;`A04` 微信登录 | `C-A-TAC-API/C-A-TAC-A11Y/C-A-LOGIN/C-A-SMS-SEND/C-A-RESET/C-A-REGISTER/C-A-WECHAT` → A01/A04/A05 | A01—A03 `改造后采用`,补 TAC/协议/错误;A04 `后端缺失,暂时关闭` |
|
||||
| `D006` `调整世代.png` | `D006-P01-A01` 调整始祖世代并联动其他成员 | `C-G-SORT` → G 候选 | `后端缺失,暂时关闭`;不能借 T06 排行或 G12 字辈 |
|
||||
| `D007` `发布视频.png` | `D007-P01-A01` 标题/描述/上传并发布视频 | `C-F-VIDEO-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F10 | `后端缺失,暂时关闭`;上传存在也不等于视频实体发布存在 |
|
||||
| `D008` `功德录(1).png` | `D008-P01-A01` 浏览功德记录;`A02` 进入管理 | `C-R-MERIT-BASE/C-R-MERIT-DETAIL` → R11 | A01 `改造后采用`;A02 `仅参考交互`,详情/编辑合同不足 |
|
||||
| `D009` `功德录.png` | `D009-P01-A01` 多选记录;`A02` 删除 | `C-R-MERIT-BASE` → R11 | A01 `仅参考交互`;A02 `改造后采用`,服务端仅单删且需权限/二次确认 |
|
||||
| `D010` `管理世代.png` | `D010-P01-A01` 浏览字辈代次;`A02` 编辑;`A03` 新增 | `C-G-POEM` → G12 | 三项 `改造后采用`;统一到 G12 单一 owner,不建立“世代”第二合同 |
|
||||
| `D011` `加入家谱.png` | `D011-P01-A01` 粘贴邀请码并直接加入 | `C-G-INVITE-RESOLVE/C-G-INVITE-REDEEM/C-G-INVITE-RESULT` → G06 | `后端缺失,暂时关闭`;不可借普通 `C-G-JOIN-CREATE` |
|
||||
| `D012` `家谱主页 – 1.png` | `D012-P01-A01` 家谱总览;`A02` 模块导航 | `C-G-OVERVIEW` → G05 | A01/A02 均为 `仅参考交互`;作为独立总览状态证据保留,不能因与 D043 相似就判重复;红色整页视觉不直接采纳 |
|
||||
| `D013` `家谱主页 – 22.png` | `D013-P01-A01` 贺礼邀请列表;`A02` 分类筛选;`A03` 新建 | `C-R-GREETING` → R 候选 | 三项 `待用户确认`;“贺礼邀请”既非人情簿也未证明等于祭祀献礼 |
|
||||
| `D014` `家谱主页 – 23.png` | `D014-P01-A01` 多选贺礼;`A02` 删除 | 同 D013 | A01 `仅参考交互`;A02 `待用户确认`,语义与权限未定 |
|
||||
| `D015` `家谱主页 – 24.png` | `D015-P01-A01` 贺礼详情 | 同 D013 | `待用户确认`;不能用 ceremony gift 详情猜产品语义 |
|
||||
| `D016` `家谱主页 – 25.png` | `D016-P01-A01` 创建/编辑贺礼 | 同 D013 | `待用户确认`;标题、类型、金额、受邀人和状态合同均需定义 |
|
||||
| `D017` `家谱主页 – 26.png` | `D017-P01-A01` 成长日志列表;`A02` 分类/筛选;`A03` 新建 | `C-R-GROWTH` → R08 | 三项 `改造后采用`;人物 ID 与 recordType enum 先验真 |
|
||||
| `D018` `家谱主页 – 27.png` | `D018-P01-A01` 成长日志详情 | `C-R-GROWTH` → R08 | `改造后采用` |
|
||||
| `D019` `家谱主页 – 28.png` | `D019-P01-A01` 多选成长记录;`A02` 删除 | `C-R-GROWTH` → R08 | A01 `仅参考交互`;A02 `改造后采用`,只删测试数据并二次确认 |
|
||||
| `D020` `家谱主页 – 29.png` | `D020-P01-A01` 新建成长日志 | `C-R-GROWTH` → R08 | `改造后采用`;绑定真实人物,禁止本地假插入 |
|
||||
| `D021` `家谱主页 – 30.png` | `D021-P01-A01` 人情簿列表;`A02` 新建 | `C-R-RELATIVE` → R03/R04 | 两项 `改造后采用`;收/送方向、金额精度先验真 |
|
||||
| `D022` `家谱主页 – 31.png` | `D022-P01-A01` 多选人情记录;`A02` 删除 | `C-R-RELATIVE` → R03/R04 | A01 `仅参考交互`;A02 `改造后采用` |
|
||||
| `D023` `家谱主页 – 32.png` | `D023-P01-A01` 新建/编辑人情记录 | `C-R-RELATIVE` → R04 | `改造后采用` |
|
||||
| `D024` `家谱主页 – 33.png` | `D024-P01-A01` 备忘列表;`A02` 新建 | `C-R-MEMO` → R10 | 两项 `改造后采用` |
|
||||
| `D025` `家谱主页 – 34.png` | `D025-P01-A01` 管理员列表;`A02` 添加 | `C-G-ADMIN/C-G-MEMBER-READ` → G 候选 | 两项 `待用户确认`;无 capability owner,不新增假页面 |
|
||||
| `D026` `家谱主页 – 35.png` | `D026-P01-A01` 多选管理员;`A02` 删除;`A03` 权限配置 | `C-G-ADMIN/C-G-MEMBER-READ/C-G-MEMBER-REMOVE` | A01 `仅参考交互`;A02/A03 `待用户确认`,破坏性/授权能力未闭合 |
|
||||
| `D027` `家谱主页 – 36.png` | `D027-P01-A01` 选择成员并添加管理员 | `C-G-ADMIN/C-G-MEMBER-READ` | `待用户确认` |
|
||||
| `D028` `家谱主页 – 37.png` | `D028-P01-A01` 配置管理员权限 | `C-G-ADMIN` | `待用户确认`;不能把前端勾选框当服务端 capability |
|
||||
| `D029` `家谱主页 – 38.png` | `D029-P01-A01` 发布文字/图片动态;`A02` 置顶;`A03` 加精 | `C-F-FEED-WRITE/C-F-FEED-MODERATION/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F02 | A01 `改造后采用`;A02/A03 `后端缺失,暂时关闭` |
|
||||
| `D030` `家谱主页 – 39.png` | `D030-P01-A01` 表格式世系浏览 | `C-T-TREE` → T01 | `仅参考交互`;可作为辅助模式候选,但头像卡树是当前必需主模式 |
|
||||
|
||||
### 4.2 D031—D060
|
||||
|
||||
| 文件 ID / 文件 | 页面与逐动作 ID | 当前合同键与 owner | 甄别结论与改造边界 |
|
||||
| --- | --- | --- | --- |
|
||||
| `D031` `家谱主页 – 40.png` | `D031-P01-A01` 搜索世系人物;`A02` 选择定位 | `C-T-LIST/C-T-TREE` → T01/T07 | 两项 `改造后采用`;搜索与树定位共享人物 ID owner |
|
||||
| `D032` `家谱主页 – 41.png` | `D032-P01-A01` 头像人物卡树;`A02` 横纵浏览 | `C-T-TREE/C-S-FILE-READ` → T01 | 两项 `改造后采用`,且是用户明确的 T01 必需能力;视觉重做为当前国风 |
|
||||
| `D033` `家谱主页 – 42.png` | `D033-P01-A01` 查看资料;`A02` 父亲;`A03` 母亲;`A04` 配偶;`A05` 兄弟姐妹;`A06` 排行;`A07` 儿子;`A08` 女儿;`A09` 邀请绑定;`A10` 编辑 | `C-T-DETAIL/C-T-PARENT/C-T-SPOUSE/C-T-SIBLING/C-T-RANK/C-T-CHILD/C-T-BIND-INVITE/C-T-BIND-IDENTITY/C-T-BIND-MUTATION/C-T-BIND-RESULT/C-T-EDIT` → T01/T03—T06/独立邀请流程 | 十项均为用户明确需求,产品取舍为 `改造后采用`;合同不足的动作执行态关闭且产品完成度 BLOCKED,不能删入口或假成功 |
|
||||
| `D034` `家谱主页 – 43.png` | `D034-P01-A01` 查看人物资料空态;`A02` 资料/亲属切换;`A03` 邀请其激活绑定;`A04` 编辑 | `C-T-DETAIL/C-T-BIND-INVITE/C-T-BIND-IDENTITY/C-T-BIND-MUTATION/C-T-BIND-RESULT/C-T-EDIT` → T03/T05/邀请流程 | A01/A02/A04 `改造后采用`;A03 产品需求已批准但当前 `后端缺失,暂时关闭` |
|
||||
| `D035` `家谱主页 – 44.png` | `D035-P01-A01` 查看人物亲属列表;`A02` 点亲属继续查看 | `C-T-DETAIL/C-T-LIST` → T03 | 两项 `改造后采用`;避免递归叠原生页,沿用单实例轨迹 |
|
||||
| `D036` `家谱主页 – 45.png` | `D036-P01-A01` 选择/绑定成长对象;`A02` 编辑头像姓名排行等人物字段;`A03` 填成长日志 | `C-T-BIND-INVITE/C-T-BIND-IDENTITY/C-T-BIND-MUTATION/C-T-BIND-RESULT/C-T-EDIT/C-T-RANK/C-R-GROWTH` → T04/T05/T06/R08 | A01 `后端缺失,暂时关闭`;A02/A03 `改造后采用`且必须按 owner 拆分,不能把排行和人物编辑合为宽表单 |
|
||||
| `D037` `家谱主页 – 46.png` | `D037-P01-A01` 阅读富文本详情 | `C-R-CEREMONY/C-M-HELP-LIST` → 取决于来源 | `仅参考交互`;通用长文阅读形态可复用,但数据 owner 必须由入口决定 |
|
||||
| `D038` `家谱主页 – 47.png` | `D038-P01-A01` 编辑人物基础资料;`A02` 微信/QQ/地址/学历/职业等扩展隐私资料 | `C-T-EDIT` → T05 | A01 `改造后采用`;A02 `与当前产品冲突,明确舍弃`,当前需求未授权且后端无隐私/可见性 owner,不采集、不存储、不上传 |
|
||||
| `D039` `家谱主页 – 48.png` | `D039-P01-A01` 帮助分类;`A02` 搜索 | `C-M-HELP-LIST` → M06 | 两项 `改造后采用` |
|
||||
| `D040` `家谱主页 – 49.png` | `D040-P01-A01` 阅读帮助文章 | `C-M-HELP-LIST` → M06 | `改造后采用`;由完整列表项投影承接,不新增独立远端 owner |
|
||||
| `D041` `家谱主页 – 50.png` | `D041-P01-A01` 分享应用;`A02` 邀请奖励/积分;`A03` 微信小程序首次登录限制 | `C-M-PROMO/C-S-PLATFORM-SHARE/C-M-REWARD/C-A-WECHAT` → 无当前路由的 M 推广候选 | A01 `仅参考交互`;A02/A03 `待用户确认`并保持关闭,禁止承诺积分或微信链,更不得覆盖 M08 家谱邀请 |
|
||||
| `D042` `家谱主页 – 51.png` | `D042-P01-A01` 填标题/描述并提交反馈 | `C-M-FEEDBACK` → M07 | `改造后采用`;真实提交失败和结果未知不得清空 |
|
||||
| `D043` `家谱主页.png` | `D043-P01-A01` 家谱总览;`A02` 模块导航 | `C-G-OVERVIEW` → G05 | A01/A02 均为 `仅参考交互`;独立保留为可能的角色、主题或业务状态,待入口/数据/权限证据证明后才决定是否与 D012 共用状态实现 |
|
||||
| `D044` `家族视频.png` | `D044-P01-A01` 视频列表;`A02` 播放;`A03` 管理;`A04` 发布 | `C-F-VIDEO-READ/C-F-VIDEO-WRITE/C-F-VIDEO-DELETE` → F10 | 四项 `后端缺失,暂时关闭`;播放 UI 可做关闭页信息参考 |
|
||||
| `D045` `家族相册.png` | `D045-P01-A01` 照片墙;`A02` 预览;`A03` 上传照片;`A04` 编辑相册 | `C-F-ALBUM/C-F-PHOTO-READ/C-F-PHOTO-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F08/F09 | A01—A04 均为 `改造后采用`;A03/A04 必须在文件、权限和两段写闭环后实施 |
|
||||
| `D046` `谱文(1).png` | `D046-P01-A01` 管理谱文分类 | `C-F-ARTICLE-CATEGORY-WRITE` → F04/F06 | `仅参考交互`;当前合同只有分类读取,无分类增改删,管理动作关闭 |
|
||||
| `D047` `谱文.png` | `D047-P01-A01` 浏览谱文分类;`A02` 进入内容 | `C-F-ARTICLE` → F04 | 两项 `改造后采用` |
|
||||
| `D048` `谱文详情.png` | `D048-P01-A01` 阅读谱文;`A02` 添加/编辑 | `C-F-ARTICLE` → F05/F06 | 两项 `改造后采用`;富文本和媒体必须消毒/归一化 |
|
||||
| `D049` `设置世代.png` | `D049-P01-A01` 编辑代数/字辈;`A02` 保存;`A03` 删除 | `C-G-POEM` → G12 | A01—A03 均为 `改造后采用`;A03 只能改造成停用/恢复,不得猜测为物理删除 |
|
||||
| `D050` `首页 – 14.png` | `D050-P01-A01` 我的家谱列表;`A02` 搜索;`A03` 创建;`A04` 普通申请加入;`A05` 邀请码直入 | `C-G-MINE/C-G-PUBLIC/C-G-OPTIONS/C-G-CREATE-GENEALOGY/C-T-PERSON-CREATE/C-G-CREATE-RECOVERY/C-G-JOIN-CREATE/C-G-JOIN-RECOVERY/C-G-INVITE-RESOLVE/C-G-INVITE-REDEEM/C-G-INVITE-RESULT` → G01/G03/G06/G08 | A01—A04 `改造后采用`;A05 `后端缺失,暂时关闭` |
|
||||
| `D051` `首页 – 16.png` | `D051-P01-A01` 家族动态列表;`A02` 图片墙;`A03` 评论/回复;`A04` 发布 | `C-F-FEED-READ/C-F-FEED-WRITE/C-F-COMMENT-READ/C-F-COMMENT-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F01/F02/F03 | 四项 `改造后采用`;不复制示例图片、电话号码或静态评论 |
|
||||
| `D052` `首页 – 18.png` | `D052-P01-A01` 通知列表;`A02` 全部已读;`A03` 审核加入;`A04` 打开活动通知 | `C-N-LIST/C-N-READ-ALL/C-N-DETAIL-SAME-SESSION/C-N-DETAIL-COLD-START/C-G-JOIN-AUDIT` → N01/N02/G10 | A01—A03 `改造后采用`;A03 必须深链到 G10,不能由 N01 直接审核;A04 `后端缺失,暂时关闭`,不得在无目标合同时伪造跳转 |
|
||||
| `D053` `首页 – 19.png` | `D053-P01-A01` 查看本人资料;`A02` 推广;`A03` 反馈;`A04` 安全;`A05` 帮助;`A06` 退出 | `C-A-PROFILE-READ/C-M-PROMO/C-M-FEEDBACK/C-A-PASSWORD-CHANGE/C-A-PHONE-CHANGE/C-A-LOGOUT/C-M-HELP-LIST` → M01/M03/M06/M07/M10;A02 为无当前路由候选 | A01、A03—A06 `改造后采用`;A02 同为 `改造后采用`的候选证据,但不承诺奖励且不得覆盖 M08 家谱邀请 |
|
||||
| `D054` `首页 .png` | `D054-P01-A01` 我的家谱列表;`A02` 创建;`A03` 加入 | 同 D050 | A01—A03 均为 `仅参考交互`;独立保留为可能的主题、角色或业务状态,不能只按颜色相似度与 D050 合并 |
|
||||
| `D055` `思维导图.png` | `D055-P01-A01` APP 认证/家谱/世系/内容/族务/消息/我的全功能树;`A02` 后台;`A03` 网站;`A04` PC 管理端 | A/G/T/F/R/N/M;其他端无当前路由 | A01 `仅参考交互`并作为全项目反向检查目录;A02—A04 `与当前产品冲突,明确舍弃` |
|
||||
| `D056` `添加功德人.png` | `D056-P01-A01` 姓名/内容/图片并新增功德记录 | `C-R-MERIT-BASE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → R11 | `改造后采用`;当前无编辑/详情 operation,图片 owner 待确认 |
|
||||
| `D057` `添加谱文.png` | `D057-P01-A01` 标题/正文/落款/图片质量/媒体并保存 | `C-F-ARTICLE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F06 | `改造后采用`;只提交当前合同白名单,图片质量不是后端业务字段 |
|
||||
| `D058` `相册.png` | `D058-P01-A01` 相册列表;`A02` 新建;`A03` 打开详情 | `C-F-ALBUM` → F07/F08 | 三项 `改造后采用` |
|
||||
| `D059` `新建相册.png` | `D059-P01-A01` 名称/描述并创建相册 | `C-F-ALBUM` → F07 | `改造后采用` |
|
||||
| `D060` `字辈谱.png` | `D060-P01-A01` 浏览字辈;`A02` 管理 | `C-G-POEM` → G12 | 两项 `改造后采用` |
|
||||
|
||||
## 五、第二参考源:78 条活动路由
|
||||
|
||||
“参考 wrapper”只证明旧项目尝试过某动作,不是当前合同。未列入 wrapper 的裸 `uni.request`、全局 store 传 URL、硬编码数据和被注释调用均不得迁入。
|
||||
|
||||
### 5.1 J001—J026
|
||||
|
||||
| 路由 ID / 参考路由 | 页面与逐动作 ID | 参考 wrapper | 当前合同键与 owner | 甄别结论与边界 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `J001` `pages/index/index` | `J001-A01` 读用户/家谱;`A02` 切谱;`A03` 模块导航;`A04` 宣传视频 | `getALLCreatGenealogyList`, `getAuthByUserGenealogy`, `getCreatGenealogy`, `getDictDataByDictCode`, `getUserInfo`, `getVideopublicize` | `C-G-MINE/C-G-OVERVIEW/C-A-PROFILE-READ/C-M-PROMO-VIDEO` → G01/G05;A04 为无当前路由候选 | A01—A03 `仅参考交互`并拆 owner;A04 `后端缺失,暂时关闭`,拒绝跨域巨型首页 |
|
||||
| `J002` `pages/login/login` | `J002-A01` 密码登录;`A02` 注册;`A03` 重置;`A04` 微信登录 | `getCaptcha`, `getDictDataByDictCodeNoToken`, `login`, `register`, `userResetPwd`, `wechatAppLogin` | `C-A-TAC-API/C-A-TAC-A11Y/C-A-LOGIN/C-A-SMS-SEND/C-A-REGISTER/C-A-RESET/C-A-WECHAT` → A01/A04/A05 | A01—A03 `改造后采用`;A04 `后端缺失,暂时关闭`;页面必须拆 owner |
|
||||
| `J003` `pages/render/render` | `J003-A01` 阳历/农历日期时间选择演示 | 无 | `C-LOCAL` → 共享控件候选 | `与当前产品冲突,明确舍弃`活动路由;需要日期选择时只参考控件行为 |
|
||||
| `J004` `pages/index/addGenealogy` | `J004-A01` 输入邀请信息直接入谱 | `inviteCreatGenealogy` | `C-G-INVITE-RESOLVE/C-G-INVITE-REDEEM/C-G-INVITE-RESULT` → G06 | `后端缺失,暂时关闭`;与 G08 普通申请隔离 |
|
||||
| `J005` `pages/index/createGenealogy` | `J005-A01` 选字典/地区并创建家谱 | `addCreatGenealogy`, `getDictDataByDictCode` | `C-S-REGION-CHILDREN/C-S-REGION-PATH/C-S-REGION-SEARCH/C-S-REGION-DETAIL/C-G-CREATE-GENEALOGY/C-T-PERSON-CREATE/C-G-CREATE-RECOVERY` → G03 | `改造后采用`;旧一次提交改为两阶段顺序,首写结果未知时停止并人工对账 |
|
||||
| `J006` `pages/index/invite` | `J006-A01` 邀请家人空壳 | 无 | `C-G-INVITE-ISSUE` | `与当前产品冲突,明确舍弃`空壳;不冒充 T01 邀请绑定 |
|
||||
| `J007` `pages/index/genealogyList/index` | `J007-A01` 家谱列表/选择;`A02` 删除家谱;`A03` 读配置 | `delGenealogy`, `getCreatGenealogy`, `getDictDataByDictCode`, `getDictDataByDictCodeNoToken` | `C-G-MINE/C-G-DELETE` → G01 | A01/A03 `改造后采用`;A02 `待用户确认`且不执行真实删除 |
|
||||
| `J008` `pages/index/genealogyList/characterTable` | `J008-A01` 查看字辈 | `getCharacterTable` | `C-G-POEM` → G12 | `改造后采用` |
|
||||
| `J009` `pages/index/genealogyList/add` | `J009-A01` 添加/编辑字辈;`A02` 删除 | `addCharacterTable`, `deleteCharacterTable` | `C-G-POEM` → G12 | A01/A02 均为 `改造后采用`;A02 只能按停用/恢复合同改造,拒绝物理删除猜测 |
|
||||
| `J010` `pages/index/puwen/classList` | `J010-A01` 读取并选择谱文分类 | `getDictDataByDictCode` | `C-F-ARTICLE` → F04/F06 | `仅参考交互`;分类必须来自当前文章合同 |
|
||||
| `J011` `pages/index/puwen/index` | `J011-A01` 谱文列表/筛选;`A02` 访问密码;`A03` 删除 | `deleteLiterature`, `getDictDataByDictCode`, `getLiterature`, `pw_is_cehck` | `C-F-ARTICLE/C-S-CONTENT-LOCK` → F04/F05 | A01/A03 `改造后采用`;A02 `待用户确认`,当前无内容锁 owner |
|
||||
| `J012` `pages/index/puwen/genealogy` | `J012-A01` 谱文详情 | `getLiteratureDetails` | `C-F-ARTICLE` → F05 | `改造后采用`;作为独立入口/详情状态证据保留,证明等价后才与其他详情入口共用实现 |
|
||||
| `J013` `pages/index/puwen/add` | `J013-A01` 新建;`A02` 编辑;`A03` 读原详情 | `addLiterature`, `getLiteratureDetails` | `C-F-ARTICLE` → F06 | 三项 `改造后采用` |
|
||||
| `J014` `pages/index/puwen/wjmm` | `J014-A01` 重置谱文访问密码;`A02` 成长日志访问密码;`A03` 证件访问密码 | `addLiterature`, `cz_update_password`, `cz_update_password_hx`, `getLiteratureDetails`, `pw_update_password`, `pw_update_password_hx`, `zy_update_password`, `zy_update_password_hx` | `C-S-CONTENT-LOCK` | 三项 `待用户确认`;明确不映射 A05,拒绝跨 F/R/证件的复制污染 |
|
||||
| `J015` `pages/index/album/index` | `J015-A01` 相册列表 | `getPhotocategoryList` | `C-F-ALBUM` → F07 | `改造后采用` |
|
||||
| `J016` `pages/index/album/add` | `J016-A01` 新建相册 | `addPhotocategory` | `C-F-ALBUM` → F07 | `改造后采用` |
|
||||
| `J017` `pages/index/album/details` | `J017-A01` 照片列表;`A02` 上传;`A03` 删除照片 | `deletePhoto`, `getPhotoList`, `uploadPhoto` | `C-F-PHOTO-READ/C-F-PHOTO-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F08/F09 | 三项 `改造后采用`;上传与记录两段确认 |
|
||||
| `J018` `pages/index/album/edit` | `J018-A01` 编辑相册 | `addPhotocategory` | `C-F-ALBUM` → F07/F08 | `改造后采用`;不复用“新增”旧 wrapper 语义 |
|
||||
| `J019` `pages/index/document/index` | `J019-A01` 证件列表;`A02` 密码校验;`A03` 删除 | `deletePhotodocument`, `getPhotodocument`, `zy_is_cehck` | `C-R-DOCUMENT/C-S-CONTENT-LOCK` | 三项 `待用户确认`;默认关闭,不迁移身份证明或真实 PII |
|
||||
| `J020` `pages/index/document/add` | `J020-A01` 新建/编辑证件;`A02` 选择类型 | `addPhotodocument`, `getDictDataByDictCode` | `C-R-DOCUMENT` | 两项 `待用户确认`且默认关闭 |
|
||||
| `J021` `pages/index/video/index` | `J021-A01` 视频列表;`A02` 播放;`A03` 删除 | `deleteVideo`, `getVideoList` | `C-F-VIDEO-READ/C-F-VIDEO-DELETE` → F10 | A01—A03 均为 `后端缺失,暂时关闭`;A03 不得因存在孤立删除 operation 就暴露入口 |
|
||||
| `J022` `pages/index/video/add` | `J022-A01` 上传;`A02` 发布/编辑视频 | `addVideo`, `uploadFile` | `C-F-VIDEO-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` → F10 | 两项 `后端缺失,暂时关闭` |
|
||||
| `J023` `pages/index/video/xcindex` | `J023-A01` 宣传视频列表 | `getVideopublicize` | `C-M-PROMO-VIDEO` | `待用户确认`;宣传与家族视频分离 |
|
||||
| `J024` `pages/index/video/details` | `J024-A01` 从全局 store 取 URL 播放 | 无 | `C-F-VIDEO-READ` → F10 | `仅参考交互`;全局 URL 传递方式明确舍弃 |
|
||||
| `J025` `pages/index/meritsVirtues/index` | `J025-A01` 功德列表;`A02` 删除 | `deleteVirtues`, `getVirtuesList` | `C-R-MERIT-BASE` → R11 | 两项 `改造后采用` |
|
||||
| `J026` `pages/index/meritsVirtues/add` | `J026-A01` 新增;`A02` 编辑;`A03` 读取详情 | `addVirtues`, `getVirtuesDetail` | `C-R-MERIT-BASE/C-R-MERIT-EDIT/C-R-MERIT-DETAIL` → R11 | A01 `改造后采用`;A02/A03 `后端缺失,暂时关闭`,当前无详情/编辑 operation,不能假完成 |
|
||||
|
||||
### 5.2 J027—J052
|
||||
|
||||
| 路由 ID / 参考路由 | 页面与逐动作 ID | 参考 wrapper | 当前合同键与 owner | 甄别结论与边界 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `J027` `pages/index/meritsVirtues/details` | `J027-A01` 功德详情 | `getVirtuesDetail` | `C-R-MERIT-DETAIL` → R11 | `后端缺失,暂时关闭`独立详情;可在列表使用服务端已有投影,但不能伪造详情 |
|
||||
| `J028` `pages/index/gift/index` | `J028-A01` 贺礼邀请列表;`A02` 分类;`A03` 删除 | `deleteGift`, `getDictDataByDictCode`, `getGift` | `C-R-GREETING` | 三项 `待用户确认`;先定义业务语义 |
|
||||
| `J029` `pages/index/gift/details` | `J029-A01` 贺礼详情 | `getGiftInfo` | 同 J028 | `待用户确认` |
|
||||
| `J030` `pages/index/gift/add` | `J030-A01` 新建;`A02` 编辑;`A03` 分类;`A04` 读取详情 | `addGift`, `getDictDataByDictCode`, `getGiftInfo` | 同 J028 | 四项 `待用户确认` |
|
||||
| `J031` `pages/index/log/index` | `J031-A01` 成长列表;`A02` 删除/批量;`A03` 进入详情 | `deleteDevelopmentlog`, `development`, `getDevelopmentlogList` | `C-R-GROWTH` → R08 | A01—A03 均为 `改造后采用`;A02 只按当前单条合同和权限实现;与 J070/J071 分别保留为可能的入口/筛选/角色状态 |
|
||||
| `J032` `pages/index/log/details` | `J032-A01` 成长详情 | `getDevelopmentlogDetails` | `C-R-GROWTH` → R08 | `改造后采用` |
|
||||
| `J033` `pages/index/log/add` | `J033-A01` 新增;`A02` 编辑;`A03` 分类 | `addDevelopmentlog`, `getDevelopmentlogDetails`, `getDictDataByDictCode` | `C-R-GROWTH` → R08 | 三项 `改造后采用` |
|
||||
| `J034` `pages/index/favor/index` | `J034-A01` 人情簿列表;`A02` 删除 | `deleteCashgift`, `getCashgiftList` | `C-R-RELATIVE` → R03 | 两项 `改造后采用` |
|
||||
| `J035` `pages/index/favor/details` | `J035-A01` 人情记录详情 | `getCashgiftDetails` | `C-R-RELATIVE` → R03/R04 | `改造后采用` |
|
||||
| `J036` `pages/index/favor/add` | `J036-A01` 新增;`A02` 编辑 | `addCashgift`, `getCashgiftDetails` | `C-R-RELATIVE` → R04 | 两项 `改造后采用` |
|
||||
| `J037` `pages/index/memorandum/index` | `J037-A01` 备忘列表;`A02` 删除 | `deleteMemorandum`, `getMemorandum` | `C-R-MEMO` → R10 | 两项 `改造后采用` |
|
||||
| `J038` `pages/index/memorandum/add` | `J038-A01` 新增;`A02` 编辑;`A03` 读取详情 | `addMemorandum`, `getMemorandumInfo` | `C-R-MEMO` → R10 | 三项 `改造后采用` |
|
||||
| `J039` `pages/index/memorandum/details` | `J039-A01` 备忘详情 | `getMemorandumInfo` | `C-R-MEMO` → R10 | `改造后采用` |
|
||||
| `J040` `pages/index/admin/index` | `J040-A01` 管理员列表;`A02` 移除 | `getManageUserDel`, `getManageUserList` | `C-G-ADMIN/C-G-MEMBER-READ/C-G-MEMBER-REMOVE` | 两项 `待用户确认`;移除须影响预览和再认证 |
|
||||
| `J041` `pages/index/admin/add` | `J041-A01` 静态成员勾选;`A02` 进入权限页 | 无 | `C-G-ADMIN` | A01/A02 均为 `与当前产品冲突,明确舍弃`;该半成品不迁移,不把假成员列表带入当前产品 |
|
||||
| `J042` `pages/index/admin/power` | `J042-A01` 读取权限;`A02` 提交管理员权限 | `addManageUser`, `getManagePower` | `C-G-ADMIN` | 两项 `待用户确认`,合同缺失前关闭 |
|
||||
| `J043` `pages/index/familyCircle/index` | `J043-A01` 动态列表;`A02` 评论列表;`A03` 评论;`A04` 删除动态 | `addComment`, `deleteUsernews`, `getComment`, `getUsernewsList` | `C-F-FEED-READ/C-F-FEED-WRITE/C-F-COMMENT-READ/C-F-COMMENT-WRITE` → F01/F03 | 四项 `改造后采用`;列表和评论/删除拆 owner |
|
||||
| `J044` `pages/index/familyCircle/add` | `J044-A01` 发布动态;`A02` 取公开字典 | `addUsernews`, `getDictDataByDictCodeNoToken` | `C-F-FEED-WRITE` → F02 | A01/A02 `改造后采用`;A02 仅使用当前明确字段 owner |
|
||||
| `J045` `pages/index/tree/index` | `J045-A01` 按父母展开表格式世系 | `getGenealogyUserByParentsId` | `C-T-TREE` → T01 | `仅参考交互`;不复制旧接口和递归数据形状 |
|
||||
| `J046` `pages/index/tree/tree` | `J046-A01` 树谱;`A02` 查看资料;`A03` 添加/编辑亲属;`A04` 删除人物 | `getGenealogyUser`, `userDel` | `C-T-TREE/C-T-DETAIL/C-T-PARENT/C-T-SPOUSE/C-T-SIBLING/C-T-CHILD/C-T-EDIT/C-T-DELETE` → T01/T03—T05 | A01—A03 `仅参考交互`并按当前 owner 重做;A04 `待用户确认`,停用不是物理删除 |
|
||||
| `J047` `pages/message/index` | `J047-A01` 通知/广告/文章混排;`A02` 直接审核入谱;`A03` 人物列表 | `auditInGenealogy`, `getad_list`, `getArticleList`, `getNoticeList`, `getUserList` | `C-N-LIST/C-G-JOIN-AUDIT/C-T-LIST` → N01/G10 | A01 `仅参考交互`但须拆类型;A02 `改造后采用`为跳 G10,不在 N01 写;A03 `与当前产品冲突,明确舍弃`错位数据 |
|
||||
| `J048` `pages/message/details` | `J048-A01` 通知详情 | `getNoticeDetails` | `C-N-DETAIL-SAME-SESSION/C-N-DETAIL-COLD-START` → N02 | `后端缺失,暂时关闭` LIVE 详情;仅允许列表当代内存投影 |
|
||||
| `J049` `pages/mine/index` | `J049-A01` 我的主页/资料;`A02` 宣传/广告;`A03` 删除账号 | `delUser`, `getad_list`, `getDictDataByDictCodeNoToken`, `getUserInfo`, `getVideopublicize` | `C-A-PROFILE-READ/C-M-PROMO/C-A-DEACTIVATE` → M01/M10 | A01 `改造后采用`;A02/A03 `待用户确认`,A03 为敏感注销候选且不归主页直调 |
|
||||
| `J050` `pages/mine/help` | `J050-A01` 帮助分类;`A02` 文章列表 | `getArticleList`, `getHelpClass` | `C-M-HELP-LIST` → M06 | 两项 `改造后采用` |
|
||||
| `J051` `pages/mine/setting` | `J051-A01` 设置导航;`A02` 帮助/协议内容 | `getArticleList`, `getHelpClass` | `C-M-HELP-LIST/C-LOCAL` → M03/M10 | A01/A02 均为 `仅参考交互`;设置只做导航,不另建数据 owner |
|
||||
| `J052` `pages/mine/password` | `J052-A01` 修改密码 | `userEditPWD` | `C-A-PASSWORD-CHANGE` → M04 | `改造后采用`;旧密码 wire 不能迁移为新合同 |
|
||||
|
||||
### 5.3 J053—J078 与注释路由
|
||||
|
||||
| 路由 ID / 参考路由 | 页面与逐动作 ID | 参考 wrapper | 当前合同键与 owner | 甄别结论与边界 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `J053` `pages/mine/opinion` | `J053-A01` 提交反馈 | `addUseropinion` | `C-M-FEEDBACK` → M07 | `改造后采用` |
|
||||
| `J054` `pages/mine/share` | `J054-A01` 展示推广;`A02` 立即分享 | 无 | `C-M-PROMO/C-S-PLATFORM-SHARE` → 无当前路由的 M 推广候选 | A01 `改造后采用`候选证据;A02 `仅参考交互`,旧错误跳创建家谱明确舍弃;不得覆盖 M08 家谱邀请 |
|
||||
| `J055` `pages/mine/vip_xf` | `J055-A01` 套餐;`A02` 创建/支付 VIP | `getMemberLevel`, `getUserInfo`, `payVip` | `C-M-VIP-READ/C-M-VIP-ORDER/C-M-VIP-PAY` → M09 | A01 `改造后采用`为只读;A02 `后端缺失,暂时关闭`支付闭环 |
|
||||
| `J056` `pages/mine/vip_success` | `J056-A01` 查询购买记录/成功 | `vip_log` | `C-M-VIP-READ/C-M-VIP-PAY` → M09 | `后端缺失,暂时关闭`成功页;只能由权威订单结果进入 |
|
||||
| `J057` `pages/mine/helpDetails` | `J057-A01` 帮助详情 | `getArticleDetails` | `C-M-HELP-LIST` → M06 | `改造后采用`产品意图;当前由列表项投影承接,旧独立详情 owner 不迁入 |
|
||||
| `J058` `pages/index/relationship/index` | `J058-A01` 静态人物/亲属资料;`A02` 邀请激活 | 无 | `C-T-DETAIL/C-T-BIND-INVITE/C-T-BIND-IDENTITY/C-T-BIND-MUTATION/C-T-BIND-RESULT` → T03/邀请流程 | A01 `仅参考交互`;A02 产品需求保留但当前 `后端缺失,暂时关闭` |
|
||||
| `J059` `pages/index/tree/personalData` | `J059-A01` 人物资料 | `getUserInfoId` | `C-T-DETAIL` → T03 | `改造后采用` |
|
||||
| `J060` `pages/index/tree/add` | `J060-A01` 绑定账号;`A02` 编辑头像/姓名/排行/父亲/生卒;`A03` 确认 | 无 | `C-T-BIND-INVITE/C-T-BIND-IDENTITY/C-T-BIND-MUTATION/C-T-BIND-RESULT/C-T-EDIT/C-T-RANK/C-T-PARENT` → T04—T06 | A01—A03 均为 `与当前产品冲突,明确舍弃`;宽静态表单实现不迁移,字段须逐 owner 甄别后重做 |
|
||||
| `J061` `pages/mine/userInfo` | `J061-A01` 本人资料;`A02` 添加父母;`A03` 配偶;`A04` 兄弟姐妹;`A05` 子女;`A06` 单人;`A07` 人物编辑;`A08` 排行/层级 | `addBrotherSister`, `addChildren`, `addOneUser`, `addParents`, `addUserspouse`, `getDictDataByDictCode`, `getDictDataByDictCodeNoToken`, `getLevelList`, `getMomList`, `getUserInfoId`, `getUserSpouseInfoId`, `userEdit` | `C-A-PROFILE-READ/C-A-PROFILE-WRITE/C-T-PARENT/C-T-SPOUSE/C-T-SIBLING/C-T-CHILD/C-T-EDIT/C-T-RANK` → M02/T04—T06 | A01—A05、A07/A08 `改造后采用`产品意图,但必须拆 owner;A06 与当前产品冲突,`明确舍弃`未绑定通用人物新建;旧一页多模式和旧 wrapper 全部舍弃 |
|
||||
| `J062` `pages/index/log/selectUser` | `J062-A01` 选择成长人物;`A02` 管理员选择分支 | `getUserList` | `C-T-LIST/C-R-GROWTH/C-G-ADMIN` → R08 | A01 `改造后采用`;A02 `与当前产品冲突,明确舍弃`未完成分支 |
|
||||
| `J063` `pages/index/genealogyList/ancestorsOrder` | `J063-A01` 调整始祖世代空占位 | 无 | `C-G-SORT` | `与当前产品冲突,明确舍弃`空文件;功能候选保持后端缺失关闭 |
|
||||
| `J064` `pages/mine/helpList` | `J064-A01` 按分类读帮助文章 | `getArticleList` | `C-M-HELP-LIST` → M06 | `改造后采用` |
|
||||
| `J065` `pages/content/detail` | `J065-A01` 账号协议;`A02` 帮助/关于富文本 | `getNewsDetails` | `C-LOCAL/C-M-HELP-LIST` → A/M06/M10 共享查看器 | A01/A02 均为 `仅参考交互`;入口决定 owner,明确不是 F05 谱文 |
|
||||
| `J066` `pages/mine/fenxiang` | `J066-A01` 推广推荐码/二维码;`A02` 复制;`A03` 下载 App;`A04` 分享变现 | 无 | `C-M-REFERRAL/C-M-PROMO/C-M-MONEY/C-S-PLATFORM-CLIPBOARD/C-S-PLATFORM-SHARE/C-S-SAFE-EXTERNAL-OPEN` → 无当前路由的 M 推广候选 | A01/A02 `后端缺失,暂时关闭`,明确不是家谱票据;A03 `仅参考交互`且只能由安全外链 owner 承接;A04 `待用户确认`;四项均不得覆盖 M08 |
|
||||
| `J067` `pages/login/register` | `J067-A01` 注册;`A02` 性别/邀请码;`A03` 协议 | `getCaptcha`, `getDictDataByDictCodeNoToken`, `register` | `C-A-TAC-API/C-A-TAC-A11Y/C-A-SMS-SEND/C-A-REGISTER/C-LOCAL` → A04 | A01—A03 `改造后采用`;A02 只保留当前合同字段,旧邀请码不迁入 |
|
||||
| `J068` `pages/mine/changemobile` | `J068-A01` 当前密码+新号换绑 | `userEditMobile` | `C-A-TAC-API/C-A-TAC-A11Y/C-A-PHONE-SEND/C-A-PHONE-CHANGE` → M05 | `改造后采用`产品目标;旧缺 TAC/OTP/会话撤销合同明确舍弃 |
|
||||
| `J069` `pages/index/sortGenealogy` | `J069-A01` 读取用户家谱;`A02` 批量排序 | `changeGenealogySort`, `getALLCreatGenealogyList` | `C-G-MINE/C-G-SORT` → G01 候选 | A01 `改造后采用`并复用 G01;A02 `后端缺失,暂时关闭`,不同于 T06/G12 |
|
||||
| `J070` `pages/index/log/list` | `J070-A01` 人物/分类成长列表;`A02` 密码校验;`A03` 删除;`A04` 新建 | `cz_is_cehck`, `deleteDevelopmentlog`, `getDevelopmentlogList`, `getDictDataByDictCode` | `C-R-GROWTH/C-S-CONTENT-LOCK` → R08 | A01/A03/A04 `改造后采用`并独立保留此筛选/入口状态;证明与 J031 等价后才共用实现;A02 `待用户确认` |
|
||||
| `J071` `pages/index/log/class` | `J071-A01` 成长分类;`A02` 进入列表;`A03` 错位删除逻辑 | `deleteDevelopmentlog`, `getDevelopmentlogList`, `getDictDataByDictCode` | `C-R-GROWTH` → R08 | A01/A02 `仅参考交互`;A03 `与当前产品冲突,明确舍弃` |
|
||||
| `J072` `pages/index/video/video2` | `J072-A01` 纵滑播放;`A02` 评论;`A03` 点赞;`A04` 分享;`A05` 裸请求旧 HTTP | 无 | `C-F-VIDEO-READ/C-F-VIDEO-COMMENT/C-F-VIDEO-REACTION/C-S-PLATFORM-SHARE` → F10 候选 | A01—A04 `仅参考交互`但分别进入浏览、评论、点赞、分享候选,不能共用读取 owner;A05 `与当前产品冲突,明确舍弃` |
|
||||
| `J073` `pages/index/video/video3` | `J073-A01` 宣传纵滑播放;`J073-A02@comment` 评论;`J073-A02@reaction` 点赞;`J073-A02@share` 分享;`J073-A03` 裸请求旧接口 | 无 | A01 → `C-M-PROMO-VIDEO`;A02@comment → `C-M-PROMO-VIDEO-COMMENT`;A02@reaction → `C-M-PROMO-VIDEO-REACTION`;A02@share → `C-M-PROMO-VIDEO/C-S-PLATFORM-SHARE` | A01 与三个 A02 语义子动作均 `仅参考交互`,不代表批准宣传业务;A03 `与当前产品冲突,明确舍弃` |
|
||||
| `J074` `pages/index/video/video4` | `J074-A01@browse` 第三套纵滑;`J074-A01@comment` 评论;`J074-A02` 旧 HTTP 与外部云接口 | 无 | A01@browse → `C-F-VIDEO-READ`;A01@comment → `C-F-VIDEO-COMMENT`;A02 无可迁移 owner | 两个 A01 语义子动作均 `仅参考交互`;A02 `与当前产品冲突,明确舍弃` |
|
||||
| `J075` `pages/message/ad_detail` | `J075-A01` 广告/宣传消息详情 | `ad_detail`, `getDictDataByDictCodeNoToken` | `C-N-DETAIL-SAME-SESSION/C-N-DETAIL-COLD-START/C-M-PROMO` → N02 | `待用户确认`;服务端消息类型/目标未闭合前关闭 |
|
||||
| `J076` `pages/mine/withdrawal` | `J076-A01` 余额;`A02` 资金流水;`A03` 进入提现 | `getUserInfo`, `money_log` | `C-M-MONEY` | 三项 `待用户确认`且关闭 |
|
||||
| `J077` `pages/mine/tixian` | `J077-A01` 提现金额;`A02` 上传收款码;`A03` 提交;`A04` 混入成长日志残留 | `add_tixian`, `addDevelopmentlog`, `getDevelopmentlogDetails`, `getDictDataByDictCode` | `C-M-MONEY/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | A01—A03 `待用户确认`且关闭;A04 `与当前产品冲突,明确舍弃`复制污染 |
|
||||
| `J078` `pages/mine/tixian_log` | `J078-A01` 提现记录/状态/审核时间 | `tixian_log` | `C-M-MONEY` | `待用户确认`且关闭 |
|
||||
| `JX001` `pages/index/vertical-swiper/vertical-swiper`(注释) | `JX001-A01` 纵向短视频实验 | 无 | `C-F-VIDEO-READ` → F10 | `与当前产品冲突,明确舍弃`活动路由候选;只保留交互证据且不计 78 分母 |
|
||||
|
||||
## 六、7 个未注册页面文件
|
||||
|
||||
| 文件 ID / 相对路径 | 页面与逐动作 ID | 参考 wrapper | 当前 owner | 甄别结论 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `JU01` `pages/index/genealogyList.vue` | `JU01-A01` 全功能菜单导航;`A02` 错配按钮/文案 | 无 | `C-S-NAV/C-G-OVERVIEW` → G05 与各业务域 | A01 `仅参考交互`并作为可能的角色/菜单状态保留;A02 `与当前产品冲突,明确舍弃`;未注册页面不自动新增路由 |
|
||||
| `JU02` `pages/index/tree/tree2.vue` | `JU02-A01` 树谱;`A02` 资料;`A03` 父母;`A04` 配偶;`A05` 兄弟姐妹;`A06` 儿子;`A07` 女儿;`A08` 编辑;`A09` 其他关系入口;`A10` 删除 | `getGenealogyUser`, `userDel` | `C-T-TREE/C-T-DETAIL/C-T-PARENT/C-T-SPOUSE/C-T-SIBLING/C-T-CHILD/C-T-EDIT/C-T-DELETE/C-S-NAV` → T01/T03—T06 | A01—A09 `仅参考交互`并作为另一树状态证据保留,旧代码整体舍弃;A10 `待用户确认`。其中“女儿”复用 `addSon` 是反例 |
|
||||
| `JU03` `pages/index/vertical-swiper/j-video.nvue` | `JU03-A01` 视频子项播放/暂停 | 无 | `C-F-VIDEO-READ` → F10 | `仅参考交互`;随实验页不注册 |
|
||||
| `JU04` `pages/index/vertical-swiper/vertical-swiper.nvue` | `JU04-A01` 纵向列表;`A02` 播放切换 | 无 | `C-F-VIDEO-READ` → F10 | 两项 `仅参考交互`;这是 JX001 的目标文件,不计活动路由 |
|
||||
| `JU05` `pages/index/video/douyin-scrollview/douyin-scrollview.vue` | `JU05-A01` 纵滑;`JU05-A02` 播放;`JU05-A03` 评论;`JU05-A04@reaction` 点赞;`JU05-A04@share` 分享;`JU05-A05` 裸请求旧/外部接口 | 无 | A01/A02 → `C-F-VIDEO-READ`;A03 → `C-F-VIDEO-COMMENT`;A04@reaction → `C-F-VIDEO-REACTION`;A04@share → `C-F-VIDEO-READ/C-S-PLATFORM-SHARE` | A01—A03 与两个 A04 语义子动作均 `仅参考交互`;A05 `与当前产品冲突,明确舍弃` |
|
||||
| `JU06` `pages/index/video/douyin-scrollview/douyin-scrollview.nvue` | `JU06-A01` 纵滑;`JU06-A02` 播放;`JU06-A03` 评论;`JU06-A04@reaction` 点赞;`JU06-A04@share` 分享;`JU06-A05` 裸请求旧/外部接口 | 无 | A01/A02 → `C-F-VIDEO-READ`;A03 → `C-F-VIDEO-COMMENT`;A04@reaction → `C-F-VIDEO-REACTION`;A04@share → `C-F-VIDEO-READ/C-S-PLATFORM-SHARE` | A01—A03 与两个 A04 语义子动作均 `仅参考交互`;A05 `与当前产品冲突,明确舍弃` |
|
||||
| `JU07` `pages/mine/index2.vue` | `JU07-A01` 资料;`A02` 反馈;`A03` 帮助;`A04` 设置;`A05` 退出 | `getUserInfo` | `C-A-PROFILE-READ/C-M-FEEDBACK/C-M-HELP-LIST/C-A-PASSWORD-CHANGE/C-A-PHONE-CHANGE/C-A-LOGOUT/C-S-NAV` → M01/M06/M07/M10 | 五项 `仅参考交互`;作为可能的角色/布局状态保留,未注册事实不等同于无产品价值 |
|
||||
|
||||
## 七、反向覆盖索引
|
||||
|
||||
| 当前 owner | 设计证据 | 完成项目证据 | 规划结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| A01/A04/A05 认证 | D005、D053、D055 | J002、J065、J067 | 密码/短信/注册/找回按 TAC 与当前合同改造;微信关闭 |
|
||||
| G01/G03/G05 家谱工作区 | D004、D012、D043、D050、D054、D055 | J001、J005、J007、JU01 | 列表/概览/两阶段创建采用;旧巨型首页和菜单壳不迁移 |
|
||||
| G06/G08—G10 加入与审核 | D011、D050、D052 | J004、J047 | 普通申请采用;邀请码直入关闭;通知只能回流 G10 |
|
||||
| G11/G12 设置与字辈 | D006、D010、D049、D060 | J008、J009、J063、J069 | 字辈采用;始祖世代和家谱排序缺 owner 关闭 |
|
||||
| G 管理员与破坏性成员动作 | D025—D028 | J040—J042 | 待用户确认;无 capability 前关闭 |
|
||||
| T01/T03—T08 | D030—D036、D038、D055 | J045、J046、J058—J062、JU02 | T01 十入口已批准;头像卡/面板按当前架构重做;排行/绑定按合同关闭但不删需求 |
|
||||
| F01—F03 动态 | D029、D051、D055 | J043、J044 | 动态/评论改造采用;置顶/加精关闭 |
|
||||
| F04—F06 谱文 | D046—D048、D057 | J010—J014 | 列表/详情/编辑采用;内容密码待确认 |
|
||||
| F07—F09 相册/媒体 | D003、D045、D058、D059 | J015—J018 | 相册/照片采用;共享文件链闭合前不假上传 |
|
||||
| F10 视频 | D002、D007、D044 | J021、J022、J024、J072、J074、JX001、JU03—JU06;J023/J073 为独立 M 宣传视频证据 | 家族视频完整后端链缺失,保持关闭;纵滑只作交互证据;宣传视频不得借 F10 owner |
|
||||
| R01/R02 人物录与人物资料 | D031、D034—D036、D038 | J058—J062 | R01、R02 分别作为 PA-049、PA-038/048 的独立路由状态,复用唯一列表/详情/编辑数据 owner;R02 通用新建本地预览舍弃,编辑只导航 T05 |
|
||||
| R03/R04 人情往来 | D021—D023 | J034—J036 | 改造采用 |
|
||||
| R05—R07 礼仪/贺礼候选 | D013—D016、D037 | J028—J030 | “贺礼邀请”语义待确认,不能强塞祭祀献礼 |
|
||||
| R08 成长 | D017—D020、D036 | J031—J033、J062、J070、J071 | 改造采用;各入口/筛选/角色状态分别保留,证明等价后才共用 R08 实现 |
|
||||
| R10/R11 备忘/功德 | D008、D009、D024、D056 | J025—J027、J037—J039 | 现有 operation 范围内采用;缺详情/编辑的动作关闭 |
|
||||
| R09/重要证件 | D055 | J019、J020 | 人生事件与证件均缺 owner;证件另有隐私风险,保持关闭/待确认 |
|
||||
| N01/N02 与 G01/M01 未读入口 | D052、D055 | J047、J048、J075 | 列表/已读采用;未读计数使用唯一 `C-N-UNREAD-COUNT` owner,当前缺 operation 不从分页长度推断;N02 仅列表当代投影,详情/目标跳转关闭 |
|
||||
| M01—M10 | D039—D042、D053、D055 | J049—J057、J064—J068、J075—J078、JU07 | M08 保持当前“家谱邀请票据” owner;资料/安全/帮助/反馈/关于采用;APP 推广、推荐码、奖励、变现均为无当前路由候选,分别使用 `C-M-PROMO/C-M-REFERRAL/C-M-REWARD/C-M-MONEY`,不得冒充家谱邀请 |
|
||||
| S-ID/S-PERM/S-FILE/S-REGION | D003、D004、D032、D036、D038、D045、D056、D057 | 所有含 ID、权限、上传、地区动作的 J/JU 记录 | 全域唯一 owner;任何一个域不得另造兼容 ID、权限或上传协议 |
|
||||
|
||||
## 八、规范产品动作账本
|
||||
|
||||
本账本在用户确认规划前冻结产品动作身份和分母。`PA-xxx` 是产品动作,不是来源文件数量;`CUR:` 表示当前路由基线,`!` 表示只作为反例、禁止迁移。`D001-A01`(全项目功能目录)与 `D055-A01`(全项目思维导图)由全部 PA 继承,不在每行重复。PA 的“来源证据反链”栏允许把单页、默认状态的设计动作简写为 `Dxxx-Axx`;它与源表中的完整 `Dxxx-P01-S01-Axx` 是同一 ID,不是新增来源。相同 PA 下的多个来源仍保留各自 `D/J/JX/JU` 状态 ID、六类结论和验收记录;共用 owner 不等于合并状态证据。
|
||||
|
||||
边界固定为:`必需`进入产品完成分母;`候选`保留稳定 PA ID,但用户未单独批准时不进入完成分母,初始 `productCompletion=NOT_APPLICABLE`。规划阶段没有任何 PA 可标 `COMPLETE`。表中 `P/B/NA` 分别表示 `PARTIAL/BLOCKED/NOT_APPLICABLE`。
|
||||
|
||||
### 8.1 A 认证:PA-001—PA-006
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-001` | A01 密码+TAC 登录 | 必需 | `C-A-TAC-API/C-A-TAC-A11Y/C-A-LOGIN` | D005-A01;J002-A01;CUR:A01 | B |
|
||||
| `PA-002` | A01 短信 TAC、发码并登录 | 必需 | `C-A-TAC-API/C-A-TAC-A11Y/C-A-SMS-SEND/C-A-SMS-LOGIN` | D005-A01〔登录视觉态〕;CUR:A01 | B |
|
||||
| `PA-003` | A04 TAC、发码并注册 | 必需 | `C-A-TAC-API/C-A-TAC-A11Y/C-A-SMS-SEND/C-A-REGISTER` | D005-A03;J002-A02;J067-A01—A03;CUR:A04 | B |
|
||||
| `PA-004` | A05 TAC、发码并找回密码 | 必需 | `C-A-TAC-API/C-A-TAC-A11Y/C-A-SMS-SEND/C-A-RESET` | D005-A02;J002-A03;CUR:A05 | B |
|
||||
| `PA-005` | A-LEGAL 阅读服务条款/隐私协议 | 必需 | `C-LOCAL` | J065-A01;J067-A03;D005-A01—A03〔登录协议态〕 | P |
|
||||
| `PA-006` | A01 微信一键登录 | 候选 | `C-A-WECHAT` | D005-A04;D041-A03;J002-A04 | NA |
|
||||
|
||||
### 8.2 G 家谱工作区:PA-007—PA-034
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-007` | G01 查看/筛选我的家谱列表 | 必需 | `C-G-MINE` | D050-A01;D054-A01〔主题态〕;J001-A01;J007-A01/A03;J069-A01;CUR:G01 | B |
|
||||
| `PA-008` | G01 切换当前家谱上下文 | 必需 | `C-G-MINE/C-G-OVERVIEW` | J001-A02;D012-A01/A02、D043-A01/A02〔不同总览状态〕;CUR:G01 | B |
|
||||
| `PA-009` | G03 两阶段创建家谱及首位人物;仅首写稳定返回 ID 后续办 | 必需 | `C-S-REGION-CHILDREN/C-S-REGION-PATH/C-S-REGION-SEARCH/C-S-REGION-DETAIL/C-G-CREATE-GENEALOGY/C-T-PERSON-CREATE/C-G-CREATE-RECOVERY` | D004-A01;D050-A03;D054-A02;J005-A01;CUR:G03 | B |
|
||||
| `PA-010` | G05 查看家谱总览并进入模块 | 必需 | `C-G-OVERVIEW` | D012-A01/A02〔状态一〕;D043-A01/A02〔状态二〕;J001-A03;JU01-A01〔菜单态〕;!JU01-A02;CUR:G05 | B |
|
||||
| `PA-011` | G06 搜索公开家谱 | 必需 | `C-G-PUBLIC/C-G-OPTIONS` | D050-A02;CUR:G06 | B |
|
||||
| `PA-012` | G08 提交普通加入申请 | 必需 | `C-G-JOIN-CREATE/C-G-JOIN-RECOVERY` | D050-A04;D054-A03;CUR:G08 | B |
|
||||
| `PA-013` | G09 查看我的加入申请 | 必需 | `C-G-JOIN-MINE` | CUR:G09 | B |
|
||||
| `PA-014` | G09 撤回加入申请 | 必需 | `C-G-JOIN-WITHDRAW` | CUR:G09 | B |
|
||||
| `PA-015` | G10 查看待审核申请 | 必需 | `C-G-JOIN-PENDING` | D052-A03;J047-A02〔通知回流态〕;CUR:G10 | B |
|
||||
| `PA-016` | G10 审核申请(同意/拒绝) | 必需 | `C-G-JOIN-AUDIT` | D052-A03;J047-A02;CUR:G10 | B |
|
||||
| `PA-017` | G11 查看家谱设置 | 必需 | `C-G-OVERVIEW` | CUR:G11 | B |
|
||||
| `PA-018` | G11 更新允许修改的家谱设置 | 必需 | `C-G-SETTINGS` | CUR:G11 | B |
|
||||
| `PA-019` | G12 查看字辈/代次 | 必需 | `C-G-POEM` | D010-A01;D060-A01;J008-A01;CUR:G12 | B |
|
||||
| `PA-020` | G12 新增字辈 | 必需 | `C-G-POEM` | D010-A03;D060-A02〔管理入口〕;J009-A01;CUR:G12 | B |
|
||||
| `PA-021` | G12 编辑字辈 | 必需 | `C-G-POEM` | D010-A02;D049-A01/A02;J009-A01;CUR:G12 | B |
|
||||
| `PA-022` | G12 停用/恢复字辈 | 必需 | `C-G-POEM` | D049-A03;J009-A02 | B |
|
||||
| `PA-023` | M08 选择有正式邀请权限的家谱并查看当前活动票据状态 | 必需 | `C-G-MINE/C-G-INVITE-LIST` | CUR:M08 | B |
|
||||
| `PA-024` | G06 解析、确认、兑换家谱邀请码,查询结果并刷新权威工作区后直接入谱 | 必需 | `C-G-INVITE-RESOLVE/C-G-INVITE-REDEEM/C-G-INVITE-RESULT/C-G-MINE/C-G-OVERVIEW` | D011-A01;D050-A05;J004-A01;CUR:G06 | B |
|
||||
| `PA-025` | G01 调整多个家谱展示顺序 | 候选 | `C-G-SORT` | J069-A02 | NA |
|
||||
| `PA-026` | G-SORT 调整始祖世代 | 候选 | `C-G-SORT` | D006-A01;J063-A01〔空壳反例〕 | NA |
|
||||
| `PA-027` | G-ADMIN 查看管理员列表 | 候选 | `C-G-ADMIN/C-G-MEMBER-READ` | D025-A01;D026-A01〔管理态〕;J040-A01 | NA |
|
||||
| `PA-028` | G-ADMIN 选择并新增管理员 | 候选 | `C-G-ADMIN/C-G-MEMBER-READ` | D025-A02;D027-A01;!J041-A01;!J062-A02〔未完成分支〕 | NA |
|
||||
| `PA-029` | G-ADMIN 查看/修改管理员权限 | 候选 | `C-G-ADMIN` | D026-A03;D028-A01;J042-A01/A02;!J041-A02 | NA |
|
||||
| `PA-030` | G-ADMIN 移除管理员 | 候选 | `C-G-ADMIN/C-G-MEMBER-REMOVE` | D026-A02;J040-A02 | NA |
|
||||
| `PA-031` | G-MEMBER 移除家谱账号成员 | 候选 | `C-G-MEMBER-REMOVE` | 当前成员合同;D055-A01 | NA |
|
||||
| `PA-032` | G-MEMBER 主动退出家谱 | 候选 | `C-G-MEMBER-LEAVE` | 当前成员合同;D055-A01 | NA |
|
||||
| `PA-033` | G-MEMBER 转移家谱所有者 | 候选 | `C-G-MEMBER-TRANSFER` | 当前成员合同;D055-A01 | NA |
|
||||
| `PA-034` | G01 删除家谱 | 候选 | `C-G-DELETE` | J007-A02 | NA |
|
||||
|
||||
### 8.3 T 世系与成员:PA-035—PA-052
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-035` | T01 读取并呈现头像人物卡世系树 | 必需 | `C-T-TREE/C-S-FILE-READ` | D032-A01;D033-A01—A10〔面板前置态〕;J046-A01;JU02-A01〔另一树态〕;CUR:T01 | B |
|
||||
| `PA-036` | T01 横纵浏览、搜索并定位人物 | 必需 | `C-T-TREE/C-T-LIST` | D031-A01/A02;D032-A02;CUR:T01;CUR:T07 | B |
|
||||
| `PA-037` | T01 选择人物并打开唯一操作面板 | 必需 | `C-T-TREE` | D033-A01—A10〔十入口面板态〕;J046-A01—A03;JU02-A01—A09 | B |
|
||||
| `PA-038` | T03 查看人物真实资料;R02 为独立展示状态 | 必需 | `C-T-DETAIL` | D033-A01;D034-A01〔空/未绑定态〕;J046-A02;J058-A01;J059-A01;JU02-A02;CUR:T03;CUR:R02 | B |
|
||||
| `PA-039` | T03 查看亲属并继续进入亲属资料 | 必需 | `C-T-DETAIL/C-T-LIST` | D034-A02;D035-A01/A02;J058-A01 | B |
|
||||
| `PA-040` | T04 添加父亲 | 必需 | `C-T-PARENT` | D033-A02;J046-A03;J061-A02;JU02-A03;!J060-A02〔宽表单〕;CUR:T04 | B |
|
||||
| `PA-041` | T04 添加母亲 | 必需 | `C-T-PARENT` | D033-A03;J061-A02;JU02-A03;CUR:T04 | B |
|
||||
| `PA-042` | T04 添加配偶 | 必需 | `C-T-SPOUSE` | D033-A04;J046-A03;J061-A03;JU02-A04;CUR:T04 | B |
|
||||
| `PA-043` | T04 添加兄弟姐妹 | 必需 | `C-T-SIBLING` | D033-A05;J061-A04;JU02-A05;CUR:T04 | B |
|
||||
| `PA-044` | T04 添加儿子 | 必需 | `C-T-CHILD` | D033-A07;J061-A05;JU02-A06;CUR:T04 | B |
|
||||
| `PA-045` | T04 添加女儿 | 必需 | `C-T-CHILD` | D033-A08;J061-A05;JU02-A07〔`addSon` 反例〕;CUR:T04 | B |
|
||||
| `PA-046` | T06 原子调整同辈排行 | 必需 | `C-T-RANK` | D033-A06;D036-A02;!J060-A02;J061-A08;CUR:T06 | B |
|
||||
| `PA-047` | T-BIND 邀请并绑定人物与账号 | 必需 | `C-T-BIND-INVITE/C-T-BIND-IDENTITY/C-T-BIND-MUTATION/C-T-BIND-RESULT` | D033-A09;D034-A03;D036-A01;J058-A02;!J060-A01 | B |
|
||||
| `PA-048` | T05 编辑人物资料及头像;R02 编辑入口只委托本 owner | 必需 | `C-T-EDIT/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D033-A10;D034-A04;D036-A02;D038-A01;!D038-A02〔扩展隐私字段〕;J046-A03;!J060-A02/A03;!J061-A06〔通用人物新建〕;J061-A07;JU02-A08;CUR:T05;CUR:R02 | B |
|
||||
| `PA-049` | T07 查看/搜索世系人物目录;R01 为独立展示状态 | 必需 | `C-T-LIST` | D031-A01/A02;J062-A01;CUR:T07;CUR:R01 | B |
|
||||
| `PA-050` | T08 查看人物/成员状态 | 必需 | `C-T-LIST/C-G-MEMBER-READ` | D034-A01〔未绑定态〕;CUR:T08 | B |
|
||||
| `PA-051` | T05 停用世系人物 | 候选 | `C-T-DELETE` | J046-A04;JU02-A10 | NA |
|
||||
| `PA-052` | T01 使用表格式世系辅助模式 | 候选 | `C-T-TREE` | D030-A01〔表格态〕;J045-A01〔递归态〕 | NA |
|
||||
|
||||
### 8.4 F 家族内容:PA-053—PA-082
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-053` | F01 查看家族动态列表 | 必需 | `C-F-FEED-READ` | D051-A01/A02;J043-A01;CUR:F01 | B |
|
||||
| `PA-054` | F03 查看动态详情 | 必需 | `C-F-FEED-READ` | D051-A01/A02〔动态内容态〕;CUR:F03 | B |
|
||||
| `PA-055` | F02 发布文字/图片动态 | 必需 | `C-F-FEED-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D029-A01;D051-A04;J044-A01/A02;CUR:F02 | B |
|
||||
| `PA-056` | F02 唯一编辑 owner 编辑动态;F03 仅提供入口 | 必需 | `C-F-FEED-WRITE` | CUR:F02;入口 CUR:F03 | P |
|
||||
| `PA-057` | F03 删除动态 | 必需 | `C-F-FEED-WRITE` | J043-A04 | P |
|
||||
| `PA-058` | F03 点赞/取消点赞 | 必需 | `C-F-FEED-WRITE` | 当前 feed 合同;CUR:F03 | P |
|
||||
| `PA-059` | F03 评论或回复动态 | 必需 | `C-F-COMMENT-READ/C-F-COMMENT-WRITE` | D051-A03;J043-A02/A03 | B |
|
||||
| `PA-060` | F03 删除本人评论 | 必需 | `C-F-COMMENT-WRITE` | 当前评论合同;CUR:F03 | P |
|
||||
| `PA-061` | F01 置顶动态 | 候选 | `C-F-FEED-MODERATION` | D029-A02 | NA |
|
||||
| `PA-062` | F01 加精动态 | 候选 | `C-F-FEED-MODERATION` | D029-A03 | NA |
|
||||
| `PA-063` | F04 浏览谱文分类与列表 | 必需 | `C-F-ARTICLE` | D047-A01/A02;J010-A01;J011-A01;CUR:F04 | P |
|
||||
| `PA-064` | F05 阅读谱文详情 | 必需 | `C-F-ARTICLE` | D048-A01;J012-A01〔独立详情态〕;J013-A03;CUR:F05 | P |
|
||||
| `PA-065` | F06 新建谱文 | 必需 | `C-F-ARTICLE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D048-A02;D057-A01;J013-A01;CUR:F06 | B |
|
||||
| `PA-066` | F06 编辑谱文 | 必需 | `C-F-ARTICLE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D048-A02;D057-A01;J013-A02;CUR:F06 | B |
|
||||
| `PA-067` | F05 唯一删除 owner 删除谱文;F04 仅提供入口 | 必需 | `C-F-ARTICLE` | J011-A03;CUR:F05 | P |
|
||||
| `PA-068` | F04 增改删谱文分类 | 候选 | `C-F-ARTICLE-CATEGORY-WRITE` | D046-A01 | NA |
|
||||
| `PA-069` | F05 设置、校验或重置谱文访问密码;获批前不启用 | 候选 | `C-S-CONTENT-LOCK` | J011-A02;J014-A01 | NA |
|
||||
| `PA-070` | F07 查看相册列表 | 必需 | `C-F-ALBUM` | D058-A01/A03;J015-A01;CUR:F07 | P |
|
||||
| `PA-071` | F07 新建相册 | 必需 | `C-F-ALBUM` | D058-A02;D059-A01;J016-A01 | P |
|
||||
| `PA-072` | F07 编辑相册资料/封面 | 必需 | `C-F-ALBUM/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D003-A01;D045-A04;J018-A01 | B |
|
||||
| `PA-073` | F07 删除相册 | 必需 | `C-F-ALBUM` | D003-A02 | P |
|
||||
| `PA-074` | F08 查看并预览相册照片 | 必需 | `C-F-PHOTO-READ/C-S-FILE-READ` | D045-A01/A02;J017-A01;CUR:F08 | B |
|
||||
| `PA-075` | F09 上传文件并新增照片记录 | 必需 | `C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ/C-F-PHOTO-WRITE` | D045-A03;J017-A02;CUR:F09 | B |
|
||||
| `PA-076` | F08 删除照片 | 必需 | `C-F-PHOTO-WRITE` | J017-A03 | P |
|
||||
| `PA-077` | F10 查看家族视频列表 | 必需 | `C-F-VIDEO-READ` | D044-A01;J021-A01;CUR:F10 | B |
|
||||
| `PA-078` | F10 播放/查看视频详情 | 必需 | `C-F-VIDEO-READ` | D044-A02;J021-A02;J024-A01〔全局 URL 反例〕 | B |
|
||||
| `PA-079` | F10 发布视频 | 候选 | `C-F-VIDEO-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D007-A01;D044-A04;J022-A01/A02 | NA |
|
||||
| `PA-080` | F10 编辑视频 | 候选 | `C-F-VIDEO-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D044-A03〔管理入口〕;J022-A02 | NA |
|
||||
| `PA-081` | F10 删除视频 | 候选 | `C-F-VIDEO-READ/C-F-VIDEO-DELETE` | D002-A01;J021-A03 | NA |
|
||||
| `PA-082` | F10 纵滑短视频浏览/播放模式 | 候选 | `C-F-VIDEO-READ` | J072-A01;J074-A01@browse;JX001-A01;JU03-A01;JU04-A01/A02;JU05-A01/A02;JU06-A01/A02;!J072-A05;!J074-A02;!JU05-A05;!JU06-A05 | NA |
|
||||
|
||||
### 8.5 R 人物与族务:PA-083—PA-124
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-083` | R03 查看/筛选人情往来记录 | 必需 | `C-R-RELATIVE` | D021-A01;D022-A01〔管理态〕;J034-A01;CUR:R03 | P |
|
||||
| `PA-084` | R04 查看人情记录详情 | 必需 | `C-R-RELATIVE` | J035-A01;CUR:R04 | P |
|
||||
| `PA-085` | R04 新建人情记录 | 必需 | `C-R-RELATIVE` | D021-A02;D023-A01;J036-A01;CUR:R04 | P |
|
||||
| `PA-086` | R04 编辑人情记录 | 必需 | `C-R-RELATIVE` | D023-A01;J036-A02;CUR:R04 | P |
|
||||
| `PA-087` | R04 唯一删除 owner 删除人情记录;R03 仅提供入口 | 必需 | `C-R-RELATIVE` | D022-A02;J034-A02;CUR:R04 | P |
|
||||
| `PA-088` | R05 查看祭祀/礼仪列表 | 必需 | `C-R-CEREMONY` | CUR:R05 | P |
|
||||
| `PA-089` | R06 查看祭祀/礼仪详情 | 必需 | `C-R-CEREMONY` | D037-A01〔通用长文状态,入口决定 owner〕;CUR:R06 | P |
|
||||
| `PA-090` | R07 新建祭祀/礼仪 | 必需 | `C-R-CEREMONY` | CUR:R07 | P |
|
||||
| `PA-091` | R07 编辑祭祀/礼仪 | 必需 | `C-R-CEREMONY` | CUR:R07 | P |
|
||||
| `PA-092` | R06 唯一删除 owner 删除祭祀/礼仪;R05 仅提供入口 | 必需 | `C-R-CEREMONY` | 当前 ceremony 合同;CUR:R06 | P |
|
||||
| `PA-093` | R06 查看祭祀献礼 | 必需 | `C-R-CEREMONY` | 当前 gifts 合同 | P |
|
||||
| `PA-094` | R06 新增祭祀献礼 | 必需 | `C-R-CEREMONY` | 当前 gifts 合同;CUR:R06 | P |
|
||||
| `PA-095` | R06 删除祭祀献礼 | 必需 | `C-R-CEREMONY` | 当前 gifts 合同;CUR:R06 | P |
|
||||
| `PA-096` | R08 查看/筛选成长记录 | 必需 | `C-R-GROWTH` | D017-A01/A02〔普通态〕;D019-A01〔管理态〕;J031-A01〔旧入口〕;J070-A01〔人物/分类态〕;J071-A01/A02〔分类态〕;CUR:R08 | P |
|
||||
| `PA-097` | R08 查看成长记录详情 | 必需 | `C-R-GROWTH` | D018-A01;J031-A03;J032-A01 | P |
|
||||
| `PA-098` | R08 新建成长记录 | 必需 | `C-R-GROWTH` | D017-A03;D020-A01;J033-A01/A03;J070-A04 | P |
|
||||
| `PA-099` | R08 编辑成长记录 | 必需 | `C-R-GROWTH` | J033-A02 | P |
|
||||
| `PA-100` | R08 删除成长记录 | 必需 | `C-R-GROWTH` | D019-A02;J031-A02;J070-A03;!J071-A03〔错位逻辑〕 | P |
|
||||
| `PA-101` | R08 选择成长记录对应人物 | 必需 | `C-T-LIST/C-R-GROWTH` | D036-A01/A03;J062-A01 | B |
|
||||
| `PA-102` | R08 设置、校验或重置成长记录访问密码 | 候选 | `C-S-CONTENT-LOCK` | J014-A02;J070-A02 | NA |
|
||||
| `PA-103` | R10 查看备忘录列表 | 必需 | `C-R-MEMO` | D024-A01;J037-A01;CUR:R10 | P |
|
||||
| `PA-104` | R10 查看备忘详情 | 必需 | `C-R-MEMO` | J038-A03;J039-A01 | P |
|
||||
| `PA-105` | R10 新建备忘 | 必需 | `C-R-MEMO` | D024-A02;J038-A01 | P |
|
||||
| `PA-106` | R10 编辑备忘 | 必需 | `C-R-MEMO` | J038-A02 | P |
|
||||
| `PA-107` | R10 删除备忘 | 必需 | `C-R-MEMO` | J037-A02 | P |
|
||||
| `PA-108` | R11 查看功德记录 | 必需 | `C-R-MERIT-BASE` | D008-A01〔普通态〕;D009-A01〔管理态〕;J025-A01;CUR:R11 | P |
|
||||
| `PA-109` | R11 新增功德记录 | 必需 | `C-R-MERIT-BASE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | D056-A01;J026-A01 | B |
|
||||
| `PA-110` | R11 删除功德记录 | 必需 | `C-R-MERIT-BASE` | D009-A02;J025-A02 | P |
|
||||
| `PA-111` | R11 查看独立功德详情 | 候选 | `C-R-MERIT-DETAIL` | D008-A02〔进入管理/详情证据〕;J026-A03;J027-A01 | NA |
|
||||
| `PA-112` | R11 编辑功德记录 | 候选 | `C-R-MERIT-EDIT` | J026-A02 | NA |
|
||||
| `PA-113` | R09 查看/管理人生事件 | 必需 | `C-R-LIFE` | D055-A01;CUR:R09 | B |
|
||||
| `PA-114` | R-DOCUMENT 查看重要证件列表 | 候选 | `C-R-DOCUMENT` | J019-A01 | NA |
|
||||
| `PA-115` | R-DOCUMENT 查看重要证件详情 | 候选 | `C-R-DOCUMENT` | J019-A01〔列表进入详情状态〕 | NA |
|
||||
| `PA-116` | R-DOCUMENT 新建重要证件 | 候选 | `C-R-DOCUMENT/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | J020-A01/A02 | NA |
|
||||
| `PA-117` | R-DOCUMENT 编辑重要证件 | 候选 | `C-R-DOCUMENT/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | J020-A01/A02 | NA |
|
||||
| `PA-118` | R-DOCUMENT 删除重要证件 | 候选 | `C-R-DOCUMENT` | J019-A03 | NA |
|
||||
| `PA-119` | R-DOCUMENT 校验或重置证件访问密码 | 候选 | `C-S-CONTENT-LOCK` | J014-A03;J019-A02 | NA |
|
||||
| `PA-120` | R-GREETING 查看/筛选贺礼邀请列表 | 候选 | `C-R-GREETING` | D013-A01/A02;D014-A01〔管理态〕;J028-A01/A02 | NA |
|
||||
| `PA-121` | R-GREETING 查看贺礼邀请详情 | 候选 | `C-R-GREETING` | D015-A01;J029-A01;D037-A01〔通用详情态〕 | NA |
|
||||
| `PA-122` | R-GREETING 新建贺礼邀请 | 候选 | `C-R-GREETING` | D013-A03;D016-A01;J030-A01/A03 | NA |
|
||||
| `PA-123` | R-GREETING 编辑贺礼邀请 | 候选 | `C-R-GREETING` | D016-A01;J030-A02/A04 | NA |
|
||||
| `PA-124` | R-GREETING 删除贺礼邀请 | 候选 | `C-R-GREETING` | D014-A02;J028-A03 | NA |
|
||||
|
||||
### 8.6 N 消息:PA-125—PA-131
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-125` | N01 查看通知活动集合,并由 G01/M01 消费同一未读计数 owner | 必需 | `C-N-LIST/C-N-UNREAD-COUNT` | D052-A01;J047-A01〔混排反例〕;CUR:N01;CUR:G01;CUR:M01 | B |
|
||||
| `PA-126` | N01 标记单条通知已读 | 必需 | `C-N-READ-ONE` | 当前通知合同;CUR:N01 | B |
|
||||
| `PA-127` | N01 全部标记已读 | 必需 | `C-N-READ-ALL` | D052-A02;CUR:N01 | B |
|
||||
| `PA-128` | N02 查看通知详情 | 必需 | `C-N-DETAIL-SAME-SESSION/C-N-DETAIL-COLD-START` | D052-A04;J048-A01;CUR:N02 | B |
|
||||
| `PA-129` | N01 从通知安全回流目标业务页 | 必需 | `C-N-LIST/C-N-DETAIL-COLD-START` | D052-A03/A04;J047-A02;!J047-A03 | B |
|
||||
| `PA-130` | N02 查看广告/宣传消息详情 | 候选 | `C-N-DETAIL-SAME-SESSION/C-N-DETAIL-COLD-START/C-M-PROMO` | J075-A01 | NA |
|
||||
| `PA-131` | N01 支持生日、疫苗、备忘等类型化提醒 | 候选 | `C-N-TYPED-REMINDER` | D055-A01 | NA |
|
||||
|
||||
### 8.7 M 我的:PA-132—PA-160
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-132` | M01 查看“我的”主页和本人资料摘要 | 必需 | `C-A-PROFILE-READ` | D053-A01;J049-A01;JU07-A01〔另一布局态〕;CUR:M01 | B |
|
||||
| `PA-133` | M02 编辑本人资料及头像 | 必需 | `C-A-PROFILE-READ/C-A-PROFILE-WRITE/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | J061-A01;CUR:M02 | B |
|
||||
| `PA-134` | M03 查看安全设置入口及脱敏绑定信息 | 必需 | `C-A-PROFILE-READ` | D053-A04;J051-A01;JU07-A04;CUR:M03 | B |
|
||||
| `PA-135` | M04 修改登录密码 | 必需 | `C-A-PASSWORD-CHANGE` | J052-A01;CUR:M04 | B |
|
||||
| `PA-136` | M05 换绑手机号 | 必需 | `C-A-TAC-API/C-A-TAC-A11Y/C-A-PHONE-SEND/C-A-PHONE-CHANGE` | J068-A01;CUR:M05 | B |
|
||||
| `PA-137` | M06 浏览/搜索帮助分类与列表 | 必需 | `C-M-HELP-LIST` | D039-A01/A02;J050-A01/A02;J064-A01;JU07-A03;CUR:M06 | B |
|
||||
| `PA-138` | M06 阅读帮助文章 | 必需 | `C-M-HELP-LIST` | D040-A01;D037-A01〔通用长文态〕;J057-A01;J065-A02 | B |
|
||||
| `PA-139` | M07 提交反馈 | 必需 | `C-M-FEEDBACK` | D042-A01;D053-A03〔反馈入口〕;J053-A01;JU07-A02;CUR:M07 | P |
|
||||
| `PA-140` | M07 查看本人反馈记录 | 必需 | `C-M-FEEDBACK` | 当前 feedback GET;CUR:M07 | P |
|
||||
| `PA-141` | M-PROMO 查看 APP 推广内容 | 候选 | `C-M-PROMO` | D053-A02;J049-A02;J054-A01 | NA |
|
||||
| `PA-142` | M-PROMO 分享应用 | 候选 | `C-M-PROMO/C-S-PLATFORM-SHARE` | D041-A01;J054-A02;!旧跳转创建家谱 | NA |
|
||||
| `PA-143` | M-PROMO 展示/复制 APP 推广推荐码或二维码 | 候选 | `C-M-REFERRAL/C-M-PROMO/C-S-PLATFORM-CLIPBOARD` | J066-A01/A02 | NA |
|
||||
| `PA-144` | M-PROMO 展示邀请奖励或积分 | 候选 | `C-M-REWARD` | D041-A02 | NA |
|
||||
| `PA-145` | M09 查看 VIP 套餐 | 必需 | `C-M-VIP-READ` | J055-A01;CUR:M09 | P |
|
||||
| `PA-146` | M09 创建 VIP 订单 | 必需 | `C-M-VIP-ORDER` | J055-A02;CUR:M09 | B |
|
||||
| `PA-147` | M09 查看 VIP 订单记录 | 必需 | `C-M-VIP-READ` | J056-A01;CUR:M09 | P |
|
||||
| `PA-148` | M09 支付并确认 VIP 最终结果 | 候选 | `C-M-VIP-PAY` | J055-A02;J056-A01〔假成功页反例〕 | NA |
|
||||
| `PA-149` | M10 查看关于、协议、版本信息 | 必需 | `C-LOCAL` | D053-A05;J051-A02;J065-A02;CUR:M10 | P |
|
||||
| `PA-150` | M10 唯一会话 owner 安全退出登录;M01/M03 仅提供入口 | 必需 | `C-A-LOGOUT` | D053-A06;JU07-A05;CUR:M10 | B |
|
||||
| `PA-151` | M03 注销账号 | 候选 | `C-A-DEACTIVATE/C-A-SMS-SEND` | J049-A03 | NA |
|
||||
| `PA-152` | M-MONEY 查看余额和资金流水 | 候选 | `C-M-MONEY` | J076-A01/A02 | NA |
|
||||
| `PA-153` | M-MONEY 提交提现申请及收款码 | 候选 | `C-M-MONEY/C-S-FILE-BINARY-WRITE/C-S-FILE-REFERENCE-WRITE/C-S-FILE-READ` | J076-A03;J077-A01—A03;!J077-A04 | NA |
|
||||
| `PA-154` | M-MONEY 查看提现记录和状态 | 候选 | `C-M-MONEY` | J078-A01 | NA |
|
||||
| `PA-155` | M-PROMO 调起平台分享并承接变现资格/结果 | 候选 | `C-M-MONEY/C-M-PROMO/C-S-PLATFORM-SHARE` | J066-A04 | NA |
|
||||
| `PA-156` | M-PROMO 查看广告/宣传视频 | 候选 | `C-M-PROMO-VIDEO` | J001-A04;J023-A01;J049-A02〔广告/视频混排反例〕;J073-A01;!J073-A03〔旧接口〕 | NA |
|
||||
| `PA-157` | M08 幂等签发家谱邀请票据并在结果未知时恢复权威状态 | 必需 | `C-G-INVITE-ISSUE/C-G-INVITE-LIST` | !J006-A01〔空壳反例〕;CUR:M08 | B |
|
||||
| `PA-158` | M08 显示、复制并系统分享当前活动家谱邀请票据 | 必需 | `C-G-INVITE-LIST/C-S-PLATFORM-CLIPBOARD/C-S-PLATFORM-SHARE` | CUR:M08 | B |
|
||||
| `PA-159` | M08 撤销活动家谱邀请票据并收敛竞态/未知结果 | 必需 | `C-G-INVITE-REVOKE/C-G-INVITE-LIST` | CUR:M08 | B |
|
||||
| `PA-160` | M-PROMO 经官方 allowlist 打开应用下载页 | 候选 | `C-M-PROMO/C-S-SAFE-EXTERNAL-OPEN` | J066-A03 | NA |
|
||||
|
||||
### 8.8 F/M 视频互动追加候选:PA-161—PA-166
|
||||
|
||||
这些动作追加在账本末尾,是因为交叉评审发现旧 PA-082 把浏览、评论、点赞、分享误并到读取合同,且宣传视频不能借家族视频 owner;稳定 PA 不回收、不重排。
|
||||
|
||||
| PA | 唯一 owner / 产品动作 | 边界 | 合同键 | 来源证据反链 | 初始 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `PA-161` | F10 查看/发表短视频评论 | 候选 | `C-F-VIDEO-COMMENT` | J072-A02;J074-A01@comment;JU05-A03;JU06-A03 | NA |
|
||||
| `PA-162` | F10 点赞/取消点赞短视频 | 候选 | `C-F-VIDEO-REACTION` | J072-A03;JU05-A04@reaction;JU06-A04@reaction | NA |
|
||||
| `PA-163` | F10 系统分享短视频 | 候选 | `C-F-VIDEO-READ/C-S-PLATFORM-SHARE` | J072-A04;JU05-A04@share;JU06-A04@share | NA |
|
||||
| `PA-164` | M-PROMO 查看/发表宣传视频评论 | 候选 | `C-M-PROMO-VIDEO-COMMENT` | J073-A02@comment | NA |
|
||||
| `PA-165` | M-PROMO 点赞/取消点赞宣传视频 | 候选 | `C-M-PROMO-VIDEO-REACTION` | J073-A02@reaction | NA |
|
||||
| `PA-166` | M-PROMO 系统分享宣传视频 | 候选 | `C-M-PROMO-VIDEO/C-S-PLATFORM-SHARE` | J073-A02@share | NA |
|
||||
|
||||
### 8.9 共享门禁、状态变体与冻结计数
|
||||
|
||||
共享门禁不是额外的用户产品动作,不增加 PA 分母,但所有相关 PA 必须通过:
|
||||
|
||||
| 门禁 owner | 完成前置 |
|
||||
| --- | --- |
|
||||
| `S-ID` | 全部 ID 使用安全十进制字符串 wire |
|
||||
| `S-PERM` | 服务端 capability、撤权刷新和 403 语义 |
|
||||
| `S-FILE` | 选择/上传、业务引用、访问 URL、重进显示 |
|
||||
| `S-REGION` | 行政区划和 `regionCode` |
|
||||
| `S-SESSION` | 会话持久化、失效、账号切换和迟到响应隔离 |
|
||||
| `S-NAV` | route key、必填参数、返回与根切换 |
|
||||
| `S-A11Y` | 触控、字号、焦点、读屏和系统返回 |
|
||||
|
||||
PA 是产品动作分母,状态变体是独立验收分母。已知跨路由复用与 N02 状态先冻结为:
|
||||
|
||||
| 状态 ID | 入口与条件 | `contractState` | `dataMode` | `productCompletion` |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `PA-038-S01` | 从 T01/T07 进入 T03 查看人物资料 | `CONTRACT_CONFLICT` | `LOCAL_PREVIEW` | `BLOCKED` |
|
||||
| `PA-038-S02` | 从 F01→R01→R02 的人物录上下文查看同一人物资料 | `CONTRACT_CONFLICT` | `LOCAL_PREVIEW` | `BLOCKED` |
|
||||
| `PA-048-S01` | T03 进入 T05 编辑;T05 是唯一 mutation owner | `CONTRACT_CONFLICT` | `LOCAL_PREVIEW` | `BLOCKED` |
|
||||
| `PA-048-S02` | R02 的编辑入口只导航 T05,不在 R02 本地保存或报成功 | `CONTRACT_CONFLICT` | `CLOSED` | `BLOCKED` |
|
||||
| `PA-049-S01` | T01 进入 T07 世系成员目录 | `CONTRACT_CONFLICT` | `LOCAL_PREVIEW` | `BLOCKED` |
|
||||
| `PA-049-S02` | F01 进入 R01 人物录,并保留 R01→R02→R01 返回现场 | `CONTRACT_CONFLICT` | `LOCAL_PREVIEW` | `BLOCKED` |
|
||||
| `PA-125-S01` | N01 读取通知活动集合 | `CONTRACT_CONFLICT` | `LOCAL_PREVIEW` | `BLOCKED` |
|
||||
| `PA-125-S02` | G01 显示共享未读计数;不得从分页列表长度推断 | `MISSING_OPERATION` | `CLOSED` | `BLOCKED` |
|
||||
| `PA-125-S03` | M01 显示同一共享未读计数;账号切换后必须失效 | `MISSING_OPERATION` | `CLOSED` | `BLOCKED` |
|
||||
| `PA-128-S01` | 从 N01 当前会话、且完整列表项快照仍在时打开 | `CONTRACT_CONFLICT` | `LOCAL_PREVIEW` | `PARTIAL` |
|
||||
| `PA-128-S02` | 冷启动、进程重启、外部深链或快照丢失 | `MISSING_OPERATION` | `CLOSED` | `BLOCKED` |
|
||||
|
||||
R02 现存的“通用新建人物本地预览”和 T06 现存的“关系修正本地预览”不是已批准 PA:二者均不得保存、造 ID、改列表或显示成功;本轮分别关闭/移除,不能偷换成 T04 关系新增、G03 首人创建或 PA-046 排行。用户以后若明确需要独立创建人物或关系修正,必须重新规划独立产品动作及原子合同。
|
||||
|
||||
其他外观相似、同路由或同动作来源也按 `PA-xxx-Snn` 追加独立状态验收记录;只有入口、对象、数据、接口、权限、动作和返回行为全部证明等价时才能复用状态实现,不能删除来源状态 ID 或减少验收分母。规划阶段的 `P/PARTIAL` 只说明当前存在结构或 `LOCAL_PREVIEW`,不代表动作是 LIVE,也不能绕过 `C-S-ID/C-S-CAPABILITY` 等共享冲突。
|
||||
|
||||
冻结计数为:
|
||||
|
||||
- `productActionsTotal=166`;
|
||||
- `requiredActions=111`,进入产品完成分母;
|
||||
- `candidateActions=55`,用户未单独批准时不进入完成分母;
|
||||
- `approvedCandidateActions=0`;
|
||||
- 规划阶段 `completeRequiredActions=0`、`partialRequiredActions=42`、`blockedRequiredActions=69`、`notApplicableCandidateActions=55`。
|
||||
|
||||
候选日后获批只改变边界和完成态,不创建新 PA ID;用户拒绝的候选也保留 ID 与拒绝记录,不删除或重排。
|
||||
|
||||
## 九、甄别分母与确认后冻结方式
|
||||
|
||||
当前源证据共拆出 341 条动作记录:
|
||||
|
||||
| 结论 | 设计源 | 完成项目活动/注释路由 | 未注册文件 | 合计 |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| 直接采用 | 0 | 0 | 0 | 0 |
|
||||
| 改造后采用 | 86 | 75 | 0 | 161 |
|
||||
| 仅参考交互 | 19 | 26 | 26 | 71 |
|
||||
| 后端缺失,暂时关闭 | 15 | 18 | 0 | 33 |
|
||||
| 与当前产品冲突,明确舍弃 | 5 | 17 | 3 | 25 |
|
||||
| 待用户确认 | 14 | 36 | 1 | 51 |
|
||||
| 合计 | 139 | 172 | 30 | 341 |
|
||||
|
||||
这里的 341 是“源状态动作记录”,不是 341 个已经判定互不相同或已经判定重复的产品功能。多个截图和旧页面可能是独立状态,也可能在证据充分后共用同一个实现 owner。
|
||||
|
||||
`D001-A01` 与 `D055-A01` 是全部 PA 继承的全局覆盖目录;`D001-A02`、`D055-A02—A04` 是非本仓库端形态,统一作为全局冲突舍弃证据;`J003-A01` 是纯日期时间选择演示,统一作为全局冲突舍弃证据。`J003` 是唯一不生成 PA 反链的源基 ID;上述全局动作仍必须进入 341 条来源证据计数,不能用全局规则掩盖其他逐动作遗漏。
|
||||
|
||||
本次交给用户确认的证据与产品动作范围分别冻结为:
|
||||
|
||||
- `referenceEvidenceRecords=341`;
|
||||
- `adaptedReferenceEvidenceRecords=161`,只是“改造后采用”的来源证据数量,不是产品动作分母;
|
||||
- `interactionEvidenceRecords=71`,只增加独立交互/状态验收证据,不新增数据合同;
|
||||
- `closedReferenceEvidenceRecords=33`;
|
||||
- `rejectedReferenceEvidenceRecords=25`;
|
||||
- `pendingReferenceEvidenceRecords=51`,已反链到候选 PA,用户未单独批准时不进入实现范围;
|
||||
- `productActionsTotal=166`、`requiredActions=111`、`candidateActions=55`、`approvedCandidateActions=0`;
|
||||
- `approvedNewRoutes=0`,当前提案全部先落现有 owner 或诚实关闭。
|
||||
|
||||
用户确认后,执行第 0 批只能:
|
||||
|
||||
1. 重算源文件、活动/注释路由与未注册文件清单,确认 341 条状态动作记录未因源变化失效;
|
||||
2. 原样冻结 PA-001—PA-166、111 个必需动作、55 个候选动作及全部来源反链;执行阶段不得再归并、拆分、删除或重排 PA;
|
||||
3. 对已证明等价的状态动作可共用实现 owner,但每个来源状态 ID 仍保留独立验收记录;新发现的角色/数据/权限/错误状态追加 `PA-xxx-Snn`,不能覆盖既有状态或改变产品动作身份;
|
||||
4. “待用户确认”若本次仍无单独选择,一律维持候选 PA 的 `NOT_APPLICABLE`,不新增路由;
|
||||
5. 分别报告路由分母、`requiredActions=111`、`liveCompletedActions`、逐 PA 四字段和 341 条来源证据去向,不得把来源证据条数、代码复用或结构遍历充当产品完成率;
|
||||
6. 任一参考动作即使关闭态检查通过,其必需 PA 的 `productCompletion` 仍可为 `BLOCKED`;候选未获批则为 `NOT_APPLICABLE`,不能写成整个项目 PASS。
|
||||
|
||||
## 十、参考项目资产复用索引
|
||||
|
||||
用户已允许把第二参考源中的图标等资产作为当前产品的复用候选。当前只读分母为 `referenceAssetFiles=531`,全部位于 `Jiapu-App\static`,约 6.45 MiB;按声明扩展名为 PNG 307、GIF 221、SVG 2、JPG 1,按文件签名为 PNG 311、GIF 217、SVG 2、JPG 1。已发现 6 个扩展名/MIME 不一致和 14 组完全重复文件。
|
||||
|
||||
资产不会增加或改变 PA 分母。任何文件在复制前必须建立 `RAxxx` 记录并绑定一个已批准 PA 及其目标路由/组件/状态;相似图标、不同选中态、禁用态、权限态或主题态仍分别留证。逐文件字段和来源、隐私、旧品牌、格式、安全、视觉、无障碍、性能、候选构建验收门禁以主计划第 11.10 节为准。
|
||||
|
||||
当前候选分类只用于确定优先甄别顺序,不是逐文件采用结论;在 `RAxxx` 记录通过门禁前,以下各类采用数都仍为 0:
|
||||
|
||||
| 类别 | 例子 | 初始决定 |
|
||||
| --- | --- | --- |
|
||||
| 水墨/宗祠/谱书氛围 | `iconpng/902.png`、`iconpng/z8526@2x.png`、`login/bj.jpg`、`iconpng/book.png` | 优先甄别,尚未形成采用结论;固定文字、裁切、格式和可读性先处理 |
|
||||
| 世系人物卡装饰 | `iconpng/treeBJ.png` | 优先甄别,尚未形成采用结论;若采用优先九宫格或重绘,避免 81×105 小图直接拉伸 |
|
||||
| 中性导航/功能图标 | `icon/index.svg`、`navigation/*`、`tabulation/*`、`pu/*`、`jr.png` | 优先逐文件甄别直接复用或重绘,尚未形成采用结论;必须统一当前图标系统 |
|
||||
| 默认头像风格 | `nan.png`、`nv.png`、`treeman.png` 及尺寸变体 | `待用户确认`具体风格;先过来源、肖像、偏见和重复哈希门禁 |
|
||||
| 水墨蝴蝶动效 | `login/hd*.gif` | 仅作动效方向候选;必须有静态降级、减少动态效果和性能预算 |
|
||||
| QQ 表情、抖音/视频实验、支付/微信/支付宝、VIP/奖励、旧 logo/口号 | `emojis/qq/*`、`douyin/*`、视频实验图、`wx.png`、`zfb.png`、`logo.png` 等 | `与当前产品冲突,明确舍弃`直接迁入;必要时仅参考语义并重绘 |
|
||||
|
||||
规划确认时固定:
|
||||
|
||||
- `referenceAssetFiles=531`;
|
||||
- `approvedDirectReuseAssets=0`;
|
||||
- `approvedAdaptReuseAssets=0`;
|
||||
- `assetReuseAuthorization=USER_ALLOWED_WITH_PER_FILE_GATES`。
|
||||
|
||||
收到“开始执行”后,采用数只能随已完成门禁的 `RAxxx` 增加;不能整目录复制,不能用资产存在反向启用 F10、支付、邀请奖励等关闭或候选功能,也不能迁移旧组件、样式或外部资源地址。
|
||||
@@ -1,628 +0,0 @@
|
||||
# 今晚全量联调与明早测试执行计划
|
||||
|
||||
> 修订日期:2026-07-24(北京时间)
|
||||
> 时间口径:“今晚”固定指 2026-07-23 晚间,“明早”固定指 2026-07-24 上午。
|
||||
> 当前状态:用户已明确说“开始执行”,实施、测试与 MuMu 基座联调已启动;用户将本轮硬截止提前为 `T_due=2026-07-24 08:00`。55 个候选 PA 本轮仍不纳入(`approvedCandidateActions=0`)。
|
||||
|
||||
> 本次续执行状态:逐页 Apifox 账本已覆盖 53 个页面文件;当前页面目录不再导入 `data/mock`。已接线但未实测的创建/维护动作仍统一记为 `DECLARED_UNVERIFIED`;缺 DTO、ID、权限或上传 owner 的页面已改为明确关闭态,不以 fixture、本地数组、timer 或本地成功提示冒充服务端结果。本次续执行只做静态 API 语法和源代码归属核验,未构建、未操作 MuMu、未发起任何真实写入。
|
||||
|
||||
## 0. 已执行记录与人工回归保留
|
||||
|
||||
- 已通过 HBuilderX 标准基座连接 `emulator-5554` 并完成差量编译、同步、启动;本轮不构建或安装独立测试包。
|
||||
- A01 密码登录页已在 MuMu 实机完成账号密码提交、协议勾选和真实供应商 TAC challenge 展示验证;TAC 已改为供应商原生呈现,不再叠加项目标题、主题、按钮或覆盖供应商刷新/关闭控件。
|
||||
- 已自动通过 A01/A04/A05 的认证合同、认证接口映射、短信冷却、TAC renderjs 安全传输、注册后导航和编译审计;原始截图仅保存在本机临时受限目录,仓库不保留账号、手机号、令牌、短信或 TAC 相关截图。
|
||||
- 2026-07-23 20:56 全量夜跑逻辑调度 `208` 项:`PASS=162`、`EXPECTED_BLOCKED=19`、`FAIL=0`、`INFRA_ERROR=27`、`timedOut=0`。27 项均依赖“`localhost:5173` 的 H5 页面 + `127.0.0.1:9222` 的 Chrome 调试页”;临时 H5 服务可启动,但当前执行环境拒绝启动 Chrome 调试端口,故夜跑器已将这组前置条件显式标为 `H5_CHROME_RUNTIME_UNAVAILABLE`,不将其写成产品失败或通过。临时 H5 服务已停止。
|
||||
- 2026-07-23 23:01 HBuilderX 5.07 已通过标准基座向 `emulator-5554` 完成最新差量编译;控制台末次记录为“项目 jiapuapp 编译成功”。未生成或安装独立测试包。
|
||||
- 同轮 Apifox 合同收紧后的最小验证已通过:`compile-audit`、`navigation-flow-contract`、`t04-relative-remote-close-contract`、`t05-member-remote-close-contract`、`lineage-write-apifox-contract`、`t03-t08-member-flow-contract`、`tree-member-fixture-runtime-smoke`。新增 Apifox 写入合同脚本尚未纳入 20:56 的历史全量夜跑,后续全量统计须重新计算,不得沿用 `208` 作为最新 inventory。
|
||||
- 2026-07-23 23:29 已移除 T01 旧固定底部抽屉;点击头像人物卡现在直接打开唯一人物操作面板,面板中央头像可进入 T03,十个入口仍由同一 `selected` 人物上下文承载。相关 T01 面板、视觉、导航、文档流与编译审计已通过;23:28 的 HBuilderX 标准基座差量编译同样成功,未生成或安装独立测试包。
|
||||
- 2026-07-23 23:37 已按 Apifox 的已登录改密 owner 接通 M04:`PUT /genealogy/app/auth/password`、`oldPassword/newPassword` 32 位 MD5 摘要、鉴权与 APP `clientId` 由统一请求层持有。页面移除“仅本地校验、不提交”伪流程,成功/明确失败/离页取消均有对应状态;本轮不实际修改测试账号密码,真实调用与密码恢复保留人工窗口。
|
||||
- 2026-07-23 23:42 已按 Apifox 的已登录退出 owner 接通 M10:REMOTE 模式使用 `DELETE /genealogy/app/auth/logout`,无请求体,鉴权与 APP `clientId` 继续由统一请求层持有;严格成功才可确认远端已响应。无论请求失败、取消或结果未知,本机会话均安全清理并回到 A01,不自动重试、不把失败写成服务端已退出。本轮未对测试账号发送该敏感请求。M10、M04 的静态契约、页面归属、导航和编译审计均已通过;23:42 HBuilderX 标准基座差量编译成功,未生成或安装独立测试包。
|
||||
- 2026-07-23 23:50 当前源码的全量夜跑已完整执行 `209/209`:`PASS=163`、`EXPECTED_BLOCKED=19`、`FAIL=0`、`INFRA_ERROR=27`、`timedOut=0`、`NOT_RUN=0`。库存为 `baselineInventoryTests=204` 加本轮 `newExecutableTests=5`。27 项均是需 `localhost:5173` 页面及 `127.0.0.1:9222` Chrome 调试页的 H5 运行时检查,统一记 `H5_CHROME_RUNTIME_UNAVAILABLE`,不写成产品失败或通过;因此本轮尚无可冻结候选。T01 唯一操作面板替换造成的五项旧断言/孤儿资产偏差已外科式收口并重跑通过。23:50 HBuilderX 5.07 标准基座差量编译成功,未生成或安装独立测试包。
|
||||
- 2026-07-24 00:00 已从 `emulator-5554` 的 HBuilderX 标准基座读取 A01 实机画面:国风登录页、密码/验证码切换、协议入口、注册/忘记密码与微信登录入口均正常呈现,无白块、截断或覆盖。此检查未输入账号密码、未触发 TAC、短信、注册、找回或任何远端写操作;截图只保留在本机临时受限目录,不入库,也不替代登录后的完整实机验收。
|
||||
- 2026-07-24 00:13 已用 HBuilderX 临时 Web 运行复核 H5 页面服务,`http://localhost:5173` 返回 `200`;但 `127.0.0.1:9222/json/list` 仍超时,当前执行环境不允许启动隔离 Chrome 调试端口。故 27 项 H5 Chrome 运行时检查继续统一记 `H5_CHROME_RUNTIME_UNAVAILABLE`,不改变其测试口径,也不将 H5 服务可达写成浏览器运行时通过。
|
||||
- 2026-07-24 00:30 已在本机临时验收目录建立唯一 `role-seed-matrix.json`:仅登记脱敏测试角色别名、允许动作、人工 TAC/短信阻塞与清理责任,当前对象 ID 为零;不含账号、手机号、密码、令牌、验证码、TAC proof 或原始响应。
|
||||
- 2026-07-24 00:31 已对当前源码重新执行 T0 夜跑:`inventory=209`、`scheduled=25`、`executed=25`、`PASS=6`、`EXPECTED_BLOCKED=19`、`FAIL=0`、`INFRA_ERROR=0`、`timedOut=0`、`notRunScheduled=0`;其余 184 项为本次 T0 未调度项,不得写成已通过。输出仅保存在本机临时验收目录。
|
||||
- 2026-07-24 00:33 已重跑 T01/T03—T08 的 12 项人物流门禁:唯一人物操作面板、树状态/视觉/文档流、成员详情映射、亲属与资料写入合同、排行关闭态、Apifox 写入合同及树 fixture runtime 均通过。此为静态/运行时映射证据,不替代未取得的真实服务端写入响应。
|
||||
- 2026-07-24 00:36 已对受保护的“我的家谱”读取执行无鉴权只读探测:远端可达,HTTP 成功信封内业务码为 `401` 且数据为空。未携带账号、令牌或其他凭据,未发送写请求;后续受保护读取/写入的唯一下一步仍是人工完成 TAC 并建立会话。
|
||||
- 2026-07-24 00:40 已对当前源码完整执行 `ALL` 夜跑 `209/209`:`PASS=163`、`EXPECTED_BLOCKED=19`、`FAIL=0`、`INFRA_ERROR=27`、`timedOut=0`、`NOT_RUN=0`。27 项均在连接 `localhost:5173` 的 Chrome 调试页前被统一标记 `H5_CHROME_RUNTIME_UNAVAILABLE`,没有进入产品断言;不得将它们记为产品失败或通过。输出仅保存在本机临时验收目录。
|
||||
- 2026-07-24 00:45 已再次读取 `emulator-5554` 的 HBuilderX 标准基座 A01 画面:国风背景、密码/验证码切换、手机号与密码输入区、协议入口、注册和找回入口完整可见,无白屏、截断或遮挡。未输入账号、未触发 TAC/短信或远端写操作;截图只保存在本机临时受限目录。
|
||||
- 2026-07-24 00:51 已在 Apifox 的 APP 目录核对“搜索行政区划” operation 为 `GET /genealogy/region/search`,随后以只读请求取得当前部署实证:HTTP `200`、业务码 `200`、服务器 `Date=Thu, 23 Jul 2026 16:51:08 GMT`,单条结果稳定含字符串 `regionCode`、`label`、`parentCode`、`ancestors`、`regionName`、`regionLevel`、`regionType` 与 `leaf`。当前部署的旧 `/genealogy/app/region/search` 同样返回该投影,但 Apifox 的 APP 目录 owner 仍以前者为准;不将双路径同响应静默写成兼容 owner。
|
||||
- 2026-07-24 00:52 已重订 G03 客户端历史门禁:页面在原子 bootstrap、结果查询和错误收口合同缺失时保持明确关闭态,不生成本地预览,也不存在虚构的远端请求;该关闭态门禁已转为可通过并从预期阻塞清单移除。保护 OpenAPI 门禁同时只报告实际快照与 Apifox 的合同冲突,不要求项目实现未声明的 bootstrap。
|
||||
- 2026-07-24 00:55 已对更新后的当前源码再次完整执行 `ALL` 夜跑 `209/209`:`PASS=164`、`EXPECTED_BLOCKED=18`、`FAIL=0`、`INFRA_ERROR=27`、`timedOut=0`、`NOT_RUN=0`。库存仍为 `baselineInventoryTests=204` 加本轮 `newExecutableTests=5`。27 项均因当前执行环境拒绝提供 `127.0.0.1:9222` 的 Chrome 调试运行时而在产品断言前标记为 `H5_CHROME_RUNTIME_UNAVAILABLE`;不记为产品失败或通过。输出仅保存在本机临时验收目录。
|
||||
- 2026-07-24 00:56 已重订 M06 帮助中心的旧 OpenAPI 门禁:不再要求受保护快照提供 `RListHelpArticleVo`、文章分类/标题/纯文本正文等当前 Apifox 未声明的 DTO,也不引入独立详情 owner。门禁现已通过并从预期阻塞清单移除;M06 页面补充“本地使用说明、非服务端文章”的可见来源提示,仍只提供本地说明与 M07 反馈入口,远端列表保持 `DECLARED_UNVERIFIED`。
|
||||
- 2026-07-24 00:57 已对 M06 变更后的当前源码再次完整执行 `ALL` 夜跑 `209/209`:`PASS=165`、`EXPECTED_BLOCKED=17`、`FAIL=0`、`INFRA_ERROR=27`、`timedOut=0`、`NOT_RUN=0`。27 项仍全部为 `H5_CHROME_RUNTIME_UNAVAILABLE`,未进入产品断言;输出仅保存在本机临时验收目录。
|
||||
- 2026-07-24 00:58 HBuilderX 5.07 控制台记录“开始编译…”后输出“项目 jiapuapp 编译成功”,已通过标准基座同步 `emulator-5554`;未生成或安装独立测试包。前台 CLI 未自行退出但对应基座仍正常前台,故只将 IDE 的成功回执计为编译证据,不将 CLI 常驻误记为失败或额外构建。
|
||||
- 2026-07-24 01:04 已读取同步后的 `emulator-5554` 标准基座 A01 画面:登录页完整可见,密码/验证码登录切换、手机号/密码输入、找回、微信、注册与协议入口均无白屏、截断或错位。未输入账号、未勾选协议、未触发 TAC/短信或任何远端写请求;截图只保存在本机临时受限目录。
|
||||
- 2026-07-24 01:08 已重订认证旧 OpenAPI 门禁:密码登录的唯一请求 wire 为 `phone`、MD5 `password` 与 `grantType=password`,原生 TAC 保持客户端前置,不上传 `validToken`;短信发送仍为唯一消费 `validToken` 的认证动作。门禁与认证 API runtime 均通过,并从预期阻塞清单移除。
|
||||
- 2026-07-24 01:10 已对当前源码完整执行 `ALL` 夜跑 `209/209`:`PASS=167`、`EXPECTED_BLOCKED=15`、`FAIL=0`、`INFRA_ERROR=27`、`timedOut=0`、`NOT_RUN=0`。剩余 15 项均为仍缺真实合同、稳定 DTO/权限投影或人工前置的精确阻塞;27 项仍为未取得 `127.0.0.1:9222` Chrome 调试运行时的 `H5_CHROME_RUNTIME_UNAVAILABLE`,未进入产品断言。输出仅保存在本机临时验收目录。
|
||||
- 2026-07-24 01:12 已修复 G03 OpenAPI 门禁以中文计划文件名读取时在 Windows PowerShell 无 BOM 解析下产生的伪阻塞;该门禁现只依据快照/客户端合同判断并通过,也已从预期阻塞清单移除。若同版本快照以后出现错误 owner,仍会以精确 `BLOCKED` 报告。
|
||||
- 2026-07-24 01:20 已再跑最新 T0:`25/25`,`PASS=10`、`EXPECTED_BLOCKED=15`、`FAIL=0`、`INFRA_ERROR=0`、`NOT_RUN=184`。本轮 allowlist 与计划中的 15 条精确阻塞逐项一致;其余 H5 运行时前置只在 `ALL` 中作为基础设施阻塞统计。
|
||||
- 2026-07-24 03:59 已将 M04/M10 的旧快照门禁改为当前 Apifox 已核对客户端接线门禁:M04 校验 `PUT /genealogy/app/auth/password` 的 MD5 body 与取消归属;M10 校验 `DELETE /genealogy/app/auth/logout` 的无 body、取消归属与本机会话兜底。两项均通过并从预期阻塞清单移除;真实改密、服务端退出继续分别保留人工恢复/登录会话验证,未发起任何远端 mutation。随后完整执行 `ALL` 夜跑 `209/209`:`PASS=169`、`EXPECTED_BLOCKED=13`、`FAIL=0`、`INFRA_ERROR=27`、`timedOut=0`、`NOT_RUN=0`。27 项仍均为缺失 `127.0.0.1:9222` Chrome 调试运行时的 `H5_CHROME_RUNTIME_UNAVAILABLE`,未进入产品断言;输出仅保存在本机临时验收目录。
|
||||
- 2026-07-24 04:00 已按更新后的 manifest 再跑 T0:`23/23`,`PASS=10`、`EXPECTED_BLOCKED=13`、`FAIL=0`、`INFRA_ERROR=0`、`NOT_RUN=186`;allowlist 与第 0.2 节的 13 条精确自动阻塞逐项一致。该结果只说明安全/合同候选门禁没有新增失败,不替代人工 TAC、短信、敏感 mutation 或登录后实机闭环。
|
||||
- 早晨人工回归保留:密码登录真实拖动 TAC;短信登录、注册、忘记密码的真实短信与 TAC。不得绕过、猜解或重复请求这些人机/短信步骤。
|
||||
|
||||
### 0.1 明早人工回归最短清单
|
||||
|
||||
1. 使用已启动的 HBuilderX 标准基座进入 A01;不构建或安装独立测试包。
|
||||
2. 人工勾选协议后,在密码登录页使用已单独提供的测试账号发起一次登录;在供应商原生 TAC 中由人工完成拖动,不添加任何项目自定义样式或覆盖层。成功后检查是否进入 G01,并冷启动一次确认会话恢复;不记录或截图凭据、令牌、验证码和 TAC proof。
|
||||
3. 短信登录、注册和忘记密码各自需要真实收码人和原生 TAC:每个场景只在本人在场时发起一次,遵守页面冷却;未能完成即记录“人工 TAC/短信阻塞”,不重试、不猜解、不绕过。
|
||||
4. 换绑手机号、修改密码、注销、支付、提现、删除和退出家谱均不在无人值守阶段执行。若人工验证修改密码,结束后按约定恢复,并只在本机临时脱敏台账登记结果。
|
||||
5. 人工结果只记录页面、动作、时间、四字段结论和非敏感对象 ID;远端返回、手机号、账号、密码、令牌、验证码、TAC proof、邀请码和个人资料一律不进入仓库、文档或截图文件名。
|
||||
|
||||
### 0.2 当前 12 条精确自动阻塞与解除条件
|
||||
|
||||
| 门禁 | 当前阻塞 | 解除条件 |
|
||||
| --- | --- | --- |
|
||||
| Android 认证无障碍 | 原生 TAC 的 TalkBack、键盘与大字号无法由当前自动化可靠判定 | 早晨在 MuMu/真机人工完成原生 TAC 无障碍回归 |
|
||||
| G11 家谱设置 | 依赖的 mine/overview 工作区读取未取得唯一稳定 owner | 先收敛工作区读取合同与真实权限投影 |
|
||||
| G12 字辈诗 | 正常列表、维护列表、批量预览与保存已接线,但尚未获得真实登录会话下的读取/预览/保存响应 | 在人工可观察会话中按“读列表→读维护→预览→保存→维护回读”验证;浏览器 CORS 仅是 H5 环境前置,不替代 APP 业务合同 |
|
||||
| 家谱工作区 | 单家谱 overview owner 在受保护快照中缺失或不唯一 | 以 Apifox 与同版本快照收敛唯一读取路径、DTO 与权限 |
|
||||
| 邀请票据 | 无“我的票据/签发/撤销/接受”当前 operation | 后端提供独立邀请票据闭环,不以普通申请替代 |
|
||||
| 加入申请 | public 搜索/申请 operation 标识与快照不一致 | 后端同版本合同明确查询、提交、撤回、审核及结果语义 |
|
||||
| 世系 locator | 缺少精确定位人物的读取 operation | 后端声明并实测人物定位/恢复读取 owner;不得从列表猜 ID |
|
||||
| 通知读取 | 缺未读数 operation 且列表无稳定通知 DTO | 后端提供未读数与列表 item 的 ID、正文、类型/跳转投影 |
|
||||
| 通知已读状态 | notification ID wire 与 `RVoid` 信封约束不完整 | 同一 owner 收紧 ID、响应和错误语义,再用可控通知种子实测 |
|
||||
| 换绑手机号 | 缺专用受保护发码 operation 与资料前置投影 | 后端补齐 operation/DTO 后,在人工 TAC/短信窗口实测 |
|
||||
| 个人资料读取 | `RObject` 未声明可消费资料字段 | 后端提供稳定资料 DTO、权限与脱敏语义 |
|
||||
| 个人资料更新 | 缺 profileVersion/If-Match 与合并 body 合同 | 后端提供版本并发与字段白名单,再对测试账号做可恢复验证 |
|
||||
|
||||
M04 和 M10 的客户端接线门禁现只以 Apifox 已核对的 owner、方法、body/空 body、取消归属与本机会话收口为准,已不再把旧受保护导出中虚构的会话安全语义当作阻塞。两项真实远端 mutation 仍均为 `DECLARED_UNVERIFIED`:改密必须在可恢复的人工窗口完成后恢复约定密码;服务端退出必须由人工登录会话确认撤销结果。两者均不得在无人值守期间发起。
|
||||
|
||||
F01/F02/F03 必须拆开处理:F01 已删除本地动态列表,因列表条目 DTO 缺失而明确关闭正文/详情入口;F02 已按唯一可映射的 `feedContent` 接通发布,不发送媒体、排序或状态猜测字段;F03 动态正文继续不接线、不猜字段,一级评论已有 `FamilyFeedCommentView[]` 和明确提交 body,客户端已按该合同接通真实读取/提交并在提交后回读。没有真实登录会话、实际响应和人工可观察写入前,三页均仍是 `DECLARED_UNVERIFIED`,绝不能把接线写成已完成。
|
||||
|
||||
## 一、计划地位
|
||||
|
||||
本文是今晚到明早的唯一执行顺序与验收入口;[产品参考页面功能映射表](./产品参考页面功能映射表.md) 是本文直接引用的权威附件,二者必须一起评审、一起确认。既有治理文档继续提供历史背景和长期发布约束,但与今晚的批次顺序、时间分配或“可测试”口径冲突时,以本文及该附件为准。`APP.openapi.yaml` 和 `APP.openapi.json` 只读且受保护,不得修改、格式化、覆盖或删除。
|
||||
|
||||
当前处于“执行与验证”阶段。用户已完成三人交叉评审后的规划确认并明确说“开始执行”,因此允许按本文对业务代码、页面样式、接口接线、测试、HBuilderX 与 MuMu 标准基座做最小必要变更与验证;仍不得以已存在的半成品、旧报告、参考项目能运行或局部截图代替当前项目验收。
|
||||
|
||||
## 二、明早交付目标与项目范围
|
||||
|
||||
本规划对象是当前 `jiapuapp` UniApp 整个项目,不只覆盖认证或世系树。A、G、T、F、R、N、M 七个路由域、共享导航与会话、文件上传、权限、异常恢复、视觉、参考资产、无障碍、构建和 MuMu 验收都在范围内。参考思维导图中的后台管理、公司官网和独立 PC 管理端不是本仓库的实现范围,只能为 APP 角色、权限和后端依赖提供参考,不能据此在当前仓库静默扩张成三个新项目。
|
||||
|
||||
当前 `pages.json` 的 52 条活动路由是今晚的最低活动基线,不是产品功能的永久上限,也不能单独代表整个项目完成。两个参考源中发现的候选功能必须先逐页面、逐动作、逐接口完成书面甄别;只有结论为“直接采用”或“改造后采用”,且明确当前路由归属或新增路由必要性后,才进入最终活动清单。最终遍历分母为“52 条基线路由+本轮明确采纳并已注册的新增路由”,报告必须同时给出基线分母和最终分母,禁止用 52/52 掩盖已确认但未纳入的产品功能。
|
||||
|
||||
明早目标是在用户授权开始执行后,交付一套连接 `https://backend-api.ddxcjp.cn/`、能够在 MuMu 中从认证入口开始遍历的 UniApp 测试版本。最终活动清单中的页面必须可进入、可返回、无白屏和死路;后端已有且合同可用的动作必须调用真实接口,后端确实没有可靠 operation 的动作必须显示“服务暂未开放”或同义的明确状态,不得用 mock、fixture、timer、本地数组写入或假成功伪装闭环。
|
||||
|
||||
测试版本不等同于正式发布版本。发布签名、正式域名 CORS、后端未实现合同和真实支付等外部条件可以保留为发布阻塞,但必须提供失败门禁、复现证据、解除条件和继续步骤。
|
||||
|
||||
“全量”按五个互不替代的层级报告,禁止把较低层通过写成整个产品完成:
|
||||
|
||||
1. **产品库存覆盖**:52 条当前基线路由、已批准新增路由、60 个设计文件、78 条参考活动路由、1 条注释路由声明、7 个未注册参考页面文件和 531 个参考媒体资产均有稳定 ID、候选池或书面去向;资产候选池覆盖不等于逐文件批准复用。
|
||||
2. **路由结构遍历**:某候选包中的已注册活动路由可进入、可返回、无白屏和死路;这只证明结构可遍历。
|
||||
3. **实时接口迁移**:单个动作的合同、权限、请求、响应、刷新和重进闭环均完成,并通过引导式真实设备实时验收;当前没有可证明自动操控设备与断言业务结果的完整 E2E harness,因此不使用“自动 live E2E”表述。
|
||||
4. **明早最低候选**:存在可追溯的冻结候选,当前 7 个直接 `appApi` consumer 的主链结果、其余页面的数据模式、参考甄别结论和精确剩余项齐全;完整九小时窗口的目标还包括 52 条基线路由结构结果。若有效窗口不足或结构遍历未完成,未跑路由必须记 `NOT_RUN`,本层不得冒充达成。
|
||||
5. **整个产品完成**:所有已批准产品动作均达到产品完成条件;任一必需动作仍为关闭、半成品、未运行或合同阻塞时,整个产品不得标记完成。
|
||||
|
||||
完整九小时窗口的可靠目标是第 1、2、4 层和可在时间窗内诚实完成的第 3 层;窗口缩短时第 1 层与精确剩余项仍必须交付,第 2、3、4 层按实际结果报告,不承诺在一个夜间窗口内把全部 52 页与所有参考候选都迁成 LIVE。不得为了追求数字把路径拼接、宽 DTO 直传、页面内 fixture、timer 提示、诚实关闭页或单一成功样例提前标记为产品完成。
|
||||
|
||||
## 三、已确认口径
|
||||
|
||||
- 当前源码基线由用户在 2026-07-23 手动拉取最新 `main` 后提供。本轮及后续执行均不进行任何 Git 操作,也不读取或写入 HEAD、分支、dirty、提交哈希作为实施前置;计划中的旧提交哈希全部视为历史记录,不再代表当前基线。
|
||||
- 第一参考源为 `C:\Users\Rain\Desktop\job\app设计`,当前只读清单为 59 张 PNG 和 1 份 PDF。项目内 `docs/design/references/产品参考原稿` 与其中 59 个同名文件 SHA-256 一致;源目录新增 `思维导图.png`,本轮只把它作为规划证据,不在用户确认前复制或归档。
|
||||
- 第二参考源为 `C:\Users\Rain\Desktop\job\Jiapu-App`。第一轮只读盘点确认其 `pages.json` 有 79 个 `path` 文本,其中 `pages/index/vertical-swiper/vertical-swiper` 整段已注释,故活动路由为 78 条;另有 79 个 Vue 文件、6 个 NVue 文件、7 个未注册页面文件和 113 个旧 API wrapper。未安装依赖、未运行、未构建、未修改。它使用旧技术与旧接口封装,只能证明候选页面、动作和状态存在,不能证明当前后端合同可用。
|
||||
- 用户已明确允许把第二参考源中的图标、插画、背景等资产作为复用候选。该授权只改变“可以逐文件甄别”的边界,不代表整目录批准,也不证明第三方/商标素材的来源或平台规范;任何资产仍须绑定已批准 PA、页面和状态,并逐文件通过来源、隐私、旧品牌、格式、视觉、无障碍和性能门禁。
|
||||
- 产品目标以用户对当前项目的明确需求为第一优先;接口路径、方法、字段、权限、状态码和失败语义以当前真实后端合同与可复现响应为准;当前项目架构、安全和国风视觉决定落地方式;截图和已完成参考项目排在最后,只作候选证据。
|
||||
- 唯一后端为 `https://backend-api.ddxcjp.cn/`,今晚联调使用 remote 模式。
|
||||
- 已提供有效测试账号;账号凭据只用于本机联调,不写入源码、测试、文档、日志或 Git。
|
||||
- 规划前在 2026-07-23 曾以标准 JSON 观察到密码登录和 `/captcha/challenge` 返回 HTTP 200,challenge 摘要为 `TIANAI/SLIDER`;后端可识别版本未留存,敏感响应不进入规划。该记录只解释此前因命令行 JSON 引号破坏得到的空体 500,不属于本轮 `LIVE_VERIFIED` 或 `PASS`。收到“开始执行”后仍须对冻结的线上合同和部署重新取证。
|
||||
- 密码登录、短信登录、注册、忘记密码都必须显示并完成 TAC。密码登录接口不接收 `validToken`,滑动成功只作为客户端强制前置;短信发送接口必须消费对应场景的 `validToken`。
|
||||
- 只有用户明确说“开始执行”后才允许操作 MuMu,并把实机画面、返回路径和交互状态纳入验收;规划确认本身不构成 MuMu 授权。
|
||||
- 当前 `static` 国风视觉资产、token 和现有页面结构仍是唯一视觉基线;参考项目资产可在逐文件通过门禁后直接复用、裁切重导出或重绘,不能反向改变已批准产品动作,也不能把旧整页红色主题、旧组件或旧样式一并迁入。
|
||||
- 允许测试账号创建带“联调测试”标识的家谱、成员、申请、动态、文章、相册、礼仪、备忘、功德和反馈等测试数据。
|
||||
- 不删除已有真实数据;无人值守期间不执行支付、换绑手机号、注销账号或不可逆操作。修改密码若经人工窗口测试,结束后恢复约定密码。
|
||||
- 本轮不执行任何 Git 命令或 Git 写操作;源码同步由用户自行负责。
|
||||
|
||||
## 四、单页完成定义
|
||||
|
||||
一个页面只有同时满足以下五项才标记为完成:
|
||||
|
||||
1. 从真实业务入口可进入,系统返回键、页面返回按钮和根页面切换行为正确。
|
||||
2. 后端已有操作使用真实接口,路径、方法、请求字段、响应字段和身份上下文与 Apifox、线上文档及真实响应一致。
|
||||
3. 正常、加载、空数据、失败、无权限和提交中状态完整;写操作另有校验、重复点击保护、成功、明确失败和结果未知处理。
|
||||
4. MuMu 实际画面没有白块、文字截断、控件错位、默认原生底色或不可点击区域;普通内容、长内容和状态页均可阅读。
|
||||
5. 页面对应的 mapper/runtime 测试、静态合同、编译检查和实机检查均通过。
|
||||
|
||||
页面内存在按钮不等于功能完成。每个主动作还必须验证“入口人物或对象正确 → 参数身份正确 → 权限来自可靠合同 → 请求结果可判定 → 返回后源页面刷新为服务端事实 → 重进页面仍一致”的跨页闭环;其中任一环仍依赖 fixture、旧参考接口、timer 或本地数组写入时,该动作不得标记完成。一个页面有多个主动作时逐动作记状态,不能用一个成功动作覆盖其他未完成动作。
|
||||
|
||||
自动脚本通过不能替代实机视觉合格,单张静态截图也不能替代接口与交互合格。
|
||||
|
||||
每个动作必须同时记录四个正交字段,禁止用一个“通过”覆盖不同含义:
|
||||
|
||||
| 字段 | 允许值 | 判定用途 |
|
||||
| --- | --- | --- |
|
||||
| `contractState` | `LIVE_VERIFIED`、`DECLARED_UNVERIFIED`、`CONTRACT_CONFLICT`、`MISSING_OPERATION`、`NOT_APPLICABLE` | 当前后端合同及真实部署证据;纯本地权威内容用 `NOT_APPLICABLE` |
|
||||
| `dataMode` | `LIVE`、`LOCAL_PREVIEW`、`CLOSED` | 页面当前从哪里取得或是否允许提交数据;唯一 owner 的正式本地静态内容可为 `LIVE` |
|
||||
| `checkResult` | `PASS`、`FAIL`、`EXPECTED_BLOCKED`、`NOT_RUN`、`INFRA_ERROR` | 某一次合同、测试、构建或实机检查的结果 |
|
||||
| `productCompletion` | `COMPLETE`、`PARTIAL`、`BLOCKED`、`NOT_APPLICABLE` | 用户所需产品动作是否真正闭环 |
|
||||
|
||||
`CLOSED` 页面的关闭文案、返回路径和无假成功检查可以得到 `checkResult=PASS`,但必需动作仍须记 `productCompletion=BLOCKED`;不能由此把页面或产品写成完成。已知合同门禁脚本只有在“非零退出+精确 `... BLOCKED` 标记”同时成立时才记 `checkResult=EXPECTED_BLOCKED`,它与关闭页行为检查的 `PASS` 不是同一结果。`LOCAL_PREVIEW` 最多为 `PARTIAL`。只有已批准动作在 LIVE 模式完成权限、请求、结果确认、刷新和重进闭环时,动作才可为 `COMPLETE`。
|
||||
|
||||
汇总规则固定为:
|
||||
|
||||
1. 动作逐项保留四字段,不取平均值。
|
||||
2. 页面另报 `structuralCheck` 和 `productCompletion`;任一必需动作 `productCompletion=BLOCKED`,页面产品完成度即 `BLOCKED`;没有 BLOCKED 但存在 `productCompletion=PARTIAL`,或必需检查 `checkResult=NOT_RUN`,页面最多为 `PARTIAL`。
|
||||
3. 域与整个项目只按已批准必需动作向上汇总;出现 `BLOCKED` 即不得宣称完成,全部为 `COMPLETE/NOT_APPLICABLE` 才能标记域或产品 `COMPLETE`。
|
||||
4. 每个 `checkResult` 同时记录首次结果;允许重试时另记重试结果,不覆盖首次失败。
|
||||
|
||||
## 五、接口判定和实现规则
|
||||
|
||||
### 5.1 Apifox 桌面端优先的合同发现门禁(本轮新增硬约束)
|
||||
|
||||
导出的 `APP.openapi.yaml`、`APP.openapi.json` 和线上 `/v3/api-docs` 均可能缺少 Apifox 工作区中已经维护、但未导出的接口;它们只能作索引和交叉核验,绝不能作为“接口不存在”或“接口完整”的结论。每个受影响动作在写代码、关闭入口、补测试或判定 `MISSING_OPERATION` 前,必须先在用户已打开的 **Apifox 桌面端**逐项只读核对:
|
||||
|
||||
1. 所属目录、接口名称、HTTP 方法和完整路径;
|
||||
2. 鉴权方式、必填请求头、路径/查询/请求体字段及类型;
|
||||
3. 成功与失败响应示例、业务码、分页/ID wire 和权限语义;
|
||||
4. 是否存在同一业务动作的补充接口、前置接口或结果查询接口;
|
||||
5. 与导出文档、当前 `utils/api.js`、参考项目或真实请求不一致之处。
|
||||
|
||||
核对结果须以“动作 → Apifox 证据 → 当前部署实测 → 结论”写入临时脱敏账本;不得记录 Token、手机号、验证码、TAC proof、邀请口令或原始敏感响应。Apifox 与导出文档不一致时,以 Apifox 的业务定义为先导,并用真实部署响应复核 wire/权限/失败语义;两者仍不能证实时标为 `CONTRACT_CONFLICT` 或 `DECLARED_UNVERIFIED`,不得凭导出缺项关闭功能。只有 Apifox 也不存在、且经目录/关键词/相邻业务链检索留证后,才可标记 `MISSING_OPERATION`。
|
||||
|
||||
#### 5.1.1 本轮 Apifox 只读核对记录(2026-07-23 晚)
|
||||
|
||||
下表只记录已在用户打开的 Apifox 桌面端逐页读取到的声明;尚未通过测试账号取得同一部署的脱敏真实响应,故均不得写成 `LIVE_VERIFIED`。
|
||||
|
||||
| 动作/对象 | Apifox 桌面端声明 | 当前结论 |
|
||||
| --- | --- | --- |
|
||||
| 世系树读取 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/tree`,`genealogyId` 为必填 `int64` 路径参数,APP `clientId` header 必填 | 路径与当前读取 owner 一致;ID wire 和权限投影仍待实测,`DECLARED_UNVERIFIED` |
|
||||
| 人物详情 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}`,两个路径 ID 均为必填 `int64`,响应为 `LineagePersonResult` | 路径与当前读取 owner 一致;`DECLARED_UNVERIFIED` |
|
||||
| 人物新增/编辑 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons` 与 `PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` 均使用统一人物 body;`name` 必填,`sex` 仅说明“建议使用系统字典值”,`avatarOssId` 只能来自统一上传,`sortOrder` 仅说明“数值越小越靠前”。已以“字典”“性别”检索 APP/PC 目录,均未发现可供 APP 消费的枚举 operation | 首人/编辑可继续按 body 收紧;性别字典、上传闭环和单人排序的并发语义未证实,不能虚构枚举或把 `sortOrder` 当原子排行 |
|
||||
| 新增父母/子女/兄弟姐妹/配偶 | 已分别声明 `POST .../parents`、`POST .../children`、`POST .../siblings`、`POST .../spouses`,均返回 `LineagePersonResult` | 原来按导出文档作出的“无 operation”结论无效;关系方向、性别字典、冲突、权限、结果未知恢复尚待实测,先列为 `DECLARED_UNVERIFIED`,不得以本地成功替代 |
|
||||
| 统一文件上传与人物头像 | `POST /genealogy/app/files/upload`,APP `clientId` header 必填,`multipart/form-data` 仅有必填 `file`;返回 `ossId`、`url`、`thumbUrl`、`fileName`、`originalName`。树与人物详情只声明 `avatarOssId`,未声明可重进读取的头像 URL/file projection | 上传本身为 `DECLARED_UNVERIFIED`;不得把 `avatarOssId` 拼接为 URL,也不把一次上传响应 URL 持久化成资料事实。T01 使用确定性国风默认头像;真实头像显示仍等待文件读取投影与真实重进验证 |
|
||||
| 已登录密码修改 | `PUT /genealogy/app/auth/password`,要求鉴权与 APP `clientId`,body 为 `oldPassword`、`newPassword` 两个 32 位 MD5 字段 | 与 A05 的无登录态 `PUT /genealogy/app/auth/password/reset` 不是同一 owner;M04 已按独立 owner 接线,未发生本轮真实 mutation,仍为 `DECLARED_UNVERIFIED`,人工恢复窗口验证前不得标记完成 |
|
||||
| 已登录手机号换绑 | `PUT /genealogy/app/auth/phone`,要求鉴权与 APP `clientId`,body 为 `clientId`、新 `phone`、四位 `smsCode`;通用短信发送接口声明允许 `APP_PHONE_CHANGE`,但前置 `validToken` 需先完成验证码中心 | 当前 profile 响应未声明可安全消费的手机号 DTO,且真实 TAC/短信需要人工窗口;M05 不猜字段、不静默发码或换绑,保持人工 `DECLARED_UNVERIFIED` |
|
||||
| 已登录退出 | `DELETE /genealogy/app/auth/logout`,要求鉴权与 APP `clientId`,无 body,响应 `RVoid`/`data:null` | M10 已接严格 REMOTE owner;当前未发真实退出 mutation,仍为 `DECLARED_UNVERIFIED`。本机退出与服务端撤销确认分开记录,不能把前者写成后者 |
|
||||
| 家族圈列表、正文详情与发布 | 列表:`GET /genealogy/app/genealogies/{genealogyId}/feeds`(`ListResult`);详情:`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}`(`ObjectResult`);发布:同一路径 `POST`(`ObjectResult`)。三者均需鉴权与 APP `clientId`,路径 ID 均为 `int64`。发布 body 仅明确 `feedContent` 非空必填;`feedType` 默认 `text`、`mediaOssIds` 为英文逗号分隔 OSS ID、`sortOrder` 默认 `0`、`status` 默认正常 | 列表只见 `property1/property2` 通用项,正文详情和发布也未声明页面可消费 DTO;F01 已删除本地列表,F03 正文不猜字段。F02 只发送 `feedContent`,且只有严格成功信封后才显示已提交;不能把泛型响应当作列表条目或已完成验收;三者均为 `DECLARED_UNVERIFIED` |
|
||||
| 家族圈一级评论 | 读取:`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments` 返回 `FamilyFeedCommentView[]`;提交:同路径 `POST`,`commentContent:string` 必填且最多 1000 字,`parentCommentId:int64|null` 可选。读取 item 已声明 `commentId/genealogyId/feedId/appUserNickName/commentContent/replyCount/createTime` 等字段 | F03 已删除本地动态/评论 fixture;读取仅展示 `commentId`、昵称、内容、回复数和创建时间的已声明映射;提交只发送 `commentContent`,成功后重新读取服务端列表 | 客户端已接线,但未取得真实登录态响应或人工可观察的提交结果;仍为 `DECLARED_UNVERIFIED`,正文详情 DTO 缺失不影响评论 owner 的独立核对 |
|
||||
| 谱文列表、详情与创建 | 列表:`GET /genealogy/app/genealogies/{genealogyId}/articles`;详情:`GET .../articles/{articleId}`,均为通用响应。创建:`POST .../articles`,已声明 `articleTitle/articleContent` 必填,`categoryId/articleSummary/coverOssId/authorName/sortOrder/status` 可选 | F04/F05 已删除本地文章、分类、搜索和正文展示,等待稳定 item/详情 DTO;F06 只发送 `articleTitle/articleContent`,无分类 ID 来源时不发送分类。编辑需要可靠详情/文章 ID 来源而关闭 | 创建客户端已接线但未实测,列表/详情/编辑仍为 `DECLARED_UNVERIFIED`;不得用本地预览或泛型成功响应冒充谱文展示闭环 |
|
||||
| 帮助文章列表 | `GET /genealogy/app/help-articles`,Apifox 显示鉴权、`clientId`(带默认值)与通用 `ListResult`,`data` 为未声明字段的 object 数组;另有详情 endpoint,但尚未作为当前页面 owner 读取 | M06 需要稳定的分类、标题与纯文本正文;当前声明仍只有 `property1/property2`,不能把硬编码 FAQ 冒充远端帮助内容。继续保持本地说明与 M07 反馈入口,远端帮助读取为 `DECLARED_UNVERIFIED` |
|
||||
| 消息通知列表与已读 | 列表:`GET /genealogy/app/notifications`,鉴权与 APP `clientId` 必填,通用 `ListResult` object 数组;单条已读:`POST /genealogy/app/notifications/{notificationId}/read`,`notificationId:int64`、鉴权与 APP `clientId` 必填、无 body、`VoidResult/data:null`。目录还声明“全部标记已读” | 未发现通知详情读取 operation,列表没有类型、目标、正文或稳定 ID 的消费 DTO;N01/N02 不能由通用数组猜业务跳转,未读不能由分页长度推断。没有登录态和可控通知种子时不发送任何已读 mutation,读取/已读均为 `DECLARED_UNVERIFIED` |
|
||||
| 我的家谱列表 | `GET /genealogy/app/genealogies/mine`,鉴权与 APP `clientId` 必填,通用 `ListResult` object 数组 | G01 需要稳定的家谱 ID、名称、角色与上下文能力;Apifox 当前仍只给出 `property1/property2`。不把响应存在误记为工作区/切谱闭环,保持 `DECLARED_UNVERIFIED` |
|
||||
| 相册与图片 | 相册列表:`GET /genealogy/app/genealogies/{genealogyId}/albums`,`genealogyId:int64`、鉴权与 APP `clientId` 必填,通用 `ListResult`。创建 body 仅可安全使用 `albumName`;图片写入要求既有 `ossId` | F07 已删除相册 fixture,创建仅发送 `albumName` 并等待成功信封;F08 已关闭无 DTO 的照片展示;F09 已删除 mock 图片和预览,等待文件上传 owner、真实 OSS 回执和访问 URL 投影。创建待真实响应核验,其他展示/上传为 `DECLARED_UNVERIFIED` / `BLOCKED_BY_MEDIA_OWNER` |
|
||||
| 备忘录 | 列表:`GET /genealogy/app/genealogies/{genealogyId}/memos`,`genealogyId:int64`、鉴权与 APP `clientId` 必填,响应为通用 `ListResult`。新增:同路径 `POST`,body 明确 `memoTitle` 必填;`memoContent`、`remindTime`、`completed`、`mediaOssIds`、`sortOrder`、`status` 可选,其中 `mediaOssIds` 为逗号分隔 OSS ID。目录另有详情、修改、删除动作 | R10 已删除列表 fixture,创建只发送 `memoTitle/memoContent/remindTime`;完成状态、媒体、排序、状态无来源不发送,详情/修改/删除因无 DTO/ID 来源关闭。创建待真实响应核验,整体仍为 `DECLARED_UNVERIFIED` |
|
||||
| 成长记录 | 列表:`GET /genealogy/app/genealogies/{genealogyId}/growth-records`,`genealogyId:int64`、鉴权与 APP `clientId` 必填,响应为通用 `ListResult`。新增:同路径 `POST`,body 明确 `recordTitle` 必填;`lineagePersonId:int64`、`recordType`、`recordContent`、`recordDate`、`remindTime`、`mediaOssIds`、`sortOrder`、`status` 可选,其中 `mediaOssIds` 为逗号分隔 OSS ID。目录另有详情、修改、删除动作 | R08 已删除列表 fixture,创建只发送 `recordTitle/recordContent/recordDate`;人物绑定、类型、提醒、媒体、排序、状态无来源不发送,详情/修改/删除因无 DTO/ID 来源关闭。创建待真实响应核验,保持 `DECLARED_UNVERIFIED` |
|
||||
| 功德记录 | 列表:`GET /genealogy/app/genealogies/{genealogyId}/merit-records`,`genealogyId:int64`、鉴权与 APP `clientId` 必填,响应为通用 `ListResult`。新增:同路径 `POST`,body 的 `donorName`、`meritTitle` 必填;`meritType`、`meritContent`、`amount:double`、`meritTime`、`sortOrder`、`status` 可选。目录仅见删除,未见详情或修改 | R 功德列表及新增响应尚无稳定页面消费 DTO;不可把当前路径与参考项目的人情/贺礼混为一谈。未在无登录态下发送新增或删除 mutation,保持 `DECLARED_UNVERIFIED` |
|
||||
| 祭祀与祭祀献礼 | 祭祀列表:`GET /genealogy/app/genealogies/{genealogyId}/ceremonies`,通用 `ListResult`;创建:同路径 `POST`,`ceremonyType`、`ceremonyTitle` 必填,`ceremonyDesc`、`ceremonyTime`、`location`、`coverOssId:int64`、`sortOrder`、`status` 可选。献礼列表:`GET /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/gifts`,两个路径 ID 均为 `int64`;新增:同路径 `POST`,`giftAmount:double` 必填,`giverName`、`giftMessage` 可选。上述均要求鉴权与 APP `clientId`,目录还声明祭祀详情/修改、删除活动和删除单条祭品 | 祭祀和献礼均有专属父对象与语义;它们不是人情簿,也不是可发放/绑定的贺礼邀请。列表/新增响应仍无稳定页面 DTO,且未在无登录态下发送写入或删除请求,整体保持 `DECLARED_UNVERIFIED` |
|
||||
| 亲友记录 | 列表:`GET /genealogy/app/genealogies/{genealogyId}/relative-records`,`genealogyId:int64`、鉴权与 APP `clientId` 必填,响应为通用 `ListResult`。新增:同路径 `POST`,`relativeName` 必填;`relationName`、`eventName`、`eventTime`、`giftAmount:double`、`recordContent`、`mediaOssIds`、`sortOrder`、`status` 可选。目录另有详情、修改、删除动作 | R03/R04 已删除 fixture 列表和详情,创建只提交亲友姓名、关系、事项、时间、金额、备注;媒体/排序/状态无来源不发送。详情/修改/删除无 DTO/ID 来源关闭;创建待真实响应核验,保持 `DECLARED_UNVERIFIED` |
|
||||
| 人生事件与重要证件 | 已在 Apifox APP/PC 目录分别以“人生”“证件”检索,均未返回对应 operation;相邻的亲友、成长、备忘、功德、祭祀目录不能替代 | R09 没有当前业务 owner,维持硬关闭和可返回状态;`MISSING_OPERATION`,不以本地表单、文件上传或参考项目页面伪造保存 |
|
||||
| 视频 | Apifox 按“视频”检索只发现 APP 删除视频动作;未发现当前 F10 所需的视频列表、可播放 URL、发布/编辑、评论、点赞或分享闭环 | F10 继续保持非 LIVE;不能把参考短视频动作或单一删除 endpoint 扩展成视频产品能力,`MISSING_OPERATION` |
|
||||
| 意见反馈 | `POST /genealogy/app/feedback`,鉴权与 APP `clientId` 必填;body 的 `feedbackContent` 必填,`feedbackType` 与 `contactInfo` 可选,响应 `ObjectResult` | 与 M07 的严格 normalizer、POST owner 和提交状态机一致;静态/API 冒烟已通过,未用测试账号提交真实反馈,故远端结果仍为 `DECLARED_UNVERIFIED` |
|
||||
| 当前用户资料 | `GET /genealogy/app/auth/profile`,鉴权与 APP `clientId` 必填,响应 `ObjectResult`,当前仅给出 `property1/property2`;目录另有 `PUT /genealogy/app/auth/profile` | M01—M03/M05 需要稳定的账号、资料与手机号投影;不能从通用对象猜字段或让资料更新覆盖未知字段。读取、编辑与换绑前置均保持 `DECLARED_UNVERIFIED`,M05 另受人工 TAC/短信窗口约束 |
|
||||
| 微信登录 | 已以“微信”检索 Apifox APP/PC 目录,未返回登录授权、code 交换、回调、会话创建或结果查询 operation | A01 的微信入口不能借参考项目旧接口接通;保持 `MISSING_OPERATION` 关闭候选,是否长期纳入由用户后续确认 |
|
||||
| 家谱邀请码 | 已以“邀请码”检索 Apifox APP/PC 目录,未返回邀请码签发、校验、直入加入、撤销或结果查询 operation | G/M 的邀请码能力无当前 owner;普通加入申请、成员维护和人物邀请绑定都不能替代,保持 `MISSING_OPERATION` |
|
||||
| 行政区划搜索 | Apifox APP 目录声明 `GET /genealogy/region/search`:`keyword` 必填,`level` 可选(1 省、2 市、3 区县、4 街道、5 村社区),`limit` 可选;`clientId` header 可选,响应为通用 `ListResult`。2026-07-24 00:51 的只读部署响应为 HTTP/业务码 `200`,服务器时间 `Thu, 23 Jul 2026 16:51:08 GMT`,单条结果含字符串 `regionCode`、`label`、`parentCode`、`ancestors`、`regionName`、`regionLevel`、`regionType` 与 `leaf`;同目录另有下级查询、路径查询与详情 | 此读取 owner 为 `LIVE_VERIFIED`,G03 可消费返回的字符串 `regionCode`,但不能把 `leaf` 推断为可提交能力。非 APP 前缀为唯一业务 owner;当前部署旧 `/genealogy/app/region/search` 虽同响应,仍只记路径并存证据,不作兼容 owner。G03 两次写入及结果未知恢复仍分别按其独立合同判定,不能由该读取验证代替 |
|
||||
| 邀请绑定 | 已展开“家谱(12)”“家谱成员(6)”全部接口,并以“邀请”“绑定”检索 APP/PC 目录;仅见普通申请/审核和成员维护,无邀请票据、身份绑定、绑定 mutation 或结果查询接口 | `MISSING_OPERATION`;普通申请不能替代邀请绑定,保持诚实关闭 |
|
||||
|
||||
### 5.2 通用判定和实现规则
|
||||
|
||||
1. Apifox 用于优先发现和判断接口业务用途;线上 `/v3/api-docs` 和真实请求用于确认当前部署路径、字段及故障表现;受保护 OpenAPI 只作离线补充。参考项目 `api/index.js` 中的旧路径、参数和响应处理不属于当前接口证据。
|
||||
2. 每个动作先进入统一账本。`LIVE_VERIFIED` 只允许用于本轮开始后、绑定后端可识别版本或时间戳的真实证据;受保护 OpenAPI 有声明但未取本轮真实响应时为 `DECLARED_UNVERIFIED`;文档、部署、权限、静态门禁或页面期望冲突时为 `CONTRACT_CONFLICT`;没有可靠 operation 时为 `MISSING_OPERATION`。operation 是否存在另记为证据字段,不是第五种状态;同一最小动作同时“有声明但已知冲突”时必须取更严重的 `CONTRACT_CONFLICT`,不得写两个 `contractState`。不得把接口名相似、历史 HTTP 200 或参考项目成功写成已接通。
|
||||
3. 先列出当前批次的“当前页面 → 用户动作 → 对象身份 → 权限来源 → 方法 → 完整路径 → 输入 → 页面消费字段 → 成功/失败/结果未知表现 → 刷新确认”,再写该批次失败测试,随后实现。
|
||||
4. 只有 `LIVE_VERIFIED` 动作允许记为 LIVE。`DECLARED_UNVERIFIED` 先做只读或可控测试验证;`CONTRACT_CONFLICT` 记录冲突并失败关闭;`MISSING_OPERATION` 保留完整视觉和返回路径,动作显示服务未开放,不伪造保存、发送、上传、支付、邀请、绑定、排行或审核成功。
|
||||
5. 4xx、5xx、空体、缺字段或身份错配必须展示真实失败,不回退 mock。参考项目成功、受保护 OpenAPI 存在 operation 或当前页面已有 `appApi` 方法,都不能单独解除这一规则。
|
||||
6. 单个接口排查超过 15 分钟仍无本机解决路径时,立即记录复现证据并继续其他页面,避免阻塞整夜。
|
||||
7. 每个合同只有一个 owner;新合同落地时同步移除同类 fixture、旧入口、兼容读取和过时测试期望。若一个参考动作无法明确归入现有 owner,先判定是否需要新 owner,不能塞进名称相近的旧接口。
|
||||
8. 真实写操作仅限测试账号和本轮新建、带“联调测试”标识且已登记 ID 的对象。GET 可按退避规则重试;写操作只有接口明确提供幂等键且结果可判定时才允许重试,超时、5xx、断线或进程终止造成结果未知时立即停止该动作并查只读结果。
|
||||
9. 新增全域 P0 ID 门禁:`genealogyId`、`personId`、`memberId`、`appUserId`、父母/配偶/子女引用、内容 ID、文件 ID 与 `avatarOssId` 等 `int64` wire 必须验证服务端以十进制字符串返回且请求端接受十进制字符串。任何超出 JavaScript 安全整数的 JSON number 一经解析已不可恢复,禁止再转字符串继续使用;相关读写统一记 `CONTRACT_CONFLICT` 并关闭,直到同一 ID owner 在 schema、运行时、validator 和请求端同时收紧。
|
||||
10. 三个现有静态门禁本身与已确认规划/快照冲突,收到“开始执行”后的第一项测试工作是先按唯一 owner 重订失败期望,再实施业务:`auth-tac-openapi-contract.ps1` 不得再要求密码登录上传 `validToken`;两个 G03 门禁不得再要求未声明的原子 bootstrap、错误的 `/genealogy/app/region/search` 或不存在的结果查询;`help-center-openapi-contract.ps1` 与 M06 统一为“完整列表是唯一远端 owner、文章阅读由列表项投影承接”,不新增独立远端详情 owner。门禁目标路径不能写成当前 operation,也不能因旧测试期望而覆盖真实后端合同。
|
||||
|
||||
每条路由的执行记录至少包含:`route`、真实入口、必填参数、测试角色/种子、四个正交状态字段、参考来源、候选动作、六类甄别结论、接口 owner、权限 owner、主动作、返回结果、页面状态证据、LIVE 请求响应证据、候选包 ID、MuMu 结果和 blocker。
|
||||
|
||||
每次汇总必须同时列出这些分母,任何一个都不能被“52/52”代替:
|
||||
|
||||
- `baselineRoutes=52`;
|
||||
- `approvedNewRoutes`(规划确认采纳、但不一定已注册);
|
||||
- `registeredRoutes`(候选包实际注册);
|
||||
- `traversedRoutes`(绑定该候选包完成结构遍历);
|
||||
- `referenceEvidenceRecords=341`,以及六类证据结论数量:直接采用、改造后采用、仅参考交互、后端缺失暂关、冲突舍弃、待用户确认;
|
||||
- `productActionsTotal=166`、`requiredActions=111`、`candidateActions=55`、`approvedCandidateActions=0`;产品完成分母固定为附件 PA-001—PA-166 中的 111 个必需动作;
|
||||
- `liveCompletedActions`、各动作的 `productCompletion`,以及按必需/可选、A/G/T/F/R/N/M/共享 owner 的分组结果;
|
||||
- `inventoryTests`、`scheduledTests`、`executedTests`、`notRunTests`、`timedOutTests` 与各 `checkResult` 数量。
|
||||
|
||||
## 六、执行批次与相对时间
|
||||
|
||||
以下计时只在用户明确说“开始执行”后启动。在此之前,参考映射与产品取舍必须已在权威附件中完成并由用户确认;执行第 0 批只能重算清单/哈希、冻结确认结果,不得再临场作重大产品决策。
|
||||
|
||||
### 6.1 时间模型与降级规则
|
||||
|
||||
- `T_start`:收到用户“开始执行”的北京时间。
|
||||
- `T_due`:用户已更新为 2026-07-24 08:00(北京时间)。
|
||||
- 正常候选周期为 `T_start + 9h`,但不得越过 `T_due`;要获得完整九小时窗口,最迟须在 2026-07-24 01:00 开始。
|
||||
- `T_test_cutoff = min(T_start + 6h, T_due - 3h)`。截止前必须完成本轮测试调度和首个候选尝试;截止后反向保留 0.5 小时候选修复/冻结、1.75 小时最终实机和 0.75 小时缓冲,不能用缩短窗口挤占这三段。
|
||||
- 首个候选固定预留 `firstCandidateWorstCase=30m`:2 分钟重算输入清单并准备全新输出根、15 分钟构建、3 分钟生成输出清单/指纹、7 分钟部署或安装、3 分钟设备身份确认。测试只有在 `now + testWorstCase + firstCandidateWorstCase <= T_test_cutoff` 时才允许启动;全部已调度测试收口后,首个候选只有在 `now + firstCandidateWorstCase <= T_test_cutoff` 时才允许启动。任何在途进程都不得跨越 `T_test_cutoff`:意外超时时在截止点终止本轮进程树,具体测试记 `timedOutTests/INFRA_ERROR`,候选尝试记基础设施失败,然后一次性冻结计数。不得以“已经开始”为由占用后续三小时。
|
||||
- `T_start >= T_due` 时不启动本轮执行,先请用户重新确认截止时间;`T_test_cutoff <= T_start` 时不启动代码、测试或构建批次,只交付预检与“无冻结候选”的精确原因。
|
||||
- 有效窗口不足 9 小时时不压缩人工认证和上述尾部三段:6—9 小时优先削减 F/R/N/M 的新增 LIVE 扩展;3—6 小时只在 `T_test_cutoff` 前做 P0 合同/安全修复、七个现有 `appApi` consumer 和首个候选尝试;不足 3 小时时不启动无法留出验证时间的代码批次,只做可完成的预检、现状与报告。所有被削减项记 `NOT_RUN`,不得改写成通过。
|
||||
- 九小时只是一次可靠候选周期,不是整个产品的完成承诺;明早报告必须把第 2 节五个层级分别结论化。
|
||||
|
||||
### 6.2 正常九小时批次
|
||||
|
||||
#### 第 0—0.5 小时:冻结基线、合同、角色与夜跑清单
|
||||
|
||||
- 以用户手动拉取的当前文件为源码基线,不执行 Git;重算 52 条路由、60 个设计文件、78 条参考活动路由、1 条注释路由声明、7 个未注册参考页面文件、531 个参考媒体资产和权威附件覆盖率。
|
||||
- 在任何“接口缺失”、接口接线、写操作或页面关闭结论之前,先按第 5.1 节在 Apifox 桌面端完成当前批次动作的目录、请求、响应、鉴权和相邻链路检索;把未导出的接口和与导出文档不一致的字段列入脱敏合同账本,再决定实测、实现或阻塞。不得跳过此步骤直接按导出 OpenAPI 结论推进。
|
||||
- 冻结线上 `/v3/api-docs` 的取证时间与可识别版本;受保护 OpenAPI 保持只读。接口或参考源相对已确认附件发生变化时,只记录差异并暂停受影响动作,不静默改变产品范围。
|
||||
- 先在仓库外的本机临时验收目录建立唯一 `role-seed-matrix.json` owner:只记录脱敏角色别名、角色类型、对象类型、十进制字符串对象 ID、来源/创建时间、允许的动作和清理责任;不得写账号、手机号、Token、OTP、TAC proof 或其他凭据。普通成员、家谱所有者或管理员、第二账号,以及测试家谱、人物、申请、内容和媒体均由该矩阵登记。缺少角色、跨账号对象或收码号码时,对应动作标记测试数据阻塞。
|
||||
- 机械生成当前 204 个可执行脚本的 manifest 基表和显式 override,并冻结 `baselineInventoryTests=204=150 PS1+54 JS`。`tests/night-run.ps1` 与 `tests/night-run.manifest.json` 是编排入口/清单,不计测试项;实施中为本轮变更新建的每个可执行测试都记入 `newExecutableTests` 并追加到 manifest,最终 `inventoryTests=baselineInventoryTests+newExecutableTests`。每项先按第 6.3 节确定风险层级、依赖、是否远端写入及预期结果;第 0 批只校验已确认的 `PA-xxx` 产品动作和来源反链未漂移,禁止重新归并、拆分或改变产品动作分母。任何参考资产复制前另建逐文件 `RAxxx` 记录;资产选择可以在已批准 PA 内发生,但不能新增产品动作或跳过来源门禁。
|
||||
- 在仓库外的本机临时验收目录准备候选输入清单模板。每次候选构建/部署前,对项目自有源码、配置、资产和 lockfile 重算规范化逐文件 SHA-256;明确排除 `.git`、`unpackage`、依赖/工具缓存、日志、截图、报告和清单自身,并另记 HBuilderX、插件及解析后依赖版本。输入清单的规范化与第 6—6.5 小时输出清单使用同一算法,且不含凭据。
|
||||
- 检查 remote 配置、网络、磁盘、HBuilderX、MuMu 状态和测试账号,但此时不把任何历史运行结果算入本轮。
|
||||
|
||||
#### 第 0.5—1.75 小时:A 认证人工窗口与会话
|
||||
|
||||
- 本轮先完成密码登录页、账号密码提交、TAC challenge 展示、challenge/verify 合同、会话保存与 G01 跳转的可自动化验证;密码登录的真实拖动、短信登录、注册和找回密码的短信/TAC 全部保留为早晨人工回归,四条流程不互相替代。
|
||||
- 不循环发码、不破解或绕过 TAC。测试账号凭据只保留在当前安全会话,绝不写入仓库、文档、截图或日志。
|
||||
- 人工完成后验证页面重进和应用重启的会话;不记录 token。会话失效时停止身份写操作并熔断,不以临时接口 token 冒充认证页面验收。
|
||||
|
||||
#### 第 1.75—4 小时:A/G/T P0 主链与 T01/T03
|
||||
|
||||
- 按 A01 → G01 → G05 → T01、G03 两阶段建谱、G06/G08—G12、T03—T08推进;每个动作先过合同、ID、权限和结果未知门禁。
|
||||
- T01 优先完成头像人物卡、选择态和唯一人物面板;十入口逐项落到 T03/T04/T05/T06/邀请流程。合同不足的入口只允许诚实关闭,其关闭检查可 PASS,但 T01 产品完成度仍为 BLOCKED。
|
||||
- T03 始终从未完成半成品起算;已有 normalizer、fixture 或旧门禁不得计完成。
|
||||
- 本批时间用尽即停止扩张并留下可验证断点,不把 T01 大型布局和十条真实写链压缩成单一“完成”。
|
||||
|
||||
#### 第 4—4.5 小时:F/R/N/M 风险优先扩展
|
||||
|
||||
- 优先处理已经有当前后端声明、且能在剩余时间内完成闭环的读取和小型写入;无视频完整链、人生事件、重要证件、通知详情、支付/提现等保持诚实关闭。
|
||||
- 换绑、注销、支付、所有者转移、退出家谱、删除真实内容等敏感动作不在无人值守阶段执行。
|
||||
- 每域更新动作分母与四字段,不要求为了“全绿”把全部参考候选临时实现。
|
||||
|
||||
#### 第 4.5—6 小时:分层测试、首个候选与全量硬截止
|
||||
|
||||
- 唯一测试清单 owner 为执行时建立的 `tests/night-run.manifest.json`,唯一入口为 `tests/night-run.ps1`;二者只在用户说“开始执行”后创建。manifest 逐项明确脚本、解释器、排序、120 秒默认超时、依赖、预期退出码、预期标记、领域、是否允许写远端及检查点;当前 12 个 allowlist 项必须各自冻结完整且唯一的 `expectedBlockedMarker`,不得用包含匹配;4 个 JSON 数据文件不是可执行脚本。
|
||||
- 测试分三层:`T0` 为 P0 安全/合同、路由、编译及本轮实际修改 owner 的门禁,是形成候选的必要条件;`T1` 为 A/G/T/F/R/N/M 受影响域的其余 mapper/runtime/合同回归;`T2` 为未受影响域和历史扩展检查。204 个基线项与所有 `newExecutableTests` 全部进入 inventory,但只有 manifest 明确列入当轮的项目计入 `scheduledTests`;先执行 T0,再在硬截止前执行 T1,T2 仅在 T0/T1 完成且仍有时间时调度。未调度或未执行项分别如实进入 `notRunTests`,不得把 inventory 数量写成执行数量。
|
||||
- 一级顺序固定为 T0 → T1 → T2;每层内部再按纯静态/合同 PowerShell → 纯 Node mapper/runtime → 该层编译/专项检查排序,全部已调度测试收口后才形成候选构建。PowerShell 使用 `powershell.exe -NoProfile -ExecutionPolicy Bypass -File <exact-script>`;Node 使用 `node <exact-script>`。无网络、无共享写入且无相互依赖的本地脚本最多 4 个并发 worker;远端、写操作、编译和构建一律串行。单项失败继续下一项并回收子进程,域熔断只跳过同一远端风险动作。
|
||||
- 当前 150 个 PowerShell、54 个 Node 脚本以及实施中新增的每个可执行测试必须逐一进入 manifest;runner 和 manifest 自身不计测试项。本轮“预期阻塞”只允许以下 12 条精确脚本,并同时要求非零退出和各自精确 `... BLOCKED` 标记;其他非零均为 `FAIL`:`auth-android-accessibility-release-gate.ps1`、`g11-settings-openapi-contract.ps1`、`g12-generation-poem-openapi-contract.ps1`、`genealogy-workspace-openapi-contract.ps1`、`invite-ticket-openapi-contract.ps1`、`join-application-openapi-contract.ps1`、`lineage-openapi-contract.ps1`、`notification-read-openapi-contract.ps1`、`notification-read-state-openapi-contract.ps1`、`phone-change-openapi-contract.ps1`、`profile-openapi-contract.ps1`、`profile-update-openapi-contract.ps1`。已转绿的 `auth-tac`、两个 G03、F 家族圈、M04、M06、M10 与 T03 门禁不得再被列作预期阻塞;M04/M10 的真实 mutation 仍只进入人工窗口。清单冻结前须核对这些脚本的实际退出语义,不能仅因文件含 “BLOCKED” 字样放行。
|
||||
- allowlist 脚本若本轮变为退出码 `0` 且出现精确 PASS 标记,按 `PASS` 接受并从预期阻塞清单移除;只有非零退出且精确 BLOCKED 标记匹配才是 `EXPECTED_BLOCKED`。退出码与标记任一不匹配均为 `FAIL` 或 runner 错误,不能因历史预期而放行。
|
||||
- 夜跑在每项结束后原子写入本机临时验收目录中的 checkpoint(脚本、开始/结束、退出码、标记、耗时、首次结果),续跑只从最后完整记录之后开始。总入口退出码固定为:`0`=无 FAIL/INFRA 且预期阻塞完全匹配;`2`=测试或合同断言失败;`3`=构建、部署、安装或设备基础设施失败;`4`=manifest 漂移、单项超时、测试执行基础设施或 runner 自身错误;同时出现时按 `4 > 3 > 2 > 0` 聚合。单项超时记该测试 `checkResult=INFRA_ERROR` 并进入 `timedOutTests`;无法归到具体测试的 manifest/runner 故障另记 `runnerInfraErrors`,不塞入测试恒等式。任何 `EXPECTED_BLOCKED` 都必须在摘要中单列,退出 0 不等于产品全绿。
|
||||
- 全部已调度测试按层级收口后,首个候选严格使用第 6.1 节 30 分钟预算与同一构建入口;任一子段超时即本次候选失败,不把失败段的剩余时间转给另一段,也不在 cutoff 前启动第二次首候选尝试。第 6—6.5 小时只负责复用该候选或进行一次受限修复/最终冻结。
|
||||
- `T_test_cutoff` 是测试调度与首个候选尝试的硬截止;每项按第 6.1 节 `latestStart` 准入,不能在最坏耗时将越过 cutoff 时启动。截止时终止意外仍在途的项目,排队但未启动的已调度项进入 `notRunScheduledTests`,再一次性冻结 `scheduledTests/executedTests/notRunScheduledTests/notRunTests/timedOutTests` 和最终恒等式。T0 未全部取得允许结果或候选无法追溯时,不进入最终实机验收。
|
||||
- 构建入口固定为仓库根目录与 `.hbuilderx/launch.json` 中的 `uni-app:app-android`。执行前记录实际 HBuilderX CLI 绝对路径、版本、命令、退出码和输出目录;不得把旧 `unpackage` 产物冒充新包。
|
||||
|
||||
#### 第 6—6.5 小时:仅修复候选阻塞并冻结最终候选
|
||||
|
||||
- 本阶段只能二选一,不得借用后续 105 分钟实机窗口。若首个候选之后源码输入和生成输出均未变化,前 20 分钟内重算输入/输出 manifest 并逐项确认 hash 完全相同,必须复用该候选且不重复构建;随后最多使用 7 分钟部署/安装、3 分钟设备身份确认。若必须修复,前 5 分钟的组合硬上限同时覆盖一次 P0/P1 外科式修复、受影响的聚焦测试和 `sourceManifestSha256` 重算;随后 15 分钟的组合硬上限同时覆盖最终构建、完整输出 manifest 与 `outputManifestSha256`,再用 7 分钟 DBG 部署或 APK 安装、3 分钟设备身份确认,合计正好 30 分钟。任一组合段内的前置工作耗尽预算,后续工作来不及完成时即判该路径失败,不能把清单/指纹移出预算。
|
||||
- 任一路径在准入时无法按最坏预算于本阶段结束前收口,或任一硬上限内未完成,立即终止本轮启动的进程树、停止继续安装并记退出码 `3/INFRA_ERROR`,交付“无冻结候选”;不得重试、不得压缩身份核验,也不得挤占 MuMu 窗口。
|
||||
- 候选分两类且必须二选一取得可追溯、可复验的指纹:APK 使用 `APK-YYYYMMDD-HHMM-<apkSha256前12位>`,记录完整 APK SHA-256;HBuilderX 调试部署使用 `DBG-YYYYMMDD-HHMM-<outputManifestSha256前12位>`。两类都绑定 `sourceManifestSha256`、测试 manifest 结果、开始/结束时间、输出目录、应用包名/版本、HBuilderX/插件/依赖版本、部署或安装回执,以及 MuMu 已安装包的包名、版本、签名摘要和安装时间。
|
||||
- 源码输入与 DBG 输出清单的规范化算法固定为:以各自声明的根目录生成相对路径,路径分隔符统一为 `/`,按相对路径 ordinal 升序,每行写 `sha256<TAB>bytes<TAB>relativePath`,整体使用 UTF-8 无 BOM 与 LF。源码侧沿用第 0 批明确列出的排除集合。DBG 输出根固定为本轮 HBuilderX 新生成的准确输出目录,输出 manifest 存放在根目录之外并递归纳入全部生成文件;输出侧只允许排除存在时的 `Thumbs.db`、`.DS_Store`,且必须逐项记录,除此之外不得排除。`outputManifestSha256` 是完整规范化输出清单的 SHA-256,`sourceManifestSha256` 同理。
|
||||
- 找不到可重复构建/部署入口、无法取得上述任一指纹或安装结果与指纹不一致时记 `INFRA_ERROR`,明确报告“无冻结候选”,不得进入 MuMu 最终验收。任何代码或生成输出变化都会使旧设备证据失效,必须取得新候选 ID 并重验。
|
||||
|
||||
#### 第 6.5—8.25 小时:冻结候选的最终实机验收
|
||||
|
||||
- 本阶段 105 分钟固定拆为:前 10 分钟核对已安装身份、冷启动、证据目录和一次故障恢复余量;随后 65 分钟完成“52 条基线路由+已批准且已注册新增路由”的合计结构遍历,基线路由优先;最后 30 分钟做 P0 实时 smoke。结构遍历开始时计算 `routeBudgetSeconds=floor(3900/registeredRoutes)`(只有 52 条基线路由时为 75 秒),按基线路由优先的冻结顺序给每条路由一次预算;已启动路由超预算记 `FAIL` 并继续,65 分钟到点仍未启动的路由记 `NOT_RUN`。任何新增路由、低优先路由或故障恢复都不得侵占 P0 时段。
|
||||
- 结构遍历报告基线、已批准新增、实际注册、实际遍历和 `NOT_RUN` 五个分母/结果。P0 smoke 在同一候选上覆盖认证根页 A01、四个主入口 G01/F01/N01/M01、A/G/T P0 主链以及本轮改变的 F/R/N/M 动作;检查上下文、返回、空/错/无权限、重复点击、取消、前后台与迟到响应。更深的状态矩阵在各实现批次持续取证,最终候选至少重复 P0 smoke,旧候选证据不得沿用。
|
||||
- 本地故障注入只能证明客户端分支,不能证明远端实时接口;真实服务不做攻击性 4xx/5xx/429 压测。所有设备证据绑定候选 ID、分辨率、density、角色和种子。
|
||||
|
||||
#### 第 8.25—9 小时:45 分钟保留缓冲与交付收口
|
||||
|
||||
- 本时段是保留缓冲,不安排新功能。前面持续写入的报告在此校验四字段、首次结果、分母、熔断、人工项和继续步骤。
|
||||
- 若前序超时,缓冲只用于恢复、必要重建和最短复验;未完成项分别记清 `checkResult=NOT_RUN`、`productCompletion=PARTIAL` 或 `productCompletion=BLOCKED`,不得混写成一个状态。若缓冲未使用,可增加探索检查,但不得改变冻结候选或既定结论。
|
||||
|
||||
### 6.3 测试风险层级与计数规则
|
||||
|
||||
测试层级在第 0 批依据文件名、manifest 元数据和本轮人工变更账本机械生成,不依赖 Git diff,也不能由执行者为了赶时间临时降级:
|
||||
|
||||
| 层级 | 确定性纳入规则 | 候选门禁 |
|
||||
| --- | --- | --- |
|
||||
| `T0` | `compile-audit.ps1`、路由/导航/会话/运行配置/共享 ID 与权限门禁、第 6.2 节预期阻塞 allowlist,以及本轮每个被修改 owner 对应的合同、runtime 和视觉专项 | 全部必须取得 `PASS` 或精确允许的 `EXPECTED_BLOCKED`;否则无冻结候选 |
|
||||
| `T1` | 与本轮被修改 owner 同域的其余 A/G/T/F/R/N/M mapper/runtime、文档流、状态和响应式回归 | 在 `T_test_cutoff` 前尽量全部执行;未执行项记 `NOT_RUN` 并降低相应域结论 |
|
||||
| `T2` | 未受影响域、历史扩展、仓库卫生与探索性检查 | 仅在 T0/T1 完成且时间有余时调度;不以 T2 未跑伪装全量测试通过 |
|
||||
|
||||
计数恒等式固定为:
|
||||
|
||||
- `baselineInventoryTests=204=150 PS1+54 JS`,4 个 JSON 仅作为数据文件,runner/manifest 仅作编排,均不计可执行测试;
|
||||
- `inventoryTests=baselineInventoryTests+newExecutableTests`,本轮未新增测试脚本时 `newExecutableTests=0`;
|
||||
- `scheduledTests=executedTests+notRunScheduledTests`;
|
||||
- `executedTests=passTests+failTests+expectedBlockedTests+infraErrorTests`,其中 `timedOutTests` 是 `infraErrorTests` 的诊断子集,不重复相加;
|
||||
- `notRunTests=(inventoryTests-scheduledTests)+notRunScheduledTests`。
|
||||
|
||||
`runnerInfraErrors`、构建/部署/安装/设备基础设施错误另列,不进入上述测试项恒等式;只要存在任一此类错误,候选和报告仍按对应退出码失败。报告必须同时给出各层级数量、首次结果和重试结果。默认 120 秒只是单项上限,不是预计耗时;四 worker 也不能用理论并发量承诺完整 inventory 必然在 1.5 小时内跑完。冻结候选只宣称 T0 门禁已满足和实际执行范围,不能把 inventory 数量写成“全通过”。
|
||||
|
||||
## 七、三人交叉复核
|
||||
|
||||
三人固定为主代理和两位只读评审者,主代理是唯一写入者。三人都必须完整检查本规划,不能把范围割裂后只看自己的一部分;为增强对抗性,主代理重点复核产品全量覆盖与参考甄别,评审一重点攻击后端合同、权限和数据闭环,评审二重点攻击执行顺序、时间预算、测试证据和回归风险,然后互相核对对方领域。
|
||||
|
||||
规划评审必须在交给用户确认前完成,至少检查:
|
||||
|
||||
1. 是否覆盖 A/G/T/F/R/N/M、共享基础和参考候选,而非只覆盖认证或 T01。
|
||||
2. 每个采纳动作是否有唯一页面 owner、唯一接口 owner、权限来源、状态矩阵和完成定义。
|
||||
3. T03 是否始终标为未完成,T01 十个入口是否逐项落到真实流程或诚实关闭态。
|
||||
4. 两个参考源是否逐页面、逐动作、逐接口留有结论,是否误带旧地址、旧字段、旧组件、凭据、日志或视觉。
|
||||
5. 52 条基线路由与新增采纳路由是否分母清楚,时间预算是否把阻塞、人工项和最小可靠交付说清。
|
||||
6. 参考资产是否逐文件绑定已批准 PA 和具体页面状态,是否误把用户的候选复用许可解释为整包批准,是否遗漏第三方、隐私、旧品牌、格式、无障碍和性能风险。
|
||||
|
||||
任一评审提出有证据的疑点时,主代理必须修改规划或书面保留为待用户确认项;不能以多数票掩盖未解决的合同冲突。实施开始后,三人仍在批次边界复核接口、业务、交互、异常和视觉,不并发写文件,也不把开放式讨论拖入下一批。
|
||||
|
||||
本次规划评审已于 2026-07-23 收口:
|
||||
|
||||
| 评审角色 | 最终结论 | 已复核证据 |
|
||||
| --- | --- | --- |
|
||||
| 产品主审(主代理) | `PASS` | A/G/T/F/R/N/M 七域、共享 owner、52 条 CUR、T01 十入口、T03 半成品、两个参考源 341 条基记录、166 个 PA、状态分离和 531 项资产逐文件门禁完整;当前项目职责没有被参考项目覆盖 |
|
||||
| 合同评审 | `PASS` | 122 个合同键唯一且 PA 无未定义引用;125 个唯一当前 operation 均可回到 153-operation 只读快照;M08 家谱邀请、G03、TAC、N02、帮助、家族视频与宣传视频 owner 已拆清 |
|
||||
| 执行评审 | `PASS` | 204 项测试基线与动态 inventory、`latestStart`、首候选 30 分钟预留、最终候选双路径、输出指纹、65 分钟路由预算、退出码和双门禁均可机械执行 |
|
||||
|
||||
最终无剩余 P0/P1;评审提出的 P2 也已处理,包括复合来源证据的稳定 `@browse/@comment/@reaction/@share` 后缀。机械结果为:PA-001—PA-166 连续唯一(111 必需、55 候选),初始 42 `PARTIAL`+69 `BLOCKED`+55 `NOT_APPLICABLE`;52 条当前路由全部反链;341 条来源基记录均有 PA 或全局去向;两份权威文档无旧计数和表格列错位。
|
||||
|
||||
## 八、无人值守边界
|
||||
|
||||
- 本节只有用户明确说“开始执行”后生效;此前只允许规划范围内的只读核对和规划文档写入。
|
||||
- 执行授权生效后,可以继续读取、创建带测试标识的数据、运行测试、构建和操作 MuMu。
|
||||
- 不循环请求短信,不破解验证码,不使用生产数据做破坏性试验。除用户指定的最终停止通知外不发送外部消息;本轮真正停止时仅向用户已打开的微信“文件传输助手”发送“已经停下了”。
|
||||
- 不支付、不换绑、不注销、不删除已有家谱或用户内容。
|
||||
- 后端、测试账号、发布签名或 MuMu 人工验证码成为硬阻塞时,记录:失败门禁、请求与响应、复现步骤、解除条件、恢复后的第一步。
|
||||
- 用户有新消息时优先处理。只有已经收到“开始执行”后,“准备睡了”才可作为第 0.5—1.75 小时既定认证人工窗口的提前提醒或提前触发;它不改变 `T_start`、不另起第二套时间线,也不能单独授权代码、测试、构建或 MuMu。
|
||||
- Authorization、手机号、OTP、TAC proof、邀请码和个人资料不得进入报告、截图文件名或仓库日志。原始运行日志和截图放在本机临时验收目录,限制容量并在报告中只引用脱敏摘要。
|
||||
- TalkBack、系统大字号和无法可靠自动化的原生辅助功能只做可重复的早晨人工项,自动截图不得冒充无障碍通过。
|
||||
|
||||
## 九、明早交付物
|
||||
|
||||
1. MuMu 中可启动和遍历、且绑定 `APK-*` 或 `DBG-*` 可追溯/可复验指纹、`sourceManifestSha256` 和设备侧安装身份的冻结测试候选;若两类指纹均无法取得,明确交付“无冻结候选”与 `INFRA_ERROR` 证据,不能用旧安装包代替。
|
||||
2. 52 条基线路由及所有已采纳新增路由的入口和结构结果,并分别报告 `baselineRoutes`、`approvedNewRoutes`、`registeredRoutes`、`traversedRoutes` 与 `NOT_RUN` 路由。
|
||||
3. 当前页面—动作—接口映射、真实请求结果,以及两个参考源逐页面/逐动作/逐接口的采纳结论。
|
||||
4. `referenceEvidenceRecords` 与六类证据数量、权威 PA 动作分母、`liveCompletedActions` 和逐动作四字段结果。
|
||||
5. `inventoryTests`、`scheduledTests`、`executedTests`、`notRunTests`、`timedOutTests`,以及构建/部署和 MuMu 实机验收结果。
|
||||
6. 本轮实际评估/采用的 `RAxxx` 参考资产清单、来源确认、改造方式、重复 canonical owner、包体影响及逐状态验收证据;未使用的 531 项不冒充已审。
|
||||
7. 后端阻塞、测试数据阻塞和需要人工复验的精确清单。
|
||||
8. 明早从登录开始的最短人工回归步骤。
|
||||
9. 运行元数据:用户确认的源码基线说明、开始结束时间、后端地址与可识别版本、MuMu 分辨率/density、账号角色、各项耗时和熔断记录;不调用 Git 取得 HEAD/dirty 信息,不包含任何凭据。
|
||||
|
||||
## 十、规划阶段只读核对记录
|
||||
|
||||
| 核对对象 | 当前事实 | 规划结论 |
|
||||
| --- | --- | --- |
|
||||
| 当前源码 | 用户确认已手动拉取 2026-07-23 最新 `main`;本轮未执行任何 Git 命令 | 不再沿用旧 HEAD/dirty 断点;以当前文件事实为准 |
|
||||
| 当前活动范围 | `pages.json` 有 52 条活动路由,`pages` 下有 53 个 Vue 文件 | 52 是最低基线;最终分母还要加入明确采纳的新增路由 |
|
||||
| 当前数据接线 | `runtimeConfig.mode` 为 `remote`;仅 A01、A04、A05、G01、G05、T01、M07 七页直接消费 `appApi`;40 页直接导入 `data/mock`,28 页含 `setTimeout` | 七页也须逐动作验真;其余页面逐项归类 LIVE/LOCAL_PREVIEW/CLOSED;timer 不能自动等同假成功,也不能逃过甄别 |
|
||||
| 当前 T03 | 页面已调用 `appApi.getPerson` 的 Apifox 人物详情 owner,具备严格 normalizer、取消控制与无 fixture 回退;测试目录已有静态与 mapper 门禁 | 仍未取得测试账号下的本轮真实人物响应、权限投影、跨页刷新与重进证据;明确为未完成半成品,不得记为 `LIVE_VERIFIED`、页面完成或产品完成 |
|
||||
| 受保护 OpenAPI | 本地 JSON/YAML 快照为 112 paths、153 operations,只读 | operation 存在仅记 `DECLARED_UNVERIFIED`,仍需对照线上文档和真实响应 |
|
||||
| “app设计”源 | `C:\Users\Rain\Desktop\job\app设计` 共 59 PNG+1 PDF;项目归档与 59 个旧文件哈希一致,新增 `思维导图.png` | 作为第一参考源;新图先用于规划,不在确认前复制 |
|
||||
| 已完成参考项目 | `C:\Users\Rain\Desktop\job\Jiapu-App` 有 78 条活动路由+1 条注释路由声明、79 Vue、6 NVue、7 个未注册页面文件、113 个旧 API wrapper;使用旧后端封装且没有可用测试脚本 | 作为第二参考源;78 是活动分母,注释路由和未注册文件单列候选;禁止复制其请求层、旧地址、组件和数据模型 |
|
||||
| 参考项目资产 | `Jiapu-App\static` 有 531 个媒体文件、约 6.45 MiB;声明扩展名为 307 PNG、221 GIF、2 SVG、1 JPG,文件签名实为 311 PNG、217 GIF、2 SVG、1 JPG;已发现 6 个扩展名/MIME 不一致、14 组完全重复、第三方/商标、旧品牌、固定旧文案、示例头像与短视频实验素材 | 用户允许逐文件复用候选;不整目录复制。高价值候选优先看水墨/宗祠、谱书、人物卡边框和中性功能图标;QQ 表情、短视频实验、支付/微信品牌、VIP/奖励、旧 logo 先排除直接复用 |
|
||||
| 参考映射 | 权威附件逐一登记 60 个设计文件、78 条活动路由、1 条注释路由声明和 7 个未注册页面文件 | 产品取舍必须在用户确认前完成;执行阶段只重算并冻结,不再用前 30 分钟临场决定范围 |
|
||||
| 测试与设备 | `tests` 下有 208 个文件:150 PS1、54 JS、4 JSON;当前没有统一夜跑 manifest;本轮没有运行测试、构建或 MuMu | 收到“开始执行”后才建立显式 manifest 并取得新鲜证据,旧 PASS 不冒充本轮 PASS |
|
||||
|
||||
### 当前接口覆盖初判
|
||||
|
||||
| 域 | 本地受保护快照中的接口证据 | 明确缺口或待验真项 |
|
||||
| --- | --- | --- |
|
||||
| A 认证 | 登录、短信登录、注册、找回、发码、资料、安全操作均有声明 | TAC 服务端消费、密码 wire、短信场景、会话撤销和真实错误语义仍需验真;微信登录无当前 APP operation |
|
||||
| G 家谱 | mine/public/create/detail/update、普通申请/撤回/审核、成员、字辈和行政区划均有声明 | G03 只有“创建家谱+另建首位人物”两次独立写;`regionCode` 必填,但第一步响应尚未保证稳定返回词法 `genealogyId`,创建结果查询也没有 operation,因此恢复链为 `MISSING_OPERATION`。只有第一步真实响应本身稳定给出字符串 ID 才允许进入第二步;首写超时、断线、5xx、空体或缺 ID 时立即停止并人工对账,禁止按展示名/“联调测试”标识从无正式 item DTO 的 mine 列表猜 ID,也禁止重复建谱;邀请码签发/直接加入、家谱排序、管理员 capability 没有可靠当前 owner |
|
||||
| T 世系 | tree、人物列表/详情/增改停用、父母/配偶/兄弟姐妹/子女写入均有声明 | 所有读取权限字段缺失;int64 wire、T04 性别字典、T06 原子排行、邀请四段链、两个绑定 mutation owner、头像上传到访问闭环均冲突或缺失 |
|
||||
| F 家族内容 | 动态、评论/回复/点赞、谱文、相册、照片和文件上传有声明 | 视频仅见删除操作,列表/发布/详情链不完整;视频评论、点赞和分享分别是独立候选,不能借动态互动或视频读取合同;置顶等参考动作无当前 owner |
|
||||
| R 族务记录 | 亲友记录、祭祀/献礼、成长记录、备忘录、功德记录有声明 | 人生事件和重要证件无明确 APP owner;参考“贺礼”与当前“祭祀献礼”语义必须先拆清 |
|
||||
| N 消息 | 通知列表、单条已读、全部已读有声明 | 未读计数没有 operation,G01/M01 不得从分页列表长度推断;没有通知详情 operation,列表还是无 item schema 的通用结果;N02 同一会话且列表项含完整正文时的投影单独记 `dataMode=LOCAL_PREVIEW`,冷启动、深链或缓存缺失状态单独记 `dataMode=CLOSED`;业务跳转、消息类型和目标参数均不能从文案猜测 |
|
||||
| M 我的 | 资料、安全、帮助、反馈、推广内容、VIP 套餐/订单有声明 | M08 保持当前家谱邀请 owner,票据查看、签发、撤销分别由 `C-G-INVITE-LIST/ISSUE/REVOKE` 拥有,复制与系统分享分别由唯一平台剪贴板、分享 owner 负责拒绝/失败/返回;邀请票据 operation 当前缺失。参考 APP 推广/推荐码/奖励无当前路由且保持候选;真实支付、提现/变现及部分敏感操作缺完整结果链;“关于”只用本地静态 owner,不依赖帮助列表 |
|
||||
|
||||
## 十一、产品参考功能基线与 T01 世系树重做计划
|
||||
|
||||
### 11.1 参考资料的归档与换路径办法
|
||||
|
||||
1. 第一参考源固定为 `C:\Users\Rain\Desktop\job\app设计`,只作为本机规划输入,不是运行依赖。业务代码、测试、接口合同和构建脚本均不得硬编码该绝对路径。
|
||||
2. 该目录当前有 59 张 PNG 和 1 份 PDF。项目相对目录 `docs/design/references/产品参考原稿` 保存了其中 58 张 PNG 和 1 份 PDF,59 个同名文件的 SHA-256 全部一致;源目录新增 `思维导图.png`。在用户确认规划前,不复制新增文件、不删除旧副本。
|
||||
3. `思维导图.png` 同时包含 APP、后台管理、公司官网和 PC 管理端分支。只有“用户端苹果安卓 APP”分支可直接进入当前产品候选池;其他分支只用于理解角色、权限和服务依赖,不能自动变成当前 UniApp 路由。
|
||||
4. 第二参考源固定为 `C:\Users\Rain\Desktop\job\Jiapu-App`。第一轮只读盘点已完成路由、页面和 API wrapper 清单;继续甄别时不安装依赖、不运行构建、不修改参考仓库,也不读取或迁移其 Git 历史。
|
||||
5. 参考项目使用旧的 Vue/uView 结构、旧后端地址和宽松请求封装,且请求层会输出参数和响应;这些实现、环境值、日志方式、Token 处理、组件和数据模型全部禁止迁入当前项目。API wrapper 只用于证明“参考项目曾尝试过某动作”,不能作为当前接口合同。
|
||||
6. `docs/产品参考页面功能映射表.md` 必须在交给用户确认前完成。第一源使用 `Dxxx-Pxx-Sxx-Axx` 标识文件、PDF 页/区域、页面、状态和动作;每张单页 PNG 默认自身就是独立 `S01` 状态证据,表内可省略 `S01` 作短写。第二源按 `Jxxx-Sxx-Axx` 标识 78 条活动路由的状态与动作,注释路由单列 `JX001`,7 个未注册文件使用 `JUxx-Sxx-Axx`。附件必须有正向逐项表和按当前 A/G/T/F/R/N/M owner 的反向覆盖索引;组合展示不能省略任何源 ID。
|
||||
7. 参考截图和参考项目不按文件整包采纳。甄别最小单位固定为“一个页面状态下的一个用户动作”。文件名相近、画面相似、路由目标相同或代码结构近似都不能直接判为重复:它们可能是普通、管理、编辑、空、错误、权限、角色或主题状态。只有入口、对象、动作、数据、接口和返回行为均被证明等价后,才能共用当前 owner;共用后仍须保留每个来源状态 ID。查看、创建、编辑、删除、邀请、分享、支付等动作可以分别得出不同结论。
|
||||
8. 当前项目继续使用已确定的国风资产、色彩和组件语言。参考稿的亮红导航、原卡片比例、旧弹窗、默认 uView 控件和旧图标只表达信息结构,不默认成为视觉验收目标。
|
||||
9. 参考源出现、当前项目没有路由或接口 owner 的功能先进入“候选缺口”,必须判断是复用现有页面、增加新路由、后端缺失暂关,还是与当前产品冲突舍弃;不得为了保持 52 条路由而遗漏,也不得为追求功能数量临时创建假页面。隐私资料、重要证件、资金、删除、退出家谱、所有者转移和账号注销一律作为敏感候选单列,参考源存在不构成采纳授权。
|
||||
10. 两个源再次变化时,重复“只读文件清单与哈希差异 → 更新页面/动作映射 → 记录新旧结论”的流程;不因源目录缺文件自动删除项目内归档,也不在业务代码里保存机器绝对路径。
|
||||
|
||||
### 11.2 T01 目标画面与交互
|
||||
|
||||
T01 的验收目标不是“能显示一棵文字树”,而是能够识别人、关系、代际并对选中人物执行明确动作的长世代世系树:
|
||||
|
||||
1. 人物节点使用头像卡片,至少呈现头像、姓名、关系标签和代际信息;配偶位于同一代并保持成组关系,父母、子女、兄弟姐妹的连接线不能断裂或指向错误人物。
|
||||
2. 有真实头像时通过统一文件投影显示;无头像、文件缺失或加载失败时使用确定性的国风默认头像,不使用随机网络图片或伪造真人照片。不能把 `avatarOssId` 直接拼成 URL。
|
||||
3. 支持横向与纵向浏览长世代内容;选中人物需有清晰高亮。长姓名、大字号、大量成员和数十代数据下,卡片、代际标签和连接线仍可辨认。
|
||||
4. 点击人物卡后打开唯一的人物操作面板,取代互相竞争的旧底部操作条。面板中央放大展示当前人物卡,头像区域提示并支持“点击头像查看资料”。
|
||||
5. 操作面板必须包含以下功能入口,并始终携带当前 `genealogyId` 和 `personId`:
|
||||
- 点击头像查看资料;
|
||||
- 添加父亲;
|
||||
- 添加母亲;
|
||||
- 添加配偶;
|
||||
- 添加兄弟姐妹;
|
||||
- 调整排行;
|
||||
- 添加儿子;
|
||||
- 添加女儿;
|
||||
- 邀请绑定;
|
||||
- 编辑信息。
|
||||
6. 面板遮罩点击、关闭按钮、Android 系统返回键、页面返回键、重复点击和焦点恢复行为必须一致。提交中的动作禁用重复触发;页面离开或响应迟到时不得把结果写入错误人物。
|
||||
7. 当前 Apifox 的 tree/person/member 投影均没有稳定 `canEdit/canInvite/canManage/actionCapabilities` 字段,前端不得猜测角色或伪造 capability。十个必需入口保持可发现;已有单一 declared write operation 的入口可提交最小白名单请求,由服务端最终裁决,并对 403/409/5xx/超时明确失败且不本地假成功。403 只能证明该次请求被拒绝,不能反推出可持续的前端权限。每个动作账本仍须记录权限字段、来源 operation、撤权后的刷新和 403 语义。
|
||||
|
||||
已完成参考项目只证明这组动作是产品候选,不证明实现可迁移:其树页面中“添加女儿”仍复用了 `addSon` 意图、“添加母亲”存在注释掉的入口、“邀请绑定”按钮没有闭合动作,删除又混用旧通用用户接口。因此 T01 必须按十个入口分别定义意图和合同,不能复制参考页面后把同名按钮视为完成。
|
||||
|
||||
### 11.3 页面职责与唯一 owner
|
||||
|
||||
| 页面 | 唯一职责 | 不得承担 |
|
||||
| --- | --- | --- |
|
||||
| T01 世系树 | 读取树、布局、浏览、选择人物、展示操作面板并导航到对应流程 | 不直接伪造任何写操作成功,不保存另一份成员详情 |
|
||||
| T03 成员详情 | 读取并展示真实人物资料;承接“点击头像查看资料” | 不以本地 fixture 冒充服务端人物 |
|
||||
| T04 添加亲属 | 统一承接父亲、母亲、配偶、兄弟姐妹、儿子、女儿六类新增关系 | 不为六个入口复制六套提交合同,不猜测缺失 ID |
|
||||
| T05 编辑成员 | 修改头像和允许编辑的基础人物资料 | 不承担排行或关系拓扑修改 |
|
||||
| T06 排行调整 | 原子调整同辈排行 | 不退化为另一份通用人物编辑页,也不保留旧“关系修正本地预览”假成功路径;关系修正若以后获批必须另立产品动作和原子合同 |
|
||||
| 邀请绑定流程 | 在独立合同下邀请用户并绑定人物 | 不与普通加入家谱申请或邀请码直接加入混为一条链 |
|
||||
| T07/T08 | 成员目录、成员状态等辅助读取 | 不成为 T01 写操作的旁路 owner |
|
||||
|
||||
T04 的六个入口只在路由内部传递经 validator 验证的十进制字符串 ID、内部 `relationType` 枚举和必要意图提示;`relationType` 不是 wire 字段,严禁发送到 `additionalProperties:false` 的 `LineagePersonBody`。页面先展示当前人物和待添加关系,只有性别字典、关系约束和真实响应共同确认后才允许提交。不得复制人物模拟配偶,也不得仅凭中文按钮在本地猜测 wire 值。
|
||||
|
||||
| UI 意图 | 完整 endpoint | 请求意图约束 | 当前状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| 添加父亲 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/parents` | 关系方向由 `/parents` owner 决定;只发送当前已声明并采集的基础人物字段,不发送 `relationType` 或猜测的性别 code | `DECLARED_UNVERIFIED`,待测试账号实测服务端性别/冲突/权限与读后刷新 |
|
||||
| 添加母亲 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/parents` | 同上;不得将“母亲”中文标签直接当成 `sex` wire | `DECLARED_UNVERIFIED`,待实测 |
|
||||
| 添加配偶 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/spouses` | 不发送 `relationType`;`relationName` 未由页面采集,暂不猜测 | `DECLARED_UNVERIFIED`,待关系方向、重复/冲突、权限与读后刷新实测 |
|
||||
| 添加兄弟姐妹 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/siblings` | 不发送 `relationType`;不把单人 `sortOrder` 当同辈排行 | `DECLARED_UNVERIFIED`,待字典/冲突/权限实测 |
|
||||
| 添加儿子 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/children` | 关系方向由 `/children` owner 决定;不猜测性别 code | `DECLARED_UNVERIFIED`,待实测 |
|
||||
| 添加女儿 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/children` | 同上 | `DECLARED_UNVERIFIED`,待实测 |
|
||||
|
||||
### 11.4 接口映射与启用条件
|
||||
|
||||
| 用户动作 | 页面 owner | 计划接口 | 启用条件 |
|
||||
| --- | --- | --- | --- |
|
||||
| 展示世系树 | T01 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/tree` | 树 DTO、稳定 ID、代际、配偶与父子连接关系已收紧并通过运行时测试 |
|
||||
| 查看人物资料 | T03 | `GET /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` | 路由参数与响应投影一致,不回退 fixture |
|
||||
| 添加儿子/女儿 | T04 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/children` | 性别 enum、请求 DTO、写入结果、重复提交与结果未知规则明确 |
|
||||
| 添加父亲/母亲 | T04 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/parents` | 同上,并由服务端校验关系冲突 |
|
||||
| 添加兄弟姐妹 | T04 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/siblings` | 性别/排行合同明确,不通过复制已有节点伪造 |
|
||||
| 添加配偶 | T04 | `POST /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/spouses` | 请求合同明确,并能读取提交后的真实关系 |
|
||||
| 编辑人物资料/头像引用 | T05 | `PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` | 字段白名单、头像上传/引用/访问 URL 闭环和结果确认完整 |
|
||||
| 调整排行 | T06 | 仅有候选 `PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` 的 `sortOrder` | 当前为 `CONTRACT_CONFLICT`:无批量/原子同辈重排、版本或冲突协议,不得逐人写出部分成功 |
|
||||
| 邀请签发、送达与接受 | 独立邀请流程 | 无可靠 operation | `contractState=MISSING_OPERATION`,保持关闭 |
|
||||
| 邀请目标身份查找 | 独立邀请流程 | 无隐私安全的可靠 operation | `contractState=MISSING_OPERATION`,保持关闭 |
|
||||
| 绑定 mutation | 独立邀请流程 | 成员 PUT 的 `lineagePersonId` 与人物 PUT 的 `appUserId` 是两个候选 | `contractState=CONTRACT_CONFLICT`,确认唯一 owner 前禁止双写 |
|
||||
| 邀请绑定结果查询 | 独立邀请流程 | 无可恢复查询 operation | `contractState=MISSING_OPERATION`,结果未知时禁止重试 |
|
||||
|
||||
`avatarOssId` 的 owner 是统一上传与文件访问链路;未确认上传、业务实体更新、文件引用和可访问 URL/重进显示四段闭环前,T05 不显示假上传成功。
|
||||
|
||||
邀请绑定拆成四段独立账本:
|
||||
|
||||
1. 邀请签发、送达、接受:当前没有 operation,保持关闭。
|
||||
2. 查找目标身份:当前没有隐私安全的独立 operation,保持关闭。
|
||||
3. 绑定已有成员/用户:`PUT /genealogy/app/genealogies/{genealogyId}/members/{memberId}` 的 `lineagePersonId` 与 `PUT /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}` 的 `appUserId` 是两个冲突候选;真实合同确认后只能选择一个 owner。
|
||||
4. 结果查询:当前没有可恢复 operation,结果未知时不得重试或双写。
|
||||
|
||||
邀请绑定不能借用普通加入申请、邀请码直入或同时调用两个候选 mutation。关闭态检查可以为 `PASS`,但该必需动作的 `productCompletion` 仍为 `BLOCKED`。
|
||||
|
||||
所有写操作都必须定义提交中、成功、明确失败和结果未知四种结果。只有后端合同明确支持幂等或存在无副作用的结果查询时才允许安全恢复;超时、断网或 5xx 后不能用 timer 自动提示成功,也不能把本地草稿当成服务端已提交。
|
||||
|
||||
### 11.5 数据与状态约束
|
||||
|
||||
- `genealogyId`、`personId`、`memberId`、`appUserId`、文件与亲属引用都以十进制字符串为唯一 ID owner。当前 OpenAPI 的 `integer/int64` 与 JavaScript 安全精度冲突;只有服务端响应以字符串返回且请求接受字符串后才能启用。超过安全整数的 number 不得在解析后转字符串补救。
|
||||
- 树投影至少明确头像访问结果、姓名、关系类型、代际、父母引用、配偶引用、同辈排行 `sortOrder` 和权限/能力;当前 capability 未声明,所有写入口先关闭。字段缺失必须进入可解释失败或降级状态,不能静默拼错树。
|
||||
- 关系类型采用单一枚举 owner,页面、API adapter、validator、测试和文档共同消费,禁止各页面维护中文字符串分支。
|
||||
- `sex`、关系、人物状态和排行语义都必须由真实合同提供 enum;T04 内部意图不能充当 wire 字典。
|
||||
- 排行调整当前为 `CONTRACT_CONFLICT`。在后端提供原子同辈顺序结果或明确并发协议前,前端只可展示关闭说明,不得逐人物写 `sortOrder` 或在失败后保留假顺序。
|
||||
- 恢复信息不得持久化手机号、头像原图、身份证明、邀请凭据等 PII;只保留完成恢复所需的最小非敏感标识和状态。
|
||||
|
||||
### 11.6 测试先行与实施顺序
|
||||
|
||||
只有规划经用户确认且用户随后明确说“开始执行”后,T01/T03—T06 才按以下独立小批次执行。每批由主代理写入、两位评审者只读复核接口、业务、交互、异常和视觉,当前批通过后才进入下一批:
|
||||
|
||||
1. **T01-0 失败门禁**:先新增会失败的合同,锁定头像节点、姓名/关系/代际、唯一人物操作面板、十个动作入口,并禁止旧底部操作条与新面板并存。
|
||||
2. **T01-1 树 DTO 与布局**:收紧树 normalizer 和 validator,验证父母、配偶、子女、代际、排行、缺头像、失真 ID、重复节点、断链及循环关系;旧宽 DTO 必须失败。
|
||||
3. **T01-2 视觉与交互**:实现头像人物卡、连接线、选中态、横纵浏览和操作面板;覆盖遮罩、返回键、焦点恢复、重复点击、快速切换人物和迟到响应。
|
||||
4. **T01-3 页面导航合同**:逐项验证 T01 → T03/T04/T05/T06 的参数、返回后选中态和树刷新;邀请绑定若无合同,只验证诚实关闭态。
|
||||
5. **T03/T04/T05/T06 真实接线**:每个页面先写 mapper/runtime 失败测试,再接对应 GET/POST/PUT;六种亲属动作分别验证请求意图,但复用一份 T04 提交合同。
|
||||
6. **异常与恢复**:覆盖空树、加载失败、403、404、409、429、500、超时、断网、离页取消、结果未知、权限变化、头像加载失败和提交后重新读取不一致。
|
||||
7. **性能与视觉验收**:以小树、数十代、数百成员、长姓名、无头像和多配偶数据检查布局预算、滚动流畅度、连接线及内存;不以无限数据承诺替代明确上限。
|
||||
8. **MuMu 与无障碍**:先在 720×1280 实机检查,再补 320/412 响应式检查;验证触控尺寸、文本缩放、读屏名称、焦点顺序、弹层焦点约束、系统返回和低性能设备操作反馈。TalkBack 等无法稳定自动化的项保留可复现人工步骤。
|
||||
|
||||
### 11.7 T01 检查结果与产品完成定义
|
||||
|
||||
T01 必须分别报告结构/关闭态检查和产品完成度:
|
||||
|
||||
- 头像卡、连接线、选择态、唯一操作面板、十个入口可发现、禁用原因、返回行为等可以分别得到 `checkResult=PASS/FAIL`。
|
||||
- 某入口因真实后端缺失而正确显示“服务暂未开放”,只表示该关闭态检查 `PASS`;该入口的 `productCompletion=BLOCKED`,T01 产品完成度也不得为 `COMPLETE`。
|
||||
- T01 只有以下全部成立时才可记 `productCompletion=COMPLETE`:
|
||||
|
||||
1. 真实头像或确定性默认头像可见,姓名、关系、代际和连接线正确。
|
||||
2. 点击任一人物只打开一个完整操作面板;查看资料、父亲、母亲、配偶、兄弟姐妹、排行、儿子、女儿、邀请绑定和编辑十个入口均完成真实权限与业务闭环。
|
||||
3. T03 展示真实详情;T04 六类关系写入、T05 编辑、T06 原子排行及独立邀请绑定各自遵守唯一 owner,没有 fixture、timer、兼容旁路或假成功。
|
||||
4. 树刷新和重进后能以服务端数据确认变更;写结果未知时停止重复写并提供只读恢复路径。
|
||||
5. 当前国风视觉一致,长世代滚动、卡片、连接线、遮罩和返回行为在目标尺寸上稳定,无白块、截断、误触和不可读状态。
|
||||
6. 接口、业务、交互、异常、视觉、性能和无障碍门禁通过三人交叉评审;自动测试、编译检查和绑定冻结候选包的 MuMu 实机证据齐全。
|
||||
|
||||
### 11.8 当前暂停项
|
||||
|
||||
- T03 的远端 `GET` 已按 Apifox 人物详情 owner 接线并通过静态/运行时映射门禁,但尚未以测试账号取得本轮脱敏真实响应,仍是 `DECLARED_UNVERIFIED`,不能计入 `LIVE_VERIFIED` 或页面完成。
|
||||
- T01 旧的固定底部“查看资料/添加亲属”抽屉已经移除;当前只有点击人物卡打开的唯一人物操作面板。任何单张 MuMu 预览都不构成本节完整验收证据。
|
||||
- 在用户明确说“开始执行”前不继续修改 T01/T03—T06,不批量处理参考图,不运行测试、构建或 MuMu 验收。
|
||||
|
||||
### 11.9 已完成参考项目的逐项甄别门禁
|
||||
|
||||
参考项目与当前项目可能属于不同版本、不同产品边界、不同技术实现或不同后端合同,因此采用优先级固定为:
|
||||
|
||||
1. 用户对当前产品明确确认的需求和取舍;
|
||||
2. 当前真实后端、Apifox、线上接口文档及可复现响应;
|
||||
3. 当前 UniApp 的路由、架构、安全约束和已确定国风视觉基线;
|
||||
4. 参考截图与已完成参考项目。
|
||||
|
||||
参考项目中的每个候选功能必须逐项回答:
|
||||
|
||||
- 业务目标是否与当前产品一致;
|
||||
- 使用角色、权限来源和数据归属是否一致;
|
||||
- 当前后端是否有对应 operation,请求、响应、枚举和错误语义是否一致;
|
||||
- 是否适合当前 UniApp、Android、导航结构和低性能设备;
|
||||
- 正常、加载、空、失败、无权限、重复提交和结果未知状态是否完整;
|
||||
- 视觉是否能融入当前国风体系,无障碍和触控要求是否满足;
|
||||
- 是否包含旧接口、硬编码、兼容分支、fixture、PII、凭据或其他不可继承风险。
|
||||
|
||||
每个候选功能只能得出以下一种书面结论:
|
||||
|
||||
| 结论 | 含义 | 后续动作 |
|
||||
| --- | --- | --- |
|
||||
| 直接采用 | 业务、合同、交互和视觉均与当前项目一致 | 先写当前项目失败测试,再按本项目结构实现 |
|
||||
| 改造后采用 | 功能有价值,但接口、权限、状态或视觉需要调整 | 在映射表中列出差异和改造边界后实施 |
|
||||
| 仅参考交互 | 只能借鉴信息结构或操作方式 | 不复制其数据层、API 代码和环境配置 |
|
||||
| 后端缺失,暂时关闭 | 当前服务没有可靠 operation 或结果确认链 | 保留诚实关闭态并登记解除条件 |
|
||||
| 与当前产品冲突,明确舍弃 | 违反当前需求、架构、安全或视觉口径 | 记录舍弃原因,禁止后续人员再次误迁移 |
|
||||
| 待用户确认 | 证据足够但会扩大产品范围、引入敏感能力或改变既有需求 | 保留书面选项,不进入代码批次 |
|
||||
|
||||
`docs/产品参考页面功能映射表.md` 对完成项目增加以下列:参考仓库相对路径、参考路由、候选动作、参考状态流、当前目标路由、当前接口证据、差异、甄别结论、改造边界、测试 owner 和用户待确认项。存在分歧或证据不足时标记“待确认”,不得由代理静默选择。
|
||||
|
||||
参考项目不得向当前仓库带入旧后端地址、账号、Token、密钥、签名、应用标识、用户数据、构建产物、依赖缓存或 Git 历史。采用其功能也必须重新通过当前项目的合同测试、运行时测试、编译、MuMu 视觉与三人交叉评审;“参考项目里能运行”不能作为当前项目完成证据。
|
||||
|
||||
### 11.10 参考项目资产逐文件复用门禁
|
||||
|
||||
用户已经允许把参考项目中的图标等资产拿来补足当前产品。该许可按“可进入逐文件甄别池”执行,不按“整包照搬”执行。规划期只读盘点得到:
|
||||
|
||||
- `C:\Users\Rain\Desktop\job\Jiapu-App\static` 共 531 个媒体文件、6,764,740 bytes(约 6.45 MiB);`assets` 只有 JS/CSS/SCSS,`uni_modules\uni-id.zip` 是依赖包而非产品资产。
|
||||
- 声明扩展名为 PNG 307、GIF 221、SVG 2、JPG 1;文件签名实为 PNG 311、GIF 217、SVG 2、JPG 1。6 个文件扩展名与 MIME 不一致,迁入前必须规范重导出。
|
||||
- SHA-256 完全重复 14 组、28 个文件,迁入时每组只能选择一个 canonical owner。
|
||||
- `static/emojis/qq` 434 项、`static/douyin` 18 项及旧视频实验图标、微信/支付宝/支付/VIP/奖励素材、旧 logo 和固定旧文案均有第三方、旧品牌或未批准业务风险,不能因文件存在而启用对应产品功能。
|
||||
- 水墨/宗祠、谱书、人物卡边框、中性功能图标和默认头像风格是高价值候选;其中固定姓氏、口号、生成者/提示词式文件名、示例人物、水印及低分辨率仍须逐文件处理。
|
||||
|
||||
每个实际考虑复用的文件在复制前建立 `RAxxx` 记录,至少包含:源绝对/相对路径、SHA-256、重复组与 canonical ID、声明扩展名/检测 MIME、尺寸/帧数/透明度/bytes、来源页面和状态、目标 PA/路由/组件/状态、语义用途、决策、复用方式、用户对参考项目的许可记录、第三方/商标信号、个人数据/旧品牌/固定文字/无障碍/性能风险、必要改造和验收证据。决策仍使用六类口径;复用方式固定为原文件、裁切重导出、重绘、仅构图参考或禁用。
|
||||
|
||||
逐文件门禁为:
|
||||
|
||||
1. **产品门**:必须绑定已批准 PA、页面、状态和动作;资产不能反向新增功能、解除后端关闭或扩大 55 个候选 PA。
|
||||
2. **状态门**:相似图标或画面也可能代表普通、选中、禁用、权限、错误等不同状态;未证明语义和行为等价前分别记录、分别验收。
|
||||
3. **来源门**:用户已允许评估并复用参考项目资产;带 QQ、抖音、微信、支付宝等第三方/商标信号的文件还需满足当前平台规范,来源不清时只能重绘或不用,规划不写“已拥有版权”结论。
|
||||
4. **隐私与品牌门**:不带示例真人/头像、二维码、手机号、姓名、水印、定位、旧 logo、旧口号、奖励/VIP/支付旧文案或固定姓氏。无 EXIF 不等于无个人数据,仍须看画面。
|
||||
5. **技术与安全门**:扩展名与 MIME 一致;SVG 不含脚本、外链或未经审查的 data URI;位图去无用元数据;重复哈希只保留 canonical;不得沿用旧绝对路径或外部 URL。
|
||||
6. **视觉与无障碍门**:服从当前国风 token;覆盖普通、选中、禁用、加载、错误和关闭态;小图放大不糊,功能图标有语义文本,装饰图不进入读屏,动图提供静态降级和减少动态效果。
|
||||
7. **性能与验证门**:记录解码尺寸、包体和首屏影响;超预算就压缩、重绘或按需加载。只对实际采用的 RA 在目标路由各批准状态做 MuMu 截图、缩放、离线/失败检查,并绑定冻结候选 ID。
|
||||
|
||||
首批优先甄别而非预先批准的候选包括 `static/iconpng/902.png`、`static/iconpng/z8526@2x.png`、`static/login/bj.jpg`(实为 PNG)、`static/iconpng/treeBJ.png`、`static/iconpng/book.png`、`static/icon/index.svg`、`static/navigation/*`、`static/tabulation/*`、`static/pu/*`、`static/jr.png`、默认头像风格和 `static/login/hd*.gif`。`jiap.svg` 约 397 KiB 且内嵌大位图与固定文字,只作构图参考。规划确认时固定 `referenceAssetFiles=531`、`approvedDirectReuseAssets=0`、`approvedAdaptReuseAssets=0`;收到“开始执行”后,只有通过上述逐文件门禁的 RA 才增加采用数,这属于已批准 PA 内的实现选择,不改变产品动作分母。九小时批次只甄别本轮已批准 PA 实际需要的资产,未选中的候选保持未审、未复制,不把“531 个进入候选池”写成“531 个必须在今晚迁入”。
|
||||
|
||||
### 11.11 全项目功能补足矩阵
|
||||
|
||||
下表是本轮权威规划的全项目检查骨架;逐页、逐动作和逐接口结论已经落在权威附件中。执行第 0 批只重算并冻结这些结论,不得再临场扩大产品范围。
|
||||
|
||||
| 当前域 | 当前活动路由 | 两个参考源提供的候选 | 本轮必须做出的结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| A 认证 | A01、A04、A05 | `登陆.png`、参考项目登录/注册/找回页,以及账号密码、短信、注册、找回、微信登录等动作 | 四条现有认证流程继续以 TAC 和当前后端为准;微信登录没有当前 APP operation,只能标记候选关闭或待用户确认,不能借旧接口接入 |
|
||||
| G 家谱工作区 | G01、G03、G05、G06、G08—G12 | 家谱列表、创建、加入、邀请码、家谱主页、字辈、家谱排序、始祖世代、管理员及权限 | G03 固定为“创建家谱→创建首位人物”两阶段,但恢复链按 `MISSING_OPERATION` 关闭:`regionCode` 由共享行政区划 owner 提供;只有第一步真实响应本身稳定返回词法 `genealogyId` 才登记待续办 ID 并进入第二步。首写结果未知或缺 ID 时停止并人工对账,禁止从 mine 列表按展示名/测试标识猜 ID,禁止假定通用对象壳含 ID,也禁止重复建谱。其余列表/搜索/普通申请/审核/设置/字辈逐项验真,邀请码直入、家谱排序、始祖世代和管理员权限分别判断 owner |
|
||||
| T 世系与成员 | T01、T03—T08 | 头像树、表格/树谱模式、人物资料、父母/配偶/兄弟姐妹/儿女、排行、邀请绑定、编辑及参考项目中的删除 | T01 十个必需入口逐项落到 T03/T04/T05/T06/独立邀请流程;T03保持未完成;删除人物/配偶不是本轮十个入口之一,须单列敏感候选,不能因参考项目有按钮而默认加入 |
|
||||
| F 家族内容 | F01—F10 | 家族圈、发布/删除/评论、谱文分类与增改删、相册分类与照片管理、视频列表/发布/编辑及短视频评论/点赞/分享 | 动态、谱文、相册、上传逐动作核对当前合同;视频浏览、评论、点赞、平台分享已拆成独立候选 owner,缺合同时诚实关闭,不用旧 API、动态评论 owner 或本地计数假成功 |
|
||||
| R 人物与族务 | R01—R11 | 人物、人情簿、贺礼邀请、成长日志、备忘录、功德录、重要证件 | R01/R02 分别作为人物目录、人物资料的独立路由状态,数据只消费 T07/T03/T05 的唯一列表/详情/编辑 owner;R02 不保留通用“新建人物本地预览”,编辑入口只导航 T05。亲友记录、祭祀/献礼、成长、备忘、功德按当前业务语义接线;“贺礼邀请”与“祭祀献礼”先拆分语义;人生事件和重要证件缺 owner 时进入候选缺口 |
|
||||
| N 消息 | N01、N02 | 加入申请、生日、贺礼、备忘、疫苗、点赞评论、推广、广告消息及详情 | 当前只有列表与已读合同,未读计数缺 operation,G01/M01 使用同一个关闭 owner 而不从分页长度推断;N02 无详情 operation。同一会话且列表项含完整正文时的投影是独立状态,记 `dataMode=LOCAL_PREVIEW`;冷启动、深链或缓存缺失是另一独立状态,明确返回 N01 并记 `dataMode=CLOSED`。只有服务端提供闭合详情、消息类型、目标 route key、参数和权限失效语义后才恢复 LIVE 详情与业务跳转 |
|
||||
| M 我的 | M01—M10 | 个人资料、帮助、设置、修改密码/手机、反馈、家谱邀请、VIP、注销、提现/变现 | M08 保持“选择家谱并管理家谱邀请票据”的当前职责,票据查看/签发/撤销与本地复制/系统分享分别归 `C-G-INVITE-LIST/ISSUE/REVOKE`、`C-S-PLATFORM-CLIPBOARD/SHARE`,缺真实 operation 时保持关闭;参考 APP 推广、推荐码、奖励和变现不得覆盖 M08,均维持无当前路由候选。支付、注销、换绑和提现属于敏感动作,必须有独立合同、人工窗口和结果确认 |
|
||||
|
||||
跨域共享项也必须进入映射:登录态与账号切换、当前家谱上下文、角色/capability、文件上传与访问 URL、通知回流、深链参数、缓存失效、写结果未知、Android 返回、触控、系统字号、TalkBack 和长列表性能。任何一个共享项不得在 A/G/T/F/R/N/M 各自复制一份合同。
|
||||
|
||||
第一轮已识别但不能静默纳入今晚代码的参考候选如下:
|
||||
|
||||
| 候选 | 参考证据 | 当前判定 |
|
||||
| --- | --- | --- |
|
||||
| 微信一键登录 | 思维导图与参考登录页 | 当前后端无 APP operation,`后端缺失,暂时关闭`;是否长期需要由用户后续确认 |
|
||||
| 管理员列表与细粒度权限 | 思维导图、参考 `admin` 三页 | 当前只有成员类接口证据,没有闭合的管理员角色/权限 owner,先列 `待用户确认` 与后端缺口 |
|
||||
| 家谱排序、始祖世代调整 | 参考 `sortGenealogy`、`ancestorsOrder` 与设计图 | 与 T01 人物排行、G12 字辈排序不是同一合同;分别缺可靠 owner,不能互相借用 |
|
||||
| 重要证件 | 参考 `document` 页面 | 当前 52 路由和 APP 合同均无 owner,列产品候选,不临时新增假入口 |
|
||||
| 家族圈置顶 | 思维导图 | 当前动态合同未见置顶 capability,暂时关闭 |
|
||||
| 广告/宣传视频 | 参考消息广告和宣传视频页面 | 与当前普通通知、通用推广和 F10 家族视频分开甄别;独立使用 `C-M-PROMO-VIDEO` 及其评论/点赞/分享候选 owner,无可靠 operation 时不采用 |
|
||||
| 提现、分享变现 | 参考“我的”页面 | 涉及真实资金且不属于已确认当前需求,保持 `待用户确认`,今晚不执行 |
|
||||
| 删除世系人物/配偶 | 参考 T01 操作面板 | 当前后端虽有停用人物声明,但用户本轮明确的是十个其他入口;删除必须另设权限、影响预览和二次确认后再决定 |
|
||||
| 扩展个人隐私资料 | 设计人物表单中的微信、QQ、住址、学历、职业等字段及参考重要证件页 | 当前需求未授权扩展收集,后端也无闭合隐私/可见性 owner,结论为 `与当前产品冲突,明确舍弃`;只保留反例证据,不采纳、不存储、不上传 |
|
||||
| 移除成员、退出家谱、所有者转移、账号注销 | 参考家谱列表/我的页与当前成员类声明 | 均为破坏性或身份敏感动作,必须单独产品确认、影响预览、再认证、结果查询和人工窗口;不因存在 operation 自动启用 |
|
||||
|
||||
### 11.12 确认与执行门禁
|
||||
|
||||
1. 用户已明确“需求说完了”,需求收集门禁已关闭。
|
||||
2. 主代理完成本文修订后,由三人按第七节交叉评审;只允许主代理吸收意见修改本文。
|
||||
3. 三人评审收口后,把完整修订版、主要变化、评审结论和仍待确认项交给用户。
|
||||
4. 交付用户时必须把两项单独列明并取得确认:`T_due=2026-07-24 08:00` 是否接受;55 个候选 PA 本轮是否维持 `approvedCandidateActions=0`。笼统沉默不视为接受具体截止时间或批准候选。
|
||||
- 用户已于 2026-07-23 确认将截止更新为 08:00,并确认 55 个候选 PA 本轮维持 `approvedCandidateActions=0`。
|
||||
5. 用户确认规划只代表规划定稿,业务代码、接口接线、样式、测试、构建和 MuMu 仍保持冻结。
|
||||
6. 只有用户明确说“开始执行”,第六节计时和第 0 批才启动;第 0 批只重算、冻结已确认映射和环境,不得重新解释为需求收集。
|
||||
7. 用户未说“开始执行”时,不因时间已到“今晚”而自行开工,也不把只读规划核对解释为代码阶段已经开始。
|
||||
@@ -1,140 +0,0 @@
|
||||
# 全量页面接口联调交接说明
|
||||
|
||||
更新日期:2026-07-26
|
||||
适用项目:家谱 APP 前端(`jiapuapp`)
|
||||
|
||||
## 一、交接结论
|
||||
|
||||
本轮已按 `pages.json` 对 **52 个已注册页面**做了重新复核:页面可进入、页面调用的接口方法存在、真实服务端可读取的数据已回读验证、没有继续以页面 mock/fixture 冒充服务端结果。
|
||||
|
||||
不能把本轮结论简化成“所有接口均已联调通过”。世系首位成员创建目前由服务端返回业务 `code: 500`,导致依赖真实成员的详情、编辑与关系链路没有可用测试实体,仍是明确阻塞项。
|
||||
|
||||
2026-07-26 的浏览器真实上传复测还确认了第二个合同阻塞:H5 已能从页面选择本地图片并完成 `init/chunk/complete` 上传,但 `complete.ossId` 是 19 位字符串,而照片/封面等业务 DTO 仍要求数值 `int64`。前端不能安全地把该值转成 JavaScript number,因此目前不会伪造照片创建成功。完整请求、响应和后端所需统一字段合同见 `docs/后端接口缺口与首位成员阻塞清单-2026-07-24.md` 的“八”。
|
||||
|
||||
## 二、本轮已验证的范围
|
||||
|
||||
### 2.1 页面路由与接线
|
||||
|
||||
| 模块 | 页面数 | 浏览器逐页打开 | 结论 |
|
||||
| --- | ---: | ---: | --- |
|
||||
| A 认证 | 3 | 3/3 | 页面入口、表单和会话态下的路由行为已检查;未触发短信、注册、找回密码等敏感写入。 |
|
||||
| G 家谱 | 9 | 9/9 | 家谱列表、创建、概览、搜索、申请、审核、设置、字辈页面均可稳定进入。 |
|
||||
| T 世系 | 7 | 7/7 | 树、成员目录及安全错误态可进入;真实成员读写见“阻塞项”。 |
|
||||
| F 家族 | 10 | 10/10 | 动态、谱文、相册、上传等页面均可进入;真实动态/谱文/相册数据已读回。 |
|
||||
| R 记录 | 11 | 11/11 | 人物、亲友往来、礼仪、成长、备忘、功德等页面均可进入;多类真实创建已回读。 |
|
||||
| N 通知 | 2 | 2/2 | 通知中心可读取;消息详情保持缺少读取 owner 的关闭态。 |
|
||||
| M 我的 | 10 | 10/10 | 资料、帮助、推广、VIP 等页面可进入;敏感安全操作未执行。 |
|
||||
| 合计 | **52** | **52/52** | 路由稳定渲染通过。 |
|
||||
|
||||
页面内共扫描到 71 个 `appApi` 调用,均能在 `utils/api.js` 找到对应方法;页面目录未发现 `data/mock` 或 fixture 导入。
|
||||
|
||||
### 2.2 已做过真实服务端读回的业务
|
||||
|
||||
以下均只使用测试账号和测试家谱数据,未做删除、退出、改密、短信或支付操作。
|
||||
|
||||
| 业务 | 已验证闭环 |
|
||||
| --- | --- |
|
||||
| 家谱创建 | G03 创建后,可在 G01 列表和 G05 概览读回。 |
|
||||
| 家族动态 | F02 创建后,可在 F01 列表、F03 详情读回。 |
|
||||
| 谱文 | F06 创建后,可在 F04 列表、F05 详情读回。 |
|
||||
| 相册 | F07 创建后,可在 F08 相册详情读回。 |
|
||||
| 亲友往来 | R04 创建后,可在 R03 列表读回。 |
|
||||
| 礼仪活动 | R07 创建后,可在 R05 列表读回。 |
|
||||
| 成长记录 | R08 创建后重新读取列表。 |
|
||||
| 家族备忘 | R10 创建后重新读取列表。 |
|
||||
| 功德记录 | R11 创建后重新读取列表。 |
|
||||
| 个人资料、帮助、推广、VIP、通知 | 已完成真实读取页面验证;不输出账号或会话敏感信息。 |
|
||||
|
||||
### 2.3 本轮修正
|
||||
|
||||
- F01/F03 不再把服务端 `feedType=text` 原码直接展示给用户,统一显示为“文字动态”。
|
||||
- 更新了 F 模块业务合同测试,使其校验当前真实 API 读写路径,而非旧 fixture/预览路径。
|
||||
- 新增全页面浏览器审查脚本:`tests/all-page-route-runtime-smoke.js`。
|
||||
|
||||
## 三、明确阻塞:世系首位成员创建
|
||||
|
||||
### 现象
|
||||
|
||||
测试家谱为空世系时,T04 “录入首位成员”已完成前端表单校验与请求组装;使用合法最小请求(姓名、第一世)调用:
|
||||
|
||||
```text
|
||||
POST /genealogy/app/genealogies/{genealogyId}/lineage/persons
|
||||
```
|
||||
|
||||
HTTP 返回成功,但业务响应为 `code: 500`,未创建成员;之后读取世系树仍为空。
|
||||
|
||||
### 影响范围
|
||||
|
||||
- T03 成员档案:没有真实 `personId`,无法完成真实详情读回。
|
||||
- T04 新增亲属:没有首位成员,不能继续建立亲属关系。
|
||||
- T05 编辑成员、T06 调整排行、T08 成员状态:没有真实成员实体,不能完成真实读写验证。
|
||||
- R01/R02 的真实人物详情同样没有可用实体可验证。
|
||||
|
||||
### 需要后端协助确认
|
||||
|
||||
1. 查询上述创建请求对应的服务端异常栈和租户/家谱初始化条件。
|
||||
2. 确认创建首位成员是否还存在 Apifox 未声明的必填字段或前置初始化操作;如有,补充到 APP 接口合同。
|
||||
3. 修复后提供一个可创建或可读取的测试成员,再继续 T03–T08、R01–R02 的真实闭环验证。
|
||||
|
||||
前端不会猜测额外字段,也不会用本地假成员伪造成功。
|
||||
|
||||
## 四、正确关闭的页面/动作
|
||||
|
||||
下列不是漏接,而是当前 APP 接口没有足以支撑该页面真实业务的 owner,或操作超出本轮授权范围:
|
||||
|
||||
| 页面/能力 | 当前处理 | 原因 |
|
||||
| --- | --- | --- |
|
||||
| F10 家族视频 | 明确提示暂未开放 | 仅见删除 operation,未见视频列表、详情、播放、发布等读取/写入合同。 |
|
||||
| R09 人生事件 | 明确提示暂未开放 | APP 目录中无独立人生事件资源。 |
|
||||
| N02 消息详情 | 明确提示暂未开放 | 只有通知列表和标已读,没有单条详情读取 owner。 |
|
||||
| M03 安全概览 | 已接真实 profile 只读概览 | 2026-07-26 实测 `GET /auth/profile` 返回 `phone`、`userNo`、`status`;页面仅展示掩码手机号、账号编号和状态。设备与登录记录仍无独立读取 operation,不展示或推断。 |
|
||||
| M05 换绑手机号 | 等待人工 TAC/短信验证 | 缺少可安全消费的当前手机号 DTO 与已核实验证码链路。 |
|
||||
| 删除、退出、改密、支付 | 未执行 | 本轮测试范围禁止敏感操作。 |
|
||||
|
||||
## 五、复测方式
|
||||
|
||||
### 5.1 前置条件
|
||||
|
||||
- 启动本地 Web 预览,默认地址:`http://localhost:5173`。
|
||||
- 使用已登录的测试账号浏览器,Chrome 远程调试端口为实际可用端口。
|
||||
- 设置一个测试家谱 ID;不要使用生产数据。
|
||||
|
||||
### 5.2 全页面路由复核
|
||||
|
||||
为避免一次跑完整 52 页超过终端时限,可分四段执行:
|
||||
|
||||
```powershell
|
||||
$env:CDP_PORT='9777'
|
||||
$env:GENEALOGY_ID='<测试家谱ID>'
|
||||
$env:PAGE_AUDIT_START='0'; $env:PAGE_AUDIT_END='26'; node tests\all-page-route-runtime-smoke.js http://localhost:5173
|
||||
$env:PAGE_AUDIT_START='26'; $env:PAGE_AUDIT_END='34'; node tests\all-page-route-runtime-smoke.js http://localhost:5173
|
||||
$env:PAGE_AUDIT_START='34'; $env:PAGE_AUDIT_END='45'; node tests\all-page-route-runtime-smoke.js http://localhost:5173
|
||||
$env:PAGE_AUDIT_START='45'; $env:PAGE_AUDIT_END='52'; node tests\all-page-route-runtime-smoke.js http://localhost:5173
|
||||
```
|
||||
|
||||
脚本会为有测试实体的页面读取真实数据;成员专属页面在后端首位成员故障未修复前只验证安全错误态,不把这当作真实成员接口通过。
|
||||
|
||||
### 5.3 静态和编译检查
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests\interface-page-mapping-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests\active-page-business-ownership-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests\f-business-flow-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests\r-business-flow-contract.ps1
|
||||
git diff --check
|
||||
```
|
||||
|
||||
## 六、继续推进顺序
|
||||
|
||||
1. 后端先解决首位成员创建 `code:500`,或提供可读取的测试成员。
|
||||
2. 用真实成员复测 T03–T08、R01–R02 的读取和允许的写入闭环。
|
||||
3. 对接口已存在但页面因没有稳定 ID 暂未开放的单条详情/编辑能力,拿到响应 DTO 和 ID 后逐项补齐。
|
||||
4. 需要判断视觉问题时,以模拟器为准;浏览器主要用于接口、路由和网络请求验证。
|
||||
|
||||
## 七、交接边界
|
||||
|
||||
- 不应把“页面能打开”或“表单显示成功”写成后端业务成功;必须以服务端返回和后续读取回显为准。
|
||||
- 不应添加 mock 成员、mock 视频、mock 消息详情或本地成功态补齐后端缺口。
|
||||
- 不应在无人值守时执行短信、换绑、改密、退出、删除、审核或支付。
|
||||
- 测试过程中产生的是测试家谱中的测试数据;后续清理需要由具备删除授权的人员单独确认后执行。
|
||||
@@ -1,545 +0,0 @@
|
||||
# 后端接口缺口与首位成员阻塞清单
|
||||
|
||||
更新日期:2026-07-24
|
||||
适用范围:家谱 APP 前端(`jiapuapp`)与 APP API 合同维护
|
||||
|
||||
## 目的与边界
|
||||
|
||||
本文供后端确认接口 owner、DTO 和测试数据,不要求前端猜测字段或用本地数据绕过接口。下文的“需要”分为两种:
|
||||
|
||||
- **已有接口但不可闭环**:路径和当前参数已存在,需修复服务端行为或补全可消费的 DTO。
|
||||
- **缺少业务 owner**:现有 APP OpenAPI 没有该页面所需的读取/写入 operation;需要后端和产品先确定资源归属,再发布合同。
|
||||
|
||||
除非下文明确写为“当前已声明字段”,字段名、枚举、分页形式和响应结构都由后端在 APP OpenAPI 中一次性定义;前端不会从其他模块、PC 接口或示例数据推断。
|
||||
|
||||
## 通用请求约束
|
||||
|
||||
当前已声明的受保护 APP 接口均需要当前测试账号的认证会话和 `clientid` 请求头。若请求体含 `clientId`,其值必须与该 Header 一致。本文不记录真实 token、手机号或生产数据。
|
||||
|
||||
后端交付一个新 operation 或 DTO 时,请同时在 APP OpenAPI 的 YAML/JSON 中补齐:路径、HTTP 方法、鉴权、所有 path/query/body 参数、成功响应、可预期的 4xx/5xx 业务码及字段必填性。仅有 HTTP 200 而业务 `code` 为失败,不能视为接口成功。
|
||||
|
||||
## 一、缺少业务 operation 的页面
|
||||
|
||||
### F10 家族视频:缺视频读取 owner
|
||||
|
||||
现状:`pages/family/f10-video-list.vue` 已明确关闭。当前 OpenAPI 只声明:
|
||||
|
||||
```text
|
||||
DELETE /genealogy/app/genealogies/{genealogyId}/videos/{videoId}
|
||||
```
|
||||
|
||||
没有视频列表、详情、播放地址或发布 operation。删除接口不能反推出读取和播放合同。
|
||||
|
||||
当前页面入口可提供的业务上下文只有:
|
||||
|
||||
| 参数语义 | 来源 | 状态 |
|
||||
| --- | --- | --- |
|
||||
| `genealogyId` | 页面路由 | 已有,必需 |
|
||||
| 当前登录账号 | 认证会话 | 已有,必需 |
|
||||
| `clientid` | APP 请求头 | 已有,必需 |
|
||||
|
||||
请后端/产品先确认视频资源是否归属某个家谱。若是,最小可用的首个 operation 应是“读取该家谱可见视频列表”,并明确:
|
||||
|
||||
1. 是否分页;若分页,统一选择并声明 `pageNum/pageSize` 或 `cursor/pageSize` 之一,不能让前端猜测。
|
||||
2. 每条记录的稳定视频标识,以及当前页面用于渲染列表所需的明确字段和字段类型。
|
||||
3. 当前账号无权、资源不存在、空列表的响应语义。
|
||||
|
||||
视频详情、播放、发布、编辑、评论、点赞和分享目前没有对应页面表单或页面数据模型;若产品要开放这些能力,请为每项单独给出 operation 与 DTO,不要用相册或动态接口兼容代替。
|
||||
|
||||
### R09 人生大事:缺独立资源与归属定义
|
||||
|
||||
现状:`pages/records/r09-life-events.vue` 已明确关闭;APP/PC OpenAPI 中都未发现独立“人生事件/life event”资源。
|
||||
|
||||
从 R02 人物详情跳转 R09 时会传入 `genealogyId` 和 `personId`,但 R09 当前没有读取或写入表单,因此不能从 UI 推断事件到底是“人物专属”还是“家谱公共”。请后端/产品先在以下两种归属中选择一种:
|
||||
|
||||
| 资源归属 | 最少识别参数 |
|
||||
| --- | --- |
|
||||
| 人物专属事件 | `genealogyId`、`personId` |
|
||||
| 家谱公共事件 | `genealogyId` |
|
||||
|
||||
归属确定后,请提供对应的列表/详情/创建或编辑 operation(以产品实际要开放的页面为准),并定义事件的必填业务字段、时间字段、排序/分页、权限和错误语义。归属未确定前,前端不会把成长记录、备忘或人物简介映射成人生大事。
|
||||
|
||||
### N02 消息详情:缺单条详情读取 operation
|
||||
|
||||
现状:当前已声明:
|
||||
|
||||
```text
|
||||
GET /genealogy/app/notifications
|
||||
POST /genealogy/app/notifications/{notificationId}/read
|
||||
POST /genealogy/app/notifications/read-all
|
||||
```
|
||||
|
||||
没有单条详情读取 owner,因此 `pages/notification/n02-message-detail.vue` 不展示 fixture 正文,也不从通知字段推断业务跳转。
|
||||
|
||||
建议后端补一个单条详情读取 operation;具体路径可由后端确定,但其最小输入和输出语义应为:
|
||||
|
||||
| 位置 | 需要项 |
|
||||
| --- | --- |
|
||||
| path 参数 | `notificationId`;应与现有“标记已读”接口使用同一通知标识语义 |
|
||||
| 请求上下文 | 当前登录账号、`clientid` |
|
||||
| 响应必需内容 | 通知标题、完整纯文本正文、发布时间、已读状态,以及供服务端内部定位的稳定通知标识 |
|
||||
| 错误语义 | 当前账号无权/通知不存在时应明确失败,不能返回其他账号的通知 |
|
||||
|
||||
业务跳转不是本次最低需求。若后端未来要返回业务目标,需另行提供受权限约束的 `bizType → 前端路由键 + 必填参数 + 失效语义` 闭合字典;前端不会由 `bizId`、标题或正文猜路由。
|
||||
|
||||
## 二、已有路径但缺少可安全消费合同的页面
|
||||
|
||||
### M03 账号与安全:已解除(真实 profile 只读概览)
|
||||
|
||||
2026-07-26 已用测试账号真实读取 `GET /genealogy/app/auth/profile`。响应含 `phone`、`userNo`、`status`;M03 已接入并只显示本地掩码手机号、账号编号和账号状态。页面不把明文手机号写入路由、日志或缓存。
|
||||
|
||||
“设备列表”“登录记录”“安全等级”仍没有独立读取 owner,也不属于当前 M03 的数据模型;页面不会展示或推断这些内容。建议后端仍在 Apifox 为 profile 发布明确 DTO;如产品要展示上述资源,应分别定义 operation、字段、权限和保留期。
|
||||
|
||||
### M05 换绑手机号:已有最终 PUT,但缺可验证的安全链路与读取 DTO
|
||||
|
||||
当前 OpenAPI 已声明最终写入接口:
|
||||
|
||||
```text
|
||||
PUT /genealogy/app/auth/phone
|
||||
```
|
||||
|
||||
当前已声明的请求参数如下;它们是现状记录,不是前端新增猜测:
|
||||
|
||||
| 位置 | 字段 | 约束 |
|
||||
| --- | --- | --- |
|
||||
| Header | `clientid` | 必填 |
|
||||
| Body | `clientId` | 必填,必须等于 Header `clientid` |
|
||||
| Body | `phone` | 必填,新手机号 |
|
||||
| Body | `smsCode` | 必填;当前导出合同为 4 位数字 |
|
||||
| 请求上下文 | 当前登录账号 | 必填 |
|
||||
|
||||
当前 OpenAPI 还声明通用发码接口:
|
||||
|
||||
```text
|
||||
POST /genealogy/app/auth/sms/code
|
||||
```
|
||||
|
||||
其当前 body 必填字段为 `clientId`、`tenantId`、`grantType`、`sceneCode`、`phone`、`validToken`;换绑场景为 `APP_PHONE_CHANGE`。当前 profile 已能只读获取并掩码显示手机号,但没有经过人工确认的换绑专用 TAC/发码/校验闭环;M05 因而继续保持关闭,且不在无人值守时发送短信或换绑。
|
||||
|
||||
请后端确认并在同一版本交付:
|
||||
|
||||
1. `APP_PHONE_CHANGE` 的 `validToken` 获取、绑定手机号主体校验、过期和一次性消费语义;如通用发码接口不适合作为换绑 owner,请提供专用 operation,而不是要求前端复用未知场景。
|
||||
2. 最终 PUT 成功、验证码错误/过期/重复、手机号已占用、无权限和结果未知时的明确 HTTP 与业务码语义。
|
||||
|
||||
本问题单只要求合同和人工可控的测试条件,不授权前端执行短信、换绑或其他账号安全写入。
|
||||
|
||||
## 三、已有接口但被服务端 `code:500` 阻断的成员页面
|
||||
|
||||
这不是“缺接口”,而是首位成员无法创建导致没有真实 `personId`。阻断请求为:
|
||||
|
||||
```text
|
||||
POST /genealogy/app/genealogies/{genealogyId}/lineage/persons
|
||||
```
|
||||
|
||||
当前已验证的最小请求:
|
||||
|
||||
| 位置 | 参数 | 值/约束 |
|
||||
| --- | --- | --- |
|
||||
| Path | `genealogyId` | 可访问的测试家谱 ID |
|
||||
| Header | `clientid` | 必填 |
|
||||
| 请求上下文 | 当前测试账号 | 必填 |
|
||||
| Body | `name` | 当前 `LineagePersonBody` 唯一 required 字段;非空成员姓名 |
|
||||
| Body | `generation` | 首位成员固定为整数 `1` |
|
||||
|
||||
2026-07-26 又从 T04 页面填写了可安全收集的全量资料并真实提交:姓名、人物编号、示例字典值、排序、别名、字辈、生卒日期、生卒地、安葬地、简介、备注;HTTP `200`,业务仍返回 `code:500 / 发生未知异常,请联系管理员`。首位成员不应伪填 `fatherId`、`motherId`、`relationName`;`appUserId` 缺同类型候选映射,头像 `avatarOssId` 仍受 19 位 `ossId` 类型冲突阻断。`sex`、`birthLunar`、`deathLunar`、`personStatus` 虽为可选,但 Apifox 仅称项目字典值、无枚举,页面不能把猜测的代码或农历文本作为正式交互。
|
||||
|
||||
已复现结果:最小请求与上述全字段页面请求均为 HTTP 层成功、业务响应 `code:500`;随后读取世系树仍为空。
|
||||
|
||||
请后端处理:
|
||||
|
||||
1. 查询该请求的异常栈,以及空世系创建首位成员所需的家谱/租户初始化条件。
|
||||
2. 修复后使该最小合法请求返回业务成功,并返回可读取的成员结果(至少可取得稳定 `personId`)。
|
||||
3. 以同一测试家谱验证后续读取:世系树、成员目录分页、成员详情均能读到该成员。
|
||||
4. 若暂不能修复,请提供当前测试账号有访问权限的测试 `genealogyId` 与真实 `personId`,供只读和允许写入的回读验证;不要提供生产数据。
|
||||
|
||||
解锁范围为 T03–T08、R01–R02:成员详情、首位成员/亲属创建、编辑、排行、成员目录与成员状态等。已有读取/写入路径应在取得真实 `personId` 后按页面顺序验证,不应改成 mock 或本地假成功。
|
||||
|
||||
## 四、后端回传模板
|
||||
|
||||
请每个问题按下列项目回复,便于前端不重做已接线部分:
|
||||
|
||||
```text
|
||||
页面/问题:
|
||||
资源 owner:
|
||||
APP operation(HTTP 方法 + 路径):
|
||||
鉴权和 clientid 要求:
|
||||
path/query/body 参数(字段、类型、必填、枚举/范围):
|
||||
成功响应 DTO(字段、类型、必填):
|
||||
错误响应(HTTP 状态 + 业务 code + 可展示文案):
|
||||
分页/排序/权限语义(如适用):
|
||||
可使用的测试 genealogyId / personId(仅测试数据):
|
||||
OpenAPI YAML/JSON 更新版本:
|
||||
```
|
||||
|
||||
前端收到更新后的合同和测试数据后,会先做最小浏览器真实请求,并以服务端成功响应后的列表/详情回读作为验收依据;样式问题另在模拟器复核。
|
||||
|
||||
## 五、A01 密码登录:已解除
|
||||
|
||||
2026-07-25 已在桌面版 Apifox 核对并用测试账号直连验证。最新已发布合同如下:
|
||||
|
||||
| 位置 | 字段 |
|
||||
| --- | --- |
|
||||
| Header | `clientid` |
|
||||
| Body | `grantType=password`、`tenantId`、`phone`、32 位 MD5 `password`;`validToken` 仅在验证中心策略开启时必传 |
|
||||
|
||||
`clientId` 与 `sceneCode` 不再属于密码登录 body:后端根据 `POST /genealogy/app/auth/login` 绑定 `APP_PASSWORD_LOGIN` 场景。前端先查询 `GET /genealogy/app/auth/verification/password-login/require`;服务端返回 `required:false` 时不伪造滑块或票据,直接提交上述 body;返回 `required:true` 时才完成验证中心 challenge/verify 并提交真实 `validToken`。
|
||||
|
||||
实际结果:`password-login/require` 返回 `HTTP 200 / code:200 / required:false`;随后密码登录返回 `HTTP 200 / code:200`,响应含 `access_token`。本项不再是后端阻塞。
|
||||
|
||||
## 六、2026-07-25 Apifox 认证动作合同更新(已接入)
|
||||
|
||||
Apifox 当前“家谱”项目新增并发布了下列 APP 认证动作接口;本地旧 `APP.openapi.json/yaml` 尚未同步这次导出,不能再作为认证链的 source of truth:
|
||||
|
||||
```text
|
||||
GET /genealogy/app/auth/verification/{operationCode}/require
|
||||
POST /genealogy/app/auth/verification/{operationCode}/challenge
|
||||
POST /genealogy/app/auth/verification/{operationCode}/verify
|
||||
POST /genealogy/app/auth/sms/{operationCode}/code
|
||||
```
|
||||
|
||||
`operationCode` 的已发布枚举为:
|
||||
|
||||
```text
|
||||
password-login | sms-login | register | forgot-password | phone-change | account-deactivate
|
||||
```
|
||||
|
||||
合同要点:
|
||||
|
||||
| 操作 | Header | path/query/body |
|
||||
| --- | --- | --- |
|
||||
| 查询策略 | `clientid` | path `operationCode`;query `tenantId`、`subject` |
|
||||
| 获取挑战 | `clientid` | path `operationCode`;body `tenantId`、`subject` |
|
||||
| 校验挑战 | `clientid` | path 必须与挑战使用同一 `operationCode`;body `tenantId`、`subject`、`challengeId` 和验证码证据 |
|
||||
| 发送短信 | `clientid` | path `operationCode`;body `tenantId`、`phone`、`grantType=sms`;仅服务端策略开启时提交 `validToken` |
|
||||
|
||||
所有新接口都明确禁止前端再提交 `clientId` 或 `sceneCode`;服务端按 APP 路由的当前激活绑定解析验证场景。
|
||||
|
||||
已做的最小真实验证(仅测试手机号、未发送短信):
|
||||
|
||||
| 请求 | 结果 |
|
||||
| --- | --- |
|
||||
| `GET …/verification/APP_SMS_LOGIN/require` | `HTTP 200`,业务 `code:500`:不支持的认证业务动作 |
|
||||
| `GET …/verification/sms-login/require` | `HTTP 200`,业务 `code:200`,`required:true`,`TIANAI/SLIDER` |
|
||||
| `GET …/verification/password-login/require` | `HTTP 200`,业务 `code:200`,`required:false`,服务端绑定 `sceneCode: APP_LOGIN` |
|
||||
|
||||
前端已将 A01/A04/A05 的验证、挑战、校验和发码链接到新路径;A01 密码登录使用 `password-login`,策略为 `required:false` 时直接调用最新密码登录 body;返回 `required:true` 时携带真实 `validToken`。短信、注册、找回仍只在服务端返回 `required:true` 后完成 TAC 并携带真实 `validToken`。
|
||||
|
||||
已用测试账号验证 A01 密码登录的真实成功响应;本轮未发送短信、注册、改密、换绑、退出或执行其他敏感操作。
|
||||
|
||||
## 七、2026-07-25 桌面 Apifox 复核:仍缺 owner 与分页响应异常
|
||||
|
||||
以下结论直接来自桌面版 Apifox 当前 APP 目录,前端不以其他资源替代:
|
||||
|
||||
| 页面 | Apifox 当前 operation | 缺口 |
|
||||
| --- | --- | --- |
|
||||
| F10 家族视频 | 仅 `DELETE /genealogy/app/genealogies/{genealogyId}/videos/{videoId}` | 缺视频列表、详情、播放地址、发布/上传和编辑 owner |
|
||||
| R09 人生大事 | “族务记录”目录仅有成长记录、备忘、亲友记录、功德记录四类 operation | 缺人生事件的列表、详情、创建、编辑、删除 owner |
|
||||
| N02 消息详情 | 通知目录只有列表、单条标已读、未读数、全部标已读 | 缺单条消息详情读取 owner |
|
||||
|
||||
另发现一个后端响应异常,不影响当前 F01(F01 使用非分页 `GET …/feeds`,已真实返回数组),但会使已发布分页 operation 无法使用:
|
||||
|
||||
```text
|
||||
GET /genealogy/app/genealogies/{genealogyId}/feeds/page?pageNum=1&pageSize=20
|
||||
```
|
||||
|
||||
桌面 Apifox 将成功响应声明为 `PageResult`;同一测试账号实际得到 `HTTP 200 / code:200`,却完全省略 `data`。客户端的分页合同需要 `data.rows`(数组)和 `data.total`(整数),因此当前会精确拒绝为分页响应无效,不能把空 envelope 当成空列表。
|
||||
|
||||
请后端:
|
||||
|
||||
1. 为 F10、R09、N02 分别提供独立 APP operation 与完整 DTO;不要让前端复用相册、成长记录或通知列表字段。
|
||||
2. 修复 `feeds/page` 成功响应,使 `data.rows` 和 `data.total` 与 Apifox `PageResult` 一致;若该 operation 已废弃,请在 Apifox 明确下线,避免保留可调用但无结果的合同。
|
||||
|
||||
## 八、2026-07-26 真实 H5 图片上传:`ossId` 跨接口类型冲突
|
||||
|
||||
本项使用测试家谱的 F09「添加照片」页面、浏览器文件选择器和本地真实图片
|
||||
`static/assets/foundation/transparent/auth-login-outline.png` 验证;没有使用 mock、fixture 或手工伪造上传回执。
|
||||
|
||||
实际请求链路均返回 `HTTP 200 / code:200`:
|
||||
|
||||
```text
|
||||
POST /genealogy/app/files/resumable/init
|
||||
POST /genealogy/app/files/resumable/chunk
|
||||
POST /genealogy/app/files/resumable/complete
|
||||
```
|
||||
|
||||
`complete` 的真实响应为(URL 已省略):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"fileName": "auth-login-outline.png",
|
||||
"ossId": "2081232520259612673"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
该 `ossId` 是 19 位雪花标识,必须以字符串原样传递。它大于 JavaScript `Number.MAX_SAFE_INTEGER`;转换为 number 会丢失精度。当前照片创建 DTO 却把 `ossId` 声明为 `int64` 数值,F09 无法在不篡改标识的前提下提交:页面已经明确提示并停止在关联业务数据之前。
|
||||
|
||||
受影响的是所有“上传回执 → 业务表单”页面,而不只是 F09:动态配图、谱文封面、相册封面/照片、家谱封面、礼仪图片、备忘附件等。前端不会把字符串转为不安全 number,也不会提交截断后的 ID。
|
||||
|
||||
请后端在同一 APP OpenAPI 版本统一文件标识合同:
|
||||
|
||||
| 位置 | 需要确定的合同 |
|
||||
| --- | --- |
|
||||
| 上传完成响应 | `ossId` 保持十进制字符串(现网已如此返回),并明确为稳定文件标识 |
|
||||
| 所有消费该标识的 APP 请求 DTO | 对应字段统一接受同一十进制字符串;不要在 JSON 中要求前端传 `int64` 数值 |
|
||||
| 响应 DTO 与字段示例 | 同步明确字符串类型、正整数词法约束和真实大于 `2^53-1` 的示例 |
|
||||
| Apifox 发布内容 | 更新照片创建、封面、附件等所有相关 operation,避免上传接口和业务接口各自定义一套类型 |
|
||||
|
||||
后端发布统一合同后,请提供仅测试数据可写入的家谱上下文。前端会重新从 F09 页面选择真实文件,完成“上传 → 创建照片 → 相册列表/详情回读”验收;在此之前不会猜测创建照片接口是否私下兼容字符串。
|
||||
|
||||
## 九、2026-07-26 Apifox 全量复核:贺礼邀约缺少受邀人候选来源
|
||||
|
||||
桌面 Apifox 当前已发布以下 4 个“贺礼邀约” operation:
|
||||
|
||||
```text
|
||||
PUT /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/invitees
|
||||
GET /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/invitations
|
||||
PUT /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/invitations/me
|
||||
GET /genealogy/app/genealogies/ceremony-invitations/mine
|
||||
```
|
||||
|
||||
其中请求合同已明确,前端不会补猜字段:
|
||||
|
||||
| operation | 必填参数 | 可选参数 | 备注 |
|
||||
| --- | --- | --- | --- |
|
||||
| 替换活动受邀人 | path `genealogyId`、`ceremonyId`;body `inviteeUserIds` | 无 | `inviteeUserIds` 是唯一业务用户 ID 的完整数组;空数组表示取消全部尚未响应的邀请 |
|
||||
| 查询活动邀请名单 | path `genealogyId`、`ceremonyId` | 无 | 返回邀请记录列表 |
|
||||
| 响应当前用户邀请 | path `genealogyId`、`ceremonyId`;body `inviteStatus` | 无 | 枚举仅允许 `ACCEPTED` 或 `DECLINED` |
|
||||
| 查询我的活动邀请 | 无业务 path/body | 无 | 当前登录业务用户的有效邀请列表 |
|
||||
|
||||
当前 `CeremonyInvitationVo` 可读取字段为:`invitationId`、`genealogyId`、`ceremonyId`、`inviteeUserId`、`inviteStatus`(`PENDING` / `ACCEPTED` / `DECLINED` / `CANCELED`)、`inviteVersion`、`deliveredTime`、`readTime`、`responseTime`、`ceremonyTitle`、`ceremonyTime`、`location`、`locationAddress`、`longitude`、`latitude`。这些 ID 均为 `int64`,真实雪花 ID 必须统一允许十进制字符串传递,不能要求 H5 转为不安全的 JavaScript number。
|
||||
|
||||
### 阻塞点
|
||||
|
||||
R07 需要的是 `inviteeUserIds`(业务用户 ID),但当前 APP 家谱成员列表没有声明可供选择的业务用户 ID,也没有“可受邀用户候选列表” operation。`memberId`、`lineagePersonId` 和 `inviteeUserId` 是不同资源标识,前端不会用任一个替代另一个,也不会提供让用户手输未知业务 ID 的伪流程。
|
||||
|
||||
请后端在同一版 APP OpenAPI 中二选一,并提供仅测试数据:
|
||||
|
||||
1. 在现有“家谱成员列表/选项”成功 DTO 中明确返回稳定的 `appUserId`(或等价字段),并声明该字段就是 `inviteeUserIds` 的合法值;或
|
||||
2. 新增“查询活动可邀请用户候选列表” operation,至少返回业务用户 ID、展示名、是否可邀请、不可邀请原因。
|
||||
|
||||
同时请确认 `int64` 业务用户 ID 在所有 APP JSON 请求/响应中使用十进制字符串合同,避免与第八节 `ossId` 相同的精度丢失问题。候选来源和字符串 ID 合同发布前,前端只接入邀请读取/响应的精确 API 方法,不会把“替换受邀人”伪装成可用页面功能。
|
||||
|
||||
## 十、2026-07-26 Apifox 路径修正:行政区划
|
||||
|
||||
桌面 Apifox 当前正式路径为:
|
||||
|
||||
```text
|
||||
GET /genealogy/region/children?parentCode={parentCode}
|
||||
GET /genealogy/region/path/{regionCode}
|
||||
GET /genealogy/region/search?keyword={keyword}&level={level?}&limit={limit?}
|
||||
GET /genealogy/region/{regionCode}
|
||||
```
|
||||
|
||||
其中 `search.keyword` 必填;`search.level`、`search.limit` 可选;其余 `regionCode` path 参数必填,`children.parentCode` 可选。G03 原先错误使用了 `/genealogy/app/region/children`,已改为正式路径并在 H5 浏览器验证省、市、区三级均返回业务 `code:200`。其余 3 个 operation 尚无当前页面交互入口,待桌面 Apifox 补齐可消费的响应 DTO 后按实际页面需求接入;不会以 `additionalProperties` 的导出占位结构猜字段。
|
||||
|
||||
## 十一、2026-07-26 F03 真实点赞后缺少当前用户状态
|
||||
|
||||
测试账号通过 F03 动态详情页面执行了一次真实“点赞”(没有执行取消点赞或其他删除操作):
|
||||
|
||||
```text
|
||||
POST /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/likes
|
||||
```
|
||||
|
||||
该请求返回 `HTTP 200`。随后页面重新读取详情,`likeCount` 从 `0` 变为 `1`,说明服务端已写入点赞;但详情响应没有给出可用的当前用户点赞状态,前端读取到的 `likedByMe` 仍为 `false`/缺失,按钮继续显示“点赞”而不是“取消点赞”。
|
||||
|
||||
这不是前端可以用本地布尔值补齐的缺口:页面刷新后必须以服务端状态决定下一次应该调用 `POST /likes` 还是 `DELETE /likes`。当前合同会导致重复点击语义不明确,也无法安全展示已点赞状态。
|
||||
|
||||
请后端在以下 APP 读取 DTO 中统一提供当前登录用户维度的必填布尔字段 `likedByMe`(或同义且明确的字段),并与点赞写入立即一致:
|
||||
|
||||
```text
|
||||
GET /genealogy/app/genealogies/{genealogyId}/feeds
|
||||
GET /genealogy/app/genealogies/{genealogyId}/feeds/page
|
||||
GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}
|
||||
```
|
||||
|
||||
字段必须是 `boolean`,不能以点赞总数、空值或仅他人点赞记录代替。后端发布后,前端会再从 F03 页面验证“点赞 → 详情回读为已点赞 → 仅在用户主动操作时取消点赞”的完整闭环。
|
||||
|
||||
前端已将缺失/非布尔值保留为“状态未知”,并在 F03 禁用点赞按钮、显示明确原因;不会再把它转换为 `false` 后重复发送点赞请求。
|
||||
|
||||
## 十二、2026-07-26 谱文分类列表缺少可消费的条目 DTO
|
||||
|
||||
桌面 Apifox 的正式 operation 为:
|
||||
|
||||
```text
|
||||
GET /genealogy/app/genealogies/{genealogyId}/article-categories
|
||||
```
|
||||
|
||||
请求仅要求 path `genealogyId`(以及认证 `clientid`),成功响应在当前桌面文档中标注为通用 `ListResult`,没有声明列表项字段模型、字段示例或 `categoryId` 的类型。F06 的创建谱文请求可选 `categoryId`,但前端不能在不知道“分类标识”和“分类展示名”字段的情况下把任意对象渲染成选择器。
|
||||
|
||||
请后端把该 operation 的 `data[]` 明确为具名 DTO,至少包含:
|
||||
|
||||
| 字段 | 合同要求 |
|
||||
| --- | --- |
|
||||
| `categoryId` | 稳定分类标识;若为 int64,APP JSON 统一使用十进制字符串 |
|
||||
| `categoryName` | 非空展示名称 |
|
||||
| `status` / `enabled` | 明确是否允许在新建谱文中选择;若不需要则明确只返回可选项 |
|
||||
| `sortOrder` | 可选的稳定排序字段;若服务端已排序则在文档明确 |
|
||||
|
||||
在条目 DTO 发布前,F06 继续允许按现有创建合同不带 `categoryId` 发布,不会把导出文件里的通用对象或本地硬编码分类当作真实分类数据。
|
||||
|
||||
## 十三、当前全部已确认阻塞总表
|
||||
|
||||
本表是当前 APP 136 operation 审计的唯一汇总入口;详情、请求字段和回传模板见本文件对应章节,以及 `APP-136请求参数字段核对表-2026-07-26.md`。这里的“阻塞”不等于前端缺少调用代码:可能是 operation 根本不存在、响应 DTO 无法消费、服务端真实失败,或 H5 不存在安全参数来源。
|
||||
|
||||
| 编号 | 类别 | operation / 合同 | 影响页面 | 已验证事实 | 后端解除条件 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| B01 | 缺 operation | 视频仅有 `DELETE /videos/{videoId}` | F10 | 无列表、详情、播放地址、创建、上传、编辑等 owner | 发布视频读取与发布完整 operation/DTO |
|
||||
| B02 | 缺 operation | 人生大事无资源 owner | R09 | 族务目录只有成长、备忘、亲友、功德 | 明确人物专属或家谱公共归属后发布列表/详情/写入 DTO |
|
||||
| B03 | 缺 operation | 通知仅有列表和标已读 | N02 | 无 `notificationId` 单条详情读取 | 发布单条详情读取及授权/错误语义 |
|
||||
| B05 | 安全链路缺失 | `PUT /auth/phone` | M05 | 只有最终 PUT,缺经确认的当前账号读取、TAC/发码闭环 | 发布专用换绑验证合同与读 DTO;敏感写入仍需人工测试许可 |
|
||||
| B06 | 服务端异常 | `POST /genealogies/{genealogyId}/lineage/persons` | T03–T08、R01–R02 | 2026-07-26 从 T04 页面分别以最小首位成员数据、以及包含编号/示例字典值/排序/生卒信息/简介备注的全字段资料真实提交,均为 HTTP `200` 但业务 `code:500 / 发生未知异常`,未生成本地或伪造 `personId`;同谱只读 `GET .../lineage/persons/options` 实测 `200 / data: []`,因此也没有可读取的真实人物候选 | 修复最小合法 body,返回并可读取真实 `personId` |
|
||||
| B08 | ID 类型冲突 | 上传 complete 与所有消费 `ossId` 的 DTO | F02/F06/F07/F09/G03/G11/R04/R07/R08/R10/T04/M02 | 真实 complete 返回 19 位字符串,消费者声明 `int64` number | APP JSON 统一十进制字符串 `ossId`;同版更新示例与所有消费者 |
|
||||
| B09 | 候选 ID 缺失 | `PUT .../ceremonies/{ceremonyId}/invitees` | R06/R07、我的邀请入口 | body 需要 `inviteeUserIds`,现有 member/person DTO 无同类型候选 | 公开 `appUserId` 对应关系或新增可邀请用户候选 operation |
|
||||
| B10 | 当前用户状态缺失 | 动态列表/分页/详情 `likedByMe` | F03 | 实际点赞后数量变更,详情未给当前用户布尔状态 | 三个读取 DTO 均返回同步的 required boolean `likedByMe` |
|
||||
| B11 | 条目 DTO 缺失 | `GET .../article-categories` | F06 | 只有通用 `ListResult`,无分类 ID/名称/状态/排序字段 | 发布 `categoryId`、`categoryName`、可选状态与排序 DTO |
|
||||
| B12 | 页面交互待确认 | 行政区划 path/search/detail | G03/G11 后续回填、搜索 | 2026-07-26 复测已返回 `value`、`label`、`regionCode`、层级等真实条目;但当前产品页面没有搜索/路径回填入口 | 产品确认地区搜索与路径回填交互后接入页面;接口 DTO 不再阻塞 |
|
||||
| B13 | 资源语义不能混用 | `members` 与 `lineage/persons` | 成员管理、R06/R07 | `memberId`、`personId`、`appUserId` 是不同资源,当前无独立成员管理页 | 提供成员管理页需求与稳定候选/映射 DTO,不得前端猜代 |
|
||||
| B14 | 业务绑定 owner 缺失 | `POST /files/reference` | 所有附件业务 | 需要 `bizTable`、`bizId`、`bizField`,页面没有可信业务表/字段来源 | 后端为各业务资源声明文件绑定 owner,或明确由创建 DTO 原子绑定 |
|
||||
| B15 | 枚举/候选缺失 | 多个 body 中的 `sex`、`birthLunar`、`deathLunar`、`personStatus`、`roleType`、`status`、`payType` 等 | T04/T05 及 T/M/G/R/F 写入扩展 | 2026-07-26 复核 `LineagePersonBody`:`birthLunar`、`deathLunar` 的含义是“日期是否农历”的项目字典值,不是农历日期文本;性别和人物状态也都是字典值。导出与桌面 Apifox 只给出示例 `0`,没有 value-label 枚举或字典 options operation,因此不能把输入框、农历日期文本或猜测的 `0/1` 映射留给用户 | 在 operation 详情给出完整 value-label enum,或发布字典 options operation;前端收到确定合同后统一改为选择器,并同步详情页的字典值展示 |
|
||||
| B16 | 测试边界,不是接口缺失 | 短信、改密、换绑、注销、退出、删除、审核、支付 | A/M/G/F/R/N 全域 | 当前任务禁止执行这些敏感动作 | 仅在用户另行授权、测试账号与可回收数据齐备后执行真实写入 |
|
||||
| B17 | 导出与实际校验冲突 | `POST /genealogy/app/files/resumable/init`(并影响 complete) | F02/F06/F07/F09/G03/G11/R04/R07/R08/R10/T04/M02 | 2026-07-26 真实 H5 上传:省略 `uploadId` 返回“上传ID不能为空”;以导出字段 `fileSize` 替代 `totalSize` 返回“文件大小不能为空”。实际可用请求为 `uploadId + totalSize`;秒传 `instant:true` 会合法返回 `uploadId:null` 与真实 `ossId` | 在桌面 Apifox 与可导出 OpenAPI 中统一请求/响应 DTO、required、示例及秒传分支;明确普通分片与秒传的 `uploadId` 可空规则 |
|
||||
|
||||
## 十四、真实浏览器请求与返回记录(供后端排查)
|
||||
|
||||
说明:以下均在测试账号、测试家谱中从 APP 页面发起;未记录账号密码、令牌或完整 `clientid`。所有请求均已携带运行时 `clientid`、测试账号登录态和 `genealogyId=2081191846772518914`。
|
||||
|
||||
### 1. B06:首位成员创建
|
||||
|
||||
接口:
|
||||
|
||||
```text
|
||||
POST /genealogy/app/genealogies/2081191846772518914/lineage/persons
|
||||
```
|
||||
|
||||
最小请求(2026-07-26,页面 T04):
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "首位成员最小请求验证",
|
||||
"generation": 1
|
||||
}
|
||||
```
|
||||
|
||||
实际返回:
|
||||
|
||||
```text
|
||||
HTTP 200
|
||||
{"code":500,"msg":"发生未知异常,请联系管理员","data":null}
|
||||
```
|
||||
|
||||
页面结果:`保存失败 / 首位成员尚未保存 / 发生未知异常,请联系管理员`。
|
||||
|
||||
后端称已修复后的复测(2026-07-26,重新登录测试账号后从 T04 提交):
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "后端修复验证首位成员",
|
||||
"generation": 1
|
||||
}
|
||||
```
|
||||
|
||||
返回仍为:
|
||||
|
||||
```text
|
||||
HTTP 200
|
||||
{"code":500,"msg":"发生未知异常,请联系管理员","data":null}
|
||||
```
|
||||
|
||||
因此 B06 仍未解除;本次不是会话过期导致的结论。首次请求得到 `code:401` 后已通过 A01 真实密码登录,重试才得到上述业务 `code:500`。
|
||||
|
||||
全字段诊断请求(同一页面、同一测试家谱;用于验证可选字段是否会改变异常,不是字段字典的最终验收):
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "LineageFullBody0726",
|
||||
"generation": 1,
|
||||
"personNo": "P20260726001",
|
||||
"sex": "0",
|
||||
"generationName": "FullGen",
|
||||
"aliasName": "FullBodyAlias",
|
||||
"birthLunar": "1900-01-01",
|
||||
"birthPlace": "TestBirthPlace",
|
||||
"deathLunar": "2000-01-01",
|
||||
"deathPlace": "TestDeathPlace",
|
||||
"burialPlace": "TestBurialPlace",
|
||||
"biography": "Full body browser submission verification",
|
||||
"remark": "test only",
|
||||
"personStatus": "0",
|
||||
"birthDate": "2026-07-26",
|
||||
"deathDate": "2026-07-26",
|
||||
"sortOrder": 1
|
||||
}
|
||||
```
|
||||
|
||||
实际返回同样为:
|
||||
|
||||
```text
|
||||
HTTP 200
|
||||
{"code":500,"msg":"发生未知异常,请联系管理员","data":null}
|
||||
```
|
||||
|
||||
特别说明:该诊断请求暴露出旧页面把 `birthLunar`、`deathLunar` 当作农历日期文本;Apifox 的真实语义是“是否农历”的字典值。不能把这一请求视为正确字典值示例,也不能要求前端据此猜选项。首位成员不应伪填 `fatherId`、`motherId`、`relationName`;`appUserId` 没有同类型候选,`avatarOssId` 被 B08 阻断。
|
||||
|
||||
随后读取:
|
||||
|
||||
```text
|
||||
GET /genealogy/app/genealogies/2081191846772518914/lineage/persons/options
|
||||
HTTP 200 / code:200 / data: []
|
||||
```
|
||||
|
||||
因此 T01 没有成员数据并非前端空白占位:服务端尚未成功写入任何真实成员。
|
||||
|
||||
### 2. 初次验证记录(历史结果;以 2.1 的复测结论为准)
|
||||
|
||||
| 编号 | 接口与页面 | 实际请求值/返回值 | 结论 |
|
||||
| --- | --- | --- | --- |
|
||||
| B07 | `GET /genealogy/app/genealogies/{genealogyId}/feeds/page`,F01/F03 | 已按页面分页参数真实读取;HTTP `200`、业务 `code:200`,但响应没有 Apifox `PageResult` 所需的 `data.rows`、`data.total` | 无法安全分页或把空对象伪装为无动态 |
|
||||
| B08 | `POST /genealogy/app/files/resumable/init`,F09 等上传页面 | 省略 `uploadId`:返回“上传ID不能为空”;将 `totalSize` 改为导出字段 `fileSize`:返回“文件大小不能为空”;实际可用字段为 `uploadId`、`fileName`、`fileMd5`、`totalSize`、`totalChunks`、`chunkSize`。秒传返回 `{"uploadId":null,"instant":true,"ossId":"2081232520259612673"}` | 文件服务返回 19 位字符串 ID,而业务 DTO 写 `int64` 数字,前端不能无损作为 JSON 数字提交 |
|
||||
| B10 | 动态点赞,F03 | 已真实点赞,点赞数量变化;详情/列表未返回 `likedByMe` | 不能据数量推断当前用户是否已点赞,页面已禁用不确定状态下的再次写入 |
|
||||
| B11 | `GET /genealogy/app/genealogies/{genealogyId}/article-categories`,F06 | HTTP `200`、业务 `code:200`、`data: []` | 无分类候选可供选择;同时合同没有分类条目字段定义 |
|
||||
| B12 | 行政区划 children,G03/G11 | `GET /genealogy/region/children` 已可真实读取;path/search/detail 没有可消费的条目 DTO 和页面交互归属 | 不猜地区回填字段或新增搜索行为 |
|
||||
| B17 | 分片上传初始化,F09 等 | 见 B08 的实际请求和返回;导出与服务端校验字段冲突 | Apifox 与导出必须先统一为唯一合同 |
|
||||
|
||||
### 2.1 后端称修复后的复测结果(2026-07-26)
|
||||
|
||||
| 编号 | 复测结果 | 当前结论 |
|
||||
| --- | --- | --- |
|
||||
| B06 | 重新登录后,T04 最小 body 仍返回 HTTP `200`、业务 `code:500`、`data:null` | 未修复 |
|
||||
| B07 | `GET .../feeds/page?pageNum=1&pageSize=20` 现在返回根级 `total:1` 和 `rows:[...]`,不再是空 envelope | 分页数据已出现;但 `likedByMe` 返回字符串 `"1"`,B10 仍未修复 |
|
||||
| B08 | F09 从真实图片文件上传到“已上传”成功;保存照片时前端收到真实 19 位文件 ID 后仍报“超出 APP 安全整数范围”,未发出照片创建请求 | 未修复,需统一字符串 `ossId` 合同 |
|
||||
| B09 | 礼仪列表可读取,`GET .../ceremonies/{ceremonyId}/invitations` 与 `GET .../ceremony-invitations/mine` 均返回 `data:[]`;没有可提交的 `inviteeUserIds` 候选 | 未修复,仍缺 `appUserId` 候选/映射 |
|
||||
| B11 | 谱文分类仍返回 `HTTP 200 / code:200 / data:[]` | 测试谱没有分类;仍需分类 DTO 与可用测试候选才能验证选择/写入 |
|
||||
| B12 | `GET /genealogy/region/path/110101`、`GET /genealogy/region/110101`、`GET /genealogy/region/search?keyword=北京&limit=10` 均返回包含 `value`、`label`、`regionCode`、层级等字段的真实数据 | 后端已补齐可消费条目;待产品确认搜索/回填交互后接入页面 |
|
||||
|
||||
### 2.2 世系人物身份认领合同增补(2026-07-27)
|
||||
|
||||
后端新增 `bindingMode`,所有 T04/T05 人物新增、修改及父母/子女/兄弟姐妹/配偶关系写入统一使用:
|
||||
|
||||
- `NONE`:不绑定账号,禁止提交 `appUserId`。
|
||||
- `SELF`:绑定当前登录账号,禁止提交 `appUserId`,后端从 Token 获取。
|
||||
- `SPECIFIED`:绑定指定业务用户,必须提交 `appUserId`。
|
||||
|
||||
页面已默认 `NONE` 并移除“自动读取 profile.userId 后提交”的旧路径。真实 `POST .../children` 已按 `bindingMode:"NONE"`、无 `appUserId` 发出,但仍收到 HTTP `200` / envelope `code:500` / `发生未知异常,请联系管理员`,人物未落库。B06 在新版合同下仍未闭环;需后端确认新包部署状态并给出该异常的业务原因。
|
||||
|
||||
### 3. 未发起写入请求的原因(不是漏测)
|
||||
|
||||
| 编号 | 接口/功能 | 未发起的原因 | 后端需要提供 |
|
||||
| --- | --- | --- | --- |
|
||||
| B01 | 视频 F10 | 仅发布删除接口;没有列表、详情、播放、创建、编辑或上传 owner | 完整资源 operation 与 DTO |
|
||||
| B02 | 人生大事 R09 | 没有资源 operation | 明确人物或家谱归属后的列表、详情、写入 DTO |
|
||||
| B03 | 通知详情 N02 | 只有列表、标已读;没有按 `notificationId` 读取详情 | 单条详情接口及授权语义 |
|
||||
| B05/B16 | 短信、改密、换绑、退出、注销、删除、审核、支付 | 属于本轮明确禁止的敏感动作 | 另行授权、测试账号和可回收数据后再测 |
|
||||
| B09/B13 | 礼仪受邀人、成员绑定 | 请求需要 `appUserId`,现有 `memberId`、`personId`、`appUserId` 不能互相替代;没有候选映射 | 同类型候选接口或稳定映射 DTO |
|
||||
| B14 | 文件业务引用 | 请求需要 `bizTable`、`bizId`、`bizField`,没有页面可信 owner | 各资源的文件绑定归属合同 |
|
||||
| B15 | 性别、人物状态、出生/逝世是否农历等 | 需要选择器,但 Apifox 仅给示例 `0`,没有枚举、中文标签或字典 options 接口 | value-label 枚举或字典 options operation |
|
||||
|
||||
|
||||
### 不应误标为阻塞的已完成项
|
||||
|
||||
- A01 密码登录、G03 创建家谱、家族动态/评论、谱文、相册、亲友往来、礼仪、成长记录、备忘、功德均已做过真实创建后的列表或详情回读。
|
||||
- M03 账号与安全已真实读取当前 profile,并仅展示掩码手机号、账号编号和账号状态;设备与登录记录不在当前页面范围内。
|
||||
- 4 条行政区划 operation 都已有 API owner;`children` 已在 G03/G11 页面真实读取,其余三条的阻塞是没有可安全消费 DTO/产品交互,不是路径不存在。
|
||||
- 136 条 `method + path` 均可在桌面 Apifox 当前目录找到;数量差异不是“导出漏了 path”,而是页面数、功能入口、DTO 和安全参数来源不同。
|
||||
@@ -1,670 +0,0 @@
|
||||
# 接口与页面映射总表
|
||||
|
||||
> 更新日期:2026-07-22
|
||||
> 阶段状态:阶段 0、导航任务 1—10、A01/A04/A05 TAC 客户端、领域上下文基础与 M07 反馈客户端已完成;家谱工作区、G03 原子创建、M06 帮助、个人资料读写、通知读写、M10 服务端退出、M04 密码凭证与 M05 手机号换绑三人审查及 OpenAPI 红灯已完成;普通加入、邀请码直入与 G11 设置三人审查及 OpenAPI 红灯也已完成;T01、TAC、工作区、G03、帮助、profile、通知、logout、password 与 phone-change 后端接口门禁当前红灯,加入、邀请与 settings 同样保持红灯;MuMu 原生矩阵待执行
|
||||
> 接口状态:已完成 A 系列认证/TAC、G 系列第一轮、G01/G05 工作区专项、G03 原子创建、Task36 普通加入、Task37 邀请码直入与 Task38 G11 设置专项、F 系列当前写接口边界、M06 帮助、M07 反馈、M01/M02/M03 个人资料读取、M02 资料写入、N01/N02/M01/G01 通知读写、M10 当前设备退出、M04/四条密码 wire、M05/全活动 OTP wire、T01 世系图及 2026-07-22 新线上 OpenAPI 差异核对;其余操作仍待逐项审查
|
||||
|
||||
## 一、权威边界
|
||||
|
||||
本文件是活动页面、业务目标、进入方式、返回或完成目标、适用状态与接口归属关系的唯一总表。`pages.json` 是活动路由的唯一注册清单;两者必须同轮更新并保持精确一致。
|
||||
|
||||
接口的唯一编辑源是后端维护的 Apifox 项目。根目录 `APP.openapi.json` 用于离线自动分析,`APP.openapi.yaml` 用于人工阅读与跨工具导入;部署地址的 `/v3/api-docs` 只提供当前线上实现证据。阶段 0 保护的双导出是 OpenAPI 3.0.1、112 路径、153 操作的旧快照;2026-07-22 21:52 只读核对 `https://backend-api.ddxcjp.cn/v3/api-docs` 得到 OpenAPI 3.1.0、722 路径、858 操作、507 模型。发现差异时必须由后端生成同版本双导出,不能手工覆盖受保护文件,也不能把专项结论扩张为全部线上操作均已审查。
|
||||
|
||||
当前边界如下:
|
||||
|
||||
- `pages.json` 注册 `52` 条活动路由;A02 已并入 A01,A06 保留源码但不属于活动路由。
|
||||
- 全项目响应式迁移与统一扫描已经完成;退役通用页面和零消费者旧表单删除后,实际 `64/64` 个 Vue 文件均在覆盖清单中。
|
||||
- 任务 5 实施前,A 系列及 G01—G10 曾由用户在 MuMu 中人工确认,G11、G12 以及 T、F、R、N、M 页面也曾逐页、逐状态审核并修复;这只是历史视觉基线,不覆盖任务 5—6 后的 G/T 动作、文案、权限和布局变更。任务 4—6 的当前代码仍须按实施计划重新完成 MuMu 流程矩阵。
|
||||
- 上述视觉结论是当前继续工作的基线,不等于真实接口、持久化、系统权限、真实短信、微信、支付或跨页数据闭环已经完成。
|
||||
- 后续发现明确、可复现的样式、交互或业务问题时可以重新打开页面;不得因为旧结论写着“通过”就忽略证据。
|
||||
|
||||
## 二、全局业务与交互合同
|
||||
|
||||
### 2.1 账户、启动与登录
|
||||
|
||||
- APP 不设游客模式。首次打开、无有效凭证或凭证过期时进入 A01;有效登录态进入 G01。
|
||||
- A01 是唯一活动登录页,承载密码登录、短信登录、注册、找回密码、协议入口和尚未接入的微信登录入口。当前默认密码登录;开发/联调 wire 已按线上 `POST /genealogy/app/auth/login` 接通,成功统一保存 `AppLoginVo.access_token` 并进入 G01。默认 `runtimeConfig.mode=mock` 不会发真实请求;remote 测试入口先展示 static TAC,但线上登录接口尚未消费票据,因此只可用于联调,不能据此解除生产发布红灯。
|
||||
- A04 注册成功的目标是建立登录态后进入 G01。2026-07-22 新线上 OpenAPI 已确认 `POST /genealogy/app/auth/register` 与两种登录操作统一返回 `RAppLoginVo`,`data` 引用 `AppLoginVo`,会话字段为 `access_token`;`utils/api.js` 只读取这一当前字段。正式接入应保存有效会话后直接进入 G01,不让用户重复登录,也不为受保护旧快照保留并行兼容路径。行为验证与短信发送时机仍在后续短信状态机阶段核对。
|
||||
- A05 重设成功后不自动登录:返回 A01,保留合规的手机号信息,切换密码方式、聚焦密码框并让用户使用新密码登录。
|
||||
- A04、A05、M04 当前预览仍共用 `utils/validation.js` 的 `8–32+字母数字` 旧策略;Task33 已证明该规则只在客户端且无法作为生产 owner。门禁通过后必须与 A01/A04/A05/M04 的 MD5 wire 同批原子迁移为服务端权威的 15—64 Unicode code point、NFC、允许空格与 Unicode、无组成规则,并同步替换本地唯一 owner、页面文案和测试;不得只改 M04 或保留双轨。
|
||||
- A01 未勾选协议时在协议区域就近高亮并显示错误,不弹原生提示、不跳页;用户勾选后立即清除错误状态。
|
||||
- A01、A04、A05 已接入同一个 `TacVerification` 和 `static/tac/`,不能把本地滑动成功冒充服务端验证。A01 短信登录使用 `APP_SMS_LOGIN`,A04 使用 `APP_REGISTER`,A05 使用 `APP_FORGOT_PASSWORD`;三者都先从 `/captcha/require` 取得严格 provider/type 合同,再由 `/captcha/challenge` 和 `/captcha/verify` 换取 `validToken`,携票调用 `POST /genealogy/app/auth/sms/code`。A01 密码联调入口暂借现有 TAC 场景做客户端前置后调用线上密码登录 wire,但 `validToken` 未进入或被服务端消费;它不是安全闭环,`API-AUTH-TAC-001` 仍阻止 remote 配置成为生产发布配置。
|
||||
- A01/A04/A05 已实现可发送、发送中、60 秒倒计时、失败重试、手机号变更失效、验证码到期和重复发送保护;短信码精确为 4 位。认证 HTTP 只接受 HTTP 200 严格 envelope,统一 15 秒超时,Android 返回或页面卸载会中止 RequestTask,迟到回调不得改变已离开页面。真实限流、前后台剩余时间恢复和多设备重放仍需后端集成与 MuMu 证明。
|
||||
- 凭证过期先回 A01,再显示项目自定义的单按钮信息弹窗并聚焦登录表单;主动退出清除凭证,但可以保留用户上次选择的密码或短信登录方式,不保存密码。
|
||||
|
||||
### 2.2 家谱上下文与加入、创建
|
||||
|
||||
- 一个账号允许创建或加入多个家谱。G01 列表按“我创建的”“我加入的”“加入申请”分组,顶部只表示当前选中项。
|
||||
- G01 顶部当前家谱卡用于打开切换层;下方可用家谱卡直接进入 G05。只有导航成功后才同步顶部选中项和本机当前家谱 ID,失败或并发点击不得把页面与持久上下文串到不同家谱。首次且没有历史选择或失效标记时可确定使用首个可用家谱;调用方给定的新列表不再包含历史 ID,或显式目标不可用时,必须清空、持久标记并要求用户重选,跨重载也禁止静默回退到另一家谱。只保存词法字符串 ID,不复制整份家谱数据;真实撤权检测等待 workspace 接入 onShow/事件刷新。
|
||||
- 审核中记录只展示进度和“撤回申请”,顶部卡不可进入家谱;被拒绝记录展示原因和“修改后重新提交”,进入 G08 而不是 G05;已退出或被移除记录展示原因和“重新申请”,不得访问原家谱内容。
|
||||
- 只有 READY 且当前账号 `canView=true` 的家谱能够成为全局家谱上下文;审核中、被拒绝、已退出或被移除的记录不得覆盖最近一个可用上下文。G03 新合同不再产生“待录入始祖”业务状态;历史半成品如真实存在应由后端迁移/隔离,不能继续成为客户端正式状态。
|
||||
- 没有可用家谱时,相关页面不得展示上一个失效家谱的缓存内容,应引导用户搜索家谱、使用邀请码或创建家谱。
|
||||
- G01 空态的主次顺序为搜索家谱、邀请码加入、创建家谱;非空列表保留“添加家谱”底部弹层。所有者可见世系、成员、字辈诗、申请审核四个快捷入口,普通成员不显示申请审核。
|
||||
- G06 同时承载搜索与邀请码定位。产品目标仍是“邀请码直接加入且不生成审核记录”,但当前 OpenAPI 没有邀请码校验或直接加入操作,因此本地流程只展示目标并进入 G08 填写确认,完成后无结果返回 G01,不能选中家谱或声称已经加入。搜索申请进入审核;真实邀请码终点必须等后端合同补齐后替换本地预览。
|
||||
- G06 结果至少需要谱名、姓氏、地区、堂号、所属上级谱、当前支系、管理者或认证信息、成员规模和最近更新时间,以区分同名家谱和支系;未加入、已加入、审核中、被拒绝、已退出或移除、我创建的六种关系各自只出现一个明确动作。
|
||||
- G08 当前用真实姓名、与已知长辈的文字关系和补充说明表达申请;用户可见示例统一使用“某某某堂侄”等通用占位,不出现具体姓名。后端提供结构化参照成员或关系字段后,应以新合同完整替换文字关系旧路径。
|
||||
- G03 当前在同一页面实例内依次完成“创建家谱”和“录入始祖”,不接收 `step` 或 `genealogyId` 路由参数;门禁前本地成功无业务结果进入 G05 明确预览态。生产目标不允许创建中断成空谱:第一步零网络写,最终按钮一次原子创建家谱、OWNER 与唯一始祖;进程终止后按 operationKey 查询服务端操作状态,不恢复已删除的路由步骤合同,也不让 G01 承担半成品恢复卡。
|
||||
- G05 同一路由区分公开预览与成员视图。公开预览不得闪现成员隐私或管理入口;所有者和普通成员采用最小权限模型,最终权限以接口合同为准。
|
||||
- G05 首屏按身份确认、来源确认、可信度确认三层组织信息;世系是次级入口,不自动抢占首次进入流程。
|
||||
- G11 只维护当前可解释的名称、访问预设和家谱简介;门禁前本地 fixture 的“仅成员可见”“公开可申请”仍由 `utils/genealogy-contracts.js` 映射旧 `visibility/joinMode` 并对未知组合失败关闭。任务 38 已固定唯一 merge PUT、fresh overview baseline、`settingsVersion+If-Match+typed 409`、24/80 code point、活动 PENDING 迁移阻断和 unknown 对账;后端门禁通过前不删除诚实本地预览或接宽松接口,见 2.16/5.15。任务 39 已把 G12 收紧为唯一 GET/PUT、ACTIVE-only 完整集合、`poemSetVersion+If-Match`、完整候选校验、软停用与 unknown 三方对账;后端绿前仍只做本地预览,见 2.17/5.16。
|
||||
|
||||
### 2.3 页面状态与请求结果
|
||||
|
||||
- 每个可请求页面至少判断正常、加载、空、失败、无权限和数据失效是否适用;表单另覆盖本地校验、提交中、成功、失败、取消和重复提交。
|
||||
- 本地校验先于请求;字段错误就近展示。关联错误必须关联并聚焦到真正相关的字段,页面级或系统级错误在提交区或自定义结果弹窗中说明。
|
||||
- 提交开始后锁定同一动作,避免重复写入;失败保留用户输入并提供明确重试;成功先完成必要数据刷新,再结束当前流程。
|
||||
- 列表进入详情后返回,应恢复滚动位置、搜索词、筛选条件、展开分组、已加载页数和当前家谱选择;只有主动刷新、账号切换或原数据失效时才重置。
|
||||
- 目标数据过期、权限变化、网络失败和取消不是空数据,必须分别呈现可理解的结果和下一步。
|
||||
- 分页加载必须保留已有内容和滚动位置;失败显示就地重试,结束显示明确末尾状态,数据不足一页时不制造虚假“到底”文案,也不循环触发。
|
||||
- 下拉刷新保留原列表,成功后只在确有变化时提示更新;失败在列表顶部提供重试,不把刷新和触底加载混成同一状态。
|
||||
- 空态必须区分首次使用、搜索或筛选无结果、确实没有内容、加载失败和无权限;每种空态只突出一个主操作,最多一个次操作。
|
||||
|
||||
### 2.4 导航、弹层与流程终点
|
||||
|
||||
- 当前三个业务根页面是 G01“家谱”、F01“家族”和 M01“我的”,A01 是认证根页;导航栈语义统一已经完成,路由注册表、导航网关、共享页头、自定义底栏、认证、G、T、F、R、N/M 系列活动页均按测试先行落地,退役通用页面、临时页面目录和最后一个零消费者旧表单组件均已删除。源码导航扫描为 `MIGRATION-DEBT=0`;认证至 N/M 的 MuMu 原生流程复核仍待执行。
|
||||
- 返回、取消、完成和重复进入必须分别验证。页面完成后不得把已经结束的旧流程继续留在栈中,也不得用 `navigateBack` 猜测一个可能不存在的返回目标。
|
||||
- 普通底部弹层可由遮罩或 Android 返回键关闭;存在未保存输入时先确认是否放弃。确认弹窗的返回键等同取消;任何取消都不得被记录为成功。
|
||||
- 弹窗高度只允许使用视口 `max-height` 和内部滚动;普通页面内容高度由内容决定,不为单一设备压缩字号、行高或控件尺寸。
|
||||
- 用户可见反馈使用项目自定义组件,不新增原生 UniApp Toast、Modal、Loading 或 ActionSheet 作为正式体验。
|
||||
- 轻提示、底部弹层、居中确认、结果说明和危险操作按决策成本分级。不可逆操作必须说明后果并二次确认;普通操作不滥用确认。
|
||||
- 产品合同已经定案为“邀请码直接加入且不生成审核记录”:只有未来真实邀请码校验与直接加入接口成功才允许建立成员关系。当前 G06/G08 只做本地流程预览并明确未提交服务器;M08 的旧审核分支、硬编码邀请码、复制和海报伪能力已经删除,在真实邀请码签发与校验合同落地前保持不可用。
|
||||
|
||||
### 2.5 三个根页面与主要流程
|
||||
|
||||
```text
|
||||
A01 登录/A04 注册
|
||||
→ G01 我的家谱
|
||||
→ 搜索或邀请码加入(G06 → G08 → G09 或 G01)
|
||||
→ 创建家谱(G03 创建 → G03 录入始祖 → G05)
|
||||
→ 家谱浏览与管理(G05 → T01/G10/G11/G12)
|
||||
|
||||
G01/G05
|
||||
→ F01 家族内容
|
||||
→ 动态、谱文、相册、人物、礼仪、备忘与功德
|
||||
|
||||
G01/M01
|
||||
→ N01 消息中心
|
||||
→ N02 消息详情
|
||||
→ 对应业务目标
|
||||
|
||||
M01 我的
|
||||
→ 资料、安全、帮助、反馈、推广、服务与关于
|
||||
```
|
||||
|
||||
### 2.6 当前本地数据与路由参数边界
|
||||
|
||||
当前 `52` 条活动页面除 A01/A04/A05 的认证调用外,仍使用页面内本地状态、fixture 或 mock 数据;其他活动页面没有 `appApi` 消费者。认证调用已经对准真实端点,但 `runtimeConfig.mode` 固定为 `mock` 并失败关闭,不能解释为真实后端已经联通。以下只记录页面源码当前主动读取的查询参数;上游传入但页面未读取的参数属于待审债务,不能写成有效合同。
|
||||
|
||||
| 页面 | 当前主动读取的查询参数 |
|
||||
| --- | --- |
|
||||
| A01、A04、A05 | 无 |
|
||||
| G01 | `genealogyId`、`state` |
|
||||
| G03 | 无 |
|
||||
| G05 | `genealogyId`、`state` |
|
||||
| G06 | `mode`、`state` |
|
||||
| G08 | `genealogyId`、`source`、`state` |
|
||||
| G09 | `state`、`status` |
|
||||
| G10 | `genealogyId`、`state` |
|
||||
| G11 | `genealogyId`、`state` |
|
||||
| G12 | `genealogyId`、`state` |
|
||||
| T01 | `genealogyId`、`state`、`selectedId` |
|
||||
| T03 | `genealogyId`、`personId`、`state` |
|
||||
| T04 | `genealogyId`、`personId`、`mode`、`state` |
|
||||
| T05、T06 | `genealogyId`、`personId`、`state` |
|
||||
| T07 | `genealogyId`、`state` |
|
||||
| T08 | `genealogyId`、`personId`、`state` |
|
||||
| F01 | `genealogyId`、`state` |
|
||||
| F02 | `genealogyId`、`state` |
|
||||
| F03 | `genealogyId`、`feedId`、`state` |
|
||||
| F04 | `genealogyId`、`state` |
|
||||
| F05 | `genealogyId`、`articleId`、`state` |
|
||||
| F06 | `genealogyId`、`articleId`、`mode`、`state` |
|
||||
| F07 | `genealogyId`、`state` |
|
||||
| F08、F09 | `genealogyId`、`albumId`、`state` |
|
||||
| F10 | `genealogyId` |
|
||||
| R01 | `genealogyId`、`state` |
|
||||
| R02 | `genealogyId`、`mode`、`personId`、`state` |
|
||||
| R03 | `genealogyId`、`state` |
|
||||
| R04 | `genealogyId`、`mode`、`relativeId`、`state` |
|
||||
| R05 | `genealogyId`、`state` |
|
||||
| R06 | `genealogyId`、`ceremonyId`、`state` |
|
||||
| R07 | `genealogyId`、`mode`、`ceremonyId`、`state` |
|
||||
| R08、R09 | `genealogyId`、`personId`、`state` |
|
||||
| R10、R11 | `genealogyId`、`state` |
|
||||
| N01 | `genealogyId`、`state` |
|
||||
| N02 | `id`、`state` |
|
||||
| M01 | `state` |
|
||||
| M02—M08、M10 | 无 |
|
||||
| M09 | `state` |
|
||||
|
||||
`state` 参数目前只用于直接加载页面时的本地状态审查,不代表后端请求字段;导航网关不注册也不会生成这个展示钩子。R 系列的 `count/saveResult/personName/giftId/ritualId` 已全部退役,人物名称和实体资料只能由受校验的复合身份从唯一只读 owner 取得。G03 的 `step/genealogyId`、G05 的 `mode/role/genealogyName`、G08 的 `previous/genealogyName` 以及 G12 的 `startGeneration/currentGeneration` 已从页面和注册表删除:页内步骤留在页面状态,名称按词法 `genealogyId` 从唯一 fixture 或后续领域数据取得,来源只由真实栈与受验证 `sourceKey` 表达。T03 初始 `personId` 是不可变宿主页路由身份,亲属浏览只改变页内活动成员和轨迹;因此当前 T05 本地预览必须以 `goBack()` 回到原实例,不得用活动成员重写 T03 URL。其余参数仍须在对应业务阶段判断为真实输入、页内状态、领域数据或删除项,不得把调试参数固化成接口合同。
|
||||
|
||||
T01/T03—T08 当前共用 `data/mock.js` 的唯一成员夹具 owner:列表查询必须传 `genealogyId`,单成员查询必须同时传 `genealogyId/personId`,返回值与嵌套亲属均为快照。错误家谱下的已知成员、未知成员或缺失必填身份不得回退到 1001、首位成员或“待核实成员”;T04 只有 `mode=first` 且 `personId` 为空时可以建立首位成员草稿。该夹具只支撑当前本地设计流程,不代表后端字段已经完整;任务 18 接入真实接口时必须删除临时 owner 与选择器,而不是并存第二份成员合同。
|
||||
|
||||
### 2.7 全局非功能门槛
|
||||
|
||||
- 默认字号和约 `1.3` 倍系统字号下,超长谱名、生僻姓名、错误说明和主操作不得重叠或丢失关键含义。
|
||||
- 主要触控目标不小于约 `44dp`;点击后 `100ms` 内出现反馈,预计超过 `300ms` 的操作显示明确加载状态。
|
||||
- 长列表至少用 `500` 条 mock 数据验证分批渲染、稳定 key、刷新、分页、末项可达和返回现场恢复。
|
||||
- 同一详情连续进入和退出 `20` 次,并快速切换根页面、重复开关弹层;不得出现白屏、串状态、重复堆栈、残留遮罩或逐次变慢。
|
||||
- Android 性能以约 `4GB` 内存的中低端设备为底线,验证启动、键盘、长列表、图片解码、页面切换和系统返回手势。
|
||||
- 页面离开时清理本页创建的定时器、监听器、上传任务和动画状态;连续使用不得积累重复请求或实例。
|
||||
- 当前导航阶段已完成任务 1—10 的共享基础、组件、退役入口、认证、G、T、F、R、N/M 系列静态迁移和零债务门禁;A01/A04/A05 的 TAC 客户端、领域上下文与 M07 反馈客户端也已完成,MuMu 原生矩阵尚未执行。T01、认证与家谱工作区后端门禁并行等待外部合同关闭;跨页面领域数据持久化以工作区门禁为前置,本地先按无依赖业务域、全局文字层级和无障碍第二轮逐批推进,不得一次混合实施。
|
||||
|
||||
### 2.8 G 系列第一轮接口差距账本
|
||||
|
||||
本轮已逐页核对 G01、G03、G05、G06、G08—G12 与受保护双导出,并对照新线上 OpenAPI 做了第一轮差异检查;随后任务 26 又对 G01/G05 做了三人反向质询、部署探测与失败门禁,但没有在 schema owner 未定时把页面接到 `appApi`。所有 G 页面仍是本地交互预览,页面显示角色也只是 fixture 的最小权限投影,不代表服务端授权。以下问题在真实接入前必须由接口适配合同或后端同版本新导出关闭:
|
||||
|
||||
- 公共边界:受保护旧双导出的家谱详情、列表和申请列表多为通用 `Object/ListResult`;新线上虽改为 `RListAppGenealogyVo/RAppGenealogyVo/RListGenealogyJoinApplyVo` 等类型化响应,但三个工作区模型均无 `required`。`AppGenealogyVo.genealogyId` 仍是 JSON `integer/int64`,合法最大值在 JavaScript 中不可逆失真;`roleType/status/memberStatus` 无 enum,且没有可直接用于 current context 的 `canView`。首批工作区只要求 `genealogyId/genealogyName/canView/canManage/canEditContent/roleType` 的最小闭包,不要求 22 个字段全部必填。`GET /genealogy/app/genealogies/quota` 虽已返回 `GenealogyQuotaVo`,它属于后续创建/加入写流程,不混入 G01/G05 只读批次。申请、用户、字辈等其他 int64 只在各自实际消费批次逐项关闭,不能用解析后 `String()` 冒充无损。
|
||||
- G03:任务 35 已完成三人专项审查。受保护旧双导出的 `GenealogyCreateBody` 与线上 `AppGenealogyCreateBody` 都只建谱,页面又缺可信 `regionCode`,通用人物 POST 不能保证唯一始祖或两写原子性。生产目标固定为最终按钮一次 `AppGenealogyBootstrapBody` 创建谱+OWNER+一世始祖+READY,使用 `/genealogy/app/region/search`、`GenealogyRegionCode`、`RegionSelectVo.selectable`、统一 `GenealogyAccessPreset`、词法 ID、Idempotency-Key 与无 PII operation-status;当前后端 `G03-BOOTSTRAP-OPENAPI-CONTRACT BLOCKED` 和客户端 `G03-BOOTSTRAP-CLIENT-RELEASE BLOCKED` 均为独立发布红灯,见 5.12。
|
||||
- G01/G05 只读工作区:`/mine` 是唯一可访问集合 owner,`/{genealogyId}/overview` 是 G05 唯一读取 owner,不同时调用语义重复的 `/{genealogyId}`。G01 必须在 `onShow` 或失效事件中取消旧请求并成功取得严格列表后才 reconcile;网络/5xx 不写撤权 tombstone。G05 在新请求前清旧数据并取消迟到响应,远端失败不回退 fixture。线上没有当前首屏用于确认来源和可信度的 `source/manager/certification/ancestorName/parentName/branchName/updatedAt/activeCount`;首批可以诚实隐藏或降级这些可选展示,若产品坚持保留则另补后端合同,不能让 fixture 成为真实详情。
|
||||
- G06:新线上公开搜索已经返回类型化家谱对象,但仍没有显式 `canApply`、六类关系字典、邀请码校验、邀请码目标解析或直接加入端点;未来必须由服务端返回可信的 `canJoinByInvite` 或等价结果,搜索申请资格不能代替邀请码资格,也不能信任 `source=invite` 查询参数。
|
||||
- G08:`GenealogyJoinApplyBody` 提供 `applicantName/phone/relationDesc/applyReason/inviterUserId`,当前页面的 `realName/relation/message` 仍需显式映射、手机号来源和必填规则确认;接口没有邀请码票据字段。搜索来源本地完成仅进入 G09 预览,邀请码来源本地完成仅回 G01,二者都不建立成员关系。
|
||||
- G09/G10:新线上我的申请和待审核列表已返回类型化申请行,但申请状态仍缺正式 enum/字典;真实撤回和审核必须携带服务端词法 `applyId`。线上审核体为 `{status,auditRemark}`,`status` 必填且匹配 `[12]`(1 通过、2 拒绝),`auditRemark` 最长 500;`utils/api.js` 已同步严格校验,旧 `{approved}` 路径已删除。当前本地 `LOCAL_WITHDRAWN` 和审核预览仍不得当成服务端状态。
|
||||
- G11:受保护旧双导出的 `GenealogyUpdateBody` 与线上 `AppGenealogyUpdateBody` 都有 `genealogyName/intro/visibility/joinMode`,且缺版本、If-Match、closed merge 与 typed 错误。任务 38 保留现有 PUT 为唯一 dirty-only owner,删除 generic GET/PATCH,复用 overview 的 `RAppGenealogyVo`,新增 `GenealogyName/GenealogyIntro/GenealogySettingsVersion` 与 409 三分支;G03 门禁只继续拥有共享 accessPreset 和旧 DTO/pair 删除,见 2.16/5.15。
|
||||
- G12:任务 39 已否决旧 `{poemText,disableMissing}`、collection POST、逐行 PUT、batch preview/save 与 management 多 owner,固定唯一 GET/PUT aggregate。请求改为显式 0—500 行 `{poemId?,generationNo,generationText}`+disableMissing,generationNo 唯一排序且声明严格升序;新行省略 ID,已有 ACTIVE ID 可显式移动,重复文字允许。false 保留遗漏 baseline、true 软停用,empty false no-op、empty true 清空 ACTIVE;服务端先校验声明严格升序,再构造完整 merged candidate,随后验证 ID/世代/slot/连续/最终容量并原子写,历史不物理删除。Unicode 精确为 NFC、1—50 code point 且拒绝控制/bidi/zero-width/孤代理。后端门禁仍有 72 项红灯,真实接入不得再依赖服务端 preview items 或猜批次首代,见 2.17/5.16。
|
||||
|
||||
### 2.9 新线上 OpenAPI 差异与运行边界
|
||||
|
||||
- 新运行基址为 `https://backend-api.ddxcjp.cn`,已经由 `utils/config.js` 唯一持有且无尾斜杠;当前仍保持 `mode: 'mock'`,不会让尚未接完的页面误打真实服务。线上文档的 `servers` 却仍生成 `http://backend-api.ddxcjp.cn`;客户端配置只能使用 HTTPS,后端需修正文档声明,不能让 H5 产生混合内容风险。
|
||||
- 本地 112 条路径中 109 条仍在线;旧 `/genealogy/app/files/reference`、`/genealogy/app/files/upload`、`/genealogy/pc/files/upload` 三条当前不在线,线上另有 613 条路径。任何上传与文件引用实现都必须先按新线上合同重新审查。
|
||||
- 线上把本地若干 `Genealogy*Body/View` 改为 `AppGenealogy*Body/Vo`,部分字段说明、响应包装和 operationId 也已漂移;现有离线测试只能证明受保护双导出内部的 G 系列快照,没有证明线上与旧快照一致。
|
||||
- 行为验证服务已能返回 `validToken`,短信发送体也强制接收它;但密码登录体没有票据字段。A01 密码登录、注册、忘记密码三条流程共用 TAC 是产品硬要求,后端必须明确各自 `sceneCode`、provider/captchaType、票据一次性消费与过期/重放/限流规则,以及密码登录如何强制校验。
|
||||
- 新线上文档的 `722` 条路径中没有任何 `/genealogy/app/v2/`,`507` 个 schema 中没有 `LineageGraphWindow/LineageOverview/LineageLocator` 或 `schemaVersion/treeVersion/familyUnits/edges/rootVisibility/ancestorPathSegments/affected*Ids` 等辨识字段,`LINEAGE_QUERY_INVALID/LINEAGE_FOCUS_NOT_AVAILABLE/TREE_VERSION_CHANGED/RELATIONSHIP_PATCH_EMPTY` 也全部不存在。`tests/lineage-openapi-contract.ps1` 已对受保护 JSON/YAML 建立聚合红灯并证明四条目标操作和三个固定根模型同时缺失,因此不能解除 `API-T01-001` 门禁,也不能开始任务 12。
|
||||
- 已验证 `http://localhost:5173` 对 `/captcha/challenge` 的预检允许 `POST`、`content-type`、`clientid` 和 credentials;正式 H5 域名、App 原生请求、错误码与限流仍须分别验证,不能用本次预检替代上线验收。
|
||||
|
||||
### 2.10 认证与 TAC 后端缺口账本
|
||||
|
||||
认证客户端批次已经完成,但 `runtimeConfig.mode` 继续固定为 `mock`;下列问题关闭、后端提供同版本双导出并完成真实联调前,客户端不得切换远端或宣称登录注册可上线:
|
||||
|
||||
- `API-AUTH-TAC-001`:密码登录体尚无票据字段。后端必须让 `POST /genealogy/app/auth/login` 强制消费与短信发送相同安全语义、绑定 `APP_PASSWORD_LOGIN + tenant + client + canonical phone` 的短时单次票据。A01 已开放开发/联调 wire,但客户端先展示滑块不能充当服务端强制校验,故默认仍为 mock 且生产发布保持阻塞。
|
||||
- `API-AUTH-TAC-002`:2026-07-22 对真实 `APP_REGISTER` 请求只读联调时,`POST /captcha/challenge` 返回 HTTP 500 且响应体为空。后端必须修复并提供成功、无效场景、过期、限流和服务不可用的稳定错误 envelope;不得用客户端重试掩盖空 500。
|
||||
- `API-AUTH-TAC-003`:当前 `VerificationCheckBody` 未将 `providerCode/captchaType/payload` 全部声明为必填,根对象与 TianAi/SystemImage payload 也未关闭额外字段,且缺少以 evidence/provider 为 discriminator 的 `oneOf`。后端必须建立关闭额外字段的严格分支;客户端提交的 provider/type 不能替代 challenge 的服务端所有权。`tests/auth-tac-openapi-contract.ps1` 当前聚合六项结构缺口并输出 `AUTH-TAC-OPENAPI-CONTRACT BLOCKED`。
|
||||
- `API-AUTH-TAC-004`:验证码中心必须是唯一 owner。`/captcha/require` 返回服务端绑定 `tenant/client/scene/canonical subject/riskPolicyVersion` 的 `verificationSessionId`、允许方法和短时有效期;`required=false` 也必须直接返回可供短信端点原子消费的一次性 `validToken`。同一 session 只允许一个活动 challenge,刷新或切换方法立即作废旧题但不清零失败计数;`/captcha/verify` 只在服务端验证 evidence 并结合本地风险策略通过后签发票据,票据继续绑定 method/assurance/audience。`/sms/code` 必须在同一事务中完成 `ISSUED → CONSUMED` 与唯一短信 outbox 创建:相同幂等键返回原结果,并发或不同键重放不能创建第二个任务;跨手机号、场景、租户或客户端全部失败。
|
||||
- 无障碍不得成为降风控布尔开关:禁止 `accessibility=true`、`skipCaptcha`、检测 TalkBack 后放行、供应商故障时直接发短信,以及由客服绕过验证中心触发短信。P0 先落 provider-neutral 验证中心和支持屏幕阅读器、文字聊天/中继的可审计人工兜底;文字渠道只是通信媒介,各 `sceneCode` 仍须定义独立身份或号码控制证据。案件继承且不得改写原 session 的 subject/scene,具有去重、RBAC、主体/IP/设备/审核员限额、审计、服务时段、容量与 SLA,高风险找回或换号双人复核;坐席只提交决定,验证中心才可签票。异步案件和批准授权可在合理期限内恢复,用户重新进入原流程时才激活短时 `validToken`,避免通知前过期;不得要求用户证明残障。中国大陆非交互风控供应商只进入限时 POC,真实 UniApp Android WebView 必须证明 TalkBack、外接键盘、Switch Access、弱网、错误票据、误杀和攻击拦截门槛,达标后才可成为默认自动路径,不能预先宣称无障碍合规。只有此前在同一 subject 的已认证会话绑定私钥、服务端 nonce、RP/App 绑定、`userVerification=required`、短时单次且检查撤销的设备断言才可独立放行;普通设备指纹、完整性检测或仅 user-presence 只能加权,注册和未绑定设备不能使用。音频验证码必须另经可懂度、听障覆盖和 ASR 对抗 POC,不能单独上线或充当唯一替代。
|
||||
- 客户端当前只完成浮层壳层的对话语义、焦点进入/圈定/恢复、Escape/Android 返回、原生刷新/关闭、48px 目标与小视口滚动;第三方 TianAi 仍以指针拖动为主,不能据此宣称 TalkBack 可完成。`tests/auth-android-accessibility-release-gate.ps1` 在缺少非拖动等价路径与三人 MuMu 证据时固定输出 `ANDROID-AUTH-ACCESSIBILITY-RELEASE BLOCKED`。
|
||||
|
||||
### 2.11 F 系列线上写合同与上传阻塞
|
||||
|
||||
本节只记录 2026-07-22 从 `https://backend-api.ddxcjp.cn/v3/api-docs` 只读核对到的线上事实,不改写受保护的 `APP.openapi.yaml/json`,也不代表 F 页面已经接入写接口:
|
||||
|
||||
- 动态:`AppFamilyFeedBody.feedContent` 必填且 `minLength=1`,其余字段为 `feedType`、`mediaOssIds`、`sortOrder int64`、`status`。`AppFamilyFeedCommentBody.commentContent` 必填,但文档边界为 `minLength=0/maxLength=1000`,另有可选 `parentCommentId int64`;空字符串虽然被模型允许,产品页仍可采用更严格的非空校验,但适配器不能把页面规则误写成服务端约束。
|
||||
- 谱文与相册:`AppArticleBody.articleTitle/articleContent` 必填且均为 `minLength=1`,`categoryId/coverOssId/sortOrder` 为 int64;`AppAlbumBody.albumName` 必填且 `minLength=1`,`coverOssId/sortOrder` 为 int64。所有 int64 标识在客户端边界继续以词法字符串保存,只有合同已经消除歧义的请求适配器才可编码。
|
||||
- 上传初始化:`SysOssResumableInitBo` 的 `uploadId/fileName/fileMd5/totalSize/totalChunks/chunkSize` 六项必填;`fileMd5` 匹配 `^[a-fA-F0-9]{32}$`,三个大小或分片数均要求正整数。初始化响应的即时命中分支 `SysOssResumableInitVo.ossId` 是 int64。
|
||||
- 分片与完成:chunk 要求 query `uploadId/chunkIndex/chunkMd5` 和 multipart `file`;complete 的 `SysOssResumableCompleteBo` 要求 `uploadId/fileName/fileMd5/totalSize/totalChunks`,MD5 与正整数边界同初始化。
|
||||
- 硬阻塞:complete 返回的 `SysOssUploadVo.ossId` 被声明为 string,而创建照片的 `AppAlbumPhotoBody.ossId` 必填且声明为 int64;两条成功路径对同一对象存储标识给出冲突类型。后端统一类型或明确无损转换责任并重新导出同版本文档前,客户端不得自行 `Number()`、不得提交照片创建,也不得显示上传成功。F09 因此只能保留明确的本地预览。
|
||||
|
||||
### 2.12 R 系列线上接口与静态迁移边界
|
||||
|
||||
三位评审者已经同时从接口字段、业务闭环、异常交互和视觉风险审查 R01—R11。以下是 2026-07-22 线上 OpenAPI 证据与 Task8 静态批次边界,不表示页面已经调用真实接口:
|
||||
|
||||
- 人物:R01/R02 对应 `/genealogy/app/genealogies/{genealogyId}/lineage/persons` 与详情路径;搜索分页另有 `/page`,接收 `keyword/generation/personStatus` 和必填 `pageQuery`,返回 `TableDataInfoAppLineagePersonVo`。`AppLineagePersonBody` 只要求 `name`,页面旧 `role/legacy` 不是可靠请求字段;人物状态与写权限也没有正式字典或能力位。Task8 只复用树成员只读 owner,真实人物写入留到独立接口批次与 T01 v2 原子变更一并治理。
|
||||
- 人情往来:R03/R04 对应 `relative-records`,不是强制依赖 `ceremonyId` 的 ceremony gifts。请求只要求 `relativeName`,另有 `relationName/eventName/eventTime/giftAmount/recordContent/mediaOssIds`;模型没有收礼/送礼方向及金额币种语义,后端补齐或产品明确单向定义前不能声称完整礼账闭环。
|
||||
- 礼仪:R05—R07 对应 `ceremonies`,请求要求 `ceremonyTitle/ceremonyType`;`ceremonyType/status` 无正式枚举。邀请列表只有 `inviteeUserId/inviteStatus` 等字段,页面若展示姓名必须与同谱成员选项按用户 ID 受控联接,且“受邀人”不能直接写成“已参与者”。
|
||||
- 成长:R08 对应 `growth-records`,请求要求 `recordTitle`;页面必须额外强制 `lineagePersonId`,因为家谱级列表没有人物筛选参数。`recordType/status` 无枚举,不能据此在客户端发明分类。
|
||||
- 人生事:R09 没有独立线上端点,且 `growth-records.recordType` 没有枚举或人生事件值说明。后端提供正式合同前页面硬关闭,不读取、不写入、不展示 fixture 时间轴。
|
||||
- 备忘:R10 对应 `memos`,请求要求 `memoTitle`;`completed/status` 是无枚举字符串,也没有独立幂等切换端点或版本字段,Task8 禁止点击卡片本地翻转官方状态。
|
||||
- 功德:R11 对应 `merit-records`,请求要求 `donorName/meritTitle`;`meritType/status` 无枚举,`amount` 也没有币种、精度或非负边界。当前汇总只能来自只读列表,新增预览不得改变正式次数或金额。
|
||||
- 公共边界:上述接口都只说明“需要登录”,响应没有统一 `canCreate/canEdit/canDelete`;任何页面角色、创建人或 fixture 权限都不能冒充服务端授权。所有 int64 ID 保持词法字符串;未知实体、缺参、跨谱必须失败关闭。真实写接口未接入前,R 页只允许独立且明确未提交的本地预览,生产路由没有结果能力。
|
||||
|
||||
### 2.13 N/M 系列线上接口与静态迁移边界
|
||||
|
||||
三位评审者已同时核对页面流程、2026-07-22 线上 OpenAPI、异常交互和视觉风险。Task9 完成 N/M 安全导航与诚实静态边界;其后只有 M07 在独立 Task25 接入已核对的真实反馈 owner,其余页面仍未提前接入远端:
|
||||
|
||||
- 消息:Task29 把 `GET /genealogy/app/notifications` 与 unread-count 固定为独立读取批次:无筛选列表完整返回当前账号最多 200 条活动通知、最新优先,计数精确覆盖同一集合;首版 adapter 只公开 `snapshotKey/title/content/publishedAt/unread`,N02 由当前内存 generation+ordinal key 读取完整正文。Task30 单独约束两个已读 POST 的字符串 ID、幂等与 read-all 截止点。当前受保护双导出缺 unread-count 和专用模型,线上又无 required/enum/容量、ID 为 int64 且匿名行为与文档冲突,因此两项门禁均为红灯,见 5.6/5.7。首批删除所有通用目标 CTA;后端没有闭合 `bizType` 目标字典前,客户端不猜路由且永不执行服务端 URL。
|
||||
- 个人资料:Task28 固定 `GET /genealogy/app/auth/profile` 为 M01/M02/M03 唯一读取 owner。首批 wire 只 required canonical `phone`;`nickName/realName/email` 未设置时省略,出现时分别满足 1—30、1—30、email 且 1—100。adapter 立即掩码手机号并丢弃 `userId/avatar/status` 等未消费字段,当前 `PROFILE-OPENAPI-CONTRACT BLOCKED`,见 5.5。Task31 保留 PUT 为唯一 dirty-only merge owner,只允许脏的三项资料;省略保持,realName/email 精确空串清空,`profileVersion+If-Match+409` 防并发覆盖,当前 `PROFILE-UPDATE-OPENAPI-CONTRACT BLOCKED`,见 5.8。头像与 M05 换绑继续各自独立。
|
||||
- 密码与手机:Task33 已判定 `PUT /genealogy/app/auth/password` 和登录/注册/找回共用的 32 位十六进制 MD5 不可上线;四条入口须原子迁移到 raw writeOnly、15—64 Unicode/NFC、blocklist/限速/慢哈希。M04 200 前撤销包括当前设备在内的 ALL access/refresh session;unknown 也清本机回 A01,崩溃窗口由无秘密的 sessionEpoch marker 关闭,当前 `PASSWORD-CHANGE-OPENAPI-CONTRACT BLOCKED`,见 5.10。Task34 又固定 M05 为 currentPassword 再认证+新号 `APP_PHONE_CHANGE` TAC/6 位 OTP;换绑发码必须走专用 SaToken operation,最终 200 前换号、消费 OTP、提升 epoch、撤销 ALL session并持久化旧号通知,当前 `PHONE-CHANGE-OPENAPI-CONTRACT BLOCKED`,见 5.11。M04/M05 都不伪提交。
|
||||
- 家谱创建:Task35 否决空谱+通用人物两写,固定 G03 最终按钮一次 atomic bootstrap;访问规则同版统一为 accessPreset,地区只提交 selectable 项的词法 code,结果未知按 operationKey 精确查询且本地不存始祖 PII。当前 `G03-BOOTSTRAP-OPENAPI-CONTRACT BLOCKED`,见 5.12;通过前不接宽松 create API。
|
||||
- 家谱设置:Task38 保留唯一 PUT 但收紧为原子 dirty-only merge,`/overview` 是 fresh baseline 唯一读取 owner;`GenealogySettingsVersion+If-Match+409` 与 T01/M02 并发模型一致,PUBLIC_APPLY 关闭时与普通申请准入串行化。当前 `G11-SETTINGS-OPENAPI-CONTRACT BLOCKED`,见 5.15;后端绿只允许开始客户端 TDD,不允许直接接页。
|
||||
- 字辈集合:Task39 固定唯一 `appGetGenerationPoemSet/appUpdateGenerationPoemSet`、`GenerationPoemSetVersion+If-Match`、完整候选与 `FRESH_GET_THREE_WAY_NO_AUTO_PUT`;浏览器预检由 `APP_GATEWAY_PREFLIGHT` 唯一声明。当前 `G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`,见 5.16;页面保持本地预览。
|
||||
- 帮助与反馈:M06 首批固定 `GET /genealogy/app/help-articles` 为完整列表唯一 owner,不调用详情、不消费 `helpId`;adapter 只允许投影分类、标题和纯文本正文,分类由当前列表动态派生。受保护双导出仍是通用 `ListResult/RList`,线上专用模型又缺 required、正文格式、仅发布和顺序语义,匿名行为也与文档 401 冲突,因此 `HELP-CENTER-OPENAPI-CONTRACT BLOCKED` 保持红灯,详见 5.4。`AppFeedbackBody.feedbackContent` 必填,`feedbackType/contactInfo` 可选且无 enum;M07 已由 `appApi.submitFeedback` 精确 POST `/genealogy/app/feedback`,调用方不能关闭认证头,只接受 HTTP 200 与整数成功 `code`。mock 模式不伪提交;成功、确定失败、结果未知和迟到输入已分离。两页真实服务与 MuMu 验收都等待认证远端门禁关闭。
|
||||
- 邀请:`GET /genealogy/app/promotions` 只返回推广内容与通用 `targetUrl`,没有家谱邀请码签发、校验、失效或直接加入端点,不能支撑产品邀请闭环。M08 已删除硬编码码值、剪贴板和海报伪能力,并显示不可用;未来只能接入“校验成功直接加入且不生成审核记录”的单一路径。
|
||||
- VIP 与订单:线上存在套餐和订单的查询/创建端点,但当前文档未闭合支付方式、价格精度、订单状态、重复下单、支付回调、退款与续费语义。M09 不读取查询参数、不生成演示订单并保持不可用,待独立支付合规审查后再开放。
|
||||
- 退出:Task32 固定 `DELETE /genealogy/app/auth/logout` 只撤销当前 bearer credential family,其他设备保持有效;同 client 的 active/revoked/expired 凭证重复调用都收敛为同一 200,非法/client 不匹配为 typed 401。客户端未来由唯一 logoutCoordinator 在同一同步段捕获 A、清本地并 bump epoch、用显式 A 启动不随 M10 卸载取消的请求,然后立即进入 A01;迟到结果不再 clear。当前本地/线上合同都缺 required、范围/幂等/no-store 与复用反例,`LOGOUT-OPENAPI-CONTRACT BLOCKED`,见 5.9。
|
||||
|
||||
### 2.14 任务 36 普通加入申请合同边界
|
||||
|
||||
普通申请唯一流程为 G06 鉴权搜索 → G08 普通申请 → G09 mine/撤回,以及 G10 pending/审核;邀请码成功后直接加入且不生成审核记录,另立后续批次。七个稳定 owner 为 `appSearchPublicGenealogies`、`appCreateGenealogyJoinApplication`、`appGetGenealogyJoinApplicationRequest`、`appListMyGenealogyJoinApplications`、`appWithdrawGenealogyJoinApplication`、`appListPendingGenealogyJoinApplications`、`appReviewGenealogyJoinApplication`。所有 genealogyId/applyId 使用词法字符串,三个列表使用绑定 actor/filter 的稳定 cursor、limit 1—50、无 total。
|
||||
|
||||
搜索投影只保留识别家谱所需字段与单一 viewerState;mine 以 PENDING/APPROVED/REJECTED/WITHDRAWN discriminator 表达,只有拒绝分支必带申请人可见 rejectionReason;pending 精确为 `applyId/applicantName/relationDesc/applyReason?/submittedAt`,递归禁止 phone、user、inviter、auditor。申请体只含 `applicantName/relationDesc/applyReason?`,审核只含 APPROVE 或 REJECT+rejectionReason;统一 `JOIN_APPLICATION_TEXT_V1` 规范 NFC、边界空白和换行。
|
||||
|
||||
Idempotency-Key/requestKey 共用 `GenealogyJoinApplicationRequestKey`:`gja.{13 位毫秒时间}.{22—43 位 base64url CSPRNG}`,600 秒接受窗、300 秒未来偏差、120 秒 PENDING 收敛;canonical scope 包含 method/path/genealogyId/tenant/account/client/body。状态 GET 纯读且只返回 PENDING/SUCCEEDED/FAILED_NO_COMMIT。撤回和审核都用 `WHERE status=PENDING` CAS;批准同事务创建唯一成员并写终态。静态 OpenAPI 只能锁定合同,真实唯一约束、零写、fencing、事务和 HTTP/CORS 仍须部署集成反例。
|
||||
|
||||
当前 `tests/join-application-openapi-contract.ps1` 精确输出 `JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`;旧 G-series/core-flow 不再拥有 APP 加入 schema。后端门禁前 G06/G08/G09/G10 不接远端。后续接线必须删除 G10 手机号、三处消息中心承诺、LOCAL_WITHDRAWN 和遗留 adapter,并补状态机、无障碍与 MuMu 矩阵。
|
||||
|
||||
### 2.15 任务 37 邀请码签发与直接加入合同边界
|
||||
|
||||
邀请与普通申请是两个独立 owner。六个稳定 operation 为活动票据列表、无 body 幂等签发、撤销、JSON body 安全解析(无票据消费/成员写,仅轮换短时 grant 摘要)、无 body 直接兑换和兑换状态查询。真实流程固定为 M08 管理票据,G06 输入原码→resolve 最小可信目标与短时 redemption token→明确确认“直接加入、不经审核”→redeem→status 收敛→刷新 `/mine`→安装 context→G01/G05;不再进入 G08,不提交姓名/关系/理由,不创建申请、审核记录、人物或亲属关系。
|
||||
|
||||
首版票据固定单次、24 小时和至少 128 位随机量;原码只允许在 resolve body 与签发成功/同 key 600 秒恢复窗中出现,查找使用 HMAC,短时恢复使用隔离 KMS 密文。列表、撤销、兑换、status、错误、URL/query、导航、storage、日志/APM/分析均不得出现原码或 redemption token。签发 unknown 使用 `{sessionEpoch,genealogyId,requestKey,startedAt}` 重放原路径/key,不自动换 key;600 秒只限制不存在 key 的首次认领,已存在 key 在窗内返同码、窗后返同 ticket metadata+秘密不可恢复,不签第二码。resolve 可轮换一个 HMAC 摘要 grant但不消费票据,token 最多五分钟并绑定 tenant/account/client/ticket/version/genealogy/authorizationEpoch。
|
||||
|
||||
兑换使用敏感 header 与 `gir` key,在一个事务中重验票据、grant、权限、READY、功能、账号资格与容量,完成 ACTIVE→CONSUMED CAS、唯一 MEMBER 和 SUCCEEDED receipt;FAILED_NO_COMMIT 保证票据未消费且成员未建。已有普通 PENDING 返回 `ACTIVE_PENDING_APPLICATION`,用户先去 G09 撤回,邀请流程不得暗改任务 36。当前 `tests/invite-ticket-openapi-contract.ps1` 精确输出 `INVITE-TICKET-OPENAPI-CONTRACT BLOCKED`;后端门禁前 M08 保持不可用、G06/G08 保持诚实预览,不接虚构接口。
|
||||
|
||||
### 2.16 任务 38 G11 家谱设置版本化写入合同边界
|
||||
|
||||
G11 全局唯一写 owner 保留 `PUT /genealogy/app/genealogies/{genealogyId}`,operationId 为全局唯一 `appUpdateGenealogySettings`;不新增 PATCH、`/settings` 旁路或递归引用设置 body/字段的第二写入口,并删除重复 generic GET。G11 只消费 workspace owner 门禁结论,每次进入 fresh 调用 `/{genealogyId}/overview` 建立 canonical baseline,不能信任路由、`/mine` 卡片、旧 G05 内存、roleType 或 fixture。overview 与 PUT 200 共用精确 `{code,data}` 的 `RAppGenealogyVo`,不建立第二套 settings snapshot。共享 `GenealogyName` 统一创建/更新/读取为非 null、NFC、无边界空白、无换行或控制字符的 1—24 Unicode code point;`GenealogyIntro` 为非 null 精确空串或规范 1—80,正文只允许内部 LF 并拒绝 CR/tab/其他控制字符,空串清空、省略保持;accessPreset 仍只引用 `GenealogyAccessPreset`。
|
||||
|
||||
`AppGenealogySettingsUpdateBody` 关闭额外字段并只允许 1—3 个 `genealogyName/intro/accessPreset` 脏属性,服务端事务内重验管理权限并原子 merge;canonical no-op 返回当前 200、版本不升且无领域副作用。并发唯一使用 `AppGenealogyVo.settingsVersion` 和 required `If-Match`,body 不重复版本;版本以 `x-version-scope-fields` 锁定只随三个 canonical 设置实际变化。旧版本返回 typed 409 `GENEALOGY_SETTINGS_VERSION_CHANGED`+current `AppGenealogyVo`,不用 ETag/412;409 wrapper 只允许 discriminator+三个 exact local ref 分支。另两条 409 为 `GENEALOGY_NOT_READY` 与只在实际 `PUBLIC_APPLY→MEMBER_ONLY` 且有活动待审时返回的 `ACTIVE_PENDING_APPLICATIONS`;后者引导 G10、不自动处理申请,设置 PUT 与普通申请 POST 共同声明 `ATOMIC_SINGLE_WINNER` 并在事务内重验准入。
|
||||
|
||||
unknown 不新增 status owner,也不持久含谱名/简介的 body。客户端冻结 baseline/dirty/version/sessionEpoch,网络、超时、408、取消、5xx 或畸形 2xx 后 fresh 读 overview 对账,不自动 PUT;目标值一致只说明当前事实,不能证明本次请求成功。成功后原子回填 canonical 模型,失效 mine/overview/公开搜索/预览缓存并重验 context。响应与 parameter/response/header/schema 解析只接受 exact local component ref,Cache-Control 由单值 enum 固定。当前 `tests/g11-settings-openapi-contract.ps1` 稳定输出 `G11-SETTINGS-OPENAPI-CONTRACT BLOCKED`、48 项;本批不建占位 client gate,后端绿后的第一项写操作必须是实际执行生产 normalizer/coordinator 的纯 Node 失败测试。
|
||||
|
||||
### 2.17 任务 39 G12 字辈集合版本化保存合同边界
|
||||
|
||||
G12 唯一 aggregate owner 为 `GET/PUT /genealogy/app/genealogies/{genealogyId}/generation-poems`,operationId 为 `appGetGenerationPoemSet/appUpdateGenerationPoemSet`;旧 collection POST、逐行 PUT、batch preview/save、management 及其 schema/response 同版删除,不引入 preview token、服务端 preview/status。两条 200 共用 ACTIVE-only `GenerationPoemSetSnapshot {genealogyId,poemSetVersion,items}`,按 generationNo 严格升序;GET 重验 canView,PUT 事务内重验 tenant、canEditContent、READY 和版本。
|
||||
|
||||
`AppGenerationPoemSetUpdateBody` 精确 required `{items,disableMissing}`。声明行最多 500 且严格升序;已有行 poemId 必须来自 baseline ACTIVE,新行省略 ID,稳定 ID 可随显式 generationNo 移动。false 保留未声明 baseline ACTIVE,true 软停用遗漏项;空 false no-op,空 true 停用全部。服务端先执行 `VALIDATE_DECLARED_STRICT_ORDER`,再构造声明目标与 merged candidate,随后执行 ID/世代唯一、`GENERATION_SLOT_CONFLICT`、连续性、`VALIDATE_FINAL_ACTIVE_CAPACITY`、`ALLOCATE_UNIQUE_NEW_IDS` 及新 ID 非空/唯一/非 baseline 校验;swap 显式声明所有受影响行并原子成功或零写,历史不物理删除。generationText 可重复,但每项必须 NFC、1—50 Unicode code point、well-formed 且拒绝边界空白、控制/bidi/zero-width/孤代理。
|
||||
|
||||
唯一并发 owner 为 `GenerationPoemSetVersion+If-Match`,body 不复制版本,不用 ETag/412;no-op 保持版本,ACTIVE 语义变化生成永不复用的新版本。unknown 以 baseline/version、declaredItems 和 disableMissing 构造 effective target,按 `FRESH_GET_THREE_WAY_NO_AUTO_PUT` fresh GET:existing 比较 ID+generation+NFC 文本,NEW 比较 generation+文本并要求返回 ID 新鲜;同基数且无额外 ACTIVE 行才相等。先执行 `CURRENT_EQUALS_TARGET_FIRST_NO_ATTRIBUTION`,只陈述当前事实;再判 old,否则 divergent,全部不自动 PUT。
|
||||
|
||||
响应只允许 typed JSON、private/no-store,429 带 Retry-After;SaToken security 必须是 JSON 数组,clientid 非空。顶层 `x-app-gateway-policies.APP_GATEWAY_PREFLIGHT` 是唯一 CORS 声明 owner,精确包含 Authorization/Content-Type/If-Match/clientid、GET/PUT/OPTIONS、显式 origin allowlist 与 600 秒;发布仍须真实 OPTIONS/preflight。当前主门禁输出 `G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`Issues: 72`;zero issues seed 与严格大小写/ref/security/annotation 反例输出 `G12-GENERATION-POEM-OPENAPI-ADVERSARIAL-CONTRACT PASS`,Unicode 输出 `G12-GENERATION-POEM-UNICODE-RUNTIME-SMOKE PASS`。后端绿前 G12 保持本地预览;绿后第一项客户端写操作必须是可执行生产 normalizer/coordinator 失败测试,再原子删除 fixture/timer/本地成功和旧合同。
|
||||
|
||||
### 2.18 任务 40 F01/F03 家族动态读取合同边界
|
||||
|
||||
本批只拥有 F01 动态列表、F03 动态详情和正常一级评论读取。唯一 owner 为 `GET /genealogy/app/genealogies/{genealogyId}/feeds`、`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}`、`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments`,operationId 为 `appListFamilyFeeds/appGetFamilyFeed/appListFamilyFeedRootComments`;删除两个 `/page` GET。发布、点赞、评论/回复写、回复读与媒体文件读分别留给后续独立批次。受保护双导出和线上 3.1.0 当前仍有双 owner、int64、通用/开放 response;线上评论 DTO 还含手机号、业务用户 ID 和审核字段,故不得接页。
|
||||
|
||||
`AppFamilyFeedReadItem` closed required `{feedId,feedContent,authorDisplayName,publishedAt,hasMedia}`,`AppFamilyFeedRootCommentReadItem` closed required `{commentId,commentContent,authorDisplayName,publishedAt}`。ID 均为 1—128 位词法字符串;正文非 null 且有界;publishedAt 为服务端生成的不可变 RFC3339;作者只返回授权展示名和非空退化文案。评论只含正常可见一级评论,不含 reply/删除占位/parent/level/status/审核字段。标题、标签、点赞和总评论数不是本批合同。`hasMedia=true` 时客户端在媒体读取合同前展示诚实占位,不泄露或解析 mediaOssIds,不把附件静默丢失。
|
||||
|
||||
两个列表使用默认 20、范围 1—50 的 opaque cursor,无 total/pageNum。feed 排序为 `publishedAt:DESC,feedId:DESC_ORDINAL`,comment 为 `publishedAt:ASC,commentId:ASC_ORDINAL`;`UPPER_BOUND_KEYSET_LATEST_VISIBLE` 只固定上界并排除刷新前的新头部内容,后续删除/隐藏项省略、可见编辑返回该页读取时的最新内容,不宣称 MVCC snapshot。cursor 绑定 actor/session/client、谱/动态、projection/order/limit/windowUpperBound/lastTuple;每页重验 tenant、membership、feed 归属与可见性,篡改/过期 typed 400,错谱、跨主体、撤权、删除或隐藏统一 `404 FAMILY_FEED_NOT_AVAILABLE`。
|
||||
|
||||
三个 GET 精确 200/400/401/404/429/500 typed JSON,全部 private/no-store,429 带 Retry-After,required SaToken/clientid 并复用 `APP_GATEWAY_PREFLIGHT`。当前 `tests/family-feed-read-openapi-contract.ps1` 输出 `FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED`、`Issues: 85`;zero issues 合法种子和 58 个 ref/大小写/PII/int64/offset/HTTP/cache 变异由 `tests/family-feed-read-openapi-adversarial-contract.ps1` 证明为 `FAMILY-FEED-READ-OPENAPI-ADVERSARIAL-CONTRACT PASS MUTANTS=58`。后端绿前保持复合身份 fixture,禁止连接 dormant 宽 `getFeeds` 或失败回退 fixture。后端同版本 JSON/YAML/live 通过后,客户端首写先建立直接执行生产 read normalizer/coordinator 的失败测试,再原子迁移 F01/F03 和无障碍/异常状态。
|
||||
|
||||
## 三、52 个活动页面映射
|
||||
|
||||
表中“返回或完成目标”描述业务意图,不表示现有导航 API 已经正确;导航栈阶段需要用源码扫描、测试和 MuMu 完整流程逐项验证。A04、G 系列第一轮、F 系列当前写边界、T01 和新线上差异已形成专项证据;其余接口列继续标记“待对应业务阶段 OpenAPI 审查”,避免把旧思维导图、页面 mock、旧离线快照或 PC 接口误当成当前 App 合同。
|
||||
|
||||
| 编号 | 页面 | 路由 | 当前业务目标 | 主要进入方式 | 返回或完成目标 | 必测状态 | 接口业务域 | 当前接口核对状态 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| A01 | 登录 | `pages/auth/a01-entry` | 完成密码/短信认证并处理协议;微信待合同关闭 | APP 启动、凭证失效、主动退出 | 成功进入 G01;取消或失败留在本页 | 密码、短信、协议错误、TAC、发送中、倒计时、请求取消、登录失败、凭证过期 | 认证与账户 | 密码登录线上 wire 与 `AppLoginVo.access_token` 已接入,默认 mock;`validToken` 未由登录接口消费,`API-AUTH-TAC-001` 仍阻止生产发布,见 2.10 |
|
||||
| A04 | 注册账号 | `pages/auth/a04-register` | 建立新账号并确认协议 | A01 注册入口 | 成功建立登录态并进入 G01;取消返回 A01 | 本地校验、TAC、短信、注册中、手机号占用、成功、失败、取消 | 认证与账户 | `APP_REGISTER`、4 位码、`RAppLoginVo → AppLoginVo.access_token` 客户端链已落地;真实 challenge 与 OpenAPI 仍红灯,见 2.10 |
|
||||
| A05 | 重设密码 | `pages/auth/a05-reset-password` | 验证手机号并设置新密码 | A01 忘记密码 | 成功返回 A01 的密码登录态;取消返回 A01 | 4 位码、TAC、密码策略、不一致、提交中、成功、失败、取消 | 认证与账户 | `APP_FORGOT_PASSWORD` 客户端链已落地;真实后端、Android 可访问替代与 MuMu 仍红灯,见 2.10 |
|
||||
| G01 | 我的家谱 | `pages/genealogy/g01-my-genealogies` | 选择全局家谱并完成加入或创建分流 | 登录成功、根 Tab、业务完成回流 | 进入 G03、G05、G06、G09、G10、G12、T01 或 N01 | 正常、空、加载、失败、审核中、被拒绝、退出或移除、切换弹层、未读消息 | 家谱、成员关系与通知计数 | Task26 工作区红灯已建立;`/mine` 尚未接远端,见 2.8/5.3;Task29 unread-count 红灯要求与 M01 共用唯一未读数 owner,见 2.13/5.6 |
|
||||
| G03 | 创建家谱 | `pages/genealogy/g03-create-genealogy` | 在同页收集家谱与始祖并最终原子创建 | G01 创建入口 | 门禁前进入 G05 本地预览;生产成功按 receipt→mine cache→context→G05 唯一次序收口,放弃零写 | 地区加载/失败、重复建议、始祖校验、提交中、PENDING、结果未知、fatal/quarantined、已提交待进入、放弃确认 | 家谱与成员关系 | Task35 已建立 atomic bootstrap、无 PII operation-status、统一 accessPreset、APP 可信地区与词法 ID 的后端/客户端双红灯;开放还依赖 Task26 workspace 与 MuMu,见 2.8/5.12 |
|
||||
| G05 | 家谱总览 | `pages/genealogy/g05-genealogy-overview` | 按公开预览、成员、所有者或本地预览浏览身份、来源和可信度 | G01、G06、G09、G03 本地预览 | 返回实际来源;按权限进入 T01、G08、G10、G11、G12 或 F01 | 公开预览、成员视图、所有者、本地预览、加载、空、失败、无权限 | 家谱与权限 | Task26 选定 `/overview` 为唯一 owner;最小 schema、对象级授权和错误语义未关闭,丰富首屏字段另待取舍,见 2.8/5.3 |
|
||||
| G06 | 加入家谱 | `pages/genealogy/g06-search-genealogies` | 普通搜索,或解析邀请码后明确确认并直接加入 | G01 空态或添加家谱弹层 | 普通搜索按 viewerState 进入 G05/G08/G09;邀请成功刷新 workspace/context 后进入 G01/G05 | 搜索六关系;邀请码输入、格式错、解析、目标、确认、PENDING/unknown、已加入、普通申请冲突、失效、限流 | 普通搜索与独立邀请 | Task36 搜索见 2.14/5.13;Task37 六 operation 邀请红灯见 2.15/5.14,门禁前不接远端 |
|
||||
| G08 | 关系确认与入谱 | `pages/genealogy/g08-join-application` | 只提交普通加入申请;真实接线时删除全部 invite source | G06、G05 或 G09 的普通申请入口 | 普通申请成功刷新 G09 | 不可申请、字段校验、PENDING、unknown、成功、失败、放弃 | 普通加入申请 | Task36 后端红灯见 2.14/5.13;Task37 明确邀请不得进入 G08,现有 invite 预览待接线时原子删除 |
|
||||
| G09 | 我的申请 | `pages/genealogy/g09-my-applications` | 查看四状态申请并撤回或重新申请 | G01、G08、G06 审核中 | 已通过进入 G05;拒绝/撤回可重新申请;unknown 刷新 mine | 列表、空、失败、待审、通过、拒绝、撤回、重新提交 | 加入申请 | mine 四状态、拒绝原因和撤回 CAS 由 Task36 门禁拥有;消息中心承诺待接线时删除 |
|
||||
| G10 | 入谱审核 | `pages/genealogy/g10-application-review` | 审核不含手机号的 pending 最小投影 | G01 或 G05;首版不承诺通知目标 | 审核后刷新 pending;行消失只称状态变化 | 列表、空、失败、通过确认、拒绝原因、提交中、无权限、竞态冲突;拒绝字段保留 `aria-describedby`、错误关联与失败聚焦 | 加入审核与权限 | Task36 固定 APPROVE/REJECT、PENDING CAS 与事务权限重验;手机号节点待接线时原子删除 |
|
||||
| G11 | 家谱设置 | `pages/genealogy/g11-genealogy-settings` | 门禁前本地维护;生产目标原子更新名称、访问预设和简介 | G05 管理入口,进入后 fresh overview 鉴权 | 门禁前只更新本页预览;生产成功 canonical 回填、刷新缓存/context 后回 G05 或撤权回 G01 | loading、dirty、saving、validation、saved、unknown 对账、三类 409、无权限、认证失效、不可用、未保存返回 | 家谱设置与权限 | Task38 已建立唯一 merge PUT、settingsVersion/If-Match、409 three-way、待审串行化与 unknown 红灯;页面尚未接远端,见 2.16/5.15 |
|
||||
| G12 | 字辈诗 | `pages/genealogy/g12-generation-poems` | 分批浏览并本地维护完整字辈序列 | G01 快捷入口或 G05 | 门禁前保存只更新本地列表;生产成功 canonical 回填并刷新消费者 | loading、空、编辑、校验、saving、saved、unknown、版本/READY 冲突、无权限、0/1/500×50、swap、软停用历史 | 字辈与权限 | Task39 已建立唯一 GET/PUT、poemSetVersion/If-Match、完整候选集合、unknown 与 CORS owner 红灯;页面尚未接远端,见 2.17/5.16 |
|
||||
| T01 | 世系树 | `pages/tree/t01-tree-overview` | 以当前成员为焦点阅读可扩展世系窗口,并在图、概览和线性列表间定位成员 | G01 快捷入口或 G05 | 返回来源;进入单实例 T03、T04、T06、T07 | 上二代/下二代初始窗口、搜索、四级 LOD、多配偶联合点、宽支系聚合、代际缺口、四类边界、图/列表、空、失败、版本冲突、500 节点性能;节点与线由同一 Canvas/矩阵/帧绘制 | 世系与成员 | 专项已核对:现有递归 `LineagePersonTreeView` 不满足;待后端按规范图窗口问题单更新 Apifox |
|
||||
| T03 | 成员档案 | `pages/tree/t03-member-profile` | 在单个原生页面实例内查看成员资料、亲属与受控状态 | T01、T07、R02 的成员关联 | 页内成员轨迹优先返回;轨迹结束后回实际来源;进入 T05、T08 | A→B→C→B→A 页内轨迹、可编辑、隐私、无权限、成员缺失、加载失败、离世状态;读取成功后才推进轨迹 | 成员档案与权限 | 待对应业务阶段 OpenAPI 审查 |
|
||||
| T04 | 新增亲属 | `pages/tree/t04-add-relative` | 录入首位成员或为目标成员新增亲属 | T01 指定节点或空树入口 | 当前只生成“尚未提交服务器”的本地预览,确认放弃后无结果回 T01;真实写成功后才定位新成员 | 首位成员、普通亲属、关系选择、必填、长摘要、保存中、本地预览、失败、放弃确认 | 成员与亲属关系 | 待对应业务阶段 OpenAPI 审查 |
|
||||
| T05 | 编辑成员 | `pages/tree/t05-edit-member` | 修改指定成员身份和生平资料 | T03 编辑入口 | 当前本地预览确认放弃后用 `goBack()` 回原 T03 实例且不产生结果;真实写成功后才刷新当前活动成员 | 加载、字段校验、长简介、保存中、本地预览、失败、无权限、放弃确认 | 成员档案与权限 | 待对应业务阶段 OpenAPI 审查 |
|
||||
| T06 | 编辑关系 | `pages/tree/t06-edit-relationship` | 校正两个现有成员之间的关系 | T01 关系操作 | 当前只生成“尚未提交服务器”的本地预览,确认放弃后无结果回 T01;真实写成功后才刷新关系 | 成员选择、校验、冲突、循环关系、冲突规则弹窗、保存中、本地预览、失败、无权限 | 亲属关系与权限 | 待对应业务阶段 OpenAPI 审查 |
|
||||
| T07 | 成员目录 | `pages/tree/t07-member-directory` | 搜索、筛选并选择家谱成员 | T01 成员目录入口 | 进入 T03;返回 T01 并恢复目录现场 | 完整列表、筛选、搜索无结果、明确空态、失败重试、加载、长列表、成员选择 | 成员查询 | 待对应业务阶段 OpenAPI 审查 |
|
||||
| T08 | 成员状态 | `pages/tree/t08-member-states` | 解释成员隐私、纪念或无权限状态 | T03 人物状态入口 | 返回 T03;家谱不可用时回 G01 | 隐私隐藏、离世纪念、无权限、无效成员、权限变化 | 成员状态与权限 | 待对应业务阶段 OpenAPI 审查 |
|
||||
| F01 | 家族动态 | `pages/family/f01-family-feed` | 按当前成员家谱展示动态并承载内容和档案入口 | 根 Tab 或 G05 | URL 已规范化后进入 F02—F04、F07、F10、R01、R03、R05、R10、R11 | 加载、列表、空、失败、无有效家谱、跨谱失败关闭 | 家族内容聚合 | Task40 已建立唯一 cursor GET、无 PII 投影、逐页鉴权与非泄露 404 红灯;后端绿前保持 fixture,见 2.18/5.17 |
|
||||
| F02 | 发布动态 | `pages/family/f02-publish-feed` | 编辑文字或媒体动态的本地预览 | F01 发布入口 | 预览不发布、不产出结果;取消保留或确认放弃后回同一 F01 | 表单、空内容校验、长内容、媒体权限、本地预览、无权限、放弃确认 | 动态发布与上传 | 线上写请求要求 `feedContent` 且 minLength=1,另有 `feedType/mediaOssIds/sortOrder/status`;真实调用与媒体上传未启用,mock 以 `WRITE_UNAVAILABLE` 失败关闭,详见 2.11 |
|
||||
| F03 | 动态详情 | `pages/family/f03-feed-detail` | 按 `genealogyId + feedId` 阅读动态并编辑评论草稿 | F01 动态卡 | 评论只在本页预览,不插入、不计数、不清空;返回同一 F01 | 加载、正常、内容失效、失败、评论校验、本地预览、无权限 | 动态与评论 | Task40 已拆分详情与一级评论 cursor owner;后端绿前保持 fixture,评论写仍只做未提交预览,见 2.18/5.17 |
|
||||
| F04 | 谱文列表 | `pages/family/f04-article-list` | 按家谱分类、搜索和浏览谱文 | F01 谱文入口 | 进入精确 F05 或 create 模式 F06;返回同一 F01 | 加载、列表、分类、搜索无结果并重置、空、失败、长列表、新建权限 | 谱文 | 任务 7 已核对线上列表及写接口;当前列表由唯一只读 owner 提供深拷贝 |
|
||||
| F05 | 谱文详情 | `pages/family/f05-article-detail` | 按 `genealogyId + articleId` 阅读并按权限进入编辑 | F04 谱文卡 | 返回同一 F04;有权限进入 edit 模式 F06 | 加载、正常、收藏暂未开放、编辑、失效、隐私、失败、无权限 | 谱文与权限 | 线上未证明收藏合同,当前禁用收藏;文章写请求要求 `articleTitle/articleContent` 且均为 minLength=1,详见 2.11 |
|
||||
| F06 | 编辑谱文 | `pages/family/f06-article-editor` | 新建或编辑谱文的本地预览 | F04 新建或 F05 编辑 | create 回 F04,edit 回精确 F05;预览不保存、不产出结果 | 新建、编辑、校验、加载、本地预览、失败保留、长正文、放弃确认 | 谱文编辑 | 线上 POST/PUT 已存在,`categoryId/coverOssId` 为 int64;真实调用未在导航批次启用,详见 2.11 |
|
||||
| F07 | 相册列表 | `pages/family/f07-album-list` | 按家谱浏览相册并制作独立的新相册预览 | F01 相册入口 | 正式相册进入 F08;本地预览不插入列表;返回同一 F01 | 加载、列表、长列表、空、失败、创建弹窗、本地预览、校验、权限、放弃确认 | 相册 | 线上创建要求 `albumName`;当前不调用写接口、不伪增列表或计数 |
|
||||
| F08 | 相册详情 | `pages/family/f08-album-detail` | 按 `genealogyId + albumId` 浏览照片墙和相册信息 | F07 相册卡 | 先关闭照片预览,再返回 F07;进入同一相册的 F09 | 加载、照片墙、末张预览、Android 返回先关预览、空相册、相册失效、失败、权限 | 相册与媒体 | 任务 7 已核对;当前严格按复合身份读快照,未知或跨谱相册不回退首条 |
|
||||
| F09 | 上传照片 | `pages/family/f09-media-upload` | 选择照片并填写批量及逐张说明的本地预览 | F08 添加照片入口 | 预览不上传、不生成成功态;取消确认放弃后回同一 F08 | 初始、权限、最多九张、增删、独立说明、必填、本地预览、放弃确认、无效相册 | 媒体上传 | 旧 `/files/upload` 已下线;resumable init/chunk/complete 的 complete 返回 `ossId` 为 string,而照片创建要求 int64;后端消除类型冲突前不得转换或提交,详见 2.11 |
|
||||
| F10 | 家族视频 | `pages/family/f10-video-list` | 按有效家谱说明当前视频服务尚未开放 | F01 视频入口 | 当前只返回同一 F01 | 待开放、无效家谱、返回 F01;未来能力不冒充当前功能 | 视频服务 | 任务 7 未发现可支撑当前页面闭环的已启用视频产品合同,保持关闭 |
|
||||
| R01 | 人物录 | `pages/records/r01-people-list` | 按当前家谱搜索和浏览人物只读快照 | F01 人物录入口 | 进入带精确家谱与模式的 R02;返回 F01 | 加载、列表、搜索、无结果、空、失败、分页、跨谱失败 | 人物记录 | 任务 8 已核对 `lineage/persons/page`;ID 必须保持词法字符串,真实分页尚未接入 |
|
||||
| R02 | 人物详情 | `pages/records/r02-person-detail` | 查看人物或制作不写库的新建/编辑预览 | R01 人物卡或预览入口 | 预览不产出结果;进入 R08 或硬关闭的 R09;取消回来源 | 查看、新建、编辑、校验、预览、隐私、失效、跨谱 | 人物记录与权限 | 任务 8 已核对 `AppLineagePersonBody`,`name` 必填;真实写入未启用,权限字典待补 |
|
||||
| R03 | 贺礼簿 | `pages/records/r03-gift-list` | 浏览同谱人情往来只读快照 | F01 贺礼簿入口 | 进入携带 `relativeId` 的 R04;返回 F01 | 加载、列表、空、失败、跨谱 | 人情往来 | 任务 8 已核对 `relative-records`,不是 ceremony gifts;收礼/送礼方向语义仍缺 |
|
||||
| R04 | 贺礼编辑 | `pages/records/r04-gift-editor` | 查看往来记录或制作不写库的本地预览 | R03 记录或预览入口 | 预览不插入列表、不删除记录;取消回来源 | 查看、新建、编辑、校验、本地预览、无效实体、跨谱 | 人情往来与权限 | 任务 8 已核对 `relativeId` 与 `relativeName` 必填;真实写入未启用,只允许本地预览 |
|
||||
| R05 | 礼仪列表 | `pages/records/r05-ritual-list` | 浏览同谱礼仪活动只读快照 | F01 礼仪入口 | 进入 R06 或 R07 预览;返回 F01 | 加载、列表、空、失败、活动展示、跨谱 | 礼仪活动 | 任务 8 已核对 ceremonies,`ceremonyTitle/ceremonyType` 必填且类型、状态无正式枚举 |
|
||||
| R06 | 礼仪详情 | `pages/records/r06-ritual-detail` | 查看精确礼仪与受邀人快照 | R05 活动卡 | 返回 R05;进入同一礼仪 R07 | 加载、详情、受邀人、失败、失效、跨谱 | 礼仪活动与邀请 | 任务 8 已核对 invitations;姓名需与成员选项受控联接,不能把受邀者冒充参与者 |
|
||||
| R07 | 礼仪编辑 | `pages/records/r07-ritual-editor` | 制作新建或编辑礼仪的本地预览 | R05 预览入口或 R06 编辑入口 | create 预览回 R05,edit 预览回原 R06;不产出结果 | 新建、编辑、校验、本地预览、无效实体、跨谱 | 礼仪活动与权限 | 任务 8 已核对 `ceremonyId`;必填与枚举见 R05,真实写入未启用 |
|
||||
| R08 | 成长日志 | `pages/records/r08-growth-journal` | 按同谱人物展示成长快照并制作独立预览 | R02 或 T03 人物入口 | 预览不插入正式时间轴;返回实际人物来源 | 加载、时间轴、空、失败、预览弹窗、必填、跨谱 | 人物成长记录 | 任务 8 已核对 growth-records;客户端必须强制 `lineagePersonId`,`recordType` 无枚举 |
|
||||
| R09 | 人生事 | `pages/records/r09-life-events` | 明确说明人生事件服务当前不可用 | R02 或 T03 人物入口 | 不读取或写入成长记录;安全返回人物来源 | 接口缺失、无效人物、返回来源 | 人生事件 | 任务 8 已核对:没有独立人生事件接口,后端补端点或正式类型字典前硬关闭 |
|
||||
| R10 | 家族备忘 | `pages/records/r10-memo-list` | 浏览同谱备忘快照并制作独立预览 | F01 备忘入口 | 预览不插入列表、不切换正式完成状态;返回 F01 | 加载、列表、空、失败、预览、跨谱 | 家族备忘 | 任务 8 已核对 memos,`memoTitle` 必填而 `completed` 无枚举,真实切换未启用 |
|
||||
| R11 | 功德记录 | `pages/records/r11-merit-records` | 浏览只读汇总并制作独立贡献预览 | F01 功德录入口 | 预览不改变正式汇总或列表;返回 F01 | 加载、汇总、列表、空、失败、预览、跨谱 | 功德与贡献 | 任务 8 已核对 merit-records,`donorName/meritTitle` 必填,类型、状态与金额边界无枚举 |
|
||||
| N01 | 消息中心 | `pages/notification/n01-message-center` | 展示当前账号完整活动通知快照与服务端读状态,不猜业务目标 | G01 或 M01 消息入口 | 以当前内存 `snapshotKey` 进入 N02;返回来源 | 加载、未读、已读、空、失败重试、认证失效、长内容、并发刷新 | 消息与通知 | Task29 读取红灯已建立;完整活动集合、专用 required、纯文本、时区、二值状态和计数同域待关闭,见 2.13/5.6;Task30 前不得本地伪写 |
|
||||
| N02 | 消息详情 | `pages/notification/n02-message-detail` | 从当前 generation 的内存快照展示完整纯文本正文,不持有服务端 ID | N01 消息卡 | 返回 N01;无快照时提示从消息中心重新打开,不跳业务页 | 加载、详情、无快照、认证失效、长正文、读状态写入待开放 | 消息与通知状态 | Task29 选定 list-owned snapshot 且删除目标 CTA;Task30 独立约束私有字符串 ID 与幂等写入,见 2.13/5.6/5.7 |
|
||||
| M01 | 我的 | `pages/profile/m01-profile-home` | 展示脱敏账号身份并保持通知、服务与设置入口可达 | 根 Tab | 进入 M02、M03、M06、M08、M09、M10 或 N01 | 身份与通知局部加载、正常、失败重试、认证失效、未读数不可用、服务可用性 | 个人中心聚合 | Task28 profile GET 红灯保证身份失败不锁菜单,见 2.13/5.5;Task29 unread-count 红灯删除 fixture 伪数并统一“未读消息”,见 2.13/5.6 |
|
||||
| M02 | 个人资料 | `pages/profile/m02-edit-profile` | 从唯一 profile owner 初始化并以版本化 dirty-only merge 保存昵称、真实姓名和邮箱 | M01 资料入口 | 成功应用权威响应并留在本页;放弃确认后回 M01 | 加载、失败重试、认证失效、异步 baseline、字段校验、保存、结果未知、版本冲突、账号切换、头像未接入 | 用户资料 | Task28 读取红灯仍是前置;Task31 已建立 PUT merge、清空、If-Match、typed response 和 409 红灯,头像不混入,见 2.13/5.5/5.8 |
|
||||
| M03 | 账号与安全 | `pages/profile/m03-security-settings` | 展示密码入口与脱敏绑定手机号,不伪造设备安全结论 | M01 安全入口 | 进入 M04 或 M05;返回 M01 | 手机号局部加载、正常、失败重试、认证失效、功能受限 | 账号安全 | Task28 已建立 profile GET 红灯;普通读取失败不得阻断密码入口,设备状态仍无合同,见 2.13/5.5 |
|
||||
| M04 | 修改密码 | `pages/profile/m04-change-password` | 以当前密码重新认证并安全更新统一密码凭证;门禁前保持本地预览 | M03 密码入口 | 确定错误留页;200/401/409/结果未知清本机并回 A01;放弃确认回 M03 | 空字段、15/64 边界、Unicode/NFC、blocklist、当前错误、并发、限流、提交中、结果未知、进程终止 | 账号安全与会话 | Task33 已建立 raw writeOnly、ALL 会话撤销、typed 错误与 session marker 红灯;四条密码 wire 必须同批迁移,见 2.13/5.10 |
|
||||
| M05 | 修改手机号 | `pages/profile/m05-change-phone` | 以当前密码重新认证,并通过受保护 TAC/6 位 OTP 验证新号码;门禁前保持本地预览 | M03 手机号入口 | 确定错误留页;最终 200/401/409/结果未知清本机回 A01;放弃确认回 M03 | 当前密码、新号、TAC、发送与倒计时、6 位码、占用、限流、提交中、并发、结果未知、进程终止 | 账号安全、短信与会话 | Task34 已建立专用 SaToken 发码、全活动六位码、ALL 会话撤销、outbox 与 credential marker 红灯;依赖 M04 raw wire,见 2.13/5.11 |
|
||||
| M06 | 帮助中心 | `pages/profile/m06-help-center` | 从完整帮助列表搜索、分类并展开纯文本正文,无法解决时进入反馈 | M01 帮助入口 | 返回 M01;无法解决时进入 M07 | 加载、服务端空、分类、搜索无结果、展开、失败重试、认证失效、取消 | 帮助内容 | Task27 选定列表唯一 owner 并建立红灯;专用 required、纯文本、仅发布、顺序和认证语义待后端关闭,见 2.13/5.4 |
|
||||
| M07 | 意见反馈 | `pages/profile/m07-feedback` | 通过唯一真实 owner 提交必填内容及可选类型、联系方式 | M06 联系入口 | 成功留页保留提交快照;编辑后可再提交;未提交修改放弃确认回 M06 | 必填、提交中、成功防重、失败、结果未知、mock 不可提交、未保存返回 | 用户反馈 | Task25 已接 `POST /genealogy/app/feedback` 严格客户端;remote 实测与 MuMu 待认证门禁关闭,见 2.13 |
|
||||
| M08 | 邀请家人 | `pages/profile/m08-promotion` | 从 workspace 选择有正式邀请权限的家谱并管理单次活动票据 | M01 推广入口 | 签发、显示/复制/系统分享、撤销;返回 M01 | 加载、无权限、无票据、签发/unknown、原码恢复窗、即将过期、撤销/竞态、权限失效 | 家谱邀请与系统分享 | Task37 六 operation 邀请红灯见 2.15/5.14;通过前保持不可用且不展示假码 |
|
||||
| M09 | VIP 与订单 | `pages/profile/m09-vip-orders` | 展示基础说明并明确订单服务当前不可用 | M01 服务入口 | 查看关闭说明;返回 M01 | 服务未开放、无订单数据、说明弹层 | 服务权益、订单与支付 | 套餐/订单端点存在但支付闭环未定义,已删除查询参数演示订单,见 2.13 |
|
||||
| M10 | 关于家谱 | `pages/profile/m10-about-settings` | 从 manifest 展示版本和协议说明,并安全退出当前设备凭证族 | M01 设置入口 | 协议/退出取消留在本页;确认后立即清本机并回 A01,远端结果只更新一次性提示 | 版本、协议、隐私、退出确认、双击、pending、撤销确认/未确认/拒绝、账号竞态、根导航失败 | 配置、协议与认证 | Task9 已完成本机清理基线;Task32 已建立当前凭证族、幂等 200、logoutCoordinator、required RVoid 与部署复用红灯,见 2.13/5.9 |
|
||||
|
||||
## 四、封存与已移除页面
|
||||
|
||||
| 页面 | 当前决定 | 合同边界 |
|
||||
| --- | --- | --- |
|
||||
| A02 账号登录 | 已完整并入 A01,不保留兼容路由 | 任何注册、重设或退出后的登录目标统一指向 A01 |
|
||||
| A03 | 已移除 | 不恢复无明确业务职责的历史入口 |
|
||||
| A06 登录状态 | 源码保留、活动路由封存 | 未来只有账号冻结、停用或风险限制等无法继续登录的阻断状态,且产品重新确认独立页面后才能恢复 |
|
||||
| G02 | 并入 G01 空状态 | 搜索、邀请码加入和创建三个入口由 G01 空状态承载 |
|
||||
| G04 | 并入 G03 始祖步骤 | 创建家谱与录入始祖属于同一可恢复流程 |
|
||||
| G07 | 并入 G06 | 搜索、筛选、结果与无结果均由 G06 双模式承载 |
|
||||
| T02 | 并入 T01 | 世系阅读提示、空态和失败态不再拆分独立路由 |
|
||||
|
||||
## 五、后续接口审查填充规则
|
||||
|
||||
每个对应业务阶段都必须先解析并比对两份 OpenAPI 导出,再按三人独立首审、交叉补漏、反向质询和共同收敛的顺序更新本文件。每个页面和用户操作都要补齐以下事实:
|
||||
|
||||
1. 接口分类:App 可直接使用、PC 专用、App/PC 可能共用待确认、App 合同不完整、App 缺失、页面无合理用途或双方需重定义。
|
||||
2. 精确合同:路径、方法、鉴权、请求参数、字段类型、必填性、可空性、枚举、响应模型和错误码。
|
||||
3. 数据行为:分页、排序、筛选、上传、幂等、防重复提交、并发冲突、权限和数据副作用。
|
||||
4. 页面结果:成功、失败、取消、返回、完成、来源页刷新、重复进入和目标数据过期时的表现。
|
||||
5. 证据与状态:OpenAPI 位置、页面与代码位置、MuMu 操作步骤、三人结论、后端问题编号和关闭条件。
|
||||
|
||||
接口问题不能只写“缺接口”或“字段不够”。需要给后端的每一项都必须能够直接用于修改 Apifox,并明确验收步骤。后端更新后由用户重新导出 JSON 和 YAML,先通过语义一致性与差异合同,再允许页面接入。
|
||||
|
||||
### 5.1 已核对结论 API-A04-001
|
||||
|
||||
- 页面与动作:A04 提交注册并建立会话。
|
||||
- 当前接口:`POST /genealogy/app/auth/register`。
|
||||
- 已确认响应:受保护旧快照的响应形状已经过期;2026-07-22 新线上注册成功响应为 `RAppLoginVo`,`data` 引用 `AppLoginVo`,唯一会话字段为 `access_token`。密码登录与短信登录使用同一响应链。
|
||||
- 客户端合同:`utils/api.js` 只消费 `AppLoginVo.access_token`;旧字段读取已经删除。必须等同版本双导出落地后再把页面接到远端,不能把线上证据手工写回受保护源文件。
|
||||
- 产品结论:取得并保存有效令牌后直接清理认证流程并进入 G01;不保留“注册成功后再登录”的并行终点。
|
||||
- 尚未关闭范围:短信发送、行为验证、限流和验证码状态机不由本结论代替,按后续短信阶段单独审查。
|
||||
|
||||
### 5.2 后端问题单 API-T01-001
|
||||
|
||||
**优先级:** P0;现有 6 人默认数据已能出现确定性断线,当前合同也无法安全支持几十代、几百代。
|
||||
|
||||
**受影响页面:** T01 主页面,T03 定位,T04 新增亲属,T06 编辑关系,T07 搜索成员;G01/G05 只受入口与焦点参数影响。
|
||||
|
||||
**当前接口与问题:**
|
||||
|
||||
- `GET /genealogy/app/genealogies/{genealogyId}/lineage/tree` 只接受 `genealogyId`,返回递归 `LineagePersonTreeView[]`。
|
||||
- 递归 `children/spouses` 与 `fatherId/motherId` 不能无歧义表达多个家庭联合点、单亲、收养、继亲、监护、主入边、窗口边界和树版本。
|
||||
- 世系 ID 使用 `integer/int64`,超过 JavaScript 安全整数时会改变身份。
|
||||
- 缺少世代×支系概览、人物定位、关系编辑和统一树版本并发合同。
|
||||
|
||||
**要求后端在 Apifox 原子更新:**
|
||||
|
||||
```http
|
||||
GET /genealogy/app/v2/genealogies/{genealogyId}/lineage/tree
|
||||
GET /genealogy/app/v2/genealogies/{genealogyId}/lineage/tree/overview
|
||||
GET /genealogy/app/v2/genealogies/{genealogyId}/lineage/persons/{personId}/locator
|
||||
PATCH /genealogy/app/v2/genealogies/{genealogyId}/lineage/relationships/{relationshipId}
|
||||
```
|
||||
|
||||
- `/lineage/tree` 查询参数固定为 `mode,focusPersonId,ancestorDepth,descendantDepth,boundaryId,cursor,limit,treeVersion`,不接受 `branchId/generation`。FOCUS 模式可省略焦点,但非空焦点只能是 VISIBLE 稳定人物 ID;REDACTED、不可见、过期或不存在的焦点统一返回 `404 LINEAGE_FOCUS_NOT_AVAILABLE`。深度为 0—20 的整数且默认上二代/下二代;BOUNDARY 模式必须同时提供 `boundaryId/cursor/treeVersion` 且不得带焦点或深度;`limit` 为最小 1、默认 200、最大 500,非法组合返回 `422 LINEAGE_QUERY_INVALID`。
|
||||
- 响应唯一根模型:`LineageGraphWindow`,必含 `version,state,genealogyId,nodes,familyUnits,edges,window`;版本字段固定为 `schemaVersion,treeVersion,generatedAt`,`state` 以 `EMPTY/POPULATED` 为 discriminator 使用 `oneOf`。EMPTY 精确要求空 nodes/familyUnits/edges、空 `entryPersonIds`、空 boundaries、`focusPersonId=null、generationRange=null、returnedNodeCount=0`;POPULATED 要求非空 nodes、引用其中 VISIBLE 节点的焦点、有效入口、非空代际范围,并满足 `returnedNodeCount === nodes.length`。
|
||||
- `entryPersonIds` 精确等于当前窗口无 primary 入边的节点集合,secondary 入边不取消入口身份;入口人物 `entryReason` 为 `GENEALOGY_ROOT/WINDOW_CUT/DISCONNECTED_COMPONENT` 且恰有零条 primary 入边,非入口 `entryReason=null` 且恰有一条 primary 入边。全谱根只由 overview 的可见根/隐私根计数与 locator 的根可见性分支表达;旧 `rootPersonIds/rootReason` 不再属于窗口合同。
|
||||
- Node 以 `visibility` 为 discriminator 使用 `oneOf`。VISIBLE 精确包含可见身份字段,稳定人物 ID 不得以 `redacted:` 开头,`sex` 固定为 `MALE/FEMALE/UNKNOWN`;REDACTED 只允许 `id,generation,displayName,order,visibility,entryReason`,名称固定为“隐私成员”,opaque ID 精确使用 `redacted:{treeVersion}:{token}` 并仅在该版本内作当前图内部引用,不得进入 FOCUS、locator、搜索、写接口或任何 `focusPersonId/targetPersonId`,也不得泄漏头像、性别或支系字段。
|
||||
- `FamilyUnit` 必含 `id,anchorPersonId,partnerRelationship,partners,order`;一个单亲成员或一对伴侣组成一个家庭单元。`partnerRole` 只允许 `ANCHOR/PARTNER`;双人关系对象包含稳定 `relationshipId、relationshipKind=PARTNER、relationType、status`,伴侣 `relationType` 为 `MARRIAGE/PARTNERSHIP/UNKNOWN`、`status` 为 `ACTIVE/ENDED/UNKNOWN`,单亲为 `null`,多配偶拆为不同家庭单元。
|
||||
- `ParentChildEdge` 必含 `id,familyUnitId,childId,lineageParentId,parentRelations,primary,order`;每项父母关系包含稳定 `relationshipId,relationshipKind=PARENT_CHILD,personId,parentRole,relationType`。`parentRole` 为 `FATHER/MOTHER/PARENT/GUARDIAN/UNKNOWN`,`relationType` 为 `BIOLOGICAL/ADOPTIVE/STEP/GUARDIAN/UNKNOWN`;所有父子关系都检查循环,不能只校验 primary。
|
||||
- boundary 必含稳定 ID、锚点、方向、原因、隐藏数量和 cursor;WINDOW 锚点的 `anchorId=null`,其他锚点引用对应实体;`hiddenCount` 为非负整数或 `null`,cursor 只在 UNLOADED 时非空。窗口内匿名人用 `Node.visibility=REDACTED`,窗口外隐藏拓扑用 boundary REDACTED,同一对象不得重复表达;运行时网络 FAILED 不写进后端枚举。
|
||||
- 所有实体、关系和引用 ID 使用非空字符串;`avatarOssId` 只允许非空字符串或 `null`。
|
||||
- cursor 绑定 `genealogyId/treeVersion/boundaryId`;版本变化返回 HTTP `409` 和 `TREE_VERSION_CHANGED`。
|
||||
- overview 只接受必填 `treeVersion`,版本变化返回 `409 TREE_VERSION_CHANGED`;响应以 `state=EMPTY/POPULATED` 使用 `oneOf`。EMPTY 精确为 `genealogyPersonCount=0、genealogyRootPersonIds=[]、redactedGenealogyRootCount=0、generationRange=null、buckets=[]`;POPULATED 要求正数总量、非空范围和 buckets,并满足可见根数加隐私根数至少为 1、全部 bucket 三类计数之和等于总量。可见根与 bucket `focusPersonId` 只能使用 VISIBLE 稳定 ID,隐私根只计数不返回 opaque ID。locator 将 `rootVisibility=VISIBLE/REDACTED` 与 `pathCompleteness=COMPLETE/REDACTED_GAPS` 独立建模;`ancestorPathSegments` 用 VISIBLE 人物 ID 段与不含 ID 的 REDACTED gap 段表达任意中间隐私,支持可见根但中间祖先隐藏,任何路径都不得包含 opaque ID。
|
||||
- 世系写接口携带 `If-Match`,成功返回新 `treeVersion` 以及受影响人员、家庭和关系 ID;关系 PATCH 以不可变 `relationshipKind` 为 discriminator 使用 `oneOf`,PARTNER 只更新 `relationType/status`,PARENT_CHILD 只更新 `relationType/parentRole`。每个分支至少提交一个可修改字段,省略字段保持原值;只有 `relationshipKind` 的空更新返回 `422 RELATIONSHIP_PATCH_EMPTY`,不得偷换参与人。
|
||||
- 客户端 Scene 根固定为 `{ sceneVersion, treeVersion, focusPersonId, bounds, items }`;`utils/lineage/scene.js` 唯一生成 `sceneVersion`,缺失版本或相同版本对应不同 payload 均拒绝原子替换。瞬时 `selectedId` 不进入 Scene 或版本摘要,renderjs 只用它在同一 Canvas 动态重绘光晕。
|
||||
- 四条操作统一声明 `200/400/401/403/404/422/429/5XX`;tree、overview、relationship PATCH 另声明 `409`。错误响应根层唯一业务码字段为必填字符串 `businessCode`,稳定码必须在对应响应 `oneOf` 分支中用单值 enum(OpenAPI 3.1 可用 `const`)表达;关键词、description、example 和无关 metadata 都不算证明。非空 `generationRange` 固定为关闭额外字段的 `{ minGeneration, maxGeneration }`,两项均为大于等于 1 的整数,大小顺序交给运行时 validator。
|
||||
- 旧 v1 树路径保持原合同;App 只实现上述四条固定 `/genealogy/app/v2/...` 路径,不双读、不运行时探测版本。
|
||||
|
||||
**关闭条件:** 用户从更新后的 Apifox 重新导出 JSON/YAML;两份文件同时通过 `tests/lineage-openapi-contract.ps1`;三人逐字段复核后,客户端才能开始规范化、布局和 Canvas 实施。
|
||||
|
||||
### 5.3 后端问题单 API-GENEALOGY-WORKSPACE-001—003
|
||||
|
||||
**优先级:** P1;阻塞 G01/G05 切到 remote 和正式上线,不阻塞继续审查无依赖业务域。
|
||||
|
||||
**唯一 owner:** `GET /genealogy/app/genealogies/mine`/`appListMyGenealogies` 持有当前账号可访问集合;`GET /genealogy/app/genealogies/{genealogyId}/overview`/`appGetGenealogyOverview` 持有 G05 只读展示。两个 operationId 全局唯一,路径只开放 GET、无 body;首批不接语义重复的 `GET /{genealogyId}`,不让两个详情响应互相补字段。
|
||||
|
||||
**当前线上证据:** `RListAppGenealogyVo/RAppGenealogyVo/AppGenealogyVo` 均无 `required`;`AppGenealogyVo.genealogyId` 为 `integer/int64`,`roleType/status/memberStatus` 无 enum,且没有 `canView`。最大合法 int64 经 JavaScript JSON 解析会失真,解析后再转字符串无法恢复。无令牌调用 `/mine`、`/1` 和 `/1/overview` 均实测返回 HTTP 200、`application/json;charset=UTF-8`、`{code:401,msg,data:null}`;线上文档却只列 200/401,401 schema 为 `*/* string`,也没有有效 security 声明。无令牌行为已经拒绝访问,因此不能仅凭注解缺失断言已发生公开泄漏;对象级授权仍没有有效账号反例证据。
|
||||
|
||||
**API-GENEALOGY-WORKSPACE-001:无损身份与最小 schema 闭包。** `/mine` 的 200 响应固定为 `RListAppGenealogyVo`,`/overview` 固定为 `RAppGenealogyVo`;两个 envelope 都关闭额外字段且精确 required `{code,data}`、code=200,列表 data 为 `AppGenealogyVo[]`,详情 data 为单个 `AppGenealogyVo`。首批实体必填字段固定为 `genealogyId/genealogyName/canView/canManage/canEditContent/roleType`:响应字段和 overview path 都引用词法 `GenealogyId`,名称引用 `GenealogyName`,三项 capability 为 boolean,角色为至少两个稳定非空值的正式 enum。地点、堂号、人数、简介等实体字段可选,`AppGenealogyVo` 不强制关闭未知额外字段。
|
||||
|
||||
**API-GENEALOGY-WORKSPACE-002:可访问集合与能力投影。** `/mine` 用 `x-current-account-viewable-only=true` 明确只返回当前账号仍可查看的家谱,并以 `OMIT_ONLY_AFTER_CONFIRMED_ACCESS_LOSS` 约束仅在成功确认失权时省略;G01 不能从未声明的 status 或 role 猜可访问性。`canManage/canEditContent` 是管理与内容入口的授权 UI 投影;真正写接口仍须后端逐次鉴权,capability 不能替代服务端授权。`roleType` 只拥有 G01 分组和角色标签,不替代 capability。
|
||||
|
||||
**API-GENEALOGY-WORKSPACE-003:typed HTTP、缓存与对象级授权。** 两条读取都 required SaToken 和非空 clientid;`/mine` 精确 200/401/429/500,overview 精确 200/400/401/404/429/500,不再允许 HTTP 200+业务错误。400 固定 `GENEALOGY_ID_INVALID`,401 为 `AUTH_REQUIRED`,对象无权/撤权/不存在以 `NON_DISCLOSING_GENEALOGY_NOT_AVAILABLE` 统一 404,429/500 分别为 `RATE_LIMITED/GENEALOGY_WORKSPACE_UNAVAILABLE`。全部只允许 JSON;每个响应必须含固定单值 private/no-store,429 另有 Retry-After;只允许非语义 tracing header:`traceparent/tracestate/x-request-id/x-correlation-id`,禁止 ETag 与其他语义 header。parameter/response/header/schema 只接受 exact local component ref;四种 tracing header 的引用也必须 exact local,内联 Header Object 必须 allowed-key 关闭并带非 null 的 string schema。clientid、code/data/businessCode、实体字段和 role 枚举以 allowed-key 集拒绝 `nullable`、readOnly/writeOnly、冲突组合和额外验证关键字;全局扫描全部 `/genealogy/app/` GET 的 200 schema 闭包并合并 allOf 属性,除 overview 外返回单谱实体的旁路详情一律失败,不把 `/mine` 数组误算为单谱读取。至少用两个账号执行无凭证、跨账号、撤权、删除、限流、服务异常和正常访问反例;G01 只在成功列表确认 ID 消失时写 tombstone,网络/5xx 保留现场,G05 不回退 fixture 权限。
|
||||
|
||||
**展示取舍:** 当前 G05 fixture 还显示 `source/manager/certification/ancestorName/parentName/branchName/updatedAt/activeCount`,线上没有等价字段。首批允许把这些区域隐藏或使用明确“待补充/待同步”的非业务降级;若产品要求继续把它们作为可信首屏信息,后端需另补字段或明确组合接口。不能为了复刻 mock 把 22 个字段全部列为当前硬门禁,也不能把 mock 值带进 remote。
|
||||
|
||||
**关闭条件:** 后端从同一版本重新导出 JSON/YAML,`tests/genealogy-workspace-openapi-contract.ps1` 通过;三人复核 enum 与页面消费后,才实现专属 adapter、G01 `onShow` 刷新和 G05 `/overview` 接线。随后完成有效账号行为矩阵和 MuMu 原生状态矩阵;缺少任一层证据都不能把工作区称为可上线。
|
||||
|
||||
### 5.4 后端问题单 API-M06-001—003
|
||||
|
||||
**优先级:** P1;阻塞 M06 切到 remote 和帮助内容上线,不阻塞继续审查其他无依赖页面。
|
||||
|
||||
**唯一 owner:** 当前 M06 只使用 `GET /genealogy/app/help-articles`。线上 `HelpArticleVo` 已携带完整 `helpContent`,所以手风琴展开直接使用同一列表快照;不调用 `GET /{helpId}`,不建立文章深链、详情缓存或第二正文 owner,也不让 `helpId` 进入页面模型。
|
||||
|
||||
**当前线上证据:** 列表返回 `RListHelpArticleVo`,列表项含 `helpId/helpCategory/helpTitle/helpContent/coverOssId/sortOrder/viewCount/status/remark`,但 wrapper 与 VO 都无 `required`,正文无格式语义,分类 query 无正式值域。受保护双导出更旧,只引用通用 `ListResult/RList`,没有专用 Help schema。匿名调用列表、带任意分类列表和详情均为 HTTP 200、`application/json;charset=UTF-8`、`{code:401,msg,data:null}`;线上文档则声明 HTTP 401 string 且 operation 无有效 security。
|
||||
|
||||
**API-M06-001:专用响应与最小 schema 闭包。** 列表 200 固定引用 `RListHelpArticleVo`;envelope 的 `code/data` required,`code` 为整数,`data` 为允许空数组的 `HelpArticleVo[]`。每行只把 `helpCategory/helpTitle/helpContent` 设为 required、`minLength >= 1` 的字符串;不要求当前页面不消费的 ID、封面、浏览量、状态和排序字段。后端必须从同一版本重新导出 JSON/YAML,不允许客户端手工补 schema。
|
||||
|
||||
**API-M06-002:展示标签、正文格式与发布范围。** `helpCategory` 是去边界空白后可直接展示的标签,不是需要客户端猜字典的内部代码;“全部”只由客户端拥有。`helpContent` 首版明确为 plain text,客户端只按字面显示,不解释 HTML、Markdown、图片或外链。用户侧列表只返回当前可展示的已发布文章,响应数组顺序就是页面展示顺序。若未来需要富文本、文章深链或详情,则另立内容安全和词法字符串 `helpId` 合同,不能偷偷扩张当前批次。
|
||||
|
||||
**API-M06-003:认证和错误承载一致性。** 后端可选择规范 HTTP 401,也可继续 HTTP 200+稳定业务 `code=401`,但 SaToken/security、JSON 媒体、OpenAPI 响应、部署行为和客户端 validator 必须一致。有效/失效令牌、空列表、畸形列表、5xx、超时和取消都要有集成反例;失败不得被解释成服务端空列表,也不得回退本地 FAQ 冒充线上成功。
|
||||
|
||||
**客户端关闭后的唯一形状:** adapter allowlist 输出 `{renderKey,category,title,content}`,其中 key 只由当前 response generation 与映射前 ordinal 组成;输入即使含 unsafe 或重复 `helpId` 也必须完全丢弃。筛选作用于已映射数组,搜索/分类/刷新前清空展开,旧 generation 迟到响应不得替换新列表。页面必须区分加载、服务端空、搜索无结果、错误重试和认证失效,并用原生按钮、`aria-pressed/aria-expanded/aria-controls`、状态播报及至少 44dp 目标完成无障碍闭环。
|
||||
|
||||
**关闭条件:** 后端同版本 JSON/YAML 通过 `tests/help-center-openapi-contract.ps1`;三人复核后才写专属 adapter 和页面异步状态。任务 23 关闭认证门禁后,完成有效账号部署矩阵及 MuMu 的系统字号、TalkBack、焦点、长正文、Android 返回和 M06→M07 验收。详情端点不属于本关闭条件。
|
||||
|
||||
### 5.5 后端问题单 API-PROFILE-READ-001—003
|
||||
|
||||
**优先级:** P1;阻塞 M01/M02/M03 使用真实资料和正式 remote 发布,不阻塞继续审查通知等其他只读域。
|
||||
|
||||
**唯一 owner:** `GET /genealogy/app/auth/profile` 持有当前登录账号资料。M01 身份卡、M02 表单初值和 M03 绑定手机号行都调用同一个窄 adapter,但不建立跨账号缓存、不通过路由传 PII。M05 当前手机号在 remote 发布前也必须消费同一脱敏结果或隐藏;这不等于提前接入换绑写接口。
|
||||
|
||||
**当前线上证据:** 200 已返回 `RAppProfileVo → AppProfileVo`,实体含 `userId/tenantId/userNo/phone/nickName/realName/avatar/sex/birthday/email/registerSource/loginIp/loginDate/status/clientKey/deviceType`,但 wrapper 与 VO 无 required,phone 无 pattern,姓名/邮箱无 length/format。受保护双导出仍为通用 `ObjectResult/RObject`。匿名 GET 实测 HTTP 200、`application/json;charset=UTF-8`、`{code:401,msg,data:null}`;线上文档则声明 HTTP 401 string,operation 只有“需要登录”文字而无有效 security/clientid。
|
||||
|
||||
**API-PROFILE-READ-001:专用响应与最小字段闭包。** 200 固定引用 `RAppProfileVo`,envelope 的 `code/data` required,`data` 引用 `AppProfileVo`。实体只 required `phone`,其值必须匹配 canonical `^1[3-9]\d{9}$`。`nickName/realName/email` 都是声明过的可选属性;出现时必须为非空且去边界空白的字符串,姓名长度 1—30,邮箱长度 1—100 且 `format: email`。不要求当前页面不消费的 ID、头像、状态、设备和登录审计字段。
|
||||
|
||||
**API-PROFILE-READ-002:可选值与隐私投影。** 三项可选字段唯一未设置形态是属性省略,不再并行接受 null、空串和缺失。adapter 固定输出 `{maskedPhone,phoneAccessibleLabel,nickName,realName,email}`,真正缺席的可选值规范为内部空串;出现但非法则整份失败。明文手机号只在函数局部校验后立即变为掩码和“绑定手机号,尾号 xxxx”读屏标签,不得进入页面模型、缓存、路由、日志或错误。`userId/avatar` 即使是 unsafe int64 也通过 allowlist 完全丢弃,不做 `String(number)`。
|
||||
|
||||
**API-PROFILE-READ-003:认证、配置与错误一致性。** 后端可选择规范 HTTP 401 或 HTTP 200+稳定业务 401,但 required clientid、SaToken/security、JSON 媒体、OpenAPI 与部署必须一致。客户端运行模式经 `resolveRuntimeMode()` 校验,错误 remote 配置不得静默回 fixture;读取使用严格 envelope、15 秒超时、取消和 generation 防迟到。账号失效交给 session owner,network/timeout/5xx/畸形数据是可重试读取失败,不存在写请求 uncertain。
|
||||
|
||||
**页面与后续写边界:** M01 资料失败只替换身份卡,菜单和底栏保持;查询参数假错误、fixture“创建者”和 remote 下伪通知数删除。M02 异步填表后才建立 baseline,GET 不证明 PUT;未来写批次必须验证省略字段保持、dirty-only payload、清空语义和并发。M03 仅手机号行局部失败,密码入口保持。头像、M04/M05 写入和设备管理不混入本批。
|
||||
|
||||
**关闭条件:** 后端从同一版本重新导出 JSON/YAML 并通过 `tests/profile-openapi-contract.ps1`;三人复核后才实现唯一 normalizer、三页局部状态与 M05 脱敏展示迁移。随后以不同资料完整度账号验证掩码、401、畸形响应、5xx、超时、账号切换和取消,并在 MuMu 完成系统字号、TalkBack、焦点、键盘、长昵称和返回流程。
|
||||
|
||||
### 5.6 后端问题单 API-NOTIFICATION-READ-001—003
|
||||
|
||||
**优先级:** P1;阻塞 N01/N02、M01/G01 未读数使用真实通知和正式 remote 发布,不阻塞继续审查其他业务域。
|
||||
|
||||
**唯一 owner:** `GET /genealogy/app/notifications` 不带 `readStatus` 时持有当前账号完整活动通知集合;`GET /genealogy/app/notifications/unread-count` 持有同一集合的未读数量。当前没有详情端点,N02 只消费列表成功响应形成的不可变内存快照,不建立第二正文 owner。
|
||||
|
||||
**当前线上证据:** 线上列表为 `RListNotificationVo → NotificationVo[]`,未读数为 `RLong`;两者和实体都无 required。`NotificationVo` 的 `notificationId/genealogyId/senderUserId/bizId` 是 int64,`readStatus` 无 enum,标题/正文无长度与格式,列表无分页、容量、完整性和排序。受保护双导出列表仍引用通用 `ListResult/RList` 且完全没有 unread-count。匿名 list/count 均实测 HTTP 200、`application/json;charset=UTF-8`、`{code:401,msg,data:null}`,而线上文档声明 HTTP 401 string,operation 无有效 security/clientid。
|
||||
|
||||
**API-NOTIFICATION-READ-001:专用响应与最小字段闭包。** 列表 200 固定 `RListNotificationVo`,未读数 200 固定 `RNotificationUnreadCount`;两层 `code/data` required,`code` 为 integer。列表 data 是允许为空且 `maxItems` 不超过 200 的 `NotificationVo[]`;实体 required `noticeTitle/noticeContent/publishTime/readStatus`。标题为 1—50 字符;正文为 1—1000 字符、完整未截断 plain text;时间是带 `Z` 或显式 offset 的 RFC3339 date-time;状态只允许 `READ/UNREAD`。计数是 0—200 的 int32。
|
||||
|
||||
**API-NOTIFICATION-READ-002:完整活动集合与快照。** 服务端活动集合本身最多 200 条;列表无筛选时完整返回该集合并按最新优先,未读数精确等于同一集合中 `readStatus=UNREAD` 的数量。两个请求之间并发变化允许瞬时差异,不要求客户端强行相等。adapter 公开 `{snapshotKey,title,content,publishedAt,unread}`,key 为成功响应 generation+映射前 ordinal;筛选不重编号。成功刷新原子替换快照,退出/账号切换清空且不落盘;N02 无 key 时提示“请返回消息中心重新打开”。
|
||||
|
||||
**API-NOTIFICATION-READ-003:认证、错误与内容安全。** 后端统一 required clientid、SaToken/security、JSON 媒体、HTTP 401 或业务 401 的文档与部署行为。客户端拒绝无时区时间、未知状态、空/超长标题正文和畸形 envelope;失败不得回退 fixture。首批丢弃所有 ID、sender、`noticeType/bizType/bizId`,不解释 HTML/Markdown/URL,不执行目标跳转;未知业务通知仍完整显示内容。
|
||||
|
||||
**客户端关闭后的唯一行为:** N01 摘要最多 160 个 Unicode 字素并可换行,N02 显示同一快照完整正文;M01/G01 共同调用 count owner,文案为“未读消息”,可见 `99+` 但读屏播报真实数。读取批次原子删除 fixture 未读数、本地已读 mutation、通用 G10/审核 CTA、N02 目标按钮和假重试;写能力等待 5.7。
|
||||
|
||||
**关闭条件:** 后端同版本 JSON/YAML 通过 `tests/notification-read-openapi-contract.ps1`;三人复核后才实现读取 adapter 和四页局部状态。认证门禁关闭后完成 0/1/99/100/200、并发、畸形响应和账号切换反例,再在 MuMu 验证系统字号、TalkBack、键盘/焦点、长文本、刷新、N01→N02 和 Android 返回。
|
||||
|
||||
### 5.7 后端问题单 API-NOTIFICATION-STATE-001—003
|
||||
|
||||
**优先级:** P1;阻塞真实单条/全部已读和四页状态收敛。必须在 5.6 读取批次之后独立实施,不能与读取代码混成一个不可验证批次。
|
||||
|
||||
**唯一 owner:** `POST /genealogy/app/notifications/{notificationId}/read` 持有单条已读,`POST /genealogy/app/notifications/read-all` 持有全部已读。两者无 request body,成功精确返回 `RVoid`;页面只把 `snapshotKey` 交给 notification controller,由 controller 私有解析服务端 ID。
|
||||
|
||||
**当前线上证据:** 两条 POST 已存在且返回 `RVoid`,但 path 和 `NotificationVo.notificationId` 都是 int64;最大值进入 JavaScript 会失真。`RVoid.code` 未 required,操作没有正式幂等、重试、超时未知、当前账号作用域、跨账号/不存在、read-all 截止点、并发新消息或刷新收敛语义。
|
||||
|
||||
**API-NOTIFICATION-STATE-001:无损身份和响应闭包。** `NotificationVo.notificationId` 与 path 参数必须同为 required 的 1—128 位 URL-safe opaque string,pattern 固定 `^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$`;禁止 int64 双读或解析后转字符串。`RVoid.code` 为 required integer,两个 POST 都要求 SaToken 和 required string clientid。
|
||||
|
||||
**API-NOTIFICATION-STATE-002:幂等与并发截止点。** 两个操作均对当前账号幂等,重复调用成功且没有重复副作用。read-all 以服务端接收请求时当前账号已存在的活动通知为截止集合,之后并发到达的通知保持未读;成功后客户端重取列表和 count。超时、断网、408/5xx 或畸形响应属于结果未知,允许依靠服务端幂等安全重试或先读取状态收敛,不能本地递减计数猜结果。
|
||||
|
||||
**API-NOTIFICATION-STATE-003:对象隔离和错误一致性。** 无效会话使用稳定 401;单条 ID 不存在或属于其他账号时统一返回 404 `NOTIFICATION_NOT_AVAILABLE`,避免暴露存在性。文档、部署、错误 envelope 与客户端 validator 必须一致,并以两个账号、删除消息、多端并发和迟到响应做反例。
|
||||
|
||||
**客户端迁移与关闭条件:** 写合同通过后,controller 才能私有保留 server ID,并原子删除读取首版“内部也完全丢弃 ID”的实现以及 N01/N02 的 clone mutation;公开页面模型、路由、日志和持久存储仍不得出现 ID。后端同版本 JSON/YAML 必须通过 `tests/notification-read-state-openapi-contract.ps1`,随后完成真实账号与 MuMu 的重复点击、提交中、失败/未知播报及 N01/N02/M01/G01 收敛矩阵。
|
||||
|
||||
### 5.8 后端问题单 API-PROFILE-UPDATE-001—004
|
||||
|
||||
**优先级:** P1;阻塞 M02 真实保存和 profile 正式 remote 发布。Task28 的 GET 是前置依赖;头像、相册权限、OSS、性别、生日、密码和手机号均不属于本问题单。
|
||||
|
||||
**唯一 owner:** 继续使用 `PUT /genealogy/app/auth/profile`,不再增加 PATCH。operation 必须把自身定义为字段级原子 merge update:出现的可编辑属性更新,省略的可编辑属性保持不变;重复相同字段集只设置同一状态,不产生重复通知等额外业务副作用。请求专用 owner 命名为 `AppProfileMergeUpdateBody`,避免旧 `ProfileUpdateBody/AppProfileUpdateBody` 被误当资源替换。
|
||||
|
||||
**当前双版本证据:** 受保护双导出的 PUT 使用 `ProfileUpdateBody`,只有 nickName、avatarOssId、sex、birthday 和省市区,没有 realName/email;示例又含 schema 外 `regionCode/addressDetail`,成功返回 generic `RObject`。线上变为 `AppProfileUpdateBody`,含 nickName/realName/avatar/sex/birthday/email,但无 required、`minProperties`、关闭额外字段、merge/clear/version;200 为 `*/* → RAppProfileVo`,实体与 envelope 无 required,operation 无 security/clientid,只列 200/401。两者都不能证明安全写入;未发送真实 PUT。
|
||||
|
||||
**API-PROFILE-UPDATE-001:最小 dirty command。** `AppProfileMergeUpdateBody` 是 `additionalProperties:false`、`minProperties:1/maxProperties:3` 的对象,属性集合精确为 nickName/realName/email 且均非 required。nickName 出现时为无边界空白的 1—30 字符,空串/null 非法;realName/email 分别以 `oneOf` 区分精确 `""` clear 命令与非空规范值,非空 realName 1—30,email 1—100 且 format=email。省略保持;纯空白和边界空白拒绝,服务端清库后响应省略该属性。
|
||||
|
||||
**API-PROFILE-UPDATE-002:单一版本并发。** `AppProfileVo.profileVersion` required,固定为 1—128 位 URL-safe opaque string;PUT required `If-Match` 采用同形状,body 不重复 version。服务端以当前账号和租户做原子 CAS;成功返回新版本,旧版本固定 HTTP 409 与 `RProfileVersionChanged.businessCode=PROFILE_VERSION_CHANGED`,不得 last-write-wins。H5 正式 origin 的 CORS 必须允许 `If-Match`。
|
||||
|
||||
**API-PROFILE-UPDATE-003:typed 响应、认证、错误与隐私。** 200 精确 `application/json → RAppProfileVo`,envelope `code/data` required,data 是完整 canonical profile;400/401/409/422/429/500 均进入同版本文档。operation required SaToken 和 string clientid;GET/PUT 资料响应声明并实测 `Cache-Control: private, no-store`。422 只返回 nickName/realName/email 的结构化字段错误。客户端及服务端日志、路由、持久缓存、遥测和异常不得含真实姓名、邮箱或请求/响应 payload。
|
||||
|
||||
**API-PROFILE-UPDATE-004:结果未知与账号隔离。** timeout、network、408/5xx、取消和畸形 200 均视为 outcome unknown;客户端先 GET 对账本次脏字段,全匹配确认成功、仍为旧 baseline 才允许重试、第三值或无法归因版本进入 conflict。session generation 变化时清草稿并拒绝迟到响应;RequestTask 取消不表示服务端未写。
|
||||
|
||||
**页面迁移与关闭条件:** 首次 GET 后才建立 baseline,clean 不发请求,saving 冻结三输入和返回;成功应用响应并重置 baseline,失败/unknown/conflict 保留草稿。原子删除 `currentUser.name` 同时冒充昵称/实名、500ms 假保存、API 禁用旧测试断言、假头像按钮和“邮箱用于接收通知”无依据承诺。后端同版本双导出通过 `tests/profile-update-openapi-contract.ps1` 后,才依次实现 normalizer、API、M02 状态机;再用两个账号/多端并发、超时对账和正式 H5 CORS 验证,最终在 MuMu 检查键盘、TalkBack、错误聚焦、长文本、冲突与返回。
|
||||
|
||||
### 5.9 后端问题单 API-LOGOUT-001—003
|
||||
|
||||
**优先级:** P1;阻塞 M10 服务端撤销和正式 remote 退出闭环。现有本机 `session.clear()` 仍保留为任何网络状态下的安全底线,但不能冒充服务端成功。
|
||||
|
||||
**唯一 owner 与当前证据:** `DELETE /genealogy/app/auth/logout` 无 body。受保护双导出有 required clientid、SaToken 和 200 `RVoid`,但只列 200、RVoid 无 required,未定义 scope/幂等/撤销传播。线上只有 200 RVoid 与 401 string,媒体为 `*/*`,operation 无 security/clientid;同样没有 scope、复用和其他设备反例。页面当前只执行一次本地清理并根跳转,相关测试没有远端请求、迟到 A/B 账号竞态或离线状态。
|
||||
|
||||
**API-LOGOUT-001:当前凭证族范围与撤销传播。** DELETE 只撤销 bearer 所属当前设备 credential family,包括同一登录会话的 refresh 能力;同账号其他设备 token 保持有效。200 必须表示撤销已传播至所有鉴权节点:旧 access 不能访问任一受保护接口,旧 refresh 不能换新 access。已经鉴权通过的并发业务请求不属于可回滚范围;全设备退出必须另接口。
|
||||
|
||||
**API-LOGOUT-002:唯一幂等成功和拒绝。** 能验证为该 client 历史签发的 active、revoked、expired credential 重复 DELETE 都返回相同 200 RVoid且无额外副作用。伪造、格式非法或 client 不匹配才返回 HTTP 401 `RLogoutRejected`,required `code/businessCode`,businessCode 只允许 `TOKEN_INVALID/TOKEN_CLIENT_MISMATCH`;这些拒绝不算远端撤销成功。不得长期并存 200 业务 401、HTTP 401 string 和 typed JSON 三种合同。
|
||||
|
||||
**API-LOGOUT-003:安全、媒体、缓存和反例。** operation required SaToken 与非空 string clientid,并验证 clientid 与 token client 绑定;200/401 为 application/json,`Cache-Control: private, no-store`,RVoid required integer code,另声明 400/429/500。以同账号两设备 token A/B 验证:A 删除后全受保护接口拒绝 A,重复 A 仍 200,B 保持有效;再验证 expired、伪造、client mismatch、跨鉴权节点传播、弱网/超时和正式 H5 Authorization/clientid CORS。服务端日志不得记录 bearer。
|
||||
|
||||
**客户端关闭后的唯一流程:** `logoutCoordinator` 同步捕获 A token/clientid/epoch,立即经 session owner bump epoch 并清全部账号态,再用显式 A 创建后台 RequestTask且立即 `goRoot(A01)`;M10 不持 token,请求不绑定页面 controller。coordinator 仅保存 attemptId/logoutEpoch/status,绝不在异步 finally 再 clear;A01 只在 session 为空且 epoch 未变时消费一次状态,B 登录后丢弃 A 迟到结果。所有分支都承诺“已从本机退出”,再区分 confirmed/unconfirmed/not-revoked;不持久 token、不跨重启重试、不阻塞重新登录。
|
||||
|
||||
**关闭条件:** 后端同版本 JSON/YAML 通过 `tests/logout-openapi-contract.ps1`;三人复核后才实现 session epoch、coordinator、严格 API 和 A01 提示,并原子替换 M10/导航/NM 旧静态断言。随后完成两设备部署矩阵和 MuMu 的确认、双击、系统返回、网络异常、状态播报、快速重新登录与根导航失败验收。
|
||||
|
||||
### 5.10 后端问题单 API-PASSWORD-001—005
|
||||
|
||||
**优先级:** P0;同时阻塞 A01 密码登录、A04 注册、A05 找回后的新密码验证、M04 登录态改密与正式 remote 模式。当前 M04 本地预览不得冒充修改成功。
|
||||
|
||||
**当前三方证据:** 受保护双导出的 `PasswordLoginBody/PasswordRegisterBody/PasswordResetBody/PasswordChangeBody` 都把密码写成静态 32 个十六进制字符 MD5;改密虽有 SaToken/clientid,却只有 200 RVoid,RVoid 无 required。线上相应 `AppPassword*Body` 仍接受大小写 MD5,M04 只有 200 `*/* → RVoid` 与 401 string,operation 无 security/clientid;live server 还发布 HTTP URL。现有 M04 只有 500ms 本地定时器,旧测试正确禁止提前导入 API;未发送 PUT。
|
||||
|
||||
**API-PASSWORD-001:唯一 raw wire 与策略 owner。** 新增 `CurrentPasswordSecret` 和 `NewPasswordSecret` 两个共享 schema。登录 password 与改密 oldPassword 只能引用前者,1—64 Unicode code point、原样不 trim;注册、找回和改密 newPassword 只能引用后者,NFC 后 15—64 code point,允许空格/Unicode/粘贴/密码管理器且无组成规则。四条入口在同一版本删除 MD5 与任何 raw/hash oneOf fallback;服务端执行常见/泄露密码 blocklist、账号限速、新旧不同与带独立盐的 Argon2id,无法使用时才选合规 scrypt/PBKDF2。confirm 永不出端。
|
||||
|
||||
**API-PASSWORD-002:重新认证、ALL session 与原子 CAS。** M04 以当前密码重新认证,TAC 不能替代;严格 200 前在同一安全事务中写入新 verifier、递增账号 credentialEpoch,并跨节点撤销所有设备/所有 client 的既有 access、refresh 与 renewal session,包括调用者。两个同旧密码并发请求至多一个 200,另一个 typed 409 `CREDENTIAL_VERSION_CONFLICT`。不返回新 token,不保留旧 bearer。
|
||||
|
||||
**API-PASSWORD-003:typed 错误与确定未写边界。** PUT 声明 200/400/401/409/422/429/500;409/422 的 `RPasswordChangeRejected.businessCode` 精确为 `CREDENTIAL_VERSION_CONFLICT/CURRENT_PASSWORD_INCORRECT/NEW_PASSWORD_SAME_AS_CURRENT/PASSWORD_POLICY_VIOLATION`。400/422/429 明确保证未修改;401/409 进入重新登录;network/timeout/取消/畸形 2xx/5xx 均为结果未知,客户端不得自动重试或解析 msg。
|
||||
|
||||
**API-PASSWORD-004:鉴权、媒体、缓存与秘密卫生。** required SaToken、与 token client 绑定的非空 clientid、关闭额外字段的 JSON body;所有响应 application/json 且 `Cache-Control: private, no-store`,429 required `Retry-After`,RVoid integer code required。OpenAPI server 和实际重定向全程 HTTPS。反向代理、应用日志、APM、分析、崩溃报告与错误 body 不记录 old/new/confirm、MD5、Authorization 或完整请求。
|
||||
|
||||
**API-PASSWORD-005:账号能力和客户端崩溃边界。** 后端明确所有 App 账号是否都已配置密码;若不是,profile 返回稳定 `passwordConfigured` 并让无密码账号进入独立 step-up 设置流程,M04 不猜。客户端 session owner 在 dispatch 前只持久化 `{sessionEpoch,startedAt}` 的 `credentialChangeInFlight`;确定未写清 marker,200/401/409/unknown 清同 epoch 账号态并回 A01。冷启动同 epoch marker 在任何缓存渲染前 fail closed,新登录 bump epoch,迟到旧响应不得清新账号。禁止持久 token、密码、摘要、body、operation 状态或自动重试。
|
||||
|
||||
**关闭条件:** 后端同版本 JSON/YAML 通过 `tests/password-change-openapi-contract.ps1`,并先关闭密码登录 TAC 门禁;三人复核后按共享策略→四条 API wire→session epoch/marker→M04 状态机顺序原子实施,删除 `calcMD5` 生产消费者、8—32 旧规则和 NM preview 断言。最后以两设备全部 access/refresh 撤销、并发/fault injection、秘密日志扫描、正式 CORS/HTTPS 和 MuMu 的密码管理器、系统字号、TalkBack、44dp、错误聚焦、Android 返回与跨根提示验收。
|
||||
|
||||
### 5.11 后端问题单 API-PHONE-001—005
|
||||
|
||||
**优先级:** P0;阻塞 M05、全活动短信码生产强度及正式 remote 模式,并依赖 M04 raw-password 和认证/TAC 门禁先关闭。当前 M05 只做本地 4 位码校验,不得冒充换绑。
|
||||
|
||||
**当前三方证据:** 本地 `PhoneChangeBody` 要求 `clientId/phone/smsCode`,线上 `AppPhoneChangeBody` 只要求 `phone/smsCode`;两边都是 4 位码,都没有 currentPassword、号码占用、并发、会话撤销、outbox 或结果未知语义。线上 PUT 无有效 security/clientid且返回完整 `RAppProfileVo`,错误只有 401 string;共享发码 operation 在线上明确忽略权限,当前客户端方法也固定不携 bearer。页面使用脱敏 fixture、70rpx `view role=button` 和 500ms 定时器,未调用 API/TAC;未发送 POST/PUT、短信,未操作 MuMu。
|
||||
|
||||
**API-PHONE-001:专用受保护发码 operation。** 新增 `POST /genealogy/app/auth/phone/sms/code`,required SaToken 与非空 clientid,闭合 `PhoneChangeSmsCodeBody` 只含 `phone/validToken`;服务端固定 scene=`APP_PHONE_CHANGE`,不接受 sceneCode/clientId/tenantId/grantType。公共 `/auth/sms/code` 删除该 scene。两个 operation 复用同一 OTP 服务 owner;匿名专用调用必须 401,公开登录/注册/找回发码仍可匿名。validToken 必须绑定当前账号/session、tenant、client、scene 与规范化新号并单次消费。
|
||||
|
||||
**API-PHONE-002:唯一六位 OTP wire 与生命周期。** 新增 `SmsCodeSecret`:CSPRNG 生成恰好 6 位 ASCII 数字、保留前导零、writeOnly、无示例;5 分钟 TTL、60 秒重发、最多 5 次失败、单次消费,重发废止旧 generation且不重置累计失败次数。同一复合键只有一条 active generation。A01/A04/A05/M05、`AccountDeactivateBody` 及同源生成器、短信模板、双导出、validator、页面和测试同版删除全部 4 位规则,不保留 4/6 fallback。
|
||||
|
||||
**API-PHONE-003:existing-factor 与闭合最终 PUT。** `PUT /genealogy/app/auth/phone` required SaToken/clientid,`PhoneChangeBody` 只含 required `currentPassword/phone/smsCode` 且关闭额外字段;密码引用 `CurrentPasswordSecret`,新号引用 11 位 `NewBoundPhone`,短信引用 `SmsCodeSecret`。当前密码是既有因子再认证,TAC 不能代替;无密码账号返回 `STEP_UP_UNAVAILABLE` 进入独立恢复,不能降级为 bearer+新号 OTP。不要求旧号 OTP,成功后改用旧号安全通知。
|
||||
|
||||
**API-PHONE-004:原子换绑、唯一约束与会话。** 在一个事务中验证 currentPassword/active OTP、执行 `(tenantId,canonicalPhone)` 唯一约束、消费 OTP、CAS 更新号码、递增 credentialEpoch、撤销包括当前在内的全部 access/refresh/renewal session,并持久化旧号通知 outbox;严格 200 只返回 `RVoid`。并发至多一笔成功;通知投递失败不回滚换绑,但 outbox 必须重试并告警。不得在证明新号控制权前泄露号码是否已绑定。
|
||||
|
||||
**API-PHONE-005:typed 错误、传输与客户端恢复。** POST/PUT 都声明 200/400/401/409/422/429/500 JSON、`private, no-store`,429 有 `Retry-After`;409/422/429 使用 required `RPhoneChangeRejected.code/businessCode`,稳定覆盖 current password、同号/占用、验证码错误/过期/尝试耗尽、credential 冲突、step-up 不可用、验证重做与限流,客户端不解析 msg。最终 PUT dispatch 前复用无秘密 `{sessionEpoch,startedAt}` marker;200/401/409/unknown 清同 epoch 账号态回 A01,不自动重试。HTTPS、Authorization/clientid CORS 和密码/手机号/OTP/TAC/token 全链路日志脱敏必须实测。
|
||||
|
||||
**关闭条件:** 同版本 JSON/YAML 通过 `tests/phone-change-openapi-contract.ps1`,且认证、密码和 profile 读取前置门禁全部通过;三人复核后按全活动六位码→专用发码 API→共享 credential marker→M05 状态机原子实施,替换旧四位/preview 断言。最后完成匿名/错场景/TAC 重放、前导零、重发/过期/限流、号码唯一与枚举、两设备并发、全部 session 撤销、fault injection、旧号 outbox 和 MuMu 的输入法、TalkBack、44dp、系统返回与结果未知矩阵。
|
||||
|
||||
### 5.12 后端问题单 API-G03-001—005
|
||||
|
||||
**优先级:** P0;阻塞 G03 真实创建、创建后 G01/G05/context 闭环及 APP 家谱访问规则唯一化。当前同页两步是明确本地预览,不得把 `local-created-*` 或 fixture mutation 当作后端成功。
|
||||
|
||||
**当前三方证据与方案结论:** 本地 `GenealogyCreateBody` 和线上 `AppGenealogyCreateBody` 都只创建家谱,通用人物 POST 另写始祖;创建响应未形成 required 词法 ID/OWNER/READY 回执。页面缺可信 regionCode,默认男性、硬限 1800 年、把“一世”混入 generationName;成功不安装真实 context。三人先设计 `ROOT_REQUIRED` 两写及恢复,再确认没有跨库或保存空谱需求,最终否决这类客户端 saga:它只会新增半成品配额、可见性、删除/过期、版本、G01 恢复卡和第二次未知结果。唯一最小生产方案是最终按钮一次原子 bootstrap,第一步零网络写。
|
||||
|
||||
**API-G03-001:闭合 bootstrap 与领域事务。** `POST /genealogy/app/genealogies` 唯一 body 改为 additionalProperties=false 的 `AppGenealogyBootstrapBody`,字段精确为 `genealogyName/surname/ancestralHall/regionCode/accessPreset/rootPerson`,除堂号外全部 required;rootPerson 只含 `name/sex/birthDate/biography` 且前两项 required。sex=`MALE/FEMALE/UNKNOWN`,生日 format=date,服务端固定 generation=1、唯一首根且不接收账号/编号/父母/字辈/状态。严格 200 前一个事务完成 quota、谱、OWNER、根、READY 和幂等回执,失败全回滚;通用人物 POST 仅用于 READY 后普通人物。同名不是冲突,重复提醒只做建议。数据库 bootstrap-root marker 是身份权威:根 PUT 可编辑白名单精确只有 `name/sex/birthDate/biography`,status/personStatus、账号绑定、世代、父母、根标记及任何白名单外字段一律 422;collection POST、人物 DELETE 和 parents mutation 也不能创建第二根、删除根或给根重挂父母。
|
||||
|
||||
**API-G03-002:幂等键、控制事务、结果和稳定错误。** required `Idempotency-Key` 引用 `GenealogyBootstrapOperationKey`,精确格式为 `gcb.{13位 issuedAt 毫秒}.{22—43位 base64url CSPRNG}`,随机量至少 128 位;固定 `acceptUntil=issuedAt+10 分钟`,以 server time 判定,未来超过 5 分钟返回 400 `OPERATION_KEY_INVALID`,并以 600/300 秒 extension 锁定。窗口内首次 POST 用短控制事务按 account/tenant/client/path/key 唯一 CAS 认领 PENDING、canonical digest、fencing lease 与 `resolveBy<=claimedAt+2 分钟`,以 120 秒 extension 锁定;相同作用域/key/body 的已存在操作在截止后仍返回同一结果,不同 digest 返回 409 `IDEMPOTENCY_KEY_REUSED`,过期且不存在的 key 返回 409 `OPERATION_KEY_EXPIRED`。业务事务才原子处理 quota、谱、OWNER、唯一根、READY 和 SUCCEEDED;失败回滚后 CAS FAILED_NO_COMMIT,watchdog 同样用 fencing CAS,旧 worker 不能迟交。`GenealogyBootstrapResult` required 词法字符串 genealogyId/rootPersonId、setupState=READY、roleType=OWNER、canView=true;成功防重记录至少覆盖实体生命周期。POST 声明状态专属、`code` 与 HTTP 状态单值一致的 400/401/403/409/422/429/500 typed JSON、private/no-store,429 有 Retry-After。
|
||||
|
||||
**API-G03-003:无 PII operation-status 与迟到竞态。** 新增 required SaToken/clientid 的 `GET /genealogy/app/genealogy-bootstrap-operations/{operationKey}`,有效参数只有 operationKey/clientid且没有 request body,响应集精确为 200/400/401/404/429/500,禁止泄漏性 403/default。响应以带显式 mapping 的 discriminator `oneOf` 关闭为 `PENDING{resolveBy,retryAfterSeconds}`、`SUCCEEDED{result}`、`FAILED_NO_COMMIT`,三个 status 均为单值 string;`x-state-transitions` 精确登记 `ABSENT→PENDING→SUCCEEDED/FAILED_NO_COMMIT`,两个终态无出边且 `x-terminal-immutable=true`,FAILED 同时固定 `x-domain-effects=NONE/x-quota-consumed=false`。PENDING 的 retryAfterSeconds 为 1—30,200 不强制 Retry-After。GET 必须纯读且始终无副作用:acceptUntil 前无记录返回 typed 404 `BOOTSTRAP_OPERATION_NOT_AVAILABLE`、服务端 acceptUntil 和 Retry-After,客户端保持 unknown;截止后无记录按 key 可计算地返回 FAILED_NO_COMMIT,不写 tombstone,迟到 POST 永久拒绝。PENDING 最迟 claimedAt 后 2 分钟终结;SUCCEEDED 记录至少保留实体生命周期,FAILED 至少 30 天;跨 account/tenant/client 统一不泄漏 404。响应不含原请求或人物 PII,operation 不进 `/mine`、不占业务 quota;GET 零写与 FAILED 零领域提交仍必须另以 DB 观测测试证明。
|
||||
|
||||
**API-G03-004:APP 访问预设单一 owner。** 新 `GenealogyAccessPreset` 只允许 MEMBER_ONLY/PUBLIC_APPLY,并在同一版本成为 `AppGenealogyBootstrapBody`、实际 `/mine`/overview 读取所用 `AppGenealogyVo` 和闭合 `AppGenealogySettingsUpdateBody` 的唯一访问字段。删除 `GenealogyCreateBody/AppGenealogyCreateBody/GenealogyUpdateBody/AppGenealogyUpdateBody` 旧入口以及 visibility/joinMode;不保留 oneOf fallback、数字 pair 或邀请码 mode 的暗中映射。validator、runtime、双导出、fixture 迁移、G03/G05/G11 测试和文档同批更新。这里只关闭共享字段迁移;G11 写入仍须另行完成 If-Match、版本/CAS、权限刷新和结果未知门禁。
|
||||
|
||||
**API-G03-005:可信地区、始祖不变量、认证与部署反例。** `GenealogyRegionCode` 是 1—32 位 URL-safe 词法标识;唯一地区 owner 改为 required SaToken/clientid 的 `GET /genealogy/app/region/search`,同版删除旧公共 `/genealogy/region/search`。keyword required 且 minLength=1/maxLength≤50;`RListRegionSelectVo.code/data` 和 `RegionSelectVo.regionCode/label/selectable` required,leaf 不等于 selectable,不强制层级;页面只展示 label、提交 code,POST 在业务事务中复验仍可选。通用人物写入以 typed 409 `GENEALOGY_NOT_READY` 和 422 `BOOTSTRAP_ROOT_IMMUTABLE` 覆盖 collection/PUT/DELETE/parents;PUT operation 以 `x-bootstrap-root-editable-fields=[name,sex,birthDate,biography]` 和 `x-bootstrap-root-noneditable-policy=REJECT_422_BOOTSTRAP_ROOT_IMMUTABLE` 精确锁定仅四项可编辑,其余字段一律 422。create/status/settings/region及相关人物私有响应必须是 JSON+private/no-store;同一后端模型重导后先由 `openapi-yaml-json-parity-runtime-smoke.js` 以无损任意精度数字和严格 YAML mapping 语法深比较完整 JSON/YAML,再递归检查组合 schema 字段。以匿名、错 client、跨账号 status、unsafe 数字 ID 差一、地区失效、quota race、同 key 并发、control/business/terminal 各写点 fault injection、GET 零写、根 PUT 白名单及其他绕过、超时/5xx/畸形响应和正式 HTTPS/CORS 验证文档与部署一致。
|
||||
|
||||
**客户端关闭后的唯一流程:** 第一步只校验并进入页内始祖步骤;最终校验后冻结 canonical snapshot,先持久 `{sessionEpoch,operationKey,startedAt}` 再 POST。本地校验或可证明零发出的 request-build 失败不留 marker;服务端在 claim 前返回的 400/401/403 清 marker,401 同时清会话;`IDEMPOTENCY_KEY_REUSED` 进入 fatal/quarantined,不查装 status、不自动换 key,只有用户看到警告并显式放弃才清;确定未提交的 limit/expired/422 可清。429 保持同 key/body并先查 status;500/network/timeout/408/发出后取消/意外 2xx/3xx/畸形 200 都保持 marker按 unknown 查询。status 截止前 404 保持,400 清损坏 marker,401 走会话失效,429/500/network/cancel/unexpected/malformed 保持退避,FAILED_NO_COMMIT 才允许新 key。冷启动只查 status,不保存姓名/生日/生平、完整 body或可逆日志。SUCCEEDED 唯一次序为 committed receipt → 失效或定点更新 `/mine` → 安装 context → G05;context/导航失败不重发创建。落地时删除 local preview/mock create 与旧禁止 API 断言,不能长期并存两个创建 owner。
|
||||
|
||||
**页面与关闭条件:** 地区搜索、PENDING、unknown、fatal/quarantined、committed、context/导航失败必须可见;默认 UNKNOWN,删除 1800/UTC 日期错误;label、radio、aria-invalid/describedby、首错聚焦、至少 44dp 原生按钮、AppDialog 焦点与状态播报同批实现。后端同版本 JSON/YAML 必须通过 `tests/g03-bootstrap-openapi-contract.ps1`,客户端实现必须另行通过会实际执行状态机套件的 `tests/g03-bootstrap-client-release-gate.ps1`;它们只是 G03 自身两门禁,真实开放还要求 Task26 workspace 读取门禁、聚焦/全量回归和 MuMu 原生字号、TalkBack、键盘、慢网、双击、杀进程及 Android 返回矩阵全部通过。
|
||||
|
||||
当前其余已知但尚未核实的重点依赖包括:微信登录、公共行为验证、完整短信状态机、邀请码验证与直接加入、结构化亲属关系、上级家谱与支系权限、管理员授权与功能开关、上传与系统权限、消息业务目标、系统分享、订单支付与退款。它们只表示审查重点,不预判后端一定缺失。
|
||||
|
||||
### 5.13 后端问题单 API-JOIN-001—006
|
||||
|
||||
**优先级:** P0;阻塞 G06/G08/G09/G10 普通申请、撤回和审核的真实闭环。邀请码直入不属于本问题单。
|
||||
|
||||
**API-JOIN-001:七个稳定 owner、词法身份与 cursor。** 发布设计 23.10 的七个 operationId;三个列表分别返回专用 page/item,不返回 total,limit 1—50,cursor 绑定 tenant/account/client/filter;搜索按 updatedAt+genealogyId,mine/pending 按 submittedAt+applyId 稳定排序。genealogyId/applyId 均引用 1—128 位 URL-safe string owner;搜索 viewerState 只允许 NOT_JOINED/MEMBER/PENDING/REJECTED/FORMER_MEMBER/OWNER,不另发 canApply。
|
||||
|
||||
**API-JOIN-002:闭合投影与文本。** 申请体仅 `applicantName/relationDesc/applyReason?`,前两项 required;审核体仅 APPROVE 或 REJECT+required rejectionReason 两分支。三项申请文本和拒绝原因共用 `JOIN_APPLICATION_TEXT_V1`。mine 使用四状态 discriminator且拒绝分支必有可见原因;pending 精确五字段并递归禁止手机号、用户、邀请人和审核人。删除旧 APP join DTO 和通用响应引用。
|
||||
|
||||
**API-JOIN-003:幂等、恢复、零写与准入协调。** request key 为 `gja.{issuedAt}.{CSPRNG}`,600/300/120 秒边界;canonical identity 覆盖 method/path/genealogyId/tenant/account/client/body。parameter/response 只允许 exact local 分区引用;幂等 scope、活动唯一 scope、事务 effects、重验字段、状态迁移和 cursor 扩展必须是真实 JSON 数组,逗号字符串不能伪装集合。数据库唯一约束保证同账号同谱一个 PENDING;POST 在事务内重验 READY、PUBLIC_APPLY 与 applicationEligibility,并与 G11 设置 PUT 共享 `x-public-apply-coordination=ATOMIC_SINGLE_WINNER`,关闭公开申请与新准入竞态只允许一方提交。申请行与 SUCCEEDED receipt 同事务。新增纯读 status GET,三态转换和终态不可变;窗口内 404、窗口后零写 FAILED、跨主体非泄漏 404、迟到 POST 拒绝,客户端只持久无 PII marker。
|
||||
|
||||
**API-JOIN-004:撤回。** DELETE 以 PENDING CAS 决定唯一赢家;相同撤回只重放 WITHDRAWN typed 200,审核或其他终态获胜时返回 typed 409+最小 current state,不存在或越权统一 404。key 复用、key 过期与活动 PENDING 冲突不强制返回不存在的申请 current。
|
||||
|
||||
**API-JOIN-005:审核。** PUT 在事务内重验权限、READY、PUBLIC_APPLY,执行 PENDING CAS、唯一成员关系和终态;相同决定只重放 APPROVED/REJECTED 原 200,绝不返回 WITHDRAWN;相反决定或不同规范化拒绝理由返回 409。POST 的 409 精确引用 `RJoinApplicationKeyConflict`,DELETE/PUT 的 409 精确引用 `RJoinApplicationStateConflict`,不得共享会接纳跨操作业务码的宽联合 owner。无 applicationVersion、If-Match 或详情端点。
|
||||
|
||||
**API-JOIN-006:安全与发布。** 所有响应精确 typed JSON、private/no-store,429 和 status 窗口内 404 带 Retry-After;禁止 default、3xx、`*/*`、200 包认证错误、int64 和通用 RList/RObject/RVoid。后端以真实账号、数据库观测、并发与 fault injection 证明 cursor、唯一约束、fencing、零写、事务、跨主体不泄漏和正式 HTTP/CORS;OpenAPI 静态扩展不替代实现证据。
|
||||
|
||||
**关闭条件:** 同版本双导出通过 `tests/join-application-openapi-contract.ps1`;再完成后端运行时反例、客户端 marker/status/CAS 收敛测试、旧 adapter/手机号/消息承诺/LOCAL_WITHDRAWN 原子删除、全量回归和 MuMu 320/360/412、系统字号、TalkBack、键盘、返回、双击、慢网、断网、杀进程矩阵。当前门禁输出 `JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`,页面保持本地预览。
|
||||
|
||||
### 5.14 后端问题单 API-INVITE-001—006
|
||||
|
||||
**优先级:** P0;阻塞 M08 邀请签发、G06 邀请码解析与直接加入。普通申请继续由 API-JOIN 唯一拥有。
|
||||
|
||||
**API-INVITE-001:六个专用 owner 与流程隔离。** 发布 23.11 的 list/issue/revoke/resolve/redeem/redemption-status 六 operation,required SaToken/clientid、词法 genealogy/ticket/membership ID、operation-specific typed responses。G06 直接确认兑换,G08 只保留普通申请;普通申请 body 反向禁止 inviteCode/ticket/token。禁止平行旧入口、通用 promotions、礼仪邀请或普通申请 POST 承担本域。
|
||||
|
||||
**API-INVITE-002:单次秘密票据。** 原码固定版本前缀+26 位 Crockford Base32 随机量、至少 128 位熵、24 小时单次使用;HMAC 查找,KMS 密文仅保留 600 秒幂等恢复窗。列表只返回最多 20 个活动元数据;原码只允许 issue 200 指定位置,redemption token 只允许 resolve 200 指定位置,并对所有响应 `$ref/oneOf/allOf/items` 递归检查秘密与 PII 闭包。
|
||||
|
||||
**API-INVITE-003:签发、权限与撤销。** issue 无 body,`gii` key 按 method/path/genealogy/tenant/account/client 唯一;已存在 key 不受首次接受窗影响,不同 digest 优先冲突,600 秒内返同码、窗后返同 ticket metadata+`ISSUED_SECRET_UNAVAILABLE` 且不新建。ticket、HMAC、KMS 密文与 request receipt 原子提交。workspace `canInviteMembers` 唯一映射服务端 `INVITE_MEMBER`;list/issue/revoke 均重验并只管理 actor 自己签发的票据,跨 issuer 404;活动上限由数据库约束。DELETE 以 ACTIVE→REVOKED CAS,相同撤销重放 200,CONSUMED/EXPIRED typed 409 current;撤销与兑换只有一个赢家。
|
||||
|
||||
**API-INVITE-004:安全解析与原子兑换。** resolve 的原码只在 JSON body,不消费票据或建立成员但可轮换唯一短时 grant 摘要,并统一 `INVITE_TICKET_NOT_AVAILABLE`、多维限流与时间侧信道控制;返回最多五分钟且绑定 actor/client/ticketVersion/genealogy/authorizationEpoch 的敏感 token。redeem 无 body,事务谓词包含 token、版本、数据库时钟过期、unused、READY、功能、签发者权限、账号资格和容量;票据消费、唯一 MEMBER 与回执同事务。ALREADY_MEMBER、活动普通申请、账号禁用或票据失效均不得消费票据。
|
||||
|
||||
**API-INVITE-005:幂等与 unknown 恢复。** `gir` key 的 canonical identity 包含 token identity/ticket/genealogy/actor/client;同 key 不同 identity typed 409。600/300/120 秒边界、control claim、fencing/watchdog 和纯读 status 固定 PENDING/SUCCEEDED/FAILED_NO_COMMIT;窗口内 404 带 acceptUntil/Retry-After,窗口后零写计算 FAILED,跨主体统一 404。已存在终态优先,终态回执至少保留 30 天且晚于 30 天客户端 marker 清理;清理后不得据 absence 否定领域写。客户端只持久无秘密 marker,成功后只重试 workspace/context/导航本地收口。
|
||||
|
||||
**API-INVITE-006:安全、无障碍与发布。** 所有响应 JSON+private/no-store,429 带 Retry-After;URL/query/storage/log/APM/分析/崩溃报告/自动测试和发布证据截图零秘密,用户主动显示、复制或系统分享必须先提示风险且不得自动触发。后端以真实数据库并发、fault injection、权限降级、猜码、两人同码、同人两码、撤销竞态、日志审计与 HTTP/CORS 证明实现,静态扩展只登记意图。客户端原子删除 `JP2026`、fixture target、invite→G08 与 G08 invite 分支;补原生按钮、44dp、tab/label/aria、状态播报、长码换行、冻结和 MuMu 全矩阵。
|
||||
|
||||
**关闭条件:** 同版本双导出通过 `tests/invite-ticket-openapi-contract.ps1`,再通过后端运行时反例、客户端 coordinator 测试、Task36 普通申请隔离、workspace/context 收口、全量回归及 MuMu 320/360/412、1.3 倍字号、TalkBack、键盘/粘贴、双击、慢网/断网、杀进程、Android 返回和系统分享取消。当前输出 `INVITE-TICKET-OPENAPI-CONTRACT BLOCKED`,页面不得接假接口。
|
||||
|
||||
### 5.15 后端问题单 API-SETTINGS-001—006
|
||||
|
||||
**优先级:** P0;阻塞 G11 家谱设置真实读取、并发写入、访问规则切换与发布。
|
||||
|
||||
**API-SETTINGS-001:唯一 read/write 与共享字段 owner。** 保留全局唯一 `appUpdateGenealogySettings` PUT,递归拒绝旁路 settings 写、任一 `genealogyName/intro/accessPreset` 单字段第二 body owner以及外部/错分区同名 `$ref`;`/genealogy/app/genealogies...` 写 body 根层 `intro` 明确保留给设置,子域使用自身字段名。删除 generic GET 且不新增 PATCH;overview 是 G11 canonical baseline 唯一读取 owner,并由 workspace 门禁以 schema 闭包与 allOf 合成排除旁路详情。发布共享非 null `GenealogyName/GenealogyIntro/GenealogySettingsVersion`:名称拒绝换行/控制字符,简介只允许内部 LF并拒绝 CR/tab/其他控制字符,让 bootstrap、settings body 与 `AppGenealogyVo` 引用同一 24/80/版本合同;`GenealogyAccessPreset` 继续由共享 owner 唯一持有且禁止 nullable。200 复用关闭额外字段的 `RAppGenealogyVo`,不建重复 snapshot。
|
||||
|
||||
**API-SETTINGS-002:原子 dirty-only merge。** body 关闭额外字段、1—3 个出现字段,省略保持、intro 精确空串清空、null/空白/旧 pair/其他设置全部早失败。事务内锁定并重验 tenant、资源、权限,只应用出现字段;任一字段或迁移前置失败整笔零写。canonical no-op 保留版本且不产生额外领域副作用。
|
||||
|
||||
**API-SETTINGS-003:版本 CAS 与非泄漏权限。** `AppGenealogyVo.settingsVersion` 和 If-Match 共用 1—128 位 opaque owner,并以 `x-version-scope-fields`/`CANONICAL_SETTINGS_CHANGE_ONLY` 限定只在 canonical 设置实际变化时更换;旧版本精确 409+current,不发布 412/ETag 双轨。只有仍有权限者可得到版本/current;跨主体统一 404,权限撤销 403。冲突 precedence 为 version→READY→active pending,409 wrapper 只含 discriminator/oneOf 且分支均为 exact local ref,正式 H5 CORS 允许 If-Match。
|
||||
|
||||
**API-SETTINGS-004:访问迁移与申请串行化。** 活动 PENDING 只阻断真实 PUBLIC_APPLY→MEMBER_ONLY,返回无 PII 的 `ACTIVE_PENDING_APPLICATIONS` 并让客户端引导 G10;不阻断其他字段/no-op,不自动拒绝或撤回,不改变邀请合同。设置 PUT 与任务 36 新申请 POST 都在事务内重验 genealogyState/accessPreset,申请另验 eligibility,并共享 `x-public-apply-coordination=ATOMIC_SINGLE_WINNER`;竞态只允许一方提交,不把合同绑死为某种数据库隔离级别。
|
||||
|
||||
**API-SETTINGS-005:typed 响应、unknown 与缓存。** 精确 200/400/401/403/404/409/422/429/500,只允许 JSON;每个 response 必须含单值 enum private/no-store,429 另有 Retry-After;只允许非语义 tracing header:`traceparent/tracestate/x-request-id/x-correlation-id`,禁止 ETag 与其他语义 header,所有 component `$ref` 必须 exact local。四种 tracing header 若内联,只接受 allowed-key 关闭且带非 null 的 string schema 的 Header Object。标量、引用字段、成功/错误 envelope 与 fieldErrors 以 allowed-key 集关闭 `nullable`、readOnly/writeOnly、冲突组合和额外验证关键字;409 使用纯 businessCode discriminator 三分支,422 只返回三个字段错误,500 明示 outcome unknown。后端与客户端用真实账号、数据库观测、并发和 fault injection 验证零部分写、版本、权限与申请竞态;unknown 只以 fresh overview 对账,成功失效 mine/overview/search/preview 并重验 context。
|
||||
|
||||
**API-SETTINGS-006:客户端、无障碍与发布。** 同版双导出绿后,客户端首写先建可执行生产模块的纯 Node 失败测试,再实现 adapter/coordinator 并原子删除 fixture pair、timer、本地成功和 API 禁用旧断言;禁止恒红、token 扫描或测试内参考实现冒充行为证据。G11 覆盖原生 button/radio、label、aria-invalid/describedby、首错聚焦、busy/live、44dp、长文换行、返回冻结和冲突/unknown 草稿保留。OpenAPI、workspace/shared owner、客户端行为门禁、全量回归及 MuMu 原生矩阵任一未绿都不得接远端。
|
||||
|
||||
**关闭条件:** 后端从同一版本重导 JSON/YAML 并同时通过 workspace、join 与 `tests/g11-settings-openapi-contract.ps1`,再完成真实权限/版本/待审竞态/fault injection/HTTP/CORS;客户端随后按测试先行完成可执行 coordinator、页面/缓存/context 原子迁移,最后通过聚焦/全量和 MuMu 320/360/412、1.3 倍字号、TalkBack、软键盘、双击、慢网/断网/杀进程、Android 返回、权限撤销与版本竞态。当前输出 `G11-SETTINGS-OPENAPI-CONTRACT BLOCKED`,48 项缺口;受保护 OpenAPI 未修改。
|
||||
|
||||
### 5.16 后端问题单 API-POEM-001—006
|
||||
|
||||
**优先级:** P0;阻塞 G12 字辈集合真实读取、原子保存、并发恢复、T01 正式消费与发布。
|
||||
|
||||
**API-POEM-001:唯一 owner 与 canonical 模型。** 发布唯一 `GET/PUT /genealogy/app/genealogies/{genealogyId}/generation-poems` 和 `appGetGenerationPoemSet/appUpdateGenerationPoemSet`,删除 collection POST、逐行 PUT、batch preview/save、management 及旧 DTO/response;不新增 preview token/status。GET/PUT 200 共用 closed `RGenerationPoemSetSnapshot → GenerationPoemSetSnapshot`,精确 required genealogyId/poemSetVersion/items,ACTIVE-only 且按 generationNo 升序;GET 重验 canView,PUT 事务内重验 tenant/canEditContent/READY。
|
||||
|
||||
**API-POEM-002:完整候选、软停用与原子写。** body 唯一为 closed required `AppGenerationPoemSetUpdateBody {items,disableMissing}`。items 0—500 严格 generationNo 升序;已有 ID 只允许 baseline ACTIVE 且可显式 move,新行省略 ID,disabled/unknown ID 失败,重复文本允许。false 保留遗漏 baseline,true 软停用;empty false no-op,empty true 停用全部。先校验声明严格升序,再构造声明目标与完整 merged candidate,随后按固定步骤验证唯一/slot/连续/最终容量、分配并校验新 ID,最后原子写;`GENERATION_SLOT_CONFLICT` 与所有校验失败零写,swap 必须显式声明全部受影响行,历史绝不物理删除。
|
||||
|
||||
**API-POEM-003:版本 CAS 与 Unicode。** `GenerationPoemSetVersion` 是 1—128 位 opaque、不可解析、永不复用的 ACTIVE 语义版本,PUT required If-Match,body 无版本,禁止 ETag/412;no-op 保持版本,实际变化生成新版本。poemId/version 均保持词法字符串。`GenerationPoemText` 为 NFC、1—50 Unicode code point、well-formed UTF-16、无边界空白,拒绝控制字符、CR/LF/tab、bidi override/isolate/mark、zero-width/BOM/word joiner、行段分隔符和孤代理;generationNo 是 1—2147483647 的唯一排序 owner。
|
||||
|
||||
**API-POEM-004:typed HTTP、security 与部署 CORS。** GET 精确 200/400/401/404/429/500,PUT 另有 403/409/422;全部 typed `application/json`、private/no-store,429 带 Retry-After,禁止 default/3xx/`*/*`/通用 envelope/200 包业务错。SaToken 精确为 Authorization header apiKey,operation security 是数组且 scopes 为空,clientid required 非空。顶层 closed `APP_GATEWAY_PREFLIGHT` policy 精确允许四个请求头、GET/PUT/OPTIONS、部署 allowlist 与 600 秒;GET/PUT 引用它。后端必须用正式 H5 origin 的真实 OPTIONS/preflight、凭证、拒绝 origin/header/method 反例证明 gateway 实现。
|
||||
|
||||
**API-POEM-005:冲突、unknown 与缓存收口。** 409 只含版本变化+current 与 READY 两分支,422 只含可达请求/候选错误。网络、超时、408、取消、5xx 和畸形 2xx 是 unknown;客户端冻结 baseline/version/declared/disableMissing/sessionEpoch,构造 effective target 后 fresh GET。existing/NEW、同基数、无额外行和版本策略必须按 `FRESH_GET_THREE_WAY_NO_AUTO_PUT` 执行;current==target 优先且不归因,current==old 才可由用户明确重试,其他进入 divergent,不自动 PUT。成功 canonical 回填并失效字辈消费者缓存;权限、READY 或账号变化失败关闭。
|
||||
|
||||
**API-POEM-006:客户端、无障碍与发布。** 同版双导出通过主门禁、zero issues 对抗合同和 Unicode Node 冒烟后,客户端首写先建直接执行生产 normalizer/coordinator 的失败测试,再实现唯一 adapter/coordinator,并原子删除 fixture、timer、本地成功、旧 preview/save 断言与兼容分支。页面覆盖清空确认、loading/empty/editing/saving/saved/unknown/conflict/no-permission、live region、首错聚焦、44dp 和返回冻结;MuMu 覆盖 320/360/412、字号、TalkBack、键盘、0/1/500×50、swap、双击、断网/杀进程、权限撤销、READY 与账号切换。
|
||||
|
||||
**关闭条件:** 后端同版本重导 JSON/YAML 并通过 `tests/g12-generation-poem-openapi-contract.ps1`、对抗合同、真实 DB/并发/fault injection/HTTP/CORS;客户端随后通过生产行为测试、页面原子迁移、聚焦/全量回归与 MuMu 矩阵。当前输出 `G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`Issues: 72`;`G12-GENERATION-POEM-OPENAPI-ADVERSARIAL-CONTRACT PASS` 和 `G12-GENERATION-POEM-UNICODE-RUNTIME-SMOKE PASS` 只证明门禁质量,不解除后端红灯。受保护 OpenAPI 未修改。
|
||||
|
||||
### 5.17 后端问题单 API-FEED-READ-001—006
|
||||
|
||||
**优先级:** P0;阻塞 F01 动态列表和 F03 动态详情/一级评论的生产读取。发布、点赞、评论/回复写及媒体读取不属于本问题单。
|
||||
|
||||
**API-FEED-READ-001:三个稳定 owner 与旧入口删除。** 发布谱内嵌套的 `appListFamilyFeeds/appGetFamilyFeed/appListFamilyFeedRootComments`,全局各唯一;删除两个 `/page` GET,collection GET 使用 cursor。保留 `(genealogyId,feedId)` 复合资源边界,不新增可枚举的全局 feed 路由,不用写方法或 replies 冒充读取 owner。
|
||||
|
||||
**API-FEED-READ-002:词法身份与无 PII 最小 projection。** GenealogyId/FamilyFeedId/FamilyFeedCommentId 均为 opaque string。Feed 只含 `feedId/feedContent/authorDisplayName/publishedAt/hasMedia`,root comment 只含 `commentId/commentContent/authorDisplayName/publishedAt`;closed、required、非 null、有界。排除手机号、账号/业务用户 ID、tenant、status、remark、审核字段、parent/level、删除占位、内部媒体 ID 与持久化字段。`hasMedia` 只触发诚实占位;title/tag/like/count 不从 fixture 或正文猜测。
|
||||
|
||||
**API-FEED-READ-003:对象级授权与非泄露 404。** 每次/每页 fresh 验 tenant、genealogy、membership;详情和评论再验 feed 属于 path genealogy 且可见,评论只读正常 root。未知、错谱、删除/隐藏、撤权、跨主体或 cursor 跨 scope 统一 `FAMILY_FEED_NOT_AVAILABLE`,禁止 403 分流资源存在性;未认证才返回 401。
|
||||
|
||||
**API-FEED-READ-004:keyset cursor 与读取窗口。** `cursor? + limit?`,默认 20、1—50,无 total/pageNum;nextCursor 缺席即结束。feed 用 publishedAt/feedId 倒序,root comment 用 publishedAt/commentId 正序,时间不可变、ID ordinal tie-break。cursor 绑定 actor/session/client/scope/projection/order/limit/windowUpperBound/lastTuple,篡改或过期 typed 400。`UPPER_BOUND_KEYSET_LATEST_VISIBLE` 排除刷新前新增,后续删除/隐藏省略、编辑返回最新可见内容,不伪称严格 snapshot。
|
||||
|
||||
**API-FEED-READ-005:typed HTTP、安全与部署。** 三 GET 精确 200/400/401/404/429/500,只允许 closed typed application/json、private/no-store;429 Retry-After。SaToken 必须是数组且空 scopes,clientid required 非空;禁止 int64、通用 RList/RObject/PageResult、default/3xx/`*/*`/HTTP 200 业务错。复用 `APP_GATEWAY_PREFLIGHT`,正式 OPTIONS/preflight 与拒绝反例由部署证明。
|
||||
|
||||
**API-FEED-READ-006:证据与客户端激活。** 主门禁先以 zero issues 合法种子和 ref/大小写/HTTP 方法/PII/int64/offset/404 分流对抗变异证明自身,再要求后端同版本 JSON/YAML/live、真实权限撤销/跨谱 cursor/并发可见性/HTTP/CORS。后端绿后首写必须是执行生产 read normalizer/coordinator 的 Node 失败测试,再原子迁移 F01/F03,删除 fixture 锁、嵌入 comments、伪重试和旧 fixture 断言;远端失败不回退 mock。完成 sessionEpoch、局部错误、媒体占位、焦点/滚动、无障碍和 MuMu 矩阵后才可发布。
|
||||
|
||||
**关闭条件:** `tests/family-feed-read-openapi-contract.ps1`、对抗门禁、后端运行时反例、同版本三份接口证据、客户端生产行为测试、聚焦/全量回归与 MuMu 矩阵全部通过。当前输出 `FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED`、`Issues: 85`;`FAMILY-FEED-READ-OPENAPI-ADVERSARIAL-CONTRACT PASS MUTANTS=58` 只证明门禁质量,不解除后端阻塞。受保护 OpenAPI 与 F01/F03 页面未修改。
|
||||
@@ -1,100 +0,0 @@
|
||||
# 视觉资产与构建基线
|
||||
|
||||
> 状态:当前有效
|
||||
> 更新日期:2026-07-22
|
||||
> 适用范围:正式运行时图片、可重建视觉资产、构建清单、质量报告与 MuMu 视觉验收
|
||||
|
||||
## 一、所有权边界
|
||||
|
||||
视觉资产分为两类,不能用同一套字段混写:
|
||||
|
||||
1. 已提交二进制:由业务域运行时清单锁定路径、像素尺寸、透明度、字节数与 SHA-256;它们的 `provenance` 必须为 `committed-binary`,且 `rebuildable` 必须为 `false`。
|
||||
2. 可重建资产:由 schema v3 生成清单锁定母版、处理参数、物理输出尺寸和质量阈值;运行时清单只导入它,不复制物理规格。
|
||||
|
||||
schema v3 注册入口是 `design-pipeline/manifests/runtime-assets.json`。任何新增的 `runtime-asset-inventory` 或 `asset-build-manifest` 都必须进入该注册表的导入闭包;未注册 owner、重复资产 `id` 与重复正式输出都会被拒绝。当前 `static/assets` 中的每个文件都必须恰好属于一个正式 owner,并至少存在一个真实运行时消费者。
|
||||
|
||||
导航任务 3 删除了无活动消费者的通用页面旧入口,并同步删除两张仅靠该入口人工补数的 notification frame。当前注册表闭合 `77` 个正式 `static/assets` 输出;family/profile/records 的同名 frame 仍有真实专项 mixin 消费,`ModulePageBackground` 仍有活动页面消费者,均继续保留。`tests/retired-module-page-contract.ps1` 是这次退役边界的防回归所有者。
|
||||
|
||||
认证直接资产由 `design-pipeline/manifests/auth-runtime-assets.json` 管理,其余无法重建但仍被产品消费的直接二进制由 `design-pipeline/manifests/application-runtime-assets.json` 管理。四张共享卷轴、六张长页面背景和 G01 空态边框的生成事实依次只属于 `design-pipeline/manifests/shared-scroll-skins-v3.json`、`design-pipeline/manifests/page-backgrounds-v3.json` 与 `design-pipeline/manifests/g01-state-frame-v3.json`。
|
||||
|
||||
页面、组件、样式、数据映射和工具代码本身是消费者关系的唯一事实源。生成清单不得保存槽位、Vue 组件、选择器、`uni-app mode`、消费者列表或其他运行时渲染语义;这些规则只能由实际消费者源码及对应合同拥有。
|
||||
|
||||
## 二、schema v3 生成清单
|
||||
|
||||
生成清单只允许以下职责:
|
||||
|
||||
- `source`:仓库内可追溯母版;
|
||||
- `processing`:实际由构建器消费的色键、端帽、调色板等处理参数;
|
||||
- `output` 与 `outputPixels`:正式输出路径和像素尺寸;
|
||||
- `alpha`、`edge`、`quality`:由质量分析器真实执行的透明边、边缘污染、体积和色彩空间约束。
|
||||
|
||||
清单、资产及其嵌套对象均拒绝未知字段。不能用近似字段名重新塞入旧合同,也不能声明构建器或质量分析器没有执行的规则。
|
||||
|
||||
## 三、Python 与依赖
|
||||
|
||||
Python 依赖由 `design-pipeline/requirements.txt` 锁定,当前 Pillow 版本为 `12.3.0`。唯一解释器解析逻辑位于 `design-pipeline/scripts/python-runtime.mjs`,顺序为:
|
||||
|
||||
1. 显式 `PYTHON`;
|
||||
2. `design-pipeline/.venv`;
|
||||
3. Windows Python Manager 的真实入口;
|
||||
4. 可实际执行的系统命令。
|
||||
|
||||
所有 Python 构建和测试都通过统一执行器加入 `-B`,禁止在源码目录生成 `__pycache__` 或 `.pyc`。不透明缩放、居中 cover 裁切与暖金边框提取统一由 `design-pipeline/scripts/build_raster_assets.py` 实现,Node 入口只负责严格清单校验、解释器编排和质量审计,不再保留 G01、模块背景或 Sharp 专用分支。
|
||||
|
||||
## 四、当前验证命令
|
||||
|
||||
在 `design-pipeline/` 目录运行:
|
||||
|
||||
```powershell
|
||||
npm.cmd test
|
||||
npm.cmd run validate:shared-scroll-skins
|
||||
npm.cmd run validate:page-backgrounds
|
||||
npm.cmd run validate:g01-state-frame
|
||||
npm.cmd run validate:runtime-assets
|
||||
npm.cmd run build:shared-scroll-skins
|
||||
npm.cmd run build:page-backgrounds
|
||||
npm.cmd run build:g01-state-frame
|
||||
npm.cmd run verify:shared-scroll-skins
|
||||
```
|
||||
|
||||
其中 `npm.cmd test` 同时执行 Node 和 Python 测试。质量报告只允许保存工作区相对路径;同一母版与相同参数连续构建必须产生相同字节哈希和相同报告。
|
||||
|
||||
在项目根目录运行:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File tests/runtime-assets-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests/retired-asset-removal-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests/retired-module-page-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests/a01-retired-pipeline-removal-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests/a01-no-photoshop-pipeline-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests/mumu-visual-acceptance-boundary-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests/project-responsive-layout-contract.ps1
|
||||
powershell -ExecutionPolicy Bypass -File tests/compile-audit.ps1
|
||||
```
|
||||
|
||||
## 五、视觉验收
|
||||
|
||||
- 当前只维护用户确认的浅色国风主题;深色与跟随系统延期到后续独立版本,不能在页面内散落未生效的主题入口或覆盖样式。
|
||||
- 内部响应式基线为 `320×568`、`360×640`、`360×800`、`412×915`;G01 连续长背景另做 `412×1000` 压力检查。这些内部尺寸不能替代最终 MuMu 证据。
|
||||
- 浏览器截图只可用于逻辑调试,不能作为视觉通过证据。
|
||||
- 仓库不再维护自动浏览器截图助手、联系表或截图自证合同;浏览器运行时测试只保留 CDP、DOM、状态、溢出和内容可达性断言,不写入截图。确需临时截图调试时应使用仓库外命令,不能提交为长期证据。
|
||||
- 最终视觉复核只能使用用户当前在线的 MuMu 安卓模拟器,不得由代理启动、关闭或调整模拟器。
|
||||
- 生成成功和像素质量通过不等于页面视觉通过;相关页面仍需在 MuMu 检查默认、错误、取消、完成和重复进入等实际状态。
|
||||
- 不通过压缩字号、行高、控件尺寸或单设备补丁掩盖布局问题。
|
||||
- 普通页面、卡片、表单和说明由内容自然撑高;只有弹窗和明确独立滚动区域可以使用视口 `max-height` 与内部滚动。
|
||||
- 九宫格和 `border-image-slice` 的唯一所有者是 `styles/adaptive-frame-profiles.scss`;Vue 页面和组件只能消费其公开混入,不能直接重复声明。
|
||||
- 响应式扫描范围只属于 `tests/responsive-layout-coverage.json`,固定尺寸例外只属于 `tests/responsive-layout-allowlist.json`。
|
||||
- 安全区、软键盘、约 `1.3` 倍系统字号、长文本和 Android 返回手势必须在对应页面验证;主要触控目标不小于约 `44dp`。
|
||||
- G 系列共享连续家谱背景,T、F、R、N、M 使用各自模块背景;具体消费者、渲染方式和当前视觉数值只由源码及机器合同拥有,本文件不复制尺寸、哈希、透明度或选择器。
|
||||
- G 系列背景映射只由 `components/GenealogyPageBackground.vue` 消费,当前正式运行图是 `static/assets/modules/genealogy/opaque/genealogy-page-background-long.png`;T、F、R、N、M 的映射只由 `components/ModulePageBackground.vue` 消费。等比、裁切、贴底和透明度等渲染数值继续由这两个组件拥有。
|
||||
- 复杂水墨、品牌装饰和完整视觉面使用正式位图;文字、布局、状态与交互由代码承担。整页截图不得成为运行时资产,可变高度装饰不得绕过共享九宫格所有者。
|
||||
- 用户可见示例姓名统一使用“某某某”等通用表达;fixture 和 mock 数据可以保留真实感测试样本,但不能把样本姓名写成产品提示。
|
||||
|
||||
## 六、参考图与正式资产边界
|
||||
|
||||
以下两张图片是用户已批准的 A01 选型证据,只用于后续人工视觉复核,标记为 `reference-only / non-runtime`,不进入运行时注册表,也不能因零代码引用被删除:
|
||||
|
||||
- `docs/design/assets/a01-vnext/A01-shared-scroll-skins-with-dialog-approved.png`
|
||||
- `docs/design/assets/a01-vnext/A01-shared-skin-family-option-2-selected.png`
|
||||
|
||||
G01 的 A/B/C 方向候选、无确定变换的 add-sheet/close 色键源、重复的旗舰 ImageGen 源、旧 `static/icons` 和阶段 0 当时存在的未接入 TAC 旧批次已经退役。`static/tac/` 当前共 5 个文件:4 个后端提供的供应商文件保持原字节,项目只新增 `static/tac/js/jiapu-tac-adapter.js` 作为唯一协议适配层。A01/A04/A05 已通过 `components/TacVerification.vue` 形成真实运行时消费者;这组供应商资产不是视觉构建管线的可再生输出,不进入 `runtime-assets.json`,其存在性、精确文件集合、消费者和哈希由 `tests/auth-tac-integration-contract.ps1` 唯一拥有。受保护哈希分别为 `tac.css=181694518971a9f991d551b6a6e6dab2bf750f940bfc1673a158213f92eedbe0`、`tac.min.js=505f73c051908d7b805db458990790be3e91f792c4001cec0ea9377d7d302b55`、`icon.png=53e37ffc5bb81c46e6306b7d61d2eaa3de57e47ca6cdb8d5210022ae815c21c2`、`dun.jpeg=d9178a8c4cca36e3df6c3acd7e895ce9d34dd60ef3f1cf4a70c94d4324ed96e7`;不得修改、格式化、覆盖或以重新下载文件替换。正式 add-sheet 与 close 位图作为 `committed-binary` 由 `application-runtime-assets.json` 锁定;六张长背景及 G01 空态边框则保留可执行母版和 schema v3 构建链。不得重新引入候选入口、虚构可重建关系或复制第二套 TAC 资产所有权。
|
||||
@@ -1,33 +0,0 @@
|
||||
# 家谱 App 迭代进度记录(完成 70%)
|
||||
|
||||
日期:2026-07-31
|
||||
当前分支:`main`
|
||||
|
||||
## 本轮已完成
|
||||
|
||||
- 完成全项目字体可读性与长文本换行治理,优先保证手机端、长辈用户的阅读体验。
|
||||
- 调整公共页头:项目名称“代代相传”以“Logo + 名称”组合呈现,页面功能标题保持居中;认证页与“我的”页同步使用该品牌组合。
|
||||
- 接入默认头像:男性使用男童国风头像,女性使用唐装女性头像;未选择性别时默认使用男性头像。
|
||||
- 完善成员资料展示,隐藏不应面向普通用户展示的业务用户与内部人物编号信息。
|
||||
- 修复“我的”、家谱、家族、人物录、通知等模块中已发现的文字截断、状态提示与空/错误态表达问题。
|
||||
- 保留 T02 世系谱的参考项目结构,仅做兼容性和可读性处理,未改变其核心展示逻辑。
|
||||
- 新增并通过默认头像、个人资料、消息中心等重点契约检查。
|
||||
|
||||
## 当前状态
|
||||
|
||||
- 整体功能与视觉治理进度:约 70%。
|
||||
- 页面入口已完成全局品牌标识覆盖;业务页面仍可继续在真机/模拟器逐页复核细节。
|
||||
- 相册图片是否能展示取决于接口是否返回可访问的图片地址;当前不伪造图片链接。
|
||||
|
||||
## 在另一台电脑运行
|
||||
|
||||
1. 拉取 `main` 分支的最新代码。
|
||||
2. 使用 HBuilderX 导入项目根目录 `jiapuapp`。
|
||||
3. 等待 HBuilderX 完成编译后,选择“运行到 Android App 基座”并连接 MuMu 或真机。
|
||||
4. 项目所需头像和页面静态资源已随代码提交,不需要单独拷贝资源文件。
|
||||
|
||||
## 后续建议
|
||||
|
||||
- 在目标设备尺寸上复核页头品牌组合、表单按钮与底部导航的间距。
|
||||
- 继续覆盖未登录、空数据、接口异常和超长文本等状态。
|
||||
- 按接口返回能力补充相册图片的真实访问地址或签名 URL。
|
||||
@@ -1,317 +0,0 @@
|
||||
# 项目当前总览
|
||||
|
||||
> 当前阶段:导航任务 1—10、TAC 认证客户端、领域上下文基础与 M07 反馈客户端已经完成;任务 36 普通加入、任务 37 邀请码直入、任务 38 G11 设置和任务 39 G12 字辈集合合同已完成三人审查与失败门禁;任务 40 F01/F03 家族动态读取已完成三方接口定案并建立专项失败门禁,正在收口门禁对抗评审与文档;T01、认证、家谱工作区、G03、加入/邀请/G11/G12、F01/F03 读取、M06、个人资料读写、通知读写、M10、M04 和 M05 后端接口门禁均为红灯,继续逐域关闭真实接口
|
||||
> 当前状态:A01/A04/A05 已接入统一 TAC、真实短信和认证请求代码,M07 已接真实反馈提交 owner;G01/G05、G03、普通加入、邀请码直入、G11、G12、F01/F03 读取、M06、个人资料读写、通知域、退出、密码与换绑域均已完成接口审查并建立失败门禁,均未猜测接线;`runtimeConfig.mode` 仍为 `mock`,MuMu 原生矩阵和真实环境联调待执行
|
||||
> 当前基准 HEAD:`f1edc6b53320755a8638c99d492250153a8dcb17`(`main`,工作区有任务 36/37/38/39 未提交变更)
|
||||
> 更新日期:2026-07-23
|
||||
|
||||
## 2026-07-23 换机续作断点
|
||||
|
||||
### 总目标与完成定义
|
||||
|
||||
本项目的总目标不可缩减为“只写规划”或“只让静态测试通过”:必须在 `main` 工作区内持续推进整个 UniApp 家谱项目,按测试先行和三人交叉评审完成导航、T01 长世代世系树、TAC/认证、家谱领域数据、G/T/F/R/N/M 全量页面与接口、异常恢复、无障碍、构建及上线验证,最终交付能够正常上线使用的项目。若本地可完成的工作全部完成后只剩后端合同重导、有效测试账号、应用签名、发布凭证或 MuMu 人工操作等外部状态,才允许停在明确硬阻塞;每项阻塞必须有失败门禁、复现证据、唯一所有者、解除条件和继续步骤,不能用 mock、fixture、定时器或宽松兼容伪装完成。
|
||||
|
||||
协作固定为当前主代理加两位评审者,共三人。三人都必须独立检查接口/字段、页面/业务闭环、交互/异常/视觉,再交叉质询并统一结论;主代理是唯一写入者,不再创建旧专家身份或增加并发评审者。普通技术取舍由三人自行收敛,不反复交给用户。系统目标已经重新固定为整个项目的可上线闭环并处于 active;只有项目真实达到完成定义时才能标记完成。
|
||||
|
||||
### 仓库与保护基线
|
||||
|
||||
- 当前分支为 `main`,HEAD 为 `f1edc6b53320755a8638c99d492250153a8dcb17`,上游显示 `main...origin/main`。工作区含任务 36/37/38/39 未提交修改和新增门禁,均属于当前连续治理成果;禁止用 `restore/checkout/reset` 清理,也禁止自行改分支或 worktree。
|
||||
- 本节仅记录断点,没有执行 `git add/commit/push`。由用户自行上传;换机后必须保留当前完整工作区,而不能只依赖旧远端基线。
|
||||
- 后端唯一目标地址是 `https://backend-api.ddxcjp.cn/`。受保护 `APP.openapi.yaml` 的 SHA-256 为 `8964CD583CE172425B63BBFD802F7EB587EB3641EADFD6F9D3B264FAA8090C6C`,`APP.openapi.json` 为 `87DB1DC148C5E6E877815AFF7B3A7FC7C7ECA95A2CEC50A88B42F3908961F31A`;两文件相对 HEAD 无差异。不得修改、格式化、覆盖或删除,只接受后端同一版本重新导出的双文件。
|
||||
- 不得启动、关闭或调整 MuMu。浏览器截图和源码检查不能冒充 Android 原生视觉、TalkBack、系统字号、软键盘或返回键验收。
|
||||
- 换机后 fresh 基线已重跑:任务 36 门禁前为 PowerShell `126/140`、14 项预期发布红灯;任务 36 后为 `126/141`。任务 37 新增 `tests/invite-ticket-openapi-contract.ps1` 后物理库存为 PowerShell `142`、Node `47`,全量 fresh 为 `126/142`,16 项均为明确发布红灯;任务 38 新增 `tests/g11-settings-openapi-contract.ps1` 后当前物理库存为 PowerShell `143`、Node `47`,全量 fresh 为 `126/143`,17 项均为明确发布红灯。任务 39 新增 G12 主门禁、对抗合同和 Unicode Node 冒烟后,物理库存为 PowerShell `145`、Node `48`,全量 fresh 为 `127/145`,18 项均为明确发布红灯。任务 40 新增家族动态读取主门禁与对抗合同后,当前物理库存为 PowerShell `147`、Node `48`,全量 fresh 为 `128/147`,19 项均为明确发布红灯;Node 语法 `48/48`、纯 Node `20/20`、活动 Vue 脚本 `64/64` 和编译审计均 fresh 通过。
|
||||
|
||||
### 已完成到哪里
|
||||
|
||||
导航任务 1—10、统一 TAC 客户端、领域上下文基础和 M07 真实反馈客户端已经完成本地可完成部分。T01、认证/TAC、家谱工作区、M06、个人资料读写、通知读写、退出、密码、手机号换绑均已经三人审查并建立明确 OpenAPI 红灯。任务 35 已完成 G03 原子创建合同:否决空谱加通用人物的两写方案,固定一次 atomic bootstrap、无 PII operation-status、统一 accessPreset、可信地区、词法 ID、始祖不变量及客户端激活门禁;`openapi-yaml-json-parity-runtime-smoke.js` 已升级为严格 YAML mapping 和任意精度数字的完整双源深比较。尚未批量把这些红灯域接到宽松线上接口,`runtimeConfig.mode` 仍诚实保持 `mock`。
|
||||
|
||||
### 当前精确断点:任务 36 普通加入申请闭环
|
||||
|
||||
三人已经完成 G06/G08/G09/G10 与 2026-07-22 线上 OpenAPI 的只读核对,范围只包括“鉴权搜索公开可申请家谱 → 普通申请 → 我的申请/撤回 → 待审列表/单条审核”。邀请码校验和直接加入仍是后续独立任务,产品结论保持“邀请码成功后直接加入且不生成审核记录”,不得混入普通审核合同。
|
||||
|
||||
已统一的最小正确方案如下:
|
||||
|
||||
- 搜索、我的申请和待审列表使用各自专用最小投影与稳定 cursor 分页,不返回 `total`,所有 `genealogyId/applyId` 都是有界词法字符串。搜索项只暴露识别家谱所需字段和当前查看者状态;我的申请完整表达 `PENDING/APPROVED/REJECTED/WITHDRAWN`;待审项只含 `applyId/applicantName/relationDesc/applyReason?/submittedAt`,不得泄漏手机号、用户 ID、邀请人或审核人内部字段。
|
||||
- 申请 body 闭合为 `applicantName/relationDesc/applyReason?`,前两项必填;删除 `phone/inviterUserId`。同账号、租户、家谱最多一个活动 `PENDING`,由数据库唯一约束而非先查后插保证。
|
||||
- 申请 POST 必须带无 PII 的 `Idempotency-Key`,并与状态查询的 requestKey 共用唯一 `GenealogyJoinApplicationRequestKey`:`gja.{13 位毫秒时间}.{22—43 位 base64url CSPRNG}`,随机量至少 128 位;`acceptUntil=issuedAt+10 分钟`、未来偏差最多 5 分钟、`resolveBy<=claimedAt+2 分钟`。canonical digest 唯一覆盖 method、规范 path、genealogyId、tenant、account、client 与规范 body;正文统一执行 NFC、去边界空白、CRLF/CR→LF且不折叠内部空白。同 key、同 canonical request 重放同一结果;同 key、不同 digest 返回 409。客户端只持久 `{sessionEpoch,requestKey,startedAt}`,不持久姓名、关系和理由。
|
||||
- 冷启动恢复不复用 `mine` 查询,也不持久表单 PII;新增唯一只读 owner `GET /genealogy/app/genealogies/join-apply-requests/{requestKey}`,以显式 discriminator 返回 `PENDING {resolveBy,retryAfterSeconds}`、`SUCCEEDED {applyId/genealogyId/...无 PII 回执}` 或 `FAILED_NO_COMMIT`。只允许 `ABSENT→PENDING→SUCCEEDED/FAILED_NO_COMMIT`,两个终态不可变;GET 纯读,跨账号/租户/client 统一非泄漏 404,PENDING 必须有收敛期限,从未到达的 key 也必须在可计算时间边界后成为零写 `FAILED_NO_COMMIT`。
|
||||
- 不引入 `applicationVersion`、`If-Match` 或审核详情端点。申请在 PENDING 时不可编辑,撤回、通过和拒绝都以 `WHERE status=PENDING` 的数据库 CAS 决定唯一赢家。重复相同撤回返回同一 200;重复相同审核决定返回原 200,拒绝时只有规范化后理由相同才算相同动作;相反决定、不同拒绝理由或撤回/审核竞态败方返回 typed 409 和当前最小状态。终态不可改,重新申请创建新 `applyId`。
|
||||
- 审核 body 只允许 `APPROVE`,或 `REJECT+必填申请人可见 rejectionReason`。批准必须在同一事务完成唯一成员关系和申请终态;G05 的 `canReviewJoinApplications` 只是入口 capability,服务端在事务/CAS 时仍重新验证权限、家谱状态和 `PUBLIC_APPLY`。
|
||||
- 所有操作 required SaToken 和非空 `clientid`,仅使用 `application/json`、`Cache-Control: private, no-store`,429 带 `Retry-After`。线上三个匿名 GET 当前实测为 HTTP 200 加业务 `code=401`,却与文档 HTTP 401 string 冲突;发布合同必须统一为真实 HTTP 状态与 typed JSON,禁止 `*/*`、200 包装认证错误、`default` 响应和 int64 JSON 身份。
|
||||
- 客户端结果未知时禁止乐观改列表:申请查专用 operation;撤回刷新 mine 并可安全重放同一 DELETE;审核刷新 pending,行消失只能说“状态已变化/已被处理”,不能冒充本次审核成功。首版不承诺消息中心通知;G09 的 `onShow` 与手动刷新是当前业务真相。
|
||||
|
||||
**当前实施边界:** `tests/join-application-openapi-contract.ps1` 已创建并取得精确 `JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`;它成为七个 operation 与 APP 加入 schema 的唯一 owner,旧 `g-series-openapi-contract.ps1` 和 `core-flow-contract.ps1` 不再锁定 `phone/inviterUserId`、数字状态和 `auditRemark`。任务 36 只建立后端合同、权威文档和发布反例,不修改 G06/G08/G09/G10 业务代码;后端门禁通过前页面继续保持诚实本地预览,不写只适配当前宽松线上模型的临时代码。后续客户端批次必须删除 G10 手机号、三处消息中心承诺、`LOCAL_WITHDRAWN` 与遗留 adapter,并以状态机测试和 MuMu 证据完成原子迁移。
|
||||
|
||||
任务 36 已完成本地门禁、`126/141` 全量回归和三人终审,后端缺口继续以发布红灯保留。当前已进入独立任务 37;完成后继续 G11 设置写入、G12 字辈真实保存,以及其余 G/T/F/R/N/M 业务域。不得一次混合导航、验证码、领域持久化和无障碍多个阶段;最终仍须完成真实后端联调、构建、签名/隐私配置、MuMu 全流程矩阵和发布终审。
|
||||
|
||||
### 当前精确断点:任务 37 邀请码签发与直接加入
|
||||
|
||||
三人已对 G06/G08/M08、受保护双导出和 2026-07-23 当前线上 OpenAPI 完成只读审查并交叉反驳。线上 722 条路径中只有通用 promotions 与礼仪邀请,没有家谱邀请码签发、解析、撤销或直接加入 owner。统一结论为六个专用 operation:活动票据列表、无 body 幂等签发、撤销、JSON body 安全解析、无 body 直接兑换、兑换 request-status。
|
||||
|
||||
- 真实流程只在 G06 完成“输入原码→resolve(不消费票据、不建立成员,仅允许轮换短时 grant 摘要)→展示无邀请人 PII 的可信目标→明确确认直接加入且不经审核→redeem→status 收敛→刷新 `/mine`→安装 context→G01/G05”。邀请不再进入 G08;真实接线时删除 G06→G08 invite 导航和 G08 全部 invite source,G08 只归普通申请所有。
|
||||
- 首版票据固定单次、24 小时和至少 128 位随机量;HMAC 查找,隔离 KMS 密文只保留 600 秒同 key 秘密恢复窗。签发 unknown 只重放原 `gii` POST/key,窗后返回 `ISSUED_SECRET_UNAVAILABLE` 且不新签;客户端不持久原码。
|
||||
- resolve 原码只在 JSON body,统一非枚举错误和多维限流;最多五分钟的 redemption token 绑定 tenant/account/client/ticket/version/genealogy/authorizationEpoch,只驻内存。列表、URL/query、导航、storage、日志/APM/分析、错误和除指定成功分支外的响应闭包禁止原码/token。
|
||||
- redeem 不提交姓名、关系或理由,不创建申请、审核记录、人物或亲属关系;事务内原子完成 ACTIVE→CONSUMED、唯一 MEMBER 和成功回执。已有普通 PENDING 引导先去 G09 撤回,不由邀请流程暗改任务 36。
|
||||
- 兑换 unknown 使用 `gir` key 和 PENDING/SUCCEEDED/FAILED_NO_COMMIT 纯读状态收敛;客户端只持久 `{sessionEpoch,requestKey,startedAt}`。FAILED 保证票据未消费、成员未建,成功后的 workspace/context/导航失败只重试本地收口。
|
||||
|
||||
`tests/invite-ticket-openapi-contract.ps1` 已测试先行创建,初次取得 `INVITE-TICKET-OPENAPI-CONTRACT BLOCKED`,经两位评审指出错误 envelope、撤销 CAS、秘密递归闭包、幂等时限、普通申请反向隔离等假绿后已加固到稳定 81 项后端缺口。文档合同、`126/142` 全量 PowerShell、Node `47/47`、纯 Node `19/19`、Vue 脚本 `64/64` 和编译审计均已 fresh 通过预期边界;当前门禁仍保持后端红灯,任务 37 已完成三人终审。后端门禁通过前不修改 M08/G06/G08 业务接线,不用 fixture、定时器或兼容分支伪装邀请码生产闭环。
|
||||
|
||||
### 当前精确断点:任务 38 G11 家谱设置版本化写入
|
||||
|
||||
三人已核对 G11、任务 26 workspace、任务 35 共享 accessPreset、受保护双导出与 2026-07-23 线上 OpenAPI。当前页面仍从 fixture 读取,保存只更新本页 baseline 并用 1800ms timer 显示“尚未提交服务器”;旧双导出 PUT 是宽 `GenealogyUpdateBody → RObject`,线上仍是含十个字段和 `visibility/joinMode` 的宽 `AppGenealogyUpdateBody`,两者都缺版本 CAS、typed 错误与严格权限/媒体合同。
|
||||
|
||||
- 全局唯一写 owner 保留 `PUT /genealogy/app/genealogies/{genealogyId}`,operationId 固定且全局唯一 `appUpdateGenealogySettings`;递归拒绝 PATCH、`/settings` 旁路、任一单字段设置 body/字段写入口,以及用外部或错分区同名 `$ref` 冒充 owner,并删除重复 generic GET。`/genealogy/app/genealogies...` 写 body 根层的 `intro` 明确保留给家谱设置,其他子域必须使用 `albumDesc/articleSummary` 等自身字段名,避免把设置第二写入口伪装成通用简介。workspace 同时递归扫描成功响应闭包,拒绝任何返回 `RAppGenealogyVo/AppGenealogyVo`、allOf 合成或等价实体的旁路详情 GET。G11 只消费 workspace 门禁的 PASS 结论,每次进入 fresh 读取唯一 `/overview` baseline,不信任路由、mine、旧 G05 内存、roleType 或 fixture。
|
||||
- 共享 `GenealogyName` 统一 G03/G11/读取为非 null、NFC、无边界空白、无换行/控制字符的 1—24 Unicode code point;`GenealogyIntro` 精确为空串或规范 1—80,正文只允许内部 LF,拒绝 CR/tab/其他控制字符,空串清空、省略保持。body 关闭额外字段且只允许 1—3 个 `genealogyName/intro/accessPreset` 脏属性,事务内原子 merge;canonical no-op 保留版本且无领域副作用。
|
||||
- 并发与 T01/M02 统一:`AppGenealogyVo.settingsVersion` 与 required `If-Match` 引用同一 opaque owner,以 `x-version-scope-fields` 锁定只随三个 canonical 设置实际变化,body 不重复版本,不另用强 ETag/412。409 根层只含 discriminator/oneOf 且分支为 exact local ref,精确分为版本变化+current、未 READY、活动待审;冲突优先级为 version→READY→active PENDING。
|
||||
- 活动 PENDING 只阻断实际 `PUBLIC_APPLY→MEMBER_ONLY`,整笔零写并引导 G10;不自动处理普通申请,不影响邀请码。设置 PUT 与任务 36 新申请 POST 都在事务内重验准入并共享 `ATOMIC_SINGLE_WINNER`,竞态只能一方提交。
|
||||
- 200 与 overview 共用关闭额外字段的 canonical `RAppGenealogyVo`;所有 component 解析只接受 exact local ref,标量、envelope、引用字段和错误字段以 allowed-key 集拒绝 `format/min/max/readOnly/writeOnly` 等额外约束、冲突组合关键字与 `nullable` 漂移。每个响应必须包含单值 enum 的 `Cache-Control: private, no-store`,429 另含 Retry-After;只允许 `traceparent/tracestate/x-request-id/x-correlation-id` 四种非语义 tracing header,禁止 ETag 与其他语义 header,避免产生第二套并发或缓存 owner。四种 tracing header 使用 component 时同样只能 exact local;内联时必须是 allowed-key 关闭、带非 null 的 string schema 的 Header Object。任务 36 的幂等、cursor、状态迁移、事务与重验扩展必须是真实 JSON 数组,不能用逗号字符串冒充。网络、超时、408、取消、5xx 和畸形 2xx 都是 outcome unknown;fresh overview 对账只陈述当前事实,不自动 PUT 或冒充本次成功。成功失效 mine/overview/search/preview 并重验 context。
|
||||
|
||||
`tests/g11-settings-openapi-contract.ps1` 已测试先行建立,吸收两位评审的全局 owner、workspace 前置、准入反向协调、字符、nullable、exact local ref、固定 header 与纯 discriminator 伪绿反例后稳定输出 `G11-SETTINGS-OPENAPI-CONTRACT BLOCKED`、`Issues: 48`。它接管 PUT、body、settingsVersion/If-Match、409 与响应;workspace/join/G03 门禁分别只保留读取基础、申请准入协调、bootstrap/accessPreset/旧 DTO 删除。本批不创建无法执行生产 coordinator 的占位 client gate;后端同版双导出绿后,客户端第一项写操作必须先建立实际执行生产模块的纯 Node 失败测试,再实现 adapter/page,OpenAPI 绿不等于允许接线。任务 38 完成全量回归与三人终审后继续独立任务 39:G12 字辈真实保存。
|
||||
|
||||
### 当前精确断点:任务 39 G12 字辈集合版本化保存
|
||||
|
||||
三人已完成 G12 页面、共享字辈夹具/Node 冒烟、受保护双导出及现有 G-series 门禁的只读核对,并统一为唯一 `GET/PUT /genealogy/app/genealogies/{genealogyId}/generation-poems`,operationId 分别为 `appGetGenerationPoemSet`、`appUpdateGenerationPoemSet`。旧 collection POST、逐行 PUT、batch preview/save、management 旁路必须同版删除;不引入 preview token、preview/status 接口或第二写 owner。GET/PUT 200 共用 ACTIVE-only `GenerationPoemSetSnapshot {genealogyId,poemSetVersion,items}`,稳定词法 `poemId` 可随 `generationNo` 移动,重复字辈文字允许,排序只由 1—2147483647 的 generationNo 拥有。
|
||||
|
||||
- body 唯一为精确 `{items,disableMissing}` 的 `AppGenerationPoemSetUpdateBody`。声明 items 必须严格递增且最多 500;已有行的 poemId 必须引用 baseline ACTIVE,新行省略 ID。`disableMissing=false` 保留未声明 baseline,`true` 软停用遗漏项;空 false 是 no-op,空 true 停用全部。服务端先构造完整候选集合,再按 generationNo 排序并执行唯一 ID/世代、slot collision、连续性与最终 ACTIVE 容量检查;swap 必须显式提交所有受影响行并原子成功或零写,绝不物理删除历史。候选流程包含 `VALIDATE_FINAL_ACTIVE_CAPACITY`、`ALLOCATE_UNIQUE_NEW_IDS` 及新 ID 非空、唯一、非 baseline 校验,碰撞返回 `GENERATION_SLOT_CONFLICT`。
|
||||
- 并发唯一使用 opaque `GenerationPoemSetVersion` 与 required `If-Match`;body 不复制版本,不引入 ETag/412。canonical no-op 保留版本,语义变化生成永不复用的新版本。GET 重验 canView,PUT 在事务内重验 tenant、canEdit、版本与 READY;响应严格 typed JSON、private/no-store,429 带 Retry-After。正式 CORS 唯一声明 owner 为 `x-app-gateway-policies.APP_GATEWAY_PREFLIGHT`,精确允许 Authorization/Content-Type/If-Match/clientid 和 GET/PUT/OPTIONS;最终仍须用真实 gateway OPTIONS/preflight 证明部署 allowlist,导出声明不能冒充运行证据。
|
||||
- unknown 恢复采用 `FRESH_GET_THREE_WAY_NO_AUTO_PUT`:以 baseline/version、声明项与 disableMissing 构造 effective target;已有项按 ID+generation+NFC 文本匹配,新项按 generation+文本匹配且服务端 ID 必须新鲜。当前集合与 target 相等时执行 `CURRENT_EQUALS_TARGET_FIRST_NO_ATTRIBUTION`,只确认事实而不归因本次请求;仍等于 old 才允许用户明确重试,其他情况进入分歧处理。比较要求同基数、无额外行,语义等价忽略版本,但已变化 target 必须得到新且未复用版本;任何 unknown 后都不自动 PUT。
|
||||
- 字辈文本按 NFC、1—50 Unicode code point、完整 UTF-16 且拒绝边界空白、控制字符、bidi/zero-width 类字符。客户端在后端门禁转绿前继续诚实本地预览,禁止把 fixture、timer 或本地成功接到当前宽松接口。转绿后的第一项客户端写操作必须是直接执行生产 normalizer/coordinator 的失败测试,再原子删除旧 fixture/timer/本地成功和旧合同;随后补 saving/unknown/conflict、清空确认、live region、焦点、44dp 与 MuMu 320/360/412、1.3 倍字号、TalkBack、软键盘、0/1/500×50、swap、断网/杀进程、权限撤销、READY 和账号切换矩阵。
|
||||
|
||||
测试先行证据为 `tests/g12-generation-poem-openapi-contract.ps1` 输出 `G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`Issues: 72`;72 项只指向受保护旧导出的真实路径/schema/header/CORS 缺口。完整 zero issues 合法种子及多跳 ref、callback、HTTP 方法、typed error、候选/unknown/CORS 变异由 `tests/g12-generation-poem-openapi-adversarial-contract.ps1` 证明为 `G12-GENERATION-POEM-OPENAPI-ADVERSARIAL-CONTRACT PASS`;ECMAScript Unicode 边界由 `tests/g12-generation-poem-unicode-contract-runtime-smoke.js` 证明为 `G12-GENERATION-POEM-UNICODE-RUNTIME-SMOKE PASS`。G-series 已删除旧 G12 owner,三人第三轮终审无 P0/P1;受保护 OpenAPI 和页面均未修改。
|
||||
|
||||
### 当前精确断点:任务 40 F01/F03 家族动态读取
|
||||
|
||||
本批只治理 F01 动态列表、F03 动态详情和正常一级评论读取,明确排除 F02 发布、点赞、评论/回复写、回复读取和媒体文件读取。三方已统一唯一 owner 为 `GET /genealogy/app/genealogies/{genealogyId}/feeds`、`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}`、`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments`,operationId 分别为 `appListFamilyFeeds`、`appGetFamilyFeed`、`appListFamilyFeedRootComments`;同版本删除两个 `/page` GET,保留谱上下文嵌套身份,不引入全局 feed 路由。受保护双导出当前仍有 feed list/page 与 comments list/page 双 owner、无 operationId、int64 ID、通用 RList/RObject/PageResult 和开放评论 DTO;2026-07-23 线上 OpenAPI 3.1.0 还显示 `AppFamilyFeedVo/FamilyFeedCommentVo` 无 required,评论投影含手机号和内部审核字段,因此两者都不能接页面。
|
||||
|
||||
`API-FEED-READ-001`—`006` 固定词法 `GenealogyId/FamilyFeedId/FamilyFeedCommentId` 与 closed required 最小投影。`AppFamilyFeedReadItem` 只含 `feedId/feedContent/authorDisplayName/publishedAt/hasMedia`;`hasMedia=true` 时,在媒体读取合同落地前客户端必须诚实展示附件暂不可用占位,不能静默伪装为完整纯文字动态。`AppFamilyFeedRootCommentReadItem` 只含 `commentId/commentContent/authorDisplayName/publishedAt`,只返回正常可见一级评论,不返回删除占位、reply、手机号、账号/业务用户 ID、状态或审核字段。标题、标签、点赞数、总评论数和 fixture 展示时间都不是本批服务端合同,adapter 不得猜值。
|
||||
|
||||
两个 collection GET 使用 opaque cursor,`limit` 默认 20、范围 1—50,不返回 total/pageNum;feed 按 `publishedAt DESC + feedId DESC_ORDINAL`,评论按 `publishedAt ASC + commentId ASC_ORDINAL`。读取窗口精确为 `UPPER_BOUND_KEYSET_LATEST_VISIBLE`:新插入项等刷新后再出现,删除或变为不可见的项在后续页省略,编辑内容按该页读取时的最新可见版本返回,不能宣传为严格 MVCC snapshot。cursor 绑定 tenant/account/authSession/client、谱/动态、projection/order/limit、windowUpperBound 与 lastTuple;每页重新鉴权,篡改或过期为 typed 400,跨主体、错谱、feed 不属于 path 谱、删除/隐藏、撤权或不可见统一 `404 FAMILY_FEED_NOT_AVAILABLE`,不以 403 泄露存在性。
|
||||
|
||||
`tests/family-feed-read-openapi-contract.ps1` 已测试先行取得 `FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED`、`Issues: 85`。85 项全部对应受保护旧导出的双 owner、参数、词法身份、closed projection、cursor、安全、typed JSON、private/no-store、Retry-After、严格 Reference Object 与无 PII 缺口;`tests/family-feed-read-openapi-adversarial-contract.ps1` 以完整 zero issues 合法种子和 58 个独立变异取得 `FAMILY-FEED-READ-OPENAPI-ADVERSARIAL-CONTRACT PASS MUTANTS=58`,覆盖旧 owner、大小写、security owner/数组、int64、PII/审核字段、offset/total、cursor scope/order、403 分流、wildcard、缓存头、外部/多跳 ref、HEAD/OPTIONS/callback 与 schema 关键字旁路。受保护 OpenAPI、F01/F03 和 dormant `appApi.getFeeds` 均未修改。后端绿前 F01/F03 继续使用按 `genealogyId + feedId` 失败关闭的 fixture,禁止接当前宽接口或在远端失败后回退 fixture。后端同版本 JSON/YAML/live 文档全部通过后,客户端第一项写操作必须先建立直接执行生产 read normalizer/coordinator 的纯 Node 失败测试,再原子迁移列表、详情和评论分页,删除 fixture 锁、伪重试与旧“必须 fixture”断言,并补 sessionEpoch、切谱/切账号迟到响应、局部评论错误、诚实媒体占位、焦点恢复和 MuMu/无障碍矩阵。
|
||||
|
||||
## 当前目标
|
||||
|
||||
阶段 0 的清理和验证基线已经完成。当前主代理与两位固定评审者已完成导航任务 1—10,建立路由注册表、导航网关和零债务门禁,并迁移共享组件与认证、G、T、F、R、N/M 全部活动页面。T01、认证/TAC、G01/G05 家谱工作区、G03 原子创建、M06 帮助、M01/M02/M03 个人资料读取、M02 个人资料写入、N01/N02/M01/G01 通知读写、M10 当前设备退出、M04/全认证密码凭证及 M05 手机号换绑的规范 OpenAPI 合同都已测试先行落地;TAC 客户端批次已经完成,A01 短信登录、A04 注册和 A05 忘记密码当前共用严格验证组件、服务端 `validToken`、4 位短信码与可取消请求,但生产 OTP 目标已收紧为统一 6 位,须等待后端同版原子迁移后再替换客户端,禁止 4/6 双接受。领域基础已把会话与当前家谱 ID 收紧为词法字符串:账号切换和损坏存储清理上下文;给定新列表发现历史 ID 消失或显式目标无权时写入持久失效标记,跨重载也禁止静默切谱;T01 也会在写入路由家谱前拒绝已有失效标记和无访问权限的夹具。M07 已按 `POST /genealogy/app/feedback` 接入严格真实提交,mock 模式固定返回 `WRITE_UNAVAILABLE`,不再伪造成功。后端认证门禁未关闭前保持 `mock`;其余尚未接真实写接口的页面仍是明确本地预览或硬关闭。
|
||||
|
||||
## 当前权威资料
|
||||
|
||||
- 治理设计:`docs/家谱项目全量治理设计.md`
|
||||
- 当前实施计划:`docs/家谱项目全量治理实施计划.md`
|
||||
- 视觉资产与构建:`docs/视觉资产与构建基线.md`
|
||||
- 页面、流程与接口关系:`docs/接口与页面映射总表.md`
|
||||
- 接口导出:`APP.openapi.json`、`APP.openapi.yaml`
|
||||
- schema v3 视觉资产注册表:`design-pipeline/manifests/runtime-assets.json`
|
||||
- 九宫格所有者:`styles/adaptive-frame-profiles.scss`
|
||||
- 当前预览密码策略所有者:`utils/validation.js`;生产目标 wire/policy owner 等待 `API-PASSWORD-001`—`005` 关闭后原子替换,禁止单页双轨。
|
||||
- 响应式覆盖:`tests/responsive-layout-coverage.json`
|
||||
- 固定尺寸例外:`tests/responsive-layout-allowlist.json`
|
||||
- 活动路由:`pages.json`;项目固定使用 Vue 3,`uni.scss` 是 Sass 设计令牌唯一入口。
|
||||
|
||||
阶段 0 的临时清理清单已在长期结论迁入当前唯一所有者后删除。旧设计记录、规格、计划、交接和 H5/静态设计图中的有效事实已经迁移,旧文件已删除,不再存在并行入口。
|
||||
|
||||
## 接口文档所有权
|
||||
|
||||
后端维护的 Apifox 项目是接口合同的唯一编辑源。`APP.openapi.json` 用于离线自动扫描和测试,`APP.openapi.yaml` 用于人工阅读与跨工具导入;两份文件都只接受来自同一后端版本的重新导出,不得分别手工维护。部署地址的 `/v3/api-docs` 只作为当前线上实现证据,发现差异时必须推动同版本双导出更新,不能反向覆盖受保护文件。
|
||||
|
||||
当前 JSON 文档为 OpenAPI `3.0.1`,包含 `112` 条路径、`153` 个操作和 `72` 个模型。`tests/openapi-yaml-json-parity-runtime-smoke.js` 已使用无第三方依赖、无损任意精度数字且严格校验 mapping 分隔符的结构化解析器深比较完整 JSON/YAML;相邻不安全大整数差一反例已先红后绿,当前两份受保护快照语义一致。后端今后必须同版本双导出,任何单边漂移都会在领域合同前失败。
|
||||
|
||||
后端在 2026-07-22 新提供 `https://backend-api.ddxcjp.cn/`。同日 21:52(Asia/Shanghai)只读获取其 `/v3/api-docs`,线上为 OpenAPI `3.1.0`、`722` 条路径、`858` 个操作和 `507` 个模型;本地 112 条路径中有 109 条仍在线,`/genealogy/app/files/reference`、`/genealogy/app/files/upload`、`/genealogy/pc/files/upload` 三条不在当前线上文档,线上另有 613 条路径。线上模型已把部分 `Genealogy*Body` 重命名为 `AppGenealogy*Body`,`GenerationPoemBatchBody` 也新增了由路径写入的 `genealogyId` 字段,因此本地双导出是明确的旧快照,不能再代表当前部署的完整合同。`utils/config.js` 的唯一 `baseUrl` 已更新为无尾斜杠的 HTTPS 地址;`mode` 仍保持 `mock`,在页面接口和安全合同逐批闭合前不得提前切换远端。
|
||||
|
||||
线上文档已经提供 `/captcha/require`、`/captcha/challenge`、`/captcha/verify`:挑战与校验绑定 `tenantId/clientId/sceneCode/subject`,校验成功响应可返回 `validToken`,而发送短信的 `AppSmsCodeBody` 已把 `validToken` 列为必填。客户端已按 `APP_SMS_LOGIN/APP_REGISTER/APP_FORGOT_PASSWORD` 三个精确场景实现“查询要求→取得挑战→供应商完成→服务端校验→携票发送短信”,注册和找回提交不重复执行 TAC;认证请求只接受 HTTP 200 的严格 JSON envelope,统一 15 秒超时,离页或返回会中止当前 RequestTask。A01 现以密码登录为默认并接通线上 MD5 wire、`access_token` 持久化与 G01 跳转;默认 mode 仍为 mock。密码联调入口的 static TAC 票据尚未由登录接口消费,因此只是测试性前置,不能冒充服务端强制校验,`API-AUTH-TAC-001` 继续保持发布红灯。
|
||||
|
||||
认证后端门禁仍有四组问题:`API-AUTH-TAC-001` 要求密码登录加入服务端可消费的同语义票据;`API-AUTH-TAC-002` 记录线上 `/captcha/challenge` 在 `APP_REGISTER` 实测返回 HTTP 500 且空响应;`API-AUTH-TAC-003` 要求验证请求以 provider discriminator/`oneOf` 严格关闭根对象和各 payload 的额外字段,并补齐必填 `providerCode/captchaType/payload`;`API-AUTH-TAC-004` 要求同一验证中心返回服务端绑定的 verification session、可验证方法和同一类短时单次 `validToken`,`required=false` 也必须直接签发可供短信接口消费的票据,不得形成无障碍绕过。`tests/auth-tac-openapi-contract.ps1` 当前输出 `AUTH-TAC-OPENAPI-CONTRACT BLOCKED`。密码登录、短信登录和注册的线上成功响应已统一为 `RAppLoginVo → AppLoginVo.access_token`,客户端旧令牌字段读取已删除。线上文档自身仍发布 `http://backend-api.ddxcjp.cn` server URL,与已验证可用的 HTTPS 地址不一致;客户端只能使用显式 HTTPS,后端还需修正文档 server 声明。对 `http://localhost:5173` 的预检已返回允许 `content-type/clientid`,这不能替代正式 H5 域名的 CORS 验证。
|
||||
|
||||
家谱工作区只读审查已固定 `/mine`/`appListMyGenealogies` 为可访问集合 owner、`/{genealogyId}/overview`/`appGetGenealogyOverview` 为 G05 唯一详情 owner;首批不同时请求语义重复的 `/{genealogyId}`。门禁已收紧为 GET-only/no-body、required SaToken/clientid、词法 `GenealogyId`、关闭的成功 envelope、typed HTTP、exact local ref 和固定 private/no-store;`/mine` 以 `OMIT_ONLY_AFTER_CONFIRMED_ACCESS_LOSS` 约束失权省略,overview 以 `NON_DISCLOSING_GENEALOGY_NOT_AVAILABLE` 统一对象无权/撤权/不存在,非法 ID 为 `GENEALOGY_ID_INVALID`。线上 `AppGenealogyVo.genealogyId` 仍是 JSON `integer/int64`,相关模型无 required/canView/角色 enum,无令牌部署又使用 HTTP 200+业务 401,均不能通过。问题单 `API-GENEALOGY-WORKSPACE-001`—`003` 与 `tests/genealogy-workspace-openapi-contract.ps1` 是唯一读取门禁;同版本双导出通过前不写 G01/G05 专属 adapter,不用本地字段猜测替代服务端 owner。
|
||||
|
||||
M06 三人审查选择 `GET /genealogy/app/help-articles` 的完整列表作为唯一远端 owner;线上列表模型已经包含 `helpContent`,因此页面不调用详情端点、不消费 `helpId`,也不让 JSON `int64` 进入页面模型。每次响应只允许显式投影 `helpCategory/helpTitle/helpContent`,分类从当前列表动态派生,展开键只在当前响应生命周期内使用并在搜索、分类、刷新前清空。当前受保护双导出仍返回通用 `ListResult/RList`,线上 `RListHelpArticleVo/HelpArticleVo` 又没有 `required`,正文格式、仅发布内容、展示顺序和认证失败承载也未形成一致合同;匿名实测列表与详情均为 HTTP 200+业务 `code=401`,而线上文档声明 HTTP 401 string。问题单 `API-M06-001`—`003` 与 `tests/help-center-openapi-contract.ps1` 已建立;门禁通过前保留明确本地 FAQ,不写 live-only adapter。
|
||||
|
||||
个人资料读取三人审查固定 `GET /genealogy/app/auth/profile` 为 M01/M02/M03 共用的唯一接口 owner。首批只要求 canonical 11 位 `phone` 必填;`nickName/realName/email` 未设置时唯一省略,出现时必须是非空规范字符串,姓名最多 30、邮箱格式有效且最多 100。adapter 立即把明文手机号变为掩码和读屏标签,只输出固定页面模型;`userId/avatar/status` 等字段全部丢弃,因此它们的 int64/枚举不阻塞本批。受保护双导出仍是通用 `ObjectResult/RObject`,线上 `RAppProfileVo/AppProfileVo` 则无 required 和字段边界;匿名实测仍是 HTTP 200+业务 401,与文档 401 string 冲突。问题单 `API-PROFILE-READ-001`—`003` 与 `tests/profile-openapi-contract.ps1` 已建立;门禁通过前不把 live-only 字段接进页面。
|
||||
|
||||
通知三人审查把读取与写入拆成两个原子批次。读取唯一使用 `GET /genealogy/app/notifications` 和 `GET /genealogy/app/notifications/unread-count`:列表必须完整返回当前账号最多 200 条活动通知并按最新优先,未读数精确统计同一集合;页面只消费完整纯文本标题/正文、带时区时间和 `READ/UNREAD`,所有服务端 ID、发送者与业务目标都不进入公开页面模型。N02 没有详情接口,首批只能以当前内存 `generation+ordinal` 的 `snapshotKey` 打开完整快照,重启、账号切换或成功刷新后的旧 key 均提示返回消息中心重新打开。已读写入另由两个 POST 持有,要求无损字符串 `notificationId`、当前账号幂等、read-all 截止点和并发新消息语义;通过前删除伪本地已读而不发请求。当前受保护双导出的列表仍是通用模型且没有未读数路径,线上模型无 required/枚举/容量,所有 ID 仍为 int64,匿名实测又是 HTTP 200+业务 401。问题单 `API-NOTIFICATION-READ-001`—`003`、`API-NOTIFICATION-STATE-001`—`003` 以及两项失败合同已经建立,均不以猜测代码绕过。
|
||||
|
||||
M02 资料写入三人审查保留现有 `PUT /genealogy/app/auth/profile` 作为唯一 App owner,但要求后端把它正式定义为原子 dirty-only merge,而非全资源替换或依赖 DTO 惯例猜测。请求只允许脏的 `nickName/realName/email`:省略保持,昵称出现时必须非空,真实姓名/邮箱的精确空串表示清空,null、纯空白和边界空白非法;成功返回完整 canonical `RAppProfileVo`,清空后的可选字段仍省略。并发沿用 T01 的单一版本模型:`AppProfileVo.profileVersion` 是 opaque string,PUT 必带同形状 `If-Match`,旧版本返回 409 `PROFILE_VERSION_CHANGED`,H5 CORS 同步允许该 header。受保护双导出还是旧 `ProfileUpdateBody → RObject`,线上则是无 required/merge/version/security 的 `AppProfileUpdateBody → RAppProfileVo`;当前页面还把同一 fixture 名称同时填入昵称和真实姓名,并用 500ms 定时器伪造本地校验。问题单 `API-PROFILE-UPDATE-001`—`004` 与 `tests/profile-update-openapi-contract.ps1` 已建立;GET 门禁和本门禁通过前不接写入。
|
||||
|
||||
M10 退出三人审查固定 `DELETE /genealogy/app/auth/logout` 只撤销请求中 bearer 所属的当前设备凭证族;同账号其他设备保持登录,“全部设备退出”必须另立接口。活动、已撤销和已过期但仍可验证为本 client 签发的历史凭证重复 DELETE 都返回同一个 200 `RVoid`,且成功后旧 token 对任何受保护接口均不可用;伪造、格式非法或 client 不匹配才返回 typed 401 拒绝。客户端唯一 `logoutCoordinator` 在同一同步临界段捕获 A 的 token/clientid、清本地 token/家谱上下文并 bump epoch、用显式快照创建不绑定 M10 生命周期的请求,然后立即 `goRoot(A01)`;异步回调永不再次 clear,避免误删随后登录的 B。线上 endpoint 虽存在,却无 security/clientid、required RVoid、范围/幂等/复用反例和 JSON/no-store;问题单 `API-LOGOUT-001`—`003` 与 `tests/logout-openapi-contract.ps1` 已建立。任何远端失败都不恢复本地 token,只区分“已从本机退出;服务器撤销已确认/未确认/未能撤销”。
|
||||
|
||||
M04 改密三人审查否决当前登录/注册/找回/改密共用的静态 32 个十六进制字符 MD5 wire:它是可直接重放的密码等价物,也使服务端无法执行真实新密码策略。唯一生产目标是四条入口原子迁移到 HTTPS 中的 raw `writeOnly` 密码;当前密码与登录兼容 1—64 Unicode code point,新密码统一 15—64 code point、NFC、允许空格与 Unicode、无组成规则,并由服务端执行常见/泄露密码 blocklist、账号限速和带独立盐的自适应慢哈希。M04 当前密码就是重新认证,TAC 不替代身份;用户明确要求的 A01/A04/A05 TAC 仍由原认证门禁持有。严格 200 前服务端必须原子落密、提升 `credentialEpoch` 并撤销包括调用者在内的所有 access/refresh session,客户端清本机回 A01;网络、超时、畸形响应或 5xx 也是结果未知,同样清本机且不自动重试。问题单 `API-PASSWORD-001`—`005` 与 `tests/password-change-openapi-contract.ps1` 已建立;门禁通过前 M04 保持诚实本地预览。
|
||||
|
||||
M05 换绑三人审查否决“活动 bearer+新号验证码”直接改号:这只能证明控制新号码,不能证明当前账号本人。唯一生产流程是活动 session、最终 PUT 内 raw `currentPassword` 重新认证、`APP_PHONE_CHANGE` TAC 和新号严格 6 位 OTP;不强制旧号 OTP,避免用户丢失旧号时永久锁死,但成功事务必须持久写入旧号安全通知 outbox。标准 OpenAPI 无法按公共发码 body 的 `sceneCode` 条件化鉴权,因此采用独立且强制 SaToken 的 `POST /genealogy/app/auth/phone/sms/code`,scene 由路径固定;公共 `/auth/sms/code` 删除 `APP_PHONE_CHANGE`,两个 operation 仍复用同一 OTP 生成、限速和存储 owner。最终 `PUT /auth/phone` body 只含 `currentPassword/phone/smsCode`,在同一事务内消费 OTP、执行号码唯一约束、更新号码、提升 `credentialEpoch`、撤销包括当前在内的全部 access/refresh session并写通知 outbox,严格 200 返回 `RVoid`。无密码账号返回 `STEP_UP_UNAVAILABLE`,不能降级;最终 PUT 的超时、5xx、畸形响应或进程终止均按结果未知清本机回 A01且不自动重试。问题单 `API-PHONE-001`—`005` 与 `tests/phone-change-openapi-contract.ps1` 已建立;M04 raw-password 门禁、认证/TAC 门禁和本门禁通过前,M05 保持诚实本地预览。
|
||||
|
||||
G03 创建链路三人反向质询后否决“先建空谱、再写始祖”的 `ROOT_REQUIRED` 两写方案:当前产品没有跨会话保存空谱的需求,而两写会凭空增加半成品配额、可见性、恢复、取消、过期和第二次未知结果。唯一生产目标是第一步只在本页收集资料,最终按钮以 `AppGenealogyBootstrapBody` 一次原子创建家谱、OWNER 成员关系、带数据库权威标记的唯一一世始祖、READY 状态和幂等回执;通用人物 collection、人物 DELETE 与 parents mutation 必须阻断第二根、删除根和重挂父母,人物 PUT 对根的可编辑白名单精确只有 `name/sex/birthDate/biography`,其他字段全部 typed 422。首次 POST 先以短控制事务认领 PENDING/digest/fencing,再由业务事务完成全部写入,任一步失败全回滚并 CAS 终态;结构化转换只允许 `ABSENT→PENDING→SUCCEEDED/FAILED_NO_COMMIT` 且终态不可变,FAILED 机器保证零领域写与零 quota,PENDING 的 `resolveBy<=claimedAt+2 分钟`。`GenealogyBootstrapOperationKey` 由 13 位服务端判定的 issuedAt 毫秒与至少 128 位 CSPRNG 组成,`acceptUntil=issuedAt+10 分钟`、最大未来偏差 5 分钟,并由 600/300 秒扩展锁定;operation-status GET 无 body、纯读且只返回显式 discriminator 的三个状态,截止前 404 保持同 key,截止后无记录按 key 计算 FAILED 而不写墓碑。请求使用受鉴权 `/genealogy/app/region/search`、词法 `GenealogyRegionCode`、服务端 `selectable` 和统一 `GenealogyAccessPreset=MEMBER_ONLY/PUBLIC_APPLY`,同版删除公共地区旧路由,并递归清除组合 schema 中的 `visibility/joinMode` 及旧 create/update DTO;G11 在本批只取得共享字段形状,其 If-Match、版本/CAS、权限刷新与结果未知仍是独立门禁。客户端仅持久 `{sessionEpoch,operationKey,startedAt}`;`IDEMPOTENCY_KEY_REUSED` 必须进入 fatal/quarantined,禁止查询或安装 status、自动换 key,只有用户明确放弃才能清理;其他分支按可证明未提交与 unknown 分离。成功固定按 receipt→`/mine` cache→context→G05 收口,context/导航失败只重试本地闭环。问题单 `API-G03-001`—`005`、完整双源深比较、后端 `tests/g03-bootstrap-openapi-contract.ps1` 和实际执行状态机套件的客户端 `tests/g03-bootstrap-client-release-gate.ps1` 已建立;G03 两门禁转绿仍不能绕过家谱工作区读取门禁、聚焦/全量回归与 MuMu 原生验收,全部通过前保留诚实本地预览,不接 `appApi.createGenealogy`。
|
||||
|
||||
当前 JSON 的 SHA-256 为 `87db1dc148c5e6e877815aff7b3a7fc7c7eca95a2cec50a88b42f3908961f31a`,YAML 的 SHA-256 为 `8964cd583ce172425b63bbfd802f7eb587eb3641eadfd6f9d3b264faa8090c6c`。两份文件均已被 Git 跟踪,当前相对 HEAD 无差异;本轮没有改写、格式化或覆盖接口导出。
|
||||
|
||||
## 必须保护的用户文件
|
||||
|
||||
- `APP.openapi.yaml`、`APP.openapi.json`:后端接口离线源快照,只接受同一后端版本的双导出替换,不得手工修改。
|
||||
- `static/tac/`:当前共 5 个文件,其中 4 个是后端提供且不可改写的供应商文件,第 5 个是项目适配器 `static/tac/js/jiapu-tac-adapter.js`;A01/A04/A05 已形成真实运行时消费者,文件集合与供应商哈希由 `tests/auth-tac-integration-contract.ps1` 唯一保护。
|
||||
- 当前五份中文治理文档:长期唯一入口,随已验证进度同步更新,不另建平行计划。
|
||||
|
||||
任何清理批次都不得覆盖、恢复或删除以上文件。
|
||||
|
||||
## 清理前基线
|
||||
|
||||
- 五个核心验证:全部通过。
|
||||
- PowerShell 合同:`129` 个,`128` 个通过,`1` 个旧 A01 固定画布合同失败。
|
||||
- Vue 覆盖:实际 `66`、清单 `66`、缺失 `0`、陈旧 `0`。
|
||||
- Vue 中 `100% 100% no-repeat`:`0`。
|
||||
- Vue 中直接声明 `border-image-slice`:`0`。
|
||||
- 文档:`261` 个;PowerShell 测试:`129` 个;Node 测试:`29` 个。
|
||||
- `static/`:`128` 个正式文件,约 `95.45 MiB`。
|
||||
|
||||
以上数字只记录清理起点,不是必须保持的目标。
|
||||
|
||||
## 阶段 0 最终结果
|
||||
|
||||
- 旧 A01 固定画布、PSD、Photoshop、v2 按钮和旧卷轴入口已经三人一致退役;没有通过重建旧预览制造假绿。
|
||||
- schema v3 注册表已经完整覆盖当前 `static/assets`:认证直接资产、其余应用直接资产、共享卷轴、六张长页面背景和 G01 空态边框各有唯一 owner;旧 G01 候选与模块背景清单及注册例外已经删除。
|
||||
- `design-pipeline/manifests/shared-scroll-skins-v3.json` 只拥有母版、处理、物理输出和质量规则,不再拥有页面槽位或 `uni-app mode`。
|
||||
- 阶段 0 验收时,`tests/runtime-assets-contract.ps1` 精确闭合 `79` 个正式输出、物理文件和源码消费者;导航任务 3 又删除了退役通用页面唯一虚构消费的两张 notification frame,当前正式输出为 `77` 个,并由 `tests/retired-module-page-contract.ps1` 防止旧入口与孤立资产回归。
|
||||
- 设计管线当前为 Node `25/25 PASS`、Python `19/19 PASS`;四张共享卷轴、六张长背景和 G01 空态边框均可真实重建并通过质量审计。
|
||||
- 质量报告只含工作区相对路径;确定性测试证明相同输入连续两次得到相同字节哈希与报告。
|
||||
- 六张长背景与 G01 空态边框迁移后的可见像素哈希逐张等于迁移前正式图;连续两次构建的文件 SHA-256 也完全一致。旧 Sharp 单用途依赖和专用构建器已删除。
|
||||
- 已删除 `28` 个无运行时消费者的 `static/assets`、`3` 个旧 `static/icons`、`4` 个未接入业务的 TAC 文件和 `8` 个候选或伪母版;两张用户批准的 A01 选型图作为 `reference-only / non-runtime` 视觉锚点保留。
|
||||
- 阶段 0 验收时的 MuMu 证据:`emulator-5554` 当时在线,ADB 设备字段为 `model:SDY_AN00`,系统型号为 `SDY-AN00`,物理尺寸 `720×1280`,density `320 dpi`。本轮原生截图逐张打开复核了 A01、G01、T01 和 F01,未见缺图、透明错误、异常裁切或样式回退;复核结束后已回到 A01 页面,未启动、关闭或调整模拟器。
|
||||
- `docs/接口与页面映射总表.md` 已按 `pages.json` 建立 `52/52` 活动页面映射;A04、G 系列第一轮、T01 和新线上 OpenAPI 差异已有专项结论,其余具体接口仍标记为“待对应业务阶段 OpenAPI 审查”。
|
||||
- 第一轮六项产品优化已经完成:G01/G06 统一读取受控查询参数,G03 在本轮进一步删除了无业务参数的 `onLoad`;AppDialog 统一安全区与高度预算;AppTabbar/GenealogyCard 补齐可访问点击语义;G10 拒绝原因建立错误关联与失败聚焦;A04/A05/M04 统一消费唯一密码策略;T01 可在视图漂移后精确回到当前成员。
|
||||
- 后续产品阶段按顺序为导航栈语义统一、T01 大规模世系树、短信验证码完整状态机、跨页面领域数据持久化、全局文字层级和无障碍第二轮;不得混合实施。
|
||||
- 文档权威迁移已删除 `198` 个旧 Markdown、`35` 张旧 H5/静态设计图、`4` 个只保护旧资料的测试和 `.superpowers/sdd` 的 `12` 个过程文件;阶段 0 临时清单随后也已删除,当前 `docs/` 只保留 `5` 个长期中文 Markdown 入口。
|
||||
- 浏览器截图链已把 G03、G06、G08—G12、T06、F02、N01 的有效状态断言迁回各自现有运行时合同;G01、T03—T08、T07 三个有价值的浏览器测试只剥离截图写盘,继续验证状态、滚动、溢出与交互。
|
||||
- 已删除固定 Chrome 截图助手、联系表、8 个只保护截图助手的合同,以及迁移后重复的 N01/A02 合同;`tests/mumu-visual-acceptance-boundary-contract.ps1` 现在唯一约束“仓库不维护自动截图证据链、最终视觉通过只来自 MuMu”。
|
||||
|
||||
当前物理库存为 `147` 个 PowerShell 合同、`48` 个 Node 文件和 `4` 个 JSON 合同数据文件。最新 fresh 结果为 PowerShell `128/147` 通过;其余 19 项不是可删除的普通回归,而是保留真实外部或发布阻塞的 `tests/lineage-openapi-contract.ps1`、`tests/auth-tac-openapi-contract.ps1`、`tests/genealogy-workspace-openapi-contract.ps1`、`tests/g03-bootstrap-openapi-contract.ps1`、`tests/g03-bootstrap-client-release-gate.ps1`、`tests/help-center-openapi-contract.ps1`、`tests/profile-openapi-contract.ps1`、`tests/profile-update-openapi-contract.ps1`、`tests/notification-read-openapi-contract.ps1`、`tests/notification-read-state-openapi-contract.ps1`、`tests/logout-openapi-contract.ps1`、`tests/password-change-openapi-contract.ps1`、`tests/phone-change-openapi-contract.ps1`、`tests/join-application-openapi-contract.ps1`、`tests/invite-ticket-openapi-contract.ps1`、`tests/g11-settings-openapi-contract.ps1`、`tests/g12-generation-poem-openapi-contract.ps1`、`tests/family-feed-read-openapi-contract.ps1` 和缺少 MuMu 人工证据时必须失败的 `tests/auth-android-accessibility-release-gate.ps1`。十九个输出分别为 `LINEAGE-OPENAPI-CONTRACT BLOCKED`、`AUTH-TAC-OPENAPI-CONTRACT BLOCKED`、`GENEALOGY-WORKSPACE-OPENAPI-CONTRACT BLOCKED`、`G03-BOOTSTRAP-OPENAPI-CONTRACT BLOCKED`、`G03-BOOTSTRAP-CLIENT-RELEASE BLOCKED`、`HELP-CENTER-OPENAPI-CONTRACT BLOCKED`、`PROFILE-OPENAPI-CONTRACT BLOCKED`、`PROFILE-UPDATE-OPENAPI-CONTRACT BLOCKED`、`NOTIFICATION-READ-OPENAPI-CONTRACT BLOCKED`、`NOTIFICATION-READ-STATE-OPENAPI-CONTRACT BLOCKED`、`LOGOUT-OPENAPI-CONTRACT BLOCKED`、`PASSWORD-CHANGE-OPENAPI-CONTRACT BLOCKED`、`PHONE-CHANGE-OPENAPI-CONTRACT BLOCKED`、`JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`、`INVITE-TICKET-OPENAPI-CONTRACT BLOCKED`、`G11-SETTINGS-OPENAPI-CONTRACT BLOCKED`、`G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED` 和 `ANDROID-AUTH-ACCESSIBILITY-RELEASE BLOCKED`。Node 语法 `48/48` 通过,纯 Node 冒烟 `20/20` 通过,活动 Vue 脚本模块语法 `64/64` 通过;导航源码扫描保持 `MIGRATION-DEBT=0`。依赖 `127.0.0.1:9222` 调试页的浏览器运行时文件本轮只做语法检查,没有执行;这不能冒充浏览器行为或 MuMu 原生视觉通过。
|
||||
|
||||
阶段 0 清理结束时,`static/` 的正式基线为 `79` 个文件、共 `70,414,397` 字节。任务 3 退役两张孤立通知 frame 后,正式 `static/assets` 为 `77` 个文件、共 `69,093,742` 字节;`static/tac/` 当前 5 个文件、共 `68,190` 字节,因而当前 `static/` 物理库存为 `82` 个文件、共 `69,161,932` 字节。4 个供应商文件保持原字节并由哈希合同保护,新增适配器是唯一项目映射层;TAC 已进入 A01/A04/A05 业务运行时,但不属于可重建视觉资产注册表。`tmp/`、`unpackage/` 和 `design-pipeline/generated/` 均不存在;正式生成资产仍由清单和构建器恢复,质量报告不作为长期资料保留。
|
||||
|
||||
任务 36 新增门禁后,当前物理库存更新为 PowerShell `141`、Node `47`、JSON 合同数据 `4`;新增门禁已独立验证为 `JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`。全量 fresh 复核为 `126/141`,新增加入申请红灯与原 14 项共同构成 15 项明确发布阻塞;上文 `140/47` 与 `126/140` 仅是新增门禁前的换机 fresh 基线,不能把两个时点混写为全部通过。
|
||||
|
||||
任务 37 新增邀请码门禁后,当前物理库存为 PowerShell `142`、Node `47`、JSON 合同数据 `4`;全量 fresh 为 `126/142`,新增 `INVITE-TICKET-OPENAPI-CONTRACT BLOCKED` 后共有 16 项明确发布阻塞。任务 36 的 `126/141` 是上一时点证据,不得冒充当前库存。
|
||||
|
||||
任务 38 新增设置门禁后,当前物理库存为 PowerShell `143`、Node `47`、JSON 合同数据 `4`;全量 fresh 为 `126/143`,新增 `G11-SETTINGS-OPENAPI-CONTRACT BLOCKED` 后共有 17 项明确发布阻塞,专项门禁稳定为 `Issues: 48`。
|
||||
|
||||
任务 39 新增 G12 主门禁、对抗合同和 Unicode 冒烟后,当前物理库存为 PowerShell `145`、Node `48`、JSON 合同数据 `4`;全量 fresh 为 `127/145`,对抗合同转绿而主门禁新增第 18 项发布阻塞。专项结果为 `G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`Issues: 72`、`G12-GENERATION-POEM-OPENAPI-ADVERSARIAL-CONTRACT PASS` 和 `G12-GENERATION-POEM-UNICODE-RUNTIME-SMOKE PASS`。
|
||||
|
||||
任务 40 新增家族动态读取主门禁与对抗合同后,当前物理库存为 PowerShell `147`、Node `48`、JSON 合同数据 `4`;全量 fresh 为 `128/147`,主门禁新增第 19 项发布阻塞,对抗合同本身通过。专项结果为 `FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED`、`Issues: 85` 和 `FAMILY-FEED-READ-OPENAPI-ADVERSARIAL-CONTRACT PASS MUTANTS=58`;它没有修改受保护 OpenAPI 或页面,也没有把线上宽松 DTO 当作可用合同。
|
||||
|
||||
## 当前规划结论
|
||||
|
||||
### 导航栈
|
||||
|
||||
- 迁移前 52 个活动页面只读统计为 `navigateTo 59`、`navigateBack 11`、`redirectTo 14`、`reLaunch 7`,活动页面合计 91 次;活动组件另有 4 次,封存 A06 另有 2 次。任务 3—9 已依次迁移共享组件、认证、G、T、F、R、N/M,任务 10 删除最后一个无消费者旧表单组件并关闭门禁。当前 pages/components 中 `navigateTo`、`navigateBack`、`redirectTo`、`reLaunch`、`getCurrentPages` 和业务页面路径字面量均为 `0`,`switchTab` 全项目为零;五种 Uni 导航调用和页面栈读取只允许由 `utils/navigation.js` 持有,业务路径只允许由 `utils/navigation-routes.js` 持有。
|
||||
- MuMu 已复现 F01→F03 返回后残留两个 F01、A01→A04→登录后残留两个 A01、T03 同路由连续叠页,以及栈深为 1 时 F03 错回 G01。
|
||||
- 三人终选并已实现两个唯一所有者:`utils/navigation-routes.js` 持有 52 条路由、父页参数映射和结果操作枚举,`utils/navigation.js` 持有五种 Uni 导航 API、五个公开导航语义方法、一次性结果与统一返回优先级;没有真实替换边,因此不公开替换方法。
|
||||
- G01、F01、M01 保持自定义 Tab 根页;A01 是认证根页。T03 只保留一个原生页面实例,初始路由 `personId` 是不可变宿主页身份,亲属浏览使用页内成员轨迹和可变活动成员;T05 本地预览离开使用 `goBack()`,不会把活动成员误写成宿主页路由身份。
|
||||
- 任务 1—10 已完成测试先行和静态实现;一次性结果绑定真实目标路由与业务参数上下文,只能由当前真实栈顶目标页消费。52 个活动路由、共享组件、四个根语义以及认证、G、T、F、R、N/M 系列均已迁移;通知目标只能由本地类型白名单映射,未知或越权目标失败关闭。未接真实写接口的页面只能形成明确的本地预览或硬关闭,不再展示伪保存、伪邀请码、伪订单或伪安全结论。任务 4—10 的 MuMu 原生流程复核仍因本轮禁止触碰模拟器而待执行,静态零债务不能替代该验收。
|
||||
|
||||
### T01 大规模世系树
|
||||
|
||||
- 此前默认 6 人数据中的 103→106 断线已通过唯一成员 owner 与字符串 `parentId` 修复;普通节点实际半高与全局常量仍相差约 4rpx,10×12 压力数据约 45/54 个父分组仍会断线,而旧测试只检查线段数量。
|
||||
- 当前布局最坏为 `O(G×N)`,单人一代时接近 `O(N²)`;页面与 mock 已统一当前阶段的 `id/parentId` 夹具,但 OpenAPI 仍使用递归 `children/spouses`,无法直接对接未来规范图窗口。
|
||||
- 产品终选“焦点成员渐进窗口+独立全谱概览”,初始上二代/下二代;主世系为骨架,配偶并排,每段家庭关系有独立联合点,子女从对应联合点向下。
|
||||
- 技术终选视口大小的单 Canvas 同画节点和边;纯 JavaScript 按“规范化→严格校验→可见投影→确定性布局→Scene/空间索引→相机”处理,DOM 只保留页头、工具条、两档抽屉、搜索、概览和无障碍线性列表。
|
||||
- 本地旧导出和 2026-07-22 线上 OpenAPI 都只有 v1 `/lineage/tree`,仍是递归模型,并缺少 overview、locator、稳定关系寻址和树版本并发合同。最新线上文档的 `722` 条路径中没有任何 `/genealogy/app/v2/`,`507` 个模型中也没有新图辨识字段,四个稳定业务码同样缺失。后端问题单 `API-T01-001` 已固定四条 v2 路径、FOCUS/BOUNDARY 查询、`schemaVersion/treeVersion`、EMPTY/POPULATED 空谱判别、窗口入口与全谱根分离、严格匿名节点、以 `relationshipKind` 判别的可寻址伴侣/父子关系、空 PATCH 错误码和 Scene 原子版本;`tests/lineage-openapi-contract.ps1` 已建立严格红灯,在同版本线上文档与双导出通过前,T01 客户端不得开始任务 12。
|
||||
- 当前实施轮没有改写 OpenAPI 文件,也没有启动、关闭或调整 MuMu;已完成导航共享所有者、共享组件/根页头部语义、退役死入口、认证、G 系列、T 系列和 F 系列导航合同,以及树成员与家族内容夹具统一。认证请求代码已对准真实端点,但运行模式仍失败关闭;G/T/F 系列真实写接口与 T01 新图尚未接入。
|
||||
|
||||
### TAC 认证与无障碍安全边界
|
||||
|
||||
- `utils/auth-verification.js` 是当前认证场景、4 位短信码和服务端票据形状的唯一客户端 owner;生产目标由后端 `SmsCodeSecret` 和 `tests/phone-change-openapi-contract.ps1` 锁定为严格 6 位,门禁通过时必须一次替换所有活动消费者并删除旧 owner 的四位规则。`components/TacVerification.vue` 是验证浮层与 renderjs 生命周期 owner;`static/tac/js/jiapu-tac-adapter.js` 是 TianAi challenge/proof/verify 映射 owner;`utils/api.js` 是严格 HTTP 200 envelope、15 秒超时、离页中止、认证会话写入和反馈 wire payload 的唯一 owner。旧认证专用请求控制器入口、占位验证、伪验证码、宽松令牌兼容和 M07 假提交均已删除。
|
||||
- A01 默认密码登录,线上 wire、TAC 前置、token 保存和 G01 跳转已有可执行纯 Node 状态机证据;默认 mode 仍为 mock,且密码登录未消费 `validToken`,故 `API-AUTH-TAC-001` 仍是生产发布阻塞。A04/A05 都只在发送短信前验证一次,并在手机号改变后使旧验证码上下文失效;成功、失败、取消、重复回调、空响应、非 JSON、超时、离页和返回键均有静态或纯运行时合同。短信发送与重设密码的 `RVoid` 没有声明 `data` 必填,客户端因此只要求合法 HTTP 200 与整数成功 `code`,并把“省略 data”或 `data:null` 都精确归一为 `null`;登录、注册和 challenge 等有实体响应仍强制 `data`。
|
||||
- 当前客户端浮层已补齐对话框命名、说明关联、初始聚焦、Tab 圈定、Escape/Android 返回、焦点恢复、原生刷新与关闭按钮、48px 目标及小视口内部滚动;这只是客户端壳层预检,不代表第三方滑块本身可由 TalkBack 或键盘完成。`tests/auth-android-accessibility-release-gate.ps1` 要求 MuMu 原生证据与非拖动等价验证方式,证据缺失时固定输出 `ANDROID-AUTH-ACCESSIBILITY-RELEASE BLOCKED`。
|
||||
- 三人交叉质询后的唯一方向是“同一验证中心、同一短时单次 `validToken`、供应商无关的服务端决策”,永久禁止 `accessibility=true`、跳过 TAC 或无票据发短信。中国大陆非交互风控供应商只进入限时 POC,必须在真实 UniApp Android WebView 中证明 TalkBack、外接键盘和 Switch Access 无焦点陷阱且误杀、防刷、弱网与故障指标达标,不能预先写成无障碍完成。已安全绑定设备只能作为加权信号;供应商不确定或不可用时进入支持文字/中继的可审计人工兜底或稍后重试,绝不 fail-open;音频验证码仅为后续独立 POC 候选,不能作为 P0 或唯一替代。
|
||||
|
||||
### 领域上下文与 M07 反馈
|
||||
|
||||
- `utils/genealogy-context.js` 只接受无边界空白的非空词法字符串 ID,并持有独立失效标记;`utils/session.js` 在损坏令牌、退出和账号令牌变化时同步清理 ID 与标记。首次且没有历史选择或标记时可确定选择首个可用家谱;针对调用方提供的新列表,历史选择消失或显式目标不可用时写入标记并由 G01 要求用户明确重选,跨重载也禁止静默串谱。真实后台撤权能否被及时发现仍取决于后续 workspace 的 onShow/事件刷新。
|
||||
- `appApi.submitFeedback` 是反馈提交唯一 owner:只接受 `feedbackContent` 必填、`feedbackType/contactInfo` 可选的三个字符串字段,trim 后删除空选填值;调用方不能关闭认证头。remote 精确 POST `/genealogy/app/feedback`,只认 HTTP 200 且 `code` 为整数成功码的 envelope;反馈响应没有声明 `data` 必填,页面也不消费返回实体。mock 固定失败关闭且不调用网络。
|
||||
- M07 提交中禁用输入并使用提交前快照;成功后保留回执内容并禁止原样重复提交,请求期若仍有迟到输入则明确区分“上一份已提交”和“当前修改未提交”。超时、断网、意外 2xx/3xx、HTTP 408/5xx 或响应无效进入 `uncertain`,同一快照禁止重提;unknown 回流也会重新比较当前表单,迟到输入保持可提交而不冒充旧快照。只有确定拒绝才允许重试。`tests/m07-feedback-state-runtime-smoke.js` 已直接执行这些页面状态;真实服务联调仍受认证远端门禁约束。
|
||||
|
||||
### 家谱工作区远端门禁
|
||||
|
||||
- 三人反向质询后没有要求后端把 `AppGenealogyVo` 全部字段设为必填,也不把缺少 `security` 注解或文档媒体类型 `*/*` 单独宣称为数据泄漏。首批只消费 `genealogyId/genealogyName/canView/canManage/canEditContent/roleType`;前五项需明确类型并必填,`roleType` 还需非空正式枚举。地点、堂号、人数和简介可选并由页面诚实降级,未知额外响应字段允许忽略。
|
||||
- JSON 响应身份必须使用非空词法字符串。仅在客户端拒绝 unsafe number 虽可避免串谱,却会让 OpenAPI 合法的 int64 用户永久不可用,不能作为普遍上线方案;URL path 在 wire 上本就是文本,不机械要求为了同一问题改类型。
|
||||
- `/mine` 必须以必填 `canView` 或等价、可自动验证的投影保证只把当前账号仍可查看的家谱送入 context;G01 只有成功取得新列表才 reconcile。网络、超时和 5xx 保留旧现场并显示错误,明确撤权/无权/不存在才写 tombstone。G05 使用 `/overview`,取消迟到请求并在新身份加载前清掉旧数据,远端失败绝不回退 fixture 角色。
|
||||
- OpenAPI 注解修复后仍须用有效账号执行无凭证、跨账号、撤权、删除、5xx、畸形 JSON 和取消反例;当前无令牌 HTTP 200+业务 `code=401` 的承载方式可以保留,也可改规范 HTTP 状态,但文档、运行时 validator 与部署行为必须一致。
|
||||
|
||||
### M06 帮助内容远端门禁
|
||||
|
||||
- 首批只使用 `/genealogy/app/help-articles` 一次取得完整正文;详情接口、文章深链、封面、浏览量和业务 ID 均不属于 M06。adapter 只准输出 `{category,title,content}` 与当前响应生命周期的展示键,必须显式丢弃 `helpId/status/sortOrder/viewCount/coverOssId/remark`。
|
||||
- 响应 envelope 的 `code/data` 和每行 `helpCategory/helpTitle/helpContent` 必须 required;三项均为非空字符串,分类是可直接展示标签,正文首版固定为纯文本。用户侧列表只返回已发布内容,数组顺序就是展示顺序;客户端不猜分类码、不解释 HTML/Markdown。
|
||||
- 搜索与筛选只作用于已投影数组;筛选后不得重新编号。搜索、分类和刷新先收起正文,新请求以 controller+generation 拒绝迟到响应,离页取消请求;空列表、搜索无结果、加载失败和认证失效必须分别表达。
|
||||
- M06 现有分类和问题标题使用 `<view role="button">` 且触控高度不足;真正接线时改为原生按钮语义,补 `aria-pressed/aria-expanded/aria-controls`、状态播报、重试和至少 44dp 目标。源码审查不能替代 MuMu 的系统字号、TalkBack、焦点与视觉验收。
|
||||
|
||||
### 个人资料读取远端门禁
|
||||
|
||||
- 唯一 profile adapter 在 mock/remote 两种模式都产出同一窄模型;运行模式必须经 `resolveRuntimeMode()` 校验,错误配置不得静默回 fixture。remote 使用严格 envelope、15 秒超时、请求取消和 generation 防迟到,不建立跨账号缓存或经路由传递个人资料。
|
||||
- 原始手机号只在 adapter 局部验证 canonical 格式,输出仅含 `maskedPhone` 与“绑定手机号,尾号 xxxx”读屏标签;页面、日志、错误、缓存和路由都不得接触明文。可选昵称、实名、邮箱只有真正省略时规范为内部空串;出现 null、空白、超长或非法邮箱时整份失败关闭。
|
||||
- M01 的加载/失败只替换身份卡,服务菜单与底栏保持可用,并删除查询参数制造的假错误和“重试即成功”;通知 fixture 不得与真实身份混装为线上数量。M02 完成异步填表后才建立 dirty baseline,GET 不冒充 PUT 保存;M03 只让手机号行局部加载/失败,密码入口不受普通读取失败影响,并删除不属于账号资料的“创建者”角色。
|
||||
- 真正实施时原子替换禁止页面调用 API 的旧静态断言,使用 `AppLoading` 和原生按钮,补 M02 的 `aria-invalid/aria-describedby`、失败聚焦、状态播报、44dp 目标、长昵称换行和装饰图隐藏;MuMu 仍须验证系统字号、TalkBack、焦点与真实纹理对比。
|
||||
|
||||
### 通知读取与已读状态远端门禁
|
||||
|
||||
- 读取批次以无筛选列表作为当前账号完整活动集合 owner,`RListNotificationVo.data` 允许空但最多 200 条并按 `publishTime` 最新优先;`RNotificationUnreadCount.data` 为 0—200,精确等于同一活动集合中 `readStatus=UNREAD` 的数量。两个请求之间发生并发新消息时允许瞬时差异,客户端不得据此判错。
|
||||
- `NotificationVo` 的首批 required 字段为 `noticeTitle/noticeContent/publishTime/readStatus`:标题 1—50、完整正文 1—1000 且为纯文本,时间必须是带时区 RFC3339,状态只允许 `READ/UNREAD`。N01 摘要最多显示 160 个字素,N02 展示同一快照的完整正文;长文本必须换行,不解释 HTML、Markdown、URL 或服务端跳转字段。
|
||||
- 读取 adapter 只公开 `{snapshotKey,title,content,publishedAt,unread}`,key 由成功响应 generation 与映射前 ordinal 组成;不持久化、不使用裸序号,也不把 `notificationId/genealogyId/bizId/bizType/senderPhone` 暴露给页面。成功刷新原子替换 generation,退出和账号切换立即清空;N02 不能解析 key 时只提示“请返回消息中心重新打开”。
|
||||
- 首批删除通用“前往入谱审核”、详情目标按钮和从消息字段猜路由;后端将来只有提供闭合的 `bizType → route key+必填词法参数+权限/失效语义` 字典后才可独立恢复 CTA。M01/G01 共同消费未读数 owner,文案统一为“未读消息”,可见角标封顶 `99+`,读屏仍播报真实数量。
|
||||
- 写批次通过前,打开 N01/N02、点击“标记已读”或“全部已读”都不得只改本地 clone。写合同通过后,唯一通知 controller 才能私有保留 1—128 位 URL-safe opaque `notificationId`;页面仍只持有 `snapshotKey`。单条和全部已读必须对当前账号幂等;read-all 只覆盖服务端接收时已存在的活动通知,并发新消息保持未读;超时或结果未知时重新读取列表和计数收敛。
|
||||
- 两个失败门禁分别是 `tests/notification-read-openapi-contract.ps1` 与 `tests/notification-read-state-openapi-contract.ps1`。当前分别输出 `NOTIFICATION-READ-OPENAPI-CONTRACT BLOCKED` 和 `NOTIFICATION-READ-STATE-OPENAPI-CONTRACT BLOCKED`;后端同版本双导出、有效账号反例和 MuMu 状态矩阵完成前不能宣称通知闭环上线。
|
||||
|
||||
### M02 个人资料写入远端门禁
|
||||
|
||||
- PUT 请求体唯一 owner 固定为关闭额外字段的 `AppProfileMergeUpdateBody`,只能包含 1—3 个真正脏的 `nickName/realName/email`。昵称出现时为去边界空白的 1—30 字符;真实姓名和邮箱的精确 `""` 是唯一清空命令,非空真实姓名 1—30、邮箱 1—100 且格式有效。省略表示保持,null、纯空白、边界空白、空 body、头像/性别/生日或任意额外字段全部早失败。
|
||||
- `AppProfileVo` 新增 required `profileVersion`,形状为 1—128 位 URL-safe opaque string;写请求只在 required `If-Match` header 携带,不在 body 建第二版本字段。服务端按当前账号和租户原子 CAS,成功返回含新版本的完整 canonical profile,旧版本固定 409 `PROFILE_VERSION_CHANGED`;相同字段集重复执行不产生通知、审计之外的额外业务副作用。
|
||||
- M02 首次 GET 完成后才建立 baseline;保存时冻结三个输入和提交快照,成功用响应回填并重置 baseline。确定失败保留草稿;超时、断网、408/5xx 或畸形成功响应属于结果未知,先 GET 逐项核对本次脏字段,匹配则确认成功、仍为旧值才允许重试、第三值进入冲突,不盲目重复 PUT。
|
||||
- session generation 是账号隔离边界:账号切换、退出和页面卸载中止等待、清空未持久草稿并拒绝旧账号迟到响应;取消 RequestTask 不等于服务端未写。真实姓名、邮箱、提交 payload 和版本不得进入日志、路由、持久缓存或遥测。
|
||||
- 当前假定昵称必填,所以旧账号昵称省略时可以只改其他字段,但不能把已有昵称清空。头像选择、相册权限、OSS ID、性别和生日全部留到独立批次;当前 `<view role="button">` 假头像动作在写入实施时删除。邮箱没有验证与送达合同,页面不得继续承诺“用于接收通知”。
|
||||
- `tests/profile-update-openapi-contract.ps1` 当前输出 `PROFILE-UPDATE-OPENAPI-CONTRACT BLOCKED`。后端关闭 `API-PROFILE-UPDATE-001`—`004`、同版本双导出通过、读取 owner 可用、有效账号/CORS 反例和 MuMu 表单矩阵完成前,M02 保持诚实本地校验而不发写请求。
|
||||
|
||||
### M10 当前设备退出远端门禁
|
||||
|
||||
- 后端 DELETE 只撤销当前请求 bearer 及同一可续签凭证族;其他设备 token 保持有效。合法签发给同一 client 的 active/revoked/expired token 重复调用统一返回 200 RVoid,操作幂等且无额外副作用;成功后用旧 token 调 profile 等受保护接口必须失败。非法或 client 不匹配返回 `RLogoutRejected`,业务码只允许 `TOKEN_INVALID/TOKEN_CLIENT_MISMATCH`,不能冒充远端已撤销。
|
||||
- operation 必须 required SaToken 与非空 clientid、禁止 request body、200/401 使用 application/json 并带 `Cache-Control: private, no-store`;RVoid 的整数 code required,另声明 400/429/500。线上仅有文字“需要登录”和 `*/*`,本地虽有 security/clientid 但 RVoid 无 required、只列 200,均未达到发布合同。
|
||||
- `logoutCoordinator` 是唯一跨页 owner:同步捕获 token/clientid 与 logoutEpoch,立即调用 session owner 清 token、家谱上下文和账号缓存并 bump epoch,再以显式 A 快照创建 RequestTask;整个同步段不 await,M10 页面拿不到 token。创建失败也不恢复;请求不绑定页面 controller,reLaunch/A01/M10 卸载不 abort。
|
||||
- coordinator 的公开内存态只含 `{attemptId,logoutEpoch,status}`,状态为 pending/confirmed/unconfirmed/not-revoked,不保存 token、请求头或错误 payload。A01 仅在 session 仍为空且 epoch 未变化时原子消费一次提示;B 登录后 A 的迟到结果直接丢弃。进程被杀允许丢提示,但旧 token 不落盘、不排队、不跨重启重试。
|
||||
- 唯一用户承诺始终是“已从本机退出”。200 显示服务器撤销已确认;network/timeout/408/429/5xx/畸形响应与 generic 401 显示未确认;typed 401/400/403 显示未能撤销。所有分支都留在 A01,不恢复 token、不返回 M10、不重新开放登录后页面;异步 callback/finally 绝不能再次 `session.clear()`。
|
||||
- `tests/logout-openapi-contract.ps1` 当前输出 `LOGOUT-OPENAPI-CONTRACT BLOCKED`。同版本双导出、两设备 token 隔离/复用反例、真实网络异常和 MuMu 退出提示完成前,只能称现有行为为本机退出,不能宣称服务端注销完成。
|
||||
|
||||
### M04 登录态修改密码远端门禁
|
||||
|
||||
- 密码 wire 是跨 A01 登录、A04 注册、A05 找回和 M04 登录态改密的单一合同。`PasswordLoginBody.password` 与 `PasswordChangeBody.oldPassword` 只引用 `CurrentPasswordSecret`;注册、找回和改密的新密码只引用 `NewPasswordSecret`。生产入口不再接受 MD5、十六进制摘要或两套兼容分支;确认密码只留客户端。
|
||||
- `CurrentPasswordSecret` 是原样、不 trim 的 1—64 Unicode code point;`NewPasswordSecret` 是 NFC 后 15—64 code point,允许空格、Unicode 和密码管理器粘贴,不强制字母/数字组成。服务端才是策略权威,必须执行常见/泄露密码 blocklist、当前密码验证、新旧不同、账号级限速和带盐慢哈希;页面校验只是即时提示。
|
||||
- PUT required SaToken、非空 clientid 与关闭额外字段的 JSON body;200/400/401/409/422/429/500 均为 typed JSON、`private, no-store`,429 带 `Retry-After`。409/422 用 `RPasswordChangeRejected` 区分 `CREDENTIAL_VERSION_CONFLICT/CURRENT_PASSWORD_INCORRECT/NEW_PASSWORD_SAME_AS_CURRENT/PASSWORD_POLICY_VIOLATION`,不解析 `msg`。
|
||||
- 唯一会话方案是 ALL:严格 200 前原子写入新 verifier、提升 credential epoch,并让所有设备/所有 client 的旧 access/refresh session 跨节点失效;不返回新 token,也不让当前 bearer 继续存活。200、401、409 和传输结果未知都清秘密与对应本机会话并回 A01;只有明确未写的 400/422/429 可清 `credentialChangeInFlight` 后留页。
|
||||
- 为关闭 PUT 已发出后进程被杀的窗口,session owner 在发送前只持久化 `{sessionEpoch,startedAt}` marker,禁止保存 token、密码、摘要或 body。冷启动发现同 epoch marker 时必须在任何账号缓存渲染前清会话并进 A01;新登录 bump epoch,使旧 marker 和迟到响应失效。客户端不自动重试、不建 operation-status;重新登录就是最小对账路径。
|
||||
- `tests/password-change-openapi-contract.ps1` 当前输出 `PASSWORD-CHANGE-OPENAPI-CONTRACT BLOCKED`。后端关闭 `API-PASSWORD-001`—`005`、原子重导双文件、密码登录 TAC 可用、两设备/并发/故障注入与 MuMu 无障碍矩阵完成前,M04 继续显示“不提交服务器”。
|
||||
|
||||
## 三人规则
|
||||
|
||||
- 总共三人:主代理与两位固定评审者。
|
||||
- 三个人都完整检查文档、测试和资产,不割裂分工。
|
||||
- 审查阶段只读,实际文件变更只由主代理执行。
|
||||
- 删除候选必须三人一致确认;任意一人提出有效疑点时继续调查。
|
||||
- 用户已授权三人一致后直接删除,无需逐文件再次确认。
|
||||
|
||||
## 当前禁止事项
|
||||
|
||||
- 不执行 Git add、commit、push、restore、checkout 或 reset。
|
||||
- 不启动、关闭或调整 MuMu。
|
||||
- 不删除活动业务源码、接口导出、当前权威设计或用户改动;只有三人以消费者、合同和资产清单共同证明已经退役的旧入口才可同轮删除。
|
||||
- 不因测试失败而删除测试。
|
||||
- 不因静态搜索无匹配而直接删除资产。
|
||||
- 不归档确认失效的旧内容,不保留兼容入口。
|
||||
|
||||
## 下一步
|
||||
|
||||
1. T01 后端接口门禁已经建立并运行出预期红灯;等待后端按 `API-T01-001` 发布四条 v2 操作并提供同一版本重新导出的 JSON/YAML,不手改当前快照,也不提前实施任务 12。
|
||||
2. TAC 客户端批次已经完成。认证后端仍须关闭 `API-AUTH-TAC-001`—`004`、提供同版本双导出并修复 challenge 500;随后才允许把 `runtimeConfig.mode` 从 `mock` 切为 `remote`,执行正式 H5 CORS、真实票据重放/限流和 MuMu Android 流程。
|
||||
3. 并行推进非交互风控的限时 POC 与文字/中继人工兜底合同;只有 POC、服务端原子消费和 `ANDROID-AUTH-ACCESSIBILITY-RELEASE` 全部通过,才可宣称认证达到上线门槛。
|
||||
4. 新图合同通过后,按规范化与校验、布局、Scene 与空间索引、单 Canvas、页面交互、接口回流的顺序实施 T01。
|
||||
5. 家谱工作区三人审查和失败合同已经完成;等待后端关闭 `API-GENEALOGY-WORKSPACE-001`—`003` 并提供同版本双导出。门禁通过后再测试先行实现唯一 adapter、G01 `onShow` 列表现场和 G05 `/overview` 读取,不提前固化字段或枚举。
|
||||
6. G03 原子创建三人审查和失败合同已经完成;等待后端关闭 `API-G03-001`—`005`、以同版本双导出交付 bootstrap POST、状态查询、地区选择与统一 accessPreset。通过前不接当前宽松 `createGenealogy`;通过后先实现严格 coordinator、无 PII 恢复 marker、地区选择器、context/G05/G01 闭环,再独立完成 MuMu 表单与无障碍矩阵。
|
||||
7. M06 三人审查和失败合同已经完成;等待后端关闭 `API-M06-001`—`003` 并提供同版本双导出。通过后测试先行实现 list-only adapter、加载/空/失败/重试、动态分类、纯文本手风琴和无障碍语义,不接详情或文章 ID。
|
||||
8. 个人资料读取三人审查和失败合同已经完成;等待后端关闭 `API-PROFILE-READ-001`—`003` 并提供同版本双导出。通过后测试先行实现唯一掩码 adapter 与 M01/M02/M03 局部状态,M05 当前手机号展示随同一只读 owner 原子迁移但不接换绑写接口。
|
||||
9. 通知读取与已读写入已分别完成三人审查和失败合同;等待后端关闭 `API-NOTIFICATION-READ-001`—`003` 与 `API-NOTIFICATION-STATE-001`—`003`。读取通过后先实现无 ID 的内存快照和 M01/G01 未读数;写入另批迁移私有 ID、删除伪本地写并验证并发收敛,不恢复不可信目标 CTA。
|
||||
10. M02 个人资料 PUT 已完成三人审查和失败合同;等待后端关闭 `API-PROFILE-UPDATE-001`—`004`。读取与写入门禁都通过后,按 normalizer、严格 API、M02 状态机和 MuMu 表单矩阵独立实施,不混头像或账号安全。
|
||||
11. M10 服务端退出已完成三人审查和失败合同;等待后端关闭 `API-LOGOUT-001`—`003` 后,再测试先行实现 session epoch、唯一 logoutCoordinator、A01 一次性提示和两设备撤销矩阵。
|
||||
12. M04 登录态改密与四条密码 wire 已完成三人审查和失败合同;等待后端关闭 `API-PASSWORD-001`—`005` 后,才原子迁移共享密码策略、MD5 调用、session marker、M04 状态机和全设备撤销矩阵。
|
||||
13. M05 手机号换绑三人审查和失败合同已经完成;等待后端关闭 `API-PHONE-001`—`005`,且 M04 raw-password 与认证/TAC 前置门禁同时通过后,再原子迁移全活动 OTP、实现专用受保护发码、共享 credential marker 与 M05 状态机。
|
||||
14. 继续审查下一个不依赖现有红灯的业务域;按 G/F/R 逐域推进。随后逐批完成文字层级与无障碍,不混合验证码、账号写入、领域数据或支付。
|
||||