Organizations Federation API
Organizations Service 的 HTTP 与 SDK API Reference
Organizations Federation API
这篇文档描述客户端和 Bureau 可以调用的 Organizations Action。产品后端的身份和权限接入见 Bureau 接入 Organizations。
安装
import { Federation } from "@downcity/bureau";
import { OrganizationsService } from "@downcity/services";
const federation = new Federation({ database });
federation.use(new OrganizationsService({
max_organizations_per_user: 3,
}));| 选项 | 必填 | 说明 |
|---|---|---|
max_organizations_per_user | 是 | 一个用户在 Federation 中最多拥有的 active Organization 总数 |
Service 支持 better-sqlite3、PostgreSQL 和 Cloudflare D1,并统一使用 context.transaction()。
地址与鉴权
{federation_origin}/v1/organizations/{action}所有 Action 都需要 Federation user_token:
Authorization: Bearer ub_<JWT>Federation 从已验证 Token 读取 user_id 和 bureau_id。GET Action 使用 Query,POST Action 使用 JSON。
类型
type Organization = {
organization_id: string;
name: string;
scope_type: "federation" | "bureau";
scope_bureau_id: string;
state: "active" | "archived";
created_by: string;
created_at: string;
updated_at: string;
archived_at: string;
};
type Membership = {
membership_id: string;
organization_id: string;
user_id: string;
role: "owner" | "admin" | "member";
state: "active" | "removed";
created_at: string;
updated_at: string;
removed_at: string;
removed_by: string;
};
type JoinRequest = {
request_id: string;
organization_id: string;
user_id: string;
state: "pending" | "approved" | "rejected" | "canceled";
requested_at: string;
decided_at: string;
decided_by: string;
};scope_type = federation 时 scope_bureau_id 为空字符串。scope_type = bureau 时,scope_bureau_id 来自创建请求的 user_token.bureau_id。
权限
| 操作 | Owner | Admin | Member |
|---|---|---|---|
| 读取 Organization 和成员 | ✓ | ✓ | ✓ |
| 修改名称 | ✓ | ✓ | |
| 审批 Join Request | ✓ | ✓ | |
| 移除 Member | ✓ | ✓ | |
| 移除 Admin | ✓ | ||
| 任命或撤销 Admin | ✓ | ||
| 转移 Owner | ✓ | ||
| 归档 | ✓ | ||
| 主动退出 | 转移后 | ✓ | ✓ |
Action
| Method | Action | 权限 | 说明 |
|---|---|---|---|
GET | my | User | 列出当前用户可见的 Organization |
GET | get | Member | 读取 Organization 与当前 Membership |
POST | create | User | 创建 Organization 并成为 Owner |
POST | update | Owner/Admin | 修改名称 |
POST | archive | Owner | 归档 Organization |
GET | membership/get | Member | 读取当前 Membership |
GET | members/list | Member | 列出 active Membership |
POST | members/role | Owner | 设置 Admin 或 Member |
POST | members/remove | Owner/Admin | 移除可管理的成员 |
POST | members/leave | Admin/Member | 主动退出 |
POST | owner/transfer | Owner | 转移唯一 Owner |
POST | join-requests/create | User | 申请加入 |
POST | join-requests/cancel | Applicant | 取消 pending 申请 |
GET | join-requests/list | Owner/Admin | 列出 pending 申请 |
POST | join-requests/decide | Owner/Admin | 批准或拒绝申请 |
Organization Action
GET my
GET /v1/organizations/my默认只返回 active Organization。包含归档记录:
GET /v1/organizations/my?include_archived=true返回 { "items": UserOrganization[] }。Federation Organization 在任意 Token Bureau 可见;Bureau Organization 只在当前 Token Bureau 匹配时可见。
GET get
GET /v1/organizations/get?organization_id=org_01J...要求 active Membership,返回 { organization, membership }。成员可以读取 archived Organization,但不能继续治理写入。
POST create
创建全局 Organization:
{
"name": "Genesis Research",
"scope_type": "federation"
}创建当前 Bureau Organization:
{
"name": "Genesis Research",
"scope_type": "bureau"
}Service 返回 { organization, membership },Membership 是唯一 Owner。名称去除首尾空白后必须为 1–120 个字符。
POST update
{
"organization_id": "org_01J...",
"name": "New Name"
}Owner/Admin 可修改名称。Organization 作用域创建后不能修改。
POST archive
{ "organization_id": "org_01J..." }Owner 可执行。归档不可恢复,会停止治理写入并释放 Owner 额度。Membership 和 Join Request 历史保留。
Membership Action
GET membership/get
GET /v1/organizations/membership/get?organization_id=org_01J...返回 { organization, membership }。Bureau 可以携带用户提交的同一个 user_token 调用此接口。被移除的用户返回 403 NOT_AN_ORGANIZATION_MEMBER。
GET members/list
GET /v1/organizations/members/list?organization_id=org_01J...返回 { "items": Membership[] },只包含 active Membership。
POST members/role
{
"organization_id": "org_01J...",
"membership_id": "mem_01J...",
"role": "admin"
}Owner 可将非 Owner 成员设置为 admin 或 member。转移 Owner 使用 owner/transfer。
POST members/remove
{
"organization_id": "org_01J...",
"membership_id": "mem_01J..."
}Owner 可以移除 Admin 或 Member;Admin 只能移除 Member。唯一 Owner 不能被移除。
POST members/leave
{ "organization_id": "org_01J..." }Admin 和 Member 可以退出。Owner 必须先转移所有权。
POST owner/transfer
{
"organization_id": "org_01J...",
"membership_id": "mem_new_owner"
}目标必须是 active Member,并且还有 Owner 额度。原 Owner 变为 Admin。
Join Request Action
POST join-requests/create
{ "organization_id": "org_01J..." }用户通过已知 ID 申请加入。重复申请返回同一个 pending 记录。已有 active Membership 时返回 { state: "joined", organization, membership }。
POST join-requests/cancel
{ "request_id": "join_01J..." }申请人可以取消自己的 pending 申请。
GET join-requests/list
GET /v1/organizations/join-requests/list?organization_id=org_01J...Owner/Admin 调用,返回 pending Join Request。
POST join-requests/decide
{
"request_id": "join_01J...",
"decision": "approved"
}decision 接受 approved 或 rejected。批准时,Service 在同一事务中创建新的 Member Membership。
错误
| HTTP | Code | 含义 |
|---|---|---|
400 | ORGANIZATION_INPUT_INVALID | 名称、ID、角色或决策无效 |
400 | ORGANIZATION_SCOPE_INVALID | scope_type 无效 |
401 | AUTH_REQUIRED | 缺少有效用户身份 |
403 | ORGANIZATION_BUREAU_MISMATCH | Token Bureau 不能访问该 Bureau Organization |
403 | NOT_AN_ORGANIZATION_MEMBER | 当前用户没有 active Membership |
403 | ORGANIZATION_ROLE_DENIED | 治理角色不允许操作 |
404 | ORGANIZATION_NOT_FOUND | Organization 不存在 |
404 | ORGANIZATION_MEMBERSHIP_NOT_FOUND | Membership 不存在或已失效 |
404 | JOIN_REQUEST_NOT_FOUND | Join Request 不存在或不可操作 |
409 | ORGANIZATION_LIMIT_REACHED | Owner 额度已满 |
409 | OWNER_TRANSFER_REQUIRED | 必须先转移 Owner |
410 | ORGANIZATION_ARCHIVED | Organization 已归档 |
客户端应按 error.code 分支,不要依赖错误文本。