@oj-module/cli 0.2.66 → 0.2.68

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 (200) hide show
  1. package/bin/.oj-version +1 -0
  2. package/bin/oj +4 -0
  3. package/devkit/README.md +15 -7
  4. package/devkit/SKILL.md +38 -4
  5. package/devkit/framework-dev.md +10 -4
  6. package/devkit/manual.md +146 -24
  7. package/devkit/menu-rules.md +19 -4
  8. package/devkit/module-dev-and-cdn-playground.md +4 -0
  9. package/devkit/publish-walkthrough.md +132 -37
  10. package/devkit/wecom-internal-app.md +8 -3
  11. package/devkit/wecom-multi-corp-links.md +163 -0
  12. package/package.json +2 -2
  13. package/shell-dist/assets/{index.i0kqbxp050.js → index.6alqyx6ae0.js} +21 -1
  14. package/shell-dist/assets/{runtime.1xfsxcajj0.js → runtime.1xzahckt10.js} +4863 -4847
  15. package/shell-dist/index.html +4 -4
  16. package/shell-dist/versions.json +3 -3
  17. package/src/__tests__/cli.test.ts +31 -0
  18. package/src/__tests__/new-scaffold.test.ts +13 -0
  19. package/src/__tests__/publish-keygen.test.ts +157 -0
  20. package/src/__tests__/templates-migration-schema-parity.test.ts +540 -0
  21. package/src/__tests__/templates-schema-columns.test.ts +15 -2
  22. package/src/__tests__/templates-tenant-scope.test.ts +6 -2
  23. package/src/build/module-def.ts +1 -0
  24. package/src/builtin.ts +3 -2
  25. package/src/bundle.ts +8 -3
  26. package/src/cli.ts +21 -5
  27. package/src/dev.ts +15 -10
  28. package/src/init.ts +47 -41
  29. package/src/install.ts +11 -4
  30. package/src/keygen.ts +54 -0
  31. package/src/lifecycle/__tests__/bundle.test.ts +21 -3
  32. package/src/lifecycle/__tests__/fixtures/fixture-valid/api/src/demo-solution/manifest.yaml +1 -1
  33. package/src/lifecycle/__tests__/fixtures/fixture-valid/api/src/demo-solution/migrations/0001__init.sql +2 -2
  34. package/src/lifecycle/__tests__/fixtures/fixture-valid/api/src/demo-solution/schema.yaml +5 -2
  35. package/src/lifecycle/__tests__/fixtures/fixture-valid/manifest.yaml +1 -1
  36. package/src/lifecycle/__tests__/manifest-contract.test.ts +75 -3
  37. package/src/lifecycle/__tests__/smoke.test.ts +2 -2
  38. package/src/manifest-contract.ts +91 -8
  39. package/src/market/bootstrap.ts +26 -2
  40. package/src/market/command.ts +1 -0
  41. package/src/market/publish.ts +8 -1
  42. package/src/market/walkthrough.ts +24 -8
  43. package/src/new.ts +2 -0
  44. package/src/scaffold-guard.ts +227 -0
  45. package/src/site.ts +2 -0
  46. package/src/usage.ts +13 -9
  47. package/src/vendor.ts +5 -1
  48. package/templates/config.yaml +4 -2
  49. package/templates/init.include.yaml +10 -3
  50. package/templates/openapi.json +460 -1
  51. package/templates/src/README.md +37 -0
  52. package/templates/src/app/api/_platform/_lifecycle/compensate.ts +136 -0
  53. package/templates/src/app/api/_platform/_lifecycle/installer.ts +78 -25
  54. package/templates/src/app/api/_platform/_lifecycle/lock.ts +23 -0
  55. package/templates/src/app/api/_platform/_lifecycle/steps/deploy-web.ts +28 -0
  56. package/templates/src/app/api/_platform/_lifecycle/steps/preflight.ts +46 -0
  57. package/templates/src/app/api/_platform/_lifecycle/steps/reload.ts +100 -36
  58. package/templates/src/app/api/_platform/_lifecycle/steps/smoke.ts +7 -15
  59. package/templates/src/app/api/_platform/_lifecycle/text-edit.ts +71 -19
  60. package/templates/src/app/api/_platform/_lifecycle/types.ts +26 -2
  61. package/templates/src/app/api/_platform/_lifecycle/uninstall.ts +93 -14
  62. package/templates/src/app/api/_platform/_shared/service/domain/settings.ts +8 -4
  63. package/templates/src/app/api/_platform/_shared/service/domain/solution-perms.ts +25 -10
  64. package/templates/src/app/api/_platform/manifest.yaml +1 -0
  65. package/templates/src/app/api/_platform/market/api.ts +235 -10
  66. package/templates/src/app/api/_platform/migrations/0001__baseline.mysql.sql +178 -0
  67. package/templates/src/app/api/_platform/migrations/0001__baseline.pg.sql +173 -0
  68. package/templates/src/app/api/_platform/migrations/0001__baseline.sql +188 -0
  69. package/templates/src/app/api/_platform/migrations/0002__market_release.mysql.sql +17 -0
  70. package/templates/src/app/api/_platform/migrations/0002__market_release.pg.sql +16 -0
  71. package/templates/src/app/api/_platform/migrations/0002__market_release.sql +33 -0
  72. package/templates/src/app/api/_platform/schema.yaml +18 -0
  73. package/templates/src/app/api/_platform/seed.mysql.sql +10 -0
  74. package/templates/src/app/api/_platform/seed.pg.sql +10 -0
  75. package/templates/src/app/api/auth/_shared/wecom/client.ts +24 -4
  76. package/templates/src/app/api/home/migrations/0001__create_home_tables.mysql.sql +14 -0
  77. package/templates/src/app/api/home/migrations/0001__create_home_tables.pg.sql +14 -0
  78. package/templates/src/app/api/home/migrations/0002__tenant.pg.sql +4 -0
  79. package/templates/src/app/api/home/seed.mysql.sql +71 -0
  80. package/templates/src/app/api/home/seed.pg.sql +71 -0
  81. package/templates/src/app/api/notification/_shared/notify.ts +6 -6
  82. package/templates/src/app/api/notification/migrations/0001__create_notifications.mysql.sql +11 -0
  83. package/templates/src/app/api/notification/migrations/0001__create_notifications.pg.sql +11 -0
  84. package/templates/src/app/api/notification/migrations/0002__notifications_user.mysql.sql +8 -0
  85. package/templates/src/app/api/notification/migrations/0003__notifications_broadcast.mysql.sql +21 -0
  86. package/templates/src/app/api/notification/migrations/0003__notifications_broadcast.pg.sql +22 -0
  87. package/templates/src/app/api/notification/migrations/0004__notifications_broadcast_hidden.mysql.sql +10 -0
  88. package/templates/src/app/api/notification/migrations/0004__notifications_broadcast_hidden.pg.sql +11 -0
  89. package/templates/src/app/api/notification/migrations/0005__tenant.pg.sql +6 -0
  90. package/templates/src/app/api/notification/seed.mysql.sql +8 -0
  91. package/templates/src/app/api/notification/seed.pg.sql +11 -0
  92. package/templates/src/app/api/publish/_shared/identity.ts +69 -0
  93. package/templates/src/app/api/publish/api.ts +349 -0
  94. package/templates/src/app/api/publish/manifest.yaml +8 -0
  95. package/templates/src/app/api/publish/migrations/0001__publish_credential.mysql.sql +23 -0
  96. package/templates/src/app/api/publish/migrations/0001__publish_credential.pg.sql +23 -0
  97. package/templates/src/app/api/publish/migrations/0001__publish_credential.sql +39 -0
  98. package/templates/src/app/api/publish/schema.yaml +33 -0
  99. package/templates/src/app/api/system/login-methods/api.ts +2 -1
  100. package/templates/src/app/web/_platform/__client/api.schemas.ts +15 -0
  101. package/templates/src/app/web/_platform/__client/index.ts +25 -1
  102. package/templates/src/app/web/entry.ts +9 -5
  103. package/templates/src/app/web/home/routes.ts +5 -0
  104. package/templates/src/app/web/login/locales/en-US.json +7 -1
  105. package/templates/src/app/web/login/locales/zh-CN.json +7 -1
  106. package/templates/src/app/web/login/pages/login.tsx +79 -86
  107. package/templates/src/app/web/login/routes.ts +54 -1
  108. package/templates/src/app/web/personal-center/locales/en-US.json +1 -0
  109. package/templates/src/app/web/personal-center/locales/zh-CN.json +1 -0
  110. package/templates/src/app/web/personal-center/pages/my-profile/index.tsx +5 -0
  111. package/templates/src/app/web/system/__client/api.schemas.ts +2 -1
  112. package/templates/src/app/web/system/locales/en-US.json +1 -8
  113. package/templates/src/app/web/system/locales/zh-CN.json +1 -8
  114. package/templates/src/app/web/system/pages/settings/index.tsx +17 -4
  115. package/templates/src/app/web/system/routes.ts +0 -6
  116. package/templates/src/oj-market/web/__tests__/CardGrid.test.tsx +33 -0
  117. package/templates/src/oj-market/web/__tests__/DetailDrawer.test.tsx +69 -0
  118. package/templates/src/oj-market/web/__tests__/marketClient.fake.ts +7 -1
  119. package/templates/src/oj-market/web/api/client.ts +3 -0
  120. package/templates/src/oj-market/web/api/defaultClient.ts +5 -0
  121. package/templates/src/oj-market/web/components/CardItem.tsx +44 -1
  122. package/templates/src/oj-market/web/components/DetailDrawer.tsx +17 -1
  123. package/templates/src/oj-market/web/entry.ts +31 -2
  124. package/templates/src/oj-market/web/locales/en-US.json +5 -1
  125. package/templates/src/oj-market/web/locales/zh-CN.json +5 -1
  126. package/templates/src/oj-market/web/publish/__client/api.schemas.ts +61 -0
  127. package/templates/src/oj-market/web/publish/__client/index.ts +164 -0
  128. package/templates/src/oj-market/web/publish/locales/en-US.json +80 -0
  129. package/templates/src/oj-market/web/publish/locales/zh-CN.json +80 -0
  130. package/templates/src/oj-market/web/publish/pages/history.tsx +112 -0
  131. package/templates/src/oj-market/web/publish/pages/index.tsx +196 -0
  132. package/templates/src/oj-market/web/publish/pages/model.ts +52 -0
  133. package/templates/src/oj-market/web/publish/pages/token-modal.tsx +82 -0
  134. package/templates/src/oj-market/web/publish/routes.ts +41 -0
  135. package/templates/src/oj-market/web/types.ts +30 -0
  136. package/templates/tests/lifecycle/compensate.spec.ts +207 -0
  137. package/templates/tests/lifecycle/deploy-smoke.spec.ts +38 -14
  138. package/templates/tests/lifecycle/installer.spec.ts +28 -9
  139. package/templates/tests/lifecycle/market-api.spec.ts +164 -12
  140. package/templates/tests/lifecycle/preflight.spec.ts +68 -0
  141. package/templates/tests/lifecycle/register.spec.ts +22 -0
  142. package/templates/tests/lifecycle/role-title-translate.spec.ts +4 -34
  143. package/templates/tests/lifecycle/text-edit.spec.ts +45 -27
  144. package/templates/tests/lifecycle/uninstall.spec.ts +36 -0
  145. package/templates/tests/publish-credential.spec.ts +354 -0
  146. package/templates/tests/publish-identity.spec.ts +44 -0
  147. package/templates/tests/rbac-solution-perms.spec.ts +48 -3
  148. package/templates/tests/wecom-client-timeout.spec.ts +33 -3
  149. package/templates/tests/wecom-landing.spec.ts +63 -1
  150. package/templates/tsconfig.paths.json +1 -0
  151. package/templates/web.config.ts +8 -4
  152. package/vendor/host-versions.json +3 -3
  153. package/templates/seed.mysql.sql +0 -6
  154. package/templates/seed.pg.sql +0 -6
  155. package/templates/src/app/api/_platform/migrations/0001__create_users.mysql.sql +0 -9
  156. package/templates/src/app/api/_platform/migrations/0001__create_users.pg.sql +0 -9
  157. package/templates/src/app/api/_platform/migrations/0001__create_users.sql +0 -7
  158. package/templates/src/app/api/_platform/migrations/0002__add_users_avatar_base64.mysql.sql +0 -3
  159. package/templates/src/app/api/_platform/migrations/0002__add_users_avatar_base64.sql +0 -2
  160. package/templates/src/app/api/_platform/migrations/0003__users_source_display_name.mysql.sql +0 -5
  161. package/templates/src/app/api/_platform/migrations/0003__users_source_display_name.sql +0 -5
  162. package/templates/src/app/api/_platform/migrations/0004__sys_rbac.mysql.sql +0 -70
  163. package/templates/src/app/api/_platform/migrations/0004__sys_rbac.pg.sql +0 -67
  164. package/templates/src/app/api/_platform/migrations/0004__sys_rbac.sql +0 -67
  165. package/templates/src/app/api/_platform/migrations/0005__users_must_change.mysql.sql +0 -3
  166. package/templates/src/app/api/_platform/migrations/0005__users_must_change.sql +0 -2
  167. package/templates/src/app/api/_platform/migrations/0006__users_is_forbidden.mysql.sql +0 -3
  168. package/templates/src/app/api/_platform/migrations/0006__users_is_forbidden.sql +0 -3
  169. package/templates/src/app/api/_platform/migrations/0007__users_email.sql +0 -3
  170. package/templates/src/app/api/_platform/migrations/0008__sys_refresh_token.mysql.sql +0 -10
  171. package/templates/src/app/api/_platform/migrations/0008__sys_refresh_token.pg.sql +0 -10
  172. package/templates/src/app/api/_platform/migrations/0008__sys_refresh_token.sql +0 -11
  173. package/templates/src/app/api/_platform/migrations/0009__sys_throttle.mysql.sql +0 -12
  174. package/templates/src/app/api/_platform/migrations/0009__sys_throttle.pg.sql +0 -12
  175. package/templates/src/app/api/_platform/migrations/0009__sys_throttle.sql +0 -13
  176. package/templates/src/app/api/_platform/migrations/0010__sys_solution_route.mysql.sql +0 -17
  177. package/templates/src/app/api/_platform/migrations/0010__sys_solution_route.pg.sql +0 -16
  178. package/templates/src/app/api/_platform/migrations/0010__sys_solution_route.sql +0 -18
  179. package/templates/src/app/api/_platform/migrations/0011__sys_setting_group_label.mysql.sql +0 -2
  180. package/templates/src/app/api/_platform/migrations/0011__sys_setting_group_label.sql +0 -4
  181. package/templates/src/app/api/_platform/migrations/0012__market_history.mysql.sql +0 -13
  182. package/templates/src/app/api/_platform/migrations/0012__market_history.pg.sql +0 -12
  183. package/templates/src/app/api/_platform/migrations/0012__market_history.sql +0 -14
  184. package/templates/src/app/api/_platform/migrations/0013__users_profile.sql +0 -4
  185. package/templates/src/app/api/_platform/migrations/0014__reg_source_seq.mysql.sql +0 -9
  186. package/templates/src/app/api/_platform/migrations/0014__reg_source_seq.pg.sql +0 -7
  187. package/templates/src/app/api/_platform/migrations/0014__reg_source_seq.sql +0 -8
  188. package/templates/src/app/api/_platform/migrations/0015__tenant.mysql.sql +0 -12
  189. package/templates/src/app/api/_platform/migrations/0015__tenant.pg.sql +0 -11
  190. package/templates/src/app/api/_platform/migrations/0015__tenant.sql +0 -44
  191. package/templates/src/app/api/_platform/migrations/0016__org.mysql.sql +0 -41
  192. package/templates/src/app/api/_platform/migrations/0016__org.pg.sql +0 -40
  193. package/templates/src/app/api/_platform/migrations/0016__org.sql +0 -62
  194. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.mysql.sql +0 -7
  195. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.pg.sql +0 -4
  196. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.sql +0 -8
  197. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.mysql.sql +0 -3
  198. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.pg.sql +0 -3
  199. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.sql +0 -8
  200. package/templates/src/app/web/system/pages/login-methods/index.tsx +0 -30
package/src/vendor.ts CHANGED
@@ -43,8 +43,12 @@ export const NPM_PKG = "@oj-bin/oj";
43
43
  * `__client` 内省 fail-fast,`oj openapi --module-root` 契约链整体不可用)修复于
44
44
  * 0.1.86(oj-bin 0f8a6e2,第三次基线发布通道实证);module-root 工程是 0.2.20 起
45
45
  * 的默认布局,门禁必须盖住契约链(见 playbook §9 与 2026-10-23 第三次基线)。
46
+ * **0.2.68 抬到 0.1.121**:模板的方言 seed(`seed.mysql.sql` / `seed.pg.sql`)依赖
47
+ * 0.1.121 的「方言件胜出、`seed.sql` 兜底」选择语义(oj-bin 7d70b90);更早的 oj
48
+ * 只读 `seed.sql`,三方言执行同一份 sqlite 写法 → mysql/pg 上 1064 拒启。模板不再
49
+ * 教「部署期手工覆盖」,门禁必须盖住这条链路(见 playbook §11 U1)。
46
50
  */
47
- export const MIN_OJ_VERSION = "0.1.86";
51
+ export const MIN_OJ_VERSION = "0.1.121";
48
52
 
49
53
  /** 按段数值比较(字符串比较会把 0.1.9 判成大于 0.1.69);非数字段按 0 处理 */
50
54
  export function isSupportedOjVersion(version: string): boolean {
@@ -50,8 +50,6 @@ db:
50
50
  default: 'sqlite://db.sqlite' # 相对 config 目录;缺文件自动建空库
51
51
 
52
52
  vars:
53
- # ojm install 每次安装自增一次,用来触发 reload 热更。别删行、别手工回写旧值。
54
- ojm_install_seq: 0
55
53
  # 站点对外地址。装方案时服务端拿它把 /cdn 这类相对地址补全成绝对 URL(深检探针也用它)。
56
54
  # 故意不读请求头 Host(防伪造 Host 牵引出站):不配 = fail-closed,不会替你猜。
57
55
  # canonical_origin: "https://your-site.example.com"
@@ -160,6 +158,7 @@ auth:
160
158
  - /auth/wecom/callback # 企微 302 回跳:code 即凭证,此时还没有本地会话
161
159
  - /auth/wecom/ticket # 一次性票据换 TokenBundle:票据本身就是「刚验过的登录证明」
162
160
  - /auth/wecom/event # 企微指令回调:靠 msg_signature 验签,不走 Bearer
161
+ - /publish/credential/exchange # 凭证换发布身份:凭证自身即持有型证明,CLI 可能没有账号密码
163
162
 
164
163
  # 多租户(企微代开发 v3 Phase 0):开启后所有 {base} 请求必须带 X-TENANT-ID,否则 400。
165
164
  # 前端由 tenantStore + headerProvider 统一注入(单租户部署恒为 default,UX 不变)。
@@ -180,10 +179,12 @@ tenant:
180
179
  - sys_rate_window # 限速窗口(登录前就要用)
181
180
  - sys_login_throttle # 登录节流(登录前就要用)
182
181
  - market_history # 解决方案安装/升级/回滚是站点级留痕
182
+ - market_release # 发布历史:CDN 是站点级的,历史按站点归口
183
183
  - reg_source_seq # 索引新鲜度水位属于站点(防回放)
184
184
  - wecom_app_profile # 企微 corp→租户映射权威:查它时必然还没有租户上下文(D9)
185
185
  - wecom_suite_ticket # 套件级凭证,按 suite_id 全局唯一
186
186
  - wecom_login_ticket # 一次性登录票据:跨「匿名 302 回跳」与「已认证换取」两段
187
+ - publish_credential # 发布凭证:CLI 兑换那一跳没有业务租户语义,归属走 owner_tenant 列
187
188
  # 豁免缺租户头的路径(去 base 前缀后的形态)。与 auth.anonymous_paths 同语义,
188
189
  # 但这是「没有租户头也不 400」的逃生口,只给**真的拿不到头**的端点。
189
190
  # 登录类端点不在此列:前端 headerProvider 每请求都注头(单租户恒 default),
@@ -196,6 +197,7 @@ tenant:
196
197
  - /auth/wecom/callback # 企微 302 回跳:浏览器带不了头,租户由 state→profile 推导
197
198
  - /auth/wecom/ticket # 一次性票据换会话:租户由票据行携带
198
199
  - /auth/wecom/event # 企微指令回调:验签+解密即认证,无租户语义
200
+ - /publish/credential/exchange # 凭证兑换:CLI 的裸 fetch 不带租户头;表本身是共享表(B 组)
199
201
  # tenant.require_signed_claim:租户头的服务端绑定(平台级 fail-closed)。
200
202
  # 暂保持 false——上游 oj 的 jwt.sign 目前会静默丢弃自定义 claim(需求 R6),
201
203
  # 开启前无法把 tenant 放进 token。R6 落地后改 true,裸头即失去自证能力。
@@ -37,14 +37,16 @@ include:
37
37
  - types
38
38
  - web.config.ts
39
39
  - openapi.json
40
+ # src 下的模块分区说明(内置模块自治契约的人话版,动手前必读)
41
+ - src/README.md
40
42
  - src/styles.css
41
43
  # 后端 typecheck 工程(package.json 的 typecheck:api 指向它);只收后端、排除 web
42
44
  - src/tsconfig.json
43
- # —— 后端:配置 / 种子 / 测试 / 默认模块(模块源码在 src/app/api/<模块>)——
45
+ # —— 后端:配置 / 测试 / 默认模块(模块源码在 src/app/api/<模块>)——
46
+ # 方言 seed 不在这里列:它们是模块资产(`src/app/api/<模块>/seed.<dialect>.sql`),
47
+ # 根级副本会与模块内那份漂移(历史上一份只含 4 条设置、且 mysql 侧裸写保留字列),已删除。
44
48
  - config.yaml
45
49
  - .ojm-api-exempt.json
46
- - seed.mysql.sql
47
- - seed.pg.sql
48
50
  - vitest.config.ts
49
51
  # —— tests 逐条白名单(不收 tests/ 整目录)——
50
52
  # 业务工程只拷「纯 node:sqlite 夹具、零 cli 包环境假设」的测试。以下 6 个不分发
@@ -74,6 +76,9 @@ include:
74
76
  # 角色页展示层过滤 superadmin(后端 listRoles 仍返回;页面源码随 src/app/web/system 下发)
75
77
  - tests/roles-page.spec.ts
76
78
  - tests/seed-role-accounts.spec.ts
79
+ # 发布凭证:身份推导规则是跨端共用的口径,随源码下发,用户工程可本地自检
80
+ - tests/publish-identity.spec.ts
81
+ - tests/publish-credential.spec.ts
77
82
  # 用户页行级门禁:只有 superadmin 能改 superadmin 账号(后端 assertCanManageTarget 的另一面)
78
83
  - tests/users-page.spec.ts
79
84
  # 企微连接器与组织同步:源码本就分发(src/app/api/auth),对应回归也必须跟着走,
@@ -105,6 +110,7 @@ include:
105
110
  - src/app/api/auth
106
111
  - src/app/api/notification
107
112
  - src/app/api/personal-center
113
+ - src/app/api/publish
108
114
  - src/app/api/system
109
115
  - src/app/api/web
110
116
  # —— web 前端模块 ——
@@ -132,5 +138,6 @@ include:
132
138
  - src/oj-market/web/hooks
133
139
  - src/oj-market/web/locales
134
140
  - src/oj-market/web/pages
141
+ - src/oj-market/web/publish
135
142
  - src/oj-market/web/utils
136
143
  - src/app/web/web
@@ -870,6 +870,96 @@
870
870
  }
871
871
  }
872
872
  },
873
+ "/api/_platform/market/releases": {
874
+ "get": {
875
+ "operationId": "_platform_market_releases_get",
876
+ "summary": "GET api/_platform/market/releases",
877
+ "x-oj-file": "app/api/_platform/market/api.ts",
878
+ "tags": [
879
+ "_platform"
880
+ ],
881
+ "parameters": [
882
+ {
883
+ "name": "page",
884
+ "in": "query",
885
+ "required": false,
886
+ "schema": {
887
+ "type": "number",
888
+ "minimum": 1
889
+ }
890
+ },
891
+ {
892
+ "name": "limit",
893
+ "in": "query",
894
+ "required": false,
895
+ "schema": {
896
+ "type": "number",
897
+ "minimum": 1,
898
+ "maximum": 200
899
+ }
900
+ }
901
+ ],
902
+ "responses": {
903
+ "200": {
904
+ "description": "OK",
905
+ "x-oj-response-enforced": false,
906
+ "content": {
907
+ "application/json": {
908
+ "schema": {
909
+ "type": "object",
910
+ "required": [
911
+ "code",
912
+ "msg",
913
+ "data"
914
+ ],
915
+ "properties": {
916
+ "code": {
917
+ "type": "integer"
918
+ },
919
+ "msg": {
920
+ "type": "string"
921
+ },
922
+ "data": {
923
+ "type": "object",
924
+ "required": [
925
+ "list",
926
+ "total",
927
+ "page",
928
+ "size"
929
+ ],
930
+ "properties": {
931
+ "list": {
932
+ "type": "array",
933
+ "items": {
934
+ "type": "object",
935
+ "additionalProperties": true
936
+ }
937
+ },
938
+ "total": {
939
+ "type": "number"
940
+ },
941
+ "page": {
942
+ "type": "number"
943
+ },
944
+ "size": {
945
+ "type": "number"
946
+ },
947
+ "syncError": {
948
+ "type": [
949
+ "string",
950
+ "null"
951
+ ]
952
+ }
953
+ }
954
+ }
955
+ }
956
+ }
957
+ }
958
+ }
959
+ }
960
+ }
961
+ }
962
+ },
873
963
  "/api/_platform/org/departments": {
874
964
  "get": {
875
965
  "operationId": "_platform_org_departments_get",
@@ -4536,6 +4626,368 @@
4536
4626
  }
4537
4627
  }
4538
4628
  },
4629
+ "/api/publish/credential": {
4630
+ "get": {
4631
+ "operationId": "publish_credential_get",
4632
+ "summary": "GET api/publish/credential",
4633
+ "x-oj-file": "app/api/publish/api.ts",
4634
+ "tags": [
4635
+ "publish"
4636
+ ],
4637
+ "parameters": [
4638
+ {
4639
+ "name": "page",
4640
+ "in": "query",
4641
+ "required": false,
4642
+ "schema": {
4643
+ "type": "number",
4644
+ "minimum": 1
4645
+ }
4646
+ },
4647
+ {
4648
+ "name": "limit",
4649
+ "in": "query",
4650
+ "required": false,
4651
+ "schema": {
4652
+ "type": "number",
4653
+ "minimum": 1,
4654
+ "maximum": 200
4655
+ }
4656
+ },
4657
+ {
4658
+ "name": "tenant",
4659
+ "in": "query",
4660
+ "required": false,
4661
+ "schema": {
4662
+ "type": "string"
4663
+ }
4664
+ }
4665
+ ],
4666
+ "responses": {
4667
+ "200": {
4668
+ "description": "OK",
4669
+ "x-oj-response-enforced": false,
4670
+ "content": {
4671
+ "application/json": {
4672
+ "schema": {
4673
+ "type": "object",
4674
+ "required": [
4675
+ "code",
4676
+ "msg",
4677
+ "data"
4678
+ ],
4679
+ "properties": {
4680
+ "code": {
4681
+ "type": "integer"
4682
+ },
4683
+ "msg": {
4684
+ "type": "string"
4685
+ },
4686
+ "data": {
4687
+ "type": "object",
4688
+ "required": [
4689
+ "list",
4690
+ "total"
4691
+ ],
4692
+ "properties": {
4693
+ "list": {
4694
+ "type": "array",
4695
+ "items": {
4696
+ "type": "object",
4697
+ "required": [
4698
+ "id",
4699
+ "product",
4700
+ "key_id",
4701
+ "username",
4702
+ "token_hint",
4703
+ "status",
4704
+ "expires_at",
4705
+ "created_at"
4706
+ ],
4707
+ "properties": {
4708
+ "id": {
4709
+ "type": "number"
4710
+ },
4711
+ "product": {
4712
+ "type": "string"
4713
+ },
4714
+ "key_id": {
4715
+ "type": "string"
4716
+ },
4717
+ "username": {
4718
+ "type": "string"
4719
+ },
4720
+ "display_name": {
4721
+ "type": [
4722
+ "string",
4723
+ "null"
4724
+ ]
4725
+ },
4726
+ "token_hint": {
4727
+ "type": "string"
4728
+ },
4729
+ "status": {
4730
+ "type": "string",
4731
+ "enum": [
4732
+ "active",
4733
+ "used",
4734
+ "revoked",
4735
+ "expired"
4736
+ ]
4737
+ },
4738
+ "expires_at": {
4739
+ "type": "number"
4740
+ },
4741
+ "used_at": {
4742
+ "type": [
4743
+ "number",
4744
+ "null"
4745
+ ]
4746
+ },
4747
+ "created_at": {
4748
+ "type": "number"
4749
+ },
4750
+ "owner_tenant": {
4751
+ "type": "string"
4752
+ }
4753
+ }
4754
+ }
4755
+ },
4756
+ "total": {
4757
+ "type": "number"
4758
+ }
4759
+ }
4760
+ }
4761
+ }
4762
+ }
4763
+ }
4764
+ }
4765
+ }
4766
+ }
4767
+ },
4768
+ "post": {
4769
+ "operationId": "publish_credential_post",
4770
+ "summary": "POST api/publish/credential",
4771
+ "x-oj-file": "app/api/publish/api.ts",
4772
+ "tags": [
4773
+ "publish"
4774
+ ],
4775
+ "requestBody": {
4776
+ "required": true,
4777
+ "content": {
4778
+ "application/json": {
4779
+ "schema": {
4780
+ "type": "object",
4781
+ "required": [
4782
+ "product"
4783
+ ],
4784
+ "properties": {
4785
+ "product": {
4786
+ "type": "string"
4787
+ }
4788
+ }
4789
+ }
4790
+ }
4791
+ }
4792
+ },
4793
+ "responses": {
4794
+ "200": {
4795
+ "description": "OK",
4796
+ "x-oj-response-enforced": false,
4797
+ "content": {
4798
+ "application/json": {
4799
+ "schema": {
4800
+ "type": "object",
4801
+ "required": [
4802
+ "code",
4803
+ "msg",
4804
+ "data"
4805
+ ],
4806
+ "properties": {
4807
+ "code": {
4808
+ "type": "integer"
4809
+ },
4810
+ "msg": {
4811
+ "type": "string"
4812
+ },
4813
+ "data": {
4814
+ "type": "object",
4815
+ "required": [
4816
+ "token",
4817
+ "key_id",
4818
+ "product",
4819
+ "expires_at"
4820
+ ],
4821
+ "properties": {
4822
+ "token": {
4823
+ "type": "string"
4824
+ },
4825
+ "key_id": {
4826
+ "type": "string"
4827
+ },
4828
+ "product": {
4829
+ "type": "string"
4830
+ },
4831
+ "token_hint": {
4832
+ "type": "string"
4833
+ },
4834
+ "expires_at": {
4835
+ "type": "number"
4836
+ }
4837
+ }
4838
+ }
4839
+ }
4840
+ }
4841
+ }
4842
+ }
4843
+ }
4844
+ }
4845
+ }
4846
+ },
4847
+ "/api/publish/credential/revoke": {
4848
+ "post": {
4849
+ "operationId": "publish_credential_revoke_post",
4850
+ "summary": "POST api/publish/credential/revoke",
4851
+ "x-oj-file": "app/api/publish/api.ts",
4852
+ "tags": [
4853
+ "publish"
4854
+ ],
4855
+ "requestBody": {
4856
+ "required": true,
4857
+ "content": {
4858
+ "application/json": {
4859
+ "schema": {
4860
+ "type": "object",
4861
+ "required": [
4862
+ "id"
4863
+ ],
4864
+ "properties": {
4865
+ "id": {
4866
+ "type": "number"
4867
+ }
4868
+ }
4869
+ }
4870
+ }
4871
+ }
4872
+ },
4873
+ "responses": {
4874
+ "200": {
4875
+ "description": "OK",
4876
+ "x-oj-response-enforced": false,
4877
+ "content": {
4878
+ "application/json": {
4879
+ "schema": {
4880
+ "type": "object",
4881
+ "required": [
4882
+ "code",
4883
+ "msg",
4884
+ "data"
4885
+ ],
4886
+ "properties": {
4887
+ "code": {
4888
+ "type": "integer"
4889
+ },
4890
+ "msg": {
4891
+ "type": "string"
4892
+ },
4893
+ "data": {
4894
+ "type": "object",
4895
+ "required": [
4896
+ "ok"
4897
+ ],
4898
+ "properties": {
4899
+ "ok": {
4900
+ "type": "boolean"
4901
+ }
4902
+ }
4903
+ }
4904
+ }
4905
+ }
4906
+ }
4907
+ }
4908
+ }
4909
+ }
4910
+ }
4911
+ },
4912
+ "/api/publish/credential/exchange": {
4913
+ "post": {
4914
+ "operationId": "publish_credential_exchange_post",
4915
+ "summary": "POST api/publish/credential/exchange",
4916
+ "x-oj-file": "app/api/publish/api.ts",
4917
+ "tags": [
4918
+ "publish"
4919
+ ],
4920
+ "requestBody": {
4921
+ "required": true,
4922
+ "content": {
4923
+ "application/json": {
4924
+ "schema": {
4925
+ "type": "object",
4926
+ "required": [
4927
+ "token"
4928
+ ],
4929
+ "properties": {
4930
+ "token": {
4931
+ "type": "string"
4932
+ }
4933
+ }
4934
+ }
4935
+ }
4936
+ }
4937
+ },
4938
+ "responses": {
4939
+ "200": {
4940
+ "description": "OK",
4941
+ "x-oj-response-enforced": false,
4942
+ "content": {
4943
+ "application/json": {
4944
+ "schema": {
4945
+ "type": "object",
4946
+ "required": [
4947
+ "code",
4948
+ "msg",
4949
+ "data"
4950
+ ],
4951
+ "properties": {
4952
+ "code": {
4953
+ "type": "integer"
4954
+ },
4955
+ "msg": {
4956
+ "type": "string"
4957
+ },
4958
+ "data": {
4959
+ "type": "object",
4960
+ "required": [
4961
+ "key_id",
4962
+ "product",
4963
+ "username"
4964
+ ],
4965
+ "properties": {
4966
+ "key_id": {
4967
+ "type": "string"
4968
+ },
4969
+ "product": {
4970
+ "type": "string"
4971
+ },
4972
+ "username": {
4973
+ "type": "string"
4974
+ },
4975
+ "display_name": {
4976
+ "type": [
4977
+ "string",
4978
+ "null"
4979
+ ]
4980
+ }
4981
+ }
4982
+ }
4983
+ }
4984
+ }
4985
+ }
4986
+ }
4987
+ }
4988
+ }
4989
+ }
4990
+ },
4539
4991
  "/api/system/departments": {
4540
4992
  "get": {
4541
4993
  "operationId": "system_departments_get",
@@ -5325,7 +5777,8 @@
5325
5777
  "data": {
5326
5778
  "type": "object",
5327
5779
  "required": [
5328
- "methods"
5780
+ "methods",
5781
+ "site_title"
5329
5782
  ],
5330
5783
  "properties": {
5331
5784
  "methods": {
@@ -5333,6 +5786,9 @@
5333
5786
  "items": {
5334
5787
  "type": "string"
5335
5788
  }
5789
+ },
5790
+ "site_title": {
5791
+ "type": "string"
5336
5792
  }
5337
5793
  }
5338
5794
  }
@@ -6862,6 +7318,9 @@
6862
7318
  {
6863
7319
  "name": "personal-center"
6864
7320
  },
7321
+ {
7322
+ "name": "publish"
7323
+ },
6865
7324
  {
6866
7325
  "name": "system"
6867
7326
  },
@@ -0,0 +1,37 @@
1
+ # src/ 目录说明(动手前必读)
2
+
3
+ 这个目录里有两类东西,规矩不一样。
4
+
5
+ ## 框架自带的模块(不许改)
6
+
7
+ - `src/app/` —— 框架内置页面与后端(登录、首页、个人中心、通知、系统管理、认证等)
8
+ - `src/oj-market/` —— 解决方案市场
9
+
10
+ 它们由上游统一维护、跟着框架版本走。**请不要修改、也不要删除这里的文件**:
11
+
12
+ - `ojm build` 打包前会逐文件核对这两个目录,发现与官方版本不一致(改过、删过、
13
+ 或多出文件)会**直接拒绝构建**,并列出差异清单。
14
+ - 为什么这么严:你今天改一行,下次升级就对不上——轻则构建失败,重则升级后
15
+ 功能悄悄丢失。上游修过的 bug,会在你本地"复活"。
16
+ - 想改功能、加需求?给上游提 issue,等新版本下发后运行:
17
+
18
+ ```
19
+ ojm init --yes
20
+ ```
21
+
22
+ 它会把这两个目录恢复成当前版本的官方内容。注意:**会丢弃你在里面的本地修改**,
23
+ 执行前先备份。你自己的模块和 config.yaml 等工程配置不受影响。
24
+ - 真的不想要某个自带能力?在 `web.config.ts` 里把对应条目写 `enabled: false`,
25
+ 不要删目录。
26
+ - 删除 `src/.ojm-builtin.json` 会整个关掉上面的检查——不建议,出了问题没人替你兜底。
27
+
28
+ ## 你自己的模块(随便改)
29
+
30
+ - `src/<你的模块名>/` —— 用 `ojm new <名字>` 生成,或手工建 `src/<名字>/{api,web}`。
31
+
32
+ 这里是你的地盘:框架不检查、也不会覆盖。
33
+
34
+ ## 一句话总结
35
+
36
+ > `src/app` 和 `src/oj-market` 是"公家"的,`src/` 下其他目录是你自己的。
37
+ > 公家的不许动(动了 `ojm build` 会拦);要动找上游;升级后跑 `ojm init --yes` 同步。