Files
lixi f5457c2f4c
CI / docs-build (push) Successful in 2m2s
docs: M3 第三波收口——报告 21~27 入档挂导航
- 21~26 Flutter 社区接入五单 + 字典 v3 白名单(flutter 286→502、api 325→334)
- 27 收口总表:社区 demo 三页消亡、M3 四条验收标准逐条取证、
  乐观更新与媒体链路端到端、实现期修正记录
- device-verification.md 的 M3 四项真机步骤已由各单收口补全

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-10 14:48:33 +08:00

77 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 22 事件字典 v3 白名单扩充(T3-20 后端,ADR-020
**执行日期**2026-09-09
**交付**EventDictionary v2 → v322 → 42 事件)+ 全套边界测试,patbond-api dev @ `8089c06`
**依据**:06 号报告 §1.4/§1.5(事件与 props schema)、§1.2feed_viewed 聚合裁定)、§1.3(隐私红线增量)、§6.1(pageName 页面族)
---
## 0. 概要
| 项 | 值 |
|------|------|
| 新增事件 | **20**06 号 §1.5 的 19 个 + experiment_exposed 已含其中,编号 22~40 |
| 字典总量 | 22 → **42** |
| 测试 | 325 → **334**+9EventDictionaryTest +6、AnalyticsIntegrationTest +3),全绿 |
| openapi.yaml | **零变更**——/api/v1/events 契约对事件名开放(键级校验在字典层),复核无需动 |
| check-secrets.sh --all | 通过(exit 0 |
改动仅限 patbond-user analytics 包三个文件:`EventDictionary.java``EventDictionaryTest.java``AnalyticsIntegrationTest.java`
## 1. 新增事件与 06 号对照清单
props 键集与 06 号 §1.5「工单可直接抄」代码块**逐键一致**(原样落地,零偏差):
| # | 事件名 | props 白名单 | 06 号出处 |
|---|--------|--------------|-----------|
| 22 | `post_create_started` | entryPoint | §1.4 发布漏斗 |
| 23 | `post_draft_saved` | trigger, mediaCount | §1.4 发布漏斗 |
| 24 | `post_publish_succeeded` | durationMs, mediaCount, topicCount, textLengthBucket, fromDraft | §1.4 发布漏斗(漏斗事件) |
| 25 | `post_publish_failed` | failureReason, errorCode, httpStatus, attemptSeq | §1.4 发布漏斗 |
| 26 | `post_deleted` | (空集——单事件风格无专有属性) | §1.4 发布漏斗 |
| 27 | `post_media_upload_started` | mediaType, sizeBucket | §1.4 媒体漏斗(逐文件) |
| 28 | `post_media_upload_succeeded` | mediaType, sizeBucket, durationMs | §1.4 媒体漏斗(漏斗事件) |
| 29 | `post_media_upload_failed` | mediaType, sizeBucket, failureReason, errorCode, httpStatus, attemptSeq | §1.4 媒体漏斗 |
| 30 | `feed_viewed` | feedTab, durationMs, impressionCount, loadMoreCount, refreshCount | §1.2/§1.4 聚合曝光(首个高频事件) |
| 31 | `feed_load_failed` | feedTab, loadType, failureReason, errorCode, httpStatus | §1.4 Feed 消费 |
| 32 | `post_liked` | source | §1.4 互动 |
| 33 | `post_unliked` | source | §1.4 互动 |
| 34 | `post_favorited` | source | §1.4 互动 |
| 35 | `post_unfavorited` | source | §1.4 互动 |
| 36 | `comment_create_succeeded` | durationMs, isReply, textLengthBucket | §1.4 互动 |
| 37 | `comment_create_failed` | failureReason, errorCode, httpStatus, attemptSeq | §1.4 互动 |
| 38 | `user_followed` | source | §1.4 互动 |
| 39 | `user_unfollowed` | source | §1.4 互动 |
| 40 | `experiment_exposed` | experimentKey, variant | §1.4 实验基建(A/B 前置 #5M4 启用字典先行) |
**故意不进字典**(测试侧同步锁死为 unknown):`post_impression`(§1.2 逐卡曝光否决)、`post_viewed`(§1.4 由 page_viewed(post_detail) 覆盖)、`comment_create_started`(短表单不设 started)、`post_like_failed`/`user_follow_failed` 等单点互动失败(靠服务端错误率观测)、`topic_followed/unfollowed`(§1.6 缺口 3,UI 定稿前挂起待拍板)。
## 2. pageName 页面族核对(§6.1
字典侧 pageName 的登记处只有 EventDictionary 的 javadoc 注释(ingest 只校验 props **键**`page_viewed` 键集 pageName/referrer 不变)——已按 §6.1 同步为 v3 页面族:v2 九个 + 收编 4create/pet_archive/services/post_detail+ 新增 9post_form/topic_list/topic_detail/user_profile/follower_list/following_list/favorite_list/draft_list)。与 §6.1「后端零改动提示」一致,无任何校验代码变更;值级枚举仍由客户端编译期 + 离线巡检兜底。
## 3. 测试增量(325 → 334
**EventDictionaryTest +6**(沿既有 `containsExactlyInAnyOrder` 键集锁定模式):
1. `v3PostPublishFunnelMatchesDictionary` — 发布漏斗五事件,含 post_deleted 空集断言
2. `v3MediaUploadFunnelMatchesDictionary` — 媒体三段漏斗
3. `v3FeedDomainMatchesDictionary` — feed_viewed 聚合键集(无任何内容 ID 键)+ feed_load_failed
4. `v3InteractionEventsMatchDictionary` — 互动八事件(分立事件名,无 action 属性)
5. `v3ExperimentExposedRegisteredAheadOfM4Use` — experimentKey/variant
6. `v3DeliberatelyAbsentEventsStayUnknown` — §1 末段七个故意不设事件
**AnalyticsIntegrationTest +3**(沿 v2 端到端先例):
1. `acceptsV3FeedViewedAggregateEvent` — feed_viewed 全键入库落表
2. `stripsContentIdPropsFromV3InteractionEvent` — post_liked 混入白名单外 `postId` 被剥离(红线 2 的 ingest 侧兜底)
3. `rejectedPerCardImpressionStaysOutOfDictionary` — post_impression 按 unknown_event_name 拒绝(§1.2 裁定锁死)
全套 `./mvnw clean test`**334 测试 0 失败**user/auth/pet/community/common 五模块 BUILD SUCCESS)。
## 4. 边界与遗留
- **契约零变更**:events 接口对事件名开放,openapi.yaml/契约快照均不需动,本工单未触碰。
- **Flutter 半边未动**:客户端强类型封装(post_analytics.dart / feed_analytics.dart / community_interaction_analytics.dart / analytics_page_name.dart 增量)属 T3-20 客户端半边,不在本工单。
- **待拍板项不预埋**`content_rejected` 失败枚举(审核环节待拍板)与 `topic_followed`(UI 定稿)均未进字典,拍板后按 eventVersion 惯例增补。