template-monorepo/internal/model/member/SDD.md

9.4 KiB
Raw Permalink Blame History

Member Service

Member Service — SRS/SDD Document

Version Version Date Editor Memo
1.0.0 2026/05/21 Gateway Team 初版Gateway Member 模組 SDD

1. Introduction

1.1 Purpose

Member 模組為 TianTing Gateway 的會員核心領域層,管理多租戶下的 Tenant租戶、Member會員 profile、Identity外部身份對映以及 UID 生成、業務 Email/Phone OTP 驗證、TOTP step-up MFA、重發每日配額等原子業務原語。

1.2 Scope

範圍內:

  • 租戶建立與 slug 解析
  • 會員生命週期unverified → active → suspended → deleted
  • 外部身份 ProvisionOIDC / LDAP / SCIM
  • Profile 讀寫與業務 contact 驗證標記
  • OTP challengebcrypt + Redis
  • TOTP 綁定驗證備援碼AES-GCM 保護 secret
  • 可讀 UID 序號生成

範圍外:

  • 密碼驗證、JWT 簽發 → Auth 模組 + ZITADEL
  • 通知寄送 → Notification 模組logic 層編排)
  • RBAC → Permission 模組

架構原則: usecase 不可呼叫其他 usecase多步流程由 logic 層編排。

1.3 Definitions, Acronyms, and Abbreviation

縮寫 說明
Tenant 租戶B2B 客戶組織單位
Member 租戶範圍內的會員 profile
Identity 外部 IDLDAP/SCIM external_id 或 zitadel_sub→ UID 對映
UID 可讀主鍵,格式 {UIDPrefix}-{Sequence}(如 ACME-10000003
OTP 一次性數字驗證碼Email/Phone 業務驗證)
TOTP RFC 6238 時間型 OTPGoogle Authenticator
Origin 會員來源platform_native / oidc / ldap / scim

1.4 Technologies to be used

項目 技術
Application Language Go 1.22+
Framework go-zero
Cache RedisOTP、TOTP enroll、UID seq、verify rate
Database MongoDB
Crypto bcryptOTP、AES-GCMTOTP secret、RFC 6238 TOTP
API Codegen goctl / .api

1.5 Overview

Member 模組提供 7 個 atomic UseCaseNewModuleFromParam 依 Mongo / Redis / TOTP KEK 條件組裝:

UseCase 條件
OTP、VerifyRate Redis 必填
Profile、Lifecycle、Tenant、Provisioning Mongo 設定後
TOTP Mongo + TOTP.SecretKEK 設定後

2. System Overview

Member 模組是多租戶身份系統的資料核心:

  • 每個 Member 必屬一個 Tenant
  • UID 以 {TenantUIDPrefix}-{Sequence} 生成,序號從 10,000,000 起跳
  • 平台註冊走 unverified → activeOIDC/LDAP/SCIM 首登直接 active
  • 業務 Email/Phone 驗證與 TOTP 為 step-up MFA 能力

對外透過 /api/v1/members/* REST API 暴露profile、verification、TOTP


3. System Architecture

3.1 System Architecture

flowchart TB
    subgraph Client["Client"]
        App[Frontend / API Client]
    end

    subgraph Gateway["Gateway"]
        Handler["handler/member"]
        Logic["logic/member<br/>(orchestration)"]
        subgraph MemberModule["internal/model/member"]
            UC["usecase/ (7 atomic)"]
            Repo["repository/"]
            TOTP["totp/ (RFC 6238)"]
        end
    end

    subgraph Storage["Storage"]
        Mongo[(MongoDB)]
        Redis[(Redis)]
    end

    subgraph Sibling["Sibling Modules"]
        Auth[auth]
        Notif[notification]
    end

    App --> Handler
    Handler --> Logic
    Logic --> UC
    Logic --> Notif
    Auth --> UC
    UC --> Repo
    UC --> TOTP
    Repo --> Mongo
    Repo --> Redis

3.2 Decomposition Description

套件 職責
config/ OTP / TOTP / Registration 設定
domain/entity/ Member、Tenant、Identity Mongo doc
domain/enum/ MemberStatus、MemberOrigin、OTPPurpose、TenantStatus
domain/repository/ 7 個 repository 介面
domain/usecase/ 7 個 usecase 介面 + DTO
domain/redis.go Redis key helper禁止字串拼接
repository/ Mongo + Redis 實作
totp/ RFC 6238 純函式secret、verify、otpauth URL
usecase/ 實作 + module factory + mapper

3.3 Member Lifecycle

stateDiagram-v2
    [*] --> unverified: Lifecycle.CreateUnverified<br/>(platform 註冊)
    [*] --> active: Provisioning.Ensure*<br/>(OIDC/LDAP/SCIM)

    unverified --> active: Activate (OTP 通過)
    unverified --> deleted: AbortPending (註冊逾時)

    active --> suspended: Suspend
    suspended --> active: Reactivate
    active --> deleted: SoftDelete
    suspended --> deleted: SoftDelete
    deleted --> [*]

3.4 UID Generation

sequenceDiagram
    participant UC as Lifecycle / Provisioning
    participant Gen as UIDGenerator
    participant R as Redis

    UC->>Gen: Next(tenant, uidPrefix)
    Gen->>R: INCR member:seq:{tenant}
    alt seq == 1 (首次)
        Gen->>R: INCRBY (UIDSequenceStart - 1)
    end
    Gen-->>UC: "{PREFIX}-{seq}"
  • UIDSequenceStart = 10_000_000
  • UIDPrefix 限制 2~4 個大寫字母

3.5 OTP / TOTP

OTP bcrypt hash 存 Redis challengeVerify 成功後立即刪除(一次性)。

TOTP secret 以 AES-GCM cipher 存 Mongoenroll 階段 staged secret 存 RedisTTL 600sVerifyCode 含 replay 保護timestep 去重)。


4. Data Design

4.1 Data Dictionary

tenantsMongoDB

Field Type Comment Index
_id ObjectId PK PK
tenant_id String 租戶 ID
slug String URL slug Unique
name String 顯示名稱
uid_prefix String UID 前綴2-4 大寫) Unique
status String active / suspended
org_id String 外部 org ID
create_at Int64 建立時間 ms
update_at Int64 更新時間 ms

membersMongoDB

Field Type Comment Index
_id ObjectId PK PK
tenant_id String 租戶 ID Unique(tenant_id, uid)
uid String 可讀 UID Unique(tenant_id, uid)
zitadel_user_id String ZITADEL sub Unique(tenant_id, zitadel_user_id) sparse
zitadel_email String IdP email
display_name String 顯示名稱
avatar String 頭像 URL
phone String 聯絡電話
language String 語系
currency String 幣別
member_status String unverified/active/suspended/deleted
origin String platform_native/oidc/ldap/scim
business_email String 業務 email
business_email_verified Bool 業務 email 已驗證
business_phone String 業務 phone
business_phone_verified Bool 業務 phone 已驗證
totp_enrolled Bool TOTP 已綁定
totp_secret_cipher Binary AES-GCM 加密 secret
totp_backup_codes_hash Array bcrypt 備援碼 hash
suspend_reason String 停權原因
create_at Int64 建立時間 ms
update_at Int64 更新時間 ms
deleted_at Int64 軟刪時間 ms

identitiesMongoDB

Field Type Comment Index
_id ObjectId PK PK
tenant_id String 租戶 ID Unique(tenant_id, external_id)
external_id String LDAP/SCIM 外部 ID Unique(tenant_id, external_id)
zitadel_user_id String ZITADEL sub Unique(tenant_id, zitadel_user_id)
uid String 對應 Member UID
create_at Int64 建立時間 ms

Redis Keys

Key Pattern 用途 TTL
member:otp:challenge:{id} OTP challengebcrypt hash 300s
member:otp:challenge:{id}:attempts OTP 錯誤次數 同 challenge
member:verify:rate:{tenant}:{uid}:{kind} 重發冷卻 60s
member:verify:daily:{tenant}:{uid}:{kind} 每日上限計數 24h
member:totp:enroll:{tenant}:{uid} TOTP 綁定 staged secret 600s
member:totp:used:{tenant}:{uid}:{step} TOTP 重放保護 90s
member:seq:{tenant} UID 序號 INCR 永久

5. API Design

Base Path /api/v1/members

5.1 Profile

Method Path 說明
GET /me 取得當前會員 profile
PATCH /me 更新 display_name / avatar / language 等

5.2 VerificationOTP

Method Path 說明
POST /me/verifications/email/start 發起業務 email OTP
POST /me/verifications/email/confirm 確認 email OTP
POST /me/verifications/phone/start 發起業務 phone OTP
POST /me/verifications/phone/confirm 確認 phone OTP

5.3 TOTP

Method Path 說明
GET /me/totp/status TOTP 綁定狀態
POST /me/totp/enroll 開始綁定(回 otpauth_url
POST /me/totp/enroll/confirm 確認綁定(回 backup codes
POST /me/totp/verify Step-up 驗碼
POST /me/totp/disable 解除綁定
POST /me/totp/backup-codes/regenerate 重產備援碼

完整 schema 見 generate/api/member.api


6. Resource

資源 路徑
API 定義 generate/api/member.api
Logic 編排 internal/logic/member/
模組原始碼 internal/model/member/
開發 README internal/model/member/README.md
設定範例 etc/gateway.dev.example.yamlMember 區塊
設計參考 docs/identity-member-design.mddocs/model.md §6.1
Seed CLI cmd/member-seed