@pcontext/api 0.0.1

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 (342) hide show
  1. package/README.md +151 -0
  2. package/dist/app.d.mts +44779 -0
  3. package/dist/app.d.mts.map +1 -0
  4. package/dist/app.mjs +37 -0
  5. package/dist/app.mjs.map +1 -0
  6. package/dist/client.d.mts +22428 -0
  7. package/dist/client.d.mts.map +1 -0
  8. package/dist/client.mjs +15 -0
  9. package/dist/client.mjs.map +1 -0
  10. package/dist/dev.d.mts +11 -0
  11. package/dist/dev.d.mts.map +1 -0
  12. package/dist/dev.mjs +16 -0
  13. package/dist/dev.mjs.map +1 -0
  14. package/dist/index.d.mts +3 -0
  15. package/dist/index.mjs +10 -0
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/modules/doc/chat.route.d.mts +18 -0
  18. package/dist/modules/doc/chat.route.d.mts.map +1 -0
  19. package/dist/modules/doc/chat.route.mjs +20 -0
  20. package/dist/modules/doc/chat.route.mjs.map +1 -0
  21. package/dist/modules/doc/chat.service.d.mts +10 -0
  22. package/dist/modules/doc/chat.service.d.mts.map +1 -0
  23. package/dist/modules/doc/chat.service.mjs +29 -0
  24. package/dist/modules/doc/chat.service.mjs.map +1 -0
  25. package/dist/modules/doc/doc.dto.d.mts +67 -0
  26. package/dist/modules/doc/doc.dto.d.mts.map +1 -0
  27. package/dist/modules/doc/doc.dto.mjs +43 -0
  28. package/dist/modules/doc/doc.dto.mjs.map +1 -0
  29. package/dist/modules/doc/doc.entity.d.mts +19 -0
  30. package/dist/modules/doc/doc.entity.d.mts.map +1 -0
  31. package/dist/modules/doc/doc.entity.mjs +1 -0
  32. package/dist/modules/doc/doc.repo.interface.d.mts +28 -0
  33. package/dist/modules/doc/doc.repo.interface.d.mts.map +1 -0
  34. package/dist/modules/doc/doc.repo.interface.mjs +1 -0
  35. package/dist/modules/doc/doc.route.d.mts +14193 -0
  36. package/dist/modules/doc/doc.route.d.mts.map +1 -0
  37. package/dist/modules/doc/doc.route.mjs +100 -0
  38. package/dist/modules/doc/doc.route.mjs.map +1 -0
  39. package/dist/modules/doc/doc.service.d.mts +38 -0
  40. package/dist/modules/doc/doc.service.d.mts.map +1 -0
  41. package/dist/modules/doc/doc.service.mjs +134 -0
  42. package/dist/modules/doc/doc.service.mjs.map +1 -0
  43. package/dist/modules/doc/doc.vo.d.mts +17 -0
  44. package/dist/modules/doc/doc.vo.d.mts.map +1 -0
  45. package/dist/modules/doc/doc.vo.mjs +1 -0
  46. package/dist/modules/doc/infrastructure/agent/engine/chat.d.mts +21 -0
  47. package/dist/modules/doc/infrastructure/agent/engine/chat.d.mts.map +1 -0
  48. package/dist/modules/doc/infrastructure/agent/engine/chat.mjs +36 -0
  49. package/dist/modules/doc/infrastructure/agent/engine/chat.mjs.map +1 -0
  50. package/dist/modules/doc/infrastructure/agent/engine/generate.d.mts +28 -0
  51. package/dist/modules/doc/infrastructure/agent/engine/generate.d.mts.map +1 -0
  52. package/dist/modules/doc/infrastructure/agent/engine/generate.mjs +135 -0
  53. package/dist/modules/doc/infrastructure/agent/engine/generate.mjs.map +1 -0
  54. package/dist/modules/doc/infrastructure/agent/engine/query-filter.d.mts +7 -0
  55. package/dist/modules/doc/infrastructure/agent/engine/query-filter.d.mts.map +1 -0
  56. package/dist/modules/doc/infrastructure/agent/engine/query-filter.mjs +12 -0
  57. package/dist/modules/doc/infrastructure/agent/engine/query-filter.mjs.map +1 -0
  58. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.d.mts +54 -0
  59. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.d.mts.map +1 -0
  60. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.mjs +142 -0
  61. package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.mjs.map +1 -0
  62. package/dist/modules/doc/infrastructure/agent/loaders/index.d.mts +3 -0
  63. package/dist/modules/doc/infrastructure/agent/loaders/index.mjs +4 -0
  64. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.d.mts +42 -0
  65. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.d.mts.map +1 -0
  66. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.mjs +104 -0
  67. package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.mjs.map +1 -0
  68. package/dist/modules/doc/infrastructure/agent/settings.d.mts +5 -0
  69. package/dist/modules/doc/infrastructure/agent/settings.d.mts.map +1 -0
  70. package/dist/modules/doc/infrastructure/agent/settings.mjs +72 -0
  71. package/dist/modules/doc/infrastructure/agent/settings.mjs.map +1 -0
  72. package/dist/modules/doc/infrastructure/agent/storage/index.d.mts +7 -0
  73. package/dist/modules/doc/infrastructure/agent/storage/index.d.mts.map +1 -0
  74. package/dist/modules/doc/infrastructure/agent/storage/index.mjs +12 -0
  75. package/dist/modules/doc/infrastructure/agent/storage/index.mjs.map +1 -0
  76. package/dist/modules/doc/infrastructure/agent/storage/vector-store.d.mts +14 -0
  77. package/dist/modules/doc/infrastructure/agent/storage/vector-store.d.mts.map +1 -0
  78. package/dist/modules/doc/infrastructure/agent/storage/vector-store.mjs +35 -0
  79. package/dist/modules/doc/infrastructure/agent/storage/vector-store.mjs.map +1 -0
  80. package/dist/modules/doc/infrastructure/doc.po.d.mts +570 -0
  81. package/dist/modules/doc/infrastructure/doc.po.d.mts.map +1 -0
  82. package/dist/modules/doc/infrastructure/doc.po.mjs +54 -0
  83. package/dist/modules/doc/infrastructure/doc.po.mjs.map +1 -0
  84. package/dist/modules/doc/infrastructure/doc.repo.pg.d.mts +32 -0
  85. package/dist/modules/doc/infrastructure/doc.repo.pg.d.mts.map +1 -0
  86. package/dist/modules/doc/infrastructure/doc.repo.pg.mjs +157 -0
  87. package/dist/modules/doc/infrastructure/doc.repo.pg.mjs.map +1 -0
  88. package/dist/modules/doc/infrastructure/doc.repo.sqlite.d.mts +32 -0
  89. package/dist/modules/doc/infrastructure/doc.repo.sqlite.d.mts.map +1 -0
  90. package/dist/modules/doc/infrastructure/doc.repo.sqlite.mjs +153 -0
  91. package/dist/modules/doc/infrastructure/doc.repo.sqlite.mjs.map +1 -0
  92. package/dist/modules/doc/mcp.route.d.mts +18 -0
  93. package/dist/modules/doc/mcp.route.d.mts.map +1 -0
  94. package/dist/modules/doc/mcp.route.mjs +39 -0
  95. package/dist/modules/doc/mcp.route.mjs.map +1 -0
  96. package/dist/modules/doc/mcp.service.d.mts +22 -0
  97. package/dist/modules/doc/mcp.service.d.mts.map +1 -0
  98. package/dist/modules/doc/mcp.service.mjs +119 -0
  99. package/dist/modules/doc/mcp.service.mjs.map +1 -0
  100. package/dist/modules/rank/rank.dto.d.mts +10 -0
  101. package/dist/modules/rank/rank.dto.d.mts.map +1 -0
  102. package/dist/modules/rank/rank.dto.mjs +8 -0
  103. package/dist/modules/rank/rank.dto.mjs.map +1 -0
  104. package/dist/modules/rank/rank.route.d.mts +2033 -0
  105. package/dist/modules/rank/rank.route.d.mts.map +1 -0
  106. package/dist/modules/rank/rank.route.mjs +20 -0
  107. package/dist/modules/rank/rank.route.mjs.map +1 -0
  108. package/dist/modules/rank/rank.service.d.mts +32 -0
  109. package/dist/modules/rank/rank.service.d.mts.map +1 -0
  110. package/dist/modules/rank/rank.service.mjs +3 -0
  111. package/dist/modules/rank/rank.vo.d.mts +9 -0
  112. package/dist/modules/rank/rank.vo.d.mts.map +1 -0
  113. package/dist/modules/rank/rank.vo.mjs +1 -0
  114. package/dist/modules/task/infrastructure/mq/task-context.d.mts +29 -0
  115. package/dist/modules/task/infrastructure/mq/task-context.d.mts.map +1 -0
  116. package/dist/modules/task/infrastructure/mq/task-context.mjs +70 -0
  117. package/dist/modules/task/infrastructure/mq/task-context.mjs.map +1 -0
  118. package/dist/modules/task/infrastructure/mq/task-queue.d.mts +10 -0
  119. package/dist/modules/task/infrastructure/mq/task-queue.d.mts.map +1 -0
  120. package/dist/modules/task/infrastructure/mq/task-queue.mjs +12 -0
  121. package/dist/modules/task/infrastructure/mq/task-queue.mjs.map +1 -0
  122. package/dist/modules/task/infrastructure/mq/task-worker.d.mts +13 -0
  123. package/dist/modules/task/infrastructure/mq/task-worker.d.mts.map +1 -0
  124. package/dist/modules/task/infrastructure/mq/task-worker.mjs +35 -0
  125. package/dist/modules/task/infrastructure/mq/task-worker.mjs.map +1 -0
  126. package/dist/modules/task/infrastructure/task.po.d.mts +1147 -0
  127. package/dist/modules/task/infrastructure/task.po.d.mts.map +1 -0
  128. package/dist/modules/task/infrastructure/task.po.mjs +55 -0
  129. package/dist/modules/task/infrastructure/task.po.mjs.map +1 -0
  130. package/dist/modules/task/infrastructure/task.repo.pg.d.mts +21 -0
  131. package/dist/modules/task/infrastructure/task.repo.pg.d.mts.map +1 -0
  132. package/dist/modules/task/infrastructure/task.repo.pg.mjs +86 -0
  133. package/dist/modules/task/infrastructure/task.repo.pg.mjs.map +1 -0
  134. package/dist/modules/task/infrastructure/task.repo.sqlite.d.mts +21 -0
  135. package/dist/modules/task/infrastructure/task.repo.sqlite.d.mts.map +1 -0
  136. package/dist/modules/task/infrastructure/task.repo.sqlite.mjs +89 -0
  137. package/dist/modules/task/infrastructure/task.repo.sqlite.mjs.map +1 -0
  138. package/dist/modules/task/task.dto.d.mts +26 -0
  139. package/dist/modules/task/task.dto.d.mts.map +1 -0
  140. package/dist/modules/task/task.dto.mjs +25 -0
  141. package/dist/modules/task/task.dto.mjs.map +1 -0
  142. package/dist/modules/task/task.entity.d.mts +43 -0
  143. package/dist/modules/task/task.entity.d.mts.map +1 -0
  144. package/dist/modules/task/task.entity.mjs +1 -0
  145. package/dist/modules/task/task.repo.interface.d.mts +17 -0
  146. package/dist/modules/task/task.repo.interface.d.mts.map +1 -0
  147. package/dist/modules/task/task.repo.interface.mjs +1 -0
  148. package/dist/modules/task/task.route.d.mts +4087 -0
  149. package/dist/modules/task/task.route.d.mts.map +1 -0
  150. package/dist/modules/task/task.route.mjs +63 -0
  151. package/dist/modules/task/task.route.mjs.map +1 -0
  152. package/dist/modules/task/task.service.d.mts +28 -0
  153. package/dist/modules/task/task.service.d.mts.map +1 -0
  154. package/dist/modules/task/task.service.mjs +202 -0
  155. package/dist/modules/task/task.service.mjs.map +1 -0
  156. package/dist/modules/task/task.vo.d.mts +18 -0
  157. package/dist/modules/task/task.vo.d.mts.map +1 -0
  158. package/dist/modules/task/task.vo.mjs +1 -0
  159. package/dist/modules/user/application/user.service.d.mts +24 -0
  160. package/dist/modules/user/application/user.service.d.mts.map +1 -0
  161. package/dist/modules/user/application/user.service.mjs +153 -0
  162. package/dist/modules/user/application/user.service.mjs.map +1 -0
  163. package/dist/modules/user/domain/user.entity.d.mts +24 -0
  164. package/dist/modules/user/domain/user.entity.d.mts.map +1 -0
  165. package/dist/modules/user/domain/user.entity.mjs +35 -0
  166. package/dist/modules/user/domain/user.entity.mjs.map +1 -0
  167. package/dist/modules/user/domain/user.repo.interface.d.mts +27 -0
  168. package/dist/modules/user/domain/user.repo.interface.d.mts.map +1 -0
  169. package/dist/modules/user/domain/user.repo.interface.mjs +1 -0
  170. package/dist/modules/user/infrastructure/casbin/adapter.d.mts +7 -0
  171. package/dist/modules/user/infrastructure/casbin/adapter.d.mts.map +1 -0
  172. package/dist/modules/user/infrastructure/casbin/adapter.mjs +13 -0
  173. package/dist/modules/user/infrastructure/casbin/adapter.mjs.map +1 -0
  174. package/dist/modules/user/infrastructure/casbin/adapter.pg.d.mts +19 -0
  175. package/dist/modules/user/infrastructure/casbin/adapter.pg.d.mts.map +1 -0
  176. package/dist/modules/user/infrastructure/casbin/adapter.pg.mjs +129 -0
  177. package/dist/modules/user/infrastructure/casbin/adapter.pg.mjs.map +1 -0
  178. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.d.mts +19 -0
  179. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.d.mts.map +1 -0
  180. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.mjs +129 -0
  181. package/dist/modules/user/infrastructure/casbin/adapter.sqlite.mjs.map +1 -0
  182. package/dist/modules/user/infrastructure/casbin/enforcer.d.mts +9 -0
  183. package/dist/modules/user/infrastructure/casbin/enforcer.d.mts.map +1 -0
  184. package/dist/modules/user/infrastructure/casbin/enforcer.mjs +150 -0
  185. package/dist/modules/user/infrastructure/casbin/enforcer.mjs.map +1 -0
  186. package/dist/modules/user/infrastructure/casbin-rule.po.d.mts +643 -0
  187. package/dist/modules/user/infrastructure/casbin-rule.po.d.mts.map +1 -0
  188. package/dist/modules/user/infrastructure/casbin-rule.po.mjs +30 -0
  189. package/dist/modules/user/infrastructure/casbin-rule.po.mjs.map +1 -0
  190. package/dist/modules/user/infrastructure/user.po.d.mts +392 -0
  191. package/dist/modules/user/infrastructure/user.po.d.mts.map +1 -0
  192. package/dist/modules/user/infrastructure/user.po.mjs +34 -0
  193. package/dist/modules/user/infrastructure/user.po.mjs.map +1 -0
  194. package/dist/modules/user/infrastructure/user.repo.pg.d.mts +24 -0
  195. package/dist/modules/user/infrastructure/user.repo.pg.d.mts.map +1 -0
  196. package/dist/modules/user/infrastructure/user.repo.pg.mjs +90 -0
  197. package/dist/modules/user/infrastructure/user.repo.pg.mjs.map +1 -0
  198. package/dist/modules/user/infrastructure/user.repo.sqlite.d.mts +24 -0
  199. package/dist/modules/user/infrastructure/user.repo.sqlite.d.mts.map +1 -0
  200. package/dist/modules/user/infrastructure/user.repo.sqlite.mjs +88 -0
  201. package/dist/modules/user/infrastructure/user.repo.sqlite.mjs.map +1 -0
  202. package/dist/modules/user/interfaces/admin.route.d.mts +8270 -0
  203. package/dist/modules/user/interfaces/admin.route.d.mts.map +1 -0
  204. package/dist/modules/user/interfaces/admin.route.mjs +74 -0
  205. package/dist/modules/user/interfaces/admin.route.mjs.map +1 -0
  206. package/dist/modules/user/interfaces/role.route.d.mts +102 -0
  207. package/dist/modules/user/interfaces/role.route.d.mts.map +1 -0
  208. package/dist/modules/user/interfaces/role.route.mjs +60 -0
  209. package/dist/modules/user/interfaces/role.route.mjs.map +1 -0
  210. package/dist/modules/user/interfaces/user.dto.d.mts +106 -0
  211. package/dist/modules/user/interfaces/user.dto.d.mts.map +1 -0
  212. package/dist/modules/user/interfaces/user.dto.mjs +32 -0
  213. package/dist/modules/user/interfaces/user.dto.mjs.map +1 -0
  214. package/dist/modules/user/interfaces/user.route.d.mts +2093 -0
  215. package/dist/modules/user/interfaces/user.route.d.mts.map +1 -0
  216. package/dist/modules/user/interfaces/user.route.mjs +69 -0
  217. package/dist/modules/user/interfaces/user.route.mjs.map +1 -0
  218. package/dist/modules/user/interfaces/user.vo.d.mts +28 -0
  219. package/dist/modules/user/interfaces/user.vo.d.mts.map +1 -0
  220. package/dist/modules/user/interfaces/user.vo.mjs +18 -0
  221. package/dist/modules/user/interfaces/user.vo.mjs.map +1 -0
  222. package/dist/rank.service-D2h-2iJA.mjs +109 -0
  223. package/dist/rank.service-D2h-2iJA.mjs.map +1 -0
  224. package/dist/settings.d.mts +12 -0
  225. package/dist/settings.d.mts.map +1 -0
  226. package/dist/settings.mjs +27 -0
  227. package/dist/settings.mjs.map +1 -0
  228. package/dist/shared/create-app.d.mts +13 -0
  229. package/dist/shared/create-app.d.mts.map +1 -0
  230. package/dist/shared/create-app.mjs +45 -0
  231. package/dist/shared/create-app.mjs.map +1 -0
  232. package/dist/shared/db/bootstrap.d.mts +5 -0
  233. package/dist/shared/db/bootstrap.d.mts.map +1 -0
  234. package/dist/shared/db/bootstrap.mjs +51 -0
  235. package/dist/shared/db/bootstrap.mjs.map +1 -0
  236. package/dist/shared/db/connection.d.mts +1567 -0
  237. package/dist/shared/db/connection.d.mts.map +1 -0
  238. package/dist/shared/db/connection.mjs +59 -0
  239. package/dist/shared/db/connection.mjs.map +1 -0
  240. package/dist/shared/db/migrations/pg/0000_init.sql +74 -0
  241. package/dist/shared/db/migrations/pg/0001_snippets & tokens.sql +6 -0
  242. package/dist/shared/db/migrations/pg/0002_change_task_id_to_uuid_v7.sql +3 -0
  243. package/dist/shared/db/migrations/pg/meta/0000_snapshot.json +498 -0
  244. package/dist/shared/db/migrations/pg/meta/0001_snapshot.json +513 -0
  245. package/dist/shared/db/migrations/pg/meta/0002_snapshot.json +514 -0
  246. package/dist/shared/db/migrations/pg/meta/_journal.json +27 -0
  247. package/dist/shared/db/migrations/sqlite/0000_init.sql +72 -0
  248. package/dist/shared/db/migrations/sqlite/0001_snippets & tokens.sql +2 -0
  249. package/dist/shared/db/migrations/sqlite/0002_change_task_id_to_uuid_v7.sql +35 -0
  250. package/dist/shared/db/migrations/sqlite/meta/0000_snapshot.json +493 -0
  251. package/dist/shared/db/migrations/sqlite/meta/0001_snapshot.json +509 -0
  252. package/dist/shared/db/migrations/sqlite/meta/0002_snapshot.json +509 -0
  253. package/dist/shared/db/migrations/sqlite/meta/_journal.json +27 -0
  254. package/dist/shared/db/seed.d.mts +5 -0
  255. package/dist/shared/db/seed.d.mts.map +1 -0
  256. package/dist/shared/db/seed.mjs +42 -0
  257. package/dist/shared/db/seed.mjs.map +1 -0
  258. package/dist/shared/deps.d.mts +28 -0
  259. package/dist/shared/deps.d.mts.map +1 -0
  260. package/dist/shared/deps.mjs +69 -0
  261. package/dist/shared/deps.mjs.map +1 -0
  262. package/dist/shared/dto/index.d.mts +11 -0
  263. package/dist/shared/dto/index.d.mts.map +1 -0
  264. package/dist/shared/dto/index.mjs +11 -0
  265. package/dist/shared/dto/index.mjs.map +1 -0
  266. package/dist/shared/logger.d.mts +14 -0
  267. package/dist/shared/logger.d.mts.map +1 -0
  268. package/dist/shared/logger.mjs +37 -0
  269. package/dist/shared/logger.mjs.map +1 -0
  270. package/dist/shared/mcp/createTool.d.mts +15 -0
  271. package/dist/shared/mcp/createTool.d.mts.map +1 -0
  272. package/dist/shared/mcp/createTool.mjs +8 -0
  273. package/dist/shared/mcp/createTool.mjs.map +1 -0
  274. package/dist/shared/middleware/authorization.d.mts +15 -0
  275. package/dist/shared/middleware/authorization.d.mts.map +1 -0
  276. package/dist/shared/middleware/authorization.mjs +46 -0
  277. package/dist/shared/middleware/authorization.mjs.map +1 -0
  278. package/dist/shared/middleware/http-logger.d.mts +7 -0
  279. package/dist/shared/middleware/http-logger.d.mts.map +1 -0
  280. package/dist/shared/middleware/http-logger.mjs +40 -0
  281. package/dist/shared/middleware/http-logger.mjs.map +1 -0
  282. package/dist/shared/middleware/jwt.d.mts +7 -0
  283. package/dist/shared/middleware/jwt.d.mts.map +1 -0
  284. package/dist/shared/middleware/jwt.mjs +34 -0
  285. package/dist/shared/middleware/jwt.mjs.map +1 -0
  286. package/dist/shared/middleware/limiter.d.mts +7 -0
  287. package/dist/shared/middleware/limiter.d.mts.map +1 -0
  288. package/dist/shared/middleware/limiter.mjs +10 -0
  289. package/dist/shared/middleware/limiter.mjs.map +1 -0
  290. package/dist/shared/middleware/services.d.mts +8 -0
  291. package/dist/shared/middleware/services.d.mts.map +1 -0
  292. package/dist/shared/middleware/services.mjs +19 -0
  293. package/dist/shared/middleware/services.mjs.map +1 -0
  294. package/dist/shared/redis/decorator.d.mts +113 -0
  295. package/dist/shared/redis/decorator.d.mts.map +1 -0
  296. package/dist/shared/redis/decorator.mjs +203 -0
  297. package/dist/shared/redis/decorator.mjs.map +1 -0
  298. package/dist/shared/redis/factory.d.mts +18 -0
  299. package/dist/shared/redis/factory.d.mts.map +1 -0
  300. package/dist/shared/redis/factory.mjs +41 -0
  301. package/dist/shared/redis/factory.mjs.map +1 -0
  302. package/dist/shared/redis/index.d.mts +12 -0
  303. package/dist/shared/redis/index.d.mts.map +1 -0
  304. package/dist/shared/redis/index.mjs +14 -0
  305. package/dist/shared/redis/index.mjs.map +1 -0
  306. package/dist/shared/types.d.mts +36 -0
  307. package/dist/shared/types.d.mts.map +1 -0
  308. package/dist/shared/types.mjs +1 -0
  309. package/dist/shared/utils/date.d.mts +1 -0
  310. package/dist/shared/utils/date.mjs +1 -0
  311. package/dist/shared/utils/error-handler.d.mts +7 -0
  312. package/dist/shared/utils/error-handler.d.mts.map +1 -0
  313. package/dist/shared/utils/error-handler.mjs +22 -0
  314. package/dist/shared/utils/error-handler.mjs.map +1 -0
  315. package/dist/shared/utils/format.d.mts +8 -0
  316. package/dist/shared/utils/format.d.mts.map +1 -0
  317. package/dist/shared/utils/format.mjs +24 -0
  318. package/dist/shared/utils/format.mjs.map +1 -0
  319. package/dist/shared/utils/pagination.d.mts +9 -0
  320. package/dist/shared/utils/pagination.d.mts.map +1 -0
  321. package/dist/shared/utils/pagination.mjs +12 -0
  322. package/dist/shared/utils/pagination.mjs.map +1 -0
  323. package/dist/shared/utils/response-template.d.mts +69 -0
  324. package/dist/shared/utils/response-template.d.mts.map +1 -0
  325. package/dist/shared/utils/response-template.mjs +96 -0
  326. package/dist/shared/utils/response-template.mjs.map +1 -0
  327. package/dist/shared/utils/url.d.mts +18 -0
  328. package/dist/shared/utils/url.d.mts.map +1 -0
  329. package/dist/shared/utils/url.mjs +39 -0
  330. package/dist/shared/utils/url.mjs.map +1 -0
  331. package/dist/shared/utils/user.d.mts +8 -0
  332. package/dist/shared/utils/user.d.mts.map +1 -0
  333. package/dist/shared/utils/user.mjs +11 -0
  334. package/dist/shared/utils/user.mjs.map +1 -0
  335. package/dist/shared/utils/validator.d.mts +5984 -0
  336. package/dist/shared/utils/validator.d.mts.map +1 -0
  337. package/dist/shared/utils/validator.mjs +34 -0
  338. package/dist/shared/utils/validator.mjs.map +1 -0
  339. package/dist/shared/vo/index.d.mts +11 -0
  340. package/dist/shared/vo/index.d.mts.map +1 -0
  341. package/dist/shared/vo/index.mjs +1 -0
  342. package/package.json +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.route.d.mts","names":[],"sources":["../../../src/modules/task/task.route.ts"],"mappings":";;;;;;;;;;cAmBM,MAAA,kBAAM,QAAA,CAmER,WAAA;;;;;;;;;;;;;;;;;;;oBAnEQ,OAAA,CAAA,aAAA"}
@@ -0,0 +1,63 @@
1
+ import { logger } from "../../shared/logger.mjs";
2
+ import "../../rank.service-D2h-2iJA.mjs";
3
+ import { createRouter } from "../../shared/create-app.mjs";
4
+ import { Res200 } from "../../shared/utils/response-template.mjs";
5
+ import { paramValidator, queryValidator } from "../../shared/utils/validator.mjs";
6
+ import z from "zod";
7
+ import { streamSSE } from "hono/streaming";
8
+
9
+ //#region src/modules/task/task.route.ts
10
+ const idSchema = z.object({ id: z.string() });
11
+ const listQuerySchema = z.object({ limit: z.number().int().min(1).max(100).default(10) });
12
+ const router = createRouter().get("/", queryValidator(listQuerySchema), async (c) => {
13
+ const { limit } = c.req.valid("query");
14
+ const tasks = await c.var.taskService.listRecentTasks(limit);
15
+ return c.json(Res200({ tasks }), 200);
16
+ }).get("/:id", paramValidator(idSchema), async (c) => {
17
+ const { id } = c.req.valid("param");
18
+ const task = await c.var.taskService.getTaskDetail(id);
19
+ return c.json(Res200({ task }), 200);
20
+ }).get("/:id/progress", (c) => {
21
+ const { id } = c.req.param();
22
+ return streamSSE(c, async (stream) => {
23
+ const send = async (event) => {
24
+ if (event.type === "log") {
25
+ try {
26
+ await stream.writeSSE({ data: JSON.stringify([event.entry]) });
27
+ } catch {
28
+ logger.error(`sending task progress by SSE, taskId is ${id}`);
29
+ }
30
+ return;
31
+ }
32
+ if (event.type === "end") try {
33
+ await stream.writeSSE({
34
+ data: event.status,
35
+ event: "end"
36
+ });
37
+ } catch {
38
+ logger.error(`sending task end by SSE, taskId is ${id}`);
39
+ }
40
+ };
41
+ if (!id) {
42
+ await stream.writeSSE({
43
+ data: "error: TASK_ID",
44
+ event: "error"
45
+ });
46
+ return;
47
+ }
48
+ try {
49
+ const logStream = await c.var.taskService.createLogStream(id);
50
+ for await (const event of logStream) await send(event);
51
+ } catch (error) {
52
+ logger.error(`Error streaming logs for task ${id}: ${error.message}`);
53
+ await stream.writeSSE({
54
+ data: "error: INTERNAL_ERROR",
55
+ event: "error"
56
+ });
57
+ }
58
+ });
59
+ });
60
+
61
+ //#endregion
62
+ export { router as default };
63
+ //# sourceMappingURL=task.route.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.route.mjs","names":[],"sources":["../../../src/modules/task/task.route.ts"],"sourcesContent":["import type { TaskLogEvent } from './task.entity'\nimport type { TaskVO } from './task.vo'\nimport type { TaskDocDTO } from '@/modules/doc/doc.dto'\nimport type { ApiError, ApiSuccess } from '@/shared/types'\nimport { streamSSE } from 'hono/streaming'\nimport z from 'zod'\nimport { createRouter } from '@/shared/create-app'\nimport { logger } from '@/shared/logger'\nimport { Res200, Res400, Res404 } from '@/shared/utils/response-template'\nimport { paramValidator, queryValidator } from '@/shared/utils/validator'\n\nconst idSchema = z.object({\n id: z.string(),\n})\n\nconst listQuerySchema = z.object({\n limit: z.number().int().min(1).max(100).default(10),\n})\n\nconst router = createRouter()\n .get('/', queryValidator(listQuerySchema), async (c) => {\n const { limit } = c.req.valid('query')\n\n const tasks = await c.var.taskService.listRecentTasks(limit)\n return c.json(Res200({ tasks }) as ApiSuccess<{\n tasks: TaskVO<TaskDocDTO>[]\n }>, 200)\n })\n .get('/:id', paramValidator(idSchema), async (c) => {\n const { id } = c.req.valid('param')\n const task = await c.var.taskService.getTaskDetail(id)\n return c.json(Res200({ task }) as ApiSuccess<{ task: TaskVO<TaskDocDTO> | null }>, 200)\n })\n .get('/:id/progress', (c) => {\n const { id } = c.req.param()\n\n return streamSSE(c, async (stream) => {\n const send = async (event: TaskLogEvent) => {\n if (event.type === 'log') {\n try {\n await stream.writeSSE({\n data: JSON.stringify([event.entry]),\n })\n }\n catch {\n logger.error(`sending task progress by SSE, taskId is ${id}`)\n }\n return\n }\n\n if (event.type === 'end') {\n try {\n await stream.writeSSE({\n data: event.status,\n event: 'end',\n })\n }\n catch {\n logger.error(`sending task end by SSE, taskId is ${id}`)\n }\n }\n }\n\n if (!id) {\n await stream.writeSSE({\n data: 'error: TASK_ID',\n event: 'error',\n })\n return\n }\n\n try {\n const logStream = await c.var.taskService.createLogStream(id)\n\n for await (const event of logStream) {\n await send(event as TaskLogEvent)\n }\n }\n catch (error: any) {\n logger.error(`Error streaming logs for task ${id}: ${error.message}`)\n await stream.writeSSE({\n data: 'error: INTERNAL_ERROR',\n event: 'error',\n })\n }\n })\n })\n\nexport default router\n"],"mappings":";;;;;;;;;AAWA,MAAM,WAAW,EAAE,OAAO,EACxB,IAAI,EAAE,QAAQ,EACf,CAAC;AAEF,MAAM,kBAAkB,EAAE,OAAO,EAC/B,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,EACpD,CAAC;AAEF,MAAM,SAAS,cAAc,CAC1B,IAAI,KAAK,eAAe,gBAAgB,EAAE,OAAO,MAAM;CACtD,MAAM,EAAE,UAAU,EAAE,IAAI,MAAM,QAAQ;CAEtC,MAAM,QAAQ,MAAM,EAAE,IAAI,YAAY,gBAAgB,MAAM;AAC5D,QAAO,EAAE,KAAK,OAAO,EAAE,OAAO,CAAC,EAE3B,IAAI;EACR,CACD,IAAI,QAAQ,eAAe,SAAS,EAAE,OAAO,MAAM;CAClD,MAAM,EAAE,OAAO,EAAE,IAAI,MAAM,QAAQ;CACnC,MAAM,OAAO,MAAM,EAAE,IAAI,YAAY,cAAc,GAAG;AACtD,QAAO,EAAE,KAAK,OAAO,EAAE,MAAM,CAAC,EAAqD,IAAI;EACvF,CACD,IAAI,kBAAkB,MAAM;CAC3B,MAAM,EAAE,OAAO,EAAE,IAAI,OAAO;AAE5B,QAAO,UAAU,GAAG,OAAO,WAAW;EACpC,MAAM,OAAO,OAAO,UAAwB;AAC1C,OAAI,MAAM,SAAS,OAAO;AACxB,QAAI;AACF,WAAM,OAAO,SAAS,EACpB,MAAM,KAAK,UAAU,CAAC,MAAM,MAAM,CAAC,EACpC,CAAC;YAEE;AACJ,YAAO,MAAM,2CAA2C,KAAK;;AAE/D;;AAGF,OAAI,MAAM,SAAS,MACjB,KAAI;AACF,UAAM,OAAO,SAAS;KACpB,MAAM,MAAM;KACZ,OAAO;KACR,CAAC;WAEE;AACJ,WAAO,MAAM,sCAAsC,KAAK;;;AAK9D,MAAI,CAAC,IAAI;AACP,SAAM,OAAO,SAAS;IACpB,MAAM;IACN,OAAO;IACR,CAAC;AACF;;AAGF,MAAI;GACF,MAAM,YAAY,MAAM,EAAE,IAAI,YAAY,gBAAgB,GAAG;AAE7D,cAAW,MAAM,SAAS,UACxB,OAAM,KAAK,MAAsB;WAG9B,OAAY;AACjB,UAAO,MAAM,iCAAiC,GAAG,IAAI,MAAM,UAAU;AACrE,SAAM,OAAO,SAAS;IACpB,MAAM;IACN,OAAO;IACR,CAAC;;GAEJ;EACF"}
@@ -0,0 +1,28 @@
1
+ import { DocSourceEnumDTO, TaskDocDTO } from "../doc/doc.dto.mjs";
2
+ import { TaskVO } from "./task.vo.mjs";
3
+ import { DocEntity } from "../doc/doc.entity.mjs";
4
+ import { TaskContext } from "./infrastructure/mq/task-context.mjs";
5
+ import { TaskWorker } from "./infrastructure/mq/task-worker.mjs";
6
+ import { Readable } from "node:stream";
7
+ import * as bullmq from "bullmq";
8
+
9
+ //#region src/modules/task/task.service.d.ts
10
+ declare class TaskService {
11
+ private worker;
12
+ private queue;
13
+ private cache;
14
+ private get taskRepo();
15
+ private get docRepo();
16
+ constructor();
17
+ initWorker(): TaskWorker;
18
+ submitTask(type: string, data: Omit<TaskDocDTO, 'id'>): Promise<bullmq.Job<any, any, string>>;
19
+ listRecentTasks(limit?: number): Promise<TaskVO<TaskDocDTO>[]>;
20
+ getTaskDetail(taskId: string, logLimit?: number): Promise<TaskVO<TaskDocDTO> | null>;
21
+ private getTaskLogs;
22
+ indexWebsiteDoc(task: TaskContext<TaskDocDTO>): Promise<DocEntity<Date>>;
23
+ indexGitDoc(task: TaskContext<TaskDocDTO>, source: DocSourceEnumDTO): Promise<DocEntity<Date>>;
24
+ createLogStream(taskId: string): Promise<Readable>;
25
+ }
26
+ //#endregion
27
+ export { TaskService };
28
+ //# sourceMappingURL=task.service.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.service.d.mts","names":[],"sources":["../../../src/modules/task/task.service.ts"],"mappings":";;;;;;;;;cAgBa,WAAA;EAAA,QACH,MAAA;EAAA,QACA,KAAA;EAAA,QACA,KAAA;EAAA,YAEI,QAAA,CAAA;EAAA,YAIA,OAAA,CAAA;;EAUZ,UAAA,CAAA,GAAU,UAAA;EAkCJ,UAAA,CAAW,IAAA,UAAc,IAAA,EAAM,IAAA,CAAK,UAAA,UAAiB,OAAA,CAAlB,MAAA,CAAkB,GAAA;EAWrD,eAAA,CAAgB,KAAA,YAAqB,OAAA,CAAQ,MAAA,CAAO,UAAA;EAoBpD,aAAA,CAAc,MAAA,UAAgB,QAAA,YAAyB,OAAA,CAAQ,MAAA,CAAO,UAAA;EAAA,QAwB9D,WAAA;EAYR,eAAA,CAAgB,IAAA,EAAM,WAAA,CAAY,UAAA,IAAW,OAAA,CAAA,SAAA,CAAA,IAAA;EAa7C,WAAA,CAAY,IAAA,EAAM,WAAA,CAAY,UAAA,GAAa,MAAA,EAAQ,gBAAA,GAAgB,OAAA,CAAA,SAAA,CAAA,IAAA;EAanE,eAAA,CAAgB,MAAA,WAAiB,OAAA,CAAQ,QAAA;AAAA"}
@@ -0,0 +1,202 @@
1
+ import { logger } from "../../shared/logger.mjs";
2
+ import { createRedisClient } from "../../shared/redis/factory.mjs";
3
+ import { Cache, CacheableService } from "../../shared/redis/decorator.mjs";
4
+ import { n as __decorate, r as __decorateMetadata } from "../../rank.service-D2h-2iJA.mjs";
5
+ import "../../shared/redis/index.mjs";
6
+ import { generateGitRepositoryData, generateWebsiteData } from "../doc/infrastructure/agent/engine/generate.mjs";
7
+ import { TaskContext } from "./infrastructure/mq/task-context.mjs";
8
+ import { TaskQueue } from "./infrastructure/mq/task-queue.mjs";
9
+ import { TaskWorker } from "./infrastructure/mq/task-worker.mjs";
10
+ import { getRepoDeps } from "../../shared/deps.mjs";
11
+ import { PassThrough } from "node:stream";
12
+
13
+ //#region src/modules/task/task.service.ts
14
+ let TaskService = class TaskService {
15
+ worker = null;
16
+ queue;
17
+ cache;
18
+ get taskRepo() {
19
+ return getRepoDeps().taskRepo;
20
+ }
21
+ get docRepo() {
22
+ return getRepoDeps().docRepo;
23
+ }
24
+ constructor() {
25
+ this.cache = createRedisClient();
26
+ this.queue = new TaskQueue("task-queue", this.cache);
27
+ this.initWorker();
28
+ }
29
+ initWorker() {
30
+ if (this.worker) return this.worker;
31
+ this.worker = new TaskWorker("task-queue", async (job) => {
32
+ const ctx = new TaskContext(job, logger);
33
+ const taskId = job.data.id;
34
+ const source = job.data?.source;
35
+ ctx.logInfo("Task started");
36
+ try {
37
+ if (source === "website") await this.indexWebsiteDoc(ctx);
38
+ else if (source === "github" || source === "gitee") await this.indexGitDoc(ctx, source);
39
+ else throw new Error(`Unknown source: ${source}`);
40
+ await this.taskRepo.updateStatus(taskId, "completed");
41
+ ctx.logInfo("Task updated in database with status completed");
42
+ } catch (error) {
43
+ await this.taskRepo.updateStatus(taskId, "failed", error.message);
44
+ ctx.logError(`Task updated in database with status failed: ${error.message}`);
45
+ throw error;
46
+ }
47
+ }, this.cache);
48
+ return this.worker;
49
+ }
50
+ async submitTask(type, data) {
51
+ const taskEntity = await this.taskRepo.create({
52
+ type,
53
+ status: "running",
54
+ extraData: data
55
+ });
56
+ return await this.queue.add(type, {
57
+ ...data,
58
+ id: taskEntity.id
59
+ }, { jobId: taskEntity.id });
60
+ }
61
+ async listRecentTasks(limit = 20) {
62
+ return (await this.taskRepo.findRecentTasks(limit)).map((task) => {
63
+ const extraData = task.extraData ? {
64
+ id: task.id,
65
+ ...task.extraData
66
+ } : void 0;
67
+ return {
68
+ id: task.id,
69
+ status: task.status,
70
+ createdAt: task.createdAt,
71
+ updatedAt: task.updatedAt,
72
+ extraData,
73
+ logs: [],
74
+ logsLength: task.logsLength || 0
75
+ };
76
+ });
77
+ }
78
+ async getTaskDetail(taskId, logLimit = 100) {
79
+ const task = await this.taskRepo.findById(taskId);
80
+ if (!task) return null;
81
+ const status = task.status;
82
+ const logs = status === "running" ? [] : await this.getTaskLogs(taskId, logLimit);
83
+ const extraData = task.extraData ? {
84
+ id: taskId,
85
+ ...task.extraData
86
+ } : void 0;
87
+ return {
88
+ id: taskId,
89
+ status,
90
+ createdAt: task.createdAt,
91
+ updatedAt: task.updatedAt,
92
+ extraData,
93
+ logs,
94
+ logsLength: task.logsLength || logs.length
95
+ };
96
+ }
97
+ async getTaskLogs(taskId, limit) {
98
+ const rows = await this.taskRepo.findRecentLogsByTaskId(taskId, limit);
99
+ console.log("rows === ", rows);
100
+ return rows.map((row) => ({
101
+ timestamp: row.createdAt,
102
+ level: row.logLevel ?? "info",
103
+ message: row.content ?? "",
104
+ data: row.extraData ?? void 0,
105
+ traceId: row.traceId ?? taskId
106
+ }));
107
+ }
108
+ async indexWebsiteDoc(task) {
109
+ if (!task.data || task.data.id == null) throw new Error("task 必须包含 id");
110
+ const { slug, id: taskId, name: docName, url } = task.data;
111
+ const { tokens, snippets } = await generateWebsiteData({
112
+ url,
113
+ bizDocId: slug
114
+ }, task);
115
+ task.logInfo(`Indexed website ${slug} successfully`);
116
+ const record = await this.docRepo.create({
117
+ slug,
118
+ name: docName,
119
+ source: "website",
120
+ url,
121
+ taskId,
122
+ tokens,
123
+ snippets
124
+ });
125
+ task.logInfo(`Add document ${slug} with slug ${record.slug} successfully`);
126
+ return record;
127
+ }
128
+ async indexGitDoc(task, source) {
129
+ if (!task.data || task.data.id == null) throw new Error("task 必须包含 id");
130
+ const { slug, id: taskId, name: docName, url } = task.data;
131
+ const { tokens, snippets } = await generateGitRepositoryData({
132
+ url,
133
+ bizDocId: slug
134
+ }, task);
135
+ task.logInfo(`Indexed git repository ${slug} successfully`);
136
+ const record = await this.docRepo.create({
137
+ slug,
138
+ name: docName,
139
+ source,
140
+ url,
141
+ taskId,
142
+ tokens,
143
+ snippets
144
+ });
145
+ task.logInfo(`Add document ${slug} with slug ${record.slug} successfully`);
146
+ return record;
147
+ }
148
+ async createLogStream(taskId) {
149
+ const stream = new PassThrough({ objectMode: true });
150
+ const channel = `task:${taskId}:events`;
151
+ const listKey = `task:${taskId}:logs`;
152
+ if (!await this.queue.getJob(taskId)) {
153
+ stream.end();
154
+ return stream;
155
+ }
156
+ const existingLogs = await this.cache.lrange(listKey, 0, -1);
157
+ for (const logStr of existingLogs) try {
158
+ const entry = JSON.parse(logStr);
159
+ stream.write({
160
+ type: "log",
161
+ entry
162
+ });
163
+ } catch {
164
+ logger.error(`Failed to parse log entry: ${logStr}`);
165
+ }
166
+ const subRedis = this.cache.duplicate();
167
+ await subRedis.subscribe(channel);
168
+ subRedis.on("message", (ch, message) => {
169
+ if (ch !== channel) return;
170
+ try {
171
+ const event = JSON.parse(message);
172
+ stream.write(event);
173
+ if (event.type === "end") {
174
+ subRedis.unsubscribe();
175
+ subRedis.quit();
176
+ stream.end();
177
+ }
178
+ } catch {
179
+ logger.error(`Failed to parse event: ${message}`);
180
+ }
181
+ });
182
+ stream.on("close", () => {
183
+ subRedis.unsubscribe();
184
+ subRedis.quit();
185
+ });
186
+ return stream;
187
+ }
188
+ };
189
+ __decorate([
190
+ Cache({
191
+ tags: () => ["task:list"],
192
+ ttl: 300
193
+ }),
194
+ __decorateMetadata("design:type", Function),
195
+ __decorateMetadata("design:paramtypes", [String, Number]),
196
+ __decorateMetadata("design:returntype", Promise)
197
+ ], TaskService.prototype, "getTaskLogs", null);
198
+ TaskService = __decorate([CacheableService("task"), __decorateMetadata("design:paramtypes", [])], TaskService);
199
+
200
+ //#endregion
201
+ export { TaskService };
202
+ //# sourceMappingURL=task.service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.service.mjs","names":[],"sources":["../../../src/modules/task/task.service.ts"],"sourcesContent":["import type { Redis } from 'ioredis'\nimport type { Readable } from 'node:stream'\nimport type { DocSourceEnumDTO, TaskDocDTO } from '@/modules/doc/doc.dto'\nimport type { TaskLogEntry, TaskStatus } from '@/modules/task/task.entity'\nimport type { TaskVO } from '@/modules/task/task.vo'\nimport { PassThrough } from 'node:stream'\nimport { generateGitRepositoryData, generateWebsiteData } from '@/modules/doc/infrastructure/agent/engine/generate'\nimport { TaskContext } from '@/modules/task/infrastructure/mq/task-context'\nimport { TaskQueue } from '@/modules/task/infrastructure/mq/task-queue'\nimport { TaskWorker } from '@/modules/task/infrastructure/mq/task-worker'\nimport { getRepoDeps } from '@/shared/deps'\nimport { logger } from '@/shared/logger'\nimport { createRedisClient } from '@/shared/redis'\nimport { Cache, CacheableService } from '@/shared/redis/decorator'\n\n@CacheableService('task')\nexport class TaskService {\n private worker: TaskWorker | null = null\n private queue: TaskQueue\n private cache: Redis\n\n private get taskRepo() {\n return getRepoDeps().taskRepo\n }\n\n private get docRepo() {\n return getRepoDeps().docRepo\n }\n\n constructor() {\n this.cache = createRedisClient()\n this.queue = new TaskQueue('task-queue', this.cache)\n this.initWorker()\n }\n\n initWorker() {\n if (this.worker)\n return this.worker\n\n this.worker = new TaskWorker('task-queue', async (job) => {\n const ctx = new TaskContext(job, logger)\n const taskId = job.data.id\n const source = job.data?.source\n\n ctx.logInfo('Task started')\n try {\n if (source === 'website') {\n await this.indexWebsiteDoc(ctx)\n }\n else if (source === 'github' || source === 'gitee') {\n await this.indexGitDoc(ctx, source)\n }\n else {\n throw new Error(`Unknown source: ${source}`)\n }\n\n await this.taskRepo.updateStatus(taskId, 'completed')\n ctx.logInfo('Task updated in database with status completed')\n }\n catch (error: any) {\n await this.taskRepo.updateStatus(taskId, 'failed', error.message)\n ctx.logError(`Task updated in database with status failed: ${error.message}`)\n throw error\n }\n }, this.cache)\n\n return this.worker\n }\n\n async submitTask(type: string, data: Omit<TaskDocDTO, 'id'>) {\n const taskEntity = await this.taskRepo.create({\n type,\n status: 'running',\n extraData: data,\n })\n\n const job = await this.queue.add(type, { ...data, id: taskEntity.id }, { jobId: taskEntity.id })\n return job\n }\n\n async listRecentTasks(limit: number = 20): Promise<TaskVO<TaskDocDTO>[]> {\n const tasks = await this.taskRepo.findRecentTasks(limit)\n\n return tasks.map((task) => {\n const extraData = task.extraData\n ? ({ id: task.id, ...(task.extraData as any) } as TaskDocDTO)\n : undefined\n\n return {\n id: task.id,\n status: task.status,\n createdAt: task.createdAt,\n updatedAt: task.updatedAt,\n extraData,\n logs: [],\n logsLength: task.logsLength || 0,\n }\n })\n }\n\n async getTaskDetail(taskId: string, logLimit: number = 100): Promise<TaskVO<TaskDocDTO> | null> {\n const task = await this.taskRepo.findById(taskId)\n if (!task)\n return null\n\n const status = task.status as TaskStatus\n const logs = status === 'running' ? [] : await this.getTaskLogs(taskId, logLimit)\n\n const extraData = task.extraData\n ? ({ id: taskId, ...(task.extraData as any) } as TaskDocDTO)\n : undefined\n\n return {\n id: taskId,\n status,\n createdAt: task.createdAt,\n updatedAt: task.updatedAt,\n extraData,\n logs,\n logsLength: task.logsLength || logs.length,\n }\n }\n\n @Cache({ tags: () => ['task:list'], ttl: 300 })\n private async getTaskLogs(taskId: string, limit: number): Promise<TaskLogEntry[]> {\n const rows = await this.taskRepo.findRecentLogsByTaskId(taskId, limit)\n console.log('rows === ', rows)\n return rows.map(row => ({\n timestamp: row.createdAt,\n level: (row.logLevel ?? 'info') as any,\n message: row.content ?? '',\n data: row.extraData ?? undefined,\n traceId: row.traceId ?? taskId,\n })) satisfies TaskLogEntry[]\n }\n\n async indexWebsiteDoc(task: TaskContext<TaskDocDTO>) {\n if (!task.data || task.data.id == null) {\n throw new Error('task 必须包含 id')\n }\n\n const { slug, id: taskId, name: docName, url } = task.data\n const { tokens, snippets } = await generateWebsiteData({ url, bizDocId: slug }, task)\n task.logInfo(`Indexed website ${slug} successfully`)\n const record = await this.docRepo.create({ slug, name: docName, source: 'website', url, taskId, tokens, snippets })\n task.logInfo(`Add document ${slug} with slug ${record.slug} successfully`)\n return record\n }\n\n async indexGitDoc(task: TaskContext<TaskDocDTO>, source: DocSourceEnumDTO) {\n if (!task.data || task.data.id == null) {\n throw new Error('task 必须包含 id')\n }\n\n const { slug, id: taskId, name: docName, url } = task.data\n const { tokens, snippets } = await generateGitRepositoryData({ url, bizDocId: slug }, task)\n task.logInfo(`Indexed git repository ${slug} successfully`)\n const record = await this.docRepo.create({ slug, name: docName, source, url, taskId, tokens, snippets })\n task.logInfo(`Add document ${slug} with slug ${record.slug} successfully`)\n return record\n }\n\n async createLogStream(taskId: string): Promise<Readable> {\n const stream = new PassThrough({ objectMode: true })\n const channel = `task:${taskId}:events`\n const listKey = `task:${taskId}:logs`\n\n // 判断是否存在job,不存在则结束流;存在说明job未结束,监听job的log;\n const job = await this.queue.getJob(taskId)\n if (!job) {\n stream.end()\n return stream\n }\n\n const existingLogs = await this.cache.lrange(listKey, 0, -1)\n for (const logStr of existingLogs) {\n try {\n const entry = JSON.parse(logStr) as TaskLogEntry\n stream.write({ type: 'log', entry })\n }\n catch {\n logger.error(`Failed to parse log entry: ${logStr}`)\n }\n }\n\n const subRedis = this.cache.duplicate()\n await subRedis.subscribe(channel)\n\n subRedis.on('message', (ch, message) => {\n if (ch !== channel)\n return\n try {\n const event = JSON.parse(message)\n stream.write(event)\n\n if (event.type === 'end') {\n subRedis.unsubscribe()\n subRedis.quit()\n stream.end()\n }\n }\n catch {\n logger.error(`Failed to parse event: ${message}`)\n }\n })\n\n stream.on('close', () => {\n subRedis.unsubscribe()\n subRedis.quit()\n })\n\n return stream\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { TaskLogEntry, TaskStatus } from "./task.entity.mjs";
2
+
3
+ //#region src/modules/task/task.vo.d.ts
4
+ interface TaskVO<TExtraData = unknown> {
5
+ id: string;
6
+ status: TaskStatus;
7
+ createdAt: number;
8
+ updatedAt: number;
9
+ extraData?: TExtraData;
10
+ logs: TaskLogEntry[];
11
+ logsLength: number;
12
+ }
13
+ interface TaskListVO {
14
+ tasks: TaskVO[];
15
+ }
16
+ //#endregion
17
+ export { TaskListVO, TaskStatus, TaskVO };
18
+ //# sourceMappingURL=task.vo.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.vo.d.mts","names":[],"sources":["../../../src/modules/task/task.vo.ts"],"mappings":";;;UAIiB,MAAA;EACf,EAAA;EACA,MAAA,EAAQ,UAAA;EACR,SAAA;EACA,SAAA;EACA,SAAA,GAAY,UAAA;EACZ,IAAA,EAAM,YAAA;EACN,UAAA;AAAA;AAAA,UAGe,UAAA;EACf,KAAA,EAAO,MAAA;AAAA"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,24 @@
1
+ import { PaginationVO } from "../../../shared/vo/index.mjs";
2
+ import { CreateUserDTO, UpdateSelfDTO, UpdateUserDTO } from "../interfaces/user.dto.mjs";
3
+ import { LoginResultVO, UserVO } from "../interfaces/user.vo.mjs";
4
+ import { UserRole } from "../domain/user.entity.mjs";
5
+
6
+ //#region src/modules/user/application/user.service.d.ts
7
+ declare function login(input: Pick<CreateUserDTO, 'username' | 'password'>): Promise<LoginResultVO>;
8
+ declare function getUserById(id: number): Promise<UserVO | null>;
9
+ declare function listUsers(page: number, pageSize: number, filters?: {
10
+ name?: string;
11
+ }): Promise<PaginationVO<UserVO>>;
12
+ declare function createUser(input: CreateUserDTO): Promise<UserVO>;
13
+ declare function updateUserById(id: number, input: UpdateUserDTO): Promise<UserVO | null>;
14
+ declare function updateUserWithValidation(id: number, input: UpdateUserDTO): Promise<UserVO | null>;
15
+ declare function updateSelf(id: number, input: UpdateSelfDTO): Promise<UserVO | null>;
16
+ declare function softDeleteUser(id: number): Promise<UserVO | null>;
17
+ declare function getUserRoles(id: number): Promise<UserRole[] | null>;
18
+ declare function updateUserRoles(id: number, roles: UserRole[]): Promise<{
19
+ user: UserVO | null;
20
+ roles: UserRole[];
21
+ }>;
22
+ //#endregion
23
+ export { createUser, getUserById, getUserRoles, listUsers, login, softDeleteUser, updateSelf, updateUserById, updateUserRoles, updateUserWithValidation };
24
+ //# sourceMappingURL=user.service.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.service.d.mts","names":[],"sources":["../../../../src/modules/user/application/user.service.ts"],"mappings":";;;;;;iBAasB,KAAA,CAAM,KAAA,EAAO,IAAA,CAAK,aAAA,6BAA0C,OAAA,CAAQ,aAAA;AAAA,iBA6BpE,WAAA,CAAY,EAAA,WAAa,OAAA,CAAQ,MAAA;AAAA,iBAMjC,SAAA,CACpB,IAAA,UACA,QAAA,UACA,OAAA;EAAY,IAAA;AAAA,IACX,OAAA,CAAQ,YAAA,CAAa,MAAA;AAAA,iBASF,UAAA,CAAW,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,MAAA;AAAA,iBA6B1C,cAAA,CAAe,EAAA,UAAY,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,MAAA;AAAA,iBAU1D,wBAAA,CAAyB,EAAA,UAAY,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,MAAA;AAAA,iBA4CpE,UAAA,CAAW,EAAA,UAAY,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,MAAA;AAAA,iBAUtD,cAAA,CAAe,EAAA,WAAa,OAAA,CAAQ,MAAA;AAAA,iBAiBpC,YAAA,CAAa,EAAA,WAAa,OAAA,CAAQ,QAAA;AAAA,iBAclC,eAAA,CAAgB,EAAA,UAAY,KAAA,EAAO,QAAA,KAAa,OAAA;EAAU,IAAA,EAAM,MAAA;EAAe,KAAA,EAAO,QAAA;AAAA"}
@@ -0,0 +1,153 @@
1
+ import AppSettings from "../../../settings.mjs";
2
+ import { logger } from "../../../shared/logger.mjs";
3
+ import { getEnforcer } from "../infrastructure/casbin/enforcer.mjs";
4
+ import "../../../rank.service-D2h-2iJA.mjs";
5
+ import { UserEntity } from "../domain/user.entity.mjs";
6
+ import { getRepoDeps } from "../../../shared/deps.mjs";
7
+ import { userSchema } from "../interfaces/user.vo.mjs";
8
+ import { sign } from "hono/jwt";
9
+ import argon2 from "argon2";
10
+
11
+ //#region src/modules/user/application/user.service.ts
12
+ async function login(input) {
13
+ const { userRepo } = getRepoDeps();
14
+ const authUser = await userRepo.findByUsername(input.username);
15
+ if (!authUser) throw new Error("用户不存在");
16
+ if (!await argon2.verify(authUser.password, input.password)) throw new Error("密码错误");
17
+ const user = new UserEntity({
18
+ id: authUser.id,
19
+ username: authUser.username,
20
+ password: authUser.password,
21
+ name: "",
22
+ phone: "",
23
+ email: "",
24
+ role: authUser.role,
25
+ status: authUser.status,
26
+ createdAt: Date.now(),
27
+ updatedAt: Date.now()
28
+ });
29
+ user.ensureActive();
30
+ const token = await sign({
31
+ sub: String(user.id),
32
+ username: user.username,
33
+ role: user.role
34
+ }, AppSettings.config.jwt_secret, "HS256");
35
+ logger.info({
36
+ userId: user.id,
37
+ username: user.username
38
+ }, "user login");
39
+ return {
40
+ user: userSchema.parse(user),
41
+ token
42
+ };
43
+ }
44
+ async function getUserById(id) {
45
+ const { userRepo } = getRepoDeps();
46
+ const user = await userRepo.findById(id);
47
+ return user ? userSchema.parse(user) : null;
48
+ }
49
+ async function listUsers(page, pageSize, filters) {
50
+ const { userRepo } = getRepoDeps();
51
+ const result = await userRepo.list(page, pageSize, filters);
52
+ return {
53
+ ...result,
54
+ list: result.list.map((item) => userSchema.parse(item))
55
+ };
56
+ }
57
+ async function createUser(input) {
58
+ const { userRepo } = getRepoDeps();
59
+ if (await userRepo.findByUsername(input.username)) throw new Error("用户已存在");
60
+ if (await userRepo.findByPhone(input.phone)) throw new Error("手机号已存在");
61
+ if (await userRepo.findByEmail(input.email)) throw new Error("邮箱已存在");
62
+ const hashedPassword = await argon2.hash(input.password);
63
+ const created = await userRepo.create({
64
+ ...input,
65
+ password: hashedPassword
66
+ });
67
+ const primaryRole = input.role ?? "user";
68
+ await getEnforcer().addRoleForUser(created.username, primaryRole);
69
+ logger.info({
70
+ userId: created.id,
71
+ username: created.username
72
+ }, "user created");
73
+ return userSchema.parse(created);
74
+ }
75
+ async function updateUserById(id, input) {
76
+ const { userRepo } = getRepoDeps();
77
+ const patch = { ...input };
78
+ if (patch.password !== void 0) patch.password = await argon2.hash(patch.password);
79
+ const updated = await userRepo.updateById(id, patch);
80
+ return updated ? userSchema.parse(updated) : null;
81
+ }
82
+ async function updateUserWithValidation(id, input) {
83
+ const { userRepo } = getRepoDeps();
84
+ const existing = await userRepo.findById(id);
85
+ if (!existing) return null;
86
+ const patch = { ...input };
87
+ if (patch.username !== void 0) {
88
+ const userByName = await userRepo.findByUsername(patch.username);
89
+ if (userByName && userByName.id !== id) throw new Error("用户名已存在");
90
+ }
91
+ if (patch.phone !== void 0) {
92
+ const userByPhone = await userRepo.findByPhone(patch.phone);
93
+ if (userByPhone && userByPhone.id !== id) throw new Error("手机号已存在");
94
+ }
95
+ if (patch.email !== void 0) {
96
+ const userByEmail = await userRepo.findByEmail(patch.email);
97
+ if (userByEmail && userByEmail.id !== id) throw new Error("邮箱已存在");
98
+ }
99
+ const updated = await updateUserById(id, patch);
100
+ if (!updated) return null;
101
+ if (patch.role !== void 0 && patch.role !== existing.role) {
102
+ const enforcer = getEnforcer();
103
+ await enforcer.deleteRolesForUser(existing.username);
104
+ await enforcer.addRoleForUser(existing.username, patch.role);
105
+ }
106
+ return updated;
107
+ }
108
+ async function updateSelf(id, input) {
109
+ const { userRepo } = getRepoDeps();
110
+ const patch = { ...input };
111
+ if (patch.password !== void 0) patch.password = await argon2.hash(patch.password);
112
+ const updated = await userRepo.updateSelf(id, patch);
113
+ return updated ? userSchema.parse(updated) : null;
114
+ }
115
+ async function softDeleteUser(id) {
116
+ const existing = await getUserById(id);
117
+ if (!existing) return null;
118
+ const updated = await updateUserById(id, { status: "inactive" });
119
+ if (!updated) return null;
120
+ await getEnforcer().deleteUser(existing.username);
121
+ return updated;
122
+ }
123
+ async function getUserRoles(id) {
124
+ const user = await getUserById(id);
125
+ if (!user) return null;
126
+ const casbinRoles = (await getEnforcer().getRolesForUser(user.username)).filter((r) => r === "admin" || r === "user");
127
+ if (casbinRoles.length === 0) return [user.role];
128
+ return casbinRoles;
129
+ }
130
+ async function updateUserRoles(id, roles) {
131
+ const primaryRole = roles[0];
132
+ const user = await getUserById(id);
133
+ if (!user) return {
134
+ user: null,
135
+ roles: []
136
+ };
137
+ const updated = await updateUserById(id, { role: primaryRole });
138
+ if (!updated) return {
139
+ user: null,
140
+ roles: []
141
+ };
142
+ const enforcer = getEnforcer();
143
+ await enforcer.deleteRolesForUser(user.username);
144
+ for (const role of roles) await enforcer.addRoleForUser(user.username, role);
145
+ return {
146
+ user: updated,
147
+ roles
148
+ };
149
+ }
150
+
151
+ //#endregion
152
+ export { createUser, getUserById, getUserRoles, listUsers, login, softDeleteUser, updateSelf, updateUserById, updateUserRoles, updateUserWithValidation };
153
+ //# sourceMappingURL=user.service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.service.mjs","names":[],"sources":["../../../../src/modules/user/application/user.service.ts"],"sourcesContent":["import type { UserRole } from '@/modules/user/domain/user.entity'\nimport type { CreateUserDTO, UpdateSelfDTO, UpdateUserDTO } from '@/modules/user/interfaces/user.dto'\nimport type { LoginResultVO, UserVO } from '@/modules/user/interfaces/user.vo'\nimport type { PaginationVO } from '@/shared/vo'\nimport argon2 from 'argon2'\nimport { sign } from 'hono/jwt'\nimport { UserEntity } from '@/modules/user/domain/user.entity'\nimport { getEnforcer } from '@/modules/user/infrastructure/casbin/enforcer'\nimport { userSchema } from '@/modules/user/interfaces/user.vo'\nimport AppSettings from '@/settings'\nimport { getRepoDeps } from '@/shared/deps'\nimport { logger } from '@/shared/logger'\n\nexport async function login(input: Pick<CreateUserDTO, 'username' | 'password'>): Promise<LoginResultVO> {\n const { userRepo } = getRepoDeps()\n const authUser = await userRepo.findByUsername(input.username)\n if (!authUser) {\n throw new Error('用户不存在')\n }\n\n const valid = await argon2.verify(authUser.password, input.password)\n if (!valid) {\n throw new Error('密码错误')\n }\n const user = new UserEntity({\n id: authUser.id,\n username: authUser.username,\n password: authUser.password,\n name: '',\n phone: '',\n email: '',\n role: authUser.role,\n status: authUser.status,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n })\n user.ensureActive()\n const token = await sign({ sub: String(user.id), username: user.username, role: user.role }, AppSettings.config.jwt_secret, 'HS256')\n logger.info({ userId: user.id, username: user.username }, 'user login')\n return { user: userSchema.parse(user), token }\n}\n\nexport async function getUserById(id: number): Promise<UserVO | null> {\n const { userRepo } = getRepoDeps()\n const user = await userRepo.findById(id)\n return user ? userSchema.parse(user) : null\n}\n\nexport async function listUsers(\n page: number,\n pageSize: number,\n filters?: { name?: string },\n): Promise<PaginationVO<UserVO>> {\n const { userRepo } = getRepoDeps()\n const result = await userRepo.list(page, pageSize, filters)\n return {\n ...result,\n list: result.list.map(item => userSchema.parse(item)),\n }\n}\n\nexport async function createUser(input: CreateUserDTO): Promise<UserVO> {\n const { userRepo } = getRepoDeps()\n\n const hasUser = await userRepo.findByUsername(input.username)\n if (hasUser) {\n throw new Error('用户已存在')\n }\n\n const hasPhone = await userRepo.findByPhone(input.phone)\n if (hasPhone) {\n throw new Error('手机号已存在')\n }\n\n const hasEmail = await userRepo.findByEmail(input.email)\n if (hasEmail) {\n throw new Error('邮箱已存在')\n }\n\n const hashedPassword = await argon2.hash(input.password)\n const created = await userRepo.create({ ...input, password: hashedPassword })\n\n const primaryRole: UserRole = input.role ?? 'user'\n const enforcer = getEnforcer()\n await enforcer.addRoleForUser(created.username, primaryRole)\n\n logger.info({ userId: created.id, username: created.username }, 'user created')\n return userSchema.parse(created)\n}\n\nexport async function updateUserById(id: number, input: UpdateUserDTO): Promise<UserVO | null> {\n const { userRepo } = getRepoDeps()\n const patch: UpdateUserDTO = { ...input }\n if (patch.password !== undefined) {\n patch.password = await argon2.hash(patch.password)\n }\n const updated = await userRepo.updateById(id, patch)\n return updated ? userSchema.parse(updated) : null\n}\n\nexport async function updateUserWithValidation(id: number, input: UpdateUserDTO): Promise<UserVO | null> {\n const { userRepo } = getRepoDeps()\n const existing = await userRepo.findById(id)\n if (!existing) {\n return null\n }\n\n const patch: UpdateUserDTO = { ...input }\n\n if (patch.username !== undefined) {\n const userByName = await userRepo.findByUsername(patch.username)\n if (userByName && userByName.id !== id) {\n throw new Error('用户名已存在')\n }\n }\n\n if (patch.phone !== undefined) {\n const userByPhone = await userRepo.findByPhone(patch.phone)\n if (userByPhone && userByPhone.id !== id) {\n throw new Error('手机号已存在')\n }\n }\n\n if (patch.email !== undefined) {\n const userByEmail = await userRepo.findByEmail(patch.email)\n if (userByEmail && userByEmail.id !== id) {\n throw new Error('邮箱已存在')\n }\n }\n\n const updated = await updateUserById(id, patch)\n if (!updated) {\n return null\n }\n\n if (patch.role !== undefined && patch.role !== existing.role) {\n const enforcer = getEnforcer()\n await enforcer.deleteRolesForUser(existing.username)\n await enforcer.addRoleForUser(existing.username, patch.role)\n }\n\n return updated\n}\n\nexport async function updateSelf(id: number, input: UpdateSelfDTO): Promise<UserVO | null> {\n const { userRepo } = getRepoDeps()\n const patch: UpdateSelfDTO = { ...input }\n if (patch.password !== undefined) {\n patch.password = await argon2.hash(patch.password)\n }\n const updated = await userRepo.updateSelf(id, patch)\n return updated ? userSchema.parse(updated) : null\n}\n\nexport async function softDeleteUser(id: number): Promise<UserVO | null> {\n const existing = await getUserById(id)\n if (!existing) {\n return null\n }\n\n const updated = await updateUserById(id, { status: 'inactive' })\n if (!updated) {\n return null\n }\n\n const enforcer = getEnforcer()\n await enforcer.deleteUser(existing.username)\n\n return updated\n}\n\nexport async function getUserRoles(id: number): Promise<UserRole[] | null> {\n const user = await getUserById(id)\n if (!user) {\n return null\n }\n const enforcer = getEnforcer()\n const roles = await enforcer.getRolesForUser(user.username)\n const casbinRoles = roles.filter((r): r is UserRole => r === 'admin' || r === 'user')\n if (casbinRoles.length === 0) {\n return [user.role]\n }\n return casbinRoles\n}\n\nexport async function updateUserRoles(id: number, roles: UserRole[]): Promise<{ user: UserVO | null, roles: UserRole[] }> {\n const primaryRole = roles[0]\n const user = await getUserById(id)\n if (!user) {\n return { user: null, roles: [] }\n }\n\n const updated = await updateUserById(id, { role: primaryRole })\n if (!updated) {\n return { user: null, roles: [] }\n }\n\n const enforcer = getEnforcer()\n await enforcer.deleteRolesForUser(user.username)\n for (const role of roles) {\n await enforcer.addRoleForUser(user.username, role)\n }\n\n return { user: updated, roles }\n}\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { UserPgPO, UserSqlitePO } from "../infrastructure/user.po.mjs";
2
+
3
+ //#region src/modules/user/domain/user.entity.d.ts
4
+ type UserPO = UserPgPO | UserSqlitePO;
5
+ type UserRole = 'admin' | 'user';
6
+ type UserStatus = 'active' | 'inactive';
7
+ declare class UserEntity {
8
+ id: number;
9
+ username: string;
10
+ password: string;
11
+ name: string;
12
+ phone: string;
13
+ email: string;
14
+ role: UserRole;
15
+ status: UserStatus;
16
+ createdAt: number;
17
+ updatedAt: number;
18
+ constructor(data: UserPO);
19
+ isActive(): boolean;
20
+ ensureActive(): void;
21
+ }
22
+ //#endregion
23
+ export { UserEntity, UserRole, UserStatus };
24
+ //# sourceMappingURL=user.entity.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.entity.d.mts","names":[],"sources":["../../../../src/modules/user/domain/user.entity.ts"],"mappings":";;;KAEK,MAAA,GAAS,QAAA,GAAW,YAAA;AAAA,KACb,QAAA;AAAA,KACA,UAAA;AAAA,cAEC,UAAA;EACX,EAAA;EACA,QAAA;EACA,QAAA;EACA,IAAA;EACA,KAAA;EACA,KAAA;EACA,IAAA,EAAM,QAAA;EACN,MAAA,EAAQ,UAAA;EACR,SAAA;EACA,SAAA;cAEY,IAAA,EAAM,MAAA;EAalB,QAAA,CAAA;EAIA,YAAA,CAAA;AAAA"}
@@ -0,0 +1,35 @@
1
+ //#region src/modules/user/domain/user.entity.ts
2
+ var UserEntity = class {
3
+ id;
4
+ username;
5
+ password;
6
+ name;
7
+ phone;
8
+ email;
9
+ role;
10
+ status;
11
+ createdAt;
12
+ updatedAt;
13
+ constructor(data) {
14
+ this.id = data.id ?? 0;
15
+ this.username = data.username ?? "";
16
+ this.name = data.name ?? "";
17
+ this.phone = data.phone ?? "";
18
+ this.email = data.email ?? "";
19
+ this.role = data.role ?? "user";
20
+ this.status = data.status ?? "active";
21
+ this.password = data.password ?? "";
22
+ this.createdAt = data.createdAt;
23
+ this.updatedAt = data.updatedAt;
24
+ }
25
+ isActive() {
26
+ return this.status === "active";
27
+ }
28
+ ensureActive() {
29
+ if (!this.isActive()) throw new Error("用户已被禁用");
30
+ }
31
+ };
32
+
33
+ //#endregion
34
+ export { UserEntity };
35
+ //# sourceMappingURL=user.entity.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.entity.mjs","names":[],"sources":["../../../../src/modules/user/domain/user.entity.ts"],"sourcesContent":["import type { UserPgPO, UserSqlitePO } from '../infrastructure/user.po'\n\ntype UserPO = UserPgPO | UserSqlitePO\nexport type UserRole = 'admin' | 'user'\nexport type UserStatus = 'active' | 'inactive'\n\nexport class UserEntity {\n id: number\n username: string\n password: string\n name: string\n phone: string\n email: string\n role: UserRole\n status: UserStatus\n createdAt: number\n updatedAt: number\n\n constructor(data: UserPO) {\n this.id = data.id ?? 0\n this.username = data.username ?? ''\n this.name = data.name ?? ''\n this.phone = data.phone ?? ''\n this.email = data.email ?? ''\n this.role = (data.role ?? 'user') as UserRole\n this.status = (data.status ?? 'active') as UserStatus\n this.password = data.password ?? ''\n this.createdAt = data.createdAt\n this.updatedAt = data.updatedAt\n }\n\n isActive(): boolean {\n return this.status === 'active'\n }\n\n ensureActive(): void {\n if (!this.isActive()) {\n throw new Error('用户已被禁用')\n }\n }\n}\n"],"mappings":";AAMA,IAAa,aAAb,MAAwB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,MAAc;AACxB,OAAK,KAAK,KAAK,MAAM;AACrB,OAAK,WAAW,KAAK,YAAY;AACjC,OAAK,OAAO,KAAK,QAAQ;AACzB,OAAK,QAAQ,KAAK,SAAS;AAC3B,OAAK,QAAQ,KAAK,SAAS;AAC3B,OAAK,OAAQ,KAAK,QAAQ;AAC1B,OAAK,SAAU,KAAK,UAAU;AAC9B,OAAK,WAAW,KAAK,YAAY;AACjC,OAAK,YAAY,KAAK;AACtB,OAAK,YAAY,KAAK;;CAGxB,WAAoB;AAClB,SAAO,KAAK,WAAW;;CAGzB,eAAqB;AACnB,MAAI,CAAC,KAAK,UAAU,CAClB,OAAM,IAAI,MAAM,SAAS"}