@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
@@ -0,0 +1,109 @@
1
+ import type { Connection } from 'mongoose';
2
+
3
+ import { isObjectIdLike } from '../../common/helpers/id.helper.js';
4
+ import type { DataStore, FindOptions } from '../../common/persistence/data-store.interface.js';
5
+ import { getRegisteredDataStore, getStoreForModel } from '../../common/persistence/persistence-runtime.registry.js';
6
+ import { UnsupportedCapabilityError } from '../../common/persistence/unsupported-capability.error.js';
7
+ import type { FileCollection } from './file-metadata.helper.js';
8
+ import { FILESYSTEM_FILE_MODEL, S3_FILE_MODEL } from './file-metadata.models.js';
9
+ import { FILESYSTEM_FILES_COLLECTION } from './filesystem-file.helper.js';
10
+ import { S3_FILES_COLLECTION } from './s3-file.helper.js';
11
+ import { newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
12
+
13
+ /** The two stores that keep their metadata outside GridFS */
14
+ export type FileMetadataStore = 'filesystem' | 's3';
15
+
16
+ const STORES: Record<FileMetadataStore, { collection: string; model: string }> = {
17
+ filesystem: { collection: FILESYSTEM_FILES_COLLECTION, model: FILESYSTEM_FILE_MODEL },
18
+ s3: { collection: S3_FILES_COLLECTION, model: S3_FILE_MODEL },
19
+ };
20
+
21
+ /**
22
+ * Where the metadata of a store lives: its MongoDB collection, or — when `database` routes the model to a SQL source —
23
+ * that model's table, behind the same few collection operations the file helpers use. Resolved per call, so a
24
+ * service constructed before the stores exist still reaches the right one.
25
+ *
26
+ * Every reader and writer of `s3-files` / `filesystem-files` goes through here (`CoreFileService`, the TUS hand-off,
27
+ * the Hub): one of them reading the collection while the others write the table would lose files from view.
28
+ */
29
+ export function fileMetadataCollection(connection: Connection | null, store: FileMetadataStore): FileCollection {
30
+ const { collection, model } = STORES[store];
31
+ const dataStore = connection
32
+ ? connection.models?.[model]
33
+ ? getStoreForModel(connection.models[model])
34
+ : undefined
35
+ : // No MongoDB connection (PostgreSQL alone, or `database: false`): the store registered for the model is the only
36
+ // one there is — this application's, since no other can have one without a connection either
37
+ getRegisteredDataStore(model);
38
+ if (dataStore && !dataStore.capabilities.mongoosePopulate) {
39
+ return sqlFileCollection(dataStore, collection);
40
+ }
41
+ if (!connection) {
42
+ throw new UnsupportedCapabilityError(
43
+ `The ${collection} file metadata has nowhere to go: no MongoDB is configured and no data source routes ${model}`,
44
+ );
45
+ }
46
+ return connection.db.collection(collection);
47
+ }
48
+
49
+ /**
50
+ * A metadata table seen as the collection the helpers expect: `_id` (an ObjectId) is the record's `id`, MongoDB
51
+ * filters and sorts are passed to the store with `_id` renamed, and a record comes back with `_id` as an ObjectId and
52
+ * without the columns it has no value in — the shape a document of the collection has.
53
+ */
54
+ export function sqlFileCollection(store: DataStore<any>, collectionName: string): FileCollection {
55
+ const find = async (filter: unknown, options: Record<string, any> = {}) =>
56
+ (await store.find(toWhere(filter ?? {}), toFindOptions(options))).map(toDocument);
57
+ const collection = {
58
+ collectionName,
59
+ countDocuments: async (filter: unknown = {}) => store.count(toWhere(filter)),
60
+ // The table carries the `filename` index the model declares
61
+ createIndex: async () => 'filename_1',
62
+ dbName: 'sql',
63
+ deleteOne: async (filter: unknown) => ({
64
+ acknowledged: true,
65
+ deletedCount: (await store.deleteOne(toWhere(filter))) ? 1 : 0,
66
+ }),
67
+ find: (filter?: unknown, options?: Record<string, any>) => ({ toArray: () => find(filter, options) }),
68
+ findOne: async (filter?: unknown, options?: Record<string, any>) =>
69
+ (await find(filter, { ...options, limit: 1 }))[0] ?? null,
70
+ insertOne: async (doc: Record<string, any>) => {
71
+ const { _id, ...fields } = doc;
72
+ await store.insert({ ...fields, id: String(_id) });
73
+ return { acknowledged: true, insertedId: _id };
74
+ },
75
+ };
76
+ return collection as unknown as FileCollection;
77
+ }
78
+
79
+ /** A MongoDB filter for the store: `_id` becomes `id`, ObjectIds become their hex strings — at every depth */
80
+ function toWhere(value: unknown): any {
81
+ if (isObjectIdLike(value)) {
82
+ return value.toHexString();
83
+ }
84
+ if (Array.isArray(value)) {
85
+ return value.map(toWhere);
86
+ }
87
+ if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp) {
88
+ return value;
89
+ }
90
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key === '_id' ? 'id' : key, toWhere(entry)]));
91
+ }
92
+
93
+ function toFindOptions(options: Record<string, any>): FindOptions {
94
+ const { collation, limit, skip, sort } = options;
95
+ return {
96
+ ...(collation ? { collation } : {}),
97
+ ...(limit ? { limit } : {}),
98
+ ...(skip ? { skip } : {}),
99
+ ...(sort ? { sort: toWhere(sort) } : {}),
100
+ };
101
+ }
102
+
103
+ function toDocument(record: Record<string, any>): Record<string, any> {
104
+ const { id, ...fields } = record;
105
+ return {
106
+ _id: newObjectId(id),
107
+ ...Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== null && value !== undefined)),
108
+ };
109
+ }
@@ -1,6 +1,8 @@
1
1
  import { Logger } from '@nestjs/common';
2
2
 
3
3
  import { IServerOptions } from '../../common/interfaces/server-options.interface.js';
4
+ import { resolveDataSources, resolveModelSource } from '../../common/persistence/data-source.config.js';
5
+ import { FILESYSTEM_FILE_MODEL } from './file-metadata.models.js';
4
6
 
5
7
  const logger = new Logger('CoreFileStorage');
6
8
 
@@ -58,6 +60,28 @@ export function hasDatabaseConfig(config?: Partial<IServerOptions>): boolean {
58
60
  return !!config?.mongoose?.uri;
59
61
  }
60
62
 
63
+ /**
64
+ * The SQL data source `database` routes the file metadata to, or `undefined` when it stays on MongoDB. Answers from the
65
+ * configuration alone, so the driver is known before any store exists; a configuration that cannot be resolved has
66
+ * already stopped the boot in `CoreModule.forRoot()`, so it reads as "MongoDB" here.
67
+ */
68
+ export function fileMetadataSqlSource(config?: Partial<IServerOptions>): string | undefined {
69
+ if (!config?.database) {
70
+ return undefined;
71
+ }
72
+ try {
73
+ const resolved = resolveDataSources({
74
+ database: config.database,
75
+ explicitMongoose: !!config.mongoose,
76
+ mongooseUri: config.mongoose?.uri,
77
+ });
78
+ const source = resolveModelSource(resolved, FILESYSTEM_FILE_MODEL);
79
+ return source && resolved.sources[source]?.driver !== 'mongodb' ? source : undefined;
80
+ } catch {
81
+ return undefined;
82
+ }
83
+ }
84
+
61
85
  /**
62
86
  * Decide which storage driver to use.
63
87
  *
@@ -69,8 +93,10 @@ export function hasDatabaseConfig(config?: Partial<IServerOptions>): boolean {
69
93
  * Without an explicit value the default is derived, most capable first:
70
94
  *
71
95
  * 1. `s3` — when the S3 config names a bucket
72
- * 2. `gridfs` — when a database is configured
73
- * 3. `filesystem` — when neither is (today a theoretical case: `CoreModule`
96
+ * 2. `filesystem` — when `database` routes the file metadata to a SQL source:
97
+ * GridFS would put bytes and metadata into MongoDB
98
+ * 3. `gridfs` — when a database is configured
99
+ * 4. `filesystem` — when none is (today a theoretical case: `CoreModule`
74
100
  * always registers Mongoose, so a project without a database
75
101
  * does not boot at all)
76
102
  *
@@ -97,6 +123,25 @@ export function resolveFileStorage(config?: Partial<IServerOptions>): FileStorag
97
123
  return { driver: 's3', explicit: false, reason: 's3.bucket is configured' };
98
124
  }
99
125
 
126
+ if (config?.database === false) {
127
+ return {
128
+ driver: 'filesystem',
129
+ explicit: false,
130
+ reason: 'the project runs without a database (`database: false`) — file metadata has nowhere to go',
131
+ };
132
+ }
133
+
134
+ const sqlSource = fileMetadataSqlSource(config);
135
+ if (sqlSource) {
136
+ // GridFS keeps bytes AND metadata in MongoDB; a project that routes the file metadata to SQL does not get its
137
+ // files put into MongoDB without asking for it (`file.storage: 'gridfs'` still does)
138
+ return {
139
+ driver: 'filesystem',
140
+ explicit: false,
141
+ reason: `no S3 bucket is configured and the file metadata lives in the SQL source "${sqlSource}"`,
142
+ };
143
+ }
144
+
100
145
  if (hasDatabaseConfig(config)) {
101
146
  return { driver: 'gridfs', explicit: false, reason: 'a database is configured and no S3 bucket is' };
102
147
  }
@@ -1,6 +1,6 @@
1
1
  import { createReadStream, createWriteStream } from 'fs';
2
2
  import { mkdir, rm, stat } from 'fs/promises';
3
- import { Types } from 'mongoose';
3
+ import type { Types } from 'mongoose';
4
4
  import * as path from 'path';
5
5
  import { pipeline } from 'stream/promises';
6
6
  import { Readable } from 'stream';
@@ -14,8 +14,9 @@ import {
14
14
  findMetadataByName,
15
15
  } from './file-metadata.helper.js';
16
16
  import { streamToBuffer } from './s3-file.helper.js';
17
+ import { newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
17
18
 
18
- /** Metadata collection for files stored on the local filesystem */
19
+ /** Metadata collection for files stored on the local filesystem (on a SQL source: the table `filesystem_files`) */
19
20
  export const FILESYSTEM_FILES_COLLECTION = 'filesystem-files';
20
21
 
21
22
  /** Default directory for the filesystem storage driver */
@@ -31,12 +32,14 @@ export const DEFAULT_FILESYSTEM_DIR = 'uploads/files';
31
32
  export type FilesystemFileInfo = FileMetadataInfo;
32
33
 
33
34
  /**
34
- * Helper for files stored on the local filesystem with their metadata in MongoDB.
35
+ * Helper for files stored on the local filesystem with their metadata in the database.
35
36
  *
36
37
  * Counterpart of `GridFSHelper` and `S3FileHelper`: same operations, the local
37
- * disk as the byte store and `filesystem-files` as the metadata store.
38
+ * disk as the byte store and `filesystem-files` as the metadata store — pass
39
+ * `fileMetadataCollection(connection, 'filesystem')`, never the MongoDB collection
40
+ * directly: on a SQL source the metadata lives in the table `filesystem_files`.
38
41
  *
39
- * WHY THE METADATA STILL LIVES IN MONGO: filename, content type, length and the
42
+ * WHY THE METADATA STILL LIVES IN THE DATABASE: filename, content type, length and the
40
43
  * custom `metadata` a per-file authorization rule reads have to be queryable —
41
44
  * `findFileInfo()` filters and pages over them, and `checkRights()` reads them
42
45
  * per request. A directory listing answers none of that, and sidecar files would
@@ -57,7 +60,7 @@ export class FilesystemFileHelper {
57
60
  * a user-supplied filename here.
58
61
  */
59
62
  static filePath(directory: string, id: string | Types.ObjectId): string {
60
- const objectId = typeof id === 'string' ? new Types.ObjectId(id) : id;
63
+ const objectId = typeof id === 'string' ? newObjectId(id) : id;
61
64
  return path.join(path.resolve(directory), objectId.toHexString());
62
65
  }
63
66
 
@@ -83,7 +86,7 @@ export class FilesystemFileHelper {
83
86
  metadata?: Record<string, any>;
84
87
  },
85
88
  ): Promise<FilesystemFileInfo> {
86
- const _id = new Types.ObjectId();
89
+ const _id = newObjectId();
87
90
  const target = FilesystemFileHelper.filePath(directory, _id);
88
91
 
89
92
  await mkdir(path.dirname(target), { recursive: true });
@@ -163,7 +166,7 @@ export class FilesystemFileHelper {
163
166
  * up through the API.
164
167
  */
165
168
  static async deleteFile(directory: string, collection: FileCollection, id: string | Types.ObjectId): Promise<void> {
166
- const objectId = typeof id === 'string' ? new Types.ObjectId(id) : id;
169
+ const objectId = typeof id === 'string' ? newObjectId(id) : id;
167
170
  await rm(FilesystemFileHelper.filePath(directory, objectId), { force: true });
168
171
  await collection.deleteOne({ _id: objectId });
169
172
  }
@@ -1,4 +1,4 @@
1
- import { Types } from 'mongoose';
1
+ import type { Types } from 'mongoose';
2
2
  import { Readable } from 'stream';
3
3
 
4
4
  import { CoreS3Service } from '../../common/services/core-s3.service.js';
@@ -10,13 +10,15 @@ import {
10
10
  findMetadataById,
11
11
  findMetadataByName,
12
12
  } from './file-metadata.helper.js';
13
+ import { newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
13
14
 
14
15
  /**
15
16
  * Name of the MongoDB collection holding the metadata of S3-stored files.
16
17
  *
17
18
  * S3 itself has no queryable metadata store, so file info (filename, contentType,
18
19
  * length, uploadDate) is kept in this collection — the equivalent of GridFS's
19
- * `fs.files`. The object key in the bucket is the string form of `_id`.
20
+ * `fs.files`. The object key in the bucket is the string form of `_id`. On a SQL
21
+ * source the same records live in the table `s3_files` (`fileMetadataCollection()`).
20
22
  */
21
23
  export const S3_FILES_COLLECTION = 's3-files';
22
24
 
@@ -56,7 +58,9 @@ export async function streamToBuffer(stream: Readable): Promise<Buffer> {
56
58
  }
57
59
 
58
60
  /**
59
- * Helper for files stored in S3 with their metadata in MongoDB.
61
+ * Helper for files stored in S3 with their metadata in the database — pass
62
+ * `fileMetadataCollection(connection, 's3')` as the collection: on a SQL source the
63
+ * metadata lives in the table `s3_files`, not in MongoDB.
60
64
  *
61
65
  * Counterpart of GridFSHelper: same operations, S3 as the byte store and
62
66
  * `s3-files` as the metadata store.
@@ -81,7 +85,7 @@ export class S3FileHelper {
81
85
  metadata?: Record<string, any>;
82
86
  },
83
87
  ): Promise<S3FileInfo> {
84
- const _id = new Types.ObjectId();
88
+ const _id = newObjectId();
85
89
  const key = _id.toHexString();
86
90
 
87
91
  // A stream is never read into a Buffer here. Doing so — which every caller used to do —
@@ -126,7 +130,7 @@ export class S3FileHelper {
126
130
  sourceKey: string;
127
131
  },
128
132
  ): Promise<S3FileInfo> {
129
- const _id = new Types.ObjectId();
133
+ const _id = newObjectId();
130
134
  await s3Service.copyObject(options.sourceKey, _id.toHexString(), options.sourceBucket, options.contentType);
131
135
 
132
136
  return S3FileHelper.recordFile(s3Service, collection, _id, {
@@ -206,7 +210,7 @@ export class S3FileHelper {
206
210
  collection: FileCollection,
207
211
  id: string | Types.ObjectId,
208
212
  ): Promise<void> {
209
- const objectId = typeof id === 'string' ? new Types.ObjectId(id) : id;
213
+ const objectId = typeof id === 'string' ? newObjectId(id) : id;
210
214
  await s3Service.deleteObject(objectId.toHexString());
211
215
  await collection.deleteOne({ _id: objectId });
212
216
  }
@@ -215,7 +219,7 @@ export class S3FileHelper {
215
219
  * Get the download stream of a file
216
220
  */
217
221
  static async getStream(s3Service: CoreS3Service, id: string | Types.ObjectId): Promise<Readable> {
218
- const objectId = typeof id === 'string' ? new Types.ObjectId(id) : id;
222
+ const objectId = typeof id === 'string' ? newObjectId(id) : id;
219
223
  return (await s3Service.getObject(objectId.toHexString())).body;
220
224
  }
221
225
 
@@ -1,5 +1,8 @@
1
1
  import { Module } from '@nestjs/common';
2
- import { TerminusModule } from '@nestjs/terminus';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ import { HealthIndicatorService, MongooseHealthIndicator, TerminusModule } from '@nestjs/terminus';
4
+
5
+ import { getConnectionToken } from '../../common/persistence/mongo/mongoose-compat.js';
3
6
 
4
7
  import { CoreHealthCheckController } from './core-health-check.controller.js';
5
8
  import { CoreHealthCheckResolver } from './core-health-check.resolver.js';
@@ -12,6 +15,17 @@ import { CoreHealthCheckService } from './core-health-check.service.js';
12
15
  @Module({
13
16
  controllers: [CoreHealthCheckController],
14
17
  imports: [TerminusModule],
15
- providers: [CoreHealthCheckService, CoreHealthCheckResolver],
18
+ providers: [
19
+ CoreHealthCheckService,
20
+ CoreHealthCheckResolver,
21
+ {
22
+ inject: [ModuleRef, HealthIndicatorService, { optional: true, token: getConnectionToken() }],
23
+ provide: MongooseHealthIndicator,
24
+ // Terminus' indicator requires Mongoose as it is constructed. Without a MongoDB connection (a project on
25
+ // PostgreSQL alone) there is nothing for it to ping, and no Mongoose to require: the service skips the ping
26
+ useFactory: (moduleRef: ModuleRef, indicators: HealthIndicatorService, connection?: unknown) =>
27
+ connection ? new MongooseHealthIndicator(moduleRef, indicators) : null,
28
+ },
29
+ ],
16
30
  })
17
31
  export class CoreHealthCheckModule {}
@@ -1,15 +1,17 @@
1
- import { Injectable } from '@nestjs/common';
1
+ import { Inject, Injectable, Optional } from '@nestjs/common';
2
2
  import {
3
3
  DiskHealthIndicator,
4
4
  type DiskHealthIndicatorOptions,
5
5
  HealthCheckResult,
6
6
  HealthCheckService,
7
+ HealthIndicatorService,
7
8
  MemoryHealthIndicator,
8
9
  MongooseHealthIndicator,
9
10
  type MongoosePingCheckSettings,
10
11
  } from '@nestjs/terminus';
11
12
 
12
13
  import { getBuildInfo } from '../../common/helpers/meta.helper.js';
14
+ import { getPersistenceRuntime } from '../../common/persistence/persistence-runtime.registry.js';
13
15
  import { ConfigService } from '../../common/services/config.service.js';
14
16
 
15
17
  /**
@@ -20,15 +22,18 @@ import { ConfigService } from '../../common/services/config.service.js';
20
22
  export class CoreHealthCheckService {
21
23
  constructor(
22
24
  protected config: ConfigService,
23
- protected db: MongooseHealthIndicator,
25
+ // Explicit token: a union type gives Nest no class to inject; `null` where no MongoDB is configured (module factory)
26
+ @Inject(MongooseHealthIndicator) protected db: MongooseHealthIndicator | null,
24
27
  protected disk: DiskHealthIndicator,
25
28
  protected health: HealthCheckService,
26
29
  protected memory: MemoryHealthIndicator,
30
+ @Optional() protected indicators?: HealthIndicatorService,
27
31
  ) {}
28
32
 
29
33
  healthCheck(): Promise<HealthCheckResult> {
30
34
  const healthIndicatorFunctions = [];
31
- if (this.config.get<boolean>('healthCheck.configs.database.enabled')) {
35
+ // The MongoDB ping where MongoDB is configured — a project on PostgreSQL alone has no MongoDB to ping
36
+ if (this.db && this.config.get<boolean>('healthCheck.configs.database.enabled')) {
32
37
  healthIndicatorFunctions.push(() => {
33
38
  // `timeout` stays part of the config contract, but @nestjs/terminus 12 deprecated it on the
34
39
  // indicator in favour of `.withTimeout()` on the returned attempt — translate it here, so the
@@ -45,6 +50,23 @@ export class CoreHealthCheckService {
45
50
  return timeout === undefined ? attempt : attempt.withTimeout(timeout);
46
51
  });
47
52
  }
53
+ if (this.config.get<boolean>('healthCheck.configs.database.enabled')) {
54
+ // Every SQL source answers on its own key, next to the MongoDB ping: `<key>:<source>` (`database:default`). A
55
+ // database the application cannot reach is down, whichever one it is
56
+ const key = this.config.get<string>('healthCheck.configs.database.key') ?? 'database';
57
+ const timeout =
58
+ this.config.get<MongoosePingCheckSettings>('healthCheck.configs.database.options')?.timeout ?? 1000;
59
+ for (const source of getPersistenceRuntime()?.sqlSources() ?? []) {
60
+ if (this.indicators) {
61
+ healthIndicatorFunctions.push(() =>
62
+ this.indicators
63
+ .check(`${key}:${source.name}`)
64
+ .attempt(() => source.ping())
65
+ .withTimeout(timeout),
66
+ );
67
+ }
68
+ }
69
+ }
48
70
  if (this.config.get<boolean>('healthCheck.configs.memoryHeap.enabled')) {
49
71
  healthIndicatorFunctions.push(() =>
50
72
  this.memory.checkHeap(
@@ -33,11 +33,12 @@ Do NOT set `hub` in the `production` block unless you intend the cockpit to be r
33
33
  | Diagnostics | `/hub/diagnostics` | heap/rss, node/platform, collector buffer levels |
34
34
  | Logs | `/hub/logs` | in-memory log ring buffer (redacted) |
35
35
  | Request Traces | `/hub/traces` | HTTP timing middleware |
36
- | Query Performance | `/hub/queries` | MongoDB driver command monitoring (opt-in) |
36
+ | Query Performance | `/hub/queries` | MongoDB driver command monitoring (opt-in; MongoDB only) |
37
37
  | Cron Jobs | `/hub/cron` | `@nestjs/schedule` `SchedulerRegistry` (optional) |
38
- | Database | `/hub/db` | dbStats / per-collection collStats |
38
+ | Database | `/hub/db` | dbStats / per-collection collStats (MongoDB only) |
39
39
  | Models / ERD | `/hub/models` | Mongoose schemas → Mermaid ER diagram |
40
- | Migrations | `/hub/migrations` | `MigrationRunner` status + run/rollback |
40
+ | Persistence | `/hub/persistence` | data sources, and per model: source, database, capabilities |
41
+ | Migrations | `/hub/migrations` | `MigrationRunner` status + run/rollback (MongoDB or SQL state) |
41
42
  | Files | `/hub/files` | listing + delete across all three storage drivers |
42
43
  | Config | `/hub/config` | full config, secrets masked |
43
44
  | Auth Migration | `/hub/auth-migration` | Legacy → IAM progress (BetterAuth, optional) |
@@ -50,17 +51,25 @@ Do NOT set `hub` in the `production` block unless you intend the cockpit to be r
50
51
  Each panel has a `*.json` sidecar (the stable data contract) that the client polls. Optional sources
51
52
  degrade to an "unavailable" state instead of erroring.
52
53
 
54
+ With a SQL data source (`database`, see `.claude/rules/configurable-features.md` → Data Sources) the Database and
55
+ Query Performance panels cover the MongoDB connection only and report "unavailable" without one. The Migrations panel
56
+ reads the state from the store the framework keeps for the default source: on a SQL default source the
57
+ `lt_migrations` table, through the owner connection (`database.ownerUrl`, required there). That presumes
58
+ `migrations-utils/migrate.js` passes `database.ownerUrl` to `createMigrationStore()` (see the migrate README). While
59
+ it still passes the MongoDB URI, the table stays empty and the MongoDB collection lists the applied migrations; the
60
+ panel then reports that conflict and refuses Run and Rollback, which would apply the migrations a second time.
61
+
53
62
  ### Files panel
54
63
 
55
64
  The panel reads all three file metadata stores, not just GridFS — the same three
56
- `CoreFileService.findFileInfo()` consults, because metadata always lives in MongoDB whichever store
57
- holds the bytes:
58
-
59
- | Store | Collection | Bytes live in |
60
- | ------------ | ------------------------------------- | ------------------------------- |
61
- | `s3` | `s3-files` | the S3 bucket |
62
- | `filesystem` | `filesystem-files` | `file.storageDir` on local disk |
63
- | `gridfs` | `<bucket>.files` (default `fs.files`) | MongoDB |
65
+ `CoreFileService.findFileInfo()` consults, wherever `database` routes their metadata
66
+ (`fileMetadataCollection()`):
67
+
68
+ | Store | Metadata | Bytes live in |
69
+ | ------------ | ------------------------------------------------------- | ------------------------------- |
70
+ | `s3` | collection `s3-files`, on a SQL source table `s3_files` | the S3 bucket |
71
+ | `filesystem` | `filesystem-files`, on a SQL source `filesystem_files` | `file.storageDir` on local disk |
72
+ | `gridfs` | `<bucket>.files` (default `fs.files`), always MongoDB | MongoDB |
64
73
 
65
74
  Every row carries the `store` it was found in, and `files.json` reports a per-store `count` so an
66
75
  empty store reads as **empty** rather than as _"this panel does not cover your driver"_. Until
@@ -156,6 +156,11 @@ export class CoreHubController {
156
156
  this.sendJson(res, this.dbService.getModels());
157
157
  }
158
158
 
159
+ @Get('persistence.json')
160
+ persistenceJson(@Res() res: Response): void {
161
+ this.sendJson(res, this.sourcesService.getPersistence());
162
+ }
163
+
159
164
  /**
160
165
  * ADMIN-gated auth probe AND cockpit-chrome payload: 200 returns the navigation, environment badge,
161
166
  * version and external links the client uses to build the layout; 401/403 keeps the shell showing
@@ -1,5 +1,5 @@
1
1
  import { Inject, Injectable, Optional } from '@nestjs/common';
2
- import { InjectConnection } from '@nestjs/mongoose';
2
+ import { InjectConnection } from '../../common/persistence/mongo/mongoose-compat.js';
3
3
  import type { Connection } from 'mongoose';
4
4
 
5
5
  import { getBuildInfo } from '../../common/helpers/meta.helper.js';
@@ -479,6 +479,29 @@ export function getHubClientJs(): string {
479
479
  }, function (e) { clear(content); content.appendChild(unavailable('Failed to load: ' + e.message)); });
480
480
  };
481
481
 
482
+ Hub.panels.persistence = function (content) {
483
+ // Routing is fixed at boot; load once instead of polling.
484
+ hubFetch('/persistence.json').then(function (d) {
485
+ clear(content);
486
+ if (d && d.available === false) { content.appendChild(unavailable(d.hint)); return; }
487
+ content.appendChild(el('h3', { text: 'Data sources' }));
488
+ content.appendChild(table([
489
+ { key: 'name', label: 'Source', render: function (r) { return r.name + (r.name === d.defaultSource ? ' (default)' : ''); } },
490
+ { key: 'driver', label: 'Database' },
491
+ { key: 'engine', label: 'Engine', render: function (r) { return r.engine || '–'; } },
492
+ { key: 'host', label: 'Host' },
493
+ { key: 'ownerConfigured', label: 'Owner role', render: function (r) { return r.driver === 'mongodb' ? '–' : (r.ownerConfigured ? 'configured' : 'verify only'); } },
494
+ ], d.sources || []));
495
+ content.appendChild(el('h3', { text: 'Models (' + (d.models || []).length + ')' }));
496
+ content.appendChild(table([
497
+ { key: 'name', label: 'Model' },
498
+ { key: 'source', label: 'Source', render: function (r) { return r.source || '–'; } },
499
+ { key: 'driver', label: 'Store', render: function (r) { return r.driver || 'not created yet'; } },
500
+ { key: 'capabilities', label: 'Capabilities', render: function (r) { return (r.capabilities || []).join(', ') || '–'; } },
501
+ ], d.models || []));
502
+ }, function (e) { clear(content); content.appendChild(unavailable('Failed to load: ' + e.message)); });
503
+ };
504
+
482
505
  Hub.panels.config = function (content) {
483
506
  hubFetch('/config.json').then(function (d) { clear(content); content.appendChild(el('p', { class: 'hub-hint', text: 'Secrets are masked.' })); content.appendChild(jsonView(d)); },
484
507
  function (e) { clear(content); content.appendChild(unavailable('Failed to load: ' + e.message)); });
@@ -39,6 +39,12 @@ export const HubActionMessage = {
39
39
  missingHubRequestHeader: 'Missing X-Hub-Request header.',
40
40
  /** Any action that needs the Mongo connection while it is unavailable. */
41
41
  mongoUnavailable: 'No MongoDB connection is available.',
42
+ /** Migrations on a SQL default source run as the table owner. */
43
+ sqlOwnerMissing:
44
+ 'The migration state of a SQL default source is read and written as the table owner — configure database.ownerUrl.',
45
+ /** SQL default source with an empty `lt_migrations` while the MongoDB collection lists applied migrations. */
46
+ migrationStateInMongo: (collection: string) =>
47
+ `The default source is a SQL database, but its lt_migrations table is empty while the MongoDB collection "${collection}" lists applied migrations — migrations-utils/migrate.js still keeps the state in MongoDB. Pass database.ownerUrl to createMigrationStore() and move the state to the table; until then the Hub neither shows nor runs migrations, which would apply them again.`,
42
48
  /** Migrations action while no Mongo URI is configured. */
43
49
  mongoUriMissing: 'No MongoDB URI is configured.',
44
50
  /** Test mail: no recipient supplied. */
@@ -32,6 +32,7 @@ export const HUB_PANELS: readonly HubPanel[] = [
32
32
  { group: 'Runtime', id: 'cron', json: 'cron.json', optional: true, path: 'cron', title: 'Cron Jobs' },
33
33
  { group: 'Data', id: 'db', json: 'db.json', path: 'db', title: 'Database' },
34
34
  { group: 'Data', id: 'models', json: 'models.json', path: 'models', title: 'Models / ERD' },
35
+ { group: 'Data', id: 'persistence', json: 'persistence.json', path: 'persistence', title: 'Persistence' },
35
36
  { group: 'Data', id: 'migrations', json: 'migrations.json', path: 'migrations', title: 'Migrations' },
36
37
  { group: 'Data', id: 'files', json: 'files.json', path: 'files', title: 'Files' },
37
38
  { group: 'Data', id: 'config', json: 'config.json', path: 'config', title: 'Config' },
@@ -71,12 +71,19 @@ export interface HubModelsData {
71
71
  relationCount: number;
72
72
  }
73
73
 
74
+ /** Persistence panel: where each model is stored, on which database and engine, with which capabilities */
75
+ export interface HubPersistenceData {
76
+ defaultSource?: string;
77
+ models: { capabilities: string[]; driver?: string; name: string; source?: string }[];
78
+ sources: { driver: string; engine?: string; host: string; name: string; ownerConfigured: boolean }[];
79
+ }
80
+
74
81
  export interface HubMigrationsData {
75
82
  completed: string[];
76
83
  dirAvailable: boolean;
77
84
  lastRun?: string;
78
85
  pending: string[];
79
- source: 'collection' | 'runner';
86
+ source: 'collection' | 'runner' | 'table';
80
87
  }
81
88
 
82
89
  /**