@ai-partner-x/aiko-boot-cli 0.1.4

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 (389) hide show
  1. package/README.md +187 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +30 -0
  4. package/dist/commands/add-api.d.ts +5 -0
  5. package/dist/commands/add-api.js +34 -0
  6. package/dist/commands/add-app.d.ts +5 -0
  7. package/dist/commands/add-app.js +34 -0
  8. package/dist/commands/add-feature.d.ts +5 -0
  9. package/dist/commands/add-feature.js +32 -0
  10. package/dist/commands/init.d.ts +7 -0
  11. package/dist/commands/init.js +42 -0
  12. package/dist/commands/list.d.ts +6 -0
  13. package/dist/commands/list.js +36 -0
  14. package/dist/core/framework-version.d.ts +8 -0
  15. package/dist/core/framework-version.js +40 -0
  16. package/dist/core/logger.d.ts +6 -0
  17. package/dist/core/logger.js +16 -0
  18. package/dist/core/project-config.d.ts +21 -0
  19. package/dist/core/project-config.js +17 -0
  20. package/dist/core/prompts.d.ts +5 -0
  21. package/dist/core/prompts.js +43 -0
  22. package/dist/core/template-utils.d.ts +1 -0
  23. package/dist/core/template-utils.js +42 -0
  24. package/dist/core/workspace.d.ts +10 -0
  25. package/dist/core/workspace.js +141 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.js +2 -0
  28. package/dist/scaffold.d.ts +7 -0
  29. package/dist/scaffold.js +272 -0
  30. package/dist/usecases/add-api.usecase.d.ts +16 -0
  31. package/dist/usecases/add-api.usecase.js +87 -0
  32. package/dist/usecases/add-app.usecase.d.ts +16 -0
  33. package/dist/usecases/add-app.usecase.js +101 -0
  34. package/dist/usecases/add-feature.usecase.d.ts +15 -0
  35. package/dist/usecases/add-feature.usecase.js +566 -0
  36. package/dist/usecases/init-scaffold.usecase.d.ts +19 -0
  37. package/dist/usecases/init-scaffold.usecase.js +131 -0
  38. package/package.json +43 -0
  39. package/templates/api-base/app.config.ts +155 -0
  40. package/templates/api-base/package.json +55 -0
  41. package/templates/api-base/scripts/codegen.cjs +30 -0
  42. package/templates/api-base/scripts/codegen.ts +10 -0
  43. package/templates/api-base/src/controller/auth.controller.ts +160 -0
  44. package/templates/api-base/src/controller/menu.controller.ts +56 -0
  45. package/templates/api-base/src/controller/role.controller.ts +62 -0
  46. package/templates/api-base/src/controller/user.controller.ts +75 -0
  47. package/templates/api-base/src/dto/auth.dto.ts +31 -0
  48. package/templates/api-base/src/dto/menu.dto.ts +38 -0
  49. package/templates/api-base/src/dto/role.dto.ts +18 -0
  50. package/templates/api-base/src/dto/user.dto.ts +36 -0
  51. package/templates/api-base/src/entity/menu.entity.ts +35 -0
  52. package/templates/api-base/src/entity/role-menu.entity.ts +14 -0
  53. package/templates/api-base/src/entity/role.entity.ts +23 -0
  54. package/templates/api-base/src/entity/user-role.entity.ts +14 -0
  55. package/templates/api-base/src/entity/user.entity.ts +32 -0
  56. package/templates/api-base/src/mapper/menu.mapper.ts +7 -0
  57. package/templates/api-base/src/mapper/role-menu.mapper.ts +7 -0
  58. package/templates/api-base/src/mapper/role.mapper.ts +7 -0
  59. package/templates/api-base/src/mapper/user-role.mapper.ts +7 -0
  60. package/templates/api-base/src/mapper/user.mapper.ts +12 -0
  61. package/templates/api-base/src/scripts/init-db.ts +204 -0
  62. package/templates/api-base/src/server.ts +69 -0
  63. package/templates/api-base/src/service/auth.service.ts +144 -0
  64. package/templates/api-base/src/service/log.request.service.ts +72 -0
  65. package/templates/api-base/src/service/menu.service.ts +94 -0
  66. package/templates/api-base/src/service/role.service.ts +88 -0
  67. package/templates/api-base/src/service/user.service.ts +175 -0
  68. package/templates/api-base/src/utils/jwt.util.ts +39 -0
  69. package/templates/api-base/tsconfig.json +18 -0
  70. package/templates/feature-file/api/upload.controller.ts +97 -0
  71. package/templates/feature-log/api/docs/log-integration-guide.md +54 -0
  72. package/templates/feature-log/api/src/service/log.request.service.ts +112 -0
  73. package/templates/feature-log/api/src/service/log.service.ts +124 -0
  74. package/templates/feature-mq/api/src/controller/mq.controller.ts +35 -0
  75. package/templates/feature-mq/api/src/dto/mq.dto.ts +16 -0
  76. package/templates/feature-mq/api/src/service/mq.consumer.service.ts +26 -0
  77. package/templates/feature-redis/api/src/controller/cache.controller.ts +107 -0
  78. package/templates/feature-redis/api/src/dto/cache.dto.ts +24 -0
  79. package/templates/feature-redis/api/src/service/cache.service.ts +80 -0
  80. package/templates/scaffold-default/README.md +114 -0
  81. package/templates/scaffold-default/package.json +26 -0
  82. package/templates/scaffold-default/packages/admin/.env.dev +1 -0
  83. package/templates/scaffold-default/packages/admin/.env.prod +4 -0
  84. package/templates/scaffold-default/packages/admin/.env.stage +4 -0
  85. package/templates/scaffold-default/packages/admin/Dockerfile +37 -0
  86. package/templates/scaffold-default/packages/admin/README.MD +27 -0
  87. package/templates/scaffold-default/packages/admin/components.json +21 -0
  88. package/templates/scaffold-default/packages/admin/eslint.config.js +28 -0
  89. package/templates/scaffold-default/packages/admin/index.html +50 -0
  90. package/templates/scaffold-default/packages/admin/package.json +100 -0
  91. package/templates/scaffold-default/packages/admin/public/vite.svg +1 -0
  92. package/templates/scaffold-default/packages/admin/src/App.css +82 -0
  93. package/templates/scaffold-default/packages/admin/src/App.tsx +128 -0
  94. package/templates/scaffold-default/packages/admin/src/app.config.ts +3 -0
  95. package/templates/scaffold-default/packages/admin/src/components/admin-ui/data-table/data-table-pagination.tsx +148 -0
  96. package/templates/scaffold-default/packages/admin/src/components/admin-ui/data-table/data-table-sorter.tsx +50 -0
  97. package/templates/scaffold-default/packages/admin/src/components/admin-ui/data-table/index.tsx +266 -0
  98. package/templates/scaffold-default/packages/admin/src/components/admin-ui/editable-table.tsx +292 -0
  99. package/templates/scaffold-default/packages/admin/src/components/admin-ui/form/input-password.tsx +38 -0
  100. package/templates/scaffold-default/packages/admin/src/components/admin-ui/form/sign-in-form.tsx +118 -0
  101. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/error-component.tsx +71 -0
  102. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/header.tsx +162 -0
  103. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/language-switcher.tsx +47 -0
  104. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/layout.tsx +42 -0
  105. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/loading-overlay.tsx +36 -0
  106. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/shell-bar.tsx +232 -0
  107. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/sidebar.tsx +193 -0
  108. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/user-avatar.tsx +31 -0
  109. package/templates/scaffold-default/packages/admin/src/components/admin-ui/list-report.tsx +306 -0
  110. package/templates/scaffold-default/packages/admin/src/components/admin-ui/master-detail.tsx +382 -0
  111. package/templates/scaffold-default/packages/admin/src/components/admin-ui/notification/toaster.tsx +23 -0
  112. package/templates/scaffold-default/packages/admin/src/components/admin-ui/notification/undoable-notification.tsx +84 -0
  113. package/templates/scaffold-default/packages/admin/src/components/admin-ui/object-page.tsx +539 -0
  114. package/templates/scaffold-default/packages/admin/src/components/admin-ui/theme/theme-provider.tsx +160 -0
  115. package/templates/scaffold-default/packages/admin/src/components/admin-ui/theme/theme-select.tsx +129 -0
  116. package/templates/scaffold-default/packages/admin/src/components/admin-ui/theme/theme-toggle.tsx +90 -0
  117. package/templates/scaffold-default/packages/admin/src/components/ui/accordion.tsx +64 -0
  118. package/templates/scaffold-default/packages/admin/src/components/ui/alert-dialog.tsx +157 -0
  119. package/templates/scaffold-default/packages/admin/src/components/ui/alert.tsx +66 -0
  120. package/templates/scaffold-default/packages/admin/src/components/ui/aspect-ratio.tsx +9 -0
  121. package/templates/scaffold-default/packages/admin/src/components/ui/avatar.tsx +53 -0
  122. package/templates/scaffold-default/packages/admin/src/components/ui/badge.tsx +47 -0
  123. package/templates/scaffold-default/packages/admin/src/components/ui/breadcrumb.tsx +111 -0
  124. package/templates/scaffold-default/packages/admin/src/components/ui/button.tsx +59 -0
  125. package/templates/scaffold-default/packages/admin/src/components/ui/calendar.tsx +74 -0
  126. package/templates/scaffold-default/packages/admin/src/components/ui/card.tsx +92 -0
  127. package/templates/scaffold-default/packages/admin/src/components/ui/carousel.tsx +237 -0
  128. package/templates/scaffold-default/packages/admin/src/components/ui/chart.tsx +351 -0
  129. package/templates/scaffold-default/packages/admin/src/components/ui/checkbox.tsx +32 -0
  130. package/templates/scaffold-default/packages/admin/src/components/ui/collapsible.tsx +33 -0
  131. package/templates/scaffold-default/packages/admin/src/components/ui/command.tsx +182 -0
  132. package/templates/scaffold-default/packages/admin/src/components/ui/context-menu.tsx +252 -0
  133. package/templates/scaffold-default/packages/admin/src/components/ui/dialog.tsx +141 -0
  134. package/templates/scaffold-default/packages/admin/src/components/ui/drawer.tsx +130 -0
  135. package/templates/scaffold-default/packages/admin/src/components/ui/dropdown-menu.tsx +255 -0
  136. package/templates/scaffold-default/packages/admin/src/components/ui/form.tsx +166 -0
  137. package/templates/scaffold-default/packages/admin/src/components/ui/hover-card.tsx +42 -0
  138. package/templates/scaffold-default/packages/admin/src/components/ui/input-otp.tsx +77 -0
  139. package/templates/scaffold-default/packages/admin/src/components/ui/input.tsx +21 -0
  140. package/templates/scaffold-default/packages/admin/src/components/ui/label.tsx +22 -0
  141. package/templates/scaffold-default/packages/admin/src/components/ui/menubar.tsx +274 -0
  142. package/templates/scaffold-default/packages/admin/src/components/ui/navigation-menu.tsx +168 -0
  143. package/templates/scaffold-default/packages/admin/src/components/ui/pagination.tsx +127 -0
  144. package/templates/scaffold-default/packages/admin/src/components/ui/popover.tsx +48 -0
  145. package/templates/scaffold-default/packages/admin/src/components/ui/progress.tsx +29 -0
  146. package/templates/scaffold-default/packages/admin/src/components/ui/radio-group.tsx +45 -0
  147. package/templates/scaffold-default/packages/admin/src/components/ui/resizable.tsx +54 -0
  148. package/templates/scaffold-default/packages/admin/src/components/ui/scroll-area.tsx +58 -0
  149. package/templates/scaffold-default/packages/admin/src/components/ui/select.tsx +183 -0
  150. package/templates/scaffold-default/packages/admin/src/components/ui/separator.tsx +26 -0
  151. package/templates/scaffold-default/packages/admin/src/components/ui/sheet.tsx +139 -0
  152. package/templates/scaffold-default/packages/admin/src/components/ui/sidebar.tsx +740 -0
  153. package/templates/scaffold-default/packages/admin/src/components/ui/skeleton.tsx +13 -0
  154. package/templates/scaffold-default/packages/admin/src/components/ui/slider.tsx +63 -0
  155. package/templates/scaffold-default/packages/admin/src/components/ui/sonner.tsx +23 -0
  156. package/templates/scaffold-default/packages/admin/src/components/ui/switch.tsx +31 -0
  157. package/templates/scaffold-default/packages/admin/src/components/ui/table.tsx +114 -0
  158. package/templates/scaffold-default/packages/admin/src/components/ui/tabs.tsx +66 -0
  159. package/templates/scaffold-default/packages/admin/src/components/ui/textarea.tsx +18 -0
  160. package/templates/scaffold-default/packages/admin/src/components/ui/toggle-group.tsx +73 -0
  161. package/templates/scaffold-default/packages/admin/src/components/ui/toggle.tsx +45 -0
  162. package/templates/scaffold-default/packages/admin/src/components/ui/tooltip.tsx +59 -0
  163. package/templates/scaffold-default/packages/admin/src/hooks/use-mobile.ts +21 -0
  164. package/templates/scaffold-default/packages/admin/src/i18n.ts +20 -0
  165. package/templates/scaffold-default/packages/admin/src/index.tsx +19 -0
  166. package/templates/scaffold-default/packages/admin/src/layouts/menu-layout.tsx +211 -0
  167. package/templates/scaffold-default/packages/admin/src/layouts/tile-layout.tsx +355 -0
  168. package/templates/scaffold-default/packages/admin/src/lib/utils.ts +6 -0
  169. package/templates/scaffold-default/packages/admin/src/locales/en.json +68 -0
  170. package/templates/scaffold-default/packages/admin/src/locales/zh.json +68 -0
  171. package/templates/scaffold-default/packages/admin/src/pages/dashboard.tsx +12 -0
  172. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/CreatePage.tsx +302 -0
  173. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/EditPage.tsx +221 -0
  174. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/ListPage.tsx +283 -0
  175. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/ViewPage.tsx +280 -0
  176. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/index.ts +4 -0
  177. package/templates/scaffold-default/packages/admin/src/pages/home-page.tsx +244 -0
  178. package/templates/scaffold-default/packages/admin/src/pages/master-data/cost-centers/index.tsx +461 -0
  179. package/templates/scaffold-default/packages/admin/src/pages/master-data/currencies/index.tsx +255 -0
  180. package/templates/scaffold-default/packages/admin/src/pages/master-data/materials/ListPage.tsx +271 -0
  181. package/templates/scaffold-default/packages/admin/src/pages/master-data/materials/ViewPage.tsx +240 -0
  182. package/templates/scaffold-default/packages/admin/src/pages/master-data/materials/index.ts +2 -0
  183. package/templates/scaffold-default/packages/admin/src/pages/master-data/plants/ListPage.tsx +279 -0
  184. package/templates/scaffold-default/packages/admin/src/pages/master-data/plants/ViewPage.tsx +380 -0
  185. package/templates/scaffold-default/packages/admin/src/pages/master-data/plants/index.ts +2 -0
  186. package/templates/scaffold-default/packages/admin/src/pages/master-data/purchase-organizations/index.tsx +341 -0
  187. package/templates/scaffold-default/packages/admin/src/pages/master-data/units-of-measure/index.tsx +295 -0
  188. package/templates/scaffold-default/packages/admin/src/pages/master-data/vendors/ListPage.tsx +266 -0
  189. package/templates/scaffold-default/packages/admin/src/pages/master-data/vendors/ViewPage.tsx +274 -0
  190. package/templates/scaffold-default/packages/admin/src/pages/master-data/vendors/index.ts +2 -0
  191. package/templates/scaffold-default/packages/admin/src/pages/placeholder-page.tsx +13 -0
  192. package/templates/scaffold-default/packages/admin/src/pages/purchase-orders/ListPage.tsx +289 -0
  193. package/templates/scaffold-default/packages/admin/src/pages/purchase-orders/ViewPage.tsx +343 -0
  194. package/templates/scaffold-default/packages/admin/src/pages/purchase-orders/index.ts +2 -0
  195. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/CreatePage.tsx +398 -0
  196. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/EditPage.tsx +473 -0
  197. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/ListPage.tsx +307 -0
  198. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/ViewPage.tsx +304 -0
  199. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/constants.ts +51 -0
  200. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/index.ts +4 -0
  201. package/templates/scaffold-default/packages/admin/src/pages/reports/PurchaseOrderReport.tsx +312 -0
  202. package/templates/scaffold-default/packages/admin/src/pages/reports/PurchaseRequisitionReport.tsx +303 -0
  203. package/templates/scaffold-default/packages/admin/src/pages/reports/index.ts +2 -0
  204. package/templates/scaffold-default/packages/admin/src/pages/settings-page.tsx +335 -0
  205. package/templates/scaffold-default/packages/admin/src/providers/app-config.tsx +50 -0
  206. package/templates/scaffold-default/packages/admin/src/providers/auth-provider.ts +2 -0
  207. package/templates/scaffold-default/packages/admin/src/routes/auth.ts +9 -0
  208. package/templates/scaffold-default/packages/admin/src/routes/index.ts +85 -0
  209. package/templates/scaffold-default/packages/admin/src/routes/menu.ts +176 -0
  210. package/templates/scaffold-default/packages/admin/src/routes/modules/goods-receipt.ts +31 -0
  211. package/templates/scaffold-default/packages/admin/src/routes/modules/master-data.ts +41 -0
  212. package/templates/scaffold-default/packages/admin/src/routes/modules/purchase-orders.ts +27 -0
  213. package/templates/scaffold-default/packages/admin/src/routes/modules/purchase-requisitions.ts +39 -0
  214. package/templates/scaffold-default/packages/admin/src/routes/modules/reports.ts +33 -0
  215. package/templates/scaffold-default/packages/admin/src/routes/modules/settings.ts +19 -0
  216. package/templates/scaffold-default/packages/admin/src/routes/withSuspense.tsx +21 -0
  217. package/templates/scaffold-default/packages/admin/src/theme/amber.css +27 -0
  218. package/templates/scaffold-default/packages/admin/src/theme/blue.css +27 -0
  219. package/templates/scaffold-default/packages/admin/src/theme/default.css +75 -0
  220. package/templates/scaffold-default/packages/admin/src/theme/fiori.css +180 -0
  221. package/templates/scaffold-default/packages/admin/src/theme/green.css +27 -0
  222. package/templates/scaffold-default/packages/admin/src/theme/index.css +12 -0
  223. package/templates/scaffold-default/packages/admin/src/theme/rose.css +27 -0
  224. package/templates/scaffold-default/packages/admin/src/theme/violet.css +27 -0
  225. package/templates/scaffold-default/packages/admin/src/vite-env.d.ts +1 -0
  226. package/templates/scaffold-default/packages/admin/tsconfig.json +28 -0
  227. package/templates/scaffold-default/packages/admin/tsconfig.node.json +21 -0
  228. package/templates/scaffold-default/packages/admin/vite.config.ts +26 -0
  229. package/templates/scaffold-default/packages/api/.eslintrc.json +6 -0
  230. package/templates/scaffold-default/packages/api/.swcrc +17 -0
  231. package/templates/scaffold-default/packages/api/app.config.ts +163 -0
  232. package/templates/scaffold-default/packages/api/docs/api-document.md +497 -0
  233. package/templates/scaffold-default/packages/api/docs/final-completion-report.md +565 -0
  234. package/templates/scaffold-default/packages/api/docs/permission-integration-summary.md +432 -0
  235. package/templates/scaffold-default/packages/api/examples/security/README.md +664 -0
  236. package/templates/scaffold-default/packages/api/examples/security/complete/.env.example +26 -0
  237. package/templates/scaffold-default/packages/api/examples/security/complete/PROJECT_STRUCTURE.md +220 -0
  238. package/templates/scaffold-default/packages/api/examples/security/complete/README.md +847 -0
  239. package/templates/scaffold-default/packages/api/examples/security/complete/app.config.ts +69 -0
  240. package/templates/scaffold-default/packages/api/examples/security/complete/app.ts +63 -0
  241. package/templates/scaffold-default/packages/api/examples/security/complete/controller/auth.controller.ts +131 -0
  242. package/templates/scaffold-default/packages/api/examples/security/complete/controller/index.ts +4 -0
  243. package/templates/scaffold-default/packages/api/examples/security/complete/controller/permission.controller.ts +41 -0
  244. package/templates/scaffold-default/packages/api/examples/security/complete/controller/role.controller.ts +53 -0
  245. package/templates/scaffold-default/packages/api/examples/security/complete/controller/user.controller.ts +53 -0
  246. package/templates/scaffold-default/packages/api/examples/security/complete/dto/change-password.dto.ts +10 -0
  247. package/templates/scaffold-default/packages/api/examples/security/complete/dto/create-permission.dto.ts +14 -0
  248. package/templates/scaffold-default/packages/api/examples/security/complete/dto/create-role.dto.ts +11 -0
  249. package/templates/scaffold-default/packages/api/examples/security/complete/dto/create-user.dto.ts +15 -0
  250. package/templates/scaffold-default/packages/api/examples/security/complete/dto/index.ts +7 -0
  251. package/templates/scaffold-default/packages/api/examples/security/complete/dto/login.dto.ts +10 -0
  252. package/templates/scaffold-default/packages/api/examples/security/complete/dto/oauth-profile.dto.ts +7 -0
  253. package/templates/scaffold-default/packages/api/examples/security/complete/dto/register.dto.ts +17 -0
  254. package/templates/scaffold-default/packages/api/examples/security/complete/entity/index.ts +6 -0
  255. package/templates/scaffold-default/packages/api/examples/security/complete/entity/oauth-account.entity.ts +39 -0
  256. package/templates/scaffold-default/packages/api/examples/security/complete/entity/permission.entity.ts +31 -0
  257. package/templates/scaffold-default/packages/api/examples/security/complete/entity/role-permission.entity.ts +19 -0
  258. package/templates/scaffold-default/packages/api/examples/security/complete/entity/role.entity.ts +25 -0
  259. package/templates/scaffold-default/packages/api/examples/security/complete/entity/user-role.entity.ts +19 -0
  260. package/templates/scaffold-default/packages/api/examples/security/complete/entity/user.entity.ts +46 -0
  261. package/templates/scaffold-default/packages/api/examples/security/complete/init.sql +81 -0
  262. package/templates/scaffold-default/packages/api/examples/security/complete/middleware/auth.interceptor.ts +39 -0
  263. package/templates/scaffold-default/packages/api/examples/security/complete/middleware/index.ts +2 -0
  264. package/templates/scaffold-default/packages/api/examples/security/complete/middleware/permission.interceptor.ts +61 -0
  265. package/templates/scaffold-default/packages/api/examples/security/complete/package.json +54 -0
  266. package/templates/scaffold-default/packages/api/examples/security/complete/seed.sql +42 -0
  267. package/templates/scaffold-default/packages/api/examples/security/complete/service/auth.service.ts +41 -0
  268. package/templates/scaffold-default/packages/api/examples/security/complete/service/index.ts +5 -0
  269. package/templates/scaffold-default/packages/api/examples/security/complete/service/oauth.service.ts +82 -0
  270. package/templates/scaffold-default/packages/api/examples/security/complete/service/permission.service.ts +113 -0
  271. package/templates/scaffold-default/packages/api/examples/security/complete/service/role.service.ts +85 -0
  272. package/templates/scaffold-default/packages/api/examples/security/complete/service/user.service.ts +132 -0
  273. package/templates/scaffold-default/packages/api/examples/security/complete/tests/TEST_REPORT.md +318 -0
  274. package/templates/scaffold-default/packages/api/examples/security/complete/tests/generate-report.js +335 -0
  275. package/templates/scaffold-default/packages/api/examples/security/complete/tests/helpers/api-helpers.ts +116 -0
  276. package/templates/scaffold-default/packages/api/examples/security/complete/tests/helpers/index.ts +2 -0
  277. package/templates/scaffold-default/packages/api/examples/security/complete/tests/helpers/test-helpers.ts +129 -0
  278. package/templates/scaffold-default/packages/api/examples/security/complete/tests/integration/auth.api.test.ts +429 -0
  279. package/templates/scaffold-default/packages/api/examples/security/complete/tests/integration/role.api.test.ts +400 -0
  280. package/templates/scaffold-default/packages/api/examples/security/complete/tests/integration/user.api.test.ts +459 -0
  281. package/templates/scaffold-default/packages/api/examples/security/complete/tests/jest.config.js +40 -0
  282. package/templates/scaffold-default/packages/api/examples/security/complete/tests/run-all-tests.js +135 -0
  283. package/templates/scaffold-default/packages/api/examples/security/complete/tests/run-tests.js +109 -0
  284. package/templates/scaffold-default/packages/api/examples/security/complete/tests/setup.ts +19 -0
  285. package/templates/scaffold-default/packages/api/examples/security/complete/tests/unit/auth.service.test.ts +199 -0
  286. package/templates/scaffold-default/packages/api/examples/security/complete/tests/unit/permission.service.test.ts +377 -0
  287. package/templates/scaffold-default/packages/api/examples/security/complete/tests/unit/user.service.test.ts +288 -0
  288. package/templates/scaffold-default/packages/api/examples/security/complete/tsconfig.json +35 -0
  289. package/templates/scaffold-default/packages/api/examples/security/jwt/README.md +424 -0
  290. package/templates/scaffold-default/packages/api/examples/security/local/README.md +499 -0
  291. package/templates/scaffold-default/packages/api/examples/security/oauth2/README.md +637 -0
  292. package/templates/scaffold-default/packages/api/examples/security/permission/README.md +943 -0
  293. package/templates/scaffold-default/packages/api/examples/security/session/README.md +753 -0
  294. package/templates/scaffold-default/packages/api/package.json +63 -0
  295. package/templates/scaffold-default/packages/api/scripts/codegen.cjs +29 -0
  296. package/templates/scaffold-default/packages/api/scripts/codegen.ts +9 -0
  297. package/templates/scaffold-default/packages/api/src/config/security-auto-configuration.ts +75 -0
  298. package/templates/scaffold-default/packages/api/src/controller/auth.controller.ts +109 -0
  299. package/templates/scaffold-default/packages/api/src/controller/cache.controller.ts +106 -0
  300. package/templates/scaffold-default/packages/api/src/controller/menu.controller.ts +86 -0
  301. package/templates/scaffold-default/packages/api/src/controller/mq.controller.ts +35 -0
  302. package/templates/scaffold-default/packages/api/src/controller/role.controller.ts +100 -0
  303. package/templates/scaffold-default/packages/api/src/controller/upload.controller.ts +83 -0
  304. package/templates/scaffold-default/packages/api/src/controller/user.controller.ts +102 -0
  305. package/templates/scaffold-default/packages/api/src/dto/auth.dto.ts +30 -0
  306. package/templates/scaffold-default/packages/api/src/dto/cache.dto.ts +24 -0
  307. package/templates/scaffold-default/packages/api/src/dto/menu.dto.ts +37 -0
  308. package/templates/scaffold-default/packages/api/src/dto/mq.dto.ts +16 -0
  309. package/templates/scaffold-default/packages/api/src/dto/role.dto.ts +16 -0
  310. package/templates/scaffold-default/packages/api/src/dto/user.dto.ts +35 -0
  311. package/templates/scaffold-default/packages/api/src/entity/menu.entity.ts +34 -0
  312. package/templates/scaffold-default/packages/api/src/entity/role-menu.entity.ts +13 -0
  313. package/templates/scaffold-default/packages/api/src/entity/role.entity.ts +22 -0
  314. package/templates/scaffold-default/packages/api/src/entity/user-role.entity.ts +13 -0
  315. package/templates/scaffold-default/packages/api/src/entity/user.entity.ts +31 -0
  316. package/templates/scaffold-default/packages/api/src/mapper/menu.mapper.ts +6 -0
  317. package/templates/scaffold-default/packages/api/src/mapper/role-menu.mapper.ts +6 -0
  318. package/templates/scaffold-default/packages/api/src/mapper/role.mapper.ts +6 -0
  319. package/templates/scaffold-default/packages/api/src/mapper/user-role.mapper.ts +6 -0
  320. package/templates/scaffold-default/packages/api/src/mapper/user.mapper.ts +11 -0
  321. package/templates/scaffold-default/packages/api/src/scripts/assign-role.ts +41 -0
  322. package/templates/scaffold-default/packages/api/src/scripts/check-user-role.ts +28 -0
  323. package/templates/scaffold-default/packages/api/src/scripts/check-users.mjs +44 -0
  324. package/templates/scaffold-default/packages/api/src/scripts/demo-permissions.mjs +418 -0
  325. package/templates/scaffold-default/packages/api/src/scripts/init-db.ts +166 -0
  326. package/templates/scaffold-default/packages/api/src/scripts/reset-admin-password.mjs +70 -0
  327. package/templates/scaffold-default/packages/api/src/scripts/reset-password.ts +31 -0
  328. package/templates/scaffold-default/packages/api/src/scripts/simple-reset-admin.mjs +39 -0
  329. package/templates/scaffold-default/packages/api/src/scripts/test-db.ts +36 -0
  330. package/templates/scaffold-default/packages/api/src/scripts/test-di.ts +45 -0
  331. package/templates/scaffold-default/packages/api/src/scripts/test-permissions.mjs +551 -0
  332. package/templates/scaffold-default/packages/api/src/scripts/update-admin-password.mjs +56 -0
  333. package/templates/scaffold-default/packages/api/src/scripts/user-roles.ts +28 -0
  334. package/templates/scaffold-default/packages/api/src/server.ts +38 -0
  335. package/templates/scaffold-default/packages/api/src/service/auth.service.ts +165 -0
  336. package/templates/scaffold-default/packages/api/src/service/cache.service.ts +80 -0
  337. package/templates/scaffold-default/packages/api/src/service/log.request.service.ts +158 -0
  338. package/templates/scaffold-default/packages/api/src/service/log.service.ts +123 -0
  339. package/templates/scaffold-default/packages/api/src/service/menu.service.ts +94 -0
  340. package/templates/scaffold-default/packages/api/src/service/mq.consumer.service.ts +26 -0
  341. package/templates/scaffold-default/packages/api/src/service/role.service.ts +88 -0
  342. package/templates/scaffold-default/packages/api/src/service/user.service.ts +195 -0
  343. package/templates/scaffold-default/packages/api/src/types/sqljs.d.ts +18 -0
  344. package/templates/scaffold-default/packages/api/src/utils/auth.utils.js +0 -0
  345. package/templates/scaffold-default/packages/api/src/utils/jwt.util.ts +29 -0
  346. package/templates/scaffold-default/packages/api/tsconfig.json +17 -0
  347. package/templates/scaffold-default/packages/api/tsup.config.ts +14 -0
  348. package/templates/scaffold-default/packages/api/uploads/.gitkeep +0 -0
  349. package/templates/scaffold-default/packages/core/package.json +28 -0
  350. package/templates/scaffold-default/packages/core/src/auth/auth-client-middleware.ts +22 -0
  351. package/templates/scaffold-default/packages/core/src/auth/auth-constants.ts +6 -0
  352. package/templates/scaffold-default/packages/core/src/auth/auth-service.ts +65 -0
  353. package/templates/scaffold-default/packages/core/src/auth/backend-auth-provider.ts +149 -0
  354. package/templates/scaffold-default/packages/core/src/auth/default-auth-provider.ts +38 -0
  355. package/templates/scaffold-default/packages/core/src/auth/index.ts +12 -0
  356. package/templates/scaffold-default/packages/core/src/auth/types.ts +38 -0
  357. package/templates/scaffold-default/packages/core/src/authorization/authorization-client-middleware.ts +38 -0
  358. package/templates/scaffold-default/packages/core/src/authorization/authorization-config.ts +13 -0
  359. package/templates/scaffold-default/packages/core/src/authorization/authorization-provider.tsx +116 -0
  360. package/templates/scaffold-default/packages/core/src/authorization/default-authorization-provider.ts +26 -0
  361. package/templates/scaffold-default/packages/core/src/authorization/index.ts +15 -0
  362. package/templates/scaffold-default/packages/core/src/authorization/types.ts +42 -0
  363. package/templates/scaffold-default/packages/core/src/index.ts +3 -0
  364. package/templates/scaffold-default/packages/core/src/utils/promise-result-cache.ts +18 -0
  365. package/templates/scaffold-default/packages/core/tsconfig.json +19 -0
  366. package/templates/scaffold-default/packages/mobile/README.md +56 -0
  367. package/templates/scaffold-default/packages/mobile/index.html +13 -0
  368. package/templates/scaffold-default/packages/mobile/package.json +28 -0
  369. package/templates/scaffold-default/packages/mobile/postcss.config.mjs +7 -0
  370. package/templates/scaffold-default/packages/mobile/src/App.tsx +5 -0
  371. package/templates/scaffold-default/packages/mobile/src/app/globals.css +1 -0
  372. package/templates/scaffold-default/packages/mobile/src/components/LoginForm.tsx +83 -0
  373. package/templates/scaffold-default/packages/mobile/src/hooks/index.ts +5 -0
  374. package/templates/scaffold-default/packages/mobile/src/lib/utils.ts +7 -0
  375. package/templates/scaffold-default/packages/mobile/src/main.tsx +19 -0
  376. package/templates/scaffold-default/packages/mobile/src/pages/HomePage.tsx +41 -0
  377. package/templates/scaffold-default/packages/mobile/src/pages/LoginPage.tsx +24 -0
  378. package/templates/scaffold-default/packages/mobile/src/pages/index.ts +2 -0
  379. package/templates/scaffold-default/packages/mobile/src/routes/ProtectedRoute.tsx +35 -0
  380. package/templates/scaffold-default/packages/mobile/src/routes/index.tsx +24 -0
  381. package/templates/scaffold-default/packages/mobile/src/routes/routes.ts +11 -0
  382. package/templates/scaffold-default/packages/mobile/src/types/index.ts +5 -0
  383. package/templates/scaffold-default/packages/mobile/src/vite-env.d.ts +1 -0
  384. package/templates/scaffold-default/packages/mobile/tsconfig.json +23 -0
  385. package/templates/scaffold-default/packages/mobile/tsconfig.node.json +11 -0
  386. package/templates/scaffold-default/packages/mobile/vite.config.ts +20 -0
  387. package/templates/scaffold-default/pnpm-workspace.yaml +2 -0
  388. package/templates/scaffold-default/scripts/postinstall.cjs +42 -0
  389. package/templates/scaffold-default/scripts/rebuild-sqlite.cjs +23 -0
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 更新数据库admin密码为admin123
5
+ */
6
+
7
+ import bcrypt from 'bcryptjs';
8
+ import fs from 'fs';
9
+ import { fileURLToPath } from 'url';
10
+ import { dirname, join } from 'path';
11
+
12
+ async function updateAdminPassword() {
13
+ try {
14
+ console.log('🔐 Starting admin password update process...');
15
+
16
+ // 生成admin123的密码哈希
17
+ const hashedPassword = await bcrypt.hash('admin123', 10);
18
+ console.log('🔐 Generated hash for admin123:', hashedPassword.substring(0, 20) + '...');
19
+
20
+ // 检查数据库文件
21
+ const dbPath = join(dirname(fileURLToPath(import.meta.url)), '../../data/app.db');
22
+ if (!fs.existsSync(dbPath)) {
23
+ throw new Error('Database file not found: ' + dbPath);
24
+ }
25
+ console.log('📁 Database file found:', dbPath);
26
+
27
+ // 重新初始化数据库
28
+ console.log('🔄 Re-initializing database with new password...');
29
+ const { execSync } = await import('child_process');
30
+
31
+ const result = execSync('node --import @swc-node/register/esm-register src/scripts/init-db.ts', {
32
+ cwd: process.cwd(),
33
+ stdio: 'inherit',
34
+ timeout: 30000
35
+ });
36
+
37
+ if (result.status === 0) {
38
+ console.log('✅ Database re-initialization completed successfully!');
39
+ console.log('');
40
+ console.log('🎉 Admin password has been updated to admin123!');
41
+ console.log('🎉 You can now login with: admin / admin123');
42
+ console.log('');
43
+ console.log('🔐 Please restart the server for changes to take effect.');
44
+ } else {
45
+ console.error('❌ Database initialization failed with code:', result.status);
46
+ console.error('Error output:', result.stderr);
47
+ process.exit(1);
48
+ }
49
+
50
+ } catch (error) {
51
+ console.error('❌ Error updating admin password:', error);
52
+ process.exit(1);
53
+ }
54
+ }
55
+
56
+ updateAdminPassword();
@@ -0,0 +1,28 @@
1
+ import 'reflect-metadata';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+ import { createKyselyDatabase, getKyselyDatabase } from '@ai-partner-x/aiko-boot-starter-orm';
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ const dbPath = join(__dirname, '../../data/app.db');
8
+
9
+ await createKyselyDatabase({
10
+ type: 'sqlite',
11
+ filename: dbPath,
12
+ });
13
+
14
+ const db = getKyselyDatabase();
15
+
16
+ const users = await db.selectFrom('sys_user').selectAll().execute();
17
+ console.log('用户:');
18
+ console.log(JSON.stringify(users, null, 2));
19
+
20
+ const roles = await db.selectFrom('sys_role').selectAll().execute();
21
+ console.log('\n角色:');
22
+ console.log(JSON.stringify(roles, null, 2));
23
+
24
+ const userRoles = await db.selectFrom('sys_user_role').selectAll().execute();
25
+ console.log('\n用户角色关联:');
26
+ console.log(JSON.stringify(userRoles, null, 2));
27
+
28
+ process.exit(0);
@@ -0,0 +1,38 @@
1
+ import 'reflect-metadata';
2
+ import express from 'express';
3
+ import { createApp } from '@ai-partner-x/aiko-boot';
4
+ import { autoInit, getLogger } from '@ai-partner-x/aiko-boot-starter-log';
5
+
6
+ autoInit();
7
+ const logger = getLogger('server');
8
+
9
+ logger.info('Starting API server...');
10
+
11
+ import { join } from 'path';
12
+
13
+ const projectDir = process.cwd();
14
+ const srcDir = join(projectDir, 'src'); // Framework scans for controller/service/mapper relative to srcDir
15
+ const configPath = projectDir; // configPath should point to the directory with node_modules
16
+ const context = await createApp({ srcDir, configPath, verbose: true });
17
+
18
+ if (!context) {
19
+ logger.warn('ApplicationContext not available');
20
+ } else {
21
+ logger.info('Security enabled: ' + context.config.get('security.enabled', true));
22
+ }
23
+
24
+ const expressApp = await import('@ai-partner-x/aiko-boot-starter-web').then(m => m.getExpressApp());
25
+
26
+ if (!expressApp) {
27
+ logger.error('Express app not available');
28
+ process.exit(1);
29
+ }
30
+
31
+ expressApp.use(express.json());
32
+
33
+ const port = context.config.get('server.port', 3001);
34
+
35
+ expressApp.listen(port, () => {
36
+ logger.info('API Server started on port ' + port);
37
+ console.log('📡 API: http://localhost:' + port + '/api');
38
+ });
@@ -0,0 +1,165 @@
1
+ import 'reflect-metadata';
2
+ import { Service, Autowired } from '@ai-partner-x/aiko-boot';
3
+ import bcrypt from 'bcryptjs';
4
+ import jwt from 'jsonwebtoken'; // 只用于refresh token,access token使用安全组件
5
+ import { JwtStrategy } from '@ai-partner-x/aiko-boot-starter-security';
6
+ import { UserMapper } from '../mapper/user.mapper.js';
7
+ import { UserRoleMapper } from '../mapper/user-role.mapper.js';
8
+ import { RoleMapper } from '../mapper/role.mapper.js';
9
+ import { RoleMenuMapper } from '../mapper/role-menu.mapper.js';
10
+ import { MenuMapper } from '../mapper/menu.mapper.js';
11
+ import type { User } from '@ai-partner-x/aiko-boot-starter-security';
12
+
13
+ import type { LoginDto, LoginResultDto } from '../dto/auth.dto.js';
14
+
15
+ @Service()
16
+ export class AuthService {
17
+ @Autowired(UserMapper)
18
+ private userMapper!: UserMapper;
19
+
20
+ @Autowired(UserRoleMapper)
21
+ private userRoleMapper!: UserRoleMapper;
22
+
23
+ @Autowired(RoleMapper)
24
+ private roleMapper!: RoleMapper;
25
+
26
+ @Autowired(RoleMenuMapper)
27
+ private roleMenuMapper!: RoleMenuMapper;
28
+
29
+ @Autowired(MenuMapper)
30
+ private menuMapper!: MenuMapper;
31
+
32
+ @Autowired(JwtStrategy)
33
+ private jwtStrategy!: JwtStrategy;
34
+
35
+ async login(dto: LoginDto): Promise<LoginResultDto> {
36
+ const user = await this.userMapper.selectByUsername(dto.username);
37
+ if (!user) {
38
+ throw new Error('用户名或密码错误');
39
+ }
40
+ if (user.status === 0) throw new Error('账户已被禁用');
41
+
42
+ const valid = await bcrypt.compare(dto.password, user.passwordHash);
43
+ if (!valid) throw new Error('用户名或密码错误');
44
+
45
+ const userRolesAndPerms = await this.getUserRolesAndPermissions(user.id);
46
+ const roles = userRolesAndPerms.roles;
47
+ const permissions = userRolesAndPerms.permissions;
48
+
49
+ // 使用框架的User类型,包含roles和permissions字段
50
+ const frameworkUser = {
51
+ id: user.id,
52
+ username: user.username,
53
+ email: user.email,
54
+ roles: roles.map(function(r) { return { id: 0, name: r }; }), // 转换为框架格式
55
+ permissions: permissions, // 使用字符串数组格式
56
+ };
57
+
58
+ // 生成JWT token - 使用安全组件的JwtStrategy
59
+ const accessToken = await this.jwtStrategy.generateToken(frameworkUser as User);
60
+ const refreshToken = this.generateRefreshToken(user.id);
61
+
62
+ return {
63
+ accessToken: accessToken,
64
+ refreshToken: refreshToken,
65
+ userInfo: { id: user.id, username: user.username, realName: user.realName, email: user.email, roles, permissions },
66
+ };
67
+ }
68
+
69
+ async refreshToken(refreshToken: string): Promise<{ accessToken: string }> {
70
+ const payload = this.verifyRefreshToken(refreshToken);
71
+ const user = await this.userMapper.selectById(payload.userId);
72
+ if (!user || user.status === 0) throw new Error('用户不存在或已禁用');
73
+
74
+ const userRolesAndPerms = await this.getUserRolesAndPermissions(user.id);
75
+ const roles = userRolesAndPerms.roles;
76
+ const permissions = userRolesAndPerms.permissions;
77
+
78
+ const frameworkUser = {
79
+ id: user.id,
80
+ username: user.username,
81
+ email: user.email,
82
+ roles: roles.map(function(r) { return { id: 0, name: r }; }),
83
+ permissions: permissions,
84
+ };
85
+
86
+ const accessToken = await this.jwtStrategy.generateToken(frameworkUser as User);
87
+ return { accessToken };
88
+ }
89
+
90
+ async getUserInfo(userId: number): Promise<LoginResultDto['userInfo']> {
91
+ const user = await this.userMapper.selectById(userId);
92
+ if (!user) throw new Error('用户不存在');
93
+ const userRolesAndPerms = await this.getUserRolesAndPermissions(userId);
94
+ const roles = userRolesAndPerms.roles;
95
+ const permissions = userRolesAndPerms.permissions;
96
+ const safeUser: any = {};
97
+ for (const key in user) {
98
+ if (key !== 'password') {
99
+ safeUser[key] = user[key];
100
+ }
101
+ }
102
+ return { ...safeUser, roles, permissions };
103
+ }
104
+
105
+ async getCurrentUserByToken(accessToken: string): Promise<LoginResultDto['userInfo']> {
106
+ try {
107
+ // 使用安全组件的JwtStrategy验证token
108
+ const user = await this.jwtStrategy.validate(accessToken);
109
+ if (!user) {
110
+ throw new Error('Invalid token');
111
+ }
112
+ return this.getUserInfo(user.id);
113
+ } catch (error: any) {
114
+ if (error.name === 'TokenExpiredError') {
115
+ throw new Error('Token has expired');
116
+ } else if (error.name === 'JsonWebTokenError') {
117
+ throw new Error('Invalid token: ' + error.message);
118
+ } else if (error.name === 'NotBeforeError') {
119
+ throw new Error('Token not active yet');
120
+ }
121
+ throw error;
122
+ }
123
+ }
124
+
125
+ private async getUserRolesAndPermissions(userId: number) {
126
+ const userRoles = await this.userRoleMapper.selectList({ userId });
127
+ if (!userRoles.length) return { roles: [] as string[], permissions: [] as string[] };
128
+
129
+ const roleIds: number[] = [];
130
+ for (let i = 0; i < userRoles.length; i++) {
131
+ roleIds.push(userRoles[i].roleId);
132
+ }
133
+ const roles: string[] = [];
134
+ const permissions: string[] = [];
135
+
136
+ for (let i = 0; i < roleIds.length; i++) {
137
+ const roleId = roleIds[i];
138
+ const role = await this.roleMapper.selectById(roleId);
139
+ if (role && role.status === 1) {
140
+ roles.push(role.roleCode);
141
+ const roleMenus = await this.roleMenuMapper.selectList({ roleId });
142
+ for (let j = 0; j < roleMenus.length; j++) {
143
+ const rm = roleMenus[j];
144
+ const menu = await this.menuMapper.selectById(rm.menuId);
145
+ if (menu && menu.permission) permissions.push(menu.permission);
146
+ }
147
+ }
148
+ }
149
+ return { roles: [...new Set(roles)], permissions: [...new Set(permissions)] };
150
+ }
151
+
152
+ // Refresh token 方法(使用独立的secret,与安全组件的JWT分离)
153
+ private generateRefreshToken(userId: number): string {
154
+ const secret = process.env.JWT_REFRESH_SECRET || 'ai-first-refresh-secret-change-in-production';
155
+ const expiresIn = '7d';
156
+
157
+ return jwt.sign({ userId }, secret, { expiresIn } as any);
158
+ }
159
+
160
+ private verifyRefreshToken(token: string): any {
161
+ const secret = process.env.JWT_REFRESH_SECRET || 'ai-first-refresh-secret-change-in-production';
162
+ return jwt.verify(token, secret);
163
+ }
164
+ }
165
+
@@ -0,0 +1,80 @@
1
+ import 'reflect-metadata';
2
+ import { Service } from '@ai-partner-x/aiko-boot';
3
+ import type { CacheManager } from '@ai-partner-x/aiko-boot-starter-cache';
4
+ import { getCacheManager, isCacheManagerInitialized } from '@ai-partner-x/aiko-boot-starter-cache';
5
+ import type { CacheGetDto, CachePutDto, CacheEvictDto, CacheClearDto } from '../dto/cache.dto.js';
6
+
7
+ @Service()
8
+ export class CacheService {
9
+ private getCacheManagerInstance(): CacheManager {
10
+ if (!isCacheManagerInitialized()) {
11
+ throw new Error('Cache is not initialized. Enable cache in app.config.ts and ensure Redis is running.');
12
+ }
13
+ return getCacheManager();
14
+ }
15
+
16
+ /**
17
+ * 获取缓存值
18
+ * @param name 缓存命名空间
19
+ * @param key 缓存键
20
+ * @returns 缓存值(JSON 字符串),未命中返回 null
21
+ */
22
+ async get(dto: CacheGetDto): Promise<string | null> {
23
+ const cache = this.getCacheManagerInstance().getCache(dto.name);
24
+ const value = await cache.get(dto.key);
25
+ return value;
26
+ }
27
+
28
+ /**
29
+ * 设置缓存值
30
+ * @param name 缓存命名空间
31
+ * @param key 缓存键
32
+ * @param value 缓存值(任意类型,会自动序列化为 JSON 字符串存储)
33
+ * @param ttlSeconds 可选过期时间(秒)
34
+ */
35
+ async put(dto: CachePutDto): Promise<void> {
36
+ if (dto.value === undefined) {
37
+ throw new Error('Cache value is required and must be JSON-serializable.');
38
+ }
39
+
40
+ let value: string;
41
+ try {
42
+ value = JSON.stringify(dto.value);
43
+ } catch (err) {
44
+ throw new Error('Cache value is not JSON-serializable.');
45
+ }
46
+ const cache = this.getCacheManagerInstance().getCache(dto.name);
47
+ await cache.put(dto.key, value, dto.ttlSeconds);
48
+ }
49
+
50
+ /**
51
+ * 删除缓存条目
52
+ * @param name 缓存命名空间
53
+ * @param key 缓存键
54
+ * @param allEntries 是否清除所有条目
55
+ */
56
+ async evict(dto: CacheEvictDto): Promise<void> {
57
+ const cache = this.getCacheManagerInstance().getCache(dto.name);
58
+ if (dto.allEntries) {
59
+ await cache.clear();
60
+ } else {
61
+ await cache.evict(dto.key);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 清空缓存命名空间
67
+ * @param name 缓存命名空间
68
+ */
69
+ async clear(dto: CacheClearDto): Promise<void> {
70
+ const cache = this.getCacheManagerInstance().getCache(dto.name);
71
+ await cache.clear();
72
+ }
73
+
74
+ /**
75
+ * 检查缓存是否已初始化
76
+ */
77
+ isInitialized(): boolean {
78
+ return isCacheManagerInitialized();
79
+ }
80
+ }
@@ -0,0 +1,158 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { getLogger } from '@ai-partner-x/aiko-boot-starter-log';
3
+
4
+ const logger = getLogger('http');
5
+
6
+ /**
7
+ * HTTP请求日志服务
8
+ * 提供HTTP请求日志记录功能
9
+ */
10
+ export class RequestLogService {
11
+ /**
12
+ * 完整的HTTP请求日志中间件
13
+ * 记录所有HTTP请求的详细信息
14
+ */
15
+ static requestLogMiddleware(req: Request, res: Response, next: NextFunction) {
16
+ const startTime = Date.now();
17
+
18
+ // 获取请求信息
19
+ const requestInfo = {
20
+ method: req.method,
21
+ url: req.url,
22
+ path: req.path,
23
+ query: req.query,
24
+ ip: req.ip || req.connection.remoteAddress,
25
+ userAgent: req.get('user-agent') || 'unknown',
26
+ contentType: req.get('content-type'),
27
+ contentLength: req.get('content-length'),
28
+ referer: req.get('referer'),
29
+ };
30
+
31
+ // 记录请求开始
32
+ logger.http('Request started', requestInfo);
33
+
34
+ // 监听响应完成事件
35
+ res.on('finish', () => {
36
+ const duration = Date.now() - startTime;
37
+
38
+ const responseInfo = {
39
+ ...requestInfo,
40
+ status: res.statusCode,
41
+ statusMessage: res.statusMessage,
42
+ duration: `${duration}ms`,
43
+ responseTime: duration,
44
+ timestamp: new Date().toISOString(),
45
+ };
46
+
47
+ // 根据状态码选择日志级别
48
+ if (res.statusCode >= 500) {
49
+ logger.error('Request completed with server error', responseInfo);
50
+ } else if (res.statusCode >= 400) {
51
+ logger.warn('Request completed with client error', responseInfo);
52
+ } else {
53
+ logger.http('Request completed successfully', responseInfo);
54
+ }
55
+ });
56
+
57
+ // 监听响应关闭事件(客户端提前断开连接)
58
+ res.on('close', () => {
59
+ if (!res.writableFinished) {
60
+ const duration = Date.now() - startTime;
61
+ logger.warn('Request closed by client before completion', {
62
+ ...requestInfo,
63
+ duration: `${duration}ms`,
64
+ timestamp: new Date().toISOString(),
65
+ });
66
+ }
67
+ });
68
+
69
+ next();
70
+ }
71
+
72
+ /**
73
+ * 简化的请求日志中间件(仅记录基本信息)
74
+ */
75
+ static simpleRequestLogMiddleware(req: Request, res: Response, next: NextFunction) {
76
+ const startTime = Date.now();
77
+
78
+ res.on('finish', () => {
79
+ const duration = Date.now() - startTime;
80
+
81
+ logger.info(`${req.method} ${req.url} ${res.statusCode} ${duration}ms`, {
82
+ method: req.method,
83
+ url: req.url,
84
+ status: res.statusCode,
85
+ duration: `${duration}ms`,
86
+ ip: req.ip,
87
+ });
88
+ });
89
+
90
+ next();
91
+ }
92
+
93
+ /**
94
+ * 错误请求日志中间件(专门记录错误请求)
95
+ */
96
+ static errorRequestLogMiddleware(req: Request, res: Response, next: NextFunction) {
97
+ const startTime = Date.now();
98
+
99
+ res.on('finish', () => {
100
+ if (res.statusCode >= 400) {
101
+ const duration = Date.now() - startTime;
102
+
103
+ logger.warn('Error request detected', {
104
+ method: req.method,
105
+ url: req.url,
106
+ status: res.statusCode,
107
+ duration: `${duration}ms`,
108
+ ip: req.ip,
109
+ userAgent: req.get('user-agent'),
110
+ timestamp: new Date().toISOString(),
111
+ });
112
+ }
113
+ });
114
+
115
+ next();
116
+ }
117
+
118
+ /**
119
+ * 记录HTTP请求信息(直接调用,非中间件)
120
+ */
121
+ static logRequest(req: Request, res: Response, duration: number) {
122
+ const requestInfo = {
123
+ method: req.method,
124
+ url: req.url,
125
+ path: req.path,
126
+ query: req.query,
127
+ ip: req.ip || req.connection.remoteAddress,
128
+ userAgent: req.get('user-agent') || 'unknown',
129
+ status: res.statusCode,
130
+ statusMessage: res.statusMessage,
131
+ duration: `${duration}ms`,
132
+ responseTime: duration,
133
+ timestamp: new Date().toISOString(),
134
+ };
135
+
136
+ if (res.statusCode >= 500) {
137
+ logger.error('Request completed with server error', requestInfo);
138
+ } else if (res.statusCode >= 400) {
139
+ logger.warn('Request completed with client error', requestInfo);
140
+ } else {
141
+ logger.http('Request completed successfully', requestInfo);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * 记录客户端提前断开连接
147
+ */
148
+ static logClientDisconnect(req: Request, duration: number) {
149
+ logger.warn('Request closed by client before completion', {
150
+ method: req.method,
151
+ url: req.url,
152
+ path: req.path,
153
+ ip: req.ip || req.connection.remoteAddress,
154
+ duration: `${duration}ms`,
155
+ timestamp: new Date().toISOString(),
156
+ });
157
+ }
158
+ }
@@ -0,0 +1,123 @@
1
+ import { getLogger, defaultLogger, ILogger } from '@ai-partner-x/aiko-boot-starter-log';
2
+
3
+ /**
4
+ * 日志服务适配器
5
+ * 提供统一的日志接口,封装 aiko-boot-starter-log 的功能
6
+ */
7
+ export class LogService {
8
+ private static instance: LogService;
9
+ private logger: ILogger;
10
+
11
+ private constructor() {
12
+ // 使用命名logger,便于区分不同模块
13
+ this.logger = getLogger('scaffold-api');
14
+ }
15
+
16
+ /**
17
+ * 获取日志服务单例
18
+ */
19
+ static getInstance(): LogService {
20
+ if (!LogService.instance) {
21
+ LogService.instance = new LogService();
22
+ }
23
+ return LogService.instance;
24
+ }
25
+
26
+ /**
27
+ * 记录错误日志
28
+ * @param message 错误消息
29
+ * @param error 错误对象(可选)
30
+ * @param meta 附加元数据(可选)
31
+ */
32
+ error(message: string, error?: Error, meta?: Record<string, any>) {
33
+ this.logger.error(message, error, meta);
34
+ }
35
+
36
+ /**
37
+ * 记录警告日志
38
+ * @param message 警告消息
39
+ * @param meta 附加元数据(可选)
40
+ */
41
+ warn(message: string, meta?: Record<string, any>) {
42
+ this.logger.warn(message, meta);
43
+ }
44
+
45
+ /**
46
+ * 记录信息日志
47
+ * @param message 信息消息
48
+ * @param meta 附加元数据(可选)
49
+ */
50
+ info(message: string, meta?: Record<string, any>) {
51
+ this.logger.info(message, meta);
52
+ }
53
+
54
+ /**
55
+ * 记录调试日志
56
+ * @param message 调试消息
57
+ * @param meta 附加元数据(可选)
58
+ */
59
+ debug(message: string, meta?: Record<string, any>) {
60
+ this.logger.debug(message, meta);
61
+ }
62
+
63
+ /**
64
+ * 记录HTTP请求日志
65
+ * @param message HTTP消息
66
+ * @param meta 附加元数据(可选)
67
+ */
68
+ http(message: string, meta?: Record<string, any>) {
69
+ this.logger.http(message, meta);
70
+ }
71
+
72
+ /**
73
+ * 记录详细日志
74
+ * @param message 详细消息
75
+ * @param meta 附加元数据(可选)
76
+ */
77
+ verbose(message: string, meta?: Record<string, any>) {
78
+ this.logger.verbose(message, meta);
79
+ }
80
+
81
+ /**
82
+ * 记录最详细日志
83
+ * @param message 最详细消息
84
+ * @param meta 附加元数据(可选)
85
+ */
86
+ silly(message: string, meta?: Record<string, any>) {
87
+ this.logger.silly(message, meta);
88
+ }
89
+
90
+ /**
91
+ * 检查是否启用指定级别的日志
92
+ * @param level 日志级别
93
+ */
94
+ isLevelEnabled(level: string): boolean {
95
+ return this.logger.isLevelEnabled(level);
96
+ }
97
+
98
+ /**
99
+ * 获取原始logger实例
100
+ */
101
+ getLogger(): ILogger {
102
+ return this.logger;
103
+ }
104
+
105
+ /**
106
+ * 创建子logger(用于模块划分)
107
+ * @param name 子logger名称
108
+ */
109
+ createChildLogger(name: string): ILogger {
110
+ return this.logger.child(name);
111
+ }
112
+
113
+ /**
114
+ * 添加上下文信息
115
+ * @param context 上下文对象
116
+ */
117
+ withContext(context: Record<string, any>): ILogger {
118
+ return this.logger.withContext(context);
119
+ }
120
+ }
121
+
122
+ // 导出单例实例
123
+ export const logService = LogService.getInstance();