搜尋完整文件

輸入關鍵字,例如 idempotency、proposal lifecycle 或權限。

選擇 開啟
English
瀏覽文件

Relay · Channels

Channel、membership 與權限

Relay 提供一套精簡的 transport permission model。它隔離 tenant,要求 conversation write 必須具備 membership,並把 business authorization 留給 host。

目前的 read policy 比 write policy 寬。以下矩陣描述現在的 public behavior,不能視為 private-channel RBAC system。

建立 channel

任何已驗證的 tenant user 都能建立 channel:

POST /api/channels
Authorization: Bearer <jwt>
Content-Type: application/json

{
  "metadata": {
    "name": "support"
  }
}

Relay 回傳 201 Created,並自動為建立 channel 的 user 建立 membership。

Channel metadata 是由 host 定義的 JSON,encoded size 上限為 4096 bytes。Relay 負責儲存,但不替其中的 key 定義 business meaning。

目前的 permission matrix

Operation目前條件
列出 tenant 內的 channel該 tenant 內任何 authenticated user
取得單一 channel該 tenant 內任何 authenticated user
列出 channel member該 tenant 內任何 authenticated user
Join WebSocket topicChannel member
傳送 messageChannel member,且 channel 尚未關閉
列出 messageNon-member 目前收到 empty list,不是 403
新增 member既有 channel member
移除 membershipUser 只能移除自己的 membership
關閉 channelChannel member
修改 channel metadataChannel agent member 或 tenant admin
Mute notification event目前的 member 本人

前三項 tenant-wide read 不會依 channel membership 過濾。同一 tenant 內持有 token 的 user 之間,channel existence、metadata 與 member list 不能視為機密資料。

Non-member 讀取 message 時的 empty-list behavior 來自目前的 policy filter。它不是可靠的 authorization signal,未來的 contract 可能會收緊這項行為。

新增 member

既有 member 可以透過 user_id 加入另一位 host user:

POST /api/channels/{channel_id}/members
Authorization: Bearer <jwt>
Content-Type: application/json

{
  "user_id": "user-uuid"
}

建立 membership 時回傳 201 Created。同一 user 重複加入會回傳 422 validation response,因為 (channel_id, user_id) 必須唯一。

這個 endpoint 不判斷 host role、team、subscription 或 case ownership。Host 必須在 request 前決定是否應加入該 user。

離開 channel

Delete endpoint 接受 membership ID,不是 user ID:

DELETE /api/channels/{channel_id}/members/{member_id}
Authorization: Bearer <jwt>

User 只能刪除自己的 membership。成功時回傳 204 No Content。移除其他 user 的 membership 會回傳 403;membership 不存在時回傳 404

目前沒有讓 member 或 moderator 移除其他 member 的 endpoint。Admin surface 提供 tenant-wide user offboarding,但那不是 channel moderation。

關閉 channel

任何 member 都能關閉 open channel:

POST /api/channels/{channel_id}/close
Authorization: Bearer <jwt>

Close 是 idempotent operation。重複 request 會回傳已關閉的 channel,不會改變原本的 closed_at

Closed channel 保留 history,但新 message 會收到 422 validation response。目前的 public API 沒有 reopen 或 channel delete endpoint。

修改 metadata

Ordinary user member 不能修改 channel metadata。Kind 為 agent 的 channel member,或 tenant admin,可以使用以下兩種 operation:

PATCH /api/channels/{channel_id}/metadata
PUT /api/channels/{channel_id}/metadata

PATCH 只 shallow merge top-level key。Nested map 會被取代,不會 deep merge。PUT 會取代完整 metadata map。Metadata 無效或超過大小限制時回傳 422

Admin request 必須明確指定 tenant。Agent request 從 signed token 取得 tenant,且仍需具備 channel membership。

Mute notification event

目前的 member 可以 mute 或 unmute Relay 產生的 notification webhook event:

POST /api/channels/{channel_id}/notification_mute
DELETE /api/channels/{channel_id}/notification_mute

Mute 會修改 member.muted_at,但不阻止 message read、write 或 WebSocket fan-out。Host 是否傳送 email、mobile push 或 in-product badge,不由 Relay 決定。

Product boundary

Relay 負責 tenant isolation 與 coarse conversation membership。Business role,以及是否建立 channel、加入 member 或公開 Relay token,都由 host 決定。

目前的 tenant API 不提供 private channel discovery、owner 或 moderator role、移除其他 member,以及重新開啟 channel。需要這些 guarantee 的 product,必須先補上 Relay contract;把 host role 寫進 channel metadata 不會產生 authorization。

下一步:上傳並綁定 attachment