docs: 阶段B计划吸收审查修正——T6前置server时间线白名单扩展/归因分支位置与有意分歧钉死/漏斗窗口与site条件/unaccepted测试/SITE_ID
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -59,7 +59,7 @@ def test_biz_event_validation(ev, expect_reason):
|
||||
assert validate_event(ev, v2=True, batch_site_id=SITE_ID, batch_visitor_id="v1") == expect_reason
|
||||
```
|
||||
|
||||
(SITE_ID/imports 参照该文件既有测试;timezone 从 django.utils 导入。)
|
||||
(**SITE_ID 在本文件不存在**——从 test_ingest.py import 或本地定义(`SITE_ID = "site_test"`),timezone 从 django.utils 导入;注意文件头已有 imports 复用。)
|
||||
|
||||
- [ ] **Step 2: 跑失败**(property_not_allowed——白名单无新事件)
|
||||
|
||||
@@ -155,7 +155,7 @@ def test_gclid_still_paid_search():
|
||||
|
||||
- [ ] **Step 3: 实现**:
|
||||
- constants:`CHANNELS = (..., "paid_social", ...)`(paid_search 之后);`ATTRIBUTION_RULE_VERSION = "v2"`;付费 medium 全集常量 `PAID_MEDIUMS = {"cpc","ppc","paidsearch","paid","social","paid_social","social_ads","paidsocial"}`、`SOCIAL_MEDIUMS = {"social","paid_social","social_ads","paidsocial"}`
|
||||
- attribution.py classify:现有 `_paid_param` 分支改:fbclid → paid_social / gclid/msclkid/yclid → paid_search;**新增分支(在 _paid_param 之后、referrer 判定之前)**:无点击参数时若 utm_source 命中 fb 家族(复用 `_AD_FAMILIES`/家族表)且 utm_medium∈PAID_MEDIUMS → paid_social(evidence_kind="utm_label", resolution="label_only");utm_source 非 fb 家族但 medium∈PAID_MEDIUMS-\SOCIAL_MEDIUMS → paid_search label_only(既有强化行为保持)
|
||||
- attribution.py classify:现有 `_paid_param` 分支改:fbclid → paid_social / gclid/msclkid/yclid → paid_search;**fb+paid 优先检查集成在 UTM 叠加分支内部(attribution.py:202-204 的 else 路径)而非其前**——字面"放在前面"会被后续 `_utm_channel(utm_source)` 覆写(fb→referral)并破坏测试:utm_source 命中 fb 家族(经 `_canon` 归一后查 `_AD_FAMILIES`)且 medium∈PAID_MEDIUMS → paid_social(evidence_kind="utm_label", resolution="label_only");非 fb 家族 + medium∈PAID_MEDIUMS-SOCIAL_MEDIUMS → paid_search label_only(**注意这是新行为**:现行为 google+cpc 走 _utm_channel=natural_search,spec §3 将其改判付费);**非 fb + medium∈SOCIAL_MEDIUMS 不判付费**(twitter&utm_medium=social 仍走社交/引荐——与 spec 字面"其余付费 medium→paid_search"的有意分歧,防误伤自然社交,计划钉死此决策)
|
||||
- [ ] **Step 4: 全量回归 + 既有归因测试按新口径更新**(fbclid 断言从 paid_search 改 paid_social 等预期内变更)
|
||||
- [ ] **Step 5: Commit** `feat(server): 归因v2——paid_social渠道与fb+付费medium优先规则`
|
||||
|
||||
@@ -177,7 +177,7 @@ def test_funnel_summary_excludes_bots(db, ...):
|
||||
# is_bot=True 的事件不计入任何级
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 实现**:`GET /api/admin/funnel-summary?days=N`(默认 7;权限/site 过滤沿 dashboard 既有模式)。五级 event_name 序列 `["page_view","contact_click","form_start","form_submit","form_submit_result"]`,每级 `Event.objects.filter(site=, occurred_at__gte=窗口, is_bot=False, event_name=级).values("session").distinct().count()`。
|
||||
- [ ] **Step 2: 实现**:`GET /api/admin/funnel-summary?days=N`(默认 7;权限/site 过滤沿 dashboard 既有模式——**site 条件按 dashboard 的条件过滤写法**(site 参数缺省/None 时不加 filter),勿字面 `filter(site=None)`;**时间窗复用 dashboard 既有上海自然日窗口计算**(make_aware(combine(...)),`[T-N+1, T+1)`),保证"当日"与总览今日卡口径一致)。五级 event_name 序列 `["page_view","contact_click","form_start","form_submit","form_submit_result"]`,每级 `Event.objects.filter(<site 条件>, occurred_at__gte=窗口, is_bot=False, event_name=级).values("session").distinct().count()`。
|
||||
|
||||
- [ ] **Step 3: 回归 + Commit** `feat(server): 询盘漏斗API——五级独立distinct会话计数/排除机器人`
|
||||
|
||||
@@ -210,6 +210,7 @@ form_start:.wpcf7-form 内 isTrusted focusin → 事件 + _ctk_sid 空占位
|
||||
form_submit:表单原生 submit(capture 委托)→ submission_id 生成 + _ctk_sid 值更新 + 事件引用同 ID
|
||||
(两次 submit → 两个不同 submission_id)
|
||||
form_error:dispatch wpcf7statuschanged(status="invalid") → error_code=invalid;
|
||||
status="unaccepted" → error_code=invalid(spec §1.2 映射,勿漏);
|
||||
status="spam" → spam;field_count 从 DOM .wpcf7-not-valid-tip 计数
|
||||
form_submit_result:status="mail_sent" → result_code=mail_sent;"mail_failed" → mail_failed
|
||||
form_id:action="#wpcf7-f156-p20-o1" → "cf7-156"
|
||||
@@ -275,6 +276,8 @@ function matchProduct(path: string): string | null {
|
||||
- Modify: `admin/src/api/`(漏斗 API 函数,沿 dashboard 既有 API 模块)
|
||||
- Test: Playwright 视觉验证(T6 内含)
|
||||
|
||||
- [ ] **Step 0: server 时间线 payload 白名单扩展**(前置——timeline API 现只出 time/event_name/path/title/active_ms,不透出 properties,业务属性到不了前端):`server/tracker/api/visitors.py` 的 `_merge_page_stay`(约 178-202 行)事件序列化处,按事件名增加安全字段映射:contact_click→channel;form_start→form_id;form_submit→form_id+submission_id 前 8 位;form_error→error_code+field_count;form_submit_result→result_code;product_view→product_id+inferred(全部非 PII,OT10 白名单内字段)。test_visitors.py 加断言(新事件行带安全字段、无其他 properties 泄漏);admin `TimelineEvent` 接口(api/tracker/visitors.ts:119-127)同步字段。**先 server 测试红绿再动 admin**,随本任务 commit。
|
||||
|
||||
- [ ] **Step 1: EventTimeline EVENT_META 扩展**(先读现有 EVENT_META 结构):
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user