跳转到正文

English core guides · 历史记录保留中文

工作台使用与购买事件 ​

这是 I11 的服务端观测模块,默认关闭。它依据已经提交的任务、文件读取和积分包结算与个人 / 团队订阅账单付款事实记录事件,和公开工具的浏览器报告、Cloudflare 访问统计、营销邮件同意各自独立。目前没有统计后台,也不提供浏览器自报购买金额的接口。

配置与升级 ​

在 packages/core/website.ts 的 analytics 中加入:

ts
serverEvents: {
  enabled: false,
  consentVersion: "2026-10-10.2",
  retentionDays: 30,
},

启用当前版本前,把目标数据库按完整顺序升级至 0025_team_payment_activity.sql,然后一起重建 API 与工作台。0018 新增个人选择表 activity_consent 和事件表 server_activity,0019 新增个人账单恢复检查时间;0025 新增 team_activity_consent,事件必须归属个人或团队之一,团队只能记录订阅付款。旧个人事件保持原数据与全局唯一键,已有站点继续追加迁移,不重写历史。旧生成站还需补齐配置字段;本任务主预览仍为 0012,此功能关闭,不读取这些可选新表。独立测试数据库的迁移验收不代表主库已升级。

不需要新供应商密钥。consentVersion 为 1—80 字符,retentionDays 为 1—90 天;默认 30 天。修改同意用途或数据范围时更新版本,旧版本不再授权新事件。个人订阅账单用途使用版本 2026-10-10.2,更早的个人同意需重新明确选择。本轮团队选择单独从未授权状态开始,个人用途保持该版本,不能把已有个人同意升级成团队同意。provider 和 toolEvents.enabled 不会自动开启此模块。

用户选择 ​

启用后,工作台 Settings 出现 Activity reporting 卡片。初始不勾选,只有点击 Save choice 并获得服务端确认才生效;取消勾选后也要保存才能撤回。Last confirmed choice 展示最后得到确认的选择,勾选框自身不是已保存状态。失败时显示未确认,并可 Reload choice 读取实际状态,不自动重试写入。

选择属于当前个人账号,不接受客户端传入所有者。服务端重新检查账号状态、同源请求和操作限额。每次变更带当前 revision,旧标签页不能覆盖较新的撤回;返回冲突时先重新加载。相同选择与版本重复保存不延长同意起点。表中保留最新选择、版本、同意 / 撤回时间和版本号,不是完整同意历史档案。

公开工具页面的选择、注册账号或加入邮件名单都不授予此权限。撤回后停止新记录;已经收到的记录按保留规则清理。删除账号会级联删除这两张表中该账号的数据,不改变账本或管理审计各自的保留规则。

事件口径 ​

事件真实触发点去重与限制
task_started原任务首次领取执行租约,第一条尝试已提交每个任务一次;排队 / 提交不算开始,后续重试不增加开始次数
task_succeeded当前租约的结果实际发布成功,任务状态已提交每个任务一次;失败、取消或过期租约不能造成功事件
file_download_initiated私有文件实际读取成功,并进入附件响应路径每个文件在保留记录期间一次;普通预览不计,外部 API 的附件响应计入;不证明完整传输或用户已保存
purchase_confirmed积分包结算已验证、购买的 grantedAt 存在且匹配原积分发放账本每个购买一次;未付款的 Checkout、详情页浏览和客户端金额不构成购买
subscription_payment_confirmed个人或团队订阅的当前已付账单、完整已付分配记录和实际成功 PaymentIntent / 已捕获 Charge 经服务端核查每张账单一次;同一订阅的续费账单各自计数;零元试用、客户抵扣和线下 PaymentRecord 不计

事件唯一键是资源 ID 加事件类型。已签名回调、后台恢复与拥有者的购买详情读取共用同一记录;重复回调或确认页刷新不会重复增加购买与积分。这里没有另建前端购买上报通道。

购买保存原购买的最小货币单位金额、币种及 livemode。测试付款和真实付款必须分开,币种不能直接相加。这是原始购买确认,后续退款或争议不会把它改写成净收入;利润、留存、净收入归因尚未实现。订阅付款详见下一节;订阅激活、试用或打开结账页不能当作已付款。

订阅账单付款 ​

接收已有 /api/auth/stripe/webhook 的 invoice.paid,使用现有原始正文 SDK 验签和测试 / 真实模式门禁。默认关闭时不读新增表、不向供应商查询。开启时要求账单的订阅 ID、客户 ID 与已保存的订阅、当前个人 / 团队客户及该主体的明确同意全部匹配;个人和团队身份同时匹配时保守跳过,不推断归属。团队账单不会归到管理员或成员个人账号。

签名事件只提供核查线索。服务端重新读取账单,要求当前 paid、正数付款额、余额为零、正确币种 / 模式和有效付款时间;再分页读取该账单完整的已付分配记录,核查对应 PaymentIntent 的 succeeded、客户 / 模式 / 币种及实际收款,或旧式 Charge 的 paid / captured 与金额。同一收款来源的分配合计不能超过其实际收款,分配总额还必须等于账单 amount_paid。不是直接存事件载荷里的金额。

零元试用 / 全额折扣、客户余额抵扣和线下标记付款不记为新收款。存在 PaymentRecord 等未支持来源或分配不完整时保守跳过,不用部分金额冒充完整付款;超过每张账单 100 个付款分配、重复页或分页不完整时记录通用故障。本模块不会修改订阅状态、权限、额度或积分。参考 Stripe 账单、付款分配。契约核对日期为 2026-10-10;本地 SDK 固定 API 版本为 2026-08-26.dahlia,Stripe Endpoint 应采用对应账单对象结构。

唯一键使用供应商账单 ID 加固定事件类型。回调与后台恢复共用该键;个人和团队工作台的确认 / 状态页面只读取原订阅状态,不发购买上报或扫描供应商历史,刷新不会增加事件。续费的另一张账单可新增另一条事件。金额是所核实账单的原始收款确认,不扣后续退款 / 争议,也不是 MRR 或净收入。测试与真实、不同币种须分开。

有效签名账单在可选统计故障时仍应答成功,不让观测故障干扰原账单流程;后台扫描供应商的当前已付账单恢复,普通工作台读取无需等待这项扫描。每个个人或团队主体两次尝试至少相隔 15 分钟,每轮后台合计最多三个主体,按上次尝试时间轮换,失败也会让出下一轮位置。每个主体最多查 1,000 张已付账单,未完整分页不假报恢复完成;已写入的部分真实事件保留并按唯一键去重。创建时间很早但最近付款的账单仍按实际 paid_at 与同意起点筛选,不用 created 过滤误删迟付。

恢复扫描按最新同意版本原子领取统计自己的检查时间,不占用账单操作租约;供应商历史查询暂停时,用户仍可管理账单。检查时间在开始尝试时写入,失败同样等待下一轮,旧扫描没有完成后回写时间的路径。处理过程中撤回或变更版本,最终写入再次检查当前选择;重新同意会重置待检查时间。限额、供应商延迟和保守跳过会漏报,不保证即时或完整统计。参考 账单列表接口。

团队的独立选择 ​

切换到团队后,Settings 还显示 Team payment reporting 卡片。初始不勾选,个人账号是否同意不改变这里的选择。当前 owner / admin 可以明确保存或撤回;普通成员只能查看已确认状态,已移除成员不能读取或修改。团队选择只授权该团队的新订阅收款,成员的任务、文件、积分包仍属于各自个人选择。

请求带页面看到的团队 ID、当前同意版本和 revision。服务端核对所选团队与实际会话当前团队一致,重新检查仍有效的会话、未封禁个人账号和最新成员角色;成员写操作与选择保存共用团队锁。保存等待期间被降级或移除时拒绝,旧页面不能覆盖新撤回。切换团队后丢弃未保存的勾选,查询缓存按账号和团队分别隔离。这个隐私选择没有额外要求 24 小时新鲜会话。

团队同意和最终付款插入受事务保护,供应商查询期间撤回会阻止新记录;重新同意只接纳新起点后的付款,不能补齐旧同意区间的遗漏。团队付款与个人付款共用收款核查、事件表和账单 ID / 类型唯一键,即使账单以后改绑也不会再写一条。重复回调、详情页刷新和续费恢复不发积分、不修改订阅权限。

团队选择保存最后决策者的本站账号 ID、版本、revision、同意 / 撤回时间和恢复检查时间,不是完整同意历史。该决策者离队或删除个人账号不撤销团队选择,也不删除团队付款;决策者 ID 作为历史标识保留,不存姓名或邮箱。删除团队会级联删除团队选择与团队事件,原个人事件仍按个人规则保存。

保存哪些数据 ​

记录包含本站账号 ID 或团队 ID(恰好一个)、资源 ID(任务 / 文件 / 积分包使用内部 ID,订阅付款使用供应商账单 ID)、固定事件类型、同意版本、发生 / 入库时间,任务另含固定处理器 ID,购买另含上述金额、币种和测试状态。它是可关联账号或团队的第一方内部记录,不能称为匿名统计,也没有发送到外部分析供应商。

不记录输入、结果、文件名、邮箱、页面 URL、任意参数或支付原始回调。统计失败只记录通用错误名称。删除文件或任务不会删除其历史观测;观测仍受保留期限约束。上线前须把实际数据范围、站主、保留与联系方式写入自己的隐私说明;模板隐私页只是草稿。

故障恢复与保留 ​

记录在业务提交后尝试。观测表不可用不会撤销已经完成的任务、积分结算或文件内容响应,但可能漏报,也会增加少量本地查询时间。

定时入口在既有文件 / 任务维护之后补查缺失的任务开始、成功和积分包确认,每类每轮最多 100 个候选。只补当前有效同意起点之后、保留期内、仍然存在的业务事实;每次插入再次检查账号和最新选择。没有用户访问也可恢复,但不保证完整或实时统计。

撤回、改变版本或重新同意发生在恢复之前时,旧同意区间内未写入的事实不会补齐。重新同意不追溯旧行为。下载没有独立持久化基础事实,失败不能后台补造。

清理每次最多删除 500 条超过保留天数的事件,按发生时间判断;维护失败或积压会延迟实际删除。模块关闭也会停止自动清理,需要站主单独安排已有数据清理。个人同意记录保留至账号删除,团队同意记录保留至团队删除。旧任务 / 购买事实超过期限不会被恢复程序重新插入;文件原记录过期后,新的实际下载请求可以产生新记录,因此该指标不能称为终身唯一下载文件数。

本地验收 ​

bash
bun --env-file .env --env-file .env.local apps/api/local/validate-server-activity.ts

验证器只接受本地 PostgreSQL,建立并迁移自己的一次性数据库,运行真实生产入口的 Worker、Queue 与 R2。Stripe HTTP 使用受控响应,回调由已安装 SDK 生成签名;邮件捕获且其他外部请求拒绝。退出时销毁自己创建的资源,不升级主数据库。

加 --ui 可在独立 activity.localhost:21312 预览卡片。完成选择 / 保存 / 撤回后,用验证器提示的本地结束标记收尾,它会检查最终选择和事件数量后清理。测试账号和口令只用于一次性环境,不能作为部署配置。

已有证据包括 8 项真实迁移数据库行为测试、个人选择交互,以及支付测试中的已签名结算恢复 / 确认页去重。原生验收涵盖实际执行、八并发附件下载、观测故障后任务成功与定时补齐、签名购买回调和撤回。11 项个人订阅账单行为测试和 1 项普通账单读取边界测试继续通过;--invoices 同时验收签名账单、八并发去重、分页收款分配和续费恢复。

本轮新增团队选择的 6 项真实数据库 / RPC 与增量迁移测试、5 项账单归属与撤回测试,工作台选择交互扩展到 7 项(含西班牙语失败确认)。--teams 包含已有 --invoices,原生验收在真实 PostgreSQL 锁等待期间降级角色,随后八并发签名回调只生成一条团队记录;统计表故障不阻断账单,实际定时入口补回续费。--teams --ui 验证个人和团队分别保存 / 撤回,最终均为不分享、revision 4;390 像素浅深主题与 320 像素浅主题无横向溢出。真实 Stripe / Resend 与完整 I11 外部验收继续保留在开发计划中。

供语言模型读取:llms.txt · llms-full.txt
采用 MIT 许可证。