feat(gateway): 多租户增量2 —— 租户切换 + 每租户共享计费开关
用户可切活跃租户,消耗按"计费租户"扣(数据仍落活跃租户/工作区): - User.active_tenant_id(切换持久化)+ Tenant.shared_billing(每租户开关,默认关)。 - 中间件 ActiveTenantForUser:active_tenant_id 若有效(仍是成员)则用之,否则默认租户。 - 计费目标解析 ResolveBillingTenantID:本人是活跃租户 owner 或该租户 shared_billing 开 → 记活跃租户;否则记本人个人租户(各付各的)。SubmitTask 的硬拦截 + 用量都按它走。 - 接口:GET /me/tenants、POST /me/tenant(切换)、PUT /admin/tenants/:id/shared-billing; /tenants/current 改显"可花余额"(计费租户) + billing_shared 标记。 live 验证(demoB 是公司A 成员、个人租户=公司B):切到公司A 后—— shared OFF:任务落公司A 工作区、用量扣公司B(个人),公司A 不变; shared ON:用量扣公司A(共享),公司B 不变;/tenants/current 余额随之在 6.48↔15.92 切换。全过。 前端切换器 + admin 开关见后续。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,9 @@ func New(db *store.Postgres, cache *store.Redis, bus *nats.Bus, blobStore *blob.
|
||||
p.POST("/tasks", h.SubmitTask) // 解析 DSL 并 Publish 到 NATS(带已验证 uid)
|
||||
p.GET("/tasks/:id", h.TaskStatus) // 任务生命周期状态(UI 轮询 submitted/running/done/failed/timeout/waiting/rejected)
|
||||
p.POST("/tasks/:id/approve", middleware.Audit(db), h.ApproveTask) // HITL 人工审批决定(批准/拒绝,审计)
|
||||
p.GET("/tenants/current", h.TenantCurrent) // 当前租户上下文 + 角色(多租户)
|
||||
p.GET("/tenants/current", h.TenantCurrent) // 当前租户上下文 + 角色 + 可花余额(多租户)
|
||||
p.GET("/me/tenants", h.MyTenantsList) // 我所属租户(供切换)
|
||||
p.POST("/me/tenant", h.SwitchTenant) // 切换当前活跃租户
|
||||
p.GET("/me/usage", h.MyUsage) // 我的用量明细(余额 + 趋势 + 最近消耗)
|
||||
p.GET("/tasks/:id/eval", h.TaskEval) // 自动化评测结果(综合/质量/忠实度/分级)
|
||||
p.PUT("/memory", h.SetMemory) // 偏好记忆登记(→ mcp-go memory_upsert)
|
||||
@@ -105,6 +107,7 @@ func New(db *store.Postgres, cache *store.Redis, bus *nats.Bus, blobStore *blob.
|
||||
// 多租户成员管理(平台运维口径)
|
||||
admin.GET("/tenants", h.AdminTenants) // 租户目录(成员数+余额)
|
||||
admin.POST("/tenants", h.AdminCreateTenant) // 新建租户(可选指定 owner)
|
||||
admin.PUT("/tenants/:id/shared-billing", h.AdminSetSharedBilling) // 共享计费开关
|
||||
admin.GET("/tenants/:id/members", h.AdminMembers) // 成员列表
|
||||
admin.POST("/tenants/:id/members", h.AdminAddMember) // 按邮箱加成员
|
||||
admin.PUT("/tenants/:id/members/:uid", h.AdminSetMemberRole) // 改角色
|
||||
|
||||
Reference in New Issue
Block a user