f9b1358b37
CI / docs-build (push) Successful in 1m59s
安全事件(已闭环,服务恢复): - 根因链:Gitea 3000 对公网开放 → 外部调用 /api/internal/manager/add-logger 注入 gitconfig 的 uploadpack.packObjectsHook → 指向不存在的脚本 → upload-pack 发 NAK 后无法产出 pack → 全仓 HTTPS clone 失败(CI 全挂) - 攻击未达成代码执行(hook 目标脚本不存在);三仓 ref 与本地逐一核对未被篡改; 无系统层入侵(无陌生 key/crontab/挖矿进程/陌生登录) - 新建常设「服务器暴露面清单」:补上服务器侧「决策变了环境没跟上」的核对机制 (Nacos 在 ADR-002 移除后仍暴露公网近两个月) - CI Runner 手册排障表增三条:CI 秒失败先在本机复现 checkout、跨仓比 CI 须核对时间戳、clone 坏而 push 正常时查 packObjectsHook 注入 M3.5 交付报告:03 后端资料与头像(api 334→379)、04 契约冻结 v1.4.0 (31→32 路径、矩阵 173→181 格、11 格红转绿)、05 资料页与头像 UI(flutter 526→597) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
223 lines
20 KiB
Markdown
223 lines
20 KiB
Markdown
# 真机验证清单(常设)
|
||
|
||
> **定位**:跨迭代常设文档——凡「只能在真机/模拟器上验证」的事项都登记在此,按迭代分节;每项含操作步骤、通过标准与执行记录。真机到位或发版前照单执行。
|
||
> **维护约定**:各迭代收官时把真机专属验证项登记进来;完成后填执行记录并同步 [功能完成清单](feature-checklist.md) 对应条目状态。
|
||
> 原位置为 iteration-2/30 号报告,2026-09-08 提升为常设文档(M3 起亦有真机项)。
|
||
|
||
## 通用前置准备
|
||
|
||
**设备**:Android 真机(推荐)或 Android 模拟器。桌面/Web 不可用——没有真实的移动端后台生命周期(`paused` 不触发),且 platform 值不在契约枚举内会被服务端整批拒绝。
|
||
|
||
**后端**(工作机上,进入你本地检出的 patbond-api 仓库目录执行):
|
||
|
||
```bash
|
||
cd <你的工作区>/patbond-api
|
||
JAVA_HOME=/usr/lib/jvm/java-17-openjdk ./mvnw -DskipTests package
|
||
docker compose up -d --build
|
||
docker compose ps # 全部容器 Up,postgres healthy
|
||
```
|
||
|
||
**装机运行**(进入你本地检出的 patbond-flutter 仓库目录):
|
||
|
||
```bash
|
||
# 模拟器:宿主机地址用 10.0.2.2
|
||
flutter run -d <设备ID> \
|
||
--dart-define=PATBOND_API_BASE_URL=http://10.0.2.2:8081 \
|
||
--dart-define=PATBOND_USER_API_BASE_URL=http://10.0.2.2:8082 \
|
||
--dart-define=PATBOND_PET_API_BASE_URL=http://10.0.2.2:8083
|
||
|
||
# 真机:换成工作机局域网 IP(真机与工作机须同一网络)
|
||
# --dart-define=PATBOND_API_BASE_URL=http://<局域网IP>:8081 (其余同理)
|
||
```
|
||
|
||
> 注意:所有 base URL 都要传,漏传的会落到默认 127.0.0.1(指向手机自身)。M3 起若新增服务端口(如 community :8084),相应补 `PATBOND_COMMUNITY_API_BASE_URL`。
|
||
|
||
---
|
||
|
||
# M2 挂起项(2026-09-08 登记,待执行)
|
||
|
||
> 来源:报告 iteration-2/10 §2.1(验收 6)与 iteration-2/12 §3.2;方案 A 挂起决议见 iteration-2/29 §4。
|
||
> **时限提醒**(iteration-3/06):建议在 **2026-09-21(北极星首次出数日)前完成**,否则首批读数只能标「未验收」。
|
||
|
||
## 验证一:Android 事件真实落库(~10 分钟)
|
||
|
||
**目的**:确认埋点链路在真实移动端(platform=android)端到端落库——桌面端已验证全链路仅差 platform 枚举这一步。
|
||
|
||
**步骤**:
|
||
1. app 内注册新账号(用户名任意、手机号 11 位、密码 ≥8 位含字母数字),登录进入主页
|
||
2. 操作产生事件:切几个 Tab、建一只宠物档案、记一条体重
|
||
3. **把 app 退到后台**(Home 键,触发离开前台冲刷),等 5 秒
|
||
4. 工作机查库:
|
||
|
||
```bash
|
||
docker exec patbond-postgres-1 psql -U patbond -d patbond -c \
|
||
"SELECT event_name, platform, session_id, client_ts
|
||
FROM platform.product_events ORDER BY client_ts DESC LIMIT 20;"
|
||
```
|
||
|
||
**通过标准**:
|
||
- [ ] 有行返回,`platform` 列为 `android`
|
||
- [ ] 事件覆盖 ≥3 类(如 page_viewed、pet_create_started/succeeded、health_record_create_succeeded)
|
||
- [ ] 本轮所有事件共享同一个 `session_id`(UUIDv7 格式)
|
||
|
||
## 验证二:SessionTracker 30 分钟后台换会话(~45 分钟,含等待)
|
||
|
||
**目的**:验证 10 号报告 §2.1 验收 6——退后台超 30 分钟回前台应更换 sessionId,不超过则沿用。
|
||
|
||
**步骤**(接验证一,同一次登录、不杀进程):
|
||
1. 回前台随便操作一下(记一条体重)
|
||
2. **退后台等 5 分钟** → 回前台操作(再记一条体重或切 Tab)
|
||
3. **退后台等 35 分钟** → 回前台操作一次
|
||
4. 再退一次后台(触发冲刷),等 5 秒后查库:
|
||
|
||
```bash
|
||
docker exec patbond-postgres-1 psql -U patbond -d patbond -c \
|
||
"SELECT DISTINCT session_id, min(client_ts) AS first_seen
|
||
FROM platform.product_events
|
||
WHERE user_id = (SELECT id FROM identity.users WHERE username = '<你的测试用户名>')
|
||
GROUP BY session_id ORDER BY first_seen;"
|
||
```
|
||
|
||
**通过标准**:
|
||
- [ ] 恰好 **2 个** session_id(第 2 步的 5 分钟不换会话、第 3 步的 35 分钟换新)
|
||
- [ ] 两个会话的 first_seen 时间差 ≈ 40 分钟(与操作节奏吻合)
|
||
|
||
**巡检 SQL 兜底**(06 号 §5.1 口径,防「每事件一个 sessionId」缺陷复发):
|
||
|
||
```bash
|
||
docker exec patbond-postgres-1 psql -U patbond -d patbond -c \
|
||
"SELECT count(DISTINCT session_id)::float / count(*) AS ratio
|
||
FROM platform.product_events;"
|
||
# ratio 应远小于 0.9;> 0.9 说明 sessionId 生成有问题,告警
|
||
```
|
||
|
||
## 收尾
|
||
|
||
```bash
|
||
cd <你的工作区>/patbond-api && docker compose down
|
||
# 测试数据不入库(协作规则 3):本清单产生的数据都在 compose 卷里,
|
||
# 需要干净环境时 docker compose down -v 清卷即可
|
||
```
|
||
|
||
两项都过后:填写下方执行记录 + [功能完成清单](feature-checklist.md) 第 9 节「Android 真机落库验证 + SessionTracker 30min 手测」由 🟡 改 ✅。若有任何一项不过,按惯例开缺陷单修复后复测。
|
||
|
||
### M2 项执行记录
|
||
|
||
_(待真机到位后填写:日期、设备型号/Android 版本、两项结果、psql 输出摘录(脱敏)、执行人)_
|
||
|
||
---
|
||
|
||
# M3 预登记(社区,随迭代交付补全)
|
||
|
||
以下为 M3 交付过程中预计产生的真机专属验证项,**各工单收口时在此补全具体步骤与通过标准**:
|
||
|
||
1. **媒体上传弱网表现**(T3-13 收口补全,2026-09-09):真机蜂窝/弱 Wi-Fi 下选图→压缩→预签名直传→确认全链路;中断重试不产生孤儿 asset。
|
||
|
||
**前置**:通用前置准备的后端六容器在位;`PATBOND_MINIO_PUBLIC_ENDPOINT` 必须配置为手机可达地址(工作机局域网 IP:9000,.env 覆盖后重启 compose)——预签名直传 URL 直指 MinIO,漏配则手机端 PUT 必然连不上;`flutter run` 时四个 base URL 全传(含 `PATBOND_COMMUNITY_API_BASE_URL`),media 上传走 user 服务 :8082(`PATBOND_USER_API_BASE_URL`)。入口:发布页(T3-17 落地后)九宫格选图。
|
||
|
||
**步骤与通过标准**:
|
||
- (a)**蜂窝正常网**:相册多选 3 张 12MP 大图 → 逐格出现进度环且百分比递增(非一跳 100%)→ 全部转 ready;后端 `media.assets` 对应 3 行 `status='ready'`。压缩耗时中端机单张 ≤2s(超出记录机型上报)。
|
||
- (b)**弱网中断重试**:开发者选项限速或电梯/地库弱网,上传中开飞行模式掐断直传 → 该格转失败态(红色蒙层 + 重试通栏),其余图不受影响;恢复网络点格内重试 → 转 ready。
|
||
- (c)**孤儿不引用**:在(b)失败态与上传中态各尝试一次发布 → 发布钮 gating 拦截(全部 ready 前不可提交);发帖成功后 psql 核对 `community.post_media` 引用的 assetId 全部 `status='ready'`,且不含(b)中断产生的旧 assetId(该行保持 `uploading`,属服务端超时清理范围,不算失败)。
|
||
- (d)**凭据过期**:选一张图后挂起 App >10 分钟再恢复触发重试 → 客户端自动换新凭据完成上传(用户无感知,不弹「签名过期」类错误)。
|
||
- (e)**HEIC/方向**:iPhone 传输的 HEIC 图与横拍竖拍各一张 → 压缩层统一出 jpeg 且方向正确(服务端 mime 白名单不收 HEIC,此项只能真机验证原生编解码)。
|
||
2. **乐观更新真机手感**(T3-15/16 收口补全,2026-09-09):点赞/收藏快速连点的合并与回滚动画在真机帧率下的表现;Feed 卡片与详情页跨页状态一致。
|
||
|
||
**前置**:通用前置准备的后端六容器在位;`flutter run` 时四个 base URL 全传(含 `PATBOND_COMMUNITY_API_BASE_URL=http://<局域网IP>:8084`)。数据:Feed 内至少一条他人发布的帖子(可按 iteration-3 24 号报告 §5(a)种子方式造)。
|
||
|
||
**步骤与通过标准**:
|
||
- (a)**激活动画帧率**:Feed 卡片与详情页各点赞一次 → 图标同帧翻转 + 240ms 弹性缩放(1→1.25→1)+ 计数即时 ±1;中低端机无可见掉帧或延迟出现的「二次跳动」。取消点赞仅颜色渐出、无缩放。
|
||
- (b)**快速连点合并**:同一帖 1 秒内连点点赞 5~6 次 → 视觉每次即时翻转;抓包或服务端访问日志核对该帖 like 端点请求 ≤2 个(单飞 + 最终意图补发);停点后终态与最后一次点击一致,计数与 `GET /api/v1/posts/{id}` 权威值相符。
|
||
- (c)**断网回滚**:开飞行模式后点赞 → 图标即时翻转,数秒内**零动画直接跳回**原状态(不得出现「心已灭计数未减」的中间帧或回弹动画)+ SnackBar「操作失败,请重试」恰一条;恢复网络重点 → 正常收敛。
|
||
- (d)**跨页一致**:Feed 卡片点赞 → 进详情页应已是激活态;详情页取消收藏 → 返回 Feed 卡片同步取消(同一 ToggleSync 实例,无需刷新)。
|
||
- (e)**减弱动态**:系统开启「移除/减弱动画」后点赞 → 状态瞬变、无缩放动画,功能不受影响。
|
||
3. **Feed 图片加载**(T3-14 收口补全,2026-09-09):真机上滚动 Feed 的图片加载/缓存/占位表现;MinIO 经局域网/公网访问 URL 的可达性差异。
|
||
|
||
**前置**:通用前置准备的后端六容器在位;`PATBOND_MINIO_PUBLIC_ENDPOINT` 必须配置为手机可达地址(工作机局域网 IP:9000,.env 覆盖后重启 compose)——Feed 卡片封面 URL 是服务端现签的预签名 GET、直指 MinIO,漏配则真机图片全部走失败兜底(`surfaceTint` 底 + pets 图标);`flutter run` 时四个 base URL 全传(含 `PATBOND_COMMUNITY_API_BASE_URL=http://<局域网IP>:8084`)。数据:桌面/工作机先按 iteration-3 24 号报告 §5(a)的种子方式发 ≥26 帖(含单图/多图),保证两页以上可翻。
|
||
|
||
**步骤与通过标准**:
|
||
- (a)**首屏与占位**:登录进 Feed → 图片卡先出 `surfaceTint` 加载块(无白闪/布局跳动),随后出图;多图卡右下「+N」角标可读(ink 80% 胶囊白字)。
|
||
- (b)**滚动加载**:连续滚到列表底再回顶 → 中低端机不掉帧卡死;回滚经过已看过的图**不重新转圈**(缓存 key 已剥签名参数,同图不同签名命中同一内存缓存——若出现「每次刷新同图重新下载」即为缓存 key 回归,判失败)。
|
||
- (c)**下拉刷新后的缓存命中**:下拉刷新(服务端对同一批图重新现签、URL 必然变化)→ 已展示过的封面应即时出图不过转圈;抓包或 MinIO 访问日志核对同对象未重复 GET。
|
||
- (d)**过期 URL 重取**:Feed 停留 >1 小时(预签名 TTL)后滚到未加载过的卡 → 旧 URL 过期图走失败兜底属预期,下拉刷新取新签 URL 后恢复出图,无崩溃。
|
||
- (e)**可达性差异**:Wi-Fi(局域网 IP)与蜂窝(若 MinIO 未公网暴露)各滚一遍——蜂窝下连不上 MinIO 时应稳定显示失败兜底图标而非无限转圈;记录两种网络的首图出图耗时。
|
||
4. **社区事件落库**(T3-17 收口补全,2026-09-10):community 域 v3 事件(platform=android)落库观察(沿 M2 验证一的方法,事件名换 v3 增量)。**桌面端不可替代**:Linux 桌面的 `platform=linux` 不在契约枚举内,整批 400 被拒(`analytics_service.dart` 既有预期行为),故 v3 事件的**落库**只能在 Android 上验证;键集与形态的落库正确性已在工作机以 curl 造真实 payload 验证(iteration-3/26 §5c 发布/媒体 8 事件、iteration-3/25 §5c 互动 8 事件)。
|
||
|
||
**前置**:通用前置准备的后端六容器在位;`flutter run` 时四个 base URL 全传(含 `PATBOND_COMMUNITY_API_BASE_URL`);`PATBOND_MINIO_PUBLIC_ENDPOINT` 配为手机可达地址(媒体三段需真实直传)。可与第 1、2 项同一轮操作合并执行。
|
||
|
||
**步骤**:登录 → 首页 Feed 滚两屏并下拉刷新一次 → 进一条帖详情点赞/收藏/评论一次 → 返回 → 创作 Tab「发布动态」→ 输入正文 + 选 2 张图 → 「存草稿」一次 → 「发布」→ 回 Feed 确认新帖 → **退到后台等 5 秒**(触发冲刷)→ 工作机查库:
|
||
|
||
```bash
|
||
docker exec patbond-postgres-1 psql -U patbond -d patbond -c \
|
||
"SELECT event_name, platform, props FROM platform.product_events
|
||
WHERE event_name LIKE 'post\_%' OR event_name LIKE 'feed\_%'
|
||
OR event_name LIKE 'comment\_%' OR event_name LIKE 'user\_%'
|
||
ORDER BY client_ts DESC LIMIT 40;"
|
||
```
|
||
|
||
**通过标准**:
|
||
- [ ] (a)**发布漏斗成链**:`post_create_started`(entryPoint=create_tab) → `post_draft_saved`(trigger=manual, mediaCount=2) → `post_publish_succeeded`(fromDraft=true、mediaCount=2、topicCount=0、textLengthBucket、durationMs>0) 三条齐全且 `platform=android`;无 `post_publish_failed`(顺利路径)。
|
||
- [ ] (b)**媒体三段逐文件成对**:`post_media_upload_started` / `_succeeded` 各 **2** 条(每张图一条),`sizeBucket` 同一张图的 started/succeeded 取值一致,`durationMs` 为真实上传耗时(非 0);中断重试的那张(与第 1 项(b)合并执行时)另有 `post_media_upload_failed`(failureReason=network_error, attemptSeq=1) + 重试后 started 的 `attemptSeq` 递进。
|
||
- [ ] (c)**隐私红线**:上述 props 中**不含** postId / assetId / commentId / 文件名 / 本地路径 / URL / 精确字数(`textLength`)/ 精确字节数(`byteSize`)——出现任一即验收失败(红线 1/2/4)。
|
||
- [ ] (d)**互动与 Feed**:`post_liked`/`post_favorited`(source=feed 或 post_detail)、`comment_create_succeeded`、`feed_viewed`(离开 Feed 时一条,impressionCount>0、refreshCount=1)落库;**无** `post_impression`/`post_viewed`(字典锁死为 unknown,若出现即客户端违规)。
|
||
- [ ] (e)**页名归一化**:`page_viewed` 出现 `pageName='post_form'`(发布页)与 `'post_detail'`,且 pageName/referrer 中**不含 UUID**。
|
||
- [ ] (f)拒绝计数为 0:查 app 日志无 `Analytics batch permanently rejected`,或服务端响应 `rejected=0`(有 rejected 说明事件名/键集与字典不符,属回归)。
|
||
|
||
## 执行记录(M3)
|
||
|
||
_(待补)_
|
||
|
||
---
|
||
|
||
# M3.5 预登记(用户资料与头像,2026-09-11 登记)
|
||
|
||
M3.5 第二波(T3.5-08/09/10)交付后新增的真机专属项。**桌面已覆盖的不重复登记**:注册/登录 → 资料页真实化 → 设昵称 → 传用户头像 → Feed 作者名同步 → 宠物头像上传的整条链路已在 Linux 桌面对 compose 真后端跑通并逐步截图(`integration_test/profile_avatar_live_test.dart`,见 iteration-3.5/05 号报告 §4);下列四项是**桌面替代不了**的部分。
|
||
|
||
1. **头像上传弱网表现**(T3.5-08/09 收口登记):真机蜂窝/弱 Wi-Fi 下「选图 → 压缩 → 预签名直传 → confirm → PATCH 挂载」全链路。
|
||
|
||
**前置**:通用前置准备的后端六容器在位;`PATBOND_MINIO_PUBLIC_ENDPOINT` 必须配置为手机可达地址(工作机局域网 IP:9000,.env 覆盖后重启 compose)——头像直传与预签名读都直指 MinIO,漏配则手机端必失败;`flutter run` 四个 base URL 全传。入口:我的资料 → 编辑资料 → 更换头像;档案 → 宠物详情 → 点头像。
|
||
|
||
**与第 1 项(媒体上传弱网)的差异**:头像走的是**单图、单并发**的 `MediaUploader`(`maxImages: 1`、`maxConcurrentUploads: 1`),且交付口是「预览后点『使用这张』才落 assetId」,不是九宫格的批量 gating。故槽位调度与孤儿防护的表现需单独看。
|
||
|
||
**步骤与通过标准**:
|
||
- [ ] (a)**正常网真机相册**:从相册选一张 12MP 竖拍照 → sheet 内出线性进度条与递增百分比(非一跳 100%)→ 出圆形预览 → 点「使用这张」→ 回编辑页显示「已选择新头像」→ 保存后资料页头像**真的画出图**(不是爪印/人形占位)。此项同时验证原生压缩层(桌面实测用的是透传替身,真机才走 flutter_image_compress)。
|
||
- [ ] (b)**弱网中断重试**:上传中开飞行模式掐断 → sheet 转失败态并给「重试 + 重新选择」两个按钮 → 恢复网络点「重试」→ 转就绪可确认。中断产生的旧 asset 保持 `uploading`(属服务端超时清理范围,不算失败);核对 `identity.users.avatar_asset_id` / `pet_health.pets.avatar_asset_id` **未**指向中断的那个 assetId。
|
||
- [ ] (c)**压缩后仍超限**:选一张超大原图(若压缩后仍 >10 MiB)→ 失败态**只给「重新选择」、不给「重试」**(重试同一张必然再失败)。
|
||
- [ ] (d)**凭据过期**:选图后把 App 挂起 >10 分钟再回前台触发重试 → 自动换新凭据完成上传,用户无感知,不弹「签名过期」类错误。
|
||
- [ ] (e)**中途退出不留引用**:上传中直接关掉 sheet → 无 SnackBar 报错、资料/宠物头像不变;`post_media_upload_failed(failureReason=cancelled)` 一条(头像沿用同一套媒体埋点)。
|
||
- [ ] (f)**HEIC 与方向**:iPhone 传输的 HEIC 与横拍各一张 → 压缩层统一出 jpeg 且方向正确(服务端 mime 白名单不收 HEIC,只能真机验原生编解码)。
|
||
|
||
2. **头像缓存表现**(T3.5-08/09 收口登记):预签名 URL 每次响应现签,缓存 key 已剥 `X-Amz-*`;真机需确认同一张头像不会反复下载、过期后能重取。
|
||
|
||
**前置**:同第 1 项。数据:本人已设头像、至少一只宠物已设头像、Feed 内有本人发布的帖(作者头像与资料页头像同一对象)。
|
||
|
||
**步骤与通过标准**:
|
||
- [ ] (a)**跨页命中**:资料页 → 首页 Feed(作者头像)→ 档案列表 → 宠物详情,来回切三轮 → 已展示过的头像**不再转圈**;抓包或 MinIO 访问日志核对同一 object key 未重复 GET(缓存 key 剥签名参数生效;若「每次进页面同图重下」即为 `presignedImageCacheKey` 回归,判失败)。
|
||
- [ ] (b)**下拉刷新后仍命中**:Feed 下拉刷新(服务端重新现签、URL 必变)→ 作者头像即时出图不转圈。
|
||
- [ ] (c)**过期后重取**:停留 >1 小时(预签名 TTL 默认 1h)后进未加载过的页 → 旧 URL 过期走占位属预期;下拉刷新/重进页面取新签 URL 后恢复出图,无崩溃、不缓存坏图。
|
||
- [ ] (d)**清除头像后不留残影**:编辑页「清除头像」保存 → 资料页立刻回人形占位,Feed 作者头像在服务端作者缓存过期后(≤60s,见下方备注)也回占位;重启 App 后仍是占位(URL 不得被持久化,纪律 R2)。
|
||
|
||
3. **caregiver 账号改宠物头像**(T3.5-09 收口登记;ADR-022 D3.5-3 的 WRITE 档实证):桌面实测只跑了 owner 路径,caregiver 需第二个账号 + 一条协作关系。
|
||
|
||
**前置**:两个账号 A(owner)/ B(caregiver),B 对 A 的宠物有 caregiver 角色(关系授予入口尚未开放,按 `pet_health` 的协作表直接造数据,收口时补 SQL)。
|
||
|
||
**步骤与通过标准**:
|
||
- [ ] (a)B 打开该宠物详情 → **头像铅笔角标在**(WRITE 档),但「编辑资料」入口**不在**(MANAGE 档,仅 owner)。
|
||
- [ ] (b)B 上传头像 → 成功;A 侧刷新详情看到同一张。
|
||
- [ ] (c)viewer 角色的第三个账号 C → 头像不可点、无角标。
|
||
|
||
4. **获赞数与帖子点赞数对账**(T3.5-08 收口登记):资料页「获赞」= 本人已发布未删帖的 `like_count` 之和(**含自赞**,与帖子详情同口径)。
|
||
|
||
**步骤与通过标准**:
|
||
- [ ] (a)自己给自己的帖点赞 → 帖子详情 likeCount +1,资料页「获赞」也 +1(两处数字必须能对上;对不上说明口径分叉)。
|
||
- [ ] (b)他人点赞 2 次不同帖 → 资料页「获赞」为各帖 likeCount 之和。
|
||
- [ ] (c)软删一篇被赞的帖 → 「获赞」与「我的作品」同时回落(删帖即撤回其数字)。
|
||
- [ ] (d)存一篇草稿 → 「我的作品」**不**变(草稿尚非作品)。
|
||
|
||
> **备注(服务端刻意的滞后,不是缺陷)**:改昵称/换头像后,**Feed 与帖子详情里的作者名与作者头像**最多滞后 60 秒才更新——community 侧 `AuthorProfileGateway` 把 `/internal/users/profiles` 的结果放在 60s TTL 的进程内缓存里(`patbond.author-profile.cache-ttl`,M3 T3-05)。资料页与首页问候语读的是 `/me`,**没有这层缓存,立即生效**。真机执行第 2、4 项时若看到「资料页已变、Feed 还是旧名」,先等过 60 秒再判定。
|
||
|
||
## 执行记录(M3.5)
|
||
|
||
_(待补)_
|
||
|