Website 有两个 owner-local Executor:Analytics Mart 聚合与 Sitemap 提交。JobHost 通过 Quartz 适配执行;内容 Scheduled 自动发布不是其中之一。
1. 后台任务地图
2. Analytics 聚合
配置节 Website:Analytics:Aggregation:Enabled、CronExpression、TenantIds、LookbackDays。启用但 TenantIds 为空会抛启动/执行错误;Lookback clamp 1..400 天。
Executor 为每个配置租户建立 System CurrentUser scope,重建 [now-lookback,now) 的日/周/月 Mart。新租户不会自动发现,配置遗漏会长期回退事实扫描或缺少投影。
重建删除窗口 Mart 再插入 replacement,依赖 UnitOfWork 原子性。多 Job 并发、租约、跨节点 single execution 和查询中的读一致性要由 Host/Quartz 测试证明。
3. Sitemap 提交
配置包含 SitemapUrl、Google/Baidu 开关、Endpoint 与 Google access token。Application 只验证 absolute URI,没有限制 HTTP(S)、预期 host 或私网;它们虽是管理员配置,仍是 SSRF/误配置边界。
Adapter 先 Google PUT Bearer,再 Baidu POST sitemap URL。Google 成功、Baidu 失败时整个 Job 失败,重试会再次提交 Google;没有 per-provider checkpoint、idempotency 或结果审计。
// ① Google 已启用时先提交;成功没有持久 checkpoint。if (request.GoogleEnabled) await SubmitGoogleAsync(client, request, cancellationToken);
// ② Baidu 随后失败会让整个 Executor 失败。if (request.BaiduEnabled) await SubmitBaiduAsync(client, request, cancellationToken);
// ③ Quartz 重试可能重复 Google;GA 需要按 Provider 记录结果。return Result.Success();4. Content Publication Consumer
发布/下线事实被 API consumer 用于 output-cache 失效,JobHost consumer 用于触发 Sitemap 提交/调度。CAP 消费组需按 API 实例隔离缓存 fanout;Job consumer 则应保持业务幂等。
必须测试 broker 暂停、重复事件、乱序 publish/unpublish、consumer 重启和缓存陈旧 SLA。事件只有 ContentId/Slug/IsPublished/OccurredAt,没有版本序号,乱序判断能力有限。
5. 健康检查
WebsiteRuntimeProbe 检查核心 Store;GeoIP 有数据库存在/陈旧健康;分析 DLQ 有当前实例 Degraded 健康。组合成功不代表 Consent、Feature、scheduled publish 或持久 DLQ 已完成。
Readiness 需区分数据库/Redis/DataProtection Key Ring/GeoIP/队列/DLQ/CAP/Job 配置。外部 Google/Baidu 不应以高频有副作用请求做 readiness。
6. 当前测试资产
源码已有 Foundation、Growth、ReviewFix、SubmitContact 单元测试;Website API smoke;双 ORM persistence;Redis+SQL growth;分布式限流;publication broker fanout;Slug Host E2E;架构与 CI shard 测试。
这比 baseline 文档表达的成熟,但测试存在不等于每个产品声明成立。缺口仍包括 Consent、匿名 ownership、自动发布、持久 DLQ、Lead 管理、Feature 执行与通知幂等。
7. 建议测试分层
| 层 | 核心证据 |
|---|---|
| Domain | 状态机、长度、URL、PII、分桶与统计 |
| Application | 可信租户、授权、保存/事件/通知失败 |
| Infrastructure | 双 ORM、Redis、锁、Data Protection、队列/DLQ |
| Host | 路由、限流、Cookie、Feature、缓存、CAP、Quartz |
| Security | XSS、Cookie theft、SSRF、滥用、隐私竞态 |
| Operations | crash、重启、部分成功、对账、回滚与容量 |
8. 故障演练
演练 Redis 不可用、数据库慢/唯一冲突、队列满、写入连续失败、API kill -9、Data Protection key 丢失、GeoIP 陈旧、CAP 停滞、Quartz 重复执行、Google 成功+Baidu 失败和通知失败。
每项记录用户表现、数据损失窗口、告警、恢复、重放/对账和责任人。进程内 DLQ 的预期是丢失,不能把它当恢复机制。
9. 可观测性
现有 Meter 覆盖 accepted、overloaded、persist retry/persisted、deadlettered/replayed。还需队列深度/年龄、批耗时、丢弃估算、Mart lag、缓存失效 lag、Scheduled overdue、Lead notification backlog、privacy workflow 和 per-provider Sitemap 结果。
标签禁止 VisitorId、SubjectId、URL、UTM、Lead PII 或异常原文。错误详情只能进入受限日志。
10. 商业 GA 阻断
| 优先级 | 阻断 |
|---|---|
| P0 | Consent/撤回/保留不存在,仍自动采集 |
| P0 | Visitor Cookie 非凭据却用于匿名隐私数据访问/擦除 |
| P0 | Scheduled 无自动发布执行器 |
| P0 | 分析队列/DLQ 不跨崩溃,擦除可能被在途事件复活 |
| P0 | Contact 无幂等/outbox,通知失败可重复 Lead |
| P1 | 五个 Feature 未执行;Lead 管理未交付 |
| P1 | 短链全局 owner/域安全与点击降级未闭环 |
| P1 | Sitemap provider 部分成功无 checkpoint/对账 |
11. GA 证据包
需要路由/权限/Feature 清单、隐私影响评估、Consent/retention/DSR 合同、威胁模型、XSS corpus、容量与丢失 SLO、双 ORM/Redis/CAP/Quartz 报告、Key Ring 灾备、故障演练、Runbook、告警面板、SBOM 和回滚。
Website 子能力应分别评级:内容、联系、Analytics、Experiments、ShortLinks。不能因 API smoke 通过就整体 GA。
12. 当前验证命令
# ① 运行 Website 单元与架构测试。dotnet test tests/BitzOrcas.Unit.Tests/BitzOrcas.Unit.Tests.csproj --no-restore \ --filter 'FullyQualifiedName~Website'dotnet test tests/BitzOrcas.Architecture.Tests/BitzOrcas.Architecture.Tests.csproj --no-restore \ --filter 'FullyQualifiedName~Website'
# ② Docker 环境运行独立 Website integration shard。dotnet test tests/BitzOrcas.Integration.Tests/BitzOrcas.Integration.Tests.csproj --no-restore \ --filter 'Category=Docker&FullyQualifiedName~BitzOrcas.Integration.Tests.Website.'13. 完成定义
只有当前 P0/P1 对应实现和独立测试落地,运行时 Feature 真正封锁表面,隐私与可靠性证据经评审,Runbook 可在故障演练中执行,才可把相应子能力标为 GA。
14. 发布评审记录
每次发布还要记录:
- API Host、JobHost 与迁移包的同一版本;
- Feature/权限/公开路由的实际快照;
- PublicTenantId 与租户聚合名单;
- Channel 容量、批量、重试和停机时限;
- GeoIP 数据库版本与更新时间;
- Data Protection Key Ring 恢复验证;
- Quartz Cron、时区、misfire 与并发策略;
- CAP consumer group 和 backlog;
- Google/Baidu 凭据、端点与网络策略;
- 已知数据损失窗口和客户说明;
- 回滚是否会破坏 Cookie、token、Mart 或内容状态;
- 当班负责人和升级路径。