@lenne.tech/nest-server 12.0.0 → 12.1.0

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 (693) hide show
  1. package/.claude/rules/architecture.md +6 -1
  2. package/.claude/rules/better-auth.md +46 -0
  3. package/.claude/rules/configurable-features.md +3 -2
  4. package/.claude/rules/package-management.md +24 -2
  5. package/.claude/rules/persistence.md +100 -0
  6. package/.claude/rules/role-system.md +9 -0
  7. package/.claude/rules/testing.md +116 -18
  8. package/CLAUDE.md +21 -2
  9. package/FRAMEWORK-API.md +6 -4
  10. package/README.md +106 -34
  11. package/dist/core/common/decorators/unified-field.decorator.d.ts +2 -1
  12. package/dist/core/common/decorators/unified-field.decorator.js +4 -1
  13. package/dist/core/common/decorators/unified-field.decorator.js.map +1 -1
  14. package/dist/core/common/filters/mongoose-cast-error.filter.d.ts +7 -5
  15. package/dist/core/common/filters/mongoose-cast-error.filter.js +3 -2
  16. package/dist/core/common/filters/mongoose-cast-error.filter.js.map +1 -1
  17. package/dist/core/common/helpers/db.helper.d.ts +2 -1
  18. package/dist/core/common/helpers/db.helper.js +32 -26
  19. package/dist/core/common/helpers/db.helper.js.map +1 -1
  20. package/dist/core/common/helpers/decorator.helper.d.ts +1 -1
  21. package/dist/core/common/helpers/filter.helper.d.ts +2 -1
  22. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  23. package/dist/core/common/helpers/gridfs.helper.d.ts +4 -4
  24. package/dist/core/common/helpers/gridfs.helper.js +14 -6
  25. package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
  26. package/dist/core/common/helpers/id.helper.d.ts +4 -1
  27. package/dist/core/common/helpers/id.helper.js +10 -4
  28. package/dist/core/common/helpers/id.helper.js.map +1 -1
  29. package/dist/core/common/helpers/model.helper.js +5 -5
  30. package/dist/core/common/helpers/model.helper.js.map +1 -1
  31. package/dist/core/common/helpers/service.helper.js +3 -3
  32. package/dist/core/common/helpers/service.helper.js.map +1 -1
  33. package/dist/core/common/interfaces/server-options.interface.d.ts +18 -2
  34. package/dist/core/common/interfaces/service-options.interface.d.ts +2 -2
  35. package/dist/core/common/models/core-persistence.model.d.ts +1 -2
  36. package/dist/core/common/models/core-persistence.model.js +3 -3
  37. package/dist/core/common/models/core-persistence.model.js.map +1 -1
  38. package/dist/core/common/persistence/core-persistence.lifecycle.d.ts +9 -0
  39. package/dist/core/common/persistence/core-persistence.lifecycle.js +38 -0
  40. package/dist/core/common/persistence/core-persistence.lifecycle.js.map +1 -0
  41. package/dist/core/common/persistence/core-persistence.module.d.ts +9 -0
  42. package/dist/core/common/persistence/core-persistence.module.js +76 -0
  43. package/dist/core/common/persistence/core-persistence.module.js.map +1 -0
  44. package/dist/core/common/persistence/data-source.config.d.ts +33 -0
  45. package/dist/core/common/persistence/data-source.config.js +151 -0
  46. package/dist/core/common/persistence/data-source.config.js.map +1 -0
  47. package/dist/core/common/persistence/data-source.runtime.d.ts +45 -0
  48. package/dist/core/common/persistence/data-source.runtime.js +278 -0
  49. package/dist/core/common/persistence/data-source.runtime.js.map +1 -0
  50. package/dist/core/common/persistence/data-store.interface.d.ts +73 -0
  51. package/dist/core/common/persistence/data-store.interface.js +2 -0
  52. package/dist/core/common/persistence/data-store.interface.js.map +1 -0
  53. package/dist/core/common/persistence/expiry-sweep.d.ts +12 -0
  54. package/dist/core/common/persistence/expiry-sweep.js +55 -0
  55. package/dist/core/common/persistence/expiry-sweep.js.map +1 -0
  56. package/dist/core/common/persistence/id-format.d.ts +3 -0
  57. package/dist/core/common/persistence/id-format.js +21 -0
  58. package/dist/core/common/persistence/id-format.js.map +1 -0
  59. package/dist/core/common/persistence/infrastructure-locks.d.ts +13 -0
  60. package/dist/core/common/persistence/infrastructure-locks.js +35 -0
  61. package/dist/core/common/persistence/infrastructure-locks.js.map +1 -0
  62. package/dist/core/common/persistence/inject-store.decorator.d.ts +1 -0
  63. package/dist/core/common/persistence/inject-store.decorator.js +6 -0
  64. package/dist/core/common/persistence/inject-store.decorator.js.map +1 -0
  65. package/dist/core/common/persistence/lock-store.interface.d.ts +5 -0
  66. package/dist/core/common/persistence/lock-store.interface.js +2 -0
  67. package/dist/core/common/persistence/lock-store.interface.js.map +1 -0
  68. package/dist/core/common/persistence/model-descriptor.interface.d.ts +36 -0
  69. package/dist/core/common/persistence/model-descriptor.interface.js +2 -0
  70. package/dist/core/common/persistence/model-descriptor.interface.js.map +1 -0
  71. package/dist/core/common/persistence/model-metadata.registry.d.ts +14 -0
  72. package/dist/core/common/persistence/model-metadata.registry.js +194 -0
  73. package/dist/core/common/persistence/model-metadata.registry.js.map +1 -0
  74. package/dist/core/common/persistence/mongo/collection-name.d.ts +2 -0
  75. package/dist/core/common/persistence/mongo/collection-name.js +73 -0
  76. package/dist/core/common/persistence/mongo/collection-name.js.map +1 -0
  77. package/dist/core/common/persistence/mongo/declared-schema.view.d.ts +11 -0
  78. package/dist/core/common/persistence/mongo/declared-schema.view.js +292 -0
  79. package/dist/core/common/persistence/mongo/declared-schema.view.js.map +1 -0
  80. package/dist/core/common/persistence/mongo/hex-object-id.d.ts +13 -0
  81. package/dist/core/common/persistence/mongo/hex-object-id.js +54 -0
  82. package/dist/core/common/persistence/mongo/hex-object-id.js.map +1 -0
  83. package/dist/core/common/persistence/mongo/model-declarations.d.ts +35 -0
  84. package/dist/core/common/persistence/mongo/model-declarations.js +80 -0
  85. package/dist/core/common/persistence/mongo/model-declarations.js.map +1 -0
  86. package/dist/core/common/persistence/mongo/mongo-packages.d.ts +15 -0
  87. package/dist/core/common/persistence/mongo/mongo-packages.js +66 -0
  88. package/dist/core/common/persistence/mongo/mongo-packages.js.map +1 -0
  89. package/dist/core/common/persistence/mongo/mongoose-compat.d.ts +22 -0
  90. package/dist/core/common/persistence/mongo/mongoose-compat.js +65 -0
  91. package/dist/core/common/persistence/mongo/mongoose-compat.js.map +1 -0
  92. package/dist/core/common/persistence/mongo/no-mongo-connection.module.d.ts +2 -0
  93. package/dist/core/common/persistence/mongo/no-mongo-connection.module.js +19 -0
  94. package/dist/core/common/persistence/mongo/no-mongo-connection.module.js.map +1 -0
  95. package/dist/core/common/persistence/mongo-lock-store.d.ts +21 -0
  96. package/dist/core/common/persistence/mongo-lock-store.js +72 -0
  97. package/dist/core/common/persistence/mongo-lock-store.js.map +1 -0
  98. package/dist/core/common/persistence/mongoose-data-store.d.ts +33 -0
  99. package/dist/core/common/persistence/mongoose-data-store.js +187 -0
  100. package/dist/core/common/persistence/mongoose-data-store.js.map +1 -0
  101. package/dist/core/common/persistence/neutral-populate.d.ts +6 -0
  102. package/dist/core/common/persistence/neutral-populate.js +72 -0
  103. package/dist/core/common/persistence/neutral-populate.js.map +1 -0
  104. package/dist/core/common/persistence/persisted-model.decorator.d.ts +6 -0
  105. package/dist/core/common/persistence/persisted-model.decorator.js +24 -0
  106. package/dist/core/common/persistence/persisted-model.decorator.js.map +1 -0
  107. package/dist/core/common/persistence/persistence-runtime.registry.d.ts +61 -0
  108. package/dist/core/common/persistence/persistence-runtime.registry.js +47 -0
  109. package/dist/core/common/persistence/persistence-runtime.registry.js.map +1 -0
  110. package/dist/core/common/persistence/persistence.tokens.d.ts +1 -0
  111. package/dist/core/common/persistence/persistence.tokens.js +4 -0
  112. package/dist/core/common/persistence/persistence.tokens.js.map +1 -0
  113. package/dist/core/common/persistence/policies/audit.policy.d.ts +8 -0
  114. package/dist/core/common/persistence/policies/audit.policy.js +37 -0
  115. package/dist/core/common/persistence/policies/audit.policy.js.map +1 -0
  116. package/dist/core/common/persistence/policies/password.policy.d.ts +3 -0
  117. package/dist/core/common/persistence/policies/password.policy.js +46 -0
  118. package/dist/core/common/persistence/policies/password.policy.js.map +1 -0
  119. package/dist/core/common/persistence/policies/role-guard.policy.d.ts +3 -0
  120. package/dist/core/common/persistence/policies/role-guard.policy.js +46 -0
  121. package/dist/core/common/persistence/policies/role-guard.policy.js.map +1 -0
  122. package/dist/core/common/persistence/policies/system-role.policy.d.ts +5 -0
  123. package/dist/core/common/persistence/policies/system-role.policy.js +46 -0
  124. package/dist/core/common/persistence/policies/system-role.policy.js.map +1 -0
  125. package/dist/core/common/persistence/policies/tenant.policy.d.ts +19 -0
  126. package/dist/core/common/persistence/policies/tenant.policy.js +120 -0
  127. package/dist/core/common/persistence/policies/tenant.policy.js.map +1 -0
  128. package/dist/core/common/persistence/routed-model.guard.d.ts +4 -0
  129. package/dist/core/common/persistence/routed-model.guard.js +73 -0
  130. package/dist/core/common/persistence/routed-model.guard.js.map +1 -0
  131. package/dist/core/common/persistence/sql/mysql/mysql-data-store.d.ts +46 -0
  132. package/dist/core/common/persistence/sql/mysql/mysql-data-store.js +350 -0
  133. package/dist/core/common/persistence/sql/mysql/mysql-data-store.js.map +1 -0
  134. package/dist/core/common/persistence/sql/mysql/mysql-executor.d.ts +13 -0
  135. package/dist/core/common/persistence/sql/mysql/mysql-executor.js +194 -0
  136. package/dist/core/common/persistence/sql/mysql/mysql-executor.js.map +1 -0
  137. package/dist/core/common/persistence/sql/mysql/mysql-lock-store.d.ts +11 -0
  138. package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js +55 -0
  139. package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js.map +1 -0
  140. package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.d.ts +36 -0
  141. package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js +288 -0
  142. package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js.map +1 -0
  143. package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.d.ts +19 -0
  144. package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js +328 -0
  145. package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js.map +1 -0
  146. package/dist/core/common/persistence/sql/mysql/mysql-session.d.ts +13 -0
  147. package/dist/core/common/persistence/sql/mysql/mysql-session.js +85 -0
  148. package/dist/core/common/persistence/sql/mysql/mysql-session.js.map +1 -0
  149. package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.d.ts +9 -0
  150. package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js +264 -0
  151. package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js.map +1 -0
  152. package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.d.ts +20 -0
  153. package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js +519 -0
  154. package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js.map +1 -0
  155. package/dist/core/common/persistence/sql/postgres/postgres-lock-store.d.ts +11 -0
  156. package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js +44 -0
  157. package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js.map +1 -0
  158. package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.d.ts +42 -0
  159. package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js +220 -0
  160. package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js.map +1 -0
  161. package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.d.ts +12 -0
  162. package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js +315 -0
  163. package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js.map +1 -0
  164. package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.d.ts +5 -0
  165. package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js +225 -0
  166. package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js.map +1 -0
  167. package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.d.ts +13 -0
  168. package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js +484 -0
  169. package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js.map +1 -0
  170. package/dist/core/common/persistence/sql/sql-cast.d.ts +2 -0
  171. package/dist/core/common/persistence/sql/sql-cast.js +194 -0
  172. package/dist/core/common/persistence/sql/sql-cast.js.map +1 -0
  173. package/dist/core/common/persistence/sql/sql-data-store.d.ts +79 -0
  174. package/dist/core/common/persistence/sql/sql-data-store.js +592 -0
  175. package/dist/core/common/persistence/sql/sql-data-store.js.map +1 -0
  176. package/dist/core/common/persistence/sql/sql-dialect.d.ts +20 -0
  177. package/dist/core/common/persistence/sql/sql-dialect.js +38 -0
  178. package/dist/core/common/persistence/sql/sql-dialect.js.map +1 -0
  179. package/dist/core/common/persistence/sql/sql-errors.d.ts +17 -0
  180. package/dist/core/common/persistence/sql/sql-errors.js +25 -0
  181. package/dist/core/common/persistence/sql/sql-errors.js.map +1 -0
  182. package/dist/core/common/persistence/sql/sql-executor.factory.d.ts +11 -0
  183. package/dist/core/common/persistence/sql/sql-executor.factory.js +199 -0
  184. package/dist/core/common/persistence/sql/sql-executor.factory.js.map +1 -0
  185. package/dist/core/common/persistence/sql/sql-executor.interface.d.ts +32 -0
  186. package/dist/core/common/persistence/sql/sql-executor.interface.js +2 -0
  187. package/dist/core/common/persistence/sql/sql-executor.interface.js.map +1 -0
  188. package/dist/core/common/persistence/sql/sql-naming.d.ts +15 -0
  189. package/dist/core/common/persistence/sql/sql-naming.js +90 -0
  190. package/dist/core/common/persistence/sql/sql-naming.js.map +1 -0
  191. package/dist/core/common/persistence/sql/sql-schema.shared.d.ts +25 -0
  192. package/dist/core/common/persistence/sql/sql-schema.shared.js +69 -0
  193. package/dist/core/common/persistence/sql/sql-schema.shared.js.map +1 -0
  194. package/dist/core/common/persistence/sql/sql-session.d.ts +6 -0
  195. package/dist/core/common/persistence/sql/sql-session.js +78 -0
  196. package/dist/core/common/persistence/sql/sql-session.js.map +1 -0
  197. package/dist/core/common/persistence/sql/where-shared.d.ts +18 -0
  198. package/dist/core/common/persistence/sql/where-shared.js +93 -0
  199. package/dist/core/common/persistence/sql/where-shared.js.map +1 -0
  200. package/dist/core/common/persistence/store-guards.d.ts +10 -0
  201. package/dist/core/common/persistence/store-guards.js +49 -0
  202. package/dist/core/common/persistence/store-guards.js.map +1 -0
  203. package/dist/core/common/persistence/store-upsert.d.ts +2 -0
  204. package/dist/core/common/persistence/store-upsert.js +20 -0
  205. package/dist/core/common/persistence/store-upsert.js.map +1 -0
  206. package/dist/core/common/persistence/unavailable-store.d.ts +2 -0
  207. package/dist/core/common/persistence/unavailable-store.js +53 -0
  208. package/dist/core/common/persistence/unavailable-store.js.map +1 -0
  209. package/dist/core/common/persistence/unsupported-capability.error.d.ts +3 -0
  210. package/dist/core/common/persistence/unsupported-capability.error.js +4 -0
  211. package/dist/core/common/persistence/unsupported-capability.error.js.map +1 -0
  212. package/dist/core/common/plugins/mongoose-audit-fields.plugin.js +24 -68
  213. package/dist/core/common/plugins/mongoose-audit-fields.plugin.js.map +1 -1
  214. package/dist/core/common/plugins/mongoose-id.plugin.js +3 -0
  215. package/dist/core/common/plugins/mongoose-id.plugin.js.map +1 -1
  216. package/dist/core/common/plugins/mongoose-password.plugin.d.ts +1 -3
  217. package/dist/core/common/plugins/mongoose-password.plugin.js +2 -45
  218. package/dist/core/common/plugins/mongoose-password.plugin.js.map +1 -1
  219. package/dist/core/common/plugins/mongoose-role-guard.plugin.js +5 -46
  220. package/dist/core/common/plugins/mongoose-role-guard.plugin.js.map +1 -1
  221. package/dist/core/common/plugins/mongoose-system-role.plugin.js +2 -43
  222. package/dist/core/common/plugins/mongoose-system-role.plugin.js.map +1 -1
  223. package/dist/core/common/plugins/mongoose-tenant.plugin.js +10 -70
  224. package/dist/core/common/plugins/mongoose-tenant.plugin.js.map +1 -1
  225. package/dist/core/common/scalars/upload.scalar.js +1 -1
  226. package/dist/core/common/scalars/upload.scalar.js.map +1 -1
  227. package/dist/core/common/services/core-cron-jobs.initializer.js +1 -1
  228. package/dist/core/common/services/core-cron-jobs.initializer.js.map +1 -1
  229. package/dist/core/common/services/core-cron-jobs.service.d.ts +1 -0
  230. package/dist/core/common/services/core-cron-jobs.service.js +23 -14
  231. package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
  232. package/dist/core/common/services/crud.service.d.ts +4 -1
  233. package/dist/core/common/services/crud.service.js +132 -23
  234. package/dist/core/common/services/crud.service.js.map +1 -1
  235. package/dist/core/common/services/model-doc.service.js +1 -1
  236. package/dist/core/common/services/model-doc.service.js.map +1 -1
  237. package/dist/core/common/services/module.service.d.ts +9 -2
  238. package/dist/core/common/services/module.service.js +51 -6
  239. package/dist/core/common/services/module.service.js.map +1 -1
  240. package/dist/core/common/types/field-selection.type.d.ts +1 -1
  241. package/dist/core/common/types/id.type.d.ts +4 -4
  242. package/dist/core/common/types/object-id-like.type.d.ts +3 -0
  243. package/dist/core/common/types/object-id-like.type.js +2 -0
  244. package/dist/core/common/types/object-id-like.type.js.map +1 -0
  245. package/dist/core/common/types/populate-config.type.d.ts +1 -1
  246. package/dist/core/common/types/string-or-object-id.type.d.ts +2 -2
  247. package/dist/core/modules/ai/core-ai.constants.d.ts +4 -0
  248. package/dist/core/modules/ai/core-ai.constants.js +4 -0
  249. package/dist/core/modules/ai/core-ai.constants.js.map +1 -1
  250. package/dist/core/modules/ai/core-ai.module.js +21 -17
  251. package/dist/core/modules/ai/core-ai.module.js.map +1 -1
  252. package/dist/core/modules/ai/models/core-ai-budget-limit.model.d.ts +2 -92
  253. package/dist/core/modules/ai/models/core-ai-budget-limit.model.js +1 -1
  254. package/dist/core/modules/ai/models/core-ai-budget-limit.model.js.map +1 -1
  255. package/dist/core/modules/ai/models/core-ai-connection-preference.model.d.ts +2 -87
  256. package/dist/core/modules/ai/models/core-ai-connection-preference.model.js +1 -1
  257. package/dist/core/modules/ai/models/core-ai-connection-preference.model.js.map +1 -1
  258. package/dist/core/modules/ai/models/core-ai-connection.model.d.ts +2 -177
  259. package/dist/core/modules/ai/models/core-ai-connection.model.js +1 -1
  260. package/dist/core/modules/ai/models/core-ai-connection.model.js.map +1 -1
  261. package/dist/core/modules/ai/models/core-ai-conversation.model.d.ts +2 -92
  262. package/dist/core/modules/ai/models/core-ai-conversation.model.js +3 -4
  263. package/dist/core/modules/ai/models/core-ai-conversation.model.js.map +1 -1
  264. package/dist/core/modules/ai/models/core-ai-interaction.model.d.ts +2 -120
  265. package/dist/core/modules/ai/models/core-ai-interaction.model.js +2 -3
  266. package/dist/core/modules/ai/models/core-ai-interaction.model.js.map +1 -1
  267. package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.d.ts +3 -0
  268. package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js +21 -0
  269. package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js.map +1 -0
  270. package/dist/core/modules/ai/models/core-ai-mode.model.d.ts +2 -102
  271. package/dist/core/modules/ai/models/core-ai-mode.model.js +1 -1
  272. package/dist/core/modules/ai/models/core-ai-mode.model.js.map +1 -1
  273. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.d.ts +2 -97
  274. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js +1 -1
  275. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js.map +1 -1
  276. package/dist/core/modules/ai/models/core-ai-prompt.model.d.ts +2 -112
  277. package/dist/core/modules/ai/models/core-ai-prompt.model.js +1 -1
  278. package/dist/core/modules/ai/models/core-ai-prompt.model.js.map +1 -1
  279. package/dist/core/modules/ai/models/core-ai-slot.model.d.ts +2 -112
  280. package/dist/core/modules/ai/models/core-ai-slot.model.js +1 -1
  281. package/dist/core/modules/ai/models/core-ai-slot.model.js.map +1 -1
  282. package/dist/core/modules/ai/models/core-ai-tool-grant.model.d.ts +2 -97
  283. package/dist/core/modules/ai/models/core-ai-tool-grant.model.js +1 -1
  284. package/dist/core/modules/ai/models/core-ai-tool-grant.model.js.map +1 -1
  285. package/dist/core/modules/ai/models/core-ai-tool-policy.model.d.ts +2 -103
  286. package/dist/core/modules/ai/models/core-ai-tool-policy.model.js +1 -1
  287. package/dist/core/modules/ai/models/core-ai-tool-policy.model.js.map +1 -1
  288. package/dist/core/modules/ai/services/core-ai-budget.service.d.ts +3 -1
  289. package/dist/core/modules/ai/services/core-ai-budget.service.js +15 -5
  290. package/dist/core/modules/ai/services/core-ai-budget.service.js.map +1 -1
  291. package/dist/core/modules/ai/services/core-ai-connection-preference.service.d.ts +1 -1
  292. package/dist/core/modules/ai/services/core-ai-connection-preference.service.js +6 -10
  293. package/dist/core/modules/ai/services/core-ai-connection-preference.service.js.map +1 -1
  294. package/dist/core/modules/ai/services/core-ai-connection.service.d.ts +1 -1
  295. package/dist/core/modules/ai/services/core-ai-connection.service.js +20 -42
  296. package/dist/core/modules/ai/services/core-ai-connection.service.js.map +1 -1
  297. package/dist/core/modules/ai/services/core-ai-conversation.service.d.ts +1 -1
  298. package/dist/core/modules/ai/services/core-ai-conversation.service.js +28 -29
  299. package/dist/core/modules/ai/services/core-ai-conversation.service.js.map +1 -1
  300. package/dist/core/modules/ai/services/core-ai-interaction.service.d.ts +1 -1
  301. package/dist/core/modules/ai/services/core-ai-interaction.service.js +3 -4
  302. package/dist/core/modules/ai/services/core-ai-interaction.service.js.map +1 -1
  303. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.d.ts +8 -0
  304. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js +70 -18
  305. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js.map +1 -1
  306. package/dist/core/modules/ai/services/core-ai-mode.service.d.ts +1 -1
  307. package/dist/core/modules/ai/services/core-ai-mode.service.js +3 -7
  308. package/dist/core/modules/ai/services/core-ai-mode.service.js.map +1 -1
  309. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.d.ts +8 -1
  310. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js +32 -26
  311. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js.map +1 -1
  312. package/dist/core/modules/ai/services/core-ai-prompt.service.d.ts +1 -1
  313. package/dist/core/modules/ai/services/core-ai-prompt.service.js +10 -13
  314. package/dist/core/modules/ai/services/core-ai-prompt.service.js.map +1 -1
  315. package/dist/core/modules/ai/services/core-ai-slot.service.d.ts +1 -1
  316. package/dist/core/modules/ai/services/core-ai-slot.service.js +14 -25
  317. package/dist/core/modules/ai/services/core-ai-slot.service.js.map +1 -1
  318. package/dist/core/modules/ai/services/core-ai-tool-grant.service.d.ts +1 -1
  319. package/dist/core/modules/ai/services/core-ai-tool-grant.service.js +6 -18
  320. package/dist/core/modules/ai/services/core-ai-tool-grant.service.js.map +1 -1
  321. package/dist/core/modules/ai/services/core-ai-tool-policy.service.d.ts +1 -1
  322. package/dist/core/modules/ai/services/core-ai-tool-policy.service.js +4 -8
  323. package/dist/core/modules/ai/services/core-ai-tool-policy.service.js.map +1 -1
  324. package/dist/core/modules/api-token/core-api-token.model.js +1 -1
  325. package/dist/core/modules/api-token/core-api-token.model.js.map +1 -1
  326. package/dist/core/modules/api-token/core-api-token.module.js +3 -2
  327. package/dist/core/modules/api-token/core-api-token.module.js.map +1 -1
  328. package/dist/core/modules/api-token/core-api-token.service.d.ts +8 -2
  329. package/dist/core/modules/api-token/core-api-token.service.js +106 -39
  330. package/dist/core/modules/api-token/core-api-token.service.js.map +1 -1
  331. package/dist/core/modules/auth/core-auth.module.js +2 -0
  332. package/dist/core/modules/auth/core-auth.module.js.map +1 -1
  333. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +1 -2
  334. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -1
  335. package/dist/core/modules/auth/guards/role-guard.token.d.ts +1 -0
  336. package/dist/core/modules/auth/guards/role-guard.token.js +2 -0
  337. package/dist/core/modules/auth/guards/role-guard.token.js.map +1 -0
  338. package/dist/core/modules/auth/services/core-auth.service.js +4 -2
  339. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  340. package/dist/core/modules/better-auth/better-auth-sql.helper.d.ts +6 -0
  341. package/dist/core/modules/better-auth/better-auth-sql.helper.js +113 -0
  342. package/dist/core/modules/better-auth/better-auth-sql.helper.js.map +1 -0
  343. package/dist/core/modules/better-auth/better-auth-token.service.d.ts +3 -1
  344. package/dist/core/modules/better-auth/better-auth-token.service.js +15 -24
  345. package/dist/core/modules/better-auth/better-auth-token.service.js.map +1 -1
  346. package/dist/core/modules/better-auth/better-auth.config.d.ts +7 -0
  347. package/dist/core/modules/better-auth/better-auth.config.js +16 -5
  348. package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
  349. package/dist/core/modules/better-auth/better-auth.types.d.ts +1 -1
  350. package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +1 -0
  351. package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +6 -1
  352. package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
  353. package/dist/core/modules/better-auth/core-better-auth-challenge.service.js +30 -15
  354. package/dist/core/modules/better-auth/core-better-auth-challenge.service.js.map +1 -1
  355. package/dist/core/modules/better-auth/core-better-auth-mongo.users.d.ts +10 -0
  356. package/dist/core/modules/better-auth/core-better-auth-mongo.users.js +24 -0
  357. package/dist/core/modules/better-auth/core-better-auth-mongo.users.js.map +1 -0
  358. package/dist/core/modules/better-auth/core-better-auth-sql.registry.d.ts +3 -0
  359. package/dist/core/modules/better-auth/core-better-auth-sql.registry.js +8 -0
  360. package/dist/core/modules/better-auth/core-better-auth-sql.registry.js.map +1 -0
  361. package/dist/core/modules/better-auth/core-better-auth-sql.store.d.ts +71 -0
  362. package/dist/core/modules/better-auth/core-better-auth-sql.store.js +190 -0
  363. package/dist/core/modules/better-auth/core-better-auth-sql.store.js.map +1 -0
  364. package/dist/core/modules/better-auth/core-better-auth-user.mapper.d.ts +24 -1
  365. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +308 -32
  366. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
  367. package/dist/core/modules/better-auth/core-better-auth.module.d.ts +2 -0
  368. package/dist/core/modules/better-auth/core-better-auth.module.js +54 -32
  369. package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
  370. package/dist/core/modules/better-auth/core-better-auth.service.d.ts +7 -2
  371. package/dist/core/modules/better-auth/core-better-auth.service.js +61 -9
  372. package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
  373. package/dist/core/modules/file/core-file-info.model.d.ts +1 -2
  374. package/dist/core/modules/file/core-file-info.model.js +2 -2
  375. package/dist/core/modules/file/core-file-info.model.js.map +1 -1
  376. package/dist/core/modules/file/core-file.service.d.ts +5 -3
  377. package/dist/core/modules/file/core-file.service.js +16 -9
  378. package/dist/core/modules/file/core-file.service.js.map +1 -1
  379. package/dist/core/modules/file/file-metadata.helper.d.ts +1 -1
  380. package/dist/core/modules/file/file-metadata.helper.js +2 -2
  381. package/dist/core/modules/file/file-metadata.helper.js.map +1 -1
  382. package/dist/core/modules/file/file-metadata.models.d.ts +35 -0
  383. package/dist/core/modules/file/file-metadata.models.js +20 -0
  384. package/dist/core/modules/file/file-metadata.models.js.map +1 -0
  385. package/dist/core/modules/file/file-metadata.store.d.ts +6 -0
  386. package/dist/core/modules/file/file-metadata.store.js +77 -0
  387. package/dist/core/modules/file/file-metadata.store.js.map +1 -0
  388. package/dist/core/modules/file/file-storage.helper.d.ts +1 -0
  389. package/dist/core/modules/file/file-storage.helper.js +34 -0
  390. package/dist/core/modules/file/file-storage.helper.js.map +1 -1
  391. package/dist/core/modules/file/filesystem-file.helper.d.ts +1 -1
  392. package/dist/core/modules/file/filesystem-file.helper.js +4 -4
  393. package/dist/core/modules/file/filesystem-file.helper.js.map +1 -1
  394. package/dist/core/modules/file/s3-file.helper.d.ts +1 -1
  395. package/dist/core/modules/file/s3-file.helper.js +5 -5
  396. package/dist/core/modules/file/s3-file.helper.js.map +1 -1
  397. package/dist/core/modules/health-check/core-health-check.module.js +12 -2
  398. package/dist/core/modules/health-check/core-health-check.module.js.map +1 -1
  399. package/dist/core/modules/health-check/core-health-check.service.d.ts +4 -3
  400. package/dist/core/modules/health-check/core-health-check.service.js +26 -5
  401. package/dist/core/modules/health-check/core-health-check.service.js.map +1 -1
  402. package/dist/core/modules/hub/core-hub.controller.d.ts +1 -0
  403. package/dist/core/modules/hub/core-hub.controller.js +10 -0
  404. package/dist/core/modules/hub/core-hub.controller.js.map +1 -1
  405. package/dist/core/modules/hub/core-hub.service.js +1 -1
  406. package/dist/core/modules/hub/core-hub.service.js.map +1 -1
  407. package/dist/core/modules/hub/helpers/hub-client-js.helper.js +23 -0
  408. package/dist/core/modules/hub/helpers/hub-client-js.helper.js.map +1 -1
  409. package/dist/core/modules/hub/hub-action-messages.d.ts +2 -0
  410. package/dist/core/modules/hub/hub-action-messages.js +2 -0
  411. package/dist/core/modules/hub/hub-action-messages.js.map +1 -1
  412. package/dist/core/modules/hub/hub-nav.js +1 -0
  413. package/dist/core/modules/hub/hub-nav.js.map +1 -1
  414. package/dist/core/modules/hub/interfaces/hub-panels.interface.d.ts +17 -1
  415. package/dist/core/modules/hub/services/core-hub-db.service.d.ts +6 -1
  416. package/dist/core/modules/hub/services/core-hub-db.service.js +16 -14
  417. package/dist/core/modules/hub/services/core-hub-db.service.js.map +1 -1
  418. package/dist/core/modules/hub/services/core-hub-migrations.service.d.ts +5 -0
  419. package/dist/core/modules/hub/services/core-hub-migrations.service.js +74 -1
  420. package/dist/core/modules/hub/services/core-hub-migrations.service.js.map +1 -1
  421. package/dist/core/modules/hub/services/core-hub-sources.service.d.ts +2 -1
  422. package/dist/core/modules/hub/services/core-hub-sources.service.js +32 -0
  423. package/dist/core/modules/hub/services/core-hub-sources.service.js.map +1 -1
  424. package/dist/core/modules/hub/services/hub-query-profiler.service.js +1 -1
  425. package/dist/core/modules/hub/services/hub-query-profiler.service.js.map +1 -1
  426. package/dist/core/modules/migrate/cli/migrate-cli.d.ts +2 -0
  427. package/dist/core/modules/migrate/cli/migrate-cli.js +35 -1
  428. package/dist/core/modules/migrate/cli/migrate-cli.js.map +1 -1
  429. package/dist/core/modules/migrate/index.d.ts +3 -0
  430. package/dist/core/modules/migrate/index.js +3 -0
  431. package/dist/core/modules/migrate/index.js.map +1 -1
  432. package/dist/core/modules/migrate/migration-runner.d.ts +2 -2
  433. package/dist/core/modules/migrate/migration-runner.js.map +1 -1
  434. package/dist/core/modules/migrate/migration-state-store.interface.d.ts +16 -0
  435. package/dist/core/modules/migrate/migration-state-store.interface.js +2 -0
  436. package/dist/core/modules/migrate/migration-state-store.interface.js.map +1 -0
  437. package/dist/core/modules/migrate/migration.helper.d.ts +3 -2
  438. package/dist/core/modules/migrate/migration.helper.js +21 -6
  439. package/dist/core/modules/migrate/migration.helper.js.map +1 -1
  440. package/dist/core/modules/migrate/mongo-state-store.d.ts +5 -12
  441. package/dist/core/modules/migrate/mongo-state-store.js +30 -24
  442. package/dist/core/modules/migrate/mongo-state-store.js.map +1 -1
  443. package/dist/core/modules/migrate/sql-migration.helper.d.ts +4 -0
  444. package/dist/core/modules/migrate/sql-migration.helper.js +34 -0
  445. package/dist/core/modules/migrate/sql-migration.helper.js.map +1 -0
  446. package/dist/core/modules/migrate/sql-state-store.d.ts +24 -0
  447. package/dist/core/modules/migrate/sql-state-store.js +129 -0
  448. package/dist/core/modules/migrate/sql-state-store.js.map +1 -0
  449. package/dist/core/modules/system-setup/core-system-setup.service.d.ts +8 -0
  450. package/dist/core/modules/system-setup/core-system-setup.service.js +41 -25
  451. package/dist/core/modules/system-setup/core-system-setup.service.js.map +1 -1
  452. package/dist/core/modules/tenant/core-tenant-member.model.js +1 -1
  453. package/dist/core/modules/tenant/core-tenant-member.model.js.map +1 -1
  454. package/dist/core/modules/tenant/core-tenant-member.store.d.ts +2 -0
  455. package/dist/core/modules/tenant/core-tenant-member.store.js +6 -0
  456. package/dist/core/modules/tenant/core-tenant-member.store.js.map +1 -0
  457. package/dist/core/modules/tenant/core-tenant.guard.d.ts +8 -3
  458. package/dist/core/modules/tenant/core-tenant.guard.js +57 -28
  459. package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
  460. package/dist/core/modules/tenant/core-tenant.module.js +3 -2
  461. package/dist/core/modules/tenant/core-tenant.module.js.map +1 -1
  462. package/dist/core/modules/tenant/core-tenant.service.d.ts +3 -1
  463. package/dist/core/modules/tenant/core-tenant.service.js +48 -28
  464. package/dist/core/modules/tenant/core-tenant.service.js.map +1 -1
  465. package/dist/core/modules/tus/core-tus.service.d.ts +1 -1
  466. package/dist/core/modules/tus/core-tus.service.js +8 -7
  467. package/dist/core/modules/tus/core-tus.service.js.map +1 -1
  468. package/dist/core/modules/tus/tus.module.js +1 -1
  469. package/dist/core/modules/tus/tus.module.js.map +1 -1
  470. package/dist/core/modules/user/core-user.model.d.ts +1 -1
  471. package/dist/core/modules/user/core-user.model.js +1 -1
  472. package/dist/core/modules/user/core-user.model.js.map +1 -1
  473. package/dist/core/modules/user/core-user.service.d.ts +3 -1
  474. package/dist/core/modules/user/core-user.service.js +71 -16
  475. package/dist/core/modules/user/core-user.service.js.map +1 -1
  476. package/dist/core.module.js +39 -5
  477. package/dist/core.module.js.map +1 -1
  478. package/dist/index.d.ts +26 -0
  479. package/dist/index.js +26 -0
  480. package/dist/index.js.map +1 -1
  481. package/dist/server/common/models/persistence.model.d.ts +1 -1
  482. package/dist/server/common/models/persistence.model.js +3 -3
  483. package/dist/server/common/models/persistence.model.js.map +1 -1
  484. package/dist/server/modules/file/file-info.model.d.ts +1 -77
  485. package/dist/server/modules/file/file-info.model.js +1 -1
  486. package/dist/server/modules/file/file-info.model.js.map +1 -1
  487. package/dist/server/modules/file/file.service.js +1 -1
  488. package/dist/server/modules/file/file.service.js.map +1 -1
  489. package/dist/server/modules/user/user.model.d.ts +2 -186
  490. package/dist/server/modules/user/user.model.js +4 -5
  491. package/dist/server/modules/user/user.model.js.map +1 -1
  492. package/dist/server/modules/user/user.module.js +4 -3
  493. package/dist/server/modules/user/user.module.js.map +1 -1
  494. package/dist/server/modules/user/user.service.d.ts +1 -1
  495. package/dist/server/modules/user/user.service.js +5 -8
  496. package/dist/server/modules/user/user.service.js.map +1 -1
  497. package/dist/test/test.helper.js +2 -2
  498. package/dist/test/test.helper.js.map +1 -1
  499. package/dist/types/graphql-upload.d.ts +10 -7
  500. package/docs/REQUEST-LIFECYCLE.md +6 -3
  501. package/docs/choosing-a-database.md +107 -0
  502. package/docs/native-driver-security.md +29 -0
  503. package/docs/security-overrides.md +15 -6
  504. package/migration-guides/12.0.x-to-12.1.x.md +255 -0
  505. package/package.json +75 -29
  506. package/src/core/common/decorators/unified-field.decorator.ts +11 -1
  507. package/src/core/common/filters/mongoose-cast-error.filter.ts +12 -6
  508. package/src/core/common/helpers/db.helper.ts +40 -25
  509. package/src/core/common/helpers/decorator.helper.ts +1 -1
  510. package/src/core/common/helpers/filter.helper.ts +2 -1
  511. package/src/core/common/helpers/gridfs.helper.ts +28 -9
  512. package/src/core/common/helpers/id.helper.ts +21 -4
  513. package/src/core/common/helpers/model.helper.ts +5 -6
  514. package/src/core/common/helpers/service.helper.ts +3 -3
  515. package/src/core/common/interfaces/server-options.interface.ts +118 -10
  516. package/src/core/common/interfaces/service-options.interface.ts +2 -2
  517. package/src/core/common/models/core-persistence.model.ts +3 -3
  518. package/src/core/common/persistence/core-persistence.lifecycle.ts +47 -0
  519. package/src/core/common/persistence/core-persistence.module.ts +109 -0
  520. package/src/core/common/persistence/data-source.config.ts +271 -0
  521. package/src/core/common/persistence/data-source.runtime.ts +351 -0
  522. package/src/core/common/persistence/data-store.interface.ts +155 -0
  523. package/src/core/common/persistence/expiry-sweep.ts +105 -0
  524. package/src/core/common/persistence/id-format.ts +43 -0
  525. package/src/core/common/persistence/infrastructure-locks.ts +66 -0
  526. package/src/core/common/persistence/inject-store.decorator.ts +16 -0
  527. package/src/core/common/persistence/lock-store.interface.ts +17 -0
  528. package/src/core/common/persistence/model-descriptor.interface.ts +90 -0
  529. package/src/core/common/persistence/model-metadata.registry.ts +285 -0
  530. package/src/core/common/persistence/mongo/collection-name.ts +87 -0
  531. package/src/core/common/persistence/mongo/declared-schema.view.ts +378 -0
  532. package/src/core/common/persistence/mongo/hex-object-id.ts +75 -0
  533. package/src/core/common/persistence/mongo/model-declarations.ts +135 -0
  534. package/src/core/common/persistence/mongo/mongo-packages.ts +130 -0
  535. package/src/core/common/persistence/mongo/mongoose-compat.ts +129 -0
  536. package/src/core/common/persistence/mongo/no-mongo-connection.module.ts +18 -0
  537. package/src/core/common/persistence/mongo-lock-store.ts +121 -0
  538. package/src/core/common/persistence/mongoose-data-store.ts +232 -0
  539. package/src/core/common/persistence/neutral-populate.ts +98 -0
  540. package/src/core/common/persistence/persisted-model.decorator.ts +61 -0
  541. package/src/core/common/persistence/persistence-runtime.registry.ts +152 -0
  542. package/src/core/common/persistence/persistence.tokens.ts +9 -0
  543. package/src/core/common/persistence/policies/audit.policy.ts +80 -0
  544. package/src/core/common/persistence/policies/password.policy.ts +69 -0
  545. package/src/core/common/persistence/policies/role-guard.policy.ts +74 -0
  546. package/src/core/common/persistence/policies/system-role.policy.ts +90 -0
  547. package/src/core/common/persistence/policies/tenant.policy.ts +245 -0
  548. package/src/core/common/persistence/routed-model.guard.ts +107 -0
  549. package/src/core/common/persistence/sql/mysql/mysql-data-store.ts +503 -0
  550. package/src/core/common/persistence/sql/mysql/mysql-executor.ts +281 -0
  551. package/src/core/common/persistence/sql/mysql/mysql-lock-store.ts +87 -0
  552. package/src/core/common/persistence/sql/mysql/mysql-schema.compiler.ts +424 -0
  553. package/src/core/common/persistence/sql/mysql/mysql-schema.migrator.ts +453 -0
  554. package/src/core/common/persistence/sql/mysql/mysql-session.ts +131 -0
  555. package/src/core/common/persistence/sql/mysql/mysql-update.compiler.ts +379 -0
  556. package/src/core/common/persistence/sql/mysql/mysql-where.compiler.ts +686 -0
  557. package/src/core/common/persistence/sql/postgres/postgres-lock-store.ts +76 -0
  558. package/src/core/common/persistence/sql/postgres/postgres-schema.compiler.ts +328 -0
  559. package/src/core/common/persistence/sql/postgres/postgres-schema.migrator.ts +448 -0
  560. package/src/core/common/persistence/sql/postgres/postgres-update.compiler.ts +310 -0
  561. package/src/core/common/persistence/sql/postgres/postgres-where.compiler.ts +638 -0
  562. package/src/core/common/persistence/sql/sql-cast.ts +227 -0
  563. package/src/core/common/persistence/sql/sql-data-store.ts +762 -0
  564. package/src/core/common/persistence/sql/sql-dialect.ts +85 -0
  565. package/src/core/common/persistence/sql/sql-errors.ts +49 -0
  566. package/src/core/common/persistence/sql/sql-executor.factory.ts +282 -0
  567. package/src/core/common/persistence/sql/sql-executor.interface.ts +57 -0
  568. package/src/core/common/persistence/sql/sql-naming.ts +133 -0
  569. package/src/core/common/persistence/sql/sql-schema.shared.ts +105 -0
  570. package/src/core/common/persistence/sql/sql-session.ts +158 -0
  571. package/src/core/common/persistence/sql/where-shared.ts +118 -0
  572. package/src/core/common/persistence/store-guards.ts +73 -0
  573. package/src/core/common/persistence/store-upsert.ts +36 -0
  574. package/src/core/common/persistence/unavailable-store.ts +63 -0
  575. package/src/core/common/persistence/unsupported-capability.error.ts +7 -0
  576. package/src/core/common/plugins/mongoose-audit-fields.plugin.ts +33 -74
  577. package/src/core/common/plugins/mongoose-id.plugin.ts +9 -0
  578. package/src/core/common/plugins/mongoose-password.plugin.ts +6 -62
  579. package/src/core/common/plugins/mongoose-role-guard.plugin.ts +11 -63
  580. package/src/core/common/plugins/mongoose-system-role.plugin.ts +7 -78
  581. package/src/core/common/plugins/mongoose-tenant.plugin.ts +23 -144
  582. package/src/core/common/scalars/upload.scalar.ts +8 -3
  583. package/src/core/common/services/core-cron-jobs.initializer.ts +1 -1
  584. package/src/core/common/services/core-cron-jobs.service.ts +33 -22
  585. package/src/core/common/services/crud.service.ts +166 -35
  586. package/src/core/common/services/model-doc.service.ts +1 -1
  587. package/src/core/common/services/module.service.ts +78 -6
  588. package/src/core/common/types/field-selection.type.ts +1 -1
  589. package/src/core/common/types/id.type.ts +2 -2
  590. package/src/core/common/types/object-id-like.type.ts +11 -0
  591. package/src/core/common/types/populate-config.type.ts +1 -1
  592. package/src/core/common/types/string-or-object-id.type.ts +2 -2
  593. package/src/core/modules/ai/README.md +15 -2
  594. package/src/core/modules/ai/core-ai.constants.ts +10 -0
  595. package/src/core/modules/ai/core-ai.module.ts +32 -17
  596. package/src/core/modules/ai/models/core-ai-budget-limit.model.ts +2 -2
  597. package/src/core/modules/ai/models/core-ai-connection-preference.model.ts +2 -2
  598. package/src/core/modules/ai/models/core-ai-connection.model.ts +2 -2
  599. package/src/core/modules/ai/models/core-ai-conversation.model.ts +8 -4
  600. package/src/core/modules/ai/models/core-ai-interaction.model.ts +3 -3
  601. package/src/core/modules/ai/models/core-ai-mcp-oauth.models.ts +46 -0
  602. package/src/core/modules/ai/models/core-ai-mode.model.ts +2 -2
  603. package/src/core/modules/ai/models/core-ai-prompt-hint.model.ts +2 -2
  604. package/src/core/modules/ai/models/core-ai-prompt.model.ts +2 -2
  605. package/src/core/modules/ai/models/core-ai-slot.model.ts +2 -2
  606. package/src/core/modules/ai/models/core-ai-tool-grant.model.ts +2 -2
  607. package/src/core/modules/ai/models/core-ai-tool-policy.model.ts +2 -2
  608. package/src/core/modules/ai/services/core-ai-budget.service.ts +22 -4
  609. package/src/core/modules/ai/services/core-ai-connection-preference.service.ts +6 -13
  610. package/src/core/modules/ai/services/core-ai-connection.service.ts +34 -44
  611. package/src/core/modules/ai/services/core-ai-conversation.service.ts +31 -29
  612. package/src/core/modules/ai/services/core-ai-interaction.service.ts +3 -3
  613. package/src/core/modules/ai/services/core-ai-mcp-oauth.service.ts +93 -20
  614. package/src/core/modules/ai/services/core-ai-mode.service.ts +3 -6
  615. package/src/core/modules/ai/services/core-ai-prompt-hint.service.ts +43 -26
  616. package/src/core/modules/ai/services/core-ai-prompt.service.ts +15 -12
  617. package/src/core/modules/ai/services/core-ai-slot.service.ts +20 -24
  618. package/src/core/modules/ai/services/core-ai-tool-grant.service.ts +17 -27
  619. package/src/core/modules/ai/services/core-ai-tool-policy.service.ts +7 -10
  620. package/src/core/modules/api-token/core-api-token.model.ts +1 -1
  621. package/src/core/modules/api-token/core-api-token.module.ts +4 -2
  622. package/src/core/modules/api-token/core-api-token.service.ts +118 -43
  623. package/src/core/modules/auth/core-auth.module.ts +2 -0
  624. package/src/core/modules/auth/guards/legacy-auth-rate-limit.guard.ts +4 -3
  625. package/src/core/modules/auth/guards/role-guard.token.ts +7 -0
  626. package/src/core/modules/auth/services/core-auth.service.ts +16 -2
  627. package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +1 -1
  628. package/src/core/modules/better-auth/README.md +10 -1
  629. package/src/core/modules/better-auth/better-auth-sql.helper.ts +191 -0
  630. package/src/core/modules/better-auth/better-auth-token.service.ts +26 -35
  631. package/src/core/modules/better-auth/better-auth.config.ts +43 -7
  632. package/src/core/modules/better-auth/better-auth.types.ts +1 -1
  633. package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +13 -1
  634. package/src/core/modules/better-auth/core-better-auth-challenge.service.ts +36 -18
  635. package/src/core/modules/better-auth/core-better-auth-mongo.users.ts +35 -0
  636. package/src/core/modules/better-auth/core-better-auth-sql.registry.ts +20 -0
  637. package/src/core/modules/better-auth/core-better-auth-sql.store.ts +309 -0
  638. package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +418 -40
  639. package/src/core/modules/better-auth/core-better-auth.module.ts +71 -35
  640. package/src/core/modules/better-auth/core-better-auth.service.ts +81 -12
  641. package/src/core/modules/file/README.md +16 -3
  642. package/src/core/modules/file/core-file-info.model.ts +2 -2
  643. package/src/core/modules/file/core-file.service.ts +27 -18
  644. package/src/core/modules/file/file-metadata.helper.ts +7 -3
  645. package/src/core/modules/file/file-metadata.models.ts +44 -0
  646. package/src/core/modules/file/file-metadata.store.ts +109 -0
  647. package/src/core/modules/file/file-storage.helper.ts +47 -2
  648. package/src/core/modules/file/filesystem-file.helper.ts +11 -8
  649. package/src/core/modules/file/s3-file.helper.ts +11 -7
  650. package/src/core/modules/health-check/core-health-check.module.ts +16 -2
  651. package/src/core/modules/health-check/core-health-check.service.ts +25 -3
  652. package/src/core/modules/hub/README.md +20 -11
  653. package/src/core/modules/hub/core-hub.controller.ts +5 -0
  654. package/src/core/modules/hub/core-hub.service.ts +1 -1
  655. package/src/core/modules/hub/helpers/hub-client-js.helper.ts +23 -0
  656. package/src/core/modules/hub/hub-action-messages.ts +6 -0
  657. package/src/core/modules/hub/hub-nav.ts +1 -0
  658. package/src/core/modules/hub/interfaces/hub-panels.interface.ts +8 -1
  659. package/src/core/modules/hub/services/core-hub-db.service.ts +35 -17
  660. package/src/core/modules/hub/services/core-hub-migrations.service.ts +96 -2
  661. package/src/core/modules/hub/services/core-hub-sources.service.ts +47 -1
  662. package/src/core/modules/hub/services/hub-query-profiler.service.ts +1 -1
  663. package/src/core/modules/migrate/README.md +54 -0
  664. package/src/core/modules/migrate/cli/migrate-cli.ts +44 -3
  665. package/src/core/modules/migrate/index.ts +3 -0
  666. package/src/core/modules/migrate/migration-runner.ts +3 -2
  667. package/src/core/modules/migrate/migration-state-store.interface.ts +24 -0
  668. package/src/core/modules/migrate/migration.helper.ts +35 -10
  669. package/src/core/modules/migrate/mongo-state-store.ts +64 -65
  670. package/src/core/modules/migrate/sql-migration.helper.ts +48 -0
  671. package/src/core/modules/migrate/sql-state-store.ts +198 -0
  672. package/src/core/modules/system-setup/README.md +14 -2
  673. package/src/core/modules/system-setup/core-system-setup.service.ts +77 -45
  674. package/src/core/modules/tenant/README.md +9 -2
  675. package/src/core/modules/tenant/core-tenant-member.model.ts +1 -1
  676. package/src/core/modules/tenant/core-tenant-member.store.ts +13 -0
  677. package/src/core/modules/tenant/core-tenant.guard.ts +77 -24
  678. package/src/core/modules/tenant/core-tenant.module.ts +6 -3
  679. package/src/core/modules/tenant/core-tenant.service.ts +59 -42
  680. package/src/core/modules/tus/core-tus.service.ts +11 -12
  681. package/src/core/modules/tus/tus.module.ts +1 -1
  682. package/src/core/modules/user/core-user.model.ts +2 -2
  683. package/src/core/modules/user/core-user.service.ts +98 -20
  684. package/src/core.module.ts +60 -5
  685. package/src/index.ts +26 -0
  686. package/src/server/common/models/persistence.model.ts +4 -4
  687. package/src/server/modules/file/file-info.model.ts +1 -1
  688. package/src/server/modules/file/file.service.ts +1 -1
  689. package/src/server/modules/user/user.model.ts +10 -5
  690. package/src/server/modules/user/user.module.ts +9 -3
  691. package/src/server/modules/user/user.service.ts +9 -11
  692. package/src/test/test.helper.ts +2 -2
  693. package/src/types/graphql-upload.d.ts +10 -7
@@ -1,5 +1,5 @@
1
1
  import type { GraphQLScalarType } from 'graphql';
2
- import GraphQLUploadScalar from 'graphql-upload/GraphQLUpload.js';
2
+ import GraphQLUploadScalar from 'graphql-upload/GraphQLUpload.mjs';
3
3
 
4
4
  /**
5
5
  * The GraphQL `Upload` scalar for multipart file uploads — import it from `@lenne.tech/nest-server`,
@@ -10,8 +10,13 @@ import GraphQLUploadScalar from 'graphql-upload/GraphQLUpload.js';
10
10
  * copy. A resolver that imports the scalar from the project's own graphql-upload therefore works only
11
11
  * while both resolve to the same version; with two copies every upload is refused as invalid. And the
12
12
  * import path itself is not stable across graphql-upload majors (15: `GraphQLUpload.js`, 16+:
13
- * `GraphQLUpload.mjs`). Importing it from here keeps scalar and middleware one copy and leaves the
14
- * path to the framework.
13
+ * `GraphQLUpload.mjs`, the one this package imports since 12.1.0). Importing it from here keeps scalar
14
+ * and middleware one copy and leaves the path to the framework.
15
+ *
16
+ * A default import, never `import = require()` or `import * as`: graphql-upload 16+ is ESM, so under
17
+ * `require(esm)` both of those yield the module NAMESPACE, not the scalar. Compiled to CommonJS, the
18
+ * default import still reaches it — Node marks a required ES module that has a default export with
19
+ * `__esModule`, which the interop helper reads.
15
20
  *
16
21
  * The path is a CONTRACT with the lt CLI: its generator checks whether `common/scalars/upload.scalar` exists in
17
22
  * the framework root (`dist/core/` in npm mode, `src/core/` vendored) and only then writes
@@ -1,5 +1,5 @@
1
1
  import { Injectable, OnApplicationShutdown, OnModuleInit, Optional } from '@nestjs/common';
2
- import { InjectConnection } from '@nestjs/mongoose';
2
+ import { InjectConnection } from '../persistence/mongo/mongoose-compat.js';
3
3
  import type { Connection } from 'mongoose';
4
4
 
5
5
  import { setCronJobsInfrastructure } from './core-cron-jobs.registry.js';
@@ -4,6 +4,7 @@ import { CronJob } from 'cron';
4
4
 
5
5
  import { CronJobConfigWithTimeZone } from '../interfaces/cron-job-config-with-time-zone.interface.js';
6
6
  import { CronJobConfigWithUtcOffset } from '../interfaces/cron-job-config-with-utc-offset.interface.js';
7
+ import { CRON_LOCK_COLLECTION, cronMongoLocks, defaultSqlLockStore } from '../persistence/infrastructure-locks.js';
7
8
  import { Falsy } from '../types/falsy.type.js';
8
9
  import { getCronJobsInfrastructure } from './core-cron-jobs.registry.js';
9
10
 
@@ -21,14 +22,6 @@ const cronLogger = new Logger('CronJobs');
21
22
  const errorMessage = (error: unknown): string => (error instanceof Error ? error.message : String(error));
22
23
  const errorStack = (error: unknown): string | undefined => (error instanceof Error ? error.stack : undefined);
23
24
 
24
- /**
25
- * Collection holding the per-tick cron leases.
26
- *
27
- * It has no Mongoose schema, so the native driver is the correct access path here
28
- * (see docs/native-driver-security.md).
29
- */
30
- const CRON_LOCK_COLLECTION = 'cron-locks';
31
-
32
25
  /**
33
26
  * Lifetime of a cron lease: long enough to outlive any tick, short enough to keep
34
27
  * the lock collection / keyspace small.
@@ -120,6 +113,13 @@ export abstract class CoreCronJobs implements OnApplicationBootstrap, OnApplicat
120
113
  /** Cached creation of the TTL index on the lock collection */
121
114
  protected leaseIndexReady?: Promise<void>;
122
115
 
116
+ /**
117
+ * Owner of the leases this instance takes. Per-tick keys are unique, so the owner only names who ran a tick; the
118
+ * lease collection (`cron-locks`, no Mongoose schema — native access is correct, see
119
+ * docs/native-driver-security.md) keeps the 12.0.0 document so older replicas dedupe against it
120
+ */
121
+ protected readonly leaseOwner = `cron:${process.pid}:${Math.random().toString(36).slice(2)}`;
122
+
123
123
  // ===================================================================================================================
124
124
  // Initializations
125
125
  // ===================================================================================================================
@@ -303,27 +303,38 @@ export abstract class CoreCronJobs implements OnApplicationBootstrap, OnApplicat
303
303
  }
304
304
  }
305
305
 
306
- const connection = this.getConnection();
307
- if (!connection) {
306
+ const sqlLocks = await defaultSqlLockStore('cron').catch((e) => {
307
+ cronLogger.error(`Cron lease store unavailable, running the tick anyway: ${errorMessage(e)}`, errorStack(e));
308
+ return null;
309
+ });
310
+ if (sqlLocks === null) {
311
+ return true;
312
+ }
313
+ const connection = sqlLocks ? undefined : this.getConnection();
314
+ if (!sqlLocks && !connection) {
308
315
  this.warnDedupInactive();
309
316
  return true;
310
317
  }
311
318
 
312
- await this.ensureLeaseIndex(connection);
313
319
  try {
314
- await connection.db.collection(CRON_LOCK_COLLECTION).insertOne({
315
- _id: leaseKey as any,
316
- createdAt: new Date(),
317
- // Per-document expiry, so the short init window and the long tick window can
318
- // share one collection (a fixed expireAfterSeconds could only express one).
319
- expiresAt: new Date(Date.now() + ttlSeconds * 1000),
320
- });
321
- return true;
322
- } catch (e: any) {
323
- if (e?.code === 11000) {
320
+ let acquired: boolean;
321
+ if (sqlLocks) {
322
+ acquired = await sqlLocks.tryAcquire(leaseKey, this.leaseOwner, ttlSeconds);
323
+ } else {
324
+ // The TTL index only collects old leases — for this version and for older replicas, which still claim with a
325
+ // plain insert. Whether a lease is free is decided by its expiresAt (LockStore), never by the TTL monitor.
326
+ await this.ensureLeaseIndex(connection);
327
+ acquired = await cronMongoLocks(connection.db.collection(CRON_LOCK_COLLECTION)).tryAcquire(
328
+ leaseKey,
329
+ this.leaseOwner,
330
+ ttlSeconds,
331
+ );
332
+ }
333
+ if (!acquired) {
324
334
  this.logSkippedTick(leaseKey);
325
- return false;
326
335
  }
336
+ return acquired;
337
+ } catch (e) {
327
338
  cronLogger.error(`Cron lease for ${leaseKey} failed, running the tick anyway: ${errorMessage(e)}`, errorStack(e));
328
339
  return true;
329
340
  }
@@ -1,27 +1,21 @@
1
1
  import { Logger, NotFoundException } from '@nestjs/common';
2
- import {
3
- AggregateOptions,
4
- Collection,
5
- Connection,
6
- Document,
7
- Model as MongooseModel,
8
- PipelineStage,
9
- Query,
10
- QueryFilter,
11
- QueryOptions,
12
- Types,
13
- } from 'mongoose';
2
+ import type { Collection, Document, Model as MongooseModel, PipelineStage, QueryFilter } from 'mongoose';
3
+ import type { Query } from 'mongoose';
4
+ import type { AggregateOptions, Connection, QueryOptions, Types } from 'mongoose';
14
5
 
15
6
  import { FilterArgs } from '../args/filter.args.js';
16
7
  import { getStringIds } from '../helpers/db.helper.js';
17
8
  import { convertFilterArgsToQuery } from '../helpers/filter.helper.js';
18
9
  import { mergePlain, prepareServiceOptionsForCreate } from '../helpers/input.helper.js';
19
10
  import { ServiceOptions } from '../interfaces/service-options.interface.js';
11
+ import type { FindOptions, Where } from '../persistence/data-store.interface.js';
12
+ import { UnsupportedCapabilityError } from '../persistence/unsupported-capability.error.js';
20
13
  import { CoreModel } from '../models/core-model.model.js';
21
14
  import { PaginationInfo } from '../models/pagination-info.model.js';
22
15
  import { PlainObject } from '../types/plain-object.type.js';
23
16
  import { ConfigService } from './config.service.js';
24
17
  import { ModuleService } from './module.service.js';
18
+ import { isMongooseQuery } from '../persistence/mongo/mongoose-compat.js';
25
19
 
26
20
  export abstract class CrudService<
27
21
  Model extends CoreModel = any,
@@ -38,6 +32,7 @@ export abstract class CrudService<
38
32
  pipeline: PipelineStage[],
39
33
  serviceOptions?: ServiceOptions & { aggregateOptions?: AggregateOptions },
40
34
  ): Promise<T> {
35
+ this.assertMongooseStore('aggregate');
41
36
  return this.process(
42
37
  async () => {
43
38
  const aggregateOptions = serviceOptions?.aggregateOptions || {};
@@ -79,6 +74,9 @@ export abstract class CrudService<
79
74
  return this.process(
80
75
  async (data) => {
81
76
  const currentUserId = serviceOptions?.currentUser?.id;
77
+ if (this.usesNeutralStore) {
78
+ return this.dataStore.insert({ ...data.input, createdBy: currentUserId, updatedBy: currentUserId } as any);
79
+ }
82
80
  return new (this.mainDbModel as MongooseModel<Document & Model>)({
83
81
  ...data.input,
84
82
  createdBy: currentUserId,
@@ -113,13 +111,20 @@ export abstract class CrudService<
113
111
  * Get distinct values of a property
114
112
  */
115
113
  distinct(property: string): Promise<string[]> {
116
- return this.mainDbModel.distinct(property).exec() as Promise<string[]>;
114
+ return this.dataStore.distinct(property) as Promise<string[]>;
117
115
  }
118
116
 
119
117
  /**
120
118
  * Get item by ID
121
119
  */
122
120
  async get(id: string, serviceOptions?: ServiceOptions): Promise<Model> {
121
+ if (this.usesNeutralStore) {
122
+ const record = await this.dataStore.findById(id, neutralSelect(serviceOptions?.select));
123
+ if (!record) {
124
+ throw new NotFoundException(`No ${this.mainModelConstructor.name} found with ID: ${id}`);
125
+ }
126
+ return this.process(async () => record, { dbObject: record, serviceOptions });
127
+ }
123
128
  const query = this.mainDbModel.findById(id);
124
129
  if (serviceOptions?.select) {
125
130
  query.select(serviceOptions.select);
@@ -179,6 +184,11 @@ export abstract class CrudService<
179
184
  filterQuery.queryOptions = converted[1];
180
185
  }
181
186
 
187
+ if (this.usesNeutralStore) {
188
+ const { options, where } = neutralQuery(filterQuery, serviceOptions);
189
+ return this.dataStore.find(where, options);
190
+ }
191
+
182
192
  // Find in DB
183
193
  let find = this.mainDbModel.find(filterQuery.filterQuery, null, filterQuery.queryOptions);
184
194
  const collation = serviceOptions?.collation || ConfigService.get('mongoose.collation');
@@ -247,6 +257,26 @@ export abstract class CrudService<
247
257
  filterQuery.queryOptions = converted[1];
248
258
  }
249
259
 
260
+ if (this.usesNeutralStore) {
261
+ const { options, where } = neutralQuery(filterQuery, serviceOptions);
262
+ const [items, totalCount] = await Promise.all([
263
+ this.dataStore.find(where, filter?.samples ? { ...options, sample: filter.samples } : options),
264
+ this.dataStore.count(where),
265
+ ]);
266
+ const queryOptions = filterQuery.queryOptions || {};
267
+ return {
268
+ items,
269
+ pagination: PaginationInfo.create({
270
+ limit: queryOptions.limit,
271
+ offset: queryOptions.offset,
272
+ skip: queryOptions.skip,
273
+ take: queryOptions.take,
274
+ totalCount,
275
+ }),
276
+ totalCount,
277
+ };
278
+ }
279
+
250
280
  // Prepare aggregation (with fixed defined sequence)
251
281
  const aggregation: PipelineStage[] = [];
252
282
 
@@ -408,6 +438,16 @@ export abstract class CrudService<
408
438
  filterQuery.queryOptions = converted[1];
409
439
  }
410
440
 
441
+ if (this.usesNeutralStore) {
442
+ const { options, where } = neutralQuery(filterQuery, serviceOptions);
443
+ return this.dataStore.findOne(where, {
444
+ collation: options.collation,
445
+ exclude: options.exclude,
446
+ select: options.select,
447
+ sort: options.sort,
448
+ });
449
+ }
450
+
411
451
  // Find in DB
412
452
  let find = this.mainDbModel.findOne(filterQuery.filterQuery, null, filterQuery.queryOptions);
413
453
  const collation = serviceOptions?.collation || ConfigService.get('mongoose.collation');
@@ -458,6 +498,7 @@ export abstract class CrudService<
458
498
  * to ensure plugins (Tenant, Audit, RoleGuard) fire correctly.
459
499
  */
460
500
  getModel(): MongooseModel<Document & Model> {
501
+ this.assertMongooseStore('getModel');
461
502
  return this.mainDbModel as unknown as MongooseModel<Document & Model>;
462
503
  }
463
504
 
@@ -481,6 +522,7 @@ export abstract class CrudService<
481
522
  */
482
523
  protected getNativeCollection(reason: string): Collection {
483
524
  this.validateNativeAccessReason(reason, 'getNativeCollection');
525
+ this.assertMongooseStore('getNativeCollection');
484
526
 
485
527
  const modelName = (this.mainDbModel as any)?.modelName || 'Unknown';
486
528
  Logger.warn(`[SECURITY] Native collection access: ${reason} (Model: ${modelName})`, this.constructor.name);
@@ -509,6 +551,7 @@ export abstract class CrudService<
509
551
  */
510
552
  protected getNativeConnection(reason: string): Connection {
511
553
  this.validateNativeAccessReason(reason, 'getNativeConnection');
554
+ this.assertMongooseStore('getNativeConnection');
512
555
 
513
556
  const modelName = (this.mainDbModel as any)?.modelName || 'Unknown';
514
557
  Logger.warn(`[SECURITY] Native connection access: ${reason} (Model: ${modelName})`, this.constructor.name);
@@ -614,6 +657,22 @@ export abstract class CrudService<
614
657
  * Update item via ID
615
658
  */
616
659
  async update(id: string, input: PlainObject<UpdateInput>, serviceOptions?: ServiceOptions): Promise<Model> {
660
+ if (this.usesNeutralStore) {
661
+ const stored = await this.dataStore.findById(id);
662
+ if (!stored) {
663
+ throw new NotFoundException(`No ${this.mainModelConstructor.name} found with ID: ${id}`);
664
+ }
665
+ return this.process(
666
+ async (data) => {
667
+ // The same write as on MongoDB: the stored record merged with the input, written back whole — minus
668
+ // the id, which never changes, and the update time, which the store stamps
669
+ const merged = mergePlain(stored, data.input, { updatedBy: serviceOptions?.currentUser?.id });
670
+ const { _id: _mongoId, id: _id, updatedAt: _updatedAt, ...patch } = merged as Record<string, any>;
671
+ return this.dataStore.updateById(id, patch as any);
672
+ },
673
+ { dbObject: stored, input, serviceOptions },
674
+ );
675
+ }
617
676
  const dbObject = await this.mainDbModel.findById(id).lean();
618
677
  if (!dbObject) {
619
678
  throw new NotFoundException(`No ${this.mainModelConstructor.name} found with ID: ${id}`);
@@ -656,6 +715,19 @@ export abstract class CrudService<
656
715
  * Delete item via ID
657
716
  */
658
717
  async delete(id: string, serviceOptions?: ServiceOptions): Promise<Model> {
718
+ if (this.usesNeutralStore) {
719
+ const stored = await this.dataStore.findById(id, neutralSelect(serviceOptions?.select));
720
+ if (!stored) {
721
+ throw new NotFoundException(`No ${this.mainModelConstructor.name} found with ID: ${id}`);
722
+ }
723
+ return this.process(
724
+ async () => {
725
+ await this.dataStore.deleteById(id);
726
+ return stored;
727
+ },
728
+ { dbObject: stored, serviceOptions },
729
+ );
730
+ }
659
731
  const query = this.mainDbModel.findById(id);
660
732
  if (serviceOptions?.select) {
661
733
  query.select(serviceOptions.select);
@@ -728,22 +800,11 @@ export abstract class CrudService<
728
800
  return;
729
801
  }
730
802
 
731
- const stringId = getStringIds(id);
732
- const pushOp: any = { $each: itemsArray };
733
- if (options?.$slice !== undefined) {
734
- pushOp.$slice = options.$slice;
735
- }
736
- if (options?.$position !== undefined) {
737
- pushOp.$position = options.$position;
738
- }
739
- if (options?.$sort) {
740
- pushOp.$sort = options.$sort;
741
- }
742
-
743
- await this.mainDbModel
744
- .findByIdAndUpdate(stringId, { $push: { [field]: pushOp } } as any)
745
- .lean()
746
- .exec();
803
+ await this.dataStore.pushToArray(getStringIds(id), field, itemsArray, {
804
+ position: options?.$position,
805
+ slice: options?.$slice,
806
+ sort: options?.$sort,
807
+ });
747
808
  }
748
809
 
749
810
  /**
@@ -771,11 +832,7 @@ export abstract class CrudService<
771
832
  throw new Error(`pullFromArray: invalid field name "${field}"`);
772
833
  }
773
834
 
774
- const stringId = getStringIds(id);
775
- await this.mainDbModel
776
- .findByIdAndUpdate(stringId, { $pull: { [field]: condition } } as any)
777
- .lean()
778
- .exec();
835
+ await this.dataStore.pullFromArray(getStringIds(id), field, condition);
779
836
  }
780
837
 
781
838
  /**
@@ -791,7 +848,8 @@ export abstract class CrudService<
791
848
  ): Promise<T> {
792
849
  return this.process(
793
850
  () => {
794
- if (queryOrDocument instanceof Query) {
851
+ if (isMongooseQuery(queryOrDocument)) {
852
+ this.assertMongooseStore('processQueryOrDocument (with a Mongoose query)');
795
853
  if (serviceOptions?.select && queryOrDocument.select && typeof queryOrDocument.select === 'function') {
796
854
  queryOrDocument.select(serviceOptions.select);
797
855
  }
@@ -802,4 +860,77 @@ export abstract class CrudService<
802
860
  { serviceOptions },
803
861
  );
804
862
  }
863
+
864
+ /**
865
+ * Refuse an API that only exists on MongoDB when the main model is stored elsewhere. The Mongoose model may still
866
+ * be registered for such a model, so continuing would read or write ANOTHER database without a word.
867
+ */
868
+ protected assertMongooseStore(method: string): void {
869
+ if (this.usesNeutralStore) {
870
+ throw new UnsupportedCapabilityError(
871
+ `${method}() needs a MongoDB store, but ${this.dataStore.modelName} is stored on ${this.dataStore.driver} — ` +
872
+ 'use this.dataStore (or this.dataStore.native(reason) for the engine API)',
873
+ );
874
+ }
875
+ }
876
+ }
877
+
878
+ /**
879
+ * A `select` service option as a data store's projection: names to return, or — with MongoDB's `-name` — names to leave
880
+ * out. Both at once is refused by the store, as by MongoDB.
881
+ */
882
+ function neutralSelect(select: unknown): Pick<FindOptions, 'exclude' | 'select'> {
883
+ if (select === undefined || select === null) {
884
+ return {};
885
+ }
886
+ const names =
887
+ typeof select === 'string'
888
+ ? select.split(/\s+/).filter(Boolean)
889
+ : Array.isArray(select)
890
+ ? select.map(String)
891
+ : Object.entries(select as Record<string, unknown>).map(([name, include]) => (include ? name : `-${name}`));
892
+ const exclude = names.filter((name) => name.startsWith('-')).map((name) => name.slice(1));
893
+ const include = names.filter((name) => !name.startsWith('-')).map((name) => (name === '_id' ? 'id' : name));
894
+ return {
895
+ ...(exclude.length ? { exclude } : {}),
896
+ ...(include.length ? { select: include } : {}),
897
+ };
898
+ }
899
+
900
+ /** The filter and query options of a CrudService call as the neutral filter and find options */
901
+ function neutralQuery(
902
+ query: { filterQuery?: unknown; queryOptions?: QueryOptions },
903
+ serviceOptions?: ServiceOptions,
904
+ ): { options: FindOptions; where: Where } {
905
+ const queryOptions = query.queryOptions || {};
906
+ const options: FindOptions = {
907
+ collation: (serviceOptions?.collation || ConfigService.get('mongoose.collation')) as Record<string, unknown>,
908
+ ...neutralSelect(serviceOptions?.select),
909
+ };
910
+ const skip = queryOptions.skip ?? queryOptions.offset;
911
+ const limit = queryOptions.limit ?? queryOptions.take;
912
+ if (skip) {
913
+ options.skip = skip;
914
+ }
915
+ if (limit) {
916
+ options.limit = limit;
917
+ }
918
+ if (queryOptions.sort) {
919
+ options.sort = neutralSort(queryOptions.sort);
920
+ }
921
+ return { options, where: (query.filterQuery ?? {}) as Where };
922
+ }
923
+
924
+ function neutralSort(sort: unknown): Record<string, -1 | 1> {
925
+ const result: Record<string, -1 | 1> = {};
926
+ if (typeof sort === 'string') {
927
+ for (const token of sort.split(/\s+/).filter(Boolean)) {
928
+ result[token.replace(/^-/, '')] = token.startsWith('-') ? -1 : 1;
929
+ }
930
+ return result;
931
+ }
932
+ for (const [field, direction] of Object.entries(sort as Record<string, unknown>)) {
933
+ result[field] = direction === -1 || direction === 'desc' || direction === 'descending' ? -1 : 1;
934
+ }
935
+ return result;
805
936
  }
@@ -1,5 +1,5 @@
1
1
  import { Injectable, OnApplicationBootstrap } from '@nestjs/common';
2
- import { InjectConnection } from '@nestjs/mongoose';
2
+ import { InjectConnection } from '../persistence/mongo/mongoose-compat.js';
3
3
  import * as fs from 'fs';
4
4
  import type { Connection } from 'mongoose';
5
5
  import YumlDiagram from 'yuml-diagram';
@@ -1,17 +1,23 @@
1
1
  import _ from 'lodash';
2
- import { Document, Model, Types } from 'mongoose';
2
+ import type { Document, Model } from 'mongoose';
3
+ import type { Types } from 'mongoose';
3
4
 
4
5
  import { ProcessType } from '../enums/process-type.enum.js';
5
- import { getStringIds, popAndMap } from '../helpers/db.helper.js';
6
+ import { getStringIds, popAndMap, toPopulateOptions } from '../helpers/db.helper.js';
6
7
  import { check } from '../helpers/input.helper.js';
7
8
  import { prepareInput, prepareOutput } from '../helpers/service.helper.js';
8
9
  import { getTranslatablePropertyKeys, updateLanguage } from '../decorators/translatable.decorator.js';
9
10
  import { ServiceOptions } from '../interfaces/service-options.interface.js';
10
11
  import { CoreModel } from '../models/core-model.model.js';
12
+ import type { DataStore } from '../persistence/data-store.interface.js';
13
+ import { MongooseDataStore } from '../persistence/mongoose-data-store.js';
14
+ import { populateNeutral } from '../persistence/neutral-populate.js';
15
+ import { getStoreForModel } from '../persistence/persistence-runtime.registry.js';
11
16
  import { FieldSelection } from '../types/field-selection.type.js';
12
17
  import { ConfigService } from './config.service.js';
13
18
  import { ModelRegistry } from './model-registry.service.js';
14
19
  import { RequestContext } from './request-context.service.js';
20
+ import { isObjectIdLike } from '../helpers/id.helper.js';
15
21
 
16
22
  /**
17
23
  * Mongoose Model with native driver access paths removed to prevent
@@ -51,21 +57,76 @@ export abstract class ModuleService<T extends CoreModel = any> {
51
57
  */
52
58
  protected mainDbModel: SafeModel<Document & T>;
53
59
 
60
+ /** Store passed explicitly to the constructor */
61
+ private explicitDataStore?: DataStore<T>;
62
+
63
+ /** Store derived from `mainDbModel`, rebuilt when the model is replaced */
64
+ private derivedDataStore?: { model: unknown; store: DataStore<T> };
65
+
66
+ /**
67
+ * Database-neutral data store of the main model.
68
+ *
69
+ * Derived from `mainDbModel` when none is passed — at access time, not in the constructor, because a
70
+ * subclass may assign `mainDbModel` after `super()`. Operations whose semantics are identical on every
71
+ * database run through it already; the Mongoose-document path of the CRUD pipeline stays behind the
72
+ * store's `mongoosePopulate` capability until a SQL store provides the neutral one.
73
+ */
74
+ protected get dataStore(): DataStore<T> | undefined {
75
+ if (this.explicitDataStore) {
76
+ return this.explicitDataStore;
77
+ }
78
+ if (!this.mainDbModel) {
79
+ return undefined;
80
+ }
81
+ // A model registered with `CorePersistenceModule.forFeature()` is served by the store of its data source — also for
82
+ // a service that only received the Mongoose model, which is how every existing service is written
83
+ const routed = getStoreForModel(this.mainDbModel);
84
+ if (routed) {
85
+ return routed as DataStore<T>;
86
+ }
87
+ if (this.derivedDataStore?.model !== this.mainDbModel) {
88
+ this.derivedDataStore = {
89
+ model: this.mainDbModel,
90
+ store: new MongooseDataStore<T>(this.mainDbModel as unknown as Model<any>),
91
+ };
92
+ }
93
+ return this.derivedDataStore.store;
94
+ }
95
+
96
+ /**
97
+ * Whether the main model is stored without Mongoose documents (a SQL store): the CRUD pipeline then reads and
98
+ * writes plain records through `dataStore` and populates references through the stores of their models.
99
+ */
100
+ protected get usesNeutralStore(): boolean {
101
+ const store = this.dataStore;
102
+ return !!store && !store.capabilities.mongoosePopulate;
103
+ }
104
+
54
105
  /**
55
106
  * Set main properties
56
107
  */
57
108
  protected constructor(options?: {
58
109
  configService?: ConfigService;
110
+ dataStore?: DataStore<T>;
59
111
  mainDbModel?: Model<Document & T>;
60
112
  mainModelConstructor?: new (...args: any[]) => T;
61
113
  }) {
62
114
  this.configService = options?.configService;
63
115
  this.mainDbModel = options?.mainDbModel as SafeModel<Document & T>;
116
+ this.explicitDataStore = options?.dataStore;
117
+ // A service written against the store alone (`@InjectStore()`) runs on MongoDB too: the Mongoose path of the
118
+ // pipeline takes the model behind the store
119
+ if (!this.mainDbModel && options?.dataStore?.capabilities.mongoosePopulate) {
120
+ this.mainDbModel = options.dataStore.native<SafeModel<Document & T>>(
121
+ 'CrudService pipeline: the Mongoose model behind this data store',
122
+ );
123
+ }
64
124
  this.mainModelConstructor = options?.mainModelConstructor;
65
125
 
66
126
  // Auto-register model class for ResponseModelInterceptor lookups
67
- if (options?.mainModelConstructor && options?.mainDbModel?.modelName) {
68
- ModelRegistry.register(options.mainDbModel.modelName, options.mainModelConstructor);
127
+ const modelName = this.mainDbModel?.modelName ?? options?.dataStore?.modelName;
128
+ if (options?.mainModelConstructor && modelName) {
129
+ ModelRegistry.register(modelName, options.mainModelConstructor);
69
130
  }
70
131
  }
71
132
 
@@ -209,8 +270,15 @@ export abstract class ModuleService<T extends CoreModel = any> {
209
270
  // S_CREATOR and S_SELF checks. The full process() pipeline would remove
210
271
  // restricted fields, potentially breaking these checks.
211
272
  if (config.dbObject && config.checkRights && this.checkRights) {
212
- if (typeof config.dbObject === 'string' || config.dbObject instanceof Types.ObjectId) {
213
- if (this.mainDbModel) {
273
+ if (typeof config.dbObject === 'string' || isObjectIdLike(config.dbObject)) {
274
+ if (this.usesNeutralStore) {
275
+ const record = await this.dataStore.findById(getStringIds(config.dbObject));
276
+ if (record) {
277
+ config.dbObject = (this.mainModelConstructor as any)?.map
278
+ ? (this.mainModelConstructor as any).map(record)
279
+ : record;
280
+ }
281
+ } else if (this.mainDbModel) {
214
282
  const rawDoc = await this.mainDbModel.findById(getStringIds(config.dbObject)).lean().exec();
215
283
  if (rawDoc) {
216
284
  config.dbObject = (this.mainModelConstructor as any)?.map
@@ -429,6 +497,10 @@ export abstract class ModuleService<T extends CoreModel = any> {
429
497
  model?: new (...args: any[]) => T;
430
498
  } = {},
431
499
  ) {
500
+ if (this.usesNeutralStore && !options.dbModel) {
501
+ await populateNeutral(data, toPopulateOptions(fieldsSelection) as any, this.dataStore.modelName);
502
+ return data;
503
+ }
432
504
  const config = {
433
505
  dbModel: this.mainDbModel,
434
506
  model: this.mainModelConstructor,
@@ -1,5 +1,5 @@
1
1
  import { SelectionNode } from 'graphql';
2
- import { PopulateOptions } from 'mongoose';
2
+ import type { PopulateOptions } from 'mongoose';
3
3
 
4
4
  import { ResolveSelector } from '../interfaces/resolve-selector.interface.js';
5
5
 
@@ -1,3 +1,3 @@
1
- import { Types } from 'mongoose';
1
+ import type { ObjectIdLike } from './object-id-like.type.js';
2
2
 
3
- export type IdType = string | Types.ObjectId | { _id?: string | Types.ObjectId; id?: string | Types.ObjectId };
3
+ export type IdType = ObjectIdLike | string | { _id?: ObjectIdLike | string; id?: ObjectIdLike | string };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Structural shape of an ObjectId, from whichever bson copy created it.
3
+ *
4
+ * The id types describe ids by shape instead of by `mongoose`'s `Types.ObjectId` class: a class
5
+ * identity breaks across two installed copies of bson (`instanceof` fails), and the id types must not
6
+ * tie the core to the MongoDB driver now that ids are opaque strings on every database. A mongoose
7
+ * `Types.ObjectId` satisfies this shape, so every caller that passed one keeps compiling.
8
+ */
9
+ export interface ObjectIdLike {
10
+ toHexString(): string;
11
+ }
@@ -1,4 +1,4 @@
1
- import { PopulateOptions } from 'mongoose';
1
+ import type { PopulateOptions } from 'mongoose';
2
2
 
3
3
  /**
4
4
  * Configuration (path or options) for Mongoose populate methode
@@ -1,6 +1,6 @@
1
- import { Types } from 'mongoose';
1
+ import type { ObjectIdLike } from './object-id-like.type.js';
2
2
 
3
3
  /**
4
4
  * Everything which will be used by getStringIds or getObjectIds (see helpers/db.helper.ts)
5
5
  */
6
- export type StringOrObjectId<T = any> = string | T | Types.ObjectId;
6
+ export type StringOrObjectId<T = any> = ObjectIdLike | string | T;
@@ -213,6 +213,16 @@ Matching details worth knowing before you debug a refusal:
213
213
  and the framework logs an error — from the outside that state is indistinguishable from
214
214
  "correctly unset", which is exactly why it is not silent.
215
215
 
216
+ ## Where the data lives
217
+
218
+ The module's eleven models (connections, preferences, conversations, interactions, budget limits,
219
+ prompts, prompt hints, slots, modes, tool grants, tool policies) are registered through
220
+ `CorePersistenceModule.forFeature()` and every service works on its model's data store, so `database`
221
+ routes them like any model — MongoDB or a SQL source, one code path. Budget sums run in the store
222
+ (`sum()`), across tenants as before; an expired tool grant is refused on read, and on SQL the expiry
223
+ sweep removes it. Code of your own that reads these models goes through the store
224
+ (`@InjectStore('<model>')`), not through `connection.collection()`.
225
+
216
226
  ## Connections (DB configuration)
217
227
 
218
228
  Connections live in the `aiConnections` collection and are managed by admins via
@@ -690,8 +700,11 @@ Without Redis nothing changes: unknown ids answer `404` exactly as before.
690
700
 
691
701
  For generic MCP clients that auto-discover + register:
692
702
  `CoreAiMcpOAuthService` provides HMAC-signed access tokens (constant-time verify),
693
- PKCE S256, and MongoDB-backed client/code/refresh stores; the MCP controller then
694
- also accepts OAuth access tokens.
703
+ PKCE S256, and client/code/refresh stores; the MCP controller then also accepts OAuth access
704
+ tokens. The stores live wherever `database` routes the models `AiMcpOAuthClient`, `AiMcpOAuthCode`
705
+ and `AiMcpOAuthRefreshToken` (MongoDB collections, or SQL tables). An authorization code is refused
706
+ on read once it is older than ten minutes, on both databases — never only by a TTL index, which
707
+ deletes late; on SQL the expiry sweep removes old codes, on MongoDB the TTL index does.
695
708
 
696
709
  ```typescript
697
710
  // config.env.ts — that is all: endpoints, consent page and sign-in come with it