@oj-module/cli 0.2.18 → 0.2.23

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 (345) hide show
  1. package/devkit/README.md +4 -4
  2. package/devkit/SKILL.md +41 -37
  3. package/devkit/framework-dev.md +6 -5
  4. package/devkit/manual.md +352 -168
  5. package/devkit/menu-rules.md +3 -3
  6. package/devkit/module-dev-and-cdn-playground.md +31 -22
  7. package/devkit/sql-builder-missing-capabilities-pr.md +11 -6
  8. package/package.json +2 -2
  9. package/shell-dist/assets/runtime.js +59 -34
  10. package/shell-dist/index.html +2 -2
  11. package/shell-dist/versions.json +3 -3
  12. package/src/__tests__/build-backend.test.ts +54 -0
  13. package/src/__tests__/init-packagejson.test.ts +29 -0
  14. package/src/__tests__/layout.test.ts +176 -0
  15. package/src/__tests__/module-list.test.ts +66 -0
  16. package/src/__tests__/oj-caps.test.ts +114 -0
  17. package/src/alias-paths.ts +102 -0
  18. package/src/args.ts +54 -4
  19. package/src/build.ts +41 -9
  20. package/src/builtin.ts +93 -0
  21. package/src/bundle.ts +254 -38
  22. package/src/config.ts +82 -9
  23. package/src/contract/__tests__/market-client.integration.test.ts +14 -14
  24. package/src/contract/check.ts +56 -28
  25. package/src/contract/emit-stub.ts +21 -9
  26. package/src/contract/handler-scan.ts +19 -10
  27. package/src/contract/run.ts +14 -4
  28. package/src/dev.ts +80 -9
  29. package/src/index.ts +27 -7
  30. package/src/info.ts +69 -10
  31. package/src/init.ts +114 -28
  32. package/src/layout.ts +282 -24
  33. package/src/lifecycle/__tests__/args.test.ts +20 -0
  34. package/src/lifecycle/__tests__/builtin.test.ts +97 -0
  35. package/src/lifecycle/__tests__/bundle.test.ts +184 -6
  36. package/src/lifecycle/__tests__/manifest-contract.test.ts +2 -2
  37. package/src/lifecycle/__tests__/new.test.ts +129 -0
  38. package/src/lifecycle/__tests__/smoke.test.ts +2 -1
  39. package/src/manifest-contract.ts +16 -3
  40. package/src/market/__tests__/bootstrap.test.ts +17 -9
  41. package/src/market/bootstrap.ts +30 -17
  42. package/src/market/publish.ts +10 -2
  43. package/src/new.ts +208 -0
  44. package/src/oj-caps.ts +133 -0
  45. package/src/oj.ts +27 -4
  46. package/src/preview-config.ts +1 -1
  47. package/src/preview.ts +2 -1
  48. package/src/site.ts +2 -2
  49. package/src/usage.ts +24 -12
  50. package/src/vendor.ts +5 -1
  51. package/templates/{api/config.yaml → config.yaml} +13 -8
  52. package/templates/global.d.ts +7 -6
  53. package/templates/init.include.yaml +41 -36
  54. package/templates/package.json +3 -1
  55. package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/installer.ts +4 -0
  56. package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/smoke.ts +21 -2
  57. package/templates/{api/src/_platform → src/_platform/api}/fixtures/l1-test-user.sql +4 -5
  58. package/templates/{api/src/_platform → src/_platform/api}/market/api.ts +25 -15
  59. package/templates/src/_platform/api/seed.mysql.sql +16 -0
  60. package/templates/src/_platform/api/seed.pg.sql +16 -0
  61. package/templates/{api/src/_platform → src/_platform/api}/seed.sql +16 -5
  62. package/templates/{api/src/_platform → src/_platform/api}/solutions/api.ts +7 -3
  63. package/templates/{api/src/auth → src/auth/api}/_shared/login-throttle.ts +2 -2
  64. package/templates/{api/src/auth → src/auth/api}/_shared/session.ts +2 -2
  65. package/templates/{api/src/auth → src/auth/api}/api.ts +1 -1
  66. package/templates/{api/src/auth → src/auth/api}/ldap-login/api.ts +1 -1
  67. package/templates/src/auth/api/manifest.yaml +6 -0
  68. package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/InstallDialog.test.tsx +53 -1
  69. package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/marketClient.fake.ts +6 -0
  70. package/templates/{web/src/oj-market → src/oj-market/web}/api/client.ts +5 -0
  71. package/templates/{web/src/oj-market → src/oj-market/web}/api/context.ts +2 -2
  72. package/templates/{web/src/oj-market → src/oj-market/web}/api/defaultClient.ts +7 -1
  73. package/templates/src/oj-market/web/components/InstallDialog.tsx +194 -0
  74. package/templates/{web/src/oj-market → src/oj-market/web}/components/RollbackDialog.tsx +7 -3
  75. package/templates/{web/src/oj-market → src/oj-market/web}/components/UninstallConfirm.tsx +18 -7
  76. package/templates/{web/src/oj-market → src/oj-market/web}/hooks/useMarket.ts +29 -12
  77. package/templates/{web/src/oj-market → src/oj-market/web}/locales/en-US.json +10 -1
  78. package/templates/{web/src/oj-market → src/oj-market/web}/locales/zh-CN.json +10 -1
  79. package/templates/{web/src/oj-market → src/oj-market/web}/types.ts +15 -2
  80. package/templates/{api/src/system → src/system/api}/login-methods/api.ts +2 -2
  81. package/templates/src/system/api/manifest.yaml +6 -0
  82. package/templates/{api/src/system → src/system/api}/oplog/api.ts +4 -4
  83. package/templates/{api/src/system → src/system/api}/permissions/api.ts +3 -3
  84. package/templates/{api/src/system → src/system/api}/roles/api.ts +3 -3
  85. package/templates/{api/src/system → src/system/api}/roles/bindings/api.ts +3 -3
  86. package/templates/{api/src/system → src/system/api}/settings/api.ts +3 -3
  87. package/templates/{api/src/system → src/system/api}/users/api.ts +3 -3
  88. package/templates/{api/src/system → src/system/api}/users/forbidden/api.ts +3 -3
  89. package/templates/{api/src/system → src/system/api}/users/password/api.ts +3 -3
  90. package/templates/{api/src/system → src/system/api}/users/roles/api.ts +3 -3
  91. package/templates/{web/src/system → src/system/web}/locales/en-US.json +1 -1
  92. package/templates/{web/src/system → src/system/web}/locales/zh-CN.json +1 -1
  93. package/templates/src/tsconfig.json +16 -0
  94. package/templates/{api/tests → tests}/auth-ldap.spec.ts +2 -2
  95. package/templates/{api/tests → tests}/auth-session.spec.ts +3 -3
  96. package/templates/{api/tests → tests}/auth-throttle.spec.ts +1 -1
  97. package/templates/tests/fixture.ts +434 -0
  98. package/templates/{api/tests → tests}/guard.spec.ts +1 -1
  99. package/templates/{api/tests → tests}/l1-builder.test.ts +2 -2
  100. package/templates/{api/tests → tests}/lifecycle/atomic-state.spec.ts +3 -3
  101. package/templates/{api/tests → tests}/lifecycle/bootstrap.spec.ts +8 -4
  102. package/templates/{api/tests → tests}/lifecycle/deploy-smoke.spec.ts +31 -8
  103. package/templates/{api/tests → tests}/lifecycle/installer.spec.ts +15 -15
  104. package/templates/{api/tests → tests}/lifecycle/market-api.spec.ts +30 -29
  105. package/templates/{api/tests → tests}/lifecycle/migrate.spec.ts +6 -6
  106. package/templates/{api/tests → tests}/lifecycle/preflight.spec.ts +4 -4
  107. package/templates/{api/tests → tests}/lifecycle/register.spec.ts +1 -1
  108. package/templates/{api/tests → tests}/lifecycle/semver.spec.ts +1 -1
  109. package/templates/{api/tests → tests}/lifecycle/sha384.spec.ts +1 -1
  110. package/templates/{api/tests → tests}/lifecycle/sig-fixtures.spec.ts +1 -1
  111. package/templates/{api/tests → tests}/lifecycle/solutions-api.spec.ts +1 -1
  112. package/templates/{api/tests → tests}/lifecycle/steps-fs.spec.ts +12 -12
  113. package/templates/{api/tests → tests}/lifecycle/text-edit.spec.ts +1 -1
  114. package/templates/{api/tests → tests}/lifecycle/tgz-guard.spec.ts +1 -1
  115. package/templates/{api/tests → tests}/lifecycle/trust.spec.ts +5 -5
  116. package/templates/{api/tests → tests}/lifecycle/uninstall.spec.ts +7 -7
  117. package/templates/{api/tests → tests}/lifecycle/verify-checks.spec.ts +9 -6
  118. package/templates/{api/tests → tests}/lifecycle/verify-report.spec.ts +7 -5
  119. package/templates/{api/tests → tests}/query-utils.spec.ts +1 -1
  120. package/templates/{api/tests → tests}/rbac-audit.spec.ts +1 -1
  121. package/templates/{api/tests → tests}/rbac-contacts.spec.ts +2 -2
  122. package/templates/{api/tests → tests}/rbac-guard.spec.ts +1 -1
  123. package/templates/{api/tests → tests}/rbac-roles.spec.ts +2 -2
  124. package/templates/{api/tests → tests}/rbac-seed.spec.ts +13 -11
  125. package/templates/{api/tests → tests}/rbac-settings.spec.ts +2 -2
  126. package/templates/{api/tests → tests}/rbac-solution-perms.spec.ts +1 -1
  127. package/templates/{api/tests → tests}/rbac-users.spec.ts +3 -3
  128. package/templates/tests/seed-role-accounts.spec.ts +87 -0
  129. package/templates/tsconfig.json +5 -1
  130. package/templates/tsconfig.paths.json +19 -0
  131. package/templates/types/oj-modules.d.ts +17 -0
  132. package/templates/vitest.config.ts +22 -0
  133. package/templates/web.config.ts +23 -13
  134. package/vendor/host-versions.json +3 -3
  135. package/templates/api/src/_platform/seed.mysql.sql +0 -8
  136. package/templates/api/src/_platform/seed.pg.sql +0 -8
  137. package/templates/api/src/auth/manifest.yaml +0 -5
  138. package/templates/api/src/system/manifest.yaml +0 -5
  139. package/templates/api/tests/fixture.ts +0 -58
  140. package/templates/api/tsconfig.json +0 -8
  141. package/templates/api/vitest.config.ts +0 -12
  142. package/templates/logs/task-events.jsonl +0 -0
  143. package/templates/web/src/oj-market/components/InstallDialog.tsx +0 -112
  144. /package/templates/{api/.ojm-api-exempt.json → .ojm-api-exempt.json} +0 -0
  145. /package/templates/{api/seed.mysql.sql → seed.mysql.sql} +0 -0
  146. /package/templates/{api/seed.pg.sql → seed.pg.sql} +0 -0
  147. /package/templates/{api/src/_platform → src/_platform/api}/README.md +0 -0
  148. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/atomic.ts +0 -0
  149. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/history.ts +0 -0
  150. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/lock.ts +0 -0
  151. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/semver.ts +0 -0
  152. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/sha384.ts +0 -0
  153. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/state.ts +0 -0
  154. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/deploy-web.ts +0 -0
  155. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/download.ts +0 -0
  156. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/extract.ts +0 -0
  157. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/migrate.ts +0 -0
  158. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/preflight.ts +0 -0
  159. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/register.ts +0 -0
  160. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/reload.ts +0 -0
  161. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/steps/verify.ts +0 -0
  162. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/tasks.ts +0 -0
  163. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/text-edit.ts +0 -0
  164. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/tgz-guard.ts +0 -0
  165. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/trust.ts +0 -0
  166. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/types.ts +0 -0
  167. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/uninstall.ts +0 -0
  168. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/verify-checks.ts +0 -0
  169. /package/templates/{api/src/_platform → src/_platform/api}/_lifecycle/verify-report.ts +0 -0
  170. /package/templates/{api/src/_platform → src/_platform/api}/_shared/respond.ts +0 -0
  171. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/contacts.ts +0 -0
  172. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/roles.ts +0 -0
  173. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/settings.ts +0 -0
  174. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/solution-perms.ts +0 -0
  175. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/domain/users.ts +0 -0
  176. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/access.ts +0 -0
  177. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/audit.ts +0 -0
  178. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/guard.ts +0 -0
  179. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/oplog.ts +0 -0
  180. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/query.ts +0 -0
  181. /package/templates/{api/src/_platform → src/_platform/api}/_shared/service/infra/rate.ts +0 -0
  182. /package/templates/{api/src/_platform → src/_platform/api}/_shared/site-facade.ts +0 -0
  183. /package/templates/{api/src/_platform → src/_platform/api}/contacts/api.ts +0 -0
  184. /package/templates/{api/src/_platform → src/_platform/api}/contacts/detail/api.ts +0 -0
  185. /package/templates/{api/src/_platform → src/_platform/api}/manifest.yaml +0 -0
  186. /package/templates/{api/src/_platform → src/_platform/api}/market/bootstrap.ts +0 -0
  187. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0001__create_users.mysql.sql +0 -0
  188. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0001__create_users.pg.sql +0 -0
  189. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0001__create_users.sql +0 -0
  190. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0002__add_users_avatar_base64.mysql.sql +0 -0
  191. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0002__add_users_avatar_base64.sql +0 -0
  192. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0003__users_source_display_name.mysql.sql +0 -0
  193. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0003__users_source_display_name.sql +0 -0
  194. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0004__sys_rbac.mysql.sql +0 -0
  195. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0004__sys_rbac.pg.sql +0 -0
  196. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0004__sys_rbac.sql +0 -0
  197. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0005__users_must_change.mysql.sql +0 -0
  198. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0005__users_must_change.sql +0 -0
  199. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0006__users_is_forbidden.mysql.sql +0 -0
  200. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0006__users_is_forbidden.sql +0 -0
  201. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0007__users_email.sql +0 -0
  202. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0008__sys_refresh_token.mysql.sql +0 -0
  203. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0008__sys_refresh_token.pg.sql +0 -0
  204. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0008__sys_refresh_token.sql +0 -0
  205. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0009__sys_throttle.mysql.sql +0 -0
  206. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0009__sys_throttle.pg.sql +0 -0
  207. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0009__sys_throttle.sql +0 -0
  208. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0010__sys_solution_route.mysql.sql +0 -0
  209. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0010__sys_solution_route.pg.sql +0 -0
  210. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0010__sys_solution_route.sql +0 -0
  211. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0011__sys_setting_group_label.mysql.sql +0 -0
  212. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0011__sys_setting_group_label.sql +0 -0
  213. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0012__market_history.mysql.sql +0 -0
  214. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0012__market_history.pg.sql +0 -0
  215. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0012__market_history.sql +0 -0
  216. /package/templates/{api/src/_platform → src/_platform/api}/migrations/0013__users_profile.sql +0 -0
  217. /package/templates/{api/src/_platform → src/_platform/api}/schema.yaml +0 -0
  218. /package/templates/{web/src/_platform → src/_platform/web}/__client/api.schemas.ts +0 -0
  219. /package/templates/{web/src/_platform → src/_platform/web}/__client/api.ts +0 -0
  220. /package/templates/{web/src/about → src/about/web}/entry.ts +0 -0
  221. /package/templates/{web/src/about → src/about/web}/locales/en-US.json +0 -0
  222. /package/templates/{web/src/about → src/about/web}/locales/zh-CN.json +0 -0
  223. /package/templates/{web/src/about → src/about/web}/pages/constants.ts +0 -0
  224. /package/templates/{web/src/about → src/about/web}/pages/index.tsx +0 -0
  225. /package/templates/{web/src/access → src/access/web}/entry.ts +0 -0
  226. /package/templates/{web/src/access → src/access/web}/locales/en-US.json +0 -0
  227. /package/templates/{web/src/access → src/access/web}/locales/zh-CN.json +0 -0
  228. /package/templates/{web/src/access → src/access/web}/pages/access-mode/index.tsx +0 -0
  229. /package/templates/{web/src/access → src/access/web}/pages/admin-visible/index.tsx +0 -0
  230. /package/templates/{web/src/access → src/access/web}/pages/button-control/index.tsx +0 -0
  231. /package/templates/{web/src/access → src/access/web}/pages/common-visible/index.tsx +0 -0
  232. /package/templates/{web/src/access → src/access/web}/pages/page-control/index.tsx +0 -0
  233. /package/templates/{api/src/auth → src/auth/api}/_shared/ldap-login.ts +0 -0
  234. /package/templates/{api/src/auth → src/auth/api}/_shared/ldap.ts +0 -0
  235. /package/templates/{web/src/auth → src/auth/web}/__client/api.schemas.ts +0 -0
  236. /package/templates/{web/src/auth → src/auth/web}/__client/api.ts +0 -0
  237. /package/templates/{api/src/demo → src/demo/api}/manifest.yaml +0 -0
  238. /package/templates/{api/src/demo → src/demo/api}/migrations/0001__create_todos.sql +0 -0
  239. /package/templates/{api/src/demo → src/demo/api}/schema.yaml +0 -0
  240. /package/templates/{api/src/demo → src/demo/api}/seed.sql +0 -0
  241. /package/templates/{api/src/demo → src/demo/api}/todos/api.ts +0 -0
  242. /package/templates/{web/src/demo → src/demo/web}/__client/api.schemas.ts +0 -0
  243. /package/templates/{web/src/demo → src/demo/web}/__client/api.ts +0 -0
  244. /package/templates/{web/src/demo → src/demo/web}/entry.ts +0 -0
  245. /package/templates/{web/src/demo → src/demo/web}/locales/en-US.json +0 -0
  246. /package/templates/{web/src/demo → src/demo/web}/locales/zh-CN.json +0 -0
  247. /package/templates/{web/src/demo → src/demo/web}/pages/index.tsx +0 -0
  248. /package/templates/{web/src/exception → src/exception/web}/entry.ts +0 -0
  249. /package/templates/{web/src/exception → src/exception/web}/locales/en-US.json +0 -0
  250. /package/templates/{web/src/exception → src/exception/web}/locales/zh-CN.json +0 -0
  251. /package/templates/{web/src/exception → src/exception/web}/pages/403/index.tsx +0 -0
  252. /package/templates/{web/src/exception → src/exception/web}/pages/404/index.tsx +0 -0
  253. /package/templates/{web/src/exception → src/exception/web}/pages/500/index.tsx +0 -0
  254. /package/templates/{web/src/exception → src/exception/web}/pages/unknown-component/index.tsx +0 -0
  255. /package/templates/{api/src/home → src/home/api}/line/api.ts +0 -0
  256. /package/templates/{api/src/home → src/home/api}/manifest.yaml +0 -0
  257. /package/templates/{api/src/home → src/home/api}/migrations/0001__create_home_tables.sql +0 -0
  258. /package/templates/{api/src/home → src/home/api}/pie/api.ts +0 -0
  259. /package/templates/{api/src/home → src/home/api}/schema.yaml +0 -0
  260. /package/templates/{api/src/home → src/home/api}/seed.sql +0 -0
  261. /package/templates/{web/src/home → src/home/web}/__client/api.schemas.ts +0 -0
  262. /package/templates/{web/src/home → src/home/web}/__client/api.ts +0 -0
  263. /package/templates/{web/src/home → src/home/web}/entry.ts +0 -0
  264. /package/templates/{web/src/home → src/home/web}/locales/en-US.json +0 -0
  265. /package/templates/{web/src/home → src/home/web}/locales/zh-CN.json +0 -0
  266. /package/templates/{web/src/home → src/home/web}/pages/components/bar-chart.tsx +0 -0
  267. /package/templates/{web/src/home → src/home/web}/pages/components/card-list.tsx +0 -0
  268. /package/templates/{web/src/home → src/home/web}/pages/components/line-chart.tsx +0 -0
  269. /package/templates/{web/src/home → src/home/web}/pages/components/pie-chart.tsx +0 -0
  270. /package/templates/{web/src/home → src/home/web}/pages/index.tsx +0 -0
  271. /package/templates/{web/src/login → src/login/web}/entry.ts +0 -0
  272. /package/templates/{web/src/login → src/login/web}/locales/en-US.json +0 -0
  273. /package/templates/{web/src/login → src/login/web}/locales/zh-CN.json +0 -0
  274. /package/templates/{web/src/login → src/login/web}/pages/change-password.tsx +0 -0
  275. /package/templates/{web/src/login → src/login/web}/pages/login.tsx +0 -0
  276. /package/templates/{api/src/notification → src/notification/api}/_shared/notify.ts +0 -0
  277. /package/templates/{api/src/notification → src/notification/api}/api.ts +0 -0
  278. /package/templates/{api/src/notification → src/notification/api}/del/api.ts +0 -0
  279. /package/templates/{api/src/notification → src/notification/api}/manifest.yaml +0 -0
  280. /package/templates/{api/src/notification → src/notification/api}/migrations/0001__create_notifications.sql +0 -0
  281. /package/templates/{api/src/notification → src/notification/api}/migrations/0002__notifications_user.sql +0 -0
  282. /package/templates/{api/src/notification → src/notification/api}/migrations/0003__notifications_broadcast.sql +0 -0
  283. /package/templates/{api/src/notification → src/notification/api}/migrations/0004__notifications_broadcast_hidden.sql +0 -0
  284. /package/templates/{api/src/notification → src/notification/api}/schema.yaml +0 -0
  285. /package/templates/{api/src/notification → src/notification/api}/seed.sql +0 -0
  286. /package/templates/{web/src/notification → src/notification/web}/__client/api.schemas.ts +0 -0
  287. /package/templates/{web/src/notification → src/notification/web}/__client/api.ts +0 -0
  288. /package/templates/{web/src/notification → src/notification/web}/entry.ts +0 -0
  289. /package/templates/{web/src/notification → src/notification/web}/locales/en-US.json +0 -0
  290. /package/templates/{web/src/notification → src/notification/web}/locales/zh-CN.json +0 -0
  291. /package/templates/{web/src/notification → src/notification/web}/pages/center/index.tsx +0 -0
  292. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/CardGrid.test.tsx +0 -0
  293. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/HistoryDrawer.test.tsx +0 -0
  294. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/RollbackDialog.test.tsx +0 -0
  295. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/UninstallConfirm.test.tsx +0 -0
  296. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/poll.test.ts +0 -0
  297. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/render.tsx +0 -0
  298. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/runtime-stub.ts +0 -0
  299. /package/templates/{web/src/oj-market → src/oj-market/web}/__tests__/semver.test.ts +0 -0
  300. /package/templates/{web/src/oj-market → src/oj-market/web}/api/MarketClientProvider.tsx +0 -0
  301. /package/templates/{web/src/oj-market → src/oj-market/web}/components/CardGrid.tsx +0 -0
  302. /package/templates/{web/src/oj-market → src/oj-market/web}/components/CardItem.tsx +0 -0
  303. /package/templates/{web/src/oj-market → src/oj-market/web}/components/DetailDrawer.tsx +0 -0
  304. /package/templates/{web/src/oj-market → src/oj-market/web}/components/HistoryDrawer.tsx +0 -0
  305. /package/templates/{web/src/oj-market → src/oj-market/web}/entry.ts +0 -0
  306. /package/templates/{web/src/oj-market → src/oj-market/web}/pages/MarketApp.tsx +0 -0
  307. /package/templates/{web/src/oj-market → src/oj-market/web}/utils/poll.ts +0 -0
  308. /package/templates/{web/src/oj-market → src/oj-market/web}/utils/semver.ts +0 -0
  309. /package/templates/{web/src/outside → src/outside/web}/entry.ts +0 -0
  310. /package/templates/{web/src/outside → src/outside/web}/locales/en-US.json +0 -0
  311. /package/templates/{web/src/outside → src/outside/web}/locales/zh-CN.json +0 -0
  312. /package/templates/{api/src/personal-center → src/personal-center/api}/manifest.yaml +0 -0
  313. /package/templates/{api/src/personal-center → src/personal-center/api}/profile/api.ts +0 -0
  314. /package/templates/{api/src/personal-center → src/personal-center/api}/upload/api.ts +0 -0
  315. /package/templates/{web/src/personal-center → src/personal-center/web}/__client/api.schemas.ts +0 -0
  316. /package/templates/{web/src/personal-center → src/personal-center/web}/__client/api.ts +0 -0
  317. /package/templates/{web/src/personal-center → src/personal-center/web}/entry.ts +0 -0
  318. /package/templates/{web/src/personal-center → src/personal-center/web}/locales/en-US.json +0 -0
  319. /package/templates/{web/src/personal-center → src/personal-center/web}/locales/zh-CN.json +0 -0
  320. /package/templates/{web/src/personal-center → src/personal-center/web}/pages/my-profile/index.tsx +0 -0
  321. /package/templates/{web/src/route-nest → src/route-nest/web}/entry.ts +0 -0
  322. /package/templates/{web/src/route-nest → src/route-nest/web}/locales/en-US.json +0 -0
  323. /package/templates/{web/src/route-nest → src/route-nest/web}/locales/zh-CN.json +0 -0
  324. /package/templates/{web/src/route-nest → src/route-nest/web}/pages/menu1/menu1-1/index.tsx +0 -0
  325. /package/templates/{web/src/route-nest → src/route-nest/web}/pages/menu1/menu1-2/index.tsx +0 -0
  326. /package/templates/{web/src/route-nest → src/route-nest/web}/pages/menu2/index.tsx +0 -0
  327. /package/templates/{web/src → src}/styles.css +0 -0
  328. /package/templates/{web/src/system → src/system/web}/__client/api.schemas.ts +0 -0
  329. /package/templates/{web/src/system → src/system/web}/__client/api.ts +0 -0
  330. /package/templates/{web/src/system → src/system/web}/entry.ts +0 -0
  331. /package/templates/{web/src/system → src/system/web}/pages/errors.ts +0 -0
  332. /package/templates/{web/src/system → src/system/web}/pages/forbidden.tsx +0 -0
  333. /package/templates/{web/src/system → src/system/web}/pages/login-methods/index.tsx +0 -0
  334. /package/templates/{web/src/system → src/system/web}/pages/oplog/index.tsx +0 -0
  335. /package/templates/{web/src/system → src/system/web}/pages/roles/index.tsx +0 -0
  336. /package/templates/{web/src/system → src/system/web}/pages/settings/index.tsx +0 -0
  337. /package/templates/{web/src/system → src/system/web}/pages/users/index.tsx +0 -0
  338. /package/templates/{web/src/system → src/system/web}/pages/users/roles.tsx +0 -0
  339. /package/templates/{api/src/web → src/web/api}/get-async-routes/api.ts +0 -0
  340. /package/templates/{api/src/web → src/web/api}/hello/api.ts +0 -0
  341. /package/templates/{api/src/web → src/web/api}/manifest.yaml +0 -0
  342. /package/templates/{api/src/web → src/web/api}/user-info/api.ts +0 -0
  343. /package/templates/{web/src → src/web}/web/__client/api.schemas.ts +0 -0
  344. /package/templates/{web/src → src/web}/web/__client/api.ts +0 -0
  345. /package/templates/{api/tests → tests}/rbac-tables.spec.ts +0 -0
package/devkit/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  面向用 `ojm` 开发前后端一体工程的开发者与 AI agent。本目录是**源文件**,
4
4
  发布时由 cli 的 `prepack`(`packages/cli/scripts/sync-devkit.mjs`)把其中
5
- **ojm 侧的 5 个文件**同步进 `packages/cli/devkit/`,随 `@oj-module/cli`
5
+ **ojm 侧的 6 个文件**同步进 `packages/cli/devkit/`,随 `@oj-module/cli`
6
6
  发布,再由 `ojm init` 分发到工程内。
7
7
 
8
8
  整棵树覆盖前后端两侧,但仍是**两套独立分发的 skill**(同名不同物,别混):
9
9
 
10
10
  | 侧 | 本仓位置 | 用户工程里的落点 | 分发链 |
11
11
  |---|---|---|---|
12
- | ojm 模块开发(前端模块、契约、前后端对接) | 本目录顶层 5 个文件 | `.claude/skills/ojm-module-dev/` | `@oj-module/cli` 包 → `ojm init` 第 4b 步 |
12
+ | ojm 模块开发(前端模块、契约、前后端对接) | 本目录顶层 6 个文件 | `.claude/skills/ojm-module-dev/` | `@oj-module/cli` 包 → `ojm init` 第 4b 步 |
13
13
  | oj API 开发(后端 handler、全局对象、配置、测试) | `oj-api-dev/` 子目录(快照) | `.claude/skills/oj-api-dev/` | **oj 二进制自带**(`bin/devkit/`)→ `ojm init` 第 4 步 |
14
14
 
15
15
  > **`oj-api-dev/` 子目录是快照,不是本仓维护的文档**:它与本机 oj 的
@@ -24,7 +24,7 @@
24
24
  | 文件 | 用途 |
25
25
  |---|---|
26
26
  | `SKILL.md` | Claude Code 等 agent 的 skill 入口:工作流、红线、新模块 checklist、陷阱速查,按章节号引用手册 |
27
- | `manual.md` | 模块开发手册(12 章):工程结构(含 §1.7 handler 四红线——oj 运行时实测钉出,后端必读)、写模块、契约与代码生成(含 §3.10 旧 contract.ts 工程迁移指南)、provider 接管(覆盖框架内置功能)、布局、i18n、构建发布、排查、CLI 子命令参考(ojm 原生命令 vs oj 透传命令)、方案包打包与分发、签名与信任 |
27
+ | `manual.md` | 模块开发手册(13 章):工程结构(module-root 单树 + 两处产物根;含 §1.7 handler 四红线——oj 运行时实测钉出,后端必读;§1.8 `#` 别名与 TS 投影)、写模块、契约与代码生成(含 §3.10 旧 contract.ts 工程迁移指南)、provider 接管(覆盖框架内置功能)、布局、i18n、构建发布、排查、CLI 子命令参考(ojm 原生命令 vs oj 透传命令)、方案包打包与分发、签名与信任 |
28
28
  | `framework-dev.md` | 框架贡献者路线(**仅框架仓库**):改 `packages/runtime`、`packages/cli` 时的入口与红线 |
29
29
  | `module-dev-and-cdn-playground.md` | 教学文档:开发态 ≠ 分发态、「怎么安装自己的模块 / 会不会重复」、本地 CDN 市场链路五步跑通(setup → publish → build-index → verify → 安装) |
30
30
  | `sql-builder-missing-capabilities-pr.md` | 构造器能力缺口 PR 参考(**仅框架仓库**):7 项诉求的闭环记录 |
@@ -108,6 +108,6 @@ flowchart LR
108
108
  框架贡献者要把本仓快照同步到新版:从 `~/.local/share/oj/devkit/` 整目录覆盖
109
109
  `docs/devkit/oj-api-dev/`(10 个文件,保持逐字节一致以便对账)。
110
110
 
111
- > 本目录顶层 5 个文件是**自包含**的:业务工程拿到即可读懂,不需要工程仓库里的
111
+ > 本目录顶层 6 个文件是**自包含**的:业务工程拿到即可读懂,不需要工程仓库里的
112
112
  > 其它文档。`oj-api-dev/` 子目录是 oj 侧快照,同样自包含(其自身 README 即索引),
113
113
  > 但不随 cli 包发货、仅本仓参考。维护者视角的内容来源整理在 `framework-dev.md`(仅本仓)。
package/devkit/SKILL.md CHANGED
@@ -17,8 +17,9 @@ description: 用 ojm 开发前后端一体工程时使用——新增/修改前
17
17
 
18
18
  1. **读章**:建模块 → 手册 §2;加接口(handler .schema → oj openapi → 生成 → 对接)→ §3;
19
19
  接管通知/上传/菜单 → §4;换布局或加插槽 → §5;排查 → §8。
20
- 2. **建目录**:前端 `web/src/<模块名>/`(`entry.ts` 必备,`pages/`、`locales/` 按需);
21
- 后端 `api/src/<模块名>/`(目录镜像路由的 `api.ts`,动词挂 `.schema`)。
20
+ 2. **建目录**:一个目录 = 一个模块——前端一侧 `src/<模块名>/web/`(`entry.ts` 必备,
21
+ `pages/`、`locales/` 按需),后端一侧 `src/<模块名>/api/`(目录镜像路由的 `api.ts`,
22
+ 动词挂 `.schema`)。两侧可只存在一侧。
22
23
  `entry.ts` 是模块元数据**唯一来源**——没有单独的 `package.json` / `meta.json`。
23
24
  3. **对接四步流水线**(加接口就背这条):
24
25
  ```
@@ -29,19 +30,21 @@ description: 用 ojm 开发前后端一体工程时使用——新增/修改前
29
30
  flowchart LR
30
31
  A["handler 动词写 .schema(入参)+ 平级 .response(出参)"] --> B["写业务逻辑 api.ts"]
31
32
  B --> C["oj openapi 生成 openapi.json(唯一事实源)"]
32
- C --> D["ojm api 生成 web/src/模块/__client"]
33
- D --> E["entry.ts onInit:createModuleClient(ctx) 一次"]
34
- E --> F["web.config.ts 登记模块(漏了静默不加载)"]
33
+ C --> D["ojm api 生成 src/模块/web/__client"]
34
+ D --> E["entry.ts onInit:create&lt;模块&gt;Client(ctx) 一次"]
35
+ E --> F["web.config.ts 登记模块(可选覆盖;扫描为真源)"]
35
36
  ```
36
- 4. **登记**:往工程根 `web.config.ts` 的 `modules` 数组加一项。**漏了这步模块静默不加载、全程不报错。**
37
- 5. **验证**:`pnpm dev`(前端 devServer **5174** + oj 后端 **9778**,端口以 `api/config.yaml` 为准)
37
+ 4. **登记**:往工程根 `web.config.ts` 的 `modules` 数组加一项(module-root 布局里 `ojm build/dev`
38
+ 以扫描 `src/*/web/entry.ts` 为真源,登记项排前面、其余按扫描顺序追加;历史布局则必须登记)。
39
+ **要「不构建」写 `enabled: false`——注释掉无效。**
40
+ 5. **验证**:`pnpm dev`(前端 devServer **5174** + oj 后端 **9778**,端口以工程根 `config.yaml` 为准)
38
41
  → 登录 `admin / 123456` → 按 §8.1 五步清单核对。
39
42
 
40
43
  ## 红线(不可违反)
41
44
 
42
- - **登记**:模块必须写进 `web.config.ts` 的 `modules`(`enabled` 缺省即启用,显式
43
- `enabled: false` 才禁用)。文件写完 ≠ 模块会跑。
45
+ - **登记**:`web.config.ts` 的 `modules`(`enabled` 缺省即启用,显式 `enabled: false` 才禁用)。
44
46
  清单**先后顺序就是接管优先级**(同一入口先注册者生效,无优先级数字可填)。
47
+ 历史布局漏登记 = 模块安静不加载;module-root 下登记是可选的,但**排序仍靠它**。
45
48
  - **`home` / `login` 模块必须保留**:shell 预构建把 `/` 重定向到 `/home`,且宿主只消费
46
49
  模块路由、不挂内置登录页。删掉它们 → 登录回跳落错误边界、`/login` 无路由可跳。
47
50
  - **布局级路由 handle 必写 `layout: "container"`**:不写页面会裸渲染(无侧边栏/页签),
@@ -49,16 +52,16 @@ description: 用 ojm 开发前后端一体工程时使用——新增/修改前
49
52
  - **注册时机**:一切 `ctx.register.*` 必须在 `lifecycle.onInit` 内、且在 onInit 返回前完成。
50
53
  拖到 `onActivate` 或某个异步回调里注册不保证生效。`onInit` 签名是 **async**(返回
51
54
  `Promise<void>`)——漏写 `async` 会被 `tsc` 以 TS2322 拦下,范本见模板
52
- `web/src/notification/entry.ts`。
55
+ `src/notification/web/entry.ts`。
53
56
  - **一模块一 client**:`create<Module>Client(ctx)` 只在 onInit 里创建一次。
54
57
  页面/组件/事件回调里**不要**再创建——会覆盖 request 单槽。页面里直接 import 裸函数调用。
55
58
  - **只创建自己模块的 client**:A 模块的 onInit 里创建 B 模块的 client 会 DEV 告警。要别家接口,
56
59
  走「B 自己注册 provider、A 消费 provider」的正路。
57
60
  - **既然接管就整套接管**:`ctx.register.*Provider` 的方法一个都不能少,不做「只接管读、写还用框架的」。
58
- - **生成物勿手改**:`web/src/<模块>/__client/**` 重跑即覆盖(eslint 已忽略)。改需求 = 改 handler 的
61
+ - **生成物勿手改**:`src/<模块>/web/__client/**` 重跑即覆盖(eslint 已忽略)。改需求 = 改 handler 的
59
62
  `.schema`,重跑 `oj openapi` + `ojm api`。`openapi.json` 由 `oj openapi` 生成(oj 内省 `.schema` 的权威产物)。
60
- 唯一例外是 `api/**/api.ts` stub——文件头带 `// ojm-api:stub` 指纹的 stub 被人工动过后,工具**永不写永不删**。
61
- - **前缀约束**:API 前缀由**后端模块目录名**推导(`api/src/order/**` → `/order`,**不是** `/api/order`)。
63
+ 唯一例外是 `src/<模块>/api/**/api.ts` 的 stub——文件头带 `// ojm-api:stub` 指纹、被人工动过后,工具**永不写永不删**。
64
+ - **前缀约束**:API 前缀取模块 `manifest.yaml` 的 `name`(**约定与目录名一致**;`src/order/api/**` → `/order`,**不是** `/api/order`)。
62
65
  handler `.schema` / 路由须落在该目录内,否则 oj 路由表与生成物对不上、人话报错。
63
66
  - **不返回数据的接口不写 `.response`**:平级声明位直接省略即可(oj v0.1.72+;旧 `.schema.response` 通道仍兼容);校验一律放后端。
64
67
  - **上传文件**:当前 `ojm api` 的 openapi 流水线不生成 form 通道的前端 client(文件部件不进 JSON Schema),
@@ -70,30 +73,30 @@ description: 用 ojm 开发前后端一体工程时使用——新增/修改前
70
73
  写走契约 client(`ojm api` 生成模块自有 `__client`,或复用 runtime 导出的 `api/rbac` / `api/user`),
71
74
  绝不 import 框架 `#src/*`**——设计动机与红线见手册 §2.8。
72
75
  - **后端方法名是 `del`,不是 `delete`**(写成 `delete` 返回 405)。
73
- - **加一张新表是三件套,不是只写 `schema.yaml`**:`migrations/{seq:04}__*.sql`(DDL 的真正定义(实际 SQL),
76
+ - **加一张新表是三件套,不是只写 `schema.yaml`**:`src/<模块>/api/migrations/{seq:04}__*.sql`(DDL 的真正定义(实际 SQL),
74
77
  DDL 只进 migrations)+ `schema.yaml`(声明,与 migration 逐字段一致)+ `manifest.yaml` 的 `tables:`
75
78
  (与 schema 双向一致)。少一个就建不出表或启动失败。见手册 §1.5。
76
79
  - **`seed.sql` 每次启动都重放**,必须幂等(`INSERT OR IGNORE`);它按 `;` 朴素切分,
77
80
  注释里不许出现分号字面量。
78
81
  - **handler 四红线(manual §1.7,oj 运行时实测)**:① 未捕获异常恒 500 不读
79
- `err.status`——业务错误必须经 `respond()` 收口 `json.fail`;② 相对 import 按
80
- **目录**解析(多一层 `../` 就 route error);③ 模块级 `let`/`Map` 不跨请求存活
81
- (oj 每请求重建模块)——跨请求状态必须落库;④ 模块级禁止触碰运行时全局
82
- (`jwt`/`axis`/`bcrypt`),`oj build` introspect 空沙箱会炸。
82
+ `err.status`——业务错误必须经 `respond()` 收口 `json.fail`;② 跨模块引用走
83
+ `#/<模块名>/…` 别名(相对 import 按**目录**解析,多一层 `../` 就 route error);
84
+ ③ 模块级 `let`/`Map` 不跨请求存活(oj 每请求重建模块)——跨请求状态必须落库;
85
+ ④ 模块级禁止触碰运行时全局(`jwt`/`axis`/`bcrypt`),`oj build` introspect 空沙箱会炸。
83
86
 
84
87
  ## 重启边界(最容易卡住新人)
85
88
 
86
89
  | 改动 | 生效方式 |
87
90
  |---|---|
88
- | 已有 `api.ts` 的**文件内容** | 保存即热更 |
89
- | **新增/删除**后端模块目录 | **必须重启 `ojm dev`** |
91
+ | 已有 `api/**/api.ts` 的**文件内容** | 保存即热更 |
92
+ | **新增/删除**后端模块目录(`src/<模块>/api`) | **必须重启 `ojm dev`** |
90
93
  | 改 `schema.yaml` / `migrations/` / `config.yaml` | **必须重启** |
91
- | 前端 `web/src/**` | 模块重建 + 浏览器自动刷新 |
94
+ | 前端 `src/<模块>/web/**` | 模块重建 + 浏览器自动刷新 |
92
95
 
93
96
  ## 新模块 checklist
94
97
 
95
- - [ ] `web/src/<模块>/entry.ts` 默认导出 `defineModule({ name, version, routes, i18n?, lifecycle? })`
96
- - [ ] `web.config.ts` 的 `modules` 里已登记且 `enabled: true`
98
+ - [ ] `src/<模块>/web/entry.ts` 默认导出 `defineModule({ name, version, routes, i18n?, lifecycle? })`
99
+ - [ ] `web.config.ts` 的 `modules` 里已登记(`enabled` 缺省即启用;module-root 下扫描已能捡到,登记用于排序/覆盖)
97
100
  - [ ] 路由 `handle.layout` 选对了(有页面用 `"container"`;无页面模块 `routes: []`)
98
101
  - [ ] 菜单标题用命名空间语法 `"<模块名>:menu.<key>"`,且 `locales/<lang>.json` 里有这个 key
99
102
  - [ ] 有接口 → handler 动词挂了 `.schema`(入参)+ 平级 `.response`(出参,oj v0.1.72+)→ `oj openapi` + `ojm api` 跑过 → onInit 里 `create<Module>Client(ctx)`
@@ -105,10 +108,10 @@ description: 用 ojm 开发前后端一体工程时使用——新增/修改前
105
108
 
106
109
  存量工程用 `api/src/<模块>/contract.ts`(`defineApi` + zod)声明契约——翻译层已删除,
107
110
  `ojm api` 不再读取它。迁移五步:① 盘点端点 → ② 入参译到 `.schema`、`data` 译到平级
108
- `.response`(zod→JSON Schema 对照表)→ ③ `oj openapi -c api/config.yaml -d api/src -b /api -o openapi.json`
109
- → ④ `ojm api` + 前端调用点改 `camelCase(operationId)` → ⑤ 删 `contract.ts` 与旧产物
111
+ `.response`(zod→JSON Schema 对照表)→ ③ `oj openapi -c config.yaml --module-root src -b /api -o openapi.json`
112
+ (历史布局 `-d api/src`)→ ④ `ojm api` + 前端调用点改 `camelCase(operationId)` → ⑤ 删 `contract.ts` 与旧产物
110
113
  (per-module `routes.json` / `openapi.yaml`),`ojm api --check` 零漂移。
111
- 前置:oj ≥ 0.1.73、框架包 ≥ 0.1.20。完整字段映射与丢失面清单见 **manual.md §3.10**。
114
+ 前置:oj ≥ 0.1.73(迁到 module-root 布局需 ≥ 0.1.85)、框架包 ≥ 0.1.20。完整字段映射与丢失面清单见 **manual.md §3.10**。
112
115
 
113
116
  ## 常见陷阱速查
114
117
 
@@ -137,25 +140,26 @@ description: 用 ojm 开发前后端一体工程时使用——新增/修改前
137
140
  | 移动端侧边栏「不见了」 | 移动端进抽屉、iPad 默认折叠、可关 | 正常;别硬编码侧栏宽度,用 content-width |
138
141
  | 覆盖 `container` 后通知铃/页签没了 | 覆盖了内置外壳,自带 chrome 全失效 | 别覆盖;要加东西用 `header-actions` 插槽 |
139
142
  | 自定义布局里子页面空白 | 组件没渲染 `<Outlet/>` | 补 `<Outlet/>` |
140
- | 登录 401 且 msg 不是 `invalid credentials` | `/auth/*` 不在 `anonymous_paths` | 加进 `api/config.yaml`,重启 |
143
+ | 登录 401 且 msg 不是 `invalid credentials` | `/auth/*` 不在 `anonymous_paths` | 加进工程根 `config.yaml`,重启 |
141
144
  | WS 连接 401(「文件在却连不上」) | 模块写了 `ws.ts`,但其 `/ws` 路由不在 `anonymous_paths`(oj v0.1.30+ WS 握手也过鉴权) | 匿名 WS 加进 `anonymous_paths`;受保护 WS 带 Bearer/Cookie 是正当用法。`ojm api --check` 会对此 warn |
142
145
  | 登出/回登录页落空,或登录后落错误边界 | 工程缺 `login` / `home` 模块 | 在 `web.config.ts` 保留两者 |
143
- | 通知铃 404 `no route matched` | 缺 root 级 `/api/notifications` | 补 `api/src/notifications` 模块 |
144
- | `oj serve` 启动即退,报 `config uses removed server.* site keys (v0.1.58): api_prefix` | 用了 oj v0.1.58 起删除的旧站点键(`api_prefix`/`app_path`/`app_prefix`/`static_sites`/`app_spa_fallback`) | 改 `server.api_prefix: /api` 为顶层 `mounts: [{prefix: "/api", api: "src"}]`;迁移完整 YAML 由报错给出 |
145
- | 改完 `mounts:` 仍全 404 | `api:` 指向目录不是 oj 启动目录下的 `src` | `mounts[].api` 写 `"src"`,`-c` 指向 `api/config.yaml`(ojm dev/preview 已内置) |
146
- | `oj serve` 启动即退,报 `module '_shared' missing manifest.yaml` | 把共享后端代码放到了顶层 `api/src/_shared/`(oj 把 `api/src` 顶层目录都当模块,缺 `manifest.yaml`) | 嵌进所属模块目录:`api/src/<模块>/_shared/`,相对导入 |
147
- | 后端 `import '@oj-module/runtime/...'` 报 `escapes project root` | oj 解析裸 specifier 以 `api/` 为项目根并钳制不越界,`@oj-module/runtime` 符号链接在 `packages/runtime`(项目根外) | 后端原语/类型放 `api/src` 内相对导入;跨模块共享类型仍以 runtime 为单一真源,两端形状手动同步 |
146
+ | 通知铃 404 `no route matched`(`/api/notifications`) | 前端 `notification` 模块没加载 / 没注册 `notificationsApi`,回落到内置只读兜底;脚手架不再提供 root 级 `/api/notifications` | 保留 `src/notification/web/entry.ts` 的登记 + onInit 注册四方法;后端由 `src/notification/api` 出 `/api/notification/*` |
147
+ | `oj serve` 启动即退,报 `config uses removed server.* site keys (v0.1.58): api_prefix` | 用了 oj v0.1.58 起删除的旧站点键(`api_prefix`/`app_path`/`app_prefix`/`static_sites`/`app_spa_fallback`) | 改 `server.api_prefix: /api` 为顶层 `mounts:`(module-root 写 `{prefix: "/api", api: "api/dist"}`;历史布局写 `api: "src"`、源码交给 `-d`);迁移完整 YAML 由报错给出 |
148
+ | 改完 `mounts:` 仍全 404 | `api:` 指向目录不对(相对 config 所在目录) | module-root 指向产物目录 `"api/dist"`、历史布局指向源码树 `"src"`;`-c` 指向工程根 `config.yaml`(ojm dev/preview 已内置)。module-root 模板**故意不写 api 挂载**(源码交给 `--module-root src`、产物交给 `--api-path api/dist`,同时出现会报 module declared in multiple places) |
149
+ | `oj serve` 启动即退,报 `module '_shared' missing manifest.yaml` | 把共享后端代码放到了扫描根顶层(`src/_shared/`)——oj 把扫描根下的顶层目录都当模块;历史布局是 `api/src/_shared/` | 嵌进所属模块:`src/<模块>/api/_shared/`(历史布局 `api/src/<模块>/_shared/`),用 `#<本模块>/...` 别名 |
150
+ | 后端 `import '@oj-module/runtime/...'` 报错或装到站点后崩 | 那是浏览器侧包(React / 浏览器全局),且方案包 tgz 不带 `node_modules` | 后端原语/类型放本模块 `api/_shared/`,跨模块用 `#/<模块名>/_shared/...`;跨端共享类型以 runtime 为单一真源、两端形状手动同步 |
148
151
  | 跨用户删/读他人通知不报错却像没生效 | 原语对不存在/非本人的行 `UPDATE 0` 行返回 `ok`,没区分归属 | 原语(`delNotice`/`markRead`)返回 `boolean`/`count`,端点据 `false`/`0` 映射 `json.fail(403, "forbidden")` |
149
152
  | handler 写了动词子目录(`read/api.ts` 这类) | 旧形态(oj v0.1.64 前) | 按 manual §3.9「DDD 判据速查」reshape:同聚合多动词收模块根嵌套组,`del` 保留键例外 |
150
153
  | 业务错误恒 `{"code":500}`(401/403/409 全变 500) | handler 抛异常被 oj 一律抹 500,不读 `err.status` | service 抛 `Error & {status}`,handler 经 `respond()` 收口(manual §1.7-1) |
151
- | dev 日志 route error(Cannot find module)/ 端点 404 | handler 相对 import 多一层——按**目录**解析 | 按 manual §1.7 深度表改 |
154
+ | dev 日志 route error(Cannot find module)/ 端点 404 | handler 相对 import 多一层——按**目录**解析 | 改用 `#/<模块名>/…` 别名(与深度无关);存量代码按 manual §1.7 深度表改 |
152
155
  | 限速/节流/计数真实请求下永不累积(测试全绿) | 模块级 `Map`/`let` 不跨请求存活(每请求重建模块) | 状态落库(模板迁移 0009 先例)或 oj 持久面 |
153
156
  | `ojm build` 报 `introspect api.ts: jwt not configured` | 模块级语句碰运行时全局,introspect 空沙箱炸 | 移进 handler 函数体内(manual §1.7-4) |
154
157
  | 页签怎么点都关不掉、无报错提示 | `beforeClose` 守卫 fail-safe 否决(守卫抛错按取消处理) | 先查控制台 `[tabs] beforeClose` 报错;确认弹窗逻辑与 `resolve(true/false)` 收口(manual §6.4) |
155
158
 
156
159
  ## 手册
157
160
 
158
- `manual.md`(同目录)共 12 章:1 工程结构(含 **§1.7 handler 四红线**——oj 运行时实测钉出,
159
- 后端 handler 必读)/ 2 写前端模块 / 3 契约与代码生成 / 4 接管框架内置功能(provider)/
160
- 5 布局与插槽 / 6 i18n 与样式 / 7 构建与发布 / 8 排查 / 9 参考 / 10 CLI 子命令参考
161
- (ojm 原生命令 vs oj 透传命令的差异区分)/ 11 方案包打包与分发 / 12 签名与信任。
161
+ `manual.md`(同目录)共 13 章:1 工程结构(module-root 单树 / 两处产物根 / **§1.7 handler 四红线** /
162
+ **§1.8 `#` 别名与 TS 投影**——oj 运行时实测钉出,后端 handler 必读)/ 2 写前端模块 /
163
+ 3 契约与代码生成 / 4 接管框架内置功能(provider)/ 5 布局与插槽 / 6 i18n 与样式 / 7 构建与发布 /
164
+ 8 排查 / 9 参考 / 10 CLI 子命令参考(ojm 原生命令 vs oj 透传命令的差异区分)/
165
+ 11 方案包打包与分发 / 12 签名与信任 / 13 方案菜单归组规则。
@@ -1,7 +1,8 @@
1
1
  # 框架贡献者路线(仅本仓)
2
2
 
3
3
  > 读者:改 `packages/runtime/`、`packages/cli/` 的人。
4
- > **业务工程里用不到本文件**——那些工程只有 `web/src` + `api/src`,
4
+ > **业务工程里用不到本文件**——那些工程是「一棵源码树 + 一个配置」:
5
+ > `src/<模块>/{api,web}` + 工程根 `config.yaml`(历史布局为 `web/src` + `api/src`),
5
6
  > 没有 `packages/`。业务开发看 `SKILL.md` + `manual.md`。
6
7
 
7
8
  ## §1 先读哪份文档
@@ -20,7 +21,7 @@
20
21
  > ⚠️ 那两份 guide 有**已知陈旧处**,以源码为准:
21
22
  > dev 端口实际是 **3333**(guide 写的 5173 已过时;注意与 `ojm dev` 的前端 devServer
22
23
  > **5174** 不是一回事——前者是本仓 vite,后者是业务工程 devServer);包版本以
23
- > `packages/*/package.json` 为准(撰写时实际 **0.2.8**,仅供参考,以当前 package.json 为准)。
24
+ > `packages/*/package.json` 为准(撰写时实际 **0.2.20**,仅供参考,以当前 package.json 为准)。
24
25
 
25
26
  ## §2 两包结构与依赖方向
26
27
 
@@ -103,7 +104,7 @@ pnpm test tests/shell # 宿主全量
103
104
  | 不变式 | 说明 |
104
105
  |---|---|
105
106
  | scoped request 在 onInit 绑定 | `onInit` 里绑定 scoped request |
106
- | 契约前缀字面相等 | uni-dev 形态 `apiPrefix` 必须字面等于目录名 |
107
+ | 契约前缀字面相等 | 路由前缀取 `manifest.yaml` 的 `name`(0.1.85 起与目录名脱钩);uni-dev 历史形态下 `apiPrefix` 必须字面等于目录名 |
107
108
  | 模块仅 import 三类(`#src` 双声明) | `#src/*` 由 package.json `imports` 与 vite alias 双声明 |
108
109
  | 模块元信息从 entry.ts 解析 | 模块 name/version 从 `entry.ts` 解析(esbuild bundle + 真实 `import()`) |
109
110
  | 生产产物不含 fake | 生产构建不含 fake 代码(**有测试断言产物里无 fake**) |
@@ -138,7 +139,7 @@ pnpm test tests/shell # 宿主全量
138
139
  **一键发布**:`node scripts/publish-packages.mjs`(lockstep 门禁 → 构建 → 守卫测试 →
139
140
  runtime → cli → registry 复核;`--dry-run` 只演练)。下面的手动步骤是它的展开参考。
140
141
 
141
- - **两包**同版本号(`@oj-module/runtime` + `@oj-module/cli`,当前 `0.2.8`),后续发版保持
142
+ - **两包**同版本号(`@oj-module/runtime` + `@oj-module/cli`,当前 `0.2.20`),后续发版保持
142
143
  lockstep;`@plane/kit` / `@plane/editor` 不在发布集内(脚本里已注释)。
143
144
  - **必须 `pnpm publish`**——用 `npm publish` 会漏出 `workspace:*` / `catalog:` 字面量。
144
145
  - **顺序:先 `runtime` 后 `cli`**。`runtime` 未公开时,新 `cli` 的精确依赖会悬空,
@@ -186,7 +187,7 @@ runtime → cli → registry 复核;`--dry-run` 只演练)。下面的手动
186
187
 
187
188
  ## 附:本 devkit 内容来源(维护者看)
188
189
 
189
- `docs/devkit/` 是**自包含**的交付文档(顶层 5 个文件,含
190
+ `docs/devkit/` 是**自包含**的交付文档(顶层 6 个文件,含
190
191
  `sql-builder-missing-capabilities-pr.md` 这份构造器能力缺口 PR 参考),业务工程拿到即可读懂,不依赖工程仓库里的其它文档。
191
192
  另有 `oj-api-dev/` 子目录是 oj 侧 devkit 的快照(10 文件,仅本仓参考、不发货),
192
193
  结构说明见 `README.md`。