@oj-module/cli 0.2.54 → 0.2.57

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 (307) hide show
  1. package/devkit/README.md +7 -4
  2. package/devkit/SKILL.md +7 -4
  3. package/devkit/manual.md +63 -54
  4. package/devkit/module-dev-and-cdn-playground.md +7 -0
  5. package/devkit/publish-walkthrough.md +199 -0
  6. package/package.json +2 -2
  7. package/shell-dist/assets/{index-e_Mp2mb5.js → index-CImwskAz.js} +24 -11
  8. package/shell-dist/assets/runtime.js +5 -5
  9. package/shell-dist/index.html +3 -3
  10. package/shell-dist/versions.json +3 -3
  11. package/src/__tests__/layout.test.ts +30 -1
  12. package/src/__tests__/templates-schema-columns.test.ts +99 -0
  13. package/src/__tests__/vendor-devkit.test.ts +87 -0
  14. package/src/alias-paths.ts +11 -12
  15. package/src/build/backend.ts +131 -0
  16. package/src/build/module-build.ts +364 -0
  17. package/src/build/module-def.ts +381 -0
  18. package/src/build/site-merge.ts +33 -0
  19. package/src/build.ts +16 -885
  20. package/src/builtin.ts +10 -3
  21. package/src/bundle.ts +61 -0
  22. package/src/cli.ts +4 -1
  23. package/src/contract/__tests__/emit-client.test.ts +4 -4
  24. package/src/contract/__tests__/market-client.integration.test.ts +2 -2
  25. package/src/contract/__tests__/run-api.test.ts +2 -2
  26. package/src/contract/check.ts +6 -2
  27. package/src/contract/emit-client.ts +10 -3
  28. package/src/contract/run.ts +10 -2
  29. package/src/init.ts +31 -46
  30. package/src/layout.ts +72 -16
  31. package/src/lifecycle/__tests__/bundle-summary.test.ts +106 -0
  32. package/src/lifecycle/__tests__/bundle.test.ts +6 -0
  33. package/src/lifecycle/__tests__/manifest-contract.test.ts +2 -2
  34. package/src/market/__tests__/bootstrap.test.ts +1 -1
  35. package/src/site.ts +1 -1
  36. package/src/vendor.ts +34 -0
  37. package/templates/README.md +30 -20
  38. package/templates/init.include.yaml +19 -11
  39. package/templates/openapi.json +102 -86
  40. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/installer.ts +8 -3
  41. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/register.ts +53 -0
  42. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/domain/roles.ts +4 -1
  43. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/domain/solution-perms.ts +7 -3
  44. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/domain/users.ts +27 -0
  45. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/infra/oplog.ts +4 -2
  46. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.mysql.sql +7 -0
  47. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.pg.sql +4 -0
  48. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.sql +8 -0
  49. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.mysql.sql +3 -0
  50. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.pg.sql +3 -0
  51. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.sql +8 -0
  52. package/templates/src/{_platform/api → app/api/_platform}/schema.yaml +7 -0
  53. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/replay.ts +9 -3
  54. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/tenant-admin.ts +18 -27
  55. package/templates/src/{system/api → app/api/system}/oplog/api.ts +5 -3
  56. package/templates/src/{system/api → app/api/system}/roles/api.ts +2 -1
  57. package/templates/src/{_platform/web/__client/api.ts → app/web/_platform/__client/index.ts} +5 -2
  58. package/templates/src/{auth/web/__client/api.ts → app/web/auth/__client/index.ts} +5 -2
  59. package/templates/src/app/web/notification/pages/center/index.tsx +1 -1
  60. package/templates/src/app/web/notification/routes.ts +1 -1
  61. package/templates/src/app/web/personal-center/pages/my-profile/index.tsx +1 -1
  62. package/templates/src/app/web/personal-center/routes.ts +1 -1
  63. package/templates/src/app/web/system/__client/api.schemas.ts +2 -0
  64. package/templates/src/app/web/system/locales/en-US.json +2 -3
  65. package/templates/src/app/web/system/locales/zh-CN.json +2 -3
  66. package/templates/src/app/web/system/pages/departments/index.tsx +2 -2
  67. package/templates/src/app/web/system/pages/login-methods/index.tsx +1 -1
  68. package/templates/src/app/web/system/pages/oplog/index.tsx +44 -19
  69. package/templates/src/app/web/system/pages/roles/index.tsx +12 -4
  70. package/templates/src/app/web/system/pages/roles/visible-roles.ts +14 -0
  71. package/templates/src/app/web/system/pages/settings/index.tsx +2 -2
  72. package/templates/src/app/web/system/pages/users/can-manage.ts +21 -0
  73. package/templates/src/app/web/system/pages/users/index.tsx +25 -17
  74. package/templates/src/app/web/system/pages/users/roles.tsx +1 -1
  75. package/templates/src/app/web/system/routes.ts +1 -1
  76. package/templates/src/{web/web/__client/api.ts → app/web/web/__client/index.ts} +5 -2
  77. package/templates/src/oj-market/web/api/defaultClient.ts +1 -1
  78. package/templates/tests/auth-ldap.spec.ts +2 -2
  79. package/templates/tests/auth-session.spec.ts +3 -3
  80. package/templates/tests/auth-throttle.spec.ts +1 -1
  81. package/templates/tests/fixture.ts +6 -4
  82. package/templates/tests/guard.spec.ts +1 -1
  83. package/templates/tests/lifecycle/atomic-state.spec.ts +3 -3
  84. package/templates/tests/lifecycle/bootstrap.spec.ts +3 -3
  85. package/templates/tests/lifecycle/deploy-smoke.spec.ts +8 -8
  86. package/templates/tests/lifecycle/installer.spec.ts +10 -10
  87. package/templates/tests/lifecycle/market-api.spec.ts +14 -14
  88. package/templates/tests/lifecycle/migrate.spec.ts +6 -6
  89. package/templates/tests/lifecycle/preflight.spec.ts +3 -3
  90. package/templates/tests/lifecycle/register.spec.ts +1 -1
  91. package/templates/tests/lifecycle/role-title-translate.spec.ts +171 -0
  92. package/templates/tests/lifecycle/semver.spec.ts +1 -1
  93. package/templates/tests/lifecycle/sha384.spec.ts +1 -1
  94. package/templates/tests/lifecycle/solutions-api.spec.ts +1 -1
  95. package/templates/tests/lifecycle/source-seq.spec.ts +1 -1
  96. package/templates/tests/lifecycle/steps-fs.spec.ts +9 -9
  97. package/templates/tests/lifecycle/text-edit.spec.ts +1 -1
  98. package/templates/tests/lifecycle/tgz-guard.spec.ts +2 -2
  99. package/templates/tests/lifecycle/trust.spec.ts +5 -5
  100. package/templates/tests/lifecycle/uninstall.spec.ts +7 -7
  101. package/templates/tests/lifecycle/verify-checks.spec.ts +5 -5
  102. package/templates/tests/lifecycle/verify-report.spec.ts +4 -4
  103. package/templates/tests/org-departments.spec.ts +10 -6
  104. package/templates/tests/org-read.spec.ts +7 -7
  105. package/templates/tests/query-utils.spec.ts +1 -1
  106. package/templates/tests/rbac-audit.spec.ts +1 -1
  107. package/templates/tests/rbac-contacts.spec.ts +2 -2
  108. package/templates/tests/rbac-guard.spec.ts +1 -1
  109. package/templates/tests/rbac-roles.spec.ts +19 -2
  110. package/templates/tests/rbac-seed.spec.ts +1 -1
  111. package/templates/tests/rbac-settings.spec.ts +77 -7
  112. package/templates/tests/rbac-solution-perms.spec.ts +1 -1
  113. package/templates/tests/rbac-tables.spec.ts +29 -0
  114. package/templates/tests/rbac-users.spec.ts +55 -3
  115. package/templates/tests/roles-page.spec.ts +40 -0
  116. package/templates/tests/seed-role-accounts.spec.ts +1 -1
  117. package/templates/tests/tenant-access-cache.spec.ts +1 -1
  118. package/templates/tests/tenant-forgery.spec.ts +5 -5
  119. package/templates/tests/tenant-isolation.spec.ts +5 -4
  120. package/templates/tests/username-namespace.spec.ts +3 -3
  121. package/templates/tests/users-page.spec.ts +39 -0
  122. package/templates/tests/wecom-admin.spec.ts +6 -6
  123. package/templates/tests/wecom-client-timeout.spec.ts +1 -1
  124. package/templates/tests/wecom-connector.spec.ts +9 -9
  125. package/templates/tests/wecom-corp.spec.ts +9 -9
  126. package/templates/tests/wecom-crypt.spec.ts +1 -1
  127. package/templates/tests/wecom-endpoints.spec.ts +2 -2
  128. package/templates/tests/wecom-landing.spec.ts +1 -1
  129. package/templates/tests/wecom-org-sync.spec.ts +7 -7
  130. package/templates/tests/wecom-sync.spec.ts +3 -3
  131. package/templates/tsconfig.paths.json +11 -11
  132. package/templates/vitest.config.ts +2 -2
  133. package/templates/web.config.ts +5 -2
  134. package/vendor/host-versions.json +3 -3
  135. package/templates/src/{_platform/api → app/api/_platform}/README.md +0 -0
  136. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/atomic.ts +0 -0
  137. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/history.ts +0 -0
  138. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/limits.ts +0 -0
  139. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/lock.ts +0 -0
  140. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/semver.ts +0 -0
  141. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/sha384.ts +0 -0
  142. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/source-seq.ts +0 -0
  143. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/state.ts +0 -0
  144. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/deploy-web.ts +0 -0
  145. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/download.ts +0 -0
  146. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/extract.ts +0 -0
  147. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/migrate.ts +0 -0
  148. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/preflight.ts +0 -0
  149. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/reload.ts +0 -0
  150. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/smoke.ts +0 -0
  151. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/steps/verify.ts +0 -0
  152. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/tasks.ts +0 -0
  153. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/text-edit.ts +0 -0
  154. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/tgz-guard.ts +0 -0
  155. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/trust.ts +0 -0
  156. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/types.ts +0 -0
  157. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/uninstall.ts +0 -0
  158. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/verify-checks.ts +0 -0
  159. package/templates/src/{_platform/api → app/api/_platform}/_lifecycle/verify-report.ts +0 -0
  160. package/templates/src/{_platform/api → app/api/_platform}/_shared/respond.ts +0 -0
  161. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/domain/contacts.ts +0 -0
  162. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/domain/org-read.ts +0 -0
  163. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/domain/org.ts +0 -0
  164. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/domain/settings.ts +0 -0
  165. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/infra/access.ts +0 -0
  166. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/infra/audit.ts +0 -0
  167. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/infra/guard.ts +0 -0
  168. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/infra/query.ts +0 -0
  169. package/templates/src/{_platform/api → app/api/_platform}/_shared/service/infra/rate.ts +0 -0
  170. package/templates/src/{_platform/api → app/api/_platform}/_shared/site-facade.ts +0 -0
  171. package/templates/src/{_platform/api → app/api/_platform}/contacts/api.ts +0 -0
  172. package/templates/src/{_platform/api → app/api/_platform}/contacts/detail/api.ts +0 -0
  173. package/templates/src/{_platform/api → app/api/_platform}/fixtures/l1-test-user.sql +0 -0
  174. package/templates/src/{_platform/api → app/api/_platform}/manifest.yaml +0 -0
  175. package/templates/src/{_platform/api → app/api/_platform}/market/api.ts +0 -0
  176. package/templates/src/{_platform/api → app/api/_platform}/market/bootstrap.ts +0 -0
  177. package/templates/src/{_platform/api → app/api/_platform}/market/index-source.ts +0 -0
  178. package/templates/src/{_platform/api → app/api/_platform}/migrations/0001__create_users.mysql.sql +0 -0
  179. package/templates/src/{_platform/api → app/api/_platform}/migrations/0001__create_users.pg.sql +0 -0
  180. package/templates/src/{_platform/api → app/api/_platform}/migrations/0001__create_users.sql +0 -0
  181. package/templates/src/{_platform/api → app/api/_platform}/migrations/0002__add_users_avatar_base64.mysql.sql +0 -0
  182. package/templates/src/{_platform/api → app/api/_platform}/migrations/0002__add_users_avatar_base64.sql +0 -0
  183. package/templates/src/{_platform/api → app/api/_platform}/migrations/0003__users_source_display_name.mysql.sql +0 -0
  184. package/templates/src/{_platform/api → app/api/_platform}/migrations/0003__users_source_display_name.sql +0 -0
  185. package/templates/src/{_platform/api → app/api/_platform}/migrations/0004__sys_rbac.mysql.sql +0 -0
  186. package/templates/src/{_platform/api → app/api/_platform}/migrations/0004__sys_rbac.pg.sql +0 -0
  187. package/templates/src/{_platform/api → app/api/_platform}/migrations/0004__sys_rbac.sql +0 -0
  188. package/templates/src/{_platform/api → app/api/_platform}/migrations/0005__users_must_change.mysql.sql +0 -0
  189. package/templates/src/{_platform/api → app/api/_platform}/migrations/0005__users_must_change.sql +0 -0
  190. package/templates/src/{_platform/api → app/api/_platform}/migrations/0006__users_is_forbidden.mysql.sql +0 -0
  191. package/templates/src/{_platform/api → app/api/_platform}/migrations/0006__users_is_forbidden.sql +0 -0
  192. package/templates/src/{_platform/api → app/api/_platform}/migrations/0007__users_email.sql +0 -0
  193. package/templates/src/{_platform/api → app/api/_platform}/migrations/0008__sys_refresh_token.mysql.sql +0 -0
  194. package/templates/src/{_platform/api → app/api/_platform}/migrations/0008__sys_refresh_token.pg.sql +0 -0
  195. package/templates/src/{_platform/api → app/api/_platform}/migrations/0008__sys_refresh_token.sql +0 -0
  196. package/templates/src/{_platform/api → app/api/_platform}/migrations/0009__sys_throttle.mysql.sql +0 -0
  197. package/templates/src/{_platform/api → app/api/_platform}/migrations/0009__sys_throttle.pg.sql +0 -0
  198. package/templates/src/{_platform/api → app/api/_platform}/migrations/0009__sys_throttle.sql +0 -0
  199. package/templates/src/{_platform/api → app/api/_platform}/migrations/0010__sys_solution_route.mysql.sql +0 -0
  200. package/templates/src/{_platform/api → app/api/_platform}/migrations/0010__sys_solution_route.pg.sql +0 -0
  201. package/templates/src/{_platform/api → app/api/_platform}/migrations/0010__sys_solution_route.sql +0 -0
  202. package/templates/src/{_platform/api → app/api/_platform}/migrations/0011__sys_setting_group_label.mysql.sql +0 -0
  203. package/templates/src/{_platform/api → app/api/_platform}/migrations/0011__sys_setting_group_label.sql +0 -0
  204. package/templates/src/{_platform/api → app/api/_platform}/migrations/0012__market_history.mysql.sql +0 -0
  205. package/templates/src/{_platform/api → app/api/_platform}/migrations/0012__market_history.pg.sql +0 -0
  206. package/templates/src/{_platform/api → app/api/_platform}/migrations/0012__market_history.sql +0 -0
  207. package/templates/src/{_platform/api → app/api/_platform}/migrations/0013__users_profile.sql +0 -0
  208. package/templates/src/{_platform/api → app/api/_platform}/migrations/0014__reg_source_seq.mysql.sql +0 -0
  209. package/templates/src/{_platform/api → app/api/_platform}/migrations/0014__reg_source_seq.pg.sql +0 -0
  210. package/templates/src/{_platform/api → app/api/_platform}/migrations/0014__reg_source_seq.sql +0 -0
  211. package/templates/src/{_platform/api → app/api/_platform}/migrations/0015__tenant.mysql.sql +0 -0
  212. package/templates/src/{_platform/api → app/api/_platform}/migrations/0015__tenant.pg.sql +0 -0
  213. package/templates/src/{_platform/api → app/api/_platform}/migrations/0015__tenant.sql +0 -0
  214. package/templates/src/{_platform/api → app/api/_platform}/migrations/0016__org.mysql.sql +0 -0
  215. package/templates/src/{_platform/api → app/api/_platform}/migrations/0016__org.pg.sql +0 -0
  216. package/templates/src/{_platform/api → app/api/_platform}/migrations/0016__org.sql +0 -0
  217. package/templates/src/{_platform/api → app/api/_platform}/org/departments/api.ts +0 -0
  218. package/templates/src/{_platform/api → app/api/_platform}/org/is-member/api.ts +0 -0
  219. package/templates/src/{_platform/api → app/api/_platform}/org/members/api.ts +0 -0
  220. package/templates/src/{_platform/api → app/api/_platform}/org/picker/api.ts +0 -0
  221. package/templates/src/{_platform/api → app/api/_platform}/org/resolve/api.ts +0 -0
  222. package/templates/src/{_platform/api → app/api/_platform}/org/tree/api.ts +0 -0
  223. package/templates/src/{_platform/api → app/api/_platform}/org/user/api.ts +0 -0
  224. package/templates/src/{_platform/api → app/api/_platform}/seed.mysql.sql +0 -0
  225. package/templates/src/{_platform/api → app/api/_platform}/seed.pg.sql +0 -0
  226. package/templates/src/{_platform/api → app/api/_platform}/seed.sql +0 -0
  227. package/templates/src/{_platform/api → app/api/_platform}/solutions/api.ts +0 -0
  228. package/templates/src/{auth/api → app/api/auth}/_shared/ldap-login.ts +0 -0
  229. package/templates/src/{auth/api → app/api/auth}/_shared/ldap.ts +0 -0
  230. package/templates/src/{auth/api → app/api/auth}/_shared/login-throttle.ts +0 -0
  231. package/templates/src/{auth/api → app/api/auth}/_shared/session.ts +0 -0
  232. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/admin.ts +1 -1
  233. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/client.ts +0 -0
  234. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/config.ts +0 -0
  235. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/contacts.ts +0 -0
  236. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/crypt.ts +0 -0
  237. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/events.ts +1 -1
  238. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/login.ts +0 -0
  239. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/payload.ts +0 -0
  240. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/store.ts +0 -0
  241. package/templates/src/{auth/api → app/api/auth}/_shared/wecom/sync.ts +0 -0
  242. package/templates/src/{auth/api → app/api/auth}/api.ts +0 -0
  243. package/templates/src/{auth/api → app/api/auth}/ldap-login/api.ts +0 -0
  244. package/templates/src/{auth/api → app/api/auth}/manifest.yaml +0 -0
  245. package/templates/src/{auth/api → app/api/auth}/migrations/0001__wecom.mysql.sql +0 -0
  246. package/templates/src/{auth/api → app/api/auth}/migrations/0001__wecom.pg.sql +0 -0
  247. package/templates/src/{auth/api → app/api/auth}/migrations/0001__wecom.sql +0 -0
  248. package/templates/src/{auth/api → app/api/auth}/migrations/0002__org_sync.mysql.sql +0 -0
  249. package/templates/src/{auth/api → app/api/auth}/migrations/0002__org_sync.pg.sql +0 -0
  250. package/templates/src/{auth/api → app/api/auth}/migrations/0002__org_sync.sql +0 -0
  251. package/templates/src/{auth/api → app/api/auth}/migrations/0003__credential_kind.mysql.sql +0 -0
  252. package/templates/src/{auth/api → app/api/auth}/migrations/0003__credential_kind.pg.sql +0 -0
  253. package/templates/src/{auth/api → app/api/auth}/migrations/0003__credential_kind.sql +0 -0
  254. package/templates/src/{auth/api → app/api/auth}/schema.yaml +0 -0
  255. package/templates/src/{auth/api → app/api/auth}/wecom/admin/api.ts +0 -0
  256. package/templates/src/{auth/api → app/api/auth}/wecom/admin/tenant-admin/api.ts +1 -1
  257. package/templates/src/{auth/api → app/api/auth}/wecom/admin/tenant-admin/password/api.ts +1 -1
  258. /package/templates/src/{auth/api → app/api/auth}/wecom/api.ts +0 -0
  259. /package/templates/src/{auth/api → app/api/auth}/wecom/sync/api.ts +0 -0
  260. /package/templates/src/{home/api → app/api/home}/line/api.ts +0 -0
  261. /package/templates/src/{home/api → app/api/home}/manifest.yaml +0 -0
  262. /package/templates/src/{home/api → app/api/home}/migrations/0001__create_home_tables.sql +0 -0
  263. /package/templates/src/{home/api → app/api/home}/migrations/0002__tenant.mysql.sql +0 -0
  264. /package/templates/src/{home/api → app/api/home}/migrations/0002__tenant.sql +0 -0
  265. /package/templates/src/{home/api → app/api/home}/pie/api.ts +0 -0
  266. /package/templates/src/{home/api → app/api/home}/schema.yaml +0 -0
  267. /package/templates/src/{home/api → app/api/home}/seed.sql +0 -0
  268. /package/templates/src/{notification/api → app/api/notification}/_shared/notify.ts +0 -0
  269. /package/templates/src/{notification/api → app/api/notification}/api.ts +0 -0
  270. /package/templates/src/{notification/api → app/api/notification}/del/api.ts +0 -0
  271. /package/templates/src/{notification/api → app/api/notification}/manifest.yaml +0 -0
  272. /package/templates/src/{notification/api → app/api/notification}/migrations/0001__create_notifications.sql +0 -0
  273. /package/templates/src/{notification/api → app/api/notification}/migrations/0002__notifications_user.sql +0 -0
  274. /package/templates/src/{notification/api → app/api/notification}/migrations/0003__notifications_broadcast.sql +0 -0
  275. /package/templates/src/{notification/api → app/api/notification}/migrations/0004__notifications_broadcast_hidden.sql +0 -0
  276. /package/templates/src/{notification/api → app/api/notification}/migrations/0005__tenant.mysql.sql +0 -0
  277. /package/templates/src/{notification/api → app/api/notification}/migrations/0005__tenant.sql +0 -0
  278. /package/templates/src/{notification/api → app/api/notification}/schema.yaml +0 -0
  279. /package/templates/src/{notification/api → app/api/notification}/seed.sql +0 -0
  280. /package/templates/src/{personal-center/api → app/api/personal-center}/manifest.yaml +0 -0
  281. /package/templates/src/{personal-center/api → app/api/personal-center}/profile/api.ts +0 -0
  282. /package/templates/src/{personal-center/api → app/api/personal-center}/upload/api.ts +0 -0
  283. /package/templates/src/{system/api → app/api/system}/departments/api.ts +0 -0
  284. /package/templates/src/{system/api → app/api/system}/departments/detach/api.ts +0 -0
  285. /package/templates/src/{system/api → app/api/system}/departments/members/api.ts +0 -0
  286. /package/templates/src/{system/api → app/api/system}/departments/move/api.ts +0 -0
  287. /package/templates/src/{system/api → app/api/system}/login-methods/api.ts +0 -0
  288. /package/templates/src/{system/api → app/api/system}/manifest.yaml +0 -0
  289. /package/templates/src/{system/api → app/api/system}/permissions/api.ts +0 -0
  290. /package/templates/src/{system/api → app/api/system}/roles/bindings/api.ts +0 -0
  291. /package/templates/src/{system/api → app/api/system}/settings/api.ts +0 -0
  292. /package/templates/src/{system/api → app/api/system}/users/api.ts +0 -0
  293. /package/templates/src/{system/api → app/api/system}/users/forbidden/api.ts +0 -0
  294. /package/templates/src/{system/api → app/api/system}/users/password/api.ts +0 -0
  295. /package/templates/src/{system/api → app/api/system}/users/profile/api.ts +0 -0
  296. /package/templates/src/{system/api → app/api/system}/users/roles/api.ts +0 -0
  297. /package/templates/src/{web/api → app/api/web}/get-async-routes/api.ts +0 -0
  298. /package/templates/src/{web/api → app/api/web}/hello/api.ts +0 -0
  299. /package/templates/src/{web/api → app/api/web}/manifest.yaml +0 -0
  300. /package/templates/src/{web/api → app/api/web}/user-info/api.ts +0 -0
  301. /package/templates/src/{_platform/web → app/web/_platform}/__client/api.schemas.ts +0 -0
  302. /package/templates/src/{auth/web → app/web/auth}/__client/api.schemas.ts +0 -0
  303. /package/templates/src/app/web/home/__client/{api.ts → index.ts} +0 -0
  304. /package/templates/src/app/web/notification/__client/{api.ts → index.ts} +0 -0
  305. /package/templates/src/app/web/personal-center/__client/{api.ts → index.ts} +0 -0
  306. /package/templates/src/app/web/system/__client/{api.ts → index.ts} +0 -0
  307. /package/templates/src/{web → app/web}/web/__client/api.schemas.ts +0 -0
@@ -104,6 +104,12 @@ describe("buildBundle · 正路径", () => {
104
104
  expect(tarList(r.tgz).some(n => n.endsWith("/modules.json"))).toBe(false);
105
105
  });
106
106
 
107
+ it("r1 前提:模块源码 locales 双语随包(安装期角色 title 解析数据源,计划 20261103-0948)", async () => {
108
+ const names = tarList((await pack()).tgz);
109
+ expect(names).toContain("demo-solution-0.1.0/web/modules/demo-solution/locales/zh-CN.json");
110
+ expect(names).toContain("demo-solution-0.1.0/web/modules/demo-solution/locales/en-US.json");
111
+ });
112
+
107
113
  it("solution.yaml 作为 bundle 契约(优先于 manifest.yaml,避开 oj 按 manifest.yaml 枚举 api 后端的冲突)", async () => {
108
114
  // 根目录若用 manifest.yaml 当 bundle 契约,会被 oj 的 api 模块搜索枚举误判为 api 模块;
109
115
  // 故解决方案改用 solution.yaml,bundle 工具优先认它(manifest.yaml 仅旧方案回退)。
@@ -1,4 +1,4 @@
1
- import type { InstallContext } from "../../../templates/src/_platform/api/_lifecycle/steps/preflight";
1
+ import type { InstallContext } from "../../../templates/src/app/api/_platform/_lifecycle/steps/preflight";
2
2
 
3
3
  // BDD:bundle 级 manifest.yaml 契约校验(P1-11,C2 规则构建列)。
4
4
  // 规则真源:docs/prd/solution/202610171254-lifecycle-manifest-contract.md(C2-01~33 构建列,§4.1 矩阵);
@@ -13,7 +13,7 @@ import { describe, expect, it } from "vitest";
13
13
  import { parse } from "yaml";
14
14
  // 跨端引用(双端一致钉):被测实现同仓分居两运行时(计划 §1「两运行时取舍」),
15
15
  // 测试直接互调,比「两套件各读同一夹具」更强——漂移即本文件红。
16
- import { preflight } from "../../../templates/src/_platform/api/_lifecycle/steps/preflight";
16
+ import { preflight } from "../../../templates/src/app/api/_platform/_lifecycle/steps/preflight";
17
17
  import { checkLocalesComplete, checkTablesAgainstSchema, parseManifest, RESERVED_NAMES, reservedNameSuggestions, validateContract } from "../../manifest-contract";
18
18
 
19
19
  const FIXTURES = join(dirname(fileURLToPath(import.meta.url)), "fixtures");
@@ -68,7 +68,7 @@ describe("given 一个装了 oj 二进制的源工程 When 自举隔离站点",
68
68
 
69
69
  const site = await bootstrapIsolatedSite({ projectRoot: src, starter });
70
70
 
71
- expect(existsSync(join(site.root, "src", "_platform", "api", "seed.sql"))).toBe(true);
71
+ expect(existsSync(join(site.root, "src", "app", "api", "_platform", "seed.sql"))).toBe(true);
72
72
  expect(existsSync(join(site.root, "bin", "oj"))).toBe(true);
73
73
  expect(existsSync(join(site.root, "bin", "plugins", "auth.wasm"))).toBe(true);
74
74
  expect(site.root).not.toBe(src);
package/src/site.ts CHANGED
@@ -21,7 +21,7 @@ export function tenantHeaders(): Record<string, string> {
21
21
  return { [TENANT_HEADER]: DEFAULT_TENANT };
22
22
  }
23
23
 
24
- /** 任务记录(线形状镜像;真源 templates/src/_platform/api/_lifecycle/types.ts:65,客户端不 import 模板内部) */
24
+ /** 任务记录(线形状镜像;真源 templates/src/app/api/_platform/_lifecycle/types.ts:65,客户端不 import 模板内部) */
25
25
  export interface TaskRecord {
26
26
  /**
27
27
  * 记录 schema 版本(P2-10 线形状镜像):缺省(undefined)=旧记录=v1 语义照常渲染;
package/src/vendor.ts CHANGED
@@ -79,6 +79,30 @@ export function ojBinName(platform: string = process.platform): string {
79
79
  return platform === "win32" ? "oj.exe" : "oj";
80
80
  }
81
81
 
82
+ /**
83
+ * oj devkit 文档同步(计划 docs/plans/20261103-1020-vendor-devkit-sync):bin/devkit
84
+ * (@oj-bin/oj postinstall 落盘,与 bin/oj 同版本)→ 工程 `.claude/skills/oj-api-dev/`,
85
+ * 全部 `.md` **覆盖**拷入——skill 文档始终与已装 oj 版本一致(vendor/init 共用出口)。
86
+ * bin/devkit 缺失(旧版 oj/异常安装)→ ok:false,调用方记跳过、不失败。
87
+ * global.d.ts 不在此同步:工程根那份是模板自有变体、用户可编辑(init 首装 copyIfAbsent)。
88
+ */
89
+ export function syncOjDevkit(projectRoot: string, binDir: string, log: (msg: string) => void = () => {}): { ok: boolean, files: string[] } {
90
+ const devkitDir = path.join(binDir, "devkit");
91
+ if (!fs.existsSync(path.join(devkitDir, "SKILL.md")))
92
+ return { ok: false, files: [] };
93
+ const skillDir = path.join(projectRoot, ".claude", "skills", "oj-api-dev");
94
+ fs.mkdirSync(skillDir, { recursive: true });
95
+ const files: string[] = [];
96
+ for (const name of fs.readdirSync(devkitDir)) {
97
+ if (!name.endsWith(".md"))
98
+ continue;
99
+ fs.copyFileSync(path.join(devkitDir, name), path.join(skillDir, name));
100
+ files.push(name);
101
+ }
102
+ log(`[ojm] oj devkit 文档已同步 → .claude/skills/oj-api-dev/(${files.length} 个文件,与已装 oj 同版本)`);
103
+ return { ok: true, files };
104
+ }
105
+
82
106
  /**
83
107
  * 工程内 oj 二进制路径的**唯一口径**(<projectRoot>/bin/oj)。
84
108
  *
@@ -222,6 +246,12 @@ function installFromNpm(version: string, binDir: string, run: NpmRun, log: (msg:
222
246
  }
223
247
  }
224
248
 
249
+ /** devkit 同步 + 缺失时的人话跳过行(vendorCommand 两个调用点共用) */
250
+ function syncDevkitOrSkip(projectRoot: string, binDir: string, log: (msg: string) => void): void {
251
+ if (!syncOjDevkit(projectRoot, binDir, log).ok)
252
+ log("[ojm] bin/devkit 缺失,跳过 oj devkit 文档同步(旧版 oj 或异常安装;skill 文档不更新)");
253
+ }
254
+
225
255
  /**
226
256
  * US-1..US-5 编排:解析目标版本(tag 缺省经 npm view 追 latest,显式 tag 去 v 前缀)
227
257
  * → 本地已是该版本则跳过(--force 除外)→ 临时目录安装 + 拷贝 → 报告版本 → 探针冒烟。
@@ -243,6 +273,9 @@ export async function vendorCommand(
243
273
  const binDir = path.join(projectRoot, "bin");
244
274
  const local = readLocalVersion(binDir);
245
275
  if (!opts.force && local === `v${version}`) {
276
+ // 文档同步不随版本跳过:用户删过 skill 目录后重跑 vendor 即补齐(R4)。
277
+ // 先同步再打跳过行——「已是 vX」保持命令收尾行(既有门禁断言末行)。
278
+ syncDevkitOrSkip(projectRoot, binDir, log);
246
279
  log(`[ojm] oj 已是 v${version},跳过。`);
247
280
  const result = probe(binDir);
248
281
  if (!result.ok)
@@ -255,6 +288,7 @@ export async function vendorCommand(
255
288
  log(`[ojm] 本地 ${local ?? "未安装"} → v${version}`);
256
289
  installFromNpm(version, binDir, run, log);
257
290
  log(`[ojm] oj ${local ? `${local} → ` : ""}v${version} 安装完成:${path.join(binDir, ojBinName(process.platform))}`);
291
+ syncDevkitOrSkip(projectRoot, binDir, log);
258
292
  // 安装后冒烟:发布二进制可能因构建机路径被烤进而不可用(见 probeOjRuntime)
259
293
  const result = probe(binDir);
260
294
  if (!result.ok)
@@ -6,30 +6,32 @@
6
6
 
7
7
  ```bash
8
8
  pnpm install
9
- pnpm dev # 开发:前端 devServer + oj 后端(src/*/api 保存即热更)
9
+ pnpm dev # 开发:前端 devServer + oj 后端(src 下 api.ts 保存即热更)
10
10
  pnpm build # 构建:oj build + 前端全站合并到 dist/web
11
11
  pnpm preview # 预览:oj migrate + server(release 产物)
12
12
  ```
13
13
 
14
- 登录账号:`admin` / `aA123456`(见 `src/_platform/api/seed.sql`)。
14
+ 登录账号:`superadmin` / `aA123456`(四个内置角色账号见 `src/app/api/_platform/seed.sql`)。
15
15
 
16
- ## 目录(一目录 = 一个模块)
16
+ ## 目录(一个 `src/app` 装下整个应用)
17
17
 
18
18
  ```
19
- config.yaml 站点/数据库/租户配置(init 现场签发证书到 config/)
20
- src/<name>/api/ 后端模块(目录镜像路由:src/<name>/api/<路径>/api.ts)
21
- src/<name>/web/ 前端模块(entry.ts 是入口;页面 / locales / __client 同目录)
22
- src/app/web/ 框架内置页面聚合模块(多根:/home /login /personal-center /notification /system)
23
- src/oj-market/web/ 解决方案市场(第一方能力,独立模块,删目录即下线)
24
- dist/api/ oj build 后端产物
25
- dist/web/ 站点产物(shell + modules + modules.json)
26
- bin/ oj 二进制(init 解压,不入库)
19
+ config.yaml 站点/数据库/租户配置(init 现场签发证书到 config/)
20
+ src/app/api/<name>/ 后端模块(模块名 = URL 前缀;目录镜像:<路径>/api.ts)
21
+ src/app/web/ 前端聚合模块(多根,一个 entry.ts 挂 /home /login /…)
22
+ <root>/ 每个根:routes.ts + pages/ + locales/ + __client/
23
+ src/oj-market/web/ 解决方案市场(第一方能力,独立模块,删目录即下线)
24
+ dist/api/ oj build 后端产物
25
+ dist/web/ 站点产物(shell + modules + modules.json)
26
+ bin/ oj 二进制(init 解压,不入库)
27
27
  ```
28
28
 
29
- `src/app/web` 是一个**多根模块**:一个 `entry.ts` 里挂五个顶层路由,各根按
30
- `handle.order` 排菜单(与拆分时逐项一致),页面按根分目录
31
- (`<root>/routes.ts` + `pages/` + `__client/`)。新增业务页面时建议单独建模块
32
- (`pnpm exec ojm new <name>`),不要往聚合模块里塞。
29
+ - **后端**按业务域分模块:`_platform` / `auth` / `notification` / `personal-center` /
30
+ `system` / `web`,各自是独立 oj 模块(模块名即 `/api/<name>` 前缀),只是统一收在
31
+ `src/app/api` 下——顶层不再散落同名目录。
32
+ - **前端** `src/app/web` 是一个**多根模块**:一个 `entry.ts` 里挂六个顶层路由,各根按
33
+ `handle.order` 排菜单,页面按根分目录。新增业务页面时建议单独建模块
34
+ (`pnpm exec ojm new <name>`),不要往聚合模块里塞。
33
35
 
34
36
  ## 契约与 `__client`
35
37
 
@@ -38,16 +40,19 @@ bin/ oj 二进制(init 解压,不入库)
38
40
 
39
41
  ```bash
40
42
  bin/oj openapi -c config.yaml --module-root src -b /api -o openapi.json # 重产契约
41
- pnpm exec ojm api # 重生成 */web/*/__client
43
+ pnpm exec ojm api # 重生成 __client
42
44
  ```
43
45
 
46
+ 生成物入口是 `__client/index.ts`(**不是 `api.ts`**:oj dev 会把模块目录下的
47
+ `api.ts` 当路由扫描)。页面里用 `from "../__client"` 导入。
48
+
44
49
  多根聚合模块的 client 归属由 `web.config.ts` 的 `clientOwners` 决定(`system → app`),
45
- 生成物落 `src/app/web/system/__client`,与页面同级——页面相对导入 `../../__client` 不用改。
50
+ 生成物落 `src/app/web/system/__client`,与页面同级——页面相对导入不用改。
46
51
  `ojm api --check` 可对账漂移(零漂移为发布门禁)。
47
52
 
48
53
  ## 注意
49
54
 
50
- - 改 `src/*/api` 下的 api.ts 保存即生效;**新增/删除模块目录、改
55
+ - 改 `src/app/api/**/api.ts` 保存即生效;**新增/删除模块目录、改
51
56
  schema/migrations/config.yaml 需重启 `ojm dev`**(oj 热更边界)。
52
57
  - 后端开发请用 `/oj-api-dev` skill(`.claude/skills/oj-api-dev/`),手册按章节按需读。
53
58
  - `config/` 下的证书为 init 现场签发的本地 dev 证书,不构成信任边界;
@@ -55,7 +60,7 @@ pnpm exec ojm api # 重
55
60
 
56
61
  ## 排障 / 常见问题
57
62
 
58
- - **`pnpm dev` / `pnpm build` 报 `Could not resolve "../../__client/api"`**
63
+ - **`pnpm dev` / `pnpm build` 报 `Could not resolve "../../__client"`**
59
64
  对应根的 `__client` 缺失——它是 `ojm api` 的生成物。在工程根跑一次即可补齐:
60
65
 
61
66
  ```bash
@@ -73,8 +78,13 @@ pnpm exec ojm api # 重
73
78
  不能手改、也不入库——它是生成物,下次 `ojm api` 会覆盖。改接口就改 handler 的
74
79
  `.schema`/`.response`,再跑上面的命令刷新。
75
80
 
81
+ - **从旧版本升级(`__client/api.ts`)**
82
+ 0.2.54 起入口改名 `index.ts`(`api.ts` 会被 oj dev 当路由扫描)。重跑一次
83
+ `pnpm exec ojm api` 即可:新文件写入、旧 `api.ts` 自动删除;页面导入改为
84
+ `from "../__client"`。
85
+
76
86
  - **`pnpm dlx @oj-module/cli@latest init` 生成的脚手架缺模块 / 看起来很旧**
77
- pnpm dlx 会按首次解析到的版本**缓存** CLI 可执行文件。排查:`ls src` 看是否缺预期模块。
87
+ pnpm dlx 会按首次解析到的版本**缓存** CLI 可执行文件。排查:`ls src/app/api` 看是否缺预期模块。
78
88
  解决:清掉 dlx 缓存后显式指定版本重跑——
79
89
 
80
90
  ```bash
@@ -40,7 +40,7 @@ include:
40
40
  - src/styles.css
41
41
  # 后端 typecheck 工程(package.json 的 typecheck:api 指向它);只收后端、排除 web
42
42
  - src/tsconfig.json
43
- # —— 后端:配置 / 种子 / 测试 / 默认模块(模块源码在 src/<name>/api)——
43
+ # —— 后端:配置 / 种子 / 测试 / 默认模块(模块源码在 src/app/api/<模块>)——
44
44
  - config.yaml
45
45
  - .ojm-api-exempt.json
46
46
  - seed.mysql.sql
@@ -71,8 +71,12 @@ include:
71
71
  - tests/rbac-solution-perms.spec.ts
72
72
  - tests/rbac-tables.spec.ts
73
73
  - tests/rbac-users.spec.ts
74
+ # 角色页展示层过滤 superadmin(后端 listRoles 仍返回;页面源码随 src/app/web/system 下发)
75
+ - tests/roles-page.spec.ts
74
76
  - tests/seed-role-accounts.spec.ts
75
- # 企微连接器与组织同步:源码本就分发(src/auth/api),对应回归也必须跟着走,
77
+ # 用户页行级门禁:只有 superadmin 能改 superadmin 账号(后端 assertCanManageTarget 的另一面)
78
+ - tests/users-page.spec.ts
79
+ # 企微连接器与组织同步:源码本就分发(src/app/api/auth),对应回归也必须跟着走,
76
80
  # 否则用户工程升级后改配置/换套件时没有任何本地自检手段。
77
81
  - tests/wecom-admin.spec.ts
78
82
  - tests/wecom-client-timeout.spec.ts
@@ -95,15 +99,19 @@ include:
95
99
  - tests/lifecycle/uninstall.spec.ts
96
100
  - tests/lifecycle/verify-checks.spec.ts
97
101
  - tests/lifecycle/verify-report.spec.ts
98
- - src/_platform/api
99
- - src/auth/api
100
- - src/notification/api
101
- - src/personal-center/api
102
- - src/system/api
103
- - src/web/api
102
+ # 框架内置后端全部收在 src/app/api/<模块>(模块名 = URL 前缀,故仍是独立模块)。
103
+ # home 的 api 是 demo-only 不进脚手架(见下),其余全部下发。
104
+ - src/app/api/_platform
105
+ - src/app/api/auth
106
+ - src/app/api/notification
107
+ - src/app/api/personal-center
108
+ - src/app/api/system
109
+ - src/app/api/web
104
110
  # —— web 前端模块 ——
105
- - src/_platform/web
106
- - src/auth/web
111
+ # 纯 client 归属目录(无页面模块):_platform 的生成物被 oj-market 引用,
112
+ # auth / web 的是各自后端契约的配套产物,一并下发保证 ojm api --check 开箱即过。
113
+ - src/app/web/_platform
114
+ - src/app/web/auth
107
115
  # 框架内置页面聚合为一个多根模块(首页/登录/个人中心/通知/系统管理)。
108
116
  # home 只列 routes/locales/pages:其 api 模块是 demo-only 不进脚手架,__client
109
117
  # 留着会指向不存在的端点(见顶部说明),故逐子路径收录而不是整棵 src/app/web。
@@ -125,4 +133,4 @@ include:
125
133
  - src/oj-market/web/locales
126
134
  - src/oj-market/web/pages
127
135
  - src/oj-market/web/utils
128
- - src/web/web
136
+ - src/app/web/web