Website has two owner-local executors: Analytics mart aggregation and Sitemap submission. JobHost adapts them to Quartz. Scheduled content publication is not one of them.
1. Job map
2. Analytics aggregation
Website:Analytics:Aggregation configures Enabled, CronExpression, TenantIds, and LookbackDays. Enabled with no tenants throws; lookback clamps to 1..400 days.
The executor enters System current-user scope per configured tenant and rebuilds day/week/month marts. New tenants are not discovered automatically; omission means missing materialization/fallback work.
Window replacement relies on UnitOfWork atomicity. Multi-job concurrency, lease, single execution, and concurrent-read consistency need Host/Quartz and dual-ORM evidence.
3. Sitemap submission
Configuration carries SitemapUrl, Google/Baidu switches, endpoints, and Google token. Application checks absolute URI only—not HTTP(S), expected host, or private network. Admin config is still an SSRF/misconfiguration boundary.
Adapter performs Google PUT Bearer, then Baidu POST. Google success plus Baidu failure fails the job; retry submits Google again. There is no per-provider checkpoint, idempotency, or outcome audit.
// ① Google succeeds without a durable provider checkpoint.if (request.GoogleEnabled) await SubmitGoogleAsync(client, request, cancellationToken);
// ② A later Baidu failure fails the whole executor.if (request.BaiduEnabled) await SubmitBaiduAsync(client, request, cancellationToken);
// ③ Quartz retry can submit Google again.return Result.Success();4. Publication consumers
API consumers evict output-cache tag; JobHost consumers trigger sitemap work. CAP groups need per-API-instance fanout for cache and business idempotency for jobs.
Test broker pause, duplicate, out-of-order publish/unpublish, restart, and stale-cache SLO. The event has no revision number, limiting out-of-order decisions.
5. Health model
WebsiteRuntimeProbe checks core stores; GeoIP checks missing/stale database; analytics DLQ reports current-instance Degraded. Green composition does not mean consent, features, automatic publishing, or durable DLQ exists.
Readiness should distinguish database, Redis, Data Protection key ring, GeoIP, queue/DLQ, CAP, and job config. Google/Baidu side effects are not high-frequency readiness probes.
6. Existing test assets
Source has Foundation, Growth, ReviewFix, and SubmitContact unit tests; API smoke; dual-ORM persistence; Redis+SQL growth; distributed rate limiting; broker fanout; Slug host E2E; architecture and CI-shard tests.
Those assets are meaningful, but do not prove missing consent, ownership, auto-publish, durable DLQ, lead management, feature enforcement, or notification idempotency.
7. Test layers
| Layer | Required evidence |
|---|---|
| Domain | State, limits, URL, PII, bucketing, statistics |
| Application | Trusted tenant, authorization, save/event/notification failure |
| Infrastructure | Dual ORM, Redis, locks, protection, queue/DLQ |
| Host | Routes, limits, cookie, feature, cache, CAP, Quartz |
| Security | XSS, cookie theft, SSRF, abuse, privacy races |
| Operations | Crash, restart, partial success, reconciliation, rollback, capacity |
8. Fault drills
Exercise Redis outage, slow DB/unique collision, queue full, sustained write failure, API kill -9, lost protection key, stale GeoIP, stalled CAP, duplicate Quartz, Google-success/Baidu-failure, and notification failure.
Record user effect, loss window, alert, recovery, replay/reconciliation, and owner. In-process DLQ loss is expected today and cannot be called recovery.
9. Observability
Existing meters cover accepted, overloaded, persist retry/persisted, deadlettered/replayed. Add queue depth/age, batch latency, estimated loss, mart lag, cache invalidation lag, overdue Scheduled, lead notification backlog, privacy workflow, and per-provider sitemap outcome.
Never label with VisitorId, SubjectId, URL, UTM, Lead PII, or raw exception message.
10. Commercial GA blockers
| Priority | Blocker |
|---|---|
| P0 | No consent/withdrawal/retention while auto-capture runs |
| P0 | Non-credential Visitor cookie authorizes anonymous privacy read/erase |
| P0 | Scheduled has no automatic publisher |
| P0 | Queue/DLQ are not crash-safe; erase can be undone by in-flight events |
| P0 | Contact lacks idempotency/outbox; notification failure duplicates leads |
| P1 | Five features unenforced; lead management undelivered |
| P1 | Global short-link ownership/domain safety/click degradation incomplete |
| P1 | Sitemap partial provider success lacks checkpoint/reconciliation |
11. GA evidence pack
Require route/permission/feature inventory, privacy impact assessment, consent/retention/DSR contracts, threat model, XSS corpus, capacity/loss SLO, dual ORM/Redis/CAP/Quartz reports, key-ring DR, fault drills, runbooks, dashboards, SBOM, and rollback.
Rate content, contact, analytics, experiments, and short links separately; one API smoke suite is not whole-module GA.
12. Current commands
# ① Run Website unit and architecture tests.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'# ② Run the independent Docker Website integration shard when infrastructure exists.dotnet test tests/BitzOrcas.Integration.Tests/BitzOrcas.Integration.Tests.csproj --no-restore \ --filter 'Category=Docker&FullyQualifiedName~BitzOrcas.Integration.Tests.Website.'13. Definition of done
Each capability is GA only when its P0/P1 implementation and independent tests land, runtime feature gates truly close the surface, privacy/reliability evidence is reviewed, and runbooks succeed in fault drills.
14. Release review record
Each release also records:
- one version across API Host, JobHost, and migration package;
- actual feature, permission, and public-route snapshot;
- PublicTenantId and aggregation tenant list;
- Channel capacity, batch, retry, and shutdown deadline;
- GeoIP database version and freshness;
- Data Protection key-ring recovery result;
- Quartz cron, timezone, misfire, and concurrency policy;
- CAP consumer groups and backlog;
- Google/Baidu credentials, endpoints, and network policy;
- known loss window and customer disclosure;
- rollback impact on cookies, tokens, marts, and content states;
- on-call owner and escalation path.