从零开始的合规——直到机制层面
这里的隐私合规不是一句宣传语,而是一条代码路径,而且这条路径真的有牙齿:
同意开关(app 端,analytics_service.dart):
- 默认关闭。
_consentGranted = prefs.getBool('analytics_consent_granted') ?? false——没有同意就没有采集;随后setAnalyticsCollectionEnabled(_consentGranted)把这个开关一路推进 Firebase 内部,连原生的自动事件(first_open、session_start、screen_view)都一并挡住,不只是自定义事件。 grantConsent只在用户于同意屏幕接受条款之后才会被调用——而且在 E2E 测试套件里这个授权是被await的(2026-04-18 的提交修的正是这一点),所以同意路径是被测试覆盖的,不是摆设。- 针对测试/开发构建,还有一道编译标志级别的硬性关闭,做得更彻底:
setAnalyticsCollectionEnabled(false)加上resetAnalyticsData()——把缓存的 app 实例 id 一并丢掉,"这样测试模拟器就不会冒充成回访用户。" 数据卫生在源头被强制执行;分析用的 CLI 则在查询端排除模拟器——管道两端用的是同一套纪律(measurement-stack)。 - 全程 fire-and-forget 加 try/catch——分析代码绝不允许拖垮它所测量的产品;失败时是记日志,而不是悄无声息地消失(一处裸露的
debugPrint吞异常,后来在摄像头调查中被定性为"GA4 全瞎"——camera-bug-looked-like-user-behavior)。
Web 端(同一部法律,同一天): GA4 的 Consent Mode v2 cookie 横幅,针对 PIPEDA(加拿大联邦隐私法——个人信息保护和电子文档法)而做,2026-03-27 上线——和 app 端同意开关的提交同一天。一部法律,两个界面,一个变更集边界。
会话回放守同一道墙(2026-07-24): 移动端的 Clarity 屏幕录制只在一种组合下启动——release 构建、未被构建标志禁用、用户已同意——而这道门是一个纯函数 shouldStart(),整张决策表都有测试:唯一允许的组合启动,其余十五种全部拒绝。未经同意录下司机的屏幕是隐私侵犯;一道死掉的门则会发出一件默默失效的仪器。后台遮罩设为最严格,运单页面上的收件人姓名和地址永远不会出现在录像里。
应用商店强制要求的页面: 隐私政策、条款、删除账号页面(独立开发者最常在 App Store 这条要求上翻车)——都已在官网上线。
政策即 lint: 用 ESLint 强制执行 i18n(2025-12-24,"修复所有硬编码字符串"),把"一切都必须可本地化"从评审时的碎碎念变成了构建失败——这是负责人把约束机制化,而不是靠口头约定这一原则用在合规上的体现。
对外宣称也守同一条线: 硬编码的虚假聚合评分 schema 被删除(2026-03-29);无法保证真实性的"设备端数据"宣传语从落地页 About 中被剥离(2026-07-09)。合规延伸到营销说了什么,而不只是代码做了什么。
面试原型问题:"你们怎么处理隐私/合规?"——同意默认关闭并被推进 SDK 内部,授权路径有 E2E 测试覆盖,开发构建污染不了用户群组,政策是一条 lint 规则,我无法保证的营销宣称会被删掉。