feat(gateway): 多租户地基·增量1 —— 租户身份/成员/上下文(T4.A/SaaS P1)
按 SAAS_DESIGN.md P1 第一刀(真·多租户 + 桌面端为主):先立租户身份,不动查询。 - store.Tenant / TenantMember 表 + AutoMigrate - store: CreateTenant / AddMember(幂等) / DefaultTenantForUser / EnsureDefaultTenant(幂等) / BackfillDefaultTenants / GetTenant / MemberRole - 注册即建单人默认租户(owner);启动回填给存量用户补建(幂等) - middleware.TenantContext(挂 Auth 后)解析当前租户→注入 tenant_id;handler.tenantID(c) 助手 - GET /api/v1/tenants/current 验证端点(租户上下文 + 角色) - live:存量用户(回填 7 租户)/tenants/current 返回默认租户+owner;新注册自动建租户 下一步(增量2):核心表加 tenant_id + 统一 gorm scope 强制隔离 + 存量行回填 + 重写查询。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/sundynix/sundynix-gateway/internal/store"
|
||||
)
|
||||
|
||||
// CtxTenantID 是鉴权后写入 gin.Context 的当前租户 ID 键。
|
||||
const CtxTenantID = "tenant_id"
|
||||
|
||||
// TenantContext 解析当前用户的默认租户并注入 tenant_id(多租户作用域的事实源)。
|
||||
// 须挂在 Auth 之后(依赖已注入的 uid);未登录请求跳过。存量/异常无租户者由 EnsureDefaultTenant
|
||||
// 幂等兜底补建,保证任何已登录请求都能拿到 tenant_id。
|
||||
//
|
||||
// 注:当前每请求解析一次(1–2 条按索引查询)。后续可把 tenant_id 嵌入 JWT / 加缓存去掉此开销。
|
||||
func TenantContext(db *store.Postgres) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if v, ok := c.Get(CtxUserID); ok {
|
||||
if uid, _ := v.(string); uid != "" {
|
||||
if t, err := db.EnsureDefaultTenant(c.Request.Context(), uid, ""); err == nil && t != nil {
|
||||
c.Set(CtxTenantID, t.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user