- v0.25核心改进
信任升级:省钱数字加 95% 置信区间 + 创始会员 Beta 落地 + AI 成本守护
这一版几乎全部围绕同一件事 —— 让你能真正信任我们给你看的数字。省钱数字下面新增一行 95% 置信区间,把「看起来精确」换成「诚实精确」。创始会员 Beta 落地页上线,含 ROI 退款保证(最终条款律师审阅后生效)。AI 推荐卡两个灰按钮换成了清晰的「建议项」标签,不再像坏掉。后台加了结果缓存(同数据秒回、零 token)和慷慨的月度公平使用上限(只挡狂刷脚本,真实客户碰不到)。
- 「本月已为你省下 $X,XXX」大数字下面新增一行 95% 置信区间(例:$900 – $1,560)—— 用我们持久化的贝叶斯 ROAS 后验通过误差传播算出(净省钱里唯一不确定的项是反事实营收 = 反事实花费 × 预测 ROAS)。多个独立改动方差相加;新 lib/savings-tracker/interval.ts 含 10 个单元测试(σ 反推、方差相加 vs SE 相加、字符串/缺失字段降级)。把头条数字从「营销话术」升级成「带不确定性的工程事实」
- 小账户「建立基线中 · X / 5 次测量」指示器:本月只有 1-4 次 AI 改动(数据还不够稳)时显示,让你看到「还在攒、越来越稳」而不是光秃秃一个数。0 次仍走原有的引导卡(连接账户 + 让 AI 跑 7 天)
- /[lang]/beta 创始会员落地页上线(三语 en / zh-CN / es),首批 50 个名额,核心是 ROI 退款保证:年付一次性 —— 若我们 holdout 测得的省钱低于你已付订阅费,差额全退、封顶 100%。slogan「We prove your savings — or your subscription is free / 省多少看得见,省不回订阅费差额全退」最终条款律师审阅通过后落首页 + 工作台顶部
- AI 推荐卡的两个灰掉的「忽略 / 采纳」按钮换成清晰的「建议项 / Advisory」徽章,加一句一次性说明:「这些是建议项,请在你的广告平台手动执行;连接广告账户并审核通过后开放一键应用」。诚实又显得有意为之,不再像坏掉
- AI 建议结果缓存:同账户快照 + 同 provider 偏好在 12 小时内秒回缓存,零 LLM 调用、零 token。数据变了(新一天 / 连了新账户)或切换 provider,缓存键自动变化、重新生成。新表 ai_usage_events 一表两用(缓存源 + 月度公平使用计数器);DB 失败即放行(fail-open),数据库抖动绝不卡客户拿建议
- 慷慨的月度公平使用上限:免费/试用 200 次、专业版 600 次、商业版 3000 次/月 —— 全部远高于最重度真实用法(~150/月)。仅挡狂刷脚本,真实客户碰不到。触到时显示一句友好提示「数据每天才更新一次,发邮件到 [email protected] 给你提高上限」 —— 不是冷冰冰的报错,也绝不显示焦虑式计量条
- 后台审核工具去掉西班牙语(en + zh-CN 内部运营专用 —— 内部工具不需要三语)。顺手修了一个 bug:原本 /es/admin 下「最近登录时间」会 fallback 显示成中文(relativeTime 只支持 en/zh,西语 admin 落到中文不合理),现在统一为英文
- 测试 767 → 788(+21 新测试,含置信区间数学 + AI 成本护栏的 3 路径:缓存命中 / 超额 / 真实生成持久化)。lint 干净、build 全绿、生产 0 错误。版本 0.24.0 → 0.25.0
- v0.24核心平台
Shadow-mode 上线:优化器接入持久化 + 日定时跑 + 反事实回查
v0.22-0.23 把数学层证明可信了。v0.24 把它接到生产路径上 —— 当 Google Ads dev token 一到位,所有东西就直接活了。新增 lib/ads-fetcher 平台数据抽象(mock + 真实接口 stub),lib/budget-optimizer/persistence DB 层(recordRecommendation + recordOutcome + getOrAssignHoldout + 日聚合),/api/cron/run-optimizer 每日跑优化器写 budget_changes(shadow mode 不实际改预算),/api/cron/measure-outcomes 7 天后回查实际值算 netSavings 写 change_outcomes。Dashboard 第一屏的 SavingsHero 现在读真 DB —— 用户没建议时显示 empty state,有了之后显示真省钱数。整条数据流跑通:fetcher → optimizer → 落库 → 回查 → 仪表盘。
- lib/ads-fetcher 平台数据接入抽象:mockAdsFetcher(用 MOCK_ACCOUNTS + 确定性噪声)+ googleAdsFetcher/metaAdsFetcher/tiktokAdsFetcher(stub 抛错带迁移说明)+ getAdsFetcher 路由器认 USE_REAL_ADS_FETCHER 环境变量。13 路径测试覆盖(router 默认 / "1" 真切 / 防误开 / mock 确定性 / 顺序保证 / 错误账号 null / 三平台 stub 错误消息)
- lib/budget-optimizer/persistence: getOrAssignHoldout 先查再写 holdout_assignments(含 unique-violation race 兜底再读)+ recordRecommendation 写 budget_changes (numeric 用 .toFixed 保留精度) + recordOutcome 写 change_outcomes + listChangesAwaitingOutcome (left-join 找有 change 无 outcome 的) + listChangesForUser/aggregateUserSavings/dailySavingsForUser 给 dashboard 用。所有 DB 失败 try-catch + logger.error,不让 cron 因 DB 抖动崩
- /api/cron/run-optimizer:CRON_SECRET Bearer auth → 拉所有非 revoked / 非 token_expired ad_accounts → 每个 ad_account fetcher 拉 8 周历史 → 每个 campaign 分桶 holdout(control 直接 skip)→ recommend() → 落 budget_changes shadow mode(hold 和 insufficient_data 不污染表)+ Sentry/captureError on每 ad_account 级错误 + 结构化 logger.info 汇总
- /api/cron/measure-outcomes:找 ≥ N 天前但无 outcome 的 budget_changes → fetcher 拉该窗口实际 spend/revenue → computeOutcome 算反事实 netSavings → 写 change_outcomes。OUTCOME_WINDOW_DAYS env 可调(默认 7)+ MAX_CHANGES_PER_RUN=500 限单次耗时。Campaign 已删情况下记零 spend outcome 防永远重试
- Dashboard SavingsHero 接真 DB:loadSavingsForUser 并行查 month-to-date / trailing 7d / lifetime 聚合 + 30 天 daily series。零改动时 hero 自动显示 empty state(已 v0.22 内置),有 outcome 时显示真省钱数 + 真柱图(含负数日)。整条数据流闭环:cron → DB → dashboard
- 测试 644 → 657(+13 ads-fetcher 路径测试)。0 lint warning,build 全绿。版本 0.23.0 → 0.24.0
- 生产关键路径测试补满(+37 新测试):lib/budget-optimizer/persistence 16 路径覆盖 getOrAssignHoldout(已存在 / 新建 / control 路由 / DB 全死兜底)+ recordRecommendation 成功 + 失败 / listChangesForUser numeric→number 转换 + DB 死返 [] / recordOutcome 成功 + 失败 / listChangesAwaitingOutcome + aggregateUserSavings 累加 + dailySavingsForUser 按日分桶 + 升序。/api/cron/run-optimizer 11 路径覆盖 auth 三态 + 无账户 + null externalAccountId 跳过 + treatment 落库 + control 早 skip + hold/insufficient 不污染表 + per-account 错误隔离 + meta carrier。/api/cron/measure-outcomes 10 路径覆盖 auth + OUTCOME_WINDOW_DAYS env + 正常 outcome + null window 写零 + 孤儿 ad_account 跳过 + 单条 fetcher 错误隔离
- v3 change-point detection(修慢衰退最大数学缺口):posterior.detectDownwardShift 比较最近 3 个窗口 vs 更早窗口的 spend-weighted ROAS 比值,低于 0.85 阈值且总 conversions ≥ 30 时标 shifted。decision 检测到 shift + posterior.mean < target 时硬走 decrease_budget at -maxDeltaPercent(防"加预算追求最大营收"思路在 ROAS 已低于目标时反向决策)。Backtest slow-decline 方向命中率 **33% → 69%**(v0.23 主要缺口修了),代价是 seasonal 56% → 36%(正弦谷底误触 decrease,rebound 后看错方向;recentN=3 是平衡点,进一步用 v4 周期检测分辨"趋势 vs 周期")。12 路径新单测覆盖 detectDownwardShift;诚实写进 backtest-v0.24.md:净省 $174K → $146K (-16%) 是「不抓上行幸运」换「不踩下行雷」的交易
- v4 周期检测(修 v3 的季节性 collateral):posterior.detectPeriodicity 对去趋势后的 ROAS 序列计算 lag-4 Pearson autocorrelation(4 周月度周期,最常见的广告平台周期性)。≥ 0.5 阈值标 periodic。Decision 检测到 periodic → 抑制 change-point shift("recent decline" 实际是已知周期的谷底)。关键设计:先 detrend(最小二乘线性拟合后减去),否则缓慢单调下降会被误判为周期(两半都是下降趋势会正相关)。Backtest seasonal 36% → **47%**(+11pp),season 净省 $10K → **$19K**(+89%);slow-decline 69% 不退化(无周期性,新逻辑不影响)。10 路径新单测覆盖 detectPeriodicity 含正弦 / 噪声正弦 / 单调下降不误触 / 平直 / 白噪声 / 阈值 + minWindows。Backtest 报告 v0.24.md 更新到 v4 路径
- MCP server 兑现承诺:mcp-server/ 新子包,零运行时依赖(纯 Node 18+ ESM + fetch + stdin/stdout JSON-RPC 2.0 协议手写),让 Claude Desktop / Cursor 直接读 AdWhiz 状态。5 个 read-only 工具:list_ad_accounts / list_recommendations / get_savings_summary / get_recent_activity / get_quota,全部走 /api/v1 + Bearer auth。用户安装步骤:git clone + 把路径填到 claude_desktop_config.json + 设 ADWHIZ_API_KEY env。**故意不暴露 mutation 工具**(apply / pause)—— 等优化器出 shadow mode 再开。完整 README.md 含 Claude Desktop + Cursor + 其他 MCP 客户端三套安装指引 + 故障排查 + 安全模型说明。4 路径 stdio 协议 smoke test(spawn subprocess 跑真协议):initialize / tools/list / ping / unknown method
- 生产路径已就绪:等 Google Ads dev token / Meta App Review / TikTok Business API 中任一审批到位 → 实现对应 fetcher → 设 USE_REAL_ADS_FETCHER=1 → 配 EventBridge 调用两条 cron → savings hero 第一个真实「本月已为你省下 $XXX」数字出现
- v0.23核心体验
预测引擎 v2:时间权重 + 概率置信度 + 响应曲线
v0.22 回测暴露了三个真实问题:(1) 慢衰退场景方向命中率 33%(差于抛硬币)(2) 置信度本质上是二值的 (3) 校准系统性偏乐观。v0.23 三个全修了。新增 aggregateRecency 指数衰减把多 snapshot 合并成有效 snapshot(默认半衰期 ~2.3 windows),decision 重写为 P(new_revenue > current_revenue) 的概率,elasticity 从 Beta(2,5) × 2 采样(5-15% 概率 > 1 模拟饱和市场)。6 场景回测总省钱从 ~$80K 翻倍到 ~$174K,steady loser 从 -$2.7K 翻正成 +$208,校准在健康场景下完美命中(85% bucket → 85-87% 实际正向率)。
- posterior.ts: aggregateRecency(snapshots, decay) 把多 snapshot 用 exp(-decay × age) 权重合并成有效 snapshot。default decay=0.3,half-life ~2.3 windows。Beta α/β 接受小数(共轭先验数学不要求整数计数)。12 路径单测覆盖 fast path / decay=0 / 不同 decay 强度 / cold start / 零窗口
- decision.ts 重写:(1) 默认走 aggregateRecency 而不是只看最新 snapshot —— 直接修了慢衰退把老数据当真的问题 (2) confidence 从 1 - 2|δ| 改为 P(new_revenue > current_revenue) 用 paired 后验 + elasticity 采样 (3) 加 budget→ROAS 响应曲线:new_roas = roas × (current_budget / new_budget)^elasticity,elasticity 从 Beta(2,5)×2 采样 ([0,2] 支持,5-15% 概率 > 1 = 大笔预算反而亏钱的饱和市场)
- backtest 加 inclusive 顶桶 (≤ 1.0),确保 confidence=1.0 落到 [0.9, 1.0] 桶不被丢。version-suffix 输出路径 (--out=docs/backtest-vXX.md) 让历史对比可 diff
- 回测数据:6 场景 × 20 campaign × 9 周(180 决策 × 6 = 1080 总)。Steady winner +$56K (v0.22: +$27K), Regime change +$61K (+$29K), Slow decline +$20K (+$7.7K), Seasonal +$27K (+$12K), Sparse +$10K (+$5.5K), Steady loser **+$208 (flipped from -$2.7K)**。校准:winner/regime change 85% bucket → 85-87% 实际正向率(精准命中),volatile 场景(衰退 / 季节 / 稀疏)仍 Δ=-13 到 -21% 偏乐观,v3 加 regime-stability 因子修
- sampleBeta 从 posterior.ts export 出来给 decision.ts 共用(之前 private)。v1 stale 测试改成「无候选过置信度阈值 → hold」+ 加新断言 confidence ∈ [0,1]
- 诚实生产路线: v0.23 可以在任何 campaign 类型上跑 shadow mode(即使衰退场景净省 $20K,安全约束在兜底)。Conservative auto-apply 对稳定 / 增长 campaign 已可行;slow-decline auto-apply 等 v3 change-point detection 上线
- v0.22核心平台
产品核心:预测引擎 + 反事实省钱测量
砍掉外围的"添新功能"惯性,把工程精力收到一件事上:让 AI 计算"这条广告该加预算还是减"足够准、并能诚实地告诉用户「这个月省了 $X,XXX」。新加 lib/budget-optimizer(Bayesian 后验 + 决策策略 + 安全约束)+ lib/savings-tracker(反事实测量 + 15% holdout 对照组)。Dashboard 顶端换成超大数字 +「省钱明细」+ 负数日 honest 显示。LLM 只做翻译,不做预测。
- lib/budget-optimizer/posterior.ts —— Beta-binomial 共轭先验(默认 Jeffreys Beta(0.5,0.5))+ Marsaglia–Tsang Gamma 采样 + 确定性 mulberry32 PRNG(保证 audit 可回放)→ 输出 ROAS 后验均值 + 10/90 分位 + relativeWidth
- lib/budget-optimizer/decision.ts —— 5 层流水线:(1) 数据质量 gate (conv≥5 且 relativeWidth≤1) (2) pause gate (target × 0.5 阈值) (3) δ∈{-20%,-10%,0,+10%,+20%} candidate argmax 期望营收 (4) 线性度置信度 = 1-2|δ| 上限 70% (5) 1% 下限剪枝避免无意义抖动
- lib/savings-tracker/counterfactual.ts —— 用预测时刻的 ROAS 作为反事实基线(不是事后观测 ROAS,那是循环论证),输出 netSavings = profit_actual - profit_counterfactual。aggregateSavings + rollupDaily 给 dashboard chart 用
- lib/savings-tracker/holdout.ts —— SHA-256(salt,userId,campaignId) 确定性分桶到 control / treatment 组,默认 15% control。控制组永远不让 AI 动,作为 empirical baseline。Salt 升级可重排(新模型版本用)
- SavingsHero 组件 —— Dashboard 顶端超大数字「本月已为你省下 $X,XXX」+ 过去 7 天 + 累计 + 本月改动次数 + 30 天每日柱状图(负数日 rose 色诚实展示)。零 AI 改动时显示 empty state,不假装 $0
- 58 个新数学测试(17+17+13+11)覆盖 Bayesian 后验、决策策略、反事实测量、holdout 分桶。total 测试 550→608,0 lint warnings,build 全绿
- docs/budget-optimizer-design.md —— 完整设计文档:数学、安全约束、反事实测量、shadow→conservative→production validation plan。给未来工程师 + beta 用户 + 平台审批员同一份真相
- v0.21安全新功能体验
Email 验证流 + Dashboard demo 提示
注册路径补齐邮箱验证:建表、注册时发送、专门的验证落地页、/settings 顶部 banner 一键重发。Dashboard KPI 卡上方在零真账户时显示明显的「这是演示数据」banner,避免新用户把样例数字当成自己的真实业绩。
- email_verification_tokens 表(结构镜像 password_reset_tokens)+ 注册时自动发送验证邮件(24h 过期)
- /api/auth/email-verify/confirm 端点:rate-limited,幂等(已验证返回 alreadyVerified: true),TOCTOU-safe
- /[lang]/verify-email 落地页 + VerifyEmailRunner 在 mount 时 POST + 渲染结果(成功 / 已验证 / 过期 / 限流)
- /api/auth/email-verify/request resend 端点:per-user rate limit,已验证用户得 ok 但不再发邮件
- /settings 顶部 banner:emailVerified===null 时显示「请验证邮箱」+ 重发按钮(自隐藏)
- Dashboard 零真账户时显示 "These are demo numbers" amber banner + /connect CTA,避免误读样例数据
- /api/account/export GDPR 数据移出权端点:一次性下载完整 JSON(profile + subs + ad_accounts + api keys 元数据 + 近 90 天 audit_events),自动排除任何密钥 plaintext
- /api/v1/audit-events SDK 端点:API key 鉴权返回 caller 的 audit 历史,支持 ?since + ?limit (max 200)
- instrumentation.ts: SENTRY_DSN + @sentry/nextjs 同时存在时初始化并注入 globalThis.__sentry,否则静默 no-op
- /legal/privacy「Your Rights」改写:明确每条权利的 self-serve 入口(设置页 / /api/account/export),不再让用户被迫等客服
- Content-Security-Policy-Report-Only 头上线(包含 default-src self / frame-ancestors none / upgrade-insecure-requests 等),观察期收集报告后再切到强制模式
- /api/csp-report sink:兼容 legacy report-uri 和 modern Reporting-API 两种格式,违规写入 logger.warn,per-IP 速率限制 200/min
- /api/v1/usage 端点:SDK 不用 probe 就能拿到 tier + 限额 + 剩余 + reset 时间,与 X-RateLimit-* 头同源
- README 同步到当前状态:80+ 页、25+ API、11 表、135 测试、13 迁移;列出所有公开 API 端点 + Sentry / CSP 接入说明
- Stripe webhook 在 upsert 前对比已有行:plan 变更写 subscription_changed、status→canceled 写 subscription_canceled。Stripe 重试不会重复触发(idempotent)
- RecentActivity 渲染订阅事件并展示 from→to 转换;/api/auth/email-verify/request 6 路径测试覆盖(unauth / rate-limit / already-verified / unverified send / orphan)
- Auth.js signIn / signOut events 通过 next/headers 抓取 x-forwarded-for + UA,写入 audit_events 的 ip/ua 列;/settings#security 「Signed in · provider · IP X.X.X.X」一行视
- /api/v1/me 5 路径测试(unauth / orphaned key / success envelope / null last_login / count fallback)
- Token-refresh cron 在 connected → token_expired 跃迁时写 ad_account_token_expired 审计事件,用户在 /settings#security 看到「请重新授权 X 平台」
- UnverifiedEmailBanner 也在 /dashboard 顶部渲染,OAuth 用户因 emailVerified 已存在自动隐藏
- Vitest 套件扩到 140 个测试(/api/v1/me + /api/auth/email-verify/request)
- /api/v1/audit-events 加 ?kind= 过滤(逗号分隔,对未知 kind 返回 400 invalid_kind),方便 SIEM 只拉 sign_in / api_key_* 等
- /docs/security-whitepaper 从 keyPoints 大纲升级为完整 body 文章(加密 / 审计链路 / 自助权利 / CSP / 观测性 / AI 数据政策)
- /api/v1/me 加 email_verified boolean,SDK 可据此 gate 未验证用户的 UX
- /api/v1/api-keys 列出 caller 自己的全部 keys(含 lastUsedAt + active 布尔),hashedKey 永远不返回
- /admin "新用户" KPI 加上周对比 +N (+X%),运营一眼看出增长加速 / 减速
- CONTRIBUTING 加 audit-events 添加新事件清单、vi.hoisted 测试模式、Sentry 可选 wire-up 路径
- Vitest 套件扩到 149 个测试
- /api-reference 公开页同步到 13 个端点(加 /audit-events / /api-keys / /usage / /changelog)
- lib/api-auth.ts validateApiKey 加 7 个测试,封住 /api/v1 鉴权路径(缺 header / malformed / 未知 hash / 命中 / lastUsedAt 写入 / test vs live env)
- lib/api-response.ts 10 个测试覆盖 apiOk / apiError / preflightResponse / authError 全部分支
- Vitest 套件最终到 166 个测试,27 个文件
- observability.ts + refresh-tokens cron 清理 stale TODO 注释;cron catch 块加 logger.warn 结构化日志
- Settings server actions 12 个测试(updateProfile / updatePreferredLocale / updateAiProvider / updateEmailPreferences / dismissOnboarding 全路径)
- Vitest 套件扩到 178 个测试,28 个文件;README 顶部 stats 同步
- /api/contact 7 路径测试覆盖(含蜜罐丢弃 + DB error 500)
- /api/auth/register 8 路径测试(含双 insert 顺序、Accept-Language 选 locale、verify-token 失败仍返 201)
- Vitest 套件最终到 193 个测试,30 个文件
- settings actions 全 destructive 路径测试:changePassword (6) + deleteAccount (5) + disconnectAdAccount (3),含 bcrypt mock + audit event 断言
- Vitest 套件最终最终到 207 个测试
- 首页 + /vs/adwhiz 注入 schema.org JSON-LD(SoftwareApplication / Product + Offer 价格列表),让 Google 富片段在搜索结果展示
- .github/workflows/ci.yml 加 PR-level lint+test+build 验证(concurrency cancel-in-progress 避免 stale jobs),与 deploy.yml 解耦
- /api/cron/prune-tokens 周清理 password_reset_tokens (>7d) 和 email_verification_tokens (>30d) 旧行;带 5 路径测试
- infra/README cron 表 + schedule-expression 同步到新增的 2 个 prune cron
- /api/auth/email-verify/confirm 加 429 rate-limit 测试路径(断言 short-circuit:DB 不应被查)
- Vitest 套件扩到 213 个测试
- Vitest include 扩展到 .test.{ts,tsx};JsonLd 组件 4 测试覆盖 </script> 转义防御 + 嵌套对象
- /api/v1/openapi.json: OpenAPI 3.1 规格(5 个稳定端点 + 完整 schema),SDK 可 openapi-typescript / openapi-generator 直接生成
- lib/audit-events 导出 AUDIT_EVENT_KINDS + ALLOWED_KINDS 单一来源;API 路由验证、TS union、OpenAPI enum 三处共享
- CONTRIBUTING 加 "Adding a public API endpoint" 流程;README 提到 OpenAPI spec 入口;/api-reference 加 OpenAPI 按钮
- Vitest 套件扩到 223 个测试(OpenAPI 路由 6 路径覆盖)
- 新设备登录邮件提醒:UA-hash 指纹存到 audit_events.meta.device_fp;signIn event 检测到 30 天内无匹配指纹(且至少有过 1 次其他登录,避免新注册首登误报)就发邮件,per-user locale
- /api/auth/password-reset/{request,confirm} 路由测试共 14 路径覆盖(含「always 204」反枚举契约 + DB error 不泄露 + 双 update 成功路径)
- Vitest 套件最终到 237 个测试,35 个文件
- /about、/legal/privacy、/legal/terms、AI system prompt 把「Google Ads + Meta Ads」双平台文案补成三平台(含 TikTok)
- /api/oauth/google/start 路由 5 测试(CSRF state cookie + HttpOnly + SameSite=lax + 每请求新鲜随机 token)
- package.json 版本到 0.21.0
- /api/cron/trial-reminders 测试(7 路径含 plan 标签 + locale 映射 + 边缘日期 daysLeft 下限);/api/cron/monthly-digest 测试(6 路径含跨 ad_account 去重 + locale fallback + null email 跳过)
- Vitest 套件最终最终最终到 255 个测试,38 个文件;几乎全部活跃 cron 端点都有测试覆盖
- instrumentation.ts 用 runtime-computed module id 规避 bundler 静态解析,operator 安装 @sentry/nextjs 即生效
- Vitest 套件扩到 120 个测试(/api/v1/audit-events 6 路径 + /api/account/export 5 路径,验证 attachment header / ISO 序列化 / 不泄露 passwordHash 等密钥字段)
- /api/v1/changelog 加 ?limit=N (1..50) + ?since=YYYY-MM-DD:limit 取最新 N 条,since 取该日期之后的所有条目,组合即标准增量轮询;ETag 含 (lang, limit, since, content) 全量指纹防假 304;OpenAPI 同步并测试覆盖
- /api/v1/accounts 路由测试(6 路径:unauth 透传 / success envelope / spend_usd 双精度收敛 / environment 回声 / X-RateLimit-* 头注入 / OPTIONS 204 preflight)
- /api/v1/recommendations 路由测试(8 路径:unauth / 默认 status=pending / status=all 超集 / status=applied 严格过滤 / 未知 status 返回 0 行而非 400 / SDK 字段形状 / X-RateLimit 头 / OPTIONS)
- /api/v1/audit-log 标记 deprecated:RFC 8594 Deprecation: true + Sunset 头(2027-05-23)+ Link rel=successor-version 指向 /audit-events,非破坏式迁移信号;7 路径路由测试覆盖
- /api/v1/accounts/[id]/campaigns 路由测试(6 路径:unauth / 未知 id 404 + account_not_found code / valid id 全字段 envelope / spend_usd + cpa_usd 双精度收敛 / X-RateLimit 头 / OPTIONS)
- /api/v1/recommendations/[id]/apply + /dismiss 路由测试(11 路径):apply 端点 unauth / applied_at 时间戳收敛 / 头注入;dismiss 端点空 body / 文本 reason / >500 字截断 / 非字符串 reason 落 null / 畸形 JSON 容错 / OPTIONS
- /api/v1/changes/[id]/rollback 路由测试(5 路径:unauth / original_change_id 回声 + reverted_at 收敛 / rollback_audit_id 每次唯一 / X-RateLimit / OPTIONS)
- /api/v1/changelog 加 Last-Modified + If-Modified-Since 304:curl -z / wget --time-stamping 都能用日期协商缓存;同时发 ETag + IMS 时按 RFC 9110 §13.1 优先 ETag;OpenAPI 同步并 5 路径测试覆盖
- /changelog.rss 也加 Last-Modified header(锚定最新条目日期):Feedly / NewsBlur 等 RSS 聚合器用 IMS 节省带宽;force-static 不改,仅暴露 header
- /api-reference 加「增量轮询 /changelog」示例区块(4 个 curl snippet 覆盖 ETag / Last-Modified / ?since / ?limit),让 SDK 作者一眼看到推荐用法
- /api/oauth/meta/start + /api/oauth/tiktok/start 路由测试(各 5 路径,镜像 google/start 模式):unauth redirect / lang default / not_configured / state cookie 标志 / per-request fresh state
- /api/cron/refresh-tokens 路由测试(9 路径):CRON_SECRET 未配置 503 / 401 wrong bearer / 401 missing header / crypto 未配置 503 / 零候选 200 / 三平台 dispatch 全 refreshed / refresh 失败写 token_expired + audit / 未知 platform failed / GET 兼容
- /api/ai/recommend 路由测试(6 路径):无 session 401 / session 无 user.id 401 / providerOverride 从 users.aiProvider 透传 / users 行缺失走 env fallback / AI 抛 Error 500 + captureError 注入 route+user_id 上下文 / 非 Error throw 落 ai_failed
- /api/stripe/webhook 路由测试(7 路径):缺 signature 400 / 缺 STRIPE_WEBHOOK_SECRET 400 / constructEvent 抛错回声 SDK 消息 / unique 冲突返回 duplicate:true 且不上报 Sentry / 非去重 DB 错 500 + captureError(stage=dedup_insert) / handler 抛错回滚 dedup 行 + 500 + captureError(stage=handler) / happy path 200 received
- /api/oauth/google/callback 路由测试(11 路径):unauth / state 不匹配(含无 cookie 子分支)+ cookie 烧毁 / Google 用户拒绝错误回声 / 缺 code / not_configured / crypto 未配置 / token_exchange 失败 + captureError 上下文 / no_refresh_token(无新 DB 插入)/ persist 失败时不发 audit / happy path 重定向 + audit + 清 cookie
- /api/oauth/meta/callback 路由测试(7 路径):unauth / state mismatch + cookie 烧毁 / Meta 用户拒绝回声 / short-token 交换失败 / long-lived 交换失败(两步流第二步)/ 长寿令牌同时写入 access + refresh 列(Meta 无独立 refresh)/ persist 失败时不发 audit
- /api/oauth/tiktok/callback 路由测试(8 路径):unauth / state mismatch + cookie 烧毁 / `code` 兼容 fallback(TikTok 用 `auth_code`)/ exchange 失败 / N 个 advertiser 一次插 N 行 + N 个 audit / 空 advertiser_ids 插 null externalAccountId / access + refresh 分开加密(TikTok 两个都轮换)/ persist 失败时不发 audit
- /api/v1/recommendations/generate 路由测试(7 路径):unauth 透传 / body echo + SDK envelope / 推荐字段形状 / job_id 唯一性(5 次至少 2 个不同)/ 畸形 JSON echo={} / X-RateLimit-Tier 头 / OPTIONS preflight
- lib/email 单元测试(10 路径):sendEmail 4 路径(no_api_key skip / Resend 成功 / Resend 拒绝不上报 Sentry / 抛错 captureError 含 module+subject)+ sendContactNotification 路由到 SUPPORT_INBOX + null message placeholder / sendPasswordReset URL 编码 + zh-CN 翻译 + lang 路径 / sendNewDeviceAlert UA 80 字截断 + null IP 用 — placeholder
- OpenAPI info.version 1.0.0 → 1.1.0:从 1.0 起累积了 /changelog ?limit + ?since + Last-Modified + If-Modified-Since 头、/audit-log RFC 8594 Deprecation 头,全为 additive 变更,不破坏已有 SDK
- /vs/adwhiz「8 个核心端点」过期文案改成 13(+ OpenAPI 3.1 + ETag/304 增量轮询);/api-reference 的 /audit-log 加 Deprecated + sunset 2027-05-23 + 指向 /audit-events 的迁移说明
- src/proxy.ts (Next.js 16 middleware) 单元测试(14 路径):i18n redirect 6 路径(默认 / zh / en / 保留路径段 / 已有 locale 不重定向 / unknown locale 走默认)+ /api 不重定向 + request-id 上游头优先级(x-request-id → x-amzn-trace-id ALB → cf-ray Cloudflare → 新 UUID v4 fallback)+ matcher 排除 _next/static 等热路径
- lib/mock-ads-data 单元测试(8 路径):MOCK_ACCOUNTS fixture 完整性(三平台都有 / 账户 id 唯一 / 每账户内 campaign id 唯一 / metric 值非负且 conversions ≤ clicks)+ summarizeAccount 累加 + 只统计 active + 空 campaigns 全零 + 不预先 round(小数累加交给路由层 round2)
- /changelog 加「自上次访问以来新增 N 条」客户端胶囊:localStorage 记 dxk_changelog_last_visit,回访时算新条目数显示可关闭 pill,关闭时再 stamp 今天。首次访问静默种子(不闪 banner)。pure helper countNewSince 提取出来用 7 路径单元测试覆盖(lastVisit=今天 / N=2 / 全部新 / 未来日期 / 严格 > 边界 / 空数组 / 跨年跨月词典序)
- lib/docs-articles + lib/blog-posts 单元测试(18 路径):ARTICLES/POSTS fixture 完整性(slug 唯一 / 已知 CategoryKey / 不孤儿 / body 双语完整 / publishedAt ISO 形式 / dateZh+dateEn presentation 字符串)+ articleHref redirect 走 absolute / 默认走 /docs/[slug] / 跨语言路径 + relatedArticles/Posts 排除自身 + limit
- fingerprintUA 从 auth.ts 提取到 lib/ua-fingerprint,配 8 路径单元测试(null / undefined / 空字符串都返 null,UA 输出 16 字符小写 hex,同 UA 稳定,Chrome 120 vs 121 单字符差异也能区分,500 字 UA 不截断)。新设备登录提醒不变;refactor 是为了让指纹算法可独立测试 + 未来其他模块复用
- 安全头加 Cross-Origin-Opener-Policy: same-origin-allow-popups(防 tabnabbing 同时保留 OAuth 弹窗)+ Cross-Origin-Resource-Policy: same-site(允许 app.7275.com ↔ 7275.com 同一注册域,阻挡外站直接嵌资源)。低风险现代默认,不破现有 OAuth / Stripe 流程
- lib/audit-events 补 AUDIT_EVENT_KINDS taxonomy 4 路径测试:tuple 形式不变 / 10 个 slug 都在 / 强制 snake_case 命名(重命名会破坏历史审计行)/ ALLOWED_KINDS Set 严格拒空串大写错拼。审计枚举是唯一真理源,被路由 + OpenAPI + UI 三处依赖
- RecentActivity helper 提取 + 14 路径单元测试:eventLabel 覆盖 10 个 slug + 未知 slug 兜底;summaryLine 覆盖 sign_in/out 三态(provider+IP / IP-only / 双 null em-dash / 非字符串 provider 容错)+ api_key name·env 拼接 + ad_account 去 _ads 后缀 + subscription_changed 两形(plan_changed / created)+ canceled / 通用 meta-null IP-fallback / 双 null em-dash
- CrossPlatformPanel aggregatePlatform + 平台 helper 提取 export + 11 路径数学单测:求和(spend/conv/clicks/imp)+ 关键 ROAS 用 spend-weighted 而非算术平均(防小预算高 ROAS 偏倚)+ spend=0 时 ROAS 为 0 不 NaN + conv=0 时 CPA 为 0 不 Infinity + 只算 active campaigns + 空数组安全 + platformLabel/Letter/Accent 三平台映射 + Tailwind from-/to- 类字符串完整
- AuditLogTable filterEntries + Filter type export + 8 路径单元测试:all 全返回 / ai 只返 AI actor / user 排除 system actor / 三种 status filter / 顺序稳定 .filter() / 空源数组任何 filter 都返 []
- lib/ai/schema 10 路径完整性测试:RECOMMENDATION_TYPES 7 个 verb 稳定顺序 + snake_case + 唯一 / JSON schema top-level required (summary,recommendations) / recommendations 1..8 cap(防 AI 失控)/ enum 与 tuple 严格同步(drift 会让 AI completions 被丢)/ 7 个 per-rec 必填字段 / confidence low/medium/high 闭合枚举 / target 只 require accountId / 每层 additionalProperties:false(防幻觉字段)
- lib/ai/index activeProvider 提取 export + 6 路径优先级单测:override > AI_PROVIDER env > hardcoded "anthropic" 三层 / null+undefined+空串都透传 env / 大小写 + 前后空白规范化(" OpenAI " → openai)/ 未知 override(cohere)+ 未知 env(palm)双层兜底
- lib/ai/prompt 7 路径单测:SYSTEM_PROMPT 不含 ${} 模板字符串和 ISO 日期(保护 Anthropic 提示缓存命中)+ 三平台名(Google/Meta/TikTok)都出现 + 强制 tool/JSON 输出指令;buildUserPrompt 嵌 ```json 围栏可 JSON.parse round-trip / 多账户保序 / 空数组安全 / 末尾 imperative 推动模型产出
- lib/ai/anthropic + lib/ai/openai 适配器各 5 路径测试(共 11):API key 未配置清晰抛错 / tool_use 或 json_schema 正常解析 + usage 透传 / 缺 tool block 或 null content 抛错(防腐败空推荐落库)/ 错名 tool 不混用 / SDK 客户端缓存(多次请求只 new 一次)/ openai 还测了 JSON.parse 失败传播(防 strict mode 默认放松)
- /settings/api-keys actions 14 路径测试:createApiKey 覆盖 unauth / 空名 / 纯空白名 / 81 字符过长 / live + test 环境前缀 / 缺失或非法 environment 默认 live / 成功路径 41 字 plaintext + prefix 13 字 + 写 api_key_created audit / DB 抛错返 db_error 且不写 audit(防鬼记录)/ 每次调用 plaintext 都新鲜;revokeApiKey 覆盖 unauth / 缺 id / 成功撤销写 api_key_revoked audit / 已撤销不重复 audit
- OpenAPI spec 加 5 个语义 tag 分组(Identity / Quota / Activity / Keys / Public),Swagger UI / ReDoc / Postman 自动折叠展示;每个 path 都打上 tag 不留 orphan;纯 additive 不破现有 SDK;2 路径新测断言 tags 完整 + 描述 + 全 path 都被覆盖
- lib/google-oauth exchangeCode + refreshAccessToken HTTP 8 路径测试:200 token 解析(access_token / refresh_token / expires_in)+ form-urlencoded body 含全 5 个 Google 必填字段 / 4xx 抛错带 status + body 截断到 240 字符 / 5xx 同样抛错 / 网络错误不包装直接传播 / refresh 流 grant_type=refresh_token(区分 authorization_code 流,且不携带 redirect_uri)/ refresh 401 expired token 清晰抛错
- lib/meta-oauth + lib/tiktok-oauth HTTP 15 路径测试:Meta short → long-lived 两步流均用 GET + query-string(非 POST + body)、长寿令牌交换用 grant_type=fb_exchange_token 且不带 code、4xx 抛错带 status;TikTok 用 POST JSON 信封(字段 auth_code 而非 code,HTTP 200 + 业务 code 非 0 抛错)、refresh 端点与 access_token 端点不同、双令牌(access + refresh)刷新时一起轮换(test 钉住 foot-gun)
- v0.20安全平台新功能
审计与开放接口批次:audit_events + 安全头 + 公开 API + 反垃圾
建立完整的安全事件审计链路(登录、密码修改、API key、OAuth 连接),用户在 /settings 看自己的最近活动,运营在 /admin 看全站。补齐基础安全 HTTP 头、Contact 表单蜜罐反垃圾、公开 /api/v1/changelog JSON 端点。
- audit_events 表(kind / userId / ip / ua / JSONB meta),6 个事件类型写入
- /settings Security 区显示用户最近 10 条事件;/admin 加全站最近 12 条面板
- /api/cron/prune-audit-events 每周清理 180 天前的行(可通过 AUDIT_RETENTION_DAYS 覆盖)
- 基础安全 HTTP 头:X-Frame-Options DENY、X-Content-Type-Options nosniff、Referrer-Policy、Permissions-Policy
- Contact 表单加蜜罐字段,机器人填写后静默丢弃(不写库不发邮件),用户看到正常成功响应
- /api/v1/changelog JSON 端点(公开、带 lang 切换、CDN 友好缓存),与 /changelog.rss 同源数据
- API key lastUsedAt 在 /settings/api-keys 用相对时间显示,且写入由认证流自动维护
- Auth.js signOut event 也写 audit_events,关闭登录-登出生命周期审计闭环
- Sentry shim: lib/observability 在 SENTRY_DSN + globalThis.__sentry 存在时转发,无强依赖
- relativeTime 升级到 src/lib/relative-time.ts(5 处共用),覆盖年份单位 + 单元测试
- Footer copyright 年份动态化({year} 占位 + new Date().getUTCFullYear());package.json 版本对齐 0.20.0
- /audit-log 顶部加澄清注脚,区分「AI 改 campaign 历史」和「账号安全事件」(指向 /settings#security)
- /api/v1/me 补 last_login_at + connected_accounts_count,方便 SDK 消费者展示账号状态
- /api/v1/changelog 加 ETag + If-None-Match 304,长轮询消费者不再重复下载相同内容
- audit_events 加 (userId, createdAt DESC) 复合索引:/settings 渲染从全表扫降到索引扫
- /admin Recent users 表加 Plan 列(含 free 灰、professional indigo、business violet chip)
- docs/observability.md 写了完整的 Sentry 接入指南(instrumentation.ts 模板 + 为什么不走 withSentryConfig)
- Vitest 套件扩到 103 个测试(ETag + 304、Sentry shim 4 分支、prune-audit-events cron 4 路径)
- v0.19体验平台
用户偏好持久化批次:邮件 / 入门 / 登录历史 / 上次事件
把 dashboard / settings 上原来只活在 localStorage 的状态全部下沉到数据库,跨设备一致;同时给 admin 加了 MRR 估算 KPI 和「最近登录」列,状态页用真实的 incidents 数据模块替换了硬编码。
- users.emailWeeklyDigest / emailRecAlerts 两列 + EmailPreferences 组件;monthly-digest cron 在查询层过滤掉退订用户
- 入门 checklist 的「已 dismissed」状态写入 users.onboardingDismissedAt,跨设备一致;prefilledDone 用真实 ad_accounts / api_keys 行数判断
- Auth.js signIn event 写入 users.lastLoginAt;/settings 显示「上次登录于 X 天前」,/admin recent-users 加「最近登录」列
- /settings profile 区块底部显示「注册于 YYYY-MM-DD (X 个月前)」
- /status 页 incidents 数据移到 src/data/incidents.ts 模块;header 增加「上次事件:X 天前」徽章
- /admin KPI 加 MRR 估算(活跃订阅 × plan 月费,年付按 80% 计入月等效)
- Changelog 数据移到 src/data/changelog.ts,新增 /changelog.rss 公开订阅源
- Vitest 套件扩到 82 个测试(incidents 数据助手 + mrrContribution + RSS 路由)
- v0.18新功能安全平台
生产就绪批次:三平台 OAuth、忘记密码、Stripe 幂等、可观测性
一次性把生产上线前的关键环节全部落地:Google / Meta / TikTok OAuth 完整闭环(连接 → 刷新 → 断开)、忘记密码流程、Stripe webhook 幂等去重、AES-256-GCM token 加密、结构化日志 + 错误捕获 hook、CI 测试基线(63 个单元测试)、运营后台连接面板。
- /connect/google-ads + meta-ads + tiktok-ads 三个真 OAuth 流,token 在数据库里 AES-256-GCM 加密存储
- EventBridge cron 端点:每 30 分钟刷新即将过期的 token,每天发送 T-3 试用提醒,每月发性能摘要
- Stripe webhook 用 stripe_events 表幂等去重;新增处理 invoice.payment_failed / trial_will_end / payment_succeeded
- 忘记密码端到端流程:邮件 token + 15 分钟过期 + 速率限制 + 不泄露账号存在性
- observability:lib/logger(结构化 JSON)+ captureError() 错误捕获 hook + X-Request-Id 关联头
- Vitest 63 个单元测试覆盖 crypto、rate-limit、OAuth、API key、admin 允许列表、stripe lib、health 端点
- /settings 加「已连接账户」+ 一键断连;/admin 加「最近 OAuth 连接」+「过期 token」KPI 警示
- users.preferredLocale 列:cron 邮件按用户语言发送,不再硬编码 zh-CN
- v0.16新功能体验
明暗主题 + 「DEXUN AdWhiz vs AdWhiz.ai」详细对比页
全站新增明/暗主题切换,跟随系统或手动选择;同时上线竞品对比页,逐项说明 DEXUN AdWhiz 在三平台支持、MCP、REST API、年付折扣、联盟佣金上的差异。
- 所有页面(首页、文档、博客、dashboard、法律页等)支持明/暗双主题,避免深夜调账户刺眼
- Nav 右侧加日月切换按钮,初次访问默认跟随系统设置
- 新页面 /vs/adwhiz:12 行功能逐项打勾对比 + 4 个深度专题 + 3 档价格对比
- v0.15新功能
Pricing 年付 / 月付切换 + 20% 年付折扣
Pricing 上加月付 / 年付分段切换;年付一次性付 12 个月、立省 20%;Stripe 后端按 STRIPE_PRICE_*_YEARLY 价格 ID 自动路由。
- 专业版年付 $63.20/月(原 $79)· 商务版年付 $223.20/月(原 $279)· 企业版年付 $639.20/月(原 $799)
- 「Save 20%」徽章用 indigo→violet 渐变,与底部 affiliate 徽章保持视觉一致
- v0.14新功能体验
首页信任区块 + Pricing 三档监控频率描述
首页 Features 与 Pricing 之间新增信任区块,只摆可核验的事实(对照组验证省钱、ROI 退款保证、运营主体 DEXUN INC 公开可查);Pricing 三档功能描述加上分级监控频率:每日 / 每 4 小时 / 每小时。
- 信任区块:对照组实测省钱 · ROI 退款保证 · 美国 DEXUN INC 运营(无编造客户 / 数字 / 评价)
- Pricing:专业版每日审计 (20 条/天) · 商务版每 4 小时 (100 条/天) · 企业版每小时 (高配额)
- v0.13平台新功能
TikTok Ads 接入 —— 现在是三平台
TikTok Ads 作为第三个广告平台正式上线。Mock 数据、i18n 文案、Pricing 文案、FAQ、Hero bento 全部同步更新;MCP server 暴露 TikTok-specific 工具(创作者授权、Spark Code 等)。
- Dashboard:Google / Meta / TikTok 账户卡片并排展示,KPI 自动聚合
- AI 推荐支持跨平台预算迁移建议(如「Meta lookalike 应转 TikTok Spark」)
- MCP 工具集新增 tiktok.list_spark_ads / tiktok.creator_authorize / 等
- v0.12新功能
联盟计划上线(25% → 75% 终身循环佣金)
/affiliates 联盟计划页正式上线,四级佣金(25/35/55/75%),Cookie 60 天,终身循环佣金(不限首单)。Footer Resources 区加联盟徽章。
- 入门 25% / 白银 35% / 黄金 55% / 钻石 75%,按活跃推荐数自动晋级
- Net-30 付款,PayPal / Stripe 转账二选一,$50 起付
- v0.11新功能体验
Docs / Blog / API Reference / MCP Guide 四个资源页全部上线
/docs 和 /blog 上线动态路由 [slug]:7 篇完整文档 + 21 篇结构化预览 + 6 篇博客;/api-reference 列出 8 个 REST 端点与错误码;/mcp-guide 详解 Claude / Cursor 接入。
- Markdown-lite 渲染器(支持 **bold** 和 [text](url)),统一 Docs/Blog 两端样式
- Docs 顶部 popular 短链;Blog featured post 卡片 + 主题标签云
- v0.10体验新功能
Hero 重设计为左文右图 bento + Apple 风格切换控件
首页 Hero 改为左文右图 bento 布局,右侧展示 Google / Meta / TikTok 三平台缩略卡片;Nav 的切换控件从单按钮升级为 Apple 风分段式。
- 三平台缩略卡片随机展示真实账户名 + 状态 + 7 天 ROAS
- 主 CTA 从「Get started」改为聚焦 7 天免费试用的文案
- v0.9新功能体验
About / Contact / Coming-soon 三个支撑页面 + 联系表单 API
/about(含母公司、注册地、商业信息)、/contact(含表单 + DB 存储 + 邮件通知)、/coming-soon(带 ?topic= 参数的通用占位页)全部上线。Footer 所有链接接通。
- contact_submissions 表 + /api/contact 后端 + Zod 校验
- About 公开法人实体 DEXUN INC、注册地华盛顿州西雅图、母公司 DEAO GROUP LIMITED
- v0.8新功能安全
4 个法律页面上线(隐私 / 服务条款 / 退款 / Cookie)
隐私政策、服务条款、退款政策、Cookie 政策四个法律页面正式上线。适用法律改为美国华盛顿州 + AAA 仲裁 + King County。所有页面联系邮箱统一为 [email protected]。
- 统一 LegalLayout 模板,左侧 sticky 目录,右侧正文,明暗主题双适配
- v0.7新功能平台
Stripe 订阅 + Customer Portal + Webhook 完整集成
/[lang]/checkout 服务端跳转页接入 Stripe Checkout;/api/stripe/webhook 处理 customer.subscription.* 事件;Dashboard 显示订阅状态 + Customer Portal 入口。
- subscriptions 表 + users.stripeCustomerId 字段;状态映射 active / trialing / past_due 等
- 7 天免费试用,试用期内不扣费;试用结束自动转月费
- v0.6新功能安全
AI 推荐层上线(Anthropic + OpenAI 双供应商)
AI 抽象层支持 Anthropic Claude 与 OpenAI 双供应商运行时切换(AI_PROVIDER env);结构化输出 schema 验证;Dashboard 显示 mock 账户 + 真实 AI 推荐。
- /api/ai/recommend 路由:输入账户快照,输出 3-5 条结构化推荐(type / target / reason / expectedImpact)
- v0.5新功能安全
Auth.js v5 集成(Credentials + Google + GitHub)
Drizzle adapter 接入 Auth.js v5 beta;支持邮箱 / Google / GitHub 登录;JWT session;注册接口含 bcrypt 哈希 + Zod 校验。
- Dashboard 受保护路由,未登录自动跳 /login
- v0.1首次发布
DEXUN AdWhiz 公开预览版
Next.js 16 + Tailwind v4 + Drizzle + Supabase Postgres 全栈基础设施搭建完成。中英双语首页、Pricing、FAQ、Footer 上线。
- 产品由 DEXUN INC(美国华盛顿州西雅图)运营,母公司 DEAO GROUP LIMITED