@yss123/cage-admin 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -2
  3. package/dist/bootstrap.d.ts +17 -0
  4. package/dist/bootstrap.js +43 -0
  5. package/dist/bootstrap.js.map +1 -0
  6. package/dist/catalog.d.ts +43 -0
  7. package/dist/catalog.js +91 -0
  8. package/dist/catalog.js.map +1 -0
  9. package/dist/domain/constraints.d.ts +9 -0
  10. package/dist/domain/constraints.js +61 -0
  11. package/dist/domain/constraints.js.map +1 -0
  12. package/dist/domain/index.d.ts +1 -0
  13. package/dist/domain/index.js +5 -0
  14. package/dist/domain/index.js.map +1 -0
  15. package/dist/domain/org.d.ts +387 -0
  16. package/dist/domain/org.js +238 -0
  17. package/dist/domain/org.js.map +1 -0
  18. package/dist/http.d.ts +4 -0
  19. package/dist/http.js +150 -0
  20. package/dist/http.js.map +1 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.js +8 -0
  23. package/dist/index.js.map +1 -0
  24. package/package.json +49 -3
  25. package/ui/dist/app/shell.js +110 -0
  26. package/ui/dist/app.js +24 -0
  27. package/ui/dist/modules/audit/audit-page.js +95 -0
  28. package/ui/dist/modules/audit/index.js +1 -0
  29. package/ui/dist/modules/auth/index.js +1 -0
  30. package/ui/dist/modules/auth/login-page.js +30 -0
  31. package/ui/dist/modules/operations/index.js +2 -0
  32. package/ui/dist/modules/operations/operations-page.js +95 -0
  33. package/ui/dist/modules/operations/sync-page.js +48 -0
  34. package/ui/dist/modules/org/index.js +1 -0
  35. package/ui/dist/modules/org/org-page.js +213 -0
  36. package/ui/dist/modules/roles/index.js +1 -0
  37. package/ui/dist/modules/roles/roles-page.js +308 -0
  38. package/ui/dist/modules/tasks/index.js +1 -0
  39. package/ui/dist/modules/tasks/tasks-page.js +60 -0
  40. package/ui/dist/shared/api.js +84 -0
  41. package/ui/dist/shared/dom.js +103 -0
  42. package/ui/dist/shared/labels.js +55 -0
  43. package/ui/dist/shared/navigation.js +7 -0
  44. package/ui/dist/shared/types.js +1 -0
  45. package/ui/index.html +14 -0
  46. package/ui/style.css +1577 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 shunshunyue and Cage contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,50 @@
1
- # Temporary Holding Version
1
+ # @yss123/cage-admin
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 组织模型声明与 /admin 系统管理
4
+
5
+ Cage 是通过 TypeScript 声明业务、由框架统一执行权限和数据规则的中后台框架。此包是框架的一部分。
6
+
7
+ ## 使用
8
+
9
+ ```powershell
10
+ pnpm add @yss123/cage-admin
11
+ ```
12
+
13
+ 首次使用建议通过脚手架创建完整项目,所需依赖由模板统一配置。需要 Node.js 24 或更新版本。
14
+
15
+ ## 中文管理界面
16
+
17
+ 启动 API 后访问 `/admin/`。页面包含审批待办、用户与部门、角色与授权、操作审计、异步任务和第三方同步。角色页按业务对象分组展示权限,支持中文或代码搜索;操作权限即时保存,数据范围与审批额度需要点击各自的保存按钮。中文显示不改变真实权限标识,也不会自动给角色增加权限。
18
+
19
+ 业务聚合和命令应填写中文 `description`。项目根目录 `cage.config.json` 的 `graph.labels` 同时用于图谱和系统管理,无需再维护一份翻译:
20
+
21
+ ```json
22
+ {
23
+ "graph": {
24
+ "labels": {
25
+ "aggregate:PurchaseOrder": "采购单",
26
+ "command:PurchaseOrder.submit": "提交审批",
27
+ "capability:PurchaseOrder.export": "导出采购单",
28
+ "approval:poApproval": "采购审批流程",
29
+ "event:OrderSubmitted": "采购单已提交",
30
+ "job:expireStaleOrders": "清理过期草稿"
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ 以上是合并进已有配置的片段,不要覆盖项目中的 domain、contracts 等设置。修改显示名后重启 API。API 进程应在项目根目录启动;Docker 模板也会复制这份配置到运行时镜像。
37
+
38
+ 名称优先级:权限专用 `capability:` → `command:` → 命令 `description` → 常用动作中文;业务对象使用 `aggregate:` → 聚合 `description`。read/export 会自动组合对象中文名,敏感字段明文权限和调用方也会显示中文。框架无法凭代码猜测自定义业务术语,缺少中文时需要在声明或配置中补充。
39
+
40
+ 直接集成 HTTP 服务时,也可以通过 `createServer({ domain, adminLabels: { 'aggregate:Document': '业务单据' } })` 提供显示名;它覆盖本地 `graph.labels`。此选项属于 `@yss123/cage-http`,不是领域授权配置。
41
+
42
+ ## 维护管理前端
43
+
44
+ `ui/src/app` 负责页面组合,`ui/src/modules` 按管理功能组织,`ui/src/shared` 放请求、标签和 DOM 组件。界面由 TypeScript 编译成原生浏览器模块,不要求业务项目使用特定前端框架。执行 `pnpm build` 同时构建接口与界面;发布时分发 `ui/dist`、HTML 和 CSS,不直接执行 TypeScript 源码。
45
+
46
+ - [完整使用说明](https://github.com/shunshunyue/cage/blob/main/docs/使用说明.md)
47
+ - [框架源码与范例](https://github.com/shunshunyue/cage)
48
+ - [问题反馈](https://github.com/shunshunyue/cage/issues)
49
+
50
+ 许可证:[MIT](https://github.com/shunshunyue/cage/blob/main/LICENSE)。
@@ -0,0 +1,17 @@
1
+ import { type Kernel } from '@yss123/cage-kernel';
2
+ export interface BootstrapResult {
3
+ created: boolean;
4
+ username?: string;
5
+ password?: string;
6
+ rootDeptId?: string;
7
+ superadminRoleId?: string;
8
+ }
9
+ export declare function bootstrapOrg(k: Kernel, opts?: {
10
+ tenantId?: string;
11
+ adminUsername?: string;
12
+ adminPassword?: string;
13
+ rootDeptName?: string;
14
+ }): Promise<BootstrapResult>;
15
+ /** 把能力目录里的全部能力授给某个角色(cage dev 在声明新增命令后调用,生产环境由管理员在 /admin 操作) */
16
+ export declare function grantAll(k: Kernel, roleId: string, tenantId?: string): Promise<number>;
17
+ export declare function grantAllToSuperadmin(k: Kernel, tenantId?: string): Promise<number>;
@@ -0,0 +1,43 @@
1
+ // 初始化组织:第一次启动时建根部门、超级管理员角色和初始管理员账号。
2
+ // 超级管理员只是一个拥有全部能力、范围为 all 的角色,是数据而不是代码里的特例。
3
+ import { randomBytes } from 'node:crypto';
4
+ import { DEFAULT_TENANT, systemCtx } from '@yss123/cage-kernel';
5
+ function bootstrapCtx(k, tenantId) {
6
+ return systemCtx({ kind: 'system', name: 'bootstrap', tenantId, capabilities: k.catalogCaps() });
7
+ }
8
+ export async function bootstrapOrg(k, opts = {}) {
9
+ const tenantId = opts.tenantId ?? DEFAULT_TENANT;
10
+ const existing = await k.app.selectFrom('sys.user').select((eb) => eb.fn.countAll().as('n')).where('tenant_id', '=', tenantId).executeTakeFirst();
11
+ if (Number(existing?.n ?? 0) > 0)
12
+ return { created: false };
13
+ const ctx = bootstrapCtx(k, tenantId);
14
+ const root = await k.execute('Dept.create', { name: opts.rootDeptName ?? '总部', code: 'root' }, ctx);
15
+ const role = await k.execute('Role.create', { code: 'superadmin', name: '超级管理员' }, ctx);
16
+ await grantAll(k, role.id, tenantId);
17
+ await k.execute('Role.setScope', { id: role.id, aggregate: '*', combinator: 'all' }, ctx);
18
+ const username = opts.adminUsername ?? 'admin';
19
+ const password = opts.adminPassword ?? randomBytes(9).toString('base64url');
20
+ const user = await k.execute('User.create', { username, name: '管理员', deptId: root.id }, ctx);
21
+ await k.execute('User.assignRoles', { id: user.id, roleIds: [role.id] }, ctx);
22
+ await k.execute('User.setPassword', { id: user.id, password }, ctx);
23
+ return { created: true, username, password, rootDeptId: root.id, superadminRoleId: role.id };
24
+ }
25
+ /** 把能力目录里的全部能力授给某个角色(cage dev 在声明新增命令后调用,生产环境由管理员在 /admin 操作) */
26
+ export async function grantAll(k, roleId, tenantId = DEFAULT_TENANT) {
27
+ const ctx = bootstrapCtx(k, tenantId);
28
+ const role = await k.app.selectFrom('sys.role').select('capabilities').where('id', '=', roleId).executeTakeFirst();
29
+ const have = new Set((role?.capabilities ?? []).map((c) => c.capability));
30
+ let n = 0;
31
+ for (const cap of k.catalogCaps()) {
32
+ if (have.has(cap))
33
+ continue;
34
+ await k.execute('Role.grantCapability', { id: roleId, capability: cap, params: cap.endsWith('.approve') ? { ceiling: 1_000_000_000 } : undefined }, ctx);
35
+ n++;
36
+ }
37
+ return n;
38
+ }
39
+ export async function grantAllToSuperadmin(k, tenantId = DEFAULT_TENANT) {
40
+ const r = await k.app.selectFrom('sys.role').select('id').where('code', '=', 'superadmin').where('tenant_id', '=', tenantId).executeTakeFirst();
41
+ return r ? grantAll(k, r.id, tenantId) : 0;
42
+ }
43
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type Registry } from '@yss123/cage-kernel';
2
+ /** 显示名沿用图谱的节点键;只影响文案,不重命名权限、命令、表或业务字段。 */
3
+ export type AdminLabels = Record<string, string>;
4
+ /**
5
+ * 展示目录独立于内核的授权目录。原始字段继续提供给 API 调用者,额外 label 专供界面使用。
6
+ * 自定义业务名称来自项目声明或 labels,框架不猜测客户术语;缺少中文时明确提示需要命名。
7
+ */
8
+ export declare function adminCatalog(registry: Registry, labels?: AdminLabels): {
9
+ capabilities: {
10
+ label: string;
11
+ capability: string;
12
+ kind: "command" | "read" | "export" | "unmask" | "system";
13
+ aggregate?: string;
14
+ description?: string;
15
+ invokedBy?: readonly string[];
16
+ }[];
17
+ aggregates: {
18
+ name: string;
19
+ description: string | null;
20
+ label: string;
21
+ states: readonly any[];
22
+ scope: {
23
+ deptField: string | null;
24
+ ownerField: string | null;
25
+ };
26
+ sensitive: Record<string, string>;
27
+ }[];
28
+ combinators: string[];
29
+ approvals: {
30
+ name: string;
31
+ process: string;
32
+ aggregate: string;
33
+ routable: readonly string[];
34
+ label: string;
35
+ }[];
36
+ jobs: {
37
+ name: string;
38
+ cron: string;
39
+ description: string | null;
40
+ label: string;
41
+ }[];
42
+ labels: AdminLabels;
43
+ };
@@ -0,0 +1,91 @@
1
+ import { sensitiveFields } from '@yss123/cage-kernel';
2
+ const actions = {
3
+ create: '新建',
4
+ read: '查看',
5
+ export: '导出',
6
+ update: '编辑',
7
+ rename: '修改名称',
8
+ delete: '删除',
9
+ archive: '停用',
10
+ enable: '启用',
11
+ disable: '停用',
12
+ submit: '提交',
13
+ approve: '审批通过',
14
+ reject: '驳回',
15
+ cancel: '取消',
16
+ revoke: '撤回',
17
+ confirm: '确认',
18
+ void: '作废',
19
+ receive: '确认收货',
20
+ markReceived: '确认收货',
21
+ recordErpNo: '回写外部单号',
22
+ acquire: '占用资源',
23
+ release: '释放资源',
24
+ assignRoles: '分配角色',
25
+ setPassword: '重置密码',
26
+ grantCapability: '授予操作权限',
27
+ revokeCapability: '收回操作权限',
28
+ setScope: '设置数据范围',
29
+ };
30
+ const sensitive = {
31
+ phone: '手机号',
32
+ email: '邮箱',
33
+ idCard: '身份证号',
34
+ bankCard: '银行卡号',
35
+ name: '姓名',
36
+ address: '地址',
37
+ };
38
+ /**
39
+ * 展示目录独立于内核的授权目录。原始字段继续提供给 API 调用者,额外 label 专供界面使用。
40
+ * 自定义业务名称来自项目声明或 labels,框架不猜测客户术语;缺少中文时明确提示需要命名。
41
+ */
42
+ export function adminCatalog(registry, labels = {}) {
43
+ const aggregates = registry.aggregates.map((a) => {
44
+ const label = labels[`aggregate:${a.name}`] || a.description || a.name;
45
+ return {
46
+ name: a.name,
47
+ description: a.description ?? null,
48
+ label,
49
+ states: a.states.values,
50
+ scope: { deptField: a.scope.deptField ?? null, ownerField: a.scope.ownerField ?? null },
51
+ sensitive: sensitiveFields(a),
52
+ };
53
+ });
54
+ const names = new Map(aggregates.map((a) => [a.name, a.label]));
55
+ const capabilities = registry.capabilityCatalog().map((c) => {
56
+ const subject = names.get(c.aggregate ?? '') ?? '';
57
+ const action = c.capability.split('.').at(-1);
58
+ const override = labels[`capability:${c.capability}`] || labels[`command:${c.capability}`];
59
+ // 内核的 read/export 文案可能含英文聚合名,重组后才能复用项目提供的中文名称。
60
+ const label = override ||
61
+ (c.kind === 'read'
62
+ ? `查看${subject}`
63
+ : c.kind === 'export'
64
+ ? `导出${subject}`
65
+ : c.kind === 'unmask'
66
+ ? `查看${sensitive[action] ?? '敏感字段'}明文`
67
+ : c.description || actions[action] || '自定义操作');
68
+ return { ...c, label };
69
+ });
70
+ return {
71
+ capabilities,
72
+ aggregates,
73
+ combinators: ['self', 'dept', 'deptSubtree', 'deptSet', 'all'],
74
+ approvals: registry.approvals.map(({ a, name }) => ({
75
+ name,
76
+ process: a.process,
77
+ aggregate: a.agg.name,
78
+ routable: a.routable,
79
+ label: labels[`approval:${name}`] || a.process,
80
+ })),
81
+ jobs: registry.jobs.map((j) => ({
82
+ name: j.name,
83
+ cron: j.cron,
84
+ description: j.description ?? null,
85
+ label: labels[`job:${j.name}`] || j.description || j.name,
86
+ })),
87
+ // 事件、状态和连接器也能复用图谱文案,供审计、待办和运维页面解释业务标识。
88
+ labels,
89
+ };
90
+ }
91
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type Constraint } from '@yss123/cage-kernel';
2
+ /** 只能授出能力目录里存在的能力点 */
3
+ export declare const knownCapability: () => Constraint;
4
+ /** 防提权:不能授出自己没有的能力点;数值参数(额度)不能超过自己的 */
5
+ export declare const noEscalation: () => Constraint;
6
+ /** 不能授出比自己更宽的数据范围 */
7
+ export declare const noWiderScope: () => Constraint;
8
+ /** 分配角色也是授权:被分配角色里的每个能力点和范围,操作人自己都必须有 */
9
+ export declare const noEscalationViaRoles: () => Constraint;
@@ -0,0 +1,61 @@
1
+ // 授权类命令的内置硬约束:代码里不存在「管理员跳过检查」的分支,超级管理员也一样要过这些约束。
2
+ import { COMBINATOR_WIDTH, ok, violation } from '@yss123/cage-kernel';
3
+ function ownWidth(ctx, aggregate) {
4
+ const grants = ctx.scopes[aggregate] ?? ctx.scopes['*'] ?? [{ combinator: 'self' }];
5
+ return Math.max(...grants.map((g) => COMBINATOR_WIDTH[g.combinator] ?? 0));
6
+ }
7
+ /** 只能授出能力目录里存在的能力点 */
8
+ export const knownCapability = () => ({
9
+ name: 'knownCapability',
10
+ check: (_role, _ctx, input, meta) => meta.catalog().includes(input.capability) ? ok() : violation(`[CAGE-GRANT-003] 能力点 ${input.capability} 不在能力目录里`),
11
+ });
12
+ /** 防提权:不能授出自己没有的能力点;数值参数(额度)不能超过自己的 */
13
+ export const noEscalation = () => ({
14
+ name: 'noEscalation',
15
+ check: (_role, ctx, input) => {
16
+ const mine = ctx.capabilities.get(input.capability);
17
+ if (!mine)
18
+ return violation('[CAGE-GRANT-001] 不能授出自己没有的能力点');
19
+ for (const [k, v] of Object.entries(input.params ?? {})) {
20
+ if (typeof v === 'number' && typeof mine[k] === 'number' && v > mine[k]) {
21
+ return violation(`[CAGE-GRANT-001] 参数 ${k}=${v} 超过了你自己的 ${mine[k]}`);
22
+ }
23
+ }
24
+ return ok();
25
+ },
26
+ });
27
+ /** 不能授出比自己更宽的数据范围 */
28
+ export const noWiderScope = () => ({
29
+ name: 'noWiderScope',
30
+ check: (_role, ctx, input) => {
31
+ if (!input.combinator)
32
+ return ok();
33
+ const want = COMBINATOR_WIDTH[input.combinator] ?? 99;
34
+ return want <= ownWidth(ctx, input.aggregate) ? ok() : violation('[CAGE-GRANT-002] 不能授出比自己更宽的数据范围');
35
+ },
36
+ });
37
+ /** 分配角色也是授权:被分配角色里的每个能力点和范围,操作人自己都必须有 */
38
+ export const noEscalationViaRoles = () => ({
39
+ name: 'noEscalationViaRoles',
40
+ check: async (user, ctx, input, meta) => {
41
+ const before = new Set(user.roleIds ?? []);
42
+ for (const rid of input.roleIds) {
43
+ if (before.has(rid))
44
+ continue;
45
+ const role = await meta.load('Role', rid);
46
+ if (!role)
47
+ continue; // 交给 handler 报 ROLE_NOT_FOUND
48
+ for (const c of role.capabilities ?? []) {
49
+ if (!ctx.capabilities.has(c.capability))
50
+ return violation(`[CAGE-GRANT-001] 角色 ${role.code} 含有你没有的能力点 ${c.capability}`);
51
+ }
52
+ for (const s of role.scopes ?? []) {
53
+ if ((COMBINATOR_WIDTH[s.combinator] ?? 99) > ownWidth(ctx, s.aggregate)) {
54
+ return violation(`[CAGE-GRANT-002] 角色 ${role.code} 在 ${s.aggregate} 上的范围比你更宽`);
55
+ }
56
+ }
57
+ }
58
+ return ok();
59
+ },
60
+ });
61
+ //# sourceMappingURL=constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.js","sourceRoot":"","sources":["../../src/domain/constraints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { Dept, User, Role, createDept, updateDept, archiveDept, createUser, updateUser, assignRoles, disableUser, enableUser, setPassword, createRole, renameRole, grantCapability, revokeCapability, setScope, archiveRole, } from './org.js';
@@ -0,0 +1,5 @@
1
+ // @yss123/cage-admin/domain:框架自带的组织模型声明。业务 domain 的 index.ts 里写一行
2
+ // export * from '@yss123/cage-admin/domain';
3
+ // 抽取器、内核、HTTP 层就都能看到部门、用户、角色。
4
+ export { Dept, User, Role, createDept, updateDept, archiveDept, createUser, updateUser, assignRoles, disableUser, enableUser, setPassword, createRole, renameRole, grantCapability, revokeCapability, setScope, archiveRole, } from './org.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,+CAA+C;AAC/C,8BAA8B;AAC9B,OAAO,EACL,IAAI,EAAE,IAAI,EAAE,IAAI,EAChB,UAAU,EAAE,UAAU,EAAE,WAAW,EACnC,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EACzE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,WAAW,GACjF,MAAM,UAAU,CAAC"}