Skip to content

Commit 060a497

Browse files
committed
refactor(app): slim portal controllers and sync backend findings
1 parent 64cd2e9 commit 060a497

22 files changed

Lines changed: 1290 additions & 852 deletions

docs/02-domain-model.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@
7777

7878
- 唯一约束:`(namespace_id, slug)`
7979
- `status` 表示 skill 容器生命周期,不再承载“隐藏”语义。隐藏是独立的治理覆盖层,由 `hidden` / `hidden_at` / `hidden_by` 表达
80+
- 当前代码下的实际可见性判定以 `VisibilityChecker` 为准,规则如下:
81+
-`hidden=true`:仅 skill owner 或该 namespace 的 `ADMIN` / `OWNER` 可读
82+
-`latest_version_id is null`:仅 skill owner 可读;即使 `visibility=PUBLIC` 也不会对外公开
83+
- `PUBLIC`:任意人可读 skill 容器与已发布版本
84+
- `NAMESPACE_ONLY`:该 namespace 任意成员可读(`MEMBER` / `ADMIN` / `OWNER`
85+
- `PRIVATE`:仅 skill owner 或该 namespace 的 `ADMIN` / `OWNER` 可读,普通 `MEMBER` 不可读
8086
- `owner_id` 语义为"主要维护人",可转让。权限主轴是 namespace role,不是 owner:
8187
- namespace ADMIN 对空间内所有 skill 有完整管理权(归档、版本管理、提升到全局),不受 owner 限制
8288
- owner 作为 MEMBER 时可管理自己创建的 skill(提交审核、编辑草稿)
@@ -113,6 +119,12 @@
113119
- 已发布撤回:`PUBLISHED → YANKED`
114120
- 唯一约束:`(skill_id, version)` 防止重复发布
115121
- `YANKED` 状态:已发布后撤回
122+
- 当前代码下的实际读权限补充:
123+
- 普通详情 / 下载 / resolve / tag / 文件读取,只接受 `PUBLISHED`
124+
- owner 可通过常规版本详情预览自己的 `PENDING_REVIEW` 版本
125+
- owner / namespace `ADMIN` / `OWNER` 在版本列表中可看到全部五种状态:`PUBLISHED / PENDING_REVIEW / DRAFT / REJECTED / YANKED`
126+
- 但常规版本详情接口并不会放行 `DRAFT / REJECTED / YANKED`
127+
- 审核详情页走独立 review 读路径,可查看待审版本及完整版本快照
116128

117129
版本号不可变性规则:
118130

docs/03-authentication-design.md

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -396,14 +396,14 @@ API Token 仍保留,但定位从“CLI 唯一认证方式”调整为“平台
396396

397397
| 操作 | 所需权限 | 判定逻辑 |
398398
|------|---------|---------|
399-
| 提交发布审核 | `skill:publish` | 用户是该 namespace 的 MEMBER 以上,且 namespace 非 FROZEN |
399+
| 发布技能包 | `skill:publish` | 普通用户要求是目标 namespace 成员;`SUPER_ADMIN` 可绕过成员校验并直发 |
400+
| 提交已有版本进入审核 | `review:submit` | owner 本人,或 namespace `ADMIN` / `OWNER`,或 `SKILL_ADMIN` / `SUPER_ADMIN` |
400401
| 管理技能(归档/版本管理) | `skill:manage` | namespace ADMIN 以上,或 owner 本人 |
401402
| 提升到全局 | `skill:promote` | namespace ADMIN 以上,或 owner 本人 |
402-
| 审核团队空间技能 | `review:approve` | 该 namespace 的 ADMIN 或 OWNER |
403-
| 审核全局空间技能 | `review:approve` | 持有 SKILL_ADMIN / SUPER_ADMIN |
403+
| 审核技能发布 | `review:approve` | namespace `ADMIN` / `OWNER`,或 `SKILL_ADMIN` / `SUPER_ADMIN`;提交人本人仅 `SUPER_ADMIN` 可审核自己的 review task |
404404
| 审核提升申请 | `promotion:approve` | 持有 SKILL_ADMIN / SUPER_ADMIN |
405-
| 隐藏/恢复技能 | `skill:manage` | 持有 SKILL_ADMIN / SUPER_ADMIN |
406-
| 撤回已发布版本(YANK) | `skill:manage` | 持有 SKILL_ADMIN / SUPER_ADMIN |
405+
| 隐藏/恢复技能 | `skill:manage` | `SUPER_ADMIN` |
406+
| 撤回已发布版本(YANK) | `skill:manage` | `SKILL_ADMIN` / `SUPER_ADMIN` |
407407
| 管理用户角色 | `user:manage` | 持有 USER_ADMIN / SUPER_ADMIN |
408408
| 审批用户准入 | `user:approve` | 持有 USER_ADMIN / SUPER_ADMIN |
409409
| 查看审计日志 | `audit:read` | 持有 AUDITOR / SUPER_ADMIN |
@@ -417,14 +417,13 @@ API Token 仍保留,但定位从“CLI 唯一认证方式”调整为“平台
417417

418418
| API 路径 | 适用范围 | 权限要求 |
419419
|----------|---------|---------|
420-
| `POST /api/v1/admin/reviews/{id}/approve` | 全局空间审核 | SKILL_ADMIN / SUPER_ADMIN |
421-
| `POST /api/v1/admin/promotions/{id}/approve` | 提升到全局审核 | SKILL_ADMIN / SUPER_ADMIN |
422-
| `POST /api/v1/namespaces/{slug}/reviews/{id}/approve` | 团队空间内发布审核 | 该空间 ADMIN / OWNER |
420+
| `POST /api/v1/reviews/{id}/approve` | 技能发布审核 | namespace `ADMIN` / `OWNER`,或 `SKILL_ADMIN` / `SUPER_ADMIN` |
421+
| `POST /api/v1/promotions/{id}/approve` | 提升到全局审核 | `SKILL_ADMIN` / `SUPER_ADMIN` |
423422
| `GET /api/v1/admin/audit-logs` | 审计日志查询 | AUDITOR / SUPER_ADMIN |
424423
| `PUT /api/v1/admin/users/{id}/roles` | 用户角色管理 | USER_ADMIN / SUPER_ADMIN |
425424
| `POST /api/v1/admin/users/{id}/approve` | 用户准入审批 | USER_ADMIN / SUPER_ADMIN |
426425

427-
SUPER_ADMIN 和持有对应角色的用户均可通过 Admin API 操作;团队空间审核限定通过 Namespace API 完成,平台管理员不越权进入团队空间审核流程
426+
当前实现中,审核与提升都走统一 portal API;是否允许操作由服务层根据 namespace role 与 platform role 联合判定,而不是靠分叉路由表达
428427

429428
## 7. Session 设计
430429

@@ -587,11 +586,11 @@ window.location.href = '/oauth2/authorization/github'
587586

588587
| 接口 | 匿名 | 已登录 | 判定逻辑 |
589588
|------|------|--------|---------|
590-
| `GET /api/v1/skills`(搜索) | PUBLIC 技能 | PUBLIC + NAMESPACE_ONLY(成员空间)+ PRIVATE(owner/admin) | `SearchVisibilityScope` 投影 |
591-
| `GET /api/v1/skills/{ns}/{slug}` | PUBLIC 技能 | 同上 | visibility + namespace 成员关系 |
592-
| `GET /api/v1/skills/{ns}/{slug}/versions` | PUBLIC 技能 | 同上 | 同上 |
593-
| `GET /api/v1/skills/{ns}/{slug}/download` | PUBLIC 技能 | 同上 | 同上 |
594-
| `GET /api/v1/skills/{ns}/{slug}/resolve` | PUBLIC 技能 | 同上 | 同上 |
589+
| `GET /api/v1/skills`(搜索) | `PUBLIC`,且仅搜索 `ACTIVE`、非 hidden、已索引 skill | `PUBLIC + NAMESPACE_ONLY(成员空间)+ PRIVATE(owner/admin)` | `SearchVisibilityScope` + 搜索索引状态 |
590+
| `GET /api/v1/skills/{ns}/{slug}` | 仅已发布且可见的 `PUBLIC` skill | 同左,另加 owner 可读未发布 skill、namespace `ADMIN` / `OWNER` 可读 hidden | `visibility + latest_version_id + hidden + namespace 成员关系` |
591+
| `GET /api/v1/skills/{ns}/{slug}/versions` | `PUBLISHED` 版本 | owner / namespace `ADMIN` / `OWNER` 可见全部五种状态 | 同上 + version status 过滤 |
592+
| `GET /api/v1/skills/{ns}/{slug}/download` | 仅全局 namespace 下的 `PUBLIC` skill 支持匿名下载 | 已登录后按 visibility 判定;下载目标版本必须是 `PUBLISHED` | visibility + namespace type + version status |
593+
| `GET /api/v1/skills/{ns}/{slug}/resolve` | 仅全局 namespace 下的 `PUBLIC` skill 可匿名 | 同上 | visibility + namespace type + version status |
595594
| `GET /api/v1/namespaces` | 全部 | 全部 | 无限制 |
596595

597596
### 10.2 Authenticated API
@@ -600,27 +599,27 @@ window.location.href = '/oauth2/authorization/github'
600599
|------|---------|---------|
601600
| `POST /api/v1/skills/{ns}/{slug}/star` | 已登录 | Session/Token |
602601
| `POST /api/v1/skills/{ns}/{slug}/rating` | 已登录 | Session/Token |
603-
| `POST .../versions/{ver}/submit-review` | namespace MEMBER 以上 | `namespace_member.role` |
602+
| `POST /api/v1/reviews` | owner 本人,或 namespace `ADMIN` / `OWNER`,或 `SKILL_ADMIN` / `SUPER_ADMIN` | `skill.owner_id` / `namespace_member.role` / platform roles |
604603
| `POST .../versions/{ver}/withdraw-review` | 提交人本人 | `review_task.submitted_by` |
605604
| `PUT /api/v1/skills/{ns}/{slug}/tags/{tag}` | namespace ADMIN 以上 或 owner | `namespace_member.role``skill.owner_id` |
606605
| `POST /api/v1/skills/{ns}/{slug}/archive` | namespace ADMIN 以上 或 owner | `namespace_member.role``skill.owner_id` |
607-
| `DELETE .../versions/{ver}` | namespace ADMIN 以上 或 owner(仅 DRAFT/REJECTED) | `namespace_member.role``skill.owner_id` + `skill_version.status` |
606+
| `POST .../versions/{ver}/rerelease` | namespace ADMIN 以上 或 owner;源版本必须 `PUBLISHED` | `namespace_member.role``skill.owner_id` + `skill_version.status` |
607+
| `DELETE .../versions/{ver}` | namespace ADMIN 以上 或 owner(仅 `DRAFT` / `REJECTED`| `namespace_member.role``skill.owner_id` + `skill_version.status` |
608608

609609
### 10.3 CLI API
610610

611611
| 接口 | 所需凭证 | 额外判定 |
612612
|------|---------|---------|
613613
| `GET /api/v1/whoami` | 任意有效 Bearer Token ||
614-
| `POST /api/v1/publish` | Bearer Token + `skill:publish` | 用户是目标 namespace 的 MEMBER 以上 |
614+
| `POST /api/v1/publish` | Bearer Token + `skill:publish` | 普通用户要求目标 namespace 成员;`SUPER_ADMIN` 可绕过 |
615615

616616
### 10.4 Admin API
617617

618618
| 接口 | 所需平台角色 | 判定来源 |
619619
|------|------------|---------|
620-
| `POST /api/v1/admin/reviews/{id}/approve` | SKILL_ADMIN / SUPER_ADMIN | `user_role_binding``role_permission` |
621-
| `POST /api/v1/admin/reviews/{id}/reject` | SKILL_ADMIN / SUPER_ADMIN | 同上 |
622-
| `POST /api/v1/admin/promotions/{id}/approve` | SKILL_ADMIN / SUPER_ADMIN | 同上 |
623-
| `POST /api/v1/admin/promotions/{id}/reject` | SKILL_ADMIN / SUPER_ADMIN | 同上 |
620+
| `POST /api/v1/admin/skills/{id}/hide` | SUPER_ADMIN | `user_role_binding``role_permission` |
621+
| `POST /api/v1/admin/skills/{id}/unhide` | SUPER_ADMIN | 同上 |
622+
| `POST /api/v1/admin/skills/versions/{versionId}/yank` | SKILL_ADMIN / SUPER_ADMIN | 同上 |
624623
| `PUT /api/v1/admin/users/{id}/roles` | USER_ADMIN / SUPER_ADMIN | 同上,且 USER_ADMIN 不可分配 SUPER_ADMIN |
625624
| `POST /api/v1/admin/users/{id}/approve` | USER_ADMIN / SUPER_ADMIN | 同上 |
626625
| `POST /api/v1/admin/users/{id}/ban` | USER_ADMIN / SUPER_ADMIN | 同上 |
@@ -630,18 +629,16 @@ window.location.href = '/oauth2/authorization/github'
630629

631630
| 接口 | 所需 namespace 角色 | 判定来源 |
632631
|------|-------------------|---------|
633-
| `POST /api/v1/namespaces/{slug}/reviews/{id}/approve` | 该空间 ADMIN / OWNER | `namespace_member.role` |
634-
| `POST /api/v1/namespaces/{slug}/reviews/{id}/reject` | 该空间 ADMIN / OWNER | `namespace_member.role` |
635632
| `POST /api/v1/namespaces/{slug}/members` | 该空间 ADMIN 以上 | `namespace_member.role` |
636633
| `DELETE /api/v1/namespaces/{slug}/members/{userId}` | 该空间 ADMIN 以上 | `namespace_member.role` |
637-
| `POST .../skills/{skillId}/promote` | 该空间 ADMIN 以上 或 owner | `namespace_member.role``skill.owner_id` |
634+
| `POST /api/v1/promotions` | 该空间 ADMIN 以上 或 owner | `namespace_member.role``skill.owner_id` |
638635

639636
### 10.6 Compatibility API(Bearer Token 认证)
640637

641638
| 接口 | 所需凭证 | 额外判定 |
642639
|------|---------|---------|
643640
| `GET /api/v1/whoami` | 任意有效 Bearer Token ||
644641
| `GET /api/v1/search` | 可选(匿名限 PUBLIC) | `SearchVisibilityScope` |
645-
| `GET /api/v1/resolve` | 可选(匿名限 PUBLIC) | visibility |
646-
| `GET /api/v1/download/{slug}/{version}` | 可选(匿名限 PUBLIC) | visibility |
647-
| `POST /api/v1/publish` | Bearer Token + `skill:publish` | 用户是目标 namespace 的 MEMBER 以上(namespace 由 canonical slug 解析) |
642+
| `GET /api/v1/resolve` | 可选(匿名仅限全局 namespace 下的 PUBLIC) | visibility + namespace type + version status |
643+
| `GET /api/v1/download/{slug}/{version}` | 可选(匿名仅限全局 namespace 下的 PUBLIC) | visibility + namespace type + version status |
644+
| `POST /api/v1/publish` | Bearer Token + `skill:publish` | 普通用户要求目标 namespace 成员;`SUPER_ADMIN` 可绕过(namespace 由 canonical slug 解析) |

docs/05-business-flows.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959

6060
- `headlineVersion`:当前详情页/我的技能列表主展示版本
6161
- `publishedVersion`:当前最新可公开分发的已发布版本
62-
- `ownerPreviewVersion`:owner namespace 管理者可见的待审核版本
62+
- `ownerPreviewVersion`详情 projection 中仅暴露给 owner / namespace 管理者的 `PENDING_REVIEW` 版本
6363
- `resolutionMode``PUBLISHED` / `OWNER_PREVIEW` / `NONE`
6464

6565
业务规则:
@@ -69,6 +69,51 @@
6969
- 推广到全局、安装命令、公开下载都只能绑定到 `publishedVersion`
7070
- `hidden` 是独立治理覆盖层,不属于 skill 生命周期状态机
7171

72+
### 1.3 Skill 可见性与角色访问矩阵
73+
74+
以下矩阵以当前后端实现为准,综合了 `VisibilityChecker``SkillQueryService``SkillDownloadService``ReviewPermissionChecker` 的实际行为。
75+
76+
#### 1.3.1 Skill 容器读取
77+
78+
| 角色 | PUBLIC | NAMESPACE_ONLY | PRIVATE | hidden 任意 visibility |`publishedVersion``latest_version_id=null`|
79+
|------|--------|----------------|---------|------------------------|-----------------------------------------------|
80+
| 匿名用户 | 可读 | 不可读 | 不可读 | 不可读 | 不可读 |
81+
| 登录非成员 | 可读 | 不可读 | 不可读 | 不可读 | 不可读 |
82+
| namespace MEMBER | 可读 | 可读 | 不可读 | 不可读 | 仅自己是 owner 时可读 |
83+
| skill owner | 可读 | 可读 | 可读 | 可读 | 可读 |
84+
| namespace ADMIN / OWNER | 可读 | 可读 | 可读 | 可读 | 不可读,除非本人也是 skill owner |
85+
| SKILL_ADMIN / SUPER_ADMIN(仅平台角色) | 与普通登录用户一致;普通读路径不会因为平台角色自动穿透 private / hidden / unpublished |
86+
87+
补充:
88+
- `hidden=true` 时,可读权限会收敛为“skill owner 或 namespace `ADMIN` / `OWNER`
89+
- `visibility=PUBLIC` 也不意味着未发布 skill 可见;当 `latest_version_id` 为空时,只有 owner 能读
90+
91+
#### 1.3.2 Version 状态读取
92+
93+
| 场景 / 角色 | DRAFT | PENDING_REVIEW | PUBLISHED | REJECTED | YANKED |
94+
|------------|-------|----------------|-----------|----------|--------|
95+
| 普通 skill 详情页主版本投影 | 不展示 | owner / namespace 管理者可作为 `ownerPreviewVersion` 展示 | 展示 | 不展示 | 不展示 |
96+
| 普通 `listVersions` 访客 | 不可见 | 不可见 | 可见 | 不可见 | 不可见 |
97+
| `listVersions` 的 owner / namespace ADMIN / OWNER | 可见 | 可见 | 可见 | 可见 | 可见 |
98+
| 常规 `getVersionDetail` | 不可读 | 仅 owner 可读 | 可读 | 不可读 | 不可读 |
99+
| 下载 / resolve / tag / 文件读取 | 不可用 | 不可用 | 可用 | 不可用 | 不可用 |
100+
| review 详情页 | 可见完整快照 | 可见完整快照 | 可见完整快照 | 可见完整快照 | 可见完整快照 |
101+
102+
补充:
103+
- `YANKED` 版本仍出现在管理视角的版本列表中,但不可下载
104+
- `yank` 当前最新已发布版本时,会重算 `latest_version_id` 指向下一个最新的 `PUBLISHED` 版本;若没有,则置空
105+
106+
#### 1.3.3 审核 / 推广 / 治理动作
107+
108+
| 角色 | 发布新版本 | 提交审核 | 审核团队空间 | 审核全局空间 | 提交推广 | 审核推广 | hide / unhide | yank 已发布版本 |
109+
|------|------------|----------|--------------|--------------|----------|----------|---------------|----------------|
110+
| 匿名用户 | 不可 | 不可 | 不可 | 不可 | 不可 | 不可 | 不可 | 不可 |
111+
| namespace MEMBER | 可发布到所属 namespace;新版本进入 `PENDING_REVIEW` | 自己作为 owner 时可;不能代别人提审 | 不可 | 不可 | 自己作为 owner 时可 | 不可 | 不可 | 不可 |
112+
| skill owner ||| 不可 | 不可 || 不可 | 不可 | 不可 |
113+
| namespace ADMIN / OWNER || 可为本空间 skill 提交审核 || 不可 || 不可 | 不可 | 不可 |
114+
| SKILL_ADMIN | 可提交并可代提审;但普通发布仍非直发 ||||| 可,但不能审自己的 promotion | 不可 ||
115+
| SUPER_ADMIN | 可跨 namespace 发布且直接 `PUBLISHED`,跳过 membership 检查和 review task ||||| 可;review 场景下还能审自己的提交 |||
116+
72117
### 对象存储写入策略
73118

74119
一期同步写入正式路径,不使用临时区:

0 commit comments

Comments
 (0)