feat: complete tenant site provisioning flow

This commit is contained in:
2026-08-01 17:27:51 +08:00
parent d58bcd97e9
commit ecf506df8a
39 changed files with 22760 additions and 271 deletions

View File

@@ -75,6 +75,11 @@ Redis key 使用环境前缀;配置解析会强制 `AbortOnConnectFail=false`
"GatewayBaseUrl": null,
"GatewayApiKey": null
},
"TenantProvisioning": {
"DefaultBaseOfferingCode": "starter",
"DefaultTrialDays": 14,
"OwnerActivationMinutes": 30
},
"SaasSubscriptions": {
"Enabled": true,
"BatchSize": 100,
@@ -95,6 +100,8 @@ Redis key 使用环境前缀;配置解析会强制 `AbortOnConnectFail=false`
域名只有在 `AllowedCnameTargets`、DNS JSON endpoint、Gateway URL 和 API key 配置完成后,才可能从 Pending/Failed 进入 Active。仅 DNS 验证成功不代表 TLS 已就绪。
`TenantProvisioning:DefaultBaseOfferingCode` 必须指向 Active 基础套餐中当前有效的最新 Published 版本。Production API 启动时会查询 PostgreSQL 验证该版本存在;开通事务也会再次校验,缺失时返回 `default_offering_unavailable`,不会留下半成品租户。平台运营流程为:创建租户并抄录 CNAME/TXT → 等待域名 Active → 领取一次性激活链接 → 通过既有安全渠道交付 Owner。链接关闭后无法再次查看需要补发时必须填写原因并撤销旧链接。
后台任务状态和 `RunAfter` 存在 PostgreSQL。Worker 使用 `FOR UPDATE SKIP LOCKED`、五分钟租约和有限重试处理即时、延时及失败待重试任务;周期循环使用 PostgreSQL advisory lock 防止多实例重复执行。当前六个循环分别处理域名、订阅生命周期、Feature 用量、通用任务、授权缓存失效和商业账务。商业账务会生成续费应收、提醒、外部催缴投递和已审批退款Webhook 必须使用 HTTPS、Host allowlist、签名和私网地址拒绝。`Worker:Enabled=false` 会关闭全部循环,通常只用于测试或维护。
API 和 Worker 必须使用同一 PostgreSQL 数据库与一致的对象存储配置。迁移必须在两者启动前由 `Tiku.DbMigrator` 单独执行。