Files
jiapuapp/docs/后端接口缺口与首位成员阻塞清单-2026-07-24.md
T
2026-07-27 06:50:23 +08:00

36 KiB
Raw Blame History

后端接口缺口与首位成员阻塞清单

更新日期: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 只声明:

DELETE /genealogy/app/genealogies/{genealogyId}/videos/{videoId}

没有视频列表、详情、播放地址或发布 operation。删除接口不能反推出读取和播放合同。

当前页面入口可提供的业务上下文只有:

参数语义 来源 状态
genealogyId 页面路由 已有,必需
当前登录账号 认证会话 已有,必需
clientid APP 请求头 已有,必需

请后端/产品先确认视频资源是否归属某个家谱。若是,最小可用的首个 operation 应是“读取该家谱可见视频列表”,并明确:

  1. 是否分页;若分页,统一选择并声明 pageNum/pageSizecursor/pageSize 之一,不能让前端猜测。
  2. 每条记录的稳定视频标识,以及当前页面用于渲染列表所需的明确字段和字段类型。
  3. 当前账号无权、资源不存在、空列表的响应语义。

视频详情、播放、发布、编辑、评论、点赞和分享目前没有对应页面表单或页面数据模型;若产品要开放这些能力,请为每项单独给出 operation 与 DTO,不要用相册或动态接口兼容代替。

R09 人生大事:缺独立资源与归属定义

现状:pages/records/r09-life-events.vue 已明确关闭;APP/PC OpenAPI 中都未发现独立“人生事件/life event”资源。

从 R02 人物详情跳转 R09 时会传入 genealogyIdpersonId,但 R09 当前没有读取或写入表单,因此不能从 UI 推断事件到底是“人物专属”还是“家谱公共”。请后端/产品先在以下两种归属中选择一种:

资源归属 最少识别参数
人物专属事件 genealogyIdpersonId
家谱公共事件 genealogyId

归属确定后,请提供对应的列表/详情/创建或编辑 operation(以产品实际要开放的页面为准),并定义事件的必填业务字段、时间字段、排序/分页、权限和错误语义。归属未确定前,前端不会把成长记录、备忘或人物简介映射成人生大事。

N02 消息详情:缺单条详情读取 operation

现状:当前已声明:

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。响应含 phoneuserNostatus;M03 已接入并只显示本地掩码手机号、账号编号和账号状态。页面不把明文手机号写入路由、日志或缓存。

“设备列表”“登录记录”“安全等级”仍没有独立读取 owner,也不属于当前 M03 的数据模型;页面不会展示或推断这些内容。建议后端仍在 Apifox 为 profile 发布明确 DTO;如产品要展示上述资源,应分别定义 operation、字段、权限和保留期。

M05 换绑手机号:已有最终 PUT,但缺可验证的安全链路与读取 DTO

当前 OpenAPI 已声明最终写入接口:

PUT /genealogy/app/auth/phone

当前已声明的请求参数如下;它们是现状记录,不是前端新增猜测:

位置 字段 约束
Header clientid 必填
Body clientId 必填,必须等于 Header clientid
Body phone 必填,新手机号
Body smsCode 必填;当前导出合同为 4 位数字
请求上下文 当前登录账号 必填

当前 OpenAPI 还声明通用发码接口:

POST /genealogy/app/auth/sms/code

其当前 body 必填字段为 clientIdtenantIdgrantTypesceneCodephonevalidToken;换绑场景为 APP_PHONE_CHANGE。当前 profile 已能只读获取并掩码显示手机号,但没有经过人工确认的换绑专用 TAC/发码/校验闭环;M05 因而继续保持关闭,且不在无人值守时发送短信或换绑。

请后端确认并在同一版本交付:

  1. APP_PHONE_CHANGEvalidToken 获取、绑定手机号主体校验、过期和一次性消费语义;如通用发码接口不适合作为换绑 owner,请提供专用 operation,而不是要求前端复用未知场景。
  2. 最终 PUT 成功、验证码错误/过期/重复、手机号已占用、无权限和结果未知时的明确 HTTP 与业务码语义。

本问题单只要求合同和人工可控的测试条件,不授权前端执行短信、换绑或其他账号安全写入。

三、已有接口但被服务端 code:500 阻断的成员页面

这不是“缺接口”,而是首位成员无法创建导致没有真实 personId。阻断请求为:

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 / 发生未知异常,请联系管理员。首位成员不应伪填 fatherIdmotherIdrelationNameappUserId 缺同类型候选映射,头像 avatarOssId 仍受 19 位 ossId 类型冲突阻断。sexbirthLunardeathLunarpersonStatus 虽为可选,但 Apifox 仅称项目字典值、无枚举,页面不能把猜测的代码或农历文本作为正式交互。

已复现结果:最小请求与上述全字段页面请求均为 HTTP 层成功、业务响应 code:500;随后读取世系树仍为空。

请后端处理:

  1. 查询该请求的异常栈,以及空世系创建首位成员所需的家谱/租户初始化条件。
  2. 修复后使该最小合法请求返回业务成功,并返回可读取的成员结果(至少可取得稳定 personId)。
  3. 以同一测试家谱验证后续读取:世系树、成员目录分页、成员详情均能读到该成员。
  4. 若暂不能修复,请提供当前测试账号有访问权限的测试 genealogyId 与真实 personId,供只读和允许写入的回读验证;不要提供生产数据。

解锁范围为 T03–T08、R01–R02:成员详情、首位成员/亲属创建、编辑、排行、成员目录与成员状态等。已有读取/写入路径应在取得真实 personId 后按页面顺序验证,不应改成 mock 或本地假成功。

四、后端回传模板

请每个问题按下列项目回复,便于前端不重做已接线部分:

页面/问题:
资源 owner
APP operationHTTP 方法 + 路径):
鉴权和 clientid 要求:
path/query/body 参数(字段、类型、必填、枚举/范围):
成功响应 DTO(字段、类型、必填):
错误响应(HTTP 状态 + 业务 code + 可展示文案):
分页/排序/权限语义(如适用):
可使用的测试 genealogyId / personId(仅测试数据):
OpenAPI YAML/JSON 更新版本:

前端收到更新后的合同和测试数据后,会先做最小浏览器真实请求,并以服务端成功响应后的列表/详情回读作为验收依据;样式问题另在模拟器复核。

五、A01 密码登录:已解除

2026-07-25 已在桌面版 Apifox 核对并用测试账号直连验证。最新已发布合同如下:

位置 字段
Header clientid
Body grantType=passwordtenantIdphone、32 位 MD5 passwordvalidToken 仅在验证中心策略开启时必传

clientIdsceneCode 不再属于密码登录 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

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 的已发布枚举为:

password-login | sms-login | register | forgot-password | phone-change | account-deactivate

合同要点:

操作 Header path/query/body
查询策略 clientid path operationCodequery tenantIdsubject
获取挑战 clientid path operationCodebody tenantIdsubject
校验挑战 clientid path 必须与挑战使用同一 operationCodebody tenantIdsubjectchallengeId 和验证码证据
发送短信 clientid path operationCodebody tenantIdphonegrantType=sms;仅服务端策略开启时提交 validToken

所有新接口都明确禁止前端再提交 clientIdsceneCode;服务端按 APP 路由的当前激活绑定解析验证场景。

已做的最小真实验证(仅测试手机号、未发送短信):

请求 结果
GET …/verification/APP_SMS_LOGIN/require HTTP 200,业务 code:500:不支持的认证业务动作
GET …/verification/sms-login/require HTTP 200,业务 code:200required:trueTIANAI/SLIDER
GET …/verification/password-login/require HTTP 200,业务 code:200required: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 无法使用:

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.rowsdata.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

POST /genealogy/app/files/resumable/init
POST /genealogy/app/files/resumable/chunk
POST /genealogy/app/files/resumable/complete

complete 的真实响应为(URL 已省略):

{
  "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

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 genealogyIdceremonyIdbody inviteeUserIds inviteeUserIds 是唯一业务用户 ID 的完整数组;空数组表示取消全部尚未响应的邀请
查询活动邀请名单 path genealogyIdceremonyId 返回邀请记录列表
响应当前用户邀请 path genealogyIdceremonyIdbody inviteStatus 枚举仅允许 ACCEPTEDDECLINED
查询我的活动邀请 无业务 path/body 当前登录业务用户的有效邀请列表

当前 CeremonyInvitationVo 可读取字段为:invitationIdgenealogyIdceremonyIdinviteeUserIdinviteStatusPENDING / ACCEPTED / DECLINED / CANCELED)、inviteVersiondeliveredTimereadTimeresponseTimeceremonyTitleceremonyTimelocationlocationAddresslongitudelatitude。这些 ID 均为 int64,真实雪花 ID 必须统一允许十进制字符串传递,不能要求 H5 转为不安全的 JavaScript number。

阻塞点

R07 需要的是 inviteeUserIds(业务用户 ID),但当前 APP 家谱成员列表没有声明可供选择的业务用户 ID,也没有“可受邀用户候选列表” operation。memberIdlineagePersonIdinviteeUserId 是不同资源标识,前端不会用任一个替代另一个,也不会提供让用户手输未知业务 ID 的伪流程。

请后端在同一版 APP OpenAPI 中二选一,并提供仅测试数据:

  1. 在现有“家谱成员列表/选项”成功 DTO 中明确返回稳定的 appUserId(或等价字段),并声明该字段就是 inviteeUserIds 的合法值;或
  2. 新增“查询活动可邀请用户候选列表” operation,至少返回业务用户 ID、展示名、是否可邀请、不可邀请原因。

同时请确认 int64 业务用户 ID 在所有 APP JSON 请求/响应中使用十进制字符串合同,避免与第八节 ossId 相同的精度丢失问题。候选来源和字符串 ID 合同发布前,前端只接入邀请读取/响应的精确 API 方法,不会把“替换受邀人”伪装成可用页面功能。

十、2026-07-26 Apifox 路径修正:行政区划

桌面 Apifox 当前正式路径为:

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.levelsearch.limit 可选;其余 regionCode path 参数必填,children.parentCode 可选。G03 原先错误使用了 /genealogy/app/region/children,已改为正式路径并在 H5 浏览器验证省、市、区三级均返回业务 code:200。其余 3 个 operation 尚无当前页面交互入口,待桌面 Apifox 补齐可消费的响应 DTO 后按实际页面需求接入;不会以 additionalProperties 的导出占位结构猜字段。

十一、2026-07-26 F03 真实点赞后缺少当前用户状态

测试账号通过 F03 动态详情页面执行了一次真实“点赞”(没有执行取消点赞或其他删除操作):

POST /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/likes

该请求返回 HTTP 200。随后页面重新读取详情,likeCount0 变为 1,说明服务端已写入点赞;但详情响应没有给出可用的当前用户点赞状态,前端读取到的 likedByMe 仍为 false/缺失,按钮继续显示“点赞”而不是“取消点赞”。

这不是前端可以用本地布尔值补齐的缺口:页面刷新后必须以服务端状态决定下一次应该调用 POST /likes 还是 DELETE /likes。当前合同会导致重复点击语义不明确,也无法安全展示已点赞状态。

请后端在以下 APP 读取 DTO 中统一提供当前登录用户维度的必填布尔字段 likedByMe(或同义且明确的字段),并与点赞写入立即一致:

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 为:

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 T03T08、R01R02 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/名称/状态/排序字段 发布 categoryIdcategoryName、可选状态与排序 DTO
B12 页面交互待确认 行政区划 path/search/detail G03/G11 后续回填、搜索 2026-07-26 复测已返回 valuelabelregionCode、层级等真实条目;但当前产品页面没有搜索/路径回填入口 产品确认地区搜索与路径回填交互后接入页面;接口 DTO 不再阻塞
B13 资源语义不能混用 memberslineage/persons 成员管理、R06/R07 memberIdpersonIdappUserId 是不同资源,当前无独立成员管理页 提供成员管理页需求与稳定候选/映射 DTO,不得前端猜代
B14 业务绑定 owner 缺失 POST /files/reference 所有附件业务 需要 bizTablebizIdbizField,页面没有可信业务表/字段来源 后端为各业务资源声明文件绑定 owner,或明确由创建 DTO 原子绑定
B15 枚举/候选缺失 多个 body 中的 sexbirthLunardeathLunarpersonStatusroleTypestatuspayType T04/T05 及 T/M/G/R/F 写入扩展 2026-07-26 复核 LineagePersonBodybirthLunardeathLunar 的含义是“日期是否农历”的项目字典值,不是农历日期文本;性别和人物状态也都是字典值。导出与桌面 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:首位成员创建

接口:

POST /genealogy/app/genealogies/2081191846772518914/lineage/persons

最小请求(2026-07-26,页面 T04):

{
  "name": "首位成员最小请求验证",
  "generation": 1
}

实际返回:

HTTP 200
{"code":500,"msg":"发生未知异常,请联系管理员","data":null}

页面结果:保存失败 / 首位成员尚未保存 / 发生未知异常,请联系管理员

后端称已修复后的复测(2026-07-26,重新登录测试账号后从 T04 提交):

{
  "name": "后端修复验证首位成员",
  "generation": 1
}

返回仍为:

HTTP 200
{"code":500,"msg":"发生未知异常,请联系管理员","data":null}

因此 B06 仍未解除;本次不是会话过期导致的结论。首次请求得到 code:401 后已通过 A01 真实密码登录,重试才得到上述业务 code:500

全字段诊断请求(同一页面、同一测试家谱;用于验证可选字段是否会改变异常,不是字段字典的最终验收):

{
  "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
}

实际返回同样为:

HTTP 200
{"code":500,"msg":"发生未知异常,请联系管理员","data":null}

特别说明:该诊断请求暴露出旧页面把 birthLunardeathLunar 当作农历日期文本;Apifox 的真实语义是“是否农历”的字典值。不能把这一请求视为正确字典值示例,也不能要求前端据此猜选项。首位成员不应伪填 fatherIdmotherIdrelationNameappUserId 没有同类型候选,avatarOssId 被 B08 阻断。

随后读取:

GET /genealogy/app/genealogies/2081191846772518914/lineage/persons/options
HTTP 200 / code:200 / data: []

因此 T01 没有成员数据并非前端空白占位:服务端尚未成功写入任何真实成员。

2. 初次验证记录(历史结果;以 2.1 的复测结论为准)

编号 接口与页面 实际请求值/返回值 结论
B07 GET /genealogy/app/genealogies/{genealogyId}/feeds/pageF01/F03 已按页面分页参数真实读取;HTTP 200、业务 code:200,但响应没有 Apifox PageResult 所需的 data.rowsdata.total 无法安全分页或把空对象伪装为无动态
B08 POST /genealogy/app/files/resumable/initF09 等上传页面 省略 uploadId:返回“上传ID不能为空”;将 totalSize 改为导出字段 fileSize:返回“文件大小不能为空”;实际可用字段为 uploadIdfileNamefileMd5totalSizetotalChunkschunkSize。秒传返回 {"uploadId":null,"instant":true,"ossId":"2081232520259612673"} 文件服务返回 19 位字符串 ID,而业务 DTO 写 int64 数字,前端不能无损作为 JSON 数字提交
B10 动态点赞,F03 已真实点赞,点赞数量变化;详情/列表未返回 likedByMe 不能据数量推断当前用户是否已点赞,页面已禁用不确定状态下的再次写入
B11 GET /genealogy/app/genealogies/{genealogyId}/article-categoriesF06 HTTP 200、业务 code:200data: [] 无分类候选可供选择;同时合同没有分类条目字段定义
B12 行政区划 childrenG03/G11 GET /genealogy/region/children 已可真实读取;path/search/detail 没有可消费的条目 DTO 和页面交互归属 不猜地区回填字段或新增搜索行为
B17 分片上传初始化,F09 等 见 B08 的实际请求和返回;导出与服务端校验字段冲突 Apifox 与导出必须先统一为唯一合同

2.1 后端称修复后的复测结果(2026-07-26)

编号 复测结果 当前结论
B06 重新登录后,T04 最小 body 仍返回 HTTP 200、业务 code:500data:null 未修复
B07 GET .../feeds/page?pageNum=1&pageSize=20 现在返回根级 total:1rows:[...],不再是空 envelope 分页数据已出现;但 likedByMe 返回字符串 "1"B10 仍未修复
B08 F09 从真实图片文件上传到“已上传”成功;保存照片时前端收到真实 19 位文件 ID 后仍报“超出 APP 安全整数范围”,未发出照片创建请求 未修复,需统一字符串 ossId 合同
B09 礼仪列表可读取,GET .../ceremonies/{ceremonyId}/invitationsGET .../ceremony-invitations/mine 均返回 data:[];没有可提交的 inviteeUserIds 候选 未修复,仍缺 appUserId 候选/映射
B11 谱文分类仍返回 HTTP 200 / code:200 / data:[] 测试谱没有分类;仍需分类 DTO 与可用测试候选才能验证选择/写入
B12 GET /genealogy/region/path/110101GET /genealogy/region/110101GET /genealogy/region/search?keyword=北京&limit=10 均返回包含 valuelabelregionCode、层级等字段的真实数据 后端已补齐可消费条目;待产品确认搜索/回填交互后接入页面

3. 未发起写入请求的原因(不是漏测)

编号 接口/功能 未发起的原因 后端需要提供
B01 视频 F10 仅发布删除接口;没有列表、详情、播放、创建、编辑或上传 owner 完整资源 operation 与 DTO
B02 人生大事 R09 没有资源 operation 明确人物或家谱归属后的列表、详情、写入 DTO
B03 通知详情 N02 只有列表、标已读;没有按 notificationId 读取详情 单条详情接口及授权语义
B05/B16 短信、改密、换绑、退出、注销、删除、审核、支付 属于本轮明确禁止的敏感动作 另行授权、测试账号和可回收数据后再测
B09/B13 礼仪受邀人、成员绑定 请求需要 appUserId,现有 memberIdpersonIdappUserId 不能互相替代;没有候选映射 同类型候选接口或稳定映射 DTO
B14 文件业务引用 请求需要 bizTablebizIdbizField,没有页面可信 owner 各资源的文件绑定归属合同
B15 性别、人物状态、出生/逝世是否农历等 需要选择器,但 Apifox 仅给示例 0,没有枚举、中文标签或字典 options 接口 value-label 枚举或字典 options operation

不应误标为阻塞的已完成项

  • A01 密码登录、G03 创建家谱、家族动态/评论、谱文、相册、亲友往来、礼仪、成长记录、备忘、功德均已做过真实创建后的列表或详情回读。
  • M03 账号与安全已真实读取当前 profile,并仅展示掩码手机号、账号编号和账号状态;设备与登录记录不在当前页面范围内。
  • 4 条行政区划 operation 都已有 API ownerchildren 已在 G03/G11 页面真实读取,其余三条的阻塞是没有可安全消费 DTO/产品交互,不是路径不存在。
  • 136 条 method + path 均可在桌面 Apifox 当前目录找到;数量差异不是“导出漏了 path”,而是页面数、功能入口、DTO 和安全参数来源不同。