create-windy 0.6.20 → 0.7.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.
- package/dist/cli.js +16 -4
- package/package.json +1 -1
- package/template/.windy-template.json +2 -2
- package/template/apps/server/src/agent/remote-runtime.test.ts +36 -0
- package/template/apps/server/src/agent/remote-runtime.ts +15 -7
- package/template/apps/server/src/audit/policy.ts +6 -1
- package/template/apps/server/src/auth/bootstrap-admin.ts +10 -1
- package/template/apps/server/src/auth/composition.ts +5 -0
- package/template/apps/server/src/auth/credential-authorization.test.ts +257 -0
- package/template/apps/server/src/auth/credential-routes.test.ts +1 -0
- package/template/apps/server/src/auth/credential-service.ts +47 -12
- package/template/apps/server/src/auth/drizzle-repository.ts +13 -5
- package/template/apps/server/src/auth/drizzle-session-operations.ts +1 -0
- package/template/apps/server/src/auth/repository.ts +9 -6
- package/template/apps/server/src/auth/routes.test-support.ts +1 -0
- package/template/apps/server/src/auth/runtime.ts +4 -0
- package/template/apps/server/src/auth/service-options.ts +2 -0
- package/template/apps/server/src/auth/service.ts +2 -0
- package/template/apps/server/src/auth/user-credential-access.ts +37 -0
- package/template/apps/server/src/foundation-activation.test.ts +24 -1
- package/template/apps/server/src/foundation.ts +0 -2
- package/template/apps/server/src/index.ts +1 -0
- package/template/apps/server/src/runtime-development.ts +2 -0
- package/template/apps/server/src/runtime.test.ts +13 -4
- package/template/apps/server/src/system/department-organization.ts +58 -59
- package/template/apps/server/src/system/department-read-routes.ts +54 -0
- package/template/apps/server/src/system/department-routes.test.ts +27 -19
- package/template/apps/server/src/system/department-routes.ts +95 -33
- package/template/apps/server/src/system/department-transition-safety.test.ts +148 -0
- package/template/apps/server/src/system/department-validation.ts +79 -0
- package/template/apps/server/src/system/drizzle-repository.ts +14 -0
- package/template/apps/server/src/system/drizzle-system-configs.ts +2 -0
- package/template/apps/server/src/system/identity-read-model.ts +105 -0
- package/template/apps/server/src/system/identity-role-assignment.test.ts +199 -0
- package/template/apps/server/src/system/identity-role-assignment.ts +148 -0
- package/template/apps/server/src/system/identity-route-config.ts +29 -7
- package/template/apps/server/src/system/identity-write-security.test.ts +127 -0
- package/template/apps/server/src/system/identity-write-validation.ts +170 -0
- package/template/apps/server/src/system/organization-read-security.test.ts +221 -0
- package/template/apps/server/src/system/redis-health.test.ts +1 -1
- package/template/apps/server/src/system/repository.ts +29 -2
- package/template/apps/server/src/system/resource-routes.ts +116 -72
- package/template/apps/server/src/system/route-audit.test.ts +117 -0
- package/template/apps/server/src/system/route-helpers.ts +14 -0
- package/template/apps/server/src/system/route-types.ts +11 -2
- package/template/apps/server/src/system/routes.test.ts +0 -68
- package/template/apps/server/src/system/routes.ts +29 -2
- package/template/apps/server/src/system/user-account-policy.test.ts +3 -1
- package/template/apps/server/src/system/user-account-policy.ts +26 -9
- package/template/apps/web/src/pages/system/SystemResourceRoutePage.vue +27 -13
- package/template/apps/web/src/pages/system/SystemResourceRoutePage.webtest.ts +68 -0
- package/template/apps/web/src/pages/system/components/PagedSelectionList.vue +131 -0
- package/template/apps/web/src/pages/system/components/PagedSelectionList.webtest.ts +32 -0
- package/template/apps/web/src/pages/system/components/SystemRecordDetailDialog.vue +67 -0
- package/template/apps/web/src/pages/system/components/SystemResourceEditor.vue +114 -38
- package/template/apps/web/src/pages/system/components/SystemResourceEditor.webtest.ts +180 -0
- package/template/apps/web/src/pages/system/components/SystemResourceFilters.vue +8 -0
- package/template/apps/web/src/pages/system/components/SystemResourceForm.vue +8 -2
- package/template/apps/web/src/pages/system/components/SystemResourcePage.department.webtest.ts +89 -0
- package/template/apps/web/src/pages/system/components/SystemResourcePage.vue +42 -46
- package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +12 -55
- package/template/apps/web/src/pages/system/components/SystemResourceTable.vue +14 -2
- package/template/apps/web/src/pages/system/components/department/DepartmentOrganizationForm.vue +121 -85
- package/template/apps/web/src/pages/system/components/department/DepartmentOrganizationForm.webtest.ts +57 -0
- package/template/apps/web/src/pages/system/components/department/DepartmentOrganizationTable.vue +227 -0
- package/template/apps/web/src/pages/system/components/department/DepartmentOrganizationTable.webtest.ts +62 -0
- package/template/apps/web/src/pages/system/components/department/DepartmentTransitionDialog.vue +72 -52
- package/template/apps/web/src/pages/system/components/role-policy/RolePermissionTree.vue +150 -79
- package/template/apps/web/src/pages/system/components/role-policy/RolePolicyForm.vue +98 -8
- package/template/apps/web/src/pages/system/components/role-policy/RolePolicyForm.webtest.ts +108 -0
- package/template/apps/web/src/pages/system/components/selection-options.ts +71 -0
- package/template/apps/web/src/pages/system/components/selection-options.webtest.ts +49 -0
- package/template/apps/web/src/pages/system/components/user-account/CreateDepartmentDialog.vue +19 -27
- package/template/apps/web/src/pages/system/components/user-account/CreateDepartmentDialog.webtest.ts +2 -6
- package/template/apps/web/src/pages/system/components/user-account/CreateRoleDialog.vue +128 -0
- package/template/apps/web/src/pages/system/components/user-account/CreateRoleDialog.webtest.ts +76 -0
- package/template/apps/web/src/pages/system/components/user-account/RolePermissionSummary.vue +61 -3
- package/template/apps/web/src/pages/system/components/user-account/UserAccountForm.vue +144 -90
- package/template/apps/web/src/pages/system/components/user-account/UserAccountForm.webtest.ts +95 -0
- package/template/apps/web/src/pages/system/components/user-account/UserListFilters.vue +168 -0
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.vue +33 -57
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.webtest.ts +4 -4
- package/template/apps/web/src/pages/system/components/user-account/save-user-account.ts +4 -1
- package/template/apps/web/src/pages/system/components/user-account/user-account-draft.ts +81 -0
- package/template/apps/web/src/pages/system/composables/useDepartmentTransitions.ts +6 -10
- package/template/apps/web/src/pages/system/composables/useResourceEditor.ts +72 -0
- package/template/apps/web/src/pages/system/composables/useResourceEditor.webtest.ts +110 -0
- package/template/apps/web/src/pages/system/composables/useSystemResource.ts +27 -1
- package/template/apps/web/src/pages/system/resource-config.ts +2 -0
- package/template/apps/web/src/services/system-api.ts +25 -0
- package/template/docs/architecture/foundation-infrastructure.md +12 -25
- package/template/docs/development/crud-generator.md +1 -1
- package/template/docs/operations/legacy-data-migration.md +73 -0
- package/template/docs/platform/bulk-data-jobs.md +1 -1
- package/template/docs/platform/module-configuration.md +2 -2
- package/template/docs/platform/organization-membership.md +37 -6
- package/template/docs/platform/scheduled-task-executor.md +1 -1
- package/template/package.json +2 -1
- package/template/packages/config/index.test.ts +1 -5
- package/template/packages/config/package.json +2 -2
- package/template/packages/config/src/platform-boundary.test.ts +39 -0
- package/template/packages/config/src/platform.ts +0 -28
- package/template/packages/database/drizzle/0063_license_project_lifecycle.sql +28 -0
- package/template/packages/database/drizzle/meta/0063_snapshot.json +15053 -0
- package/template/packages/database/drizzle/meta/_journal.json +7 -0
- package/template/packages/database/package.json +2 -2
- package/template/packages/database/src/agent-runtime-schema.test.ts +5 -1
- package/template/packages/database/src/schema/index.ts +1 -0
- package/template/packages/database/src/schema/license-issuance-requests.ts +59 -0
- package/template/packages/database/src/schema/license-v1.ts +5 -0
- package/template/packages/jobs/package.json +2 -2
- package/template/packages/modules/package.json +1 -1
- package/template/packages/modules/src/system-api-permissions.ts +14 -0
- package/template/packages/modules/src/system-features.ts +0 -11
- package/template/packages/modules/src/system-module-catalog.test.ts +4 -0
- package/template/packages/modules/src/system-module-catalog.ts +0 -1
- package/template/packages/server-sdk/index.ts +1 -49
- package/template/packages/server-sdk/package.json +3 -2
- package/template/packages/server-sdk/src/ai-runtime-readiness-exports.ts +49 -0
- package/template/packages/shared/index.ts +2 -1
- package/template/packages/shared/package.json +1 -1
- package/template/packages/shared/src/license-console-capabilities.ts +163 -0
- package/template/packages/shared/src/license-console.ts +94 -0
- package/template/packages/shared/src/license.ts +5 -0
- package/template/docs/adapters/ruoyi-vue-compatibility.md +0 -93
- package/template/packages/shared/src/ruoyi.ts +0 -98
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## 当前落地范围
|
|
4
4
|
|
|
5
|
-
当前已经形成可运行的平台基础闭环:真实密码会话、系统 CRUD、动态 Feature Flag、License 版本 → Feature → RBAC Guard、可靠审计、后台批量任务、定时任务、运维总览、License V1 签发/安装契约、独立签名服务、Vault Transit Provider 和 PostgreSQL
|
|
5
|
+
当前已经形成可运行的平台基础闭环:真实密码会话、系统 CRUD、动态 Feature Flag、License 版本 → Feature → RBAC Guard、可靠审计、后台批量任务、定时任务、运维总览、License V1 签发/安装契约、独立签名服务、Vault Transit Provider 和 PostgreSQL 权威存储均已接入。国产数据库真实验证仍明确延期。旧系统数据通过独立迁移工具导入新模型,RuoYi 运行时兼容预留已退役。
|
|
6
6
|
|
|
7
7
|
已落地内容:
|
|
8
8
|
|
|
9
|
-
- `@southwind-ai/shared` 定义 RBAC、Feature Flag、License、Audit
|
|
9
|
+
- `@southwind-ai/shared` 定义 RBAC、Feature Flag、License、Audit、数据库兼容公共类型。
|
|
10
10
|
- `@southwind-ai/modules` 定义模块 manifest、模块 registry、菜单、权限、API 权限、功能开关、迁移、工具注册和 License 要求。
|
|
11
|
-
- `@southwind-ai/config` 通过类型化 `ModuleConfigDefinition`、严格 Zod schema、白名单环境变量和 `SecretRef` / `SecretResolver` 定义平台配置入口,覆盖数据库方言、平台 Redis、License
|
|
11
|
+
- `@southwind-ai/config` 通过类型化 `ModuleConfigDefinition`、严格 Zod schema、白名单环境变量和 `SecretRef` / `SecretResolver` 定义平台配置入口,覆盖数据库方言、平台 Redis、License和审计;未知字段、错误类型和缺失必填 Secret 在监听端口前 fail-fast。
|
|
12
12
|
|
|
13
13
|
<!-- @windy-module system.configuration begin -->
|
|
14
14
|
|
|
@@ -39,22 +39,21 @@ Web 端已接入 Vue Router,并在所有 AppShell 路由前从 `/api/admin/boo
|
|
|
39
39
|
|
|
40
40
|
Server 已通过 Swagger 插件提供 OpenAPI 文档,并暴露 Agent Tool 注册、原生执行入口和 `/api/mcp` 无状态 Streamable HTTP Adapter。Agent Tool 来自模块 Manifest 的类型化 JSON Schema 契约,统一 Registry 执行 License 版本、Feature、RBAC、数据范围、输入输出校验、超时和脱敏审计;MCP 入口另受 `system.agent` 与 `system.agent.read` 保护,只发现当前 Actor 获准的只读查询 Tool,调用时再次授权。
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Server 已提供 `/api/system/operations` 运维总览接口,Web 已提供 `/system/operations` 页面。当前覆盖在线用户、服务监控、缓存监控、定时任务、代码生成和系统接口的状态入口。定时任务区块通过 `/api/system/operations/scheduler` 读取 OPS-02 的真实代码注册定义、PostgreSQL 持久状态与最近历史;`stale` 仍是只读派生观察,但 OPS-04 允许操作员在确认旧 handler 已停止并核对业务副作用后,通过精确版本 CAS 和关键审计把该历史行终结为 `blocked`。该动作只释放后续调度,不会自动执行、重试或补偿任务。缓存监控通过平台 `REDIS_URL` 读取运行态;接口在 License 版本、动态 Feature Flag 和 RBAC Guard 全部通过后才发起探活。
|
|
43
43
|
|
|
44
44
|
CRUD 代码生成器已从 canonical 模块元数据生成独立的 DTO、PostgreSQL Drizzle schema、Repository、Service、Guard 路由和 Module Manifest,目标存在时拒绝覆盖。运维总览的系统接口权限目录只汇总 composition root 已注册 Manifest,展示 method/path、Permission、Feature、允许的 License 版本和 Guard 顺序;不会扫描源码猜测绑定。
|
|
45
45
|
|
|
46
46
|
Redis 探活使用 Bun 原生客户端并设置总超时,返回正常、超时、认证失败、不可用和未配置五类稳定状态。正常时同时展示完整探活延迟、当前数据库键数、连接客户端数、已用内存、内存上限和使用率。响应中的连接目标会移除用户名、密码和查询参数,底层错误不直接返回前端。默认超时为 1500 ms,可通过 `REDIS_HEALTH_TIMEOUT_MS` 调整;值会限制在 50 至 10000 ms。真实容器回归命令为 `bun run test:redis:health`,会验证带认证 Redis 的成功、错误或缺失密码、暂停容器超时和未配置状态,并在结束时清理容器。
|
|
47
47
|
|
|
48
|
-
##
|
|
48
|
+
## 旧系统数据迁移边界
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
平台运行时使用自身 canonical schema,不再提供 RuoYi Adapter、旧 MySQL / Redis
|
|
51
|
+
连接配置或兼容 Feature。业务模块不得直接依赖旧 `sys_*` 表。
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
本轮已把核心表枚举、迁移计划、迁移报告、权限快照、导入 Adapter、运行时 Adapter 和报告 Adapter 定义到共享契约中。
|
|
53
|
+
旧数据由具体项目的独立迁移工具按业务对象和关系导入。当前仅明确
|
|
54
|
+
[迁移范围、工程要求和移除接口](../operations/legacy-data-migration.md),尚未实现工具,
|
|
55
|
+
也未执行实际数据迁移。用户、部门、角色、数据权限、审计、调度、平台 Redis 和通用
|
|
56
|
+
数据库方言边界继续承担各自的平台职责。
|
|
58
57
|
|
|
59
58
|
## 已确认决策
|
|
60
59
|
|
|
@@ -88,7 +87,7 @@ Drizzle Kit 负责:
|
|
|
88
87
|
- 读取模块 manifest 中的 migration 描述并按模块顺序执行。
|
|
89
88
|
- 在 PostgreSQL、MySQL、达梦、人大金仓之间选择方言 Adapter。
|
|
90
89
|
- 记录执行历史、耗时、失败原因、审计事件和回滚建议。
|
|
91
|
-
- 支持 dry-run
|
|
90
|
+
- 支持 dry-run 和客户现场 schema 迁移报告。
|
|
92
91
|
- 屏蔽国产数据库连接、分页、JSON、自增、保留字等差异。
|
|
93
92
|
|
|
94
93
|
不建议只用 Drizzle Kit:它更适合生成和执行标准迁移,不承担产品级审计、客户现场报告、国产库适配和模块化启停编排。
|
|
@@ -115,17 +114,6 @@ Drizzle Kit 负责:
|
|
|
115
114
|
- 每个数据库方言有独立 Adapter,不允许业务模块拼接数据库特定 SQL。
|
|
116
115
|
- 真实差异通过国产库环境验证后补充到 Adapter 测试用例和迁移报告。
|
|
117
116
|
|
|
118
|
-
### RuoYi-Vue 运行时兼容
|
|
119
|
-
|
|
120
|
-
旧库运行时受控写入已明确延期,本轮不实现。
|
|
121
|
-
|
|
122
|
-
默认策略:
|
|
123
|
-
|
|
124
|
-
- 新项目默认不启用 RuoYi-Vue 兼容层。
|
|
125
|
-
- 旧库运行时兼容默认只读。
|
|
126
|
-
- 现有 Adapter 只保留未来扩展边界,不实现旧库写入、双写、补偿或 Redis 运行态兼容。
|
|
127
|
-
- 后续重新启动该范围时,仍必须通过 RuoYi Adapter、审计日志和迁移/兼容报告闭环。
|
|
128
|
-
|
|
129
117
|
### Web 端缺失组件
|
|
130
118
|
|
|
131
119
|
Web 端缺失组件可以在项目内自行实现,放入 `apps/web/src/components`。
|
|
@@ -149,7 +137,6 @@ Web 端缺失组件可以在项目内自行实现,放入 `apps/web/src/compone
|
|
|
149
137
|
- Ubuntu、Debian、CentOS、OpenEuler、UOS、银河麒麟的真实部署矩阵尚未逐一验证;
|
|
150
138
|
`create-windy`、`@southwind-ai/*` scope 和 `private-enterprise` profile 已确定。
|
|
151
139
|
- 国产数据库 Adapter 的真实达梦、人大金仓验证本轮明确延期。
|
|
152
|
-
- RuoYi-Vue 旧库运行时受控写入、双写、补偿和旧 Redis 运行态兼容本轮明确延期。
|
|
153
140
|
|
|
154
141
|
## 验证命令
|
|
155
142
|
|
|
@@ -38,7 +38,7 @@ bun run --cwd packages/inventory test
|
|
|
38
38
|
4. 把 `CrudAuditPort` 接到平台可靠审计 writer,并保留生成器为 create/update/delete 指定的 `critical` 策略;随后注册生成的 Module Manifest 和 routes。
|
|
39
39
|
5. 业务页面应在独立业务应用中组合自己的组件;只有明确属于平台管理控制面的能力,才可另行声明 Admin Route 并在 Windy Web 提供实现。生成器不生成 Vue 页面。
|
|
40
40
|
|
|
41
|
-
生成的 schema 仅使用 Drizzle PostgreSQL canonical
|
|
41
|
+
生成的 schema 仅使用 Drizzle PostgreSQL canonical 类型。达梦、人大金仓真实方言适配不在本任务范围内。
|
|
42
42
|
|
|
43
43
|
## 元数据约束
|
|
44
44
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 旧系统数据迁移策略
|
|
2
|
+
|
|
3
|
+
## 决策与当前状态
|
|
4
|
+
|
|
5
|
+
Windy 退役 RuoYi 兼容预留。客户单机部署已无过渡期连接旧 MySQL / Redis 运行的需求,
|
|
6
|
+
平台不再提供旧库运行时读取、写入、双写或 Redis 运行态兼容,也不保留待实现的
|
|
7
|
+
RuoYi Adapter 接口、Feature 或连接配置。
|
|
8
|
+
|
|
9
|
+
新系统以自身 canonical schema 和业务模型运行。旧系统数据通过具体项目的独立
|
|
10
|
+
迁移工具一次性导入,按真实源库结构及明确的目标系统版本开发和验收。迁移单位是
|
|
11
|
+
业务对象及其关系;旧表和字段不直接成为平台模型。
|
|
12
|
+
|
|
13
|
+
**当前仅完成策略确认与兼容预留清理,迁移工具尚未实现,未执行实际数据迁移。**
|
|
14
|
+
后续工具放在消费项目的迁移目录或独立工具包;有多个真实消费者后再提取共享逻辑,
|
|
15
|
+
不在平台预设新的通用旧库兼容接口。
|
|
16
|
+
|
|
17
|
+
## 迁移范围
|
|
18
|
+
|
|
19
|
+
平台组织与授权模型是通用能力,业务数据映射由消费项目负责。Sharp Sword 当前确认
|
|
20
|
+
的旧数据范围如下;该范围不意味着 Windy 新增案件、聊天等业务模块。
|
|
21
|
+
|
|
22
|
+
| 数据类别 | 决策 | 映射要求 |
|
|
23
|
+
| -------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| 用户、部门、角色 | 需要迁移 | 保留部门树、账户主部门、用户角色关系,建立旧新 ID 对照;角色权限和数据范围显式映射到新系统;密码允许统一重置,不要求兼容旧 hash |
|
|
25
|
+
| 案件、人员、资金、聊天、轨迹 | Sharp Sword 需要迁移 | 按利剑领域模型处理归属、关联、状态和去重,保留旧记录标识、来源与旧新 ID 对照 |
|
|
26
|
+
| 历史日志、分析成果 | 不迁移 | 不导入旧登录日志、操作日志、任务执行日志或旧分析结果;迁移执行本身仍生成新的操作审计和对账报告 |
|
|
27
|
+
| Redis 会话、缓存、旧任务执行入口 | 不迁移 | 新系统建立自身会话、缓存和任务运行状态 |
|
|
28
|
+
| 原始证据、附件、媒体文件 | 后续可选,当前不做 | 结构化数据导入必须明确原件尚未迁入,不伪造可用文件、下载链接或完整证据链 |
|
|
29
|
+
|
|
30
|
+
旧菜单、路由、组件路径和权限字符串不能直接注册为新系统能力。角色授权必须对照
|
|
31
|
+
目标版本已注册的 Module Manifest 权限与数据范围显式映射,记录无法映射项,不能
|
|
32
|
+
因迁移而扩大权限或绕过 RBAC、Feature、License 与审计边界。菜单和按钮最终由新系统
|
|
33
|
+
已注册能力生成。岗位、字典、参数、通知等未列入当前迁移范围,不默认批量复制旧表。
|
|
34
|
+
|
|
35
|
+
## 后续迁移工具要求
|
|
36
|
+
|
|
37
|
+
- 源库只读;连接凭据属于工具配置,不进入 Windy 平台运行时配置、日志或报告。
|
|
38
|
+
- 先执行 dry-run,验证源结构、目标版本、必需字段、组织和业务关联、权限映射及冲突,
|
|
39
|
+
输出可审阅的计划和失败明细,dry-run 不写入业务数据。
|
|
40
|
+
- 使用独立批次标识和稳定旧新 ID 映射,实现幂等执行和失败重试,防止重复创建账户、
|
|
41
|
+
业务记录或关联;保留源系统、源记录和迁移批次信息。
|
|
42
|
+
- 目标侧通过正式 Service、导入 API 或专用迁移入口调用 Repository,执行目标系统的
|
|
43
|
+
授权、数据范围、业务校验和审计;大批量场景可增加专用批处理入口,不直接写业务表
|
|
44
|
+
来绕过这些约束。
|
|
45
|
+
- 导入前明确重名、重复、缺失父节点和悬空引用的处置规则;无法处理的记录进入失败
|
|
46
|
+
报告,不静默丢弃关系,不用虚构值填充必需的业务事实。
|
|
47
|
+
- 按批次记录成功、跳过、失败数量和具体原因,核对源目标数量、旧新 ID、对象关联、
|
|
48
|
+
账户归属与有效授权;重试只处理尚未成功的对象,报告须能定位需要人工处理的项。
|
|
49
|
+
- 切换前按目标版本完成备份、恢复与批次处置方案,验收后新系统独立运行。具体停机
|
|
50
|
+
窗口和业务映射在实际迁移任务中确定,本策略不承诺持续同步或新旧系统并行运行。
|
|
51
|
+
|
|
52
|
+
## 退役接口与升级影响
|
|
53
|
+
|
|
54
|
+
本次移除的是没有运行实现的 RuoYi 专属预留,不修改业务表或已发布、已应用的数据库
|
|
55
|
+
迁移历史。平台用户、部门、角色、数据权限、审计、调度、平台 Redis、通用导入能力
|
|
56
|
+
以及数据库方言和 migration runner 均继续保留。
|
|
57
|
+
|
|
58
|
+
| 移除项 | 影响与处理 |
|
|
59
|
+
| -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
60
|
+
| `packages/shared/src/ruoyi.ts` 及其公共导出 | 删除 `RuoYiCoreTable`、`RuoYiConnectionConfig`、`RuoYiMigrationPlan`、`RuoYiMigrationReport`、`RuoYiPermissionSnapshot`、`RuoYiImportAdapter`、`RuoYiLegacyRuntimeAdapter`、`RuoYiReportAdapter` 和 `ruoyiCoreTables`;消费方移除相关引用,不提供空壳或别名 |
|
|
61
|
+
| `system.ruoyi-compat` | 从系统 Manifest 与能力目录移除;沿用已有 Feature 同步规则归档已存元数据,不改写历史迁移 |
|
|
62
|
+
| `DatabaseConfig.legacyRuoYiMysqlUrl`、`legacyRuoYiRedisUrl` | 删除旧库连接字段和 schema;源库连接以后由项目迁移工具独立管理 |
|
|
63
|
+
| `PlatformConfig.compatibility.ruoyiVue` | 删除兼容配置段,包括 `enabled`、`runtimeReadonly`;不保留空的 `compatibility` 配置容器 |
|
|
64
|
+
| `RUOYI_MYSQL_URL`、`RUOYI_REDIS_URL`、`RUOYI_COMPAT_ENABLED`、`RUOYI_RUNTIME_READONLY` | 删除环境绑定及 `RUOYI_` 前缀归属,平台不再读取或解析这些变量;部署配置可移除旧变量 |
|
|
65
|
+
| foundation 的 `ruoyiCompatibilityEnabled` | 删除状态字段,消费方不能继续依赖该字段展示兼容状态 |
|
|
66
|
+
|
|
67
|
+
旧结构化配置仍按现有严格 schema 校验:包含已删除字段时启动失败,应删除字段后
|
|
68
|
+
重试,不增加静默忽略或过渡兼容分支。公共类型导入和 foundation 消费代码需随版本
|
|
69
|
+
同步调整;这属于接口移除,不能只修改部署环境变量。
|
|
70
|
+
|
|
71
|
+
Starter 文档分发改为本策略,不再生成旧兼容设计文档。Sharp Sword 等已生成项目通过
|
|
72
|
+
正式 Windy 更新链路接收清理,并按目标版本的更新契约完成消费项目验证。
|
|
73
|
+
本轮不发布 npm、不升级或部署消费项目。
|
|
@@ -140,7 +140,7 @@ source、result、failures artifact 默认从各自创建时间保留 7 天,
|
|
|
140
140
|
|
|
141
141
|
V1 把 artifact 文本和 SHA-256 一起保存在 PostgreSQL `text` 列。这保证生产状态只有一个权威来源,并避免多副本共享本地目录,但只适用于上述 10 MiB / 50,000 行明确上限,不代表 PostgreSQL 适合无限大文件。后续若提升容量,应实现保持 `BulkDataRepository` 契约的对象存储 Adapter,并把 PostgreSQL 继续作为任务、权限和 artifact 元数据权威;不能直接扩大限制而把数据库当通用对象存储。
|
|
142
142
|
|
|
143
|
-
无 PostgreSQL 时只使用进程内 Repository,限开发和测试,重启即丢失。生产必须配置 PostgreSQL 并执行到包含 `bulk_data_jobs`、`bulk_data_artifacts` 的最新 migration
|
|
143
|
+
无 PostgreSQL 时只使用进程内 Repository,限开发和测试,重启即丢失。生产必须配置 PostgreSQL 并执行到包含 `bulk_data_jobs`、`bulk_data_artifacts` 的最新 migration。本功能使用平台数据模型,不承担旧系统数据迁移。
|
|
144
144
|
|
|
145
145
|
## 运维验证
|
|
146
146
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
当前首批定义只有:
|
|
10
10
|
|
|
11
|
-
- `platform.runtime`:平台名称、数据库方言、平台 Redis、Session、License
|
|
11
|
+
- `platform.runtime`:平台名称、数据库方言、平台 Redis、Session、License 公钥元数据和审计;
|
|
12
12
|
- `license.signing-service`:loopback 地址、端口、Vault 地址与 mount、速率限制、签名 key 白名单,以及签名服务 Bearer Token/Vault Token 的受保护文件引用。
|
|
13
13
|
|
|
14
14
|
配置版本治理只允许消费同一 Registry,不能新增一张绕过 Definition 的通用 KV 表。
|
|
@@ -40,7 +40,7 @@ Secret 配置分成引用和运行时值两层:
|
|
|
40
40
|
Composition 才能把本节的 `SecretRef` / `SecretResolver` 绑定到逻辑
|
|
41
41
|
handle/connection/purpose,业务模块看不到物理 locator。
|
|
42
42
|
|
|
43
|
-
平台 Server 在创建数据库连接、初始化审计恢复和监听端口前加载 `platform.runtime`。数据库、平台 Redis
|
|
43
|
+
平台 Server 在创建数据库连接、初始化审计恢复和监听端口前加载 `platform.runtime`。数据库、平台 Redis 和机器码通过 env Resolver 解析;Server 的 foundation 快照只投影名称、Feature 等非敏感字段。独立签名服务在连接 Vault 和监听端口前加载 `license.signing-service`,Bearer/Vault Token 只经受保护文件 Resolver 进入对应客户端。
|
|
44
44
|
|
|
45
45
|
## 新模块接入规则
|
|
46
46
|
|
|
@@ -2,26 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## 设计依据
|
|
4
4
|
|
|
5
|
-
Windy V1 采用单组织、单租户的企业私有化模型。canonical schema
|
|
5
|
+
Windy V1 采用单组织、单租户的企业私有化模型。canonical schema 以部门树、用户主部门和角色自定义部门范围表达组织与授权关系。旧系统组织数据通过独立迁移工具映射到该模型,业务模块不得直接依赖旧 `sys_dept` 或其它 `sys_*` 表。
|
|
6
6
|
|
|
7
7
|
- `departments.parent_id` 表示上级部门,只有平台根组织为空;
|
|
8
8
|
- `users.department_id` 表示用户唯一主部门;
|
|
9
9
|
- `roles.data_scope` 和 `roles.department_ids` 表示角色数据范围策略;
|
|
10
10
|
- 岗位、兼职部门和多组织成员关系属于后续独立模型,不复用 `department_id` 暗中表达。
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
旧用户、部门、角色及其归属和授权关系的迁移遵循
|
|
13
|
+
[旧系统数据迁移策略](../operations/legacy-data-migration.md)。数据权限必须进入查询约束,
|
|
14
|
+
不能只依赖 Web 菜单或按钮隐藏。
|
|
14
15
|
|
|
15
16
|
## 用户表单闭环
|
|
16
17
|
|
|
17
|
-
用户新增和编辑表单从 `GET /api/system/departments`
|
|
18
|
+
用户新增和编辑表单从 `GET /api/system/departments` 完整加载组织关系以构建祖先路径,并在受控分页选择器中提供启用部门,写入 `users.department_id`;角色区域从 `GET /api/system/roles` 加载启用角色,显示中文名称、稳定编码和数据范围。创建用户必须选择一个启用部门和至少一个启用角色,服务端会再次验证,不能通过直接调用 API 写入悬空部门、空角色或停用角色。
|
|
18
19
|
|
|
19
20
|
具备以下任一管理能力时,用户表单显示“新建部门”快捷入口:
|
|
20
21
|
|
|
21
22
|
- `system.department.create`:调用受限的 `POST /api/system/departments/quick`;
|
|
22
23
|
- `system.department.manage`:兼容既有管理员,调用通用部门创建接口。
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
快捷创建只接收名称、编码、必选上级、排序及合法状态字段,表单默认创建启用部门;成功后刷新部门列表并自动选中新部门。`system.department.create` 与既有 `system.department.read/manage` 使用同一能力基础 Key `system.department`,接口继续经过 `system.department` Feature Guard,并写入 `crud.create` 审计事件。没有创建或管理权限时,表单只显示部门选择,不渲染快捷入口。
|
|
25
26
|
|
|
26
27
|
## 组织树强不变量
|
|
27
28
|
|
|
@@ -33,7 +34,7 @@ Windy V1 只允许一个未删除根组织。`0037_absent_nick_fury.sql` 通过
|
|
|
33
34
|
- 角色 `custom` 数据范围至少选择一个启用部门,未知或停用部门返回 `INVALID_ROLE_DEPARTMENT_SCOPE`;
|
|
34
35
|
- 部门仍有直接下级、未删除用户或角色自定义部门范围时,普通停用和删除返回 `DEPARTMENT_MIGRATION_REQUIRED`,响应包含三类引用计数。
|
|
35
36
|
|
|
36
|
-
管理端处置部门使用 `POST /api/system/departments/:id/transition`。请求明确给出 `disable` 或 `delete
|
|
37
|
+
管理端处置部门使用 `POST /api/system/departments/:id/transition`。请求明确给出 `disable` 或 `delete`,存在关联数据时还须提供启用的迁移目标;Server 会拒绝当前节点和其下级作为目标,然后把直接下级的 `parentId`、用户主部门和角色 `departmentIds` 一起迁移,再完成停用或软删除。操作写入 `organization.department.transition` 审计事件,元数据只记录动作、目标 ID 和迁移计数。
|
|
37
38
|
|
|
38
39
|
用户、角色和部门写操作共享同一个组织 mutation coordinator。无数据库开发模式使用进程内串行;PostgreSQL 使用固定 advisory transaction lock,因此多个 Server 实例的互相移动、用户归属写入和部门处置也按同一事实顺序判定。`bun run test:db:organization` 在 PostgreSQL 17 覆盖唯一根约束、双实例循环竞态和用户归属竞态;`bun run test:db:data-scope` 继续验证组织树调整后数据范围查询不漂移。
|
|
39
40
|
|
|
@@ -44,3 +45,33 @@ Windy V1 只允许一个未删除根组织。`0037_absent_nick_fury.sql` 通过
|
|
|
44
45
|
当前用户资源已接入类型化数据访问上下文。Actor Resolver 从全部启用角色生成 `all`、`tenant`、`department`、`department-and-children`、`self` 或 `custom` grant;多个角色按可见集合并集计算。用户列表、总数、搜索、分页、导出、按 ID 读取、更新、删除和组织移动使用同一约束,跨部门猜测 ID 返回稳定的 `data-scope-denied`,不会只依赖 Web 隐藏。
|
|
45
46
|
|
|
46
47
|
详细接入契约见 [数据访问范围](./data-access-control.md)。没有明确 `ownerId` / `departmentId` 归属的资源不会自动套用部门范围。ORG-02 只覆盖单组织、用户唯一主部门和角色自定义部门范围;岗位、兼职部门与多组织成员关系仍是明确的后续模型,不在本轮暗中扩展。
|
|
48
|
+
|
|
49
|
+
## 管理体验与分页
|
|
50
|
+
|
|
51
|
+
账户的所属部门、角色,上级部门、迁移目标、自定义数据范围部门以及角色的功能权限均支持搜索与分页,默认每页 10 条。选项读取沿用具备读取权限的正式接口,逐页读完后再分页展示;不会把前 100 条当作完整组织关系,也不会因翻页清空勾选。部门选项展示祖先路径,便于区分不同上级下的同名部门。角色功能权限来自当前启用 Module 的 Manifest 快照,账户通过角色取得这些权限;账户表单的权限摘要是只读说明。有角色管理权限时,可在账户表单内“新建角色并选择权限”,创建成功自动选中新角色并保留账户草稿,同时保留前往角色管理页面的入口。嵌套新建部门或角色的未保存确认先于父账户执行,避免父表单关闭时丢失子弹窗草稿。
|
|
52
|
+
|
|
53
|
+
账户列表提供部门、角色和状态组合筛选。这些条件在 Repository 查询阶段与数据范围取交集,分页总数也使用相同条件。列表和详情返回脱敏联系方式;部门名称、角色名称分别要求对应资源的读取 Guard 通过,不以联表摘要绕过权限。
|
|
54
|
+
|
|
55
|
+
`GET /api/system/departments/organization` 提供完整组织快照,要求 `system.department.read`,供客户端构建可展开组织树、路径搜索和分页。`childDepartmentCount` 是直属下级数量;`userCount` 仅在 `system.user.read` Guard 通过时提供,并只统计操作者可见的直属账户。缺少读取权限显示空缺,而不是伪造为零。此接口按平台单组织模型返回部门,不意味着授权读取所有部门的账户。
|
|
56
|
+
|
|
57
|
+
`GET /api/system/departments/:id/transition-preview` 要求 `system.department.manage`,返回本次组织处置会影响的直属下级、账户和角色范围计数。该计数用于明确迁移影响,不包含账户资料。预览不是锁定或授权令牌,提交时仍在组织事务内重新计算和校验。
|
|
58
|
+
|
|
59
|
+
## 编辑与账户凭据
|
|
60
|
+
|
|
61
|
+
账户、部门、角色编辑均以当前值与加载或成功保存基线比较未保存状态。关闭、站内路由或参数切换会显示统一未保存确认;取消保留编辑,保存成功后才继续离开。刷新和关闭浏览器使用原生 `beforeunload` 提示。整个保存阶段禁用重复提交,失败保留输入。
|
|
62
|
+
|
|
63
|
+
账户创建仍使用“保存资料,再设置初始密码”两个正式接口。第一次保存资料成功即保留账户 ID;密码设置失败后重试更新同一账户,不重复创建。编辑器在两个请求全部完成前保持保存状态。新账户仍要求有效初始密码;没有凭据的账户不计入生产环境中“至少保留一个可登录超级管理员”的保护条件。
|
|
64
|
+
|
|
65
|
+
停用部门时,名称、编码、排序和上级编辑通过 transition 请求的 `updates` 一起提交,仅允许这四个字段。服务端先校验全部编辑和迁移目标,然后在同一 PostgreSQL 事务中迁移关联数据并保存停用状态;失败不会只迁移一半。没有关联数据时不强制选择迁移目标。组织归属或角色范围变化会传播授权失效事件,部门写入采用关键审计策略。
|
|
66
|
+
|
|
67
|
+
## 写入与委派授权边界
|
|
68
|
+
|
|
69
|
+
用户、角色、部门创建与更新只接受显式可写字段。`id`、`createdAt`、`createdBy`、`updatedAt`、`updatedBy`、`deletedAt`、`deletedBy` 等系统字段不可通过业务请求覆盖。用户名、姓名、联系方式、状态、角色数组、部门编码和排序均有运行时校验;唯一字段冲突返回可理解的业务错误。软删除账户在登录、凭据查询和会话认证中均被拒绝。
|
|
70
|
+
|
|
71
|
+
管理员重置密码同时要求 `system.user.manage`、服务端创建的数据范围上下文、目标账户可见以及目标角色处于操作者可授权范围。密码计算完成后,还会在组织操作锁内重新核验目标,防止计算期间发生部门迁移或角色提权。密码写入返回失败时不会报告成功。生产 Auth composition 显式注入统一访问服务与组织操作锁;缺失访问服务时拒绝操作。引导管理员使用服务端构造的主体继续经过这一访问服务。
|
|
72
|
+
|
|
73
|
+
超级管理员可以维护平台启用角色。其他管理员授予角色时要求角色权限不超过本人且目标账户的实际数据范围不扩大;修改已有共享角色还要求本人持有该角色。不能通过改资料、先降角色或重置同部门高权限账户的密码取得更高权限。共享角色的数据范围变更要求超级管理员处理,避免修改一个角色而隐式扩大其他成员的可见范围。
|
|
74
|
+
|
|
75
|
+
## 验证层级
|
|
76
|
+
|
|
77
|
+
提交前执行 Oxfmt、Oxlint 和 TypeScript 静态检查;最终合并候选通过 `bun run test:merge` 执行后端单元与合约、Web 组件回归及仓库规定的轻量测试。真实 PostgreSQL 回滚、多实例竞态、完整构建及生成矩阵属于发布候选门禁,不将本地组件回归表述为线上验收。
|
package/template/package.json
CHANGED
|
@@ -37,12 +37,13 @@
|
|
|
37
37
|
"test:db:notification": "bun run scripts/notification-postgres-regression.ts",
|
|
38
38
|
"test:db:governance": "bun run scripts/governance-postgres-regression.ts",
|
|
39
39
|
"test:db:legacy-license": "bun run scripts/legacy-license-migration-regression.ts",
|
|
40
|
+
"test:db:license-lifecycle": "bun run scripts/license-lifecycle-postgres-regression.ts",
|
|
40
41
|
"test:db:license-bootstrap": "bun run scripts/license-bootstrap-postgres-regression.ts",
|
|
41
42
|
"test:db:migrations": "bun run scripts/database-migration-regression.ts",
|
|
42
43
|
"test:db:config": "bun run scripts/module-configuration-postgres-regression.ts",
|
|
43
44
|
"test:db:storage": "bun run scripts/storage-postgres-regression.ts",
|
|
44
45
|
"test:db:ai-output-artifact": "bun run scripts/ai-output-artifact-postgres-regression.ts",
|
|
45
|
-
"test:db:release": "bun run test:db:migrations && bun run test:db:auth && bun run test:db:data-scope && bun run test:db:organization && bun run test:db:notification && bun run test:db:governance && bun run test:db:legacy-license && bun run test:db:license-bootstrap && bun run test:db:config && bun run test:db:storage && bun run test:db:ai-output-artifact",
|
|
46
|
+
"test:db:release": "bun run test:db:migrations && bun run test:db:auth && bun run test:db:data-scope && bun run test:db:organization && bun run test:db:notification && bun run test:db:governance && bun run test:db:legacy-license && bun run test:db:license-bootstrap && bun run test:db:license-lifecycle && bun run test:db:config && bun run test:db:storage && bun run test:db:ai-output-artifact",
|
|
46
47
|
"test:redis:health": "bun run scripts/redis-health-regression.ts",
|
|
47
48
|
"test:vault:signing": "bun run scripts/vault-signing-regression.ts",
|
|
48
49
|
"test:docker:license-signing": "bun run scripts/license-signing-compose-regression.ts",
|
|
@@ -13,20 +13,16 @@ import {
|
|
|
13
13
|
strictBoolean,
|
|
14
14
|
} from "./index.js";
|
|
15
15
|
|
|
16
|
-
test("平台 Redis
|
|
16
|
+
test("平台 Redis 通过 SecretResolver 加载连接与探活配置", () => {
|
|
17
17
|
const config = loadPlatformConfig({
|
|
18
18
|
REDIS_URL: "redis://platform-cache:6379/0",
|
|
19
19
|
REDIS_HEALTH_TIMEOUT_MS: "750",
|
|
20
|
-
RUOYI_REDIS_URL: "redis://legacy-cache:6379/1",
|
|
21
20
|
});
|
|
22
21
|
|
|
23
22
|
expect(config.cache).toEqual({
|
|
24
23
|
redisUrl: "redis://platform-cache:6379/0",
|
|
25
24
|
healthTimeoutMs: 750,
|
|
26
25
|
});
|
|
27
|
-
expect(config.database.legacyRuoYiRedisUrl).toBe(
|
|
28
|
-
"redis://legacy-cache:6379/1",
|
|
29
|
-
);
|
|
30
26
|
});
|
|
31
27
|
|
|
32
28
|
test("平台设置提供类型化默认值并校验 IANA 时区", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@southwind-ai/config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"!src/**/*.test.ts"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@southwind-ai/shared": "workspace:^0.
|
|
16
|
+
"@southwind-ai/shared": "workspace:^0.3.0",
|
|
17
17
|
"zod": "^4.4.3"
|
|
18
18
|
},
|
|
19
19
|
"exports": {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { expect, mock, test } from "bun:test";
|
|
2
|
+
import { loadModuleConfigSync } from "./environment-loader.js";
|
|
3
|
+
import { loadPlatformConfig, platformConfigDefinition } from "./platform.js";
|
|
4
|
+
|
|
5
|
+
test("退役旧库环境变量不再解析为平台配置或调用 SecretResolver", () => {
|
|
6
|
+
const resolve = mock(() => {
|
|
7
|
+
throw new Error("不应解析旧库凭据");
|
|
8
|
+
});
|
|
9
|
+
const config = loadModuleConfigSync(
|
|
10
|
+
platformConfigDefinition,
|
|
11
|
+
{
|
|
12
|
+
RUOYI_MYSQL_URL: "retired-mysql-secret",
|
|
13
|
+
RUOYI_REDIS_URL: "retired-redis-secret",
|
|
14
|
+
RUOYI_COMPAT_ENABLED: "invalid-boolean",
|
|
15
|
+
RUOYI_RUNTIME_READONLY: "invalid-boolean",
|
|
16
|
+
},
|
|
17
|
+
{ resolve },
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
expect(config).toEqual(loadPlatformConfig({}));
|
|
21
|
+
expect(config.database).toEqual({ dialect: "postgresql" });
|
|
22
|
+
expect(config.cache).toEqual({ healthTimeoutMs: 1_500 });
|
|
23
|
+
expect(config).not.toHaveProperty("compatibility");
|
|
24
|
+
expect(resolve).not.toHaveBeenCalled();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test.each([
|
|
28
|
+
["compatibility", { ruoyiVue: { enabled: false, runtimeReadonly: true } }],
|
|
29
|
+
["legacyRuoYiMysqlUrl", "retired-mysql-secret"],
|
|
30
|
+
["legacyRuoYiRedisUrl", "retired-redis-secret"],
|
|
31
|
+
] as const)("严格 schema 拒绝已移除的结构化配置 %s", (field, value) => {
|
|
32
|
+
const baseline = loadPlatformConfig({});
|
|
33
|
+
const input =
|
|
34
|
+
field === "compatibility"
|
|
35
|
+
? { ...baseline, [field]: value }
|
|
36
|
+
: { ...baseline, database: { ...baseline.database, [field]: value } };
|
|
37
|
+
|
|
38
|
+
expect(platformConfigDefinition.schema.safeParse(input).success).toBe(false);
|
|
39
|
+
});
|
|
@@ -21,8 +21,6 @@ import { isSupportedTimeZone } from "./platform-validation.js";
|
|
|
21
21
|
export interface DatabaseConfig {
|
|
22
22
|
dialect: DatabaseDialect;
|
|
23
23
|
url?: string;
|
|
24
|
-
legacyRuoYiMysqlUrl?: string;
|
|
25
|
-
legacyRuoYiRedisUrl?: string;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
export interface PlatformConfig {
|
|
@@ -64,9 +62,6 @@ export interface PlatformConfig {
|
|
|
64
62
|
// @windy-module system.agent begin
|
|
65
63
|
agentWorkflow?: { modelPricingJson?: string };
|
|
66
64
|
// @windy-module system.agent end
|
|
67
|
-
compatibility: {
|
|
68
|
-
ruoyiVue: { enabled: boolean; runtimeReadonly: boolean };
|
|
69
|
-
};
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
export interface WorkspaceConfig {
|
|
@@ -88,8 +83,6 @@ const platformSchema: z.ZodType<PlatformConfig> = z
|
|
|
88
83
|
database: z.strictObject({
|
|
89
84
|
dialect: z.enum(["postgresql", "mysql", "dm", "kingbase"]),
|
|
90
85
|
url: z.string().trim().min(1).optional(),
|
|
91
|
-
legacyRuoYiMysqlUrl: z.string().trim().min(1).optional(),
|
|
92
|
-
legacyRuoYiRedisUrl: z.string().trim().min(1).optional(),
|
|
93
86
|
}),
|
|
94
87
|
cache: z.strictObject({
|
|
95
88
|
redisUrl: z.string().trim().min(1).optional(),
|
|
@@ -162,12 +155,6 @@ const platformSchema: z.ZodType<PlatformConfig> = z
|
|
|
162
155
|
})
|
|
163
156
|
.optional(),
|
|
164
157
|
// @windy-module system.agent end
|
|
165
|
-
compatibility: z.strictObject({
|
|
166
|
-
ruoyiVue: z.strictObject({
|
|
167
|
-
enabled: z.boolean(),
|
|
168
|
-
runtimeReadonly: z.boolean(),
|
|
169
|
-
}),
|
|
170
|
-
}),
|
|
171
158
|
})
|
|
172
159
|
.superRefine((config, context) => {
|
|
173
160
|
if (config.security.passwordMinLength > config.security.passwordMaxLength) {
|
|
@@ -202,7 +189,6 @@ export const platformConfigDefinition = defineModuleConfig<PlatformConfig>({
|
|
|
202
189
|
"DATABASE_",
|
|
203
190
|
"PASSWORD_",
|
|
204
191
|
"REDIS_",
|
|
205
|
-
"RUOYI_",
|
|
206
192
|
"SESSION_",
|
|
207
193
|
"STORAGE_",
|
|
208
194
|
"MAIL_",
|
|
@@ -225,8 +211,6 @@ export const platformConfigDefinition = defineModuleConfig<PlatformConfig>({
|
|
|
225
211
|
value("PLATFORM_ENABLE_AI", "enableAI", false, strictBoolean),
|
|
226
212
|
value("DATABASE_DIALECT", "database.dialect", "postgresql"),
|
|
227
213
|
secret("DATABASE_URL", "database.url"),
|
|
228
|
-
secret("RUOYI_MYSQL_URL", "database.legacyRuoYiMysqlUrl"),
|
|
229
|
-
secret("RUOYI_REDIS_URL", "database.legacyRuoYiRedisUrl"),
|
|
230
214
|
secret("REDIS_URL", "cache.redisUrl"),
|
|
231
215
|
value(
|
|
232
216
|
"REDIS_HEALTH_TIMEOUT_MS",
|
|
@@ -301,18 +285,6 @@ export const platformConfigDefinition = defineModuleConfig<PlatformConfig>({
|
|
|
301
285
|
(raw) => raw.trim() || undefined,
|
|
302
286
|
),
|
|
303
287
|
// @windy-module system.agent end
|
|
304
|
-
value(
|
|
305
|
-
"RUOYI_COMPAT_ENABLED",
|
|
306
|
-
"compatibility.ruoyiVue.enabled",
|
|
307
|
-
false,
|
|
308
|
-
strictBoolean,
|
|
309
|
-
),
|
|
310
|
-
value(
|
|
311
|
-
"RUOYI_RUNTIME_READONLY",
|
|
312
|
-
"compatibility.ruoyiVue.runtimeReadonly",
|
|
313
|
-
true,
|
|
314
|
-
strictBoolean,
|
|
315
|
-
),
|
|
316
288
|
],
|
|
317
289
|
});
|
|
318
290
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
CREATE TABLE "license_issuance_requests" (
|
|
2
|
+
"id" varchar(64) PRIMARY KEY NOT NULL,
|
|
3
|
+
"actor_id" varchar(64) NOT NULL,
|
|
4
|
+
"idempotency_key" varchar(160) NOT NULL,
|
|
5
|
+
"project_id" varchar(64) NOT NULL,
|
|
6
|
+
"request_digest" varchar(64) NOT NULL,
|
|
7
|
+
"review_digest" varchar(64) NOT NULL,
|
|
8
|
+
"license_id" varchar(64) NOT NULL,
|
|
9
|
+
"result_license_id" varchar(64),
|
|
10
|
+
"issued_at" timestamp with time zone NOT NULL,
|
|
11
|
+
"status" varchar(20) DEFAULT 'processing' NOT NULL,
|
|
12
|
+
"fence" integer DEFAULT 1 NOT NULL,
|
|
13
|
+
"lease_until" timestamp with time zone NOT NULL,
|
|
14
|
+
"error_code" varchar(80),
|
|
15
|
+
"error_reason" text,
|
|
16
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
17
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
18
|
+
CONSTRAINT "ck_license_issuance_status" CHECK ("license_issuance_requests"."status" in ('processing', 'failed', 'completed')),
|
|
19
|
+
CONSTRAINT "ck_license_issuance_result" CHECK (("license_issuance_requests"."status" = 'completed') = ("license_issuance_requests"."result_license_id" is not null))
|
|
20
|
+
);
|
|
21
|
+
--> statement-breakpoint
|
|
22
|
+
ALTER TABLE "license_contract_versions" ADD COLUMN "predecessor_id" varchar(64);--> statement-breakpoint
|
|
23
|
+
ALTER TABLE "license_issuance_requests" ADD CONSTRAINT "license_issuance_requests_project_id_license_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."license_projects"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
24
|
+
ALTER TABLE "license_issuance_requests" ADD CONSTRAINT "license_issuance_requests_result_license_id_licenses_id_fk" FOREIGN KEY ("result_license_id") REFERENCES "public"."licenses"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
25
|
+
CREATE UNIQUE INDEX "uk_license_issuance_actor_key" ON "license_issuance_requests" USING btree ("actor_id","idempotency_key");--> statement-breakpoint
|
|
26
|
+
CREATE UNIQUE INDEX "uk_license_issuance_license" ON "license_issuance_requests" USING btree ("license_id");--> statement-breakpoint
|
|
27
|
+
CREATE INDEX "idx_license_issuance_project" ON "license_issuance_requests" USING btree ("project_id","created_at");--> statement-breakpoint
|
|
28
|
+
ALTER TABLE "license_contract_versions" ADD CONSTRAINT "license_contract_versions_predecessor_id_license_contract_versions_id_fk" FOREIGN KEY ("predecessor_id") REFERENCES "public"."license_contract_versions"("id") ON DELETE restrict ON UPDATE no action;
|