feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
# Member 模組
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
Gateway 的會員核心:涵蓋 **Tenant(租戶)**、**Member(會員 profile)**、**Identity(外部身份對映)** 三大實體,以及租戶內 readable UID、業務 email/phone OTP 驗證、TOTP step-up MFA、resend / daily 配額等業務功能。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
> **架構原則**(`docs/model.md` §6.1):
|
|
|
|
|
> usecase **不可** 呼叫其他 usecase。多步流程(例如「發起 OTP → 寄信 → 驗碼 → flip business_email_verified」)由 **logic 層** 編排。
|
|
|
|
|
> 本 module 所有 usecase 都是 **atomic primitives**。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 目錄
|
|
|
|
|
|
|
|
|
|
- [核心概念](#核心概念)
|
|
|
|
|
- [目錄結構](#目錄結構)
|
|
|
|
|
- [Module 結構與依賴](#module-結構與依賴)
|
|
|
|
|
- [Atomic UseCase 一覽](#atomic-usecase-一覽)
|
|
|
|
|
- [資料儲存](#資料儲存)
|
|
|
|
|
- [生命週期與狀態機](#生命週期與狀態機)
|
|
|
|
|
- [核心流程時序圖](#核心流程時序圖)
|
|
|
|
|
- [1. 模組裝配 (NewModuleFromParam)](#1-模組裝配-newmodulefromparam)
|
|
|
|
|
- [2. Tenant 建立](#2-tenant-建立)
|
|
|
|
|
- [3. Platform 註冊 (auth + member.Lifecycle)](#3-platform-註冊-auth--memberlifecycle)
|
|
|
|
|
- [4. Provisioning — OIDC / LDAP / SCIM](#4-provisioning--oidc--ldap--scim)
|
|
|
|
|
- [5. 業務 Email / Phone OTP 驗證](#5-業務-email--phone-otp-驗證)
|
|
|
|
|
- [6. TOTP 綁定 / Step-up](#6-totp-綁定--step-up)
|
|
|
|
|
- [7. UID 生成](#7-uid-生成)
|
|
|
|
|
- [Redis Key 命名](#redis-key-命名)
|
|
|
|
|
- [設定](#設定)
|
|
|
|
|
- [ServiceContext 注入](#servicecontext-注入)
|
|
|
|
|
- [測試](#測試)
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## 核心概念
|
|
|
|
|
|
|
|
|
|
| 實體 | 用途 | 主要欄位 | 儲存 |
|
|
|
|
|
| --- | --- | --- | --- |
|
|
|
|
|
| **Tenant** | 租戶元資料 | `tenant_id`、`slug`、`uid_prefix`、`status`、`org_id` | Mongo `tenants` |
|
|
|
|
|
| **Member** | 會員 profile(租戶範圍) | `tenant_id`+`uid`、`zitadel_user_id`、`status`、`origin`、business email/phone、TOTP cipher | Mongo `members` |
|
|
|
|
|
| **Identity** | 外部 ID → UID 對映表 | `zitadel_user_id`、`external_id`、`uid` | Mongo `identities` |
|
|
|
|
|
|
|
|
|
|
**Member 雙鍵**:`(tenant_id, uid)` 為對外的可讀主鍵;`zitadel_user_id` 是 OIDC 來源的對映鍵。
|
|
|
|
|
**多租戶等級**:每個 Member 必屬於一個 Tenant,UID 用 `{TenantUIDPrefix}-{Sequence}` 格式(例:`ACME-10000003`)。
|
|
|
|
|
|
|
|
|
|
### 來源(Origin)
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
platform_native // 前台註冊(auth.RegisterLogic + Lifecycle.CreateUnverified)
|
|
|
|
|
oidc // ZITADEL 社群登入 / SSO(Provisioning.EnsureFromOIDC)
|
|
|
|
|
ldap // Directory Sync(Provisioning.EnsureFromLDAP)
|
|
|
|
|
scim // SCIM 2.0(Provisioning.EnsureFromSCIM)
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## 目錄結構
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
```
|
|
|
|
|
internal/model/member/
|
|
|
|
|
├── config/ # OTP / TOTP / Registration 設定
|
|
|
|
|
├── domain/ # 介面、enum、entity、errors、redis key helper
|
|
|
|
|
│ ├── const.go # BSON 欄位、UID 常數
|
|
|
|
|
│ ├── entity/ # Member、Tenant、Identity Mongo doc
|
|
|
|
|
│ ├── enum/ # MemberStatus、MemberOrigin、OTPPurpose、TenantStatus、VerifyKind
|
|
|
|
|
│ ├── errors.go # ErrNotFound、ErrDuplicateMember 等
|
|
|
|
|
│ ├── redis.go # GetOTPChallengeRedisKey 等 helper
|
|
|
|
|
│ ├── repository/ # 7 個 repository 介面
|
|
|
|
|
│ └── usecase/ # 7 個 usecase 介面 + DTO
|
|
|
|
|
├── repository/ # Mongo / Redis 實作
|
|
|
|
|
├── totp/ # RFC 6238 純函式(secret、verify、otpauth URL)
|
|
|
|
|
├── usecase/ # 7 個 usecase 實作 + module factory + mapper
|
|
|
|
|
└── README.md # 本檔
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`domain/` 純介面 + 常數,**不依賴外部 lib**(除 `bson.ObjectID`)。
|
|
|
|
|
`usecase/` 只依賴 `domain/`。
|
|
|
|
|
`repository/` 依賴 `library/mongo`、`library/redis`。
|
|
|
|
|
|
|
|
|
|
---
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## Module 結構與依賴
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```mermaid
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
flowchart TB
|
|
|
|
|
Logic["logic 層<br/>(handler 編排)"]
|
|
|
|
|
|
|
|
|
|
subgraph M["member.Module (atomic usecases)"]
|
|
|
|
|
direction LR
|
|
|
|
|
OTP["OTP"]
|
|
|
|
|
TOTP["TOTP"]
|
|
|
|
|
Profile["Profile"]
|
|
|
|
|
Lifecycle["Lifecycle"]
|
|
|
|
|
Provisioning["Provisioning"]
|
|
|
|
|
Tenant["Tenant"]
|
|
|
|
|
VerifyRate["VerifyRate"]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subgraph R["domain.Repository (介面)"]
|
|
|
|
|
MemberRepo["MemberRepository"]
|
|
|
|
|
TenantRepo["TenantRepository"]
|
|
|
|
|
IdentityRepo["IdentityRepository"]
|
|
|
|
|
OTPStore["OTPChallengeStore"]
|
|
|
|
|
RateStore["VerifyRateStore"]
|
|
|
|
|
TOTPProf["TOTPProfileRepository"]
|
|
|
|
|
TOTPEnroll["TOTPEnrollStore"]
|
|
|
|
|
TOTPReplay["TOTPReplayStore"]
|
|
|
|
|
UIDGen["UIDGenerator"]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subgraph I["repository/ 實作"]
|
|
|
|
|
Mongo[(MongoDB)]
|
|
|
|
|
Redis[(Redis)]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Logic -->|單呼叫| M
|
|
|
|
|
OTP --> OTPStore
|
|
|
|
|
TOTP --> TOTPProf
|
|
|
|
|
TOTP --> TOTPEnroll
|
|
|
|
|
TOTP --> TOTPReplay
|
|
|
|
|
Profile --> MemberRepo
|
|
|
|
|
Lifecycle --> MemberRepo
|
|
|
|
|
Lifecycle --> TenantRepo
|
|
|
|
|
Lifecycle --> UIDGen
|
|
|
|
|
Provisioning --> MemberRepo
|
|
|
|
|
Provisioning --> IdentityRepo
|
|
|
|
|
Provisioning --> TenantRepo
|
|
|
|
|
Provisioning --> UIDGen
|
|
|
|
|
Tenant --> TenantRepo
|
|
|
|
|
VerifyRate --> RateStore
|
|
|
|
|
|
|
|
|
|
MemberRepo --- Mongo
|
|
|
|
|
TenantRepo --- Mongo
|
|
|
|
|
IdentityRepo --- Mongo
|
|
|
|
|
TOTPProf --- Mongo
|
|
|
|
|
OTPStore --- Redis
|
|
|
|
|
RateStore --- Redis
|
|
|
|
|
TOTPEnroll --- Redis
|
|
|
|
|
TOTPReplay --- Redis
|
|
|
|
|
UIDGen --- Redis
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
**注入規則**:Module factory 依條件啟用 usecase:
|
|
|
|
|
- `Redis` 必填 → `OTP`、`VerifyRate` 永遠存在。
|
|
|
|
|
- `MongoConf` 設定 → 啟用 `Profile`、`Lifecycle`、`Tenant`、`Provisioning`。
|
|
|
|
|
- `TOTP.SecretKEK` 設定 → 啟用 `TOTP`(否則 `mod.TOTP == nil`)。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
---
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## Atomic UseCase 一覽
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
| UseCase | 介面方法 | 職責 |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| **TenantUseCase** | `Create` / `ResolveBySlug` | 建立租戶、依 slug 反查 |
|
|
|
|
|
| **LifecycleUseCase** | `CreateUnverified` / `Activate` / `Suspend` / `Reactivate` / `SoftDelete` / `AbortPending` | platform 會員建立 + 狀態轉換(嚴格的 from→to 檢查) |
|
|
|
|
|
| **ProfileUseCase** | `GetByUID` / `GetByZitadelUserID` / `Update` / `List` / `SetBusinessEmailVerified` / `SetBusinessPhoneVerified` | 讀取 / patch 可變欄位、業務 contact 標記已驗證 |
|
|
|
|
|
| **ProvisioningUseCase** | `EnsureFromOIDC` / `EnsureFromLDAP` / `EnsureFromSCIM` | 外部身份首登/同步 upsert(Member + Identity) |
|
|
|
|
|
| **OTPUseCase** | `Generate` / `Verify` / `Invalidate` / `GetChallenge` / `MatchChallenge` | 產出/驗證一次性數字碼(bcrypt + Redis) |
|
|
|
|
|
| **TOTPUseCase** | `StartEnroll` / `ConfirmEnroll` / `VerifyCode` / `Disable` / `RegenerateBackupCodes` / `Status` | RFC 6238 step-up MFA(AES-GCM 保護 secret) |
|
|
|
|
|
| **VerifyRateUseCase** | `AssertResendAllowed` / `AssertDailyAllowed` | OTP 重發冷卻 + 每日上限 |
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
---
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## 資料儲存
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### MongoDB Collections
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
| Collection | Entity | 主要索引 |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| `members` | `Member` | unique `(tenant_id, uid)`、unique `(tenant_id, zitadel_user_id)`(sparse) |
|
|
|
|
|
| `tenants` | `Tenant` | unique `slug`、unique `uid_prefix` |
|
|
|
|
|
| `identities` | `Identity` | unique `(tenant_id, external_id)`、unique `(tenant_id, zitadel_user_id)` |
|
|
|
|
|
|
|
|
|
|
索引建立由 `repository.EnsureMongoIndexes` 在啟動時執行(對應 `cmd/mongo-index`)。
|
|
|
|
|
|
|
|
|
|
### Redis Keys
|
|
|
|
|
|
|
|
|
|
| Key 前綴 | 用途 | TTL |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| `member:otp:challenge:{id}` | OTP challenge 主紀錄(bcrypt hash) | `OTP.TTLSeconds`(預設 300) |
|
|
|
|
|
| `member:otp:challenge:{id}:attempts` | OTP 錯誤次數計數 | 同 challenge |
|
|
|
|
|
| `member:verify:rate:{tenant}:{uid}:{kind}` | resend 冷卻 lock | `OTP.ResendCooldownSeconds`(預設 60) |
|
|
|
|
|
| `member:verify:daily:{tenant}:{uid}:{kind}` | 每日上限計數 | 24h |
|
|
|
|
|
| `member:totp:enroll:{tenant}:{uid}` | 綁定中的 staged secret(AES-GCM cipher) | `TOTP.EnrollTTLSeconds`(預設 600) |
|
|
|
|
|
| `member:totp:used:{tenant}:{uid}:{timestep}` | TOTP 重放保護 | `TOTP.ReplayTTLSeconds`(預設 90) |
|
|
|
|
|
| `member:seq:{tenant}` | UID 序號(`INCR`) | 永久 |
|
|
|
|
|
|
|
|
|
|
Helper 函式見 `domain/redis.go`,**禁止** 在他處字串拼接 key。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 生命週期與狀態機
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
```mermaid
|
|
|
|
|
stateDiagram-v2
|
|
|
|
|
[*] --> unverified: Lifecycle.CreateUnverified<br/>(platform 註冊)
|
|
|
|
|
[*] --> active: Provisioning.Ensure*<br/>(OIDC/LDAP/SCIM 首登)
|
|
|
|
|
|
|
|
|
|
unverified --> active: Activate<br/>(OTP 驗證通過)
|
|
|
|
|
unverified --> deleted: AbortPending<br/>(註冊逾時)
|
|
|
|
|
|
|
|
|
|
active --> suspended: Suspend(reason)
|
|
|
|
|
suspended --> active: Reactivate
|
|
|
|
|
active --> deleted: SoftDelete
|
|
|
|
|
suspended --> deleted: SoftDelete
|
|
|
|
|
deleted --> [*]
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
`transition()` 強制 `from → to`,不符回 `ErrInvalidStatus`。
|
|
|
|
|
|
2026-05-20 13:03:59 +00:00
|
|
|
---
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## 核心流程時序圖
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 1. 模組裝配 (NewModuleFromParam)
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
autonumber
|
|
|
|
|
participant SVC as svc.NewServiceContext
|
|
|
|
|
participant Mod as member.NewModuleFromParam
|
|
|
|
|
participant Repo as repository
|
|
|
|
|
participant Redis
|
|
|
|
|
participant Mongo
|
|
|
|
|
|
|
|
|
|
SVC->>Mod: ModuleParam{Redis, MongoConf, Config}
|
|
|
|
|
Mod->>Repo: NewRedisOTPChallengeStore(redis)
|
|
|
|
|
Mod->>Repo: NewRedisVerifyRateStore(redis)
|
|
|
|
|
alt MongoConf.Host != ""
|
|
|
|
|
Mod->>Repo: NewMemberRepository / NewTenantRepository / NewIdentityRepository
|
|
|
|
|
Mod->>Repo: NewMongoTOTPProfileRepository
|
|
|
|
|
Repo->>Mongo: ping (lazy)
|
|
|
|
|
end
|
|
|
|
|
Mod->>Repo: NewRedisUIDGenerator(redis)
|
|
|
|
|
Mod->>Mod: MustOTPUseCase / MustVerifyRateUseCase
|
|
|
|
|
alt Mongo 就緒
|
|
|
|
|
Mod->>Mod: MustProfileUseCase / MustLifecycleUseCase / MustTenantUseCase / MustProvisioningUseCase
|
|
|
|
|
end
|
|
|
|
|
alt TOTP.SecretKEK != ""
|
|
|
|
|
Mod->>Mod: NewAESGCMFromString(KEK)
|
|
|
|
|
Mod->>Repo: NewRedisTOTPEnrollStore / NewRedisTOTPReplayStore
|
|
|
|
|
Mod->>Mod: MustTOTPUseCase
|
|
|
|
|
end
|
|
|
|
|
Mod-->>SVC: *Module(7 usecase + 3 repo)
|
|
|
|
|
SVC->>SVC: sc.MemberOTP / sc.MemberLifecycle / ...
|
|
|
|
|
```
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 2. Tenant 建立
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
autonumber
|
|
|
|
|
participant CLI as cmd/member-seed
|
|
|
|
|
participant TenantUC as TenantUseCase
|
|
|
|
|
participant Repo as TenantRepository
|
|
|
|
|
participant Mongo
|
|
|
|
|
|
|
|
|
|
CLI->>TenantUC: Create(req{TenantID, Slug, Name, UIDPrefix})
|
|
|
|
|
TenantUC->>TenantUC: normalizeUIDPrefix + 長度檢查 (2-4)
|
|
|
|
|
TenantUC->>Repo: GetByUIDPrefix(prefix)
|
|
|
|
|
Repo->>Mongo: findOne
|
|
|
|
|
alt prefix 已存在
|
|
|
|
|
TenantUC-->>CLI: ErrAlreadyExist("uid_prefix already exists")
|
|
|
|
|
else 不存在
|
|
|
|
|
TenantUC->>Repo: Insert(Tenant{Status: active})
|
|
|
|
|
Repo->>Mongo: insertOne
|
|
|
|
|
TenantUC-->>CLI: TenantDTO
|
|
|
|
|
end
|
|
|
|
|
```
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 3. Platform 註冊 (auth + member.Lifecycle)
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
> 屬於 `internal/logic/auth/register_logic.go` 的編排;Member module 只負責 atomic 動作。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
autonumber
|
|
|
|
|
participant Client
|
|
|
|
|
participant RegLogic as logic/auth.RegisterLogic
|
|
|
|
|
participant TenantUC as TenantUseCase
|
|
|
|
|
participant Zitadel as library/zitadel
|
|
|
|
|
participant Lifecycle as LifecycleUseCase
|
|
|
|
|
participant OTP as OTPUseCase
|
|
|
|
|
participant Notifier
|
|
|
|
|
participant Confirm as logic/auth.RegisterConfirmLogic
|
|
|
|
|
|
|
|
|
|
Client->>RegLogic: POST /auth/register {tenant_slug, email, password}
|
|
|
|
|
RegLogic->>TenantUC: ResolveBySlug(slug)
|
|
|
|
|
TenantUC-->>RegLogic: TenantDTO
|
|
|
|
|
RegLogic->>Zitadel: CreateHumanUser(...)
|
|
|
|
|
Zitadel-->>RegLogic: zitadel_user_id
|
|
|
|
|
RegLogic->>Lifecycle: CreateUnverified(req{tenant, email, hash, zitadel_user_id})
|
|
|
|
|
Lifecycle->>Lifecycle: 取 tenant.UIDPrefix → UIDGenerator.Next
|
|
|
|
|
Lifecycle->>Lifecycle: members.Insert(status=unverified)
|
|
|
|
|
Lifecycle-->>RegLogic: MemberDTO(uid)
|
|
|
|
|
RegLogic->>OTP: Generate(purpose=Register, uid, target=email)
|
|
|
|
|
OTP-->>RegLogic: challenge_id, plainCode
|
|
|
|
|
RegLogic->>Notifier: Send(VerifyEmail, code)
|
|
|
|
|
alt Notifier 失敗
|
|
|
|
|
RegLogic->>Lifecycle: AbortPending(uid)
|
|
|
|
|
RegLogic-->>Client: 5xx
|
|
|
|
|
else 成功
|
|
|
|
|
RegLogic-->>Client: {challenge_id, expires_in}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Note over Client,Confirm: 使用者收到信
|
|
|
|
|
Client->>Confirm: POST /auth/register/confirm {challenge_id, code}
|
|
|
|
|
Confirm->>OTP: MatchChallenge(challenge_id, tenant, purpose=Register, RequireUID)
|
|
|
|
|
OTP-->>Confirm: OTPChallengeInfo{uid}
|
|
|
|
|
Confirm->>OTP: Verify(challenge_id, code, uid, purpose)
|
|
|
|
|
OTP-->>Confirm: target(email)
|
|
|
|
|
Confirm->>Lifecycle: Activate(tenant, uid) // unverified → active
|
|
|
|
|
Confirm-->>Client: JWT (auth 簽發)
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 4. Provisioning — OIDC / LDAP / SCIM
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
外部身份首次登入時透過 `EnsureFromOIDC` upsert,**冪等**(既存即回傳)。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
autonumber
|
|
|
|
|
participant Logic as logic/auth.LoginSocialCallback
|
|
|
|
|
participant Prov as ProvisioningUseCase
|
|
|
|
|
participant MR as MemberRepository
|
|
|
|
|
participant IR as IdentityRepository
|
|
|
|
|
participant TR as TenantRepository
|
|
|
|
|
participant UID as UIDGenerator
|
|
|
|
|
participant Redis
|
|
|
|
|
participant Mongo
|
|
|
|
|
|
|
|
|
|
Logic->>Prov: EnsureFromOIDC(tenant, zitadel_sub, email, ...)
|
|
|
|
|
Prov->>MR: GetByZitadelUserID(tenant, sub)
|
|
|
|
|
MR->>Mongo: find
|
|
|
|
|
alt 已存在
|
|
|
|
|
MR-->>Prov: Member
|
|
|
|
|
Prov-->>Logic: MemberDTO (origin=oidc, status=active)
|
|
|
|
|
else ErrNotFound
|
|
|
|
|
Prov->>TR: GetByTenantID(tenant)
|
|
|
|
|
TR-->>Prov: Tenant{UIDPrefix}
|
|
|
|
|
Prov->>UID: Next(tenant, prefix)
|
|
|
|
|
UID->>Redis: INCR member:seq:{tenant}
|
|
|
|
|
UID-->>Prov: "ACME-10000003"
|
|
|
|
|
Prov->>MR: Insert(Member{status=active, origin=oidc, zitadel_user_id})
|
|
|
|
|
MR->>Mongo: insertOne
|
|
|
|
|
alt duplicate(競態)
|
|
|
|
|
MR-->>Prov: ErrDuplicateMember
|
|
|
|
|
Prov->>MR: GetByZitadelUserID // 再讀一次回傳
|
|
|
|
|
end
|
|
|
|
|
Prov->>IR: Insert(Identity{zitadel_user_id, uid})
|
|
|
|
|
IR->>Mongo: insertOne(忽略 dup)
|
|
|
|
|
Prov-->>Logic: MemberDTO
|
|
|
|
|
end
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
LDAP / SCIM 同樣模式,額外查 `IdentityRepository.GetByExternalID` 處理沒有 zitadel_sub 的情境。
|
|
|
|
|
|
|
|
|
|
### 5. 業務 Email / Phone OTP 驗證
|
|
|
|
|
|
|
|
|
|
由 `internal/logic/member/verify_helper.go` 編排(`startVerification` + `confirmVerification`),展示 logic 層如何把多個 atomic usecase 串起來。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
autonumber
|
|
|
|
|
participant Client
|
|
|
|
|
participant Logic as logic/member.startVerification
|
|
|
|
|
participant Rate as VerifyRateUseCase
|
|
|
|
|
participant OTP as OTPUseCase
|
|
|
|
|
participant Notif as Notifier
|
|
|
|
|
participant Profile as ProfileUseCase
|
|
|
|
|
participant Redis
|
|
|
|
|
|
|
|
|
|
Client->>Logic: POST /me/verifications/email/start {target}
|
|
|
|
|
Logic->>Rate: AssertResendAllowed(rateKey, cooldown=60s)
|
|
|
|
|
Rate->>Redis: SETNX member:verify:rate:{t}:{u}:business_email
|
|
|
|
|
alt cooldown 中
|
|
|
|
|
Rate-->>Logic: ErrTooManyRequest
|
|
|
|
|
Logic-->>Client: 429
|
|
|
|
|
end
|
|
|
|
|
Logic->>Rate: AssertDailyAllowed(dailyKey, 24h, limit=10)
|
|
|
|
|
Rate->>Redis: INCR member:verify:daily:{t}:{u}:business_email
|
|
|
|
|
Logic->>OTP: Generate(uid, purpose=BusinessEmail, target=email)
|
|
|
|
|
OTP->>Redis: SET member:otp:challenge:{id} (bcrypt hash, TTL=300s)
|
|
|
|
|
OTP-->>Logic: challenge_id, plainCode
|
|
|
|
|
Logic->>Notif: Send(channel=email, kind=VerifyEmail, data={code, expires_in})
|
|
|
|
|
alt Notifier 失敗
|
|
|
|
|
Logic->>OTP: Invalidate(challenge_id)
|
|
|
|
|
Logic-->>Client: 5xx
|
|
|
|
|
else 成功
|
|
|
|
|
Logic-->>Client: {challenge_id, expires_in}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Note over Client,Profile: 使用者收到信
|
|
|
|
|
Client->>Logic: POST /me/verifications/email/confirm {challenge_id, code}
|
|
|
|
|
Logic->>OTP: Verify(challenge_id, code, uid, purpose=BusinessEmail)
|
|
|
|
|
OTP->>Redis: GET + bcrypt compare
|
|
|
|
|
alt 失敗
|
|
|
|
|
OTP->>Redis: INCR attempts
|
|
|
|
|
alt attempts >= 5
|
|
|
|
|
OTP-->>Logic: ErrChallengeLocked
|
|
|
|
|
else
|
|
|
|
|
OTP-->>Logic: ErrInvalidOTP
|
|
|
|
|
end
|
|
|
|
|
else 成功
|
|
|
|
|
OTP->>Redis: DEL challenge
|
|
|
|
|
OTP-->>Logic: target(email)
|
|
|
|
|
Logic->>Profile: SetBusinessEmailVerified(tenant, uid, target)
|
|
|
|
|
Profile-->>Logic: nil
|
|
|
|
|
Logic-->>Client: 204
|
|
|
|
|
end
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**關鍵設計**:`Verify` 成功後 challenge **立刻刪除**(一次性);`Generate` 一定要先過 `VerifyRate` 兩道閘門。
|
|
|
|
|
|
|
|
|
|
### 6. TOTP 綁定 / Step-up
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
autonumber
|
|
|
|
|
participant Client
|
|
|
|
|
participant Logic
|
|
|
|
|
participant TOTP as TOTPUseCase
|
|
|
|
|
participant Profile as TOTPProfileRepository
|
|
|
|
|
participant Enroll as TOTPEnrollStore
|
|
|
|
|
participant Replay as TOTPReplayStore
|
|
|
|
|
participant Cipher as crypto.Cipher (AES-GCM)
|
|
|
|
|
|
|
|
|
|
Note over Client,Cipher: A. 綁定階段
|
|
|
|
|
Client->>Logic: POST /me/totp/enroll
|
|
|
|
|
Logic->>TOTP: StartEnroll(tenant, uid, account)
|
|
|
|
|
TOTP->>Profile: Get → 必須未 enrolled
|
|
|
|
|
TOTP->>TOTP: totp.GenerateSecret() (隨機 20 byte)
|
|
|
|
|
TOTP->>Cipher: Encrypt(secret) → cipherBlob
|
|
|
|
|
TOTP->>Enroll: Save(cipherBlob, TTL=600s)
|
|
|
|
|
TOTP-->>Logic: {otpauth_url, digits=6, period=30}
|
|
|
|
|
Logic-->>Client: QR code 資料
|
|
|
|
|
|
|
|
|
|
Client->>Client: 掃 QR 加入 Authenticator
|
|
|
|
|
Client->>Logic: POST /me/totp/enroll/confirm {code}
|
|
|
|
|
Logic->>TOTP: ConfirmEnroll(tenant, uid, code)
|
|
|
|
|
TOTP->>Enroll: Get → cipherBlob
|
|
|
|
|
TOTP->>Cipher: Decrypt → secret
|
|
|
|
|
TOTP->>TOTP: totp.Verify(secret, code, ±window)
|
|
|
|
|
alt 驗碼失敗
|
|
|
|
|
TOTP-->>Logic: ErrTOTPInvalidCode
|
|
|
|
|
else 成功
|
|
|
|
|
TOTP->>TOTP: 產生 N 個 backup codes + bcrypt hashes
|
|
|
|
|
TOTP->>Profile: Save({Enrolled, SecretCipher, BackupCodesHash})
|
|
|
|
|
TOTP->>Enroll: Delete (清掉 staged)
|
|
|
|
|
TOTP-->>Logic: plainCodes[](僅此一次回傳)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Note over Client,Replay: B. 日常 step-up
|
|
|
|
|
Client->>Logic: 任意敏感操作攜 6 碼
|
|
|
|
|
Logic->>TOTP: VerifyCode(tenant, uid, code)
|
|
|
|
|
TOTP->>Profile: Get → 必須 enrolled
|
|
|
|
|
TOTP->>Cipher: Decrypt(SecretCipher)
|
|
|
|
|
alt code 長度 = 6
|
|
|
|
|
TOTP->>TOTP: totp.Verify(±window) → step
|
|
|
|
|
alt OK
|
|
|
|
|
TOTP->>Replay: MarkUsed(timestep, TTL=90s) → fresh?
|
|
|
|
|
alt 已用過
|
|
|
|
|
TOTP-->>Logic: ErrTOTPCodeReplay
|
|
|
|
|
else 未用過
|
|
|
|
|
TOTP-->>Logic: nil
|
|
|
|
|
end
|
|
|
|
|
else 失敗
|
|
|
|
|
TOTP->>TOTP: fall through to backup code
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
alt 嘗試備援碼
|
|
|
|
|
loop 每組 hash
|
|
|
|
|
TOTP->>TOTP: bcrypt.CompareHashAndPassword
|
|
|
|
|
end
|
|
|
|
|
alt 命中
|
|
|
|
|
TOTP->>Profile: ConsumeBackupCode(hash) (atomic)
|
|
|
|
|
TOTP-->>Logic: nil
|
|
|
|
|
else 全失敗
|
|
|
|
|
TOTP-->>Logic: ErrTOTPInvalidCode
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
```
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 7. UID 生成
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
autonumber
|
|
|
|
|
participant Caller as Lifecycle / Provisioning
|
|
|
|
|
participant Gen as UIDGenerator
|
|
|
|
|
participant Redis
|
|
|
|
|
|
|
|
|
|
Caller->>Gen: Next(tenant, uidPrefix)
|
|
|
|
|
Gen->>Redis: INCR member:seq:{tenant}
|
|
|
|
|
Redis-->>Gen: seq
|
|
|
|
|
alt seq == 1 (首次)
|
|
|
|
|
Note right of Gen: 一次補上起始值<br/>(避開像 ACME-1 這種短 UID)
|
|
|
|
|
Gen->>Redis: INCRBY (UIDSequenceStart - 1) = 9_999_999
|
|
|
|
|
Redis-->>Gen: 10_000_000
|
|
|
|
|
end
|
|
|
|
|
Gen-->>Caller: "{PREFIX}-{seq}" 例:ACME-10000003
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
`UIDSequenceStart = 10_000_000`(7 位起跳),`UIDPrefix` 限制 2~4 個大寫字母。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Redis Key 命名
|
|
|
|
|
|
|
|
|
|
| Helper | 對應 key | 使用者 |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| `GetOTPChallengeRedisKey(id)` | `member:otp:challenge:{id}` | `OTPChallengeStore` |
|
|
|
|
|
| `GetOTPAttemptsRedisKey(id)` | `member:otp:challenge:{id}:attempts` | `OTPChallengeStore` |
|
|
|
|
|
| `GetVerifyRateRedisKey(tenant, uid, kind)` | `member:verify:rate:...` | `VerifyRate` (logic 層) |
|
|
|
|
|
| `GetVerifyDailyRedisKey(tenant, uid, kind)` | `member:verify:daily:...` | 同上 |
|
|
|
|
|
| `GetTOTPEnrollRedisKey(tenant, uid)` | `member:totp:enroll:...` | `TOTPEnrollStore` |
|
|
|
|
|
| `GetTOTPUsedRedisKey(tenant, uid, step)` | `member:totp:used:...` | `TOTPReplayStore` |
|
|
|
|
|
| `GetMemberSeqRedisKey(tenant)` | `member:seq:{tenant}` | `UIDGenerator` |
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
`kind` 通常是 `enum.OTPPurpose` 字串(`business_email`、`business_phone`、`step_up` 等)。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 設定
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
`etc/gateway.dev.yaml` → `Member` 區塊:
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
Member:
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
Registration:
|
|
|
|
|
RequireInviteCode: true # 平台註冊是否強制邀請碼
|
|
|
|
|
TrustSocialEmailVerified: true # OIDC email_verified=true 時直接 active
|
2026-05-20 13:03:59 +00:00
|
|
|
OTP:
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
Length: 6 # 驗證碼位數
|
|
|
|
|
TTLSeconds: 300 # challenge 存活時間
|
|
|
|
|
MaxAttempts: 5 # 單 challenge 最大錯誤次數
|
|
|
|
|
ResendCooldownSeconds: 60 # 重發冷卻
|
|
|
|
|
DailyVerifyLimit: 10 # 每日上限
|
2026-05-20 13:03:59 +00:00
|
|
|
TOTP:
|
|
|
|
|
Issuer: CloudEP
|
|
|
|
|
Algorithm: SHA1
|
|
|
|
|
Digits: 6
|
|
|
|
|
PeriodSeconds: 30
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
Window: 1 # ±1 time step 容忍
|
2026-05-20 13:03:59 +00:00
|
|
|
BackupCodeCount: 10
|
|
|
|
|
BackupCodeLength: 12
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
EnrollTTLSeconds: 600
|
|
|
|
|
ReplayTTLSeconds: 90
|
|
|
|
|
SecretKEK: "" # 32-byte AES key(hex 64 字元或 base64);留空關閉 TOTP
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
**`SecretKEK`** 可改用環境變數 `TOTP_SECRET_KEK`(prod 建議走 KMS / secret manager)。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## ServiceContext 注入
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```go
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
// internal/svc/service_context.go
|
|
|
|
|
sc.MemberOTP // domusecase.OTPUseCase (一定有)
|
|
|
|
|
sc.MemberVerifyRate // domusecase.VerifyRateUseCase (一定有)
|
|
|
|
|
sc.MemberProfile // domusecase.ProfileUseCase (Mongo 設定後)
|
|
|
|
|
sc.MemberLifecycle // domusecase.LifecycleUseCase (Mongo 設定後)
|
|
|
|
|
sc.MemberTenant // domusecase.TenantUseCase (Mongo 設定後)
|
|
|
|
|
sc.MemberProvisioning // domusecase.ProvisioningUseCase(Mongo 設定後)
|
|
|
|
|
sc.MemberTOTP // domusecase.TOTPUseCase (TOTP.SecretKEK 設定後;否則 nil)
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
Logic 層使用前務必檢查可能 `nil` 的欄位:
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```go
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
if sc.MemberTOTP == nil {
|
|
|
|
|
return errb.SysNotImplemented("member TOTP not configured")
|
|
|
|
|
}
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## 測試
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 單元測試
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```bash
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
go test ./internal/model/member/... -v
|
|
|
|
|
make check
|
2026-05-20 13:03:59 +00:00
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
| 檔案 | 覆蓋 |
|
|
|
|
|
| --- | --- |
|
|
|
|
|
| `usecase/otp_usecase_test.go` | Generate/Verify、UID/purpose mismatch、attempts lock |
|
|
|
|
|
| `usecase/totp_usecase_test.go` | 綁定、VerifyCode、備援碼、重放、Disable、Regenerate |
|
|
|
|
|
| `totp/totp_test.go` | RFC 6238 測試向量、window、otpauth URL |
|
2026-05-20 23:51:22 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 本機 API(P4)
|
2026-05-20 23:51:22 +00:00
|
|
|
|
|
|
|
|
```bash
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
make deps-up # docker compose: mongo + redis
|
|
|
|
|
make mongo-index # 建索引
|
|
|
|
|
make member-seed # 建 dev tenant + 一筆 member,輸出 X-Tenant-ID/X-UID headers
|
|
|
|
|
make run-local # 啟動 gateway
|
2026-05-20 23:51:22 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
# Profile
|
2026-05-20 23:51:22 +00:00
|
|
|
curl -s -H "X-Tenant-ID:dev-tenant" -H "X-UID:DEV-10000000" \
|
|
|
|
|
http://127.0.0.1:8888/api/v1/members/me | jq
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
# 業務 email 驗證(start → confirm)
|
2026-05-20 23:51:22 +00:00
|
|
|
curl -s -X POST -H "Content-Type: application/json" \
|
|
|
|
|
-H "X-Tenant-ID:dev-tenant" -H "X-UID:DEV-10000000" \
|
|
|
|
|
-d '{"target":"you@example.com"}' \
|
|
|
|
|
http://127.0.0.1:8888/api/v1/members/me/verifications/email/start | jq
|
|
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
完整 API 見 `generate/api/member.api`。
|
2026-05-20 23:51:22 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
### 互動式 TOTP(Google Authenticator)
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
make deps-up
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
make totp-test # 預設 STEP=flow:整套綁定 + 驗碼 + 重放
|
2026-05-20 13:03:59 +00:00
|
|
|
make totp-test STEP=status
|
|
|
|
|
make totp-test STEP=disable
|
|
|
|
|
```
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
需在 `etc/gateway.dev.yaml` 設定 `Member.TOTP.SecretKEK`(example 已附 dev-only 占位 key)。
|
2026-05-20 13:03:59 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
## 設計參考
|
2026-05-20 13:03:59 +00:00
|
|
|
|
feat(permission): add RBAC module with Casbin enforcement and policy reload
- Multi-tenant RBAC: permission catalog, roles, role-permission mapping,
user-role assignment, and external IdP role mapping (zitadel/ldap/scim).
- Casbin enforcer with Redis-backed adapter and Pub/Sub reload for
multi-instance policy sync; HTTP middleware enforces (tenant, role,
path, method) with platform admin bypass.
- /api/v1/permissions routes: catalog, me, policy/reload, roles CRUD,
role permissions, user roles, role mappings.
- New error scope (31) for Permission and biz code descriptions.
- Wire Permission module into ServiceContext, config, mongo-index, and
add cmd/permission-seed CLI plus etc/rbac.conf model.
- Redis client gains lazy PubSubClient helper (go-zero wrapper lacks Subscribe).
- Rewrite internal/model/member/README to cover Tenant/Member/Identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 08:47:35 +00:00
|
|
|
- 詳細領域模型 / 多租戶設計 / B2B Permission 對接:`docs/identity-member-design.md`
|
|
|
|
|
- 模組分層公約(usecase 不可呼叫 usecase):`docs/model.md` §6.1
|
|
|
|
|
- 統一錯誤格式(`errb.*`):`internal/library/errors/README.md`
|