@southwind-ai/modules 0.1.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.
@@ -0,0 +1,136 @@
1
+ import type { ModuleManifest } from "./manifest.js";
2
+
3
+ export const systemAdminRoutes: ModuleManifest["adminRoutes"] = [
4
+ route(
5
+ "system.profile",
6
+ "/admin/profile",
7
+ "个人设置",
8
+ "account",
9
+ "system.profile.read",
10
+ "system.profile",
11
+ ),
12
+ route(
13
+ "system.user",
14
+ "/admin/system/users",
15
+ "用户体系",
16
+ "sidebar",
17
+ "system.user.read",
18
+ "system.rbac",
19
+ ),
20
+ route(
21
+ "system.role",
22
+ "/admin/system/roles",
23
+ "权限策略",
24
+ "sidebar",
25
+ "system.role.read",
26
+ "system.rbac",
27
+ ),
28
+ route(
29
+ "system.department",
30
+ "/admin/system/departments",
31
+ "部门组织",
32
+ "sidebar",
33
+ "system.department.read",
34
+ "system.rbac",
35
+ ),
36
+ // @windy-module system.settings begin
37
+ {
38
+ ...route(
39
+ "system.settings",
40
+ "/admin/settings",
41
+ "全局设置",
42
+ "sidebar",
43
+ "system.admin.access",
44
+ "system.admin",
45
+ ),
46
+ directAccess: "admin-admission",
47
+ },
48
+ // @windy-module system.settings end
49
+ route(
50
+ "system.menu",
51
+ "/admin/system/menus",
52
+ "菜单管理",
53
+ "sidebar",
54
+ "system.menu.read",
55
+ "system.rbac",
56
+ ),
57
+ route(
58
+ "system.dictionary",
59
+ "/admin/system/dictionaries",
60
+ "字典管理",
61
+ "sidebar",
62
+ "system.dict.read",
63
+ "system.rbac",
64
+ ),
65
+ route(
66
+ "system.feature",
67
+ "/admin/system/features",
68
+ "功能开关",
69
+ "sidebar",
70
+ "system.feature.read",
71
+ ),
72
+ // @windy-module system.notification begin
73
+ route(
74
+ "system.notification",
75
+ "/admin/system/notifications",
76
+ "通知管理",
77
+ "sidebar",
78
+ "system.notification.manage",
79
+ "system.notification",
80
+ ),
81
+ // @windy-module system.notification end
82
+ // @windy-module system.configuration begin
83
+ route(
84
+ "system.config",
85
+ "/admin/system/configurations",
86
+ "配置版本",
87
+ "sidebar",
88
+ "system.config.read",
89
+ "system.config",
90
+ ),
91
+ // @windy-module system.configuration end
92
+ // @windy-module system.license begin
93
+ {
94
+ ...route(
95
+ "system.license",
96
+ "/admin/system/license",
97
+ "License",
98
+ "sidebar",
99
+ "system.license.read",
100
+ "system.license",
101
+ ),
102
+ directAccess: "authenticated",
103
+ },
104
+ // @windy-module system.license end
105
+ // @windy-module system.audit begin
106
+ route(
107
+ "system.audit",
108
+ "/admin/system/audit",
109
+ "审计日志",
110
+ "sidebar",
111
+ "system.audit.read",
112
+ "system.audit",
113
+ ),
114
+ // @windy-module system.audit end
115
+ // @windy-module system.operations begin
116
+ route(
117
+ "system.ops",
118
+ "/admin/system/operations",
119
+ "运维总览",
120
+ "sidebar",
121
+ "system.ops.read",
122
+ "system.ops",
123
+ ),
124
+ // @windy-module system.operations end
125
+ ];
126
+
127
+ function route(
128
+ key: string,
129
+ path: string,
130
+ title: string,
131
+ surface: ModuleManifest["adminRoutes"][number]["surface"],
132
+ permissionKey: string,
133
+ featureKey?: string,
134
+ ): ModuleManifest["adminRoutes"][number] {
135
+ return { key, path, title, surface, permissionKey, featureKey };
136
+ }
@@ -0,0 +1,28 @@
1
+ import type { ModuleManifest } from "./manifest.js";
2
+
3
+ export const systemAgentTools: ModuleManifest["tools"] = [
4
+ {
5
+ key: "system.users.list",
6
+ label: "查询用户",
7
+ description: "分页查询平台用户账号。",
8
+ permissionKey: "system.user.read",
9
+ featureKey: "system.rbac",
10
+ auditAction: "agent.tool.execute",
11
+ },
12
+ {
13
+ key: "system.features.list",
14
+ label: "查询功能开关",
15
+ description: "分页查询平台功能开关状态。",
16
+ permissionKey: "system.feature.read",
17
+ featureKey: "system.rbac",
18
+ auditAction: "agent.tool.execute",
19
+ },
20
+ {
21
+ key: "system.audit.list",
22
+ label: "查询审计日志",
23
+ description: "分页查询平台审计事件。",
24
+ permissionKey: "system.audit.read",
25
+ featureKey: "system.audit",
26
+ auditAction: "agent.tool.execute",
27
+ },
28
+ ];
@@ -0,0 +1,37 @@
1
+ import type { ApiPermissionBinding, HttpMethod } from "@southwind-ai/shared";
2
+
3
+ interface ResourceBindingInput {
4
+ path: string;
5
+ permissionResource: string;
6
+ featureKey?: string;
7
+ backupExport?: boolean;
8
+ }
9
+
10
+ export function resourceBindings(
11
+ input: ResourceBindingInput,
12
+ ): ApiPermissionBinding[] {
13
+ const base = `/api/system/${input.path}`;
14
+ const read = `system.${input.permissionResource}.read`;
15
+ const manage = `system.${input.permissionResource}.manage`;
16
+ return [
17
+ binding("GET", base, read, input.featureKey),
18
+ ...(input.backupExport === false
19
+ ? []
20
+ : [binding("GET", `${base}/export`, read, input.featureKey)]),
21
+ binding("GET", `${base}/:id`, read, input.featureKey),
22
+ binding("POST", `${base}/import`, manage, input.featureKey),
23
+ binding("POST", base, manage, input.featureKey),
24
+ binding("PUT", `${base}/:id`, manage, input.featureKey),
25
+ binding("DELETE", `${base}/:id`, manage, input.featureKey),
26
+ ];
27
+ }
28
+
29
+ export function binding(
30
+ method: HttpMethod,
31
+ path: string,
32
+ permissionKey: string,
33
+ featureKey?: string,
34
+ anonymous?: boolean,
35
+ ): ApiPermissionBinding {
36
+ return { method, path, permissionKey, featureKey, anonymous };
37
+ }
@@ -0,0 +1,21 @@
1
+ import type { ApiPermissionBinding } from "@southwind-ai/shared";
2
+ import { binding } from "./system-api-binding.js";
3
+ import { governedUserExportBindings } from "./system-governed-export-bindings.js";
4
+
5
+ export function dataGovernanceApiPermissionBindings(): ApiPermissionBinding[] {
6
+ return [
7
+ ...governedUserExportBindings(),
8
+ binding(
9
+ "GET",
10
+ "/api/system/users/:id/plaintext",
11
+ "system.user.reveal",
12
+ "system.rbac",
13
+ ),
14
+ binding(
15
+ "POST",
16
+ "/api/system/users/plaintext/batch",
17
+ "system.user.reveal",
18
+ "system.rbac",
19
+ ),
20
+ ];
21
+ }
@@ -0,0 +1,344 @@
1
+ import type { ApiPermissionBinding } from "@southwind-ai/shared";
2
+ import { binding, resourceBindings } from "./system-api-binding.js";
3
+ // @windy-module system.data-governance begin
4
+ import { dataGovernanceApiPermissionBindings } from "./system-api-data-governance.js";
5
+ // @windy-module system.data-governance end
6
+
7
+ export function systemApiPermissionBindings(): ApiPermissionBinding[] {
8
+ return [
9
+ binding(
10
+ "GET",
11
+ "/api/admin/bootstrap",
12
+ "system.admin.access",
13
+ "system.admin",
14
+ ),
15
+ binding("GET", "/api/foundation", "system.menu.read", "system.rbac", true),
16
+ // @windy-module system.search begin
17
+ binding(
18
+ "GET",
19
+ "/api/search/providers",
20
+ "system.search.read",
21
+ "system.search",
22
+ ),
23
+ binding("POST", "/api/search", "system.search.read", "system.search"),
24
+ // @windy-module system.search end
25
+ ...resourceBindings({
26
+ path: "users",
27
+ permissionResource: "user",
28
+ featureKey: "system.rbac",
29
+ backupExport: false,
30
+ }),
31
+ // @windy-module system.data-governance begin
32
+ ...dataGovernanceApiPermissionBindings(),
33
+ // @windy-module system.data-governance end
34
+ binding(
35
+ "POST",
36
+ "/api/auth/users/:id/password",
37
+ "system.user.manage",
38
+ "system.rbac",
39
+ ),
40
+ ...resourceBindings({
41
+ path: "roles",
42
+ permissionResource: "role",
43
+ featureKey: "system.rbac",
44
+ }),
45
+ ...resourceBindings({
46
+ path: "departments",
47
+ permissionResource: "department",
48
+ featureKey: "system.rbac",
49
+ }),
50
+ binding(
51
+ "POST",
52
+ "/api/system/departments/quick",
53
+ "system.department.create",
54
+ "system.rbac",
55
+ ),
56
+ binding("GET", "/api/system/menus", "system.menu.read", "system.rbac"),
57
+ binding(
58
+ "GET",
59
+ "/api/system/menus/export",
60
+ "system.menu.read",
61
+ "system.rbac",
62
+ ),
63
+ binding("GET", "/api/system/menus/:id", "system.menu.read", "system.rbac"),
64
+ binding(
65
+ "PUT",
66
+ "/api/system/menus/:id/placement",
67
+ "system.menu.manage",
68
+ "system.rbac",
69
+ ),
70
+ binding(
71
+ "PUT",
72
+ "/api/system/menus/placements",
73
+ "system.menu.manage",
74
+ "system.rbac",
75
+ ),
76
+ ...resourceBindings({
77
+ path: "dictionaries",
78
+ permissionResource: "dict",
79
+ featureKey: "system.rbac",
80
+ }),
81
+ // @windy-module system.license begin
82
+ ...resourceBindings({
83
+ path: "licenses",
84
+ permissionResource: "license",
85
+ featureKey: "system.license",
86
+ }),
87
+ // @windy-module system.license end
88
+ binding("GET", "/api/system/features", "system.feature.read"),
89
+ binding("GET", "/api/system/features/export", "system.feature.read"),
90
+ binding("GET", "/api/system/features/:id", "system.feature.read"),
91
+ binding("PUT", "/api/system/features/:id", "system.feature.manage"),
92
+ // @windy-module system.settings begin
93
+ binding(
94
+ "GET",
95
+ "/api/platform/branding",
96
+ "system.settings.read",
97
+ undefined,
98
+ true,
99
+ ),
100
+ binding(
101
+ "GET",
102
+ "/api/system/settings/branding",
103
+ "system.settings.read",
104
+ "system.settings",
105
+ ),
106
+ binding(
107
+ "PUT",
108
+ "/api/system/settings/branding",
109
+ "system.settings.manage",
110
+ "system.settings",
111
+ ),
112
+ // @windy-module system.settings end
113
+ // @windy-module system.configuration begin
114
+ binding(
115
+ "GET",
116
+ "/api/system/configurations",
117
+ "system.config.read",
118
+ "system.config",
119
+ ),
120
+ binding(
121
+ "GET",
122
+ "/api/system/configurations/:moduleKey/versions",
123
+ "system.config.read",
124
+ "system.config",
125
+ ),
126
+ binding(
127
+ "POST",
128
+ "/api/system/configurations/:moduleKey/versions",
129
+ "system.config.manage",
130
+ "system.config",
131
+ ),
132
+ binding(
133
+ "POST",
134
+ "/api/system/configurations/:moduleKey/versions/:version/rollback",
135
+ "system.config.manage",
136
+ "system.config",
137
+ ),
138
+ // @windy-module system.configuration end
139
+ binding(
140
+ "GET",
141
+ "/api/system/profile",
142
+ "system.profile.read",
143
+ "system.profile",
144
+ ),
145
+ binding(
146
+ "PUT",
147
+ "/api/system/profile",
148
+ "system.profile.manage",
149
+ "system.profile",
150
+ ),
151
+ // @windy-module system.audit begin
152
+ binding(
153
+ "GET",
154
+ "/api/system/audit-logs",
155
+ "system.audit.read",
156
+ "system.audit",
157
+ ),
158
+ binding(
159
+ "GET",
160
+ "/api/system/audit-logs/export",
161
+ "system.audit.read",
162
+ "system.audit",
163
+ ),
164
+ // @windy-module system.audit end
165
+ // @windy-module system.storage begin
166
+ binding(
167
+ "POST",
168
+ "/api/system/storage/uploads",
169
+ "system.storage.create",
170
+ "system.storage",
171
+ ),
172
+ binding(
173
+ "GET",
174
+ "/api/system/storage/uploads/:id",
175
+ "system.storage.create",
176
+ "system.storage",
177
+ ),
178
+ binding(
179
+ "PUT",
180
+ "/api/system/storage/uploads/:id/parts/:partNumber",
181
+ "system.storage.create",
182
+ "system.storage",
183
+ ),
184
+ binding(
185
+ "POST",
186
+ "/api/system/storage/uploads/:id/complete",
187
+ "system.storage.create",
188
+ "system.storage",
189
+ ),
190
+ binding(
191
+ "DELETE",
192
+ "/api/system/storage/uploads/:id",
193
+ "system.storage.create",
194
+ "system.storage",
195
+ ),
196
+ binding(
197
+ "GET",
198
+ "/api/system/storage/files/:id",
199
+ "system.storage.read",
200
+ "system.storage",
201
+ ),
202
+ binding(
203
+ "GET",
204
+ "/api/platform/files/:id",
205
+ "system.settings.read",
206
+ "system.settings",
207
+ true,
208
+ ),
209
+ // @windy-module system.storage end
210
+ // @windy-module system.operations begin
211
+ binding("GET", "/api/system/operations", "system.ops.read", "system.ops"),
212
+ // @windy-module system.operations end
213
+ // @windy-module system.notification begin
214
+ binding(
215
+ "GET",
216
+ "/api/notifications",
217
+ "system.notification.read",
218
+ "system.notification",
219
+ ),
220
+ binding(
221
+ "POST",
222
+ "/api/notifications/:id/read",
223
+ "system.notification.read",
224
+ "system.notification",
225
+ ),
226
+ binding(
227
+ "GET",
228
+ "/api/system/notifications",
229
+ "system.notification.manage",
230
+ "system.notification",
231
+ ),
232
+ binding(
233
+ "POST",
234
+ "/api/system/notifications",
235
+ "system.notification.manage",
236
+ "system.notification",
237
+ ),
238
+ binding(
239
+ "DELETE",
240
+ "/api/system/notifications/:id",
241
+ "system.notification.manage",
242
+ "system.notification",
243
+ ),
244
+ // @windy-module system.notification end
245
+ // @windy-module system.workflow begin
246
+ binding(
247
+ "GET",
248
+ "/api/workflow/work-items",
249
+ "system.workflow.read",
250
+ "system.workflow",
251
+ ),
252
+ binding(
253
+ "GET",
254
+ "/api/workflow/work-items/:id",
255
+ "system.workflow.read",
256
+ "system.workflow",
257
+ ),
258
+ binding(
259
+ "GET",
260
+ "/api/workflow/work-items/:id/history",
261
+ "system.workflow.read",
262
+ "system.workflow",
263
+ ),
264
+ binding(
265
+ "POST",
266
+ "/api/workflow/work-items",
267
+ "system.workflow.create",
268
+ "system.workflow",
269
+ ),
270
+ ...["claim", "transfer", "approve", "reject", "cancel"].map((command) =>
271
+ binding(
272
+ "POST",
273
+ `/api/workflow/work-items/:id/${command}`,
274
+ "system.workflow.approve",
275
+ "system.workflow",
276
+ ),
277
+ ),
278
+ // @windy-module system.workflow end
279
+ // @windy-module system.scheduler begin
280
+ binding(
281
+ "GET",
282
+ "/api/system/scheduled-tasks",
283
+ "system.scheduler.read",
284
+ "system.scheduler",
285
+ ),
286
+ binding(
287
+ "GET",
288
+ "/api/system/scheduled-task-runs",
289
+ "system.scheduler.read",
290
+ "system.scheduler",
291
+ ),
292
+ binding(
293
+ "GET",
294
+ "/api/system/operations/scheduler",
295
+ "system.scheduler.read",
296
+ "system.scheduler",
297
+ ),
298
+ binding(
299
+ "POST",
300
+ "/api/system/scheduled-tasks/:id/trigger",
301
+ "system.scheduler.manage",
302
+ "system.scheduler",
303
+ ),
304
+ binding(
305
+ "POST",
306
+ "/api/system/scheduled-tasks/:id/runs/:runId/recover",
307
+ "system.scheduler.manage",
308
+ "system.scheduler",
309
+ ),
310
+ // @windy-module system.scheduler end
311
+ // @windy-module system.bulk-data begin
312
+ binding(
313
+ "GET",
314
+ "/api/system/bulk-data/jobs",
315
+ "system.dict.read",
316
+ "system.bulk-data",
317
+ ),
318
+ binding(
319
+ "GET",
320
+ "/api/system/bulk-data/jobs/:id",
321
+ "system.dict.read",
322
+ "system.bulk-data",
323
+ ),
324
+ binding(
325
+ "GET",
326
+ "/api/system/bulk-data/jobs/:id/artifacts/:kind",
327
+ "system.dict.read",
328
+ "system.bulk-data",
329
+ ),
330
+ binding(
331
+ "POST",
332
+ "/api/system/bulk-data/dictionaries/import",
333
+ "system.dict.manage",
334
+ "system.bulk-data",
335
+ ),
336
+ binding(
337
+ "POST",
338
+ "/api/system/bulk-data/dictionaries/export",
339
+ "system.dict.read",
340
+ "system.bulk-data",
341
+ ),
342
+ // @windy-module system.bulk-data end
343
+ ];
344
+ }
@@ -0,0 +1,70 @@
1
+ import type { ModuleManifest } from "./manifest.js";
2
+
3
+ export const systemAuditActions: ModuleManifest["auditActions"] = [
4
+ "auth.login",
5
+ "auth.password.update",
6
+ "auth.session.revoke",
7
+ "user.profile.update",
8
+ "crud.create",
9
+ "crud.update",
10
+ "crud.delete",
11
+ // @windy-module system.configuration begin
12
+ "config.update",
13
+ "config.rollback",
14
+ // @windy-module system.configuration end
15
+ // @windy-module system.license begin
16
+ "license.verify",
17
+ // @windy-module system.license end
18
+ "feature.update",
19
+ "menu.structure.update",
20
+ // @windy-module system.notification begin
21
+ "notification.publish",
22
+ "notification.read",
23
+ "notification.archive",
24
+ // @windy-module system.notification end
25
+ // @windy-module system.workflow begin
26
+ "workflow.create",
27
+ "workflow.claim",
28
+ "workflow.transfer",
29
+ "workflow.decide",
30
+ "workflow.cancel",
31
+ "workflow.timeout",
32
+ // @windy-module system.workflow end
33
+ // @windy-module system.scheduler begin
34
+ "task.trigger",
35
+ "task.read",
36
+ "task.execute",
37
+ "task.recover",
38
+ // @windy-module system.scheduler end
39
+ // @windy-module system.search begin
40
+ "data.search",
41
+ // @windy-module system.search end
42
+ // @windy-module system.data-governance begin
43
+ "data.plaintext.read",
44
+ "data.plaintext.batch-read",
45
+ "data.governed-export.request",
46
+ "data.governed-export.generate",
47
+ "data.governed-export.download",
48
+ "data.governed-export.cancel",
49
+ // @windy-module system.data-governance end
50
+ // @windy-module system.search begin
51
+ "search.query",
52
+ "search.result.access",
53
+ // @windy-module system.search end
54
+ // @windy-module system.bulk-data begin
55
+ "data.bulk-import.create",
56
+ "data.bulk-export.create",
57
+ "data.bulk-artifact.download",
58
+ // @windy-module system.bulk-data end
59
+ // @windy-module system.storage begin
60
+ "file.upload.create",
61
+ "file.upload.complete",
62
+ "file.upload.abort",
63
+ "file.download",
64
+ // @windy-module system.storage end
65
+ // @windy-module system.agent begin
66
+ "agent.tool.execute",
67
+ // @windy-module system.agent end
68
+ "security.denied",
69
+ "system.error",
70
+ ];
@@ -0,0 +1,30 @@
1
+ import { featureKey, type DataGovernancePolicyDefinition } from "@southwind-ai/shared";
2
+
3
+ export const systemDataPolicies: DataGovernancePolicyDefinition[] = [
4
+ {
5
+ key: "system.user.fields",
6
+ resourceType: "system.user",
7
+ version: "1",
8
+ featureKey: featureKey("system.rbac"),
9
+ readPermissionKey: "system.user.read",
10
+ revealPermissionKey: "system.user.reveal",
11
+ exportPermissionKey: "system.user.export",
12
+ display: {
13
+ read: "masked",
14
+ reveal: "plaintext",
15
+ unauthorized: "hidden",
16
+ },
17
+ fields: [
18
+ {
19
+ fieldKey: "email",
20
+ classification: "personal",
21
+ mask: { kind: "partial", prefix: 2, suffix: 4 },
22
+ },
23
+ {
24
+ fieldKey: "phone",
25
+ classification: "sensitive",
26
+ mask: { kind: "partial", prefix: 3, suffix: 4 },
27
+ },
28
+ ],
29
+ },
30
+ ];