Tanplate Docs

Consent 与隐私偏好

Necessary、Analytics、Marketing 分类、匿名 Cookie、撤回流程和未来 Provider 接入规则。

Consent 由 Analytics 或 Newsletter 派生,而不是固定 Core;两者都关闭时 UI、API 与客户端状态不进入 Web 产物。启用时它们共享同一份 Consent policy,不各自维护状态;快照不绑定账号、不写 D1,也不包含邮箱、Session、Prompt 正文或其他 PII。

分类与默认值

分类默认值用途
Necessary允许安全、认证、保存隐私选择,以及退订、suppression、删除履行
Analytics拒绝页面浏览和类型化产品事件
Marketing拒绝Newsletter 营销发送、新增联系人和 Provider 正向同步

缺失 Cookie、损坏 JSON、未知字段、非布尔选择或不兼容 policy version 都会回到 optional denied。Necessary 不能被改写成 Marketing;撤回 Marketing 后,新增联系人和发送停止,但退订、suppression、Provider 联系人删除与删除请求履行仍必须继续。

状态与 HTTP 边界

GET /api/consent 返回当前快照:

{
  "choices": { "analytics": false, "marketing": false },
  "policyVersion": 1,
  "status": "unconfigured",
  "updatedAt": null
}

PUT /api/consent 只接受 analyticsmarketing 两个布尔字段。Worker 生成 policy version 与更新时间,并写入 tanplate-consent Cookie:

  • HttpOnly
  • SameSite=Lax
  • Path=/
  • HTTPS 下增加 Secure
  • 一年有效期

GET/PUT 均返回 Cache-Control: no-store。客户端不能直接读取 Cookie,只能消费并再次严格校验同源 API 返回的快照;不兼容或畸形响应不能授权 optional effect。

用户流程

Consent 能力启用时,首访者会在页面底部看到不遮挡主内容的 band,可以拒绝全部可选项、分别查看两类选择或全部接受。偏好 Dialog 将 Necessary 显示为始终启用,并为 Analytics/Marketing 提供独立 toggle。保存后 band 消失;顶栏盾牌按钮可以随时重开。保存会广播本页 typed snapshot,并写入不含选择与 PII 的 localStorage revision;其他打开的标签页收到 signal 后先把 optional cache 置为 denied,再从 API 刷新。

Provider 接入

Analytics/Newsletter 不得直接读取 Cookie 或另建同意布尔值。服务端 effect 使用 runConsentEffect,客户端脚本消费 API 快照与 Consent 同步事件,并继续调用同一 allowsConsentCategory / allowsConsentOperation policy。功能关闭、快照不兼容或同意不足时,gate 不调用 effect callback。

Analytics 已由 PRD 16 通过同一 policy 接入类型化 facade 和 Umami adapter;未同意或模块关闭时不请求配置、加载脚本或排队事件,撤回时清理匿名 Provider 状态。Newsletter 的真实 Provider 消费仍由 PRD 17 验收;Jobs/Webhooks 已由 PRD 15 验证。

验证

pnpm --filter @tanplate/consent test
pnpm --filter web test
pnpm --filter web exec playwright test tests/consent-preferences.spec.ts

覆盖单一分类源、合规操作、无副作用 gating、Cookie/API snapshot fail-closed、静默本地化请求、本页/跨标签页同步,以及首访、独立选择、刷新、重开、撤回和损坏 Cookie 浏览器流程。

On this page