@solidxai/core 0.1.11-beta.1 → 0.1.11-beta.11

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 (244) hide show
  1. package/.claude/settings.local.json +16 -0
  2. package/CLAUDE.md +26 -0
  3. package/dist/commands/migrate-removed-fields.command.d.ts +19 -0
  4. package/dist/commands/migrate-removed-fields.command.d.ts.map +1 -0
  5. package/dist/commands/migrate-removed-fields.command.js +77 -0
  6. package/dist/commands/migrate-removed-fields.command.js.map +1 -0
  7. package/dist/controllers/datasource-introspection.controller.d.ts +46 -1
  8. package/dist/controllers/datasource-introspection.controller.d.ts.map +1 -1
  9. package/dist/controllers/datasource-introspection.controller.js +38 -0
  10. package/dist/controllers/datasource-introspection.controller.js.map +1 -1
  11. package/dist/controllers/service.controller.d.ts +1 -0
  12. package/dist/controllers/service.controller.d.ts.map +1 -1
  13. package/dist/controllers/service.controller.js +2 -2
  14. package/dist/controllers/service.controller.js.map +1 -1
  15. package/dist/dtos/datasource-introspection-mapping.dto.d.ts +5 -0
  16. package/dist/dtos/datasource-introspection-mapping.dto.d.ts.map +1 -1
  17. package/dist/dtos/datasource-introspection-mapping.dto.js +24 -2
  18. package/dist/dtos/datasource-introspection-mapping.dto.js.map +1 -1
  19. package/dist/entities/{legacy-common-with-id.entity.d.ts → legacy-common-with-generated-id.entity.d.ts} +2 -2
  20. package/dist/entities/legacy-common-with-generated-id.entity.d.ts.map +1 -0
  21. package/dist/entities/{legacy-common-with-id.entity.js → legacy-common-with-generated-id.entity.js} +4 -4
  22. package/dist/entities/legacy-common-with-generated-id.entity.js.map +1 -0
  23. package/dist/entities/{legacy-common.entity.d.ts → legacy-common.entity-with-existing-id.entity.d.ts} +1 -1
  24. package/dist/entities/legacy-common.entity-with-existing-id.entity.d.ts.map +1 -0
  25. package/dist/entities/{legacy-common.entity.js → legacy-common.entity-with-existing-id.entity.js} +1 -1
  26. package/dist/entities/legacy-common.entity-with-existing-id.entity.js.map +1 -0
  27. package/dist/helpers/command.service.d.ts +2 -0
  28. package/dist/helpers/command.service.d.ts.map +1 -1
  29. package/dist/helpers/command.service.js +6 -2
  30. package/dist/helpers/command.service.js.map +1 -1
  31. package/dist/helpers/environment.helper.d.ts +1 -0
  32. package/dist/helpers/environment.helper.d.ts.map +1 -1
  33. package/dist/helpers/environment.helper.js +4 -0
  34. package/dist/helpers/environment.helper.js.map +1 -1
  35. package/dist/helpers/field-crud-managers/IntFieldCrudManager.d.ts.map +1 -1
  36. package/dist/helpers/field-crud-managers/IntFieldCrudManager.js +4 -1
  37. package/dist/helpers/field-crud-managers/IntFieldCrudManager.js.map +1 -1
  38. package/dist/helpers/model-metadata-helper.service.d.ts +2 -1
  39. package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
  40. package/dist/helpers/model-metadata-helper.service.js +9 -5
  41. package/dist/helpers/model-metadata-helper.service.js.map +1 -1
  42. package/dist/helpers/nodemon-heartbeat.d.ts +5 -0
  43. package/dist/helpers/nodemon-heartbeat.d.ts.map +1 -0
  44. package/dist/helpers/nodemon-heartbeat.js +67 -0
  45. package/dist/helpers/nodemon-heartbeat.js.map +1 -0
  46. package/dist/helpers/solid-registry.d.ts +2 -1
  47. package/dist/helpers/solid-registry.d.ts.map +1 -1
  48. package/dist/helpers/solid-registry.js.map +1 -1
  49. package/dist/helpers/typeorm-db-helper.d.ts +1 -0
  50. package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
  51. package/dist/helpers/typeorm-db-helper.js +12 -0
  52. package/dist/helpers/typeorm-db-helper.js.map +1 -1
  53. package/dist/index.d.ts +3 -2
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +3 -2
  56. package/dist/index.js.map +1 -1
  57. package/dist/interfaces/datasource-introspection-provider.interface.d.ts +1 -0
  58. package/dist/interfaces/datasource-introspection-provider.interface.d.ts.map +1 -1
  59. package/dist/interfaces/datasource-introspection-provider.interface.js.map +1 -1
  60. package/dist/interfaces.d.ts +1 -0
  61. package/dist/interfaces.d.ts.map +1 -1
  62. package/dist/interfaces.js.map +1 -1
  63. package/dist/repository/scheduled-job.repository.d.ts +2 -2
  64. package/dist/repository/scheduled-job.repository.d.ts.map +1 -1
  65. package/dist/repository/scheduled-job.repository.js +6 -3
  66. package/dist/repository/scheduled-job.repository.js.map +1 -1
  67. package/dist/repository/security-rule.repository.d.ts +2 -2
  68. package/dist/repository/security-rule.repository.d.ts.map +1 -1
  69. package/dist/repository/security-rule.repository.js +6 -3
  70. package/dist/repository/security-rule.repository.js.map +1 -1
  71. package/dist/seeders/module-metadata-seeder.service.d.ts +11 -1
  72. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  73. package/dist/seeders/module-metadata-seeder.service.js +163 -3
  74. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  75. package/dist/seeders/seed-data/solid-core-metadata.json +128 -34
  76. package/dist/services/api-key.service.d.ts.map +1 -1
  77. package/dist/services/api-key.service.js.map +1 -1
  78. package/dist/services/authentication.service.d.ts +2 -0
  79. package/dist/services/authentication.service.d.ts.map +1 -1
  80. package/dist/services/authentication.service.js +32 -11
  81. package/dist/services/authentication.service.js.map +1 -1
  82. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts.map +1 -1
  83. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +7 -5
  84. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -1
  85. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts +4 -0
  86. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts.map +1 -1
  87. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js +18 -1
  88. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js.map +1 -1
  89. package/dist/services/crud-helper.service.d.ts.map +1 -1
  90. package/dist/services/crud-helper.service.js +25 -12
  91. package/dist/services/crud-helper.service.js.map +1 -1
  92. package/dist/services/crud.service.d.ts +1 -0
  93. package/dist/services/crud.service.d.ts.map +1 -1
  94. package/dist/services/crud.service.js +27 -0
  95. package/dist/services/crud.service.js.map +1 -1
  96. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts.map +1 -1
  97. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js +12 -0
  98. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js.map +1 -1
  99. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts.map +1 -1
  100. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js +2 -0
  101. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js.map +1 -1
  102. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts.map +1 -1
  103. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js +28 -15
  104. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js.map +1 -1
  105. package/dist/services/datasource-introspection.service.d.ts +62 -2
  106. package/dist/services/datasource-introspection.service.d.ts.map +1 -1
  107. package/dist/services/datasource-introspection.service.js +654 -186
  108. package/dist/services/datasource-introspection.service.js.map +1 -1
  109. package/dist/services/import-transaction.service.d.ts.map +1 -1
  110. package/dist/services/import-transaction.service.js +3 -0
  111. package/dist/services/import-transaction.service.js.map +1 -1
  112. package/dist/services/locale.service.d.ts +14 -0
  113. package/dist/services/locale.service.d.ts.map +1 -1
  114. package/dist/services/locale.service.js +83 -0
  115. package/dist/services/locale.service.js.map +1 -1
  116. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +10 -10
  117. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
  118. package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
  119. package/dist/services/menu-item-metadata.service.js +1 -0
  120. package/dist/services/menu-item-metadata.service.js.map +1 -1
  121. package/dist/services/model-metadata.service.d.ts +3 -0
  122. package/dist/services/model-metadata.service.d.ts.map +1 -1
  123. package/dist/services/model-metadata.service.js +78 -0
  124. package/dist/services/model-metadata.service.js.map +1 -1
  125. package/dist/services/module-metadata.service.d.ts.map +1 -1
  126. package/dist/services/module-metadata.service.js +28 -0
  127. package/dist/services/module-metadata.service.js.map +1 -1
  128. package/dist/services/removed-field-migration.service.d.ts +30 -0
  129. package/dist/services/removed-field-migration.service.d.ts.map +1 -0
  130. package/dist/services/removed-field-migration.service.js +319 -0
  131. package/dist/services/removed-field-migration.service.js.map +1 -0
  132. package/dist/services/role-metadata.service.d.ts +1 -0
  133. package/dist/services/role-metadata.service.d.ts.map +1 -1
  134. package/dist/services/role-metadata.service.js +23 -2
  135. package/dist/services/role-metadata.service.js.map +1 -1
  136. package/dist/services/settings/default-settings-provider.service.d.ts +244 -0
  137. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  138. package/dist/services/settings/default-settings-provider.service.js +120 -0
  139. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  140. package/dist/services/solid-ts-morph.service.d.ts +6 -0
  141. package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
  142. package/dist/services/solid-ts-morph.service.js +43 -0
  143. package/dist/services/solid-ts-morph.service.js.map +1 -1
  144. package/dist/services/view-metadata.service.d.ts.map +1 -1
  145. package/dist/services/view-metadata.service.js +4 -7
  146. package/dist/services/view-metadata.service.js.map +1 -1
  147. package/dist/solid-core.module.d.ts.map +1 -1
  148. package/dist/solid-core.module.js +4 -0
  149. package/dist/solid-core.module.js.map +1 -1
  150. package/dist/subscribers/audit.subscriber.d.ts +5 -1
  151. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  152. package/dist/subscribers/audit.subscriber.js +76 -12
  153. package/dist/subscribers/audit.subscriber.js.map +1 -1
  154. package/dist/subscribers/computed-entity-field.subscriber.d.ts +9 -1
  155. package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
  156. package/dist/subscribers/computed-entity-field.subscriber.js +45 -11
  157. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  158. package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
  159. package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
  160. package/dist/subscribers/field-metadata.subscriber.d.ts.map +1 -1
  161. package/dist/subscribers/field-metadata.subscriber.js.map +1 -1
  162. package/dist/subscribers/scheduled-job.subscriber.d.ts.map +1 -1
  163. package/dist/subscribers/scheduled-job.subscriber.js +3 -2
  164. package/dist/subscribers/scheduled-job.subscriber.js.map +1 -1
  165. package/dist/subscribers/security-rule.subscriber.d.ts.map +1 -1
  166. package/dist/subscribers/security-rule.subscriber.js +5 -3
  167. package/dist/subscribers/security-rule.subscriber.js.map +1 -1
  168. package/package.json +1 -1
  169. package/src/commands/migrate-removed-fields.command.ts +81 -0
  170. package/src/controllers/datasource-introspection.controller.ts +27 -1
  171. package/src/controllers/service.controller.ts +3 -2
  172. package/src/dtos/datasource-introspection-mapping.dto.ts +15 -0
  173. package/src/entities/{legacy-common-with-id.entity.ts → legacy-common-with-generated-id.entity.ts} +1 -1
  174. package/src/helpers/command.service.ts +10 -2
  175. package/src/helpers/environment.helper.ts +11 -0
  176. package/src/helpers/field-crud-managers/IntFieldCrudManager.ts +4 -1
  177. package/src/helpers/model-metadata-helper.service.ts +8 -3
  178. package/src/helpers/nodemon-heartbeat.ts +59 -0
  179. package/src/helpers/solid-registry.ts +7 -1
  180. package/src/helpers/typeorm-db-helper.ts +15 -0
  181. package/src/index.ts +3 -2
  182. package/src/interfaces/datasource-introspection-provider.interface.ts +1 -0
  183. package/src/interfaces.ts +1 -0
  184. package/src/repository/scheduled-job.repository.ts +10 -4
  185. package/src/repository/security-rule.repository.ts +10 -4
  186. package/src/seeders/module-metadata-seeder.service.ts +192 -2
  187. package/src/seeders/seed-data/solid-core-metadata.json +128 -34
  188. package/src/services/1.js +6 -0
  189. package/src/services/api-key.service.ts +36 -36
  190. package/src/services/authentication.service.ts +46 -12
  191. package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +11 -5
  192. package/src/services/computed-fields/entity/concat-entity-computed-field-provider.service.ts +15 -1
  193. package/src/services/crud-helper.service.ts +25 -12
  194. package/src/services/crud.service.ts +36 -11
  195. package/src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts +12 -0
  196. package/src/services/datasource-introspection/mysql-datasource-introspection-provider.service.ts +2 -0
  197. package/src/services/datasource-introspection/postgres-datasource-introspection-provider.service.ts +28 -15
  198. package/src/services/datasource-introspection.service.ts +811 -161
  199. package/src/services/import-transaction.service.ts +5 -0
  200. package/src/services/locale.service.ts +111 -3
  201. package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +2 -2
  202. package/src/services/menu-item-metadata.service.ts +2 -1
  203. package/src/services/model-metadata.service.ts +109 -1
  204. package/src/services/module-metadata.service.ts +36 -0
  205. package/src/services/removed-field-migration.service.ts +334 -0
  206. package/src/services/role-metadata.service.ts +26 -2
  207. package/src/services/settings/default-settings-provider.service.ts +120 -0
  208. package/src/services/solid-ts-morph.service.ts +61 -1
  209. package/src/services/view-metadata.service.ts +4 -8
  210. package/src/solid-core.module.ts +4 -0
  211. package/src/subscribers/audit.subscriber.ts +101 -18
  212. package/src/subscribers/computed-entity-field.subscriber.ts +81 -28
  213. package/src/subscribers/created-by-updated-by.subscriber.ts +3 -0
  214. package/src/subscribers/field-metadata.subscriber.ts +3 -0
  215. package/src/subscribers/scheduled-job.subscriber.ts +3 -2
  216. package/src/subscribers/security-rule.subscriber.ts +8 -3
  217. package/dist/entities/legacy-common-with-id.entity.d.ts.map +0 -1
  218. package/dist/entities/legacy-common-with-id.entity.js.map +0 -1
  219. package/dist/entities/legacy-common.entity.d.ts.map +0 -1
  220. package/dist/entities/legacy-common.entity.js.map +0 -1
  221. package/dist-tests/api/authenticate.spec.js +0 -119
  222. package/dist-tests/api/authenticate.spec.js.map +0 -1
  223. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
  224. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
  225. package/dist-tests/api/ping.spec.js +0 -21
  226. package/dist-tests/api/ping.spec.js.map +0 -1
  227. package/dist-tests/helpers/auth.js +0 -41
  228. package/dist-tests/helpers/auth.js.map +0 -1
  229. package/dist-tests/helpers/env.js +0 -11
  230. package/dist-tests/helpers/env.js.map +0 -1
  231. package/docs/agent-hub-grooming.md +0 -301
  232. package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +0 -438
  233. package/docs/dashboards/dashboard-curl-smoke-tests.txt +0 -146
  234. package/docs/dashboards/delete-legacy-dashboard-metadata.sql +0 -172
  235. package/docs/datasource-introspection-ddl-analysis.md +0 -326
  236. package/docs/datasource-introspection-implementation-plan.md +0 -306
  237. package/docs/grouping-enhancements.md +0 -89
  238. package/docs/java-spring/README.md +0 -3
  239. package/docs/java-spring/solid-core-module-deep-dive-report.md +0 -1317
  240. package/docs/module-package-import-handoff.md +0 -691
  241. package/docs/seed-changes.md +0 -65
  242. package/docs/test-data-workflow.md +0 -200
  243. package/docs/type-declaration-import-issue.md +0 -24
  244. /package/src/entities/{legacy-common.entity.ts → legacy-common.entity-with-existing-id.entity.ts} +0 -0
@@ -5,6 +5,7 @@ import { ActiveUserData } from "src/interfaces/active-user-data.interface";
5
5
  import { SolidRegistry } from "src/helpers/solid-registry";
6
6
  import { BadRequestException, Logger } from "@nestjs/common";
7
7
  import { ERROR_MESSAGES } from "src/constants/error-messages";
8
+ import { buildCastToText } from "src/helpers/typeorm-db-helper";
8
9
 
9
10
  export enum FilterCombinator {
10
11
  AND = '$and',
@@ -101,15 +102,19 @@ export class CrudHelperService {
101
102
  case '$eq':
102
103
  qb.andWhere(`${colExpr} = :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$eq });
103
104
  break;
104
- case '$eqi':
105
- qb.andWhere(`LOWER(${colExpr}) = :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$eqi.toLowerCase() });
105
+ case '$eqi': {
106
+ const castExpr = buildCastToText(this.getDriver(qb), colExpr);
107
+ qb.andWhere(`LOWER(${castExpr}) = :${uniqueFieldAlias}`, { [uniqueFieldAlias]: String(normalizedPrimaryOperatorObj.$eqi).toLowerCase() });
106
108
  break;
109
+ }
107
110
  case '$ne':
108
111
  qb.andWhere(`${colExpr} != :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$ne });
109
112
  break;
110
- case '$nei':
111
- qb.andWhere(`LOWER(${colExpr}) != :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$nei.toLowerCase() });
113
+ case '$nei': {
114
+ const castExpr = buildCastToText(this.getDriver(qb), colExpr);
115
+ qb.andWhere(`LOWER(${castExpr}) != :${uniqueFieldAlias}`, { [uniqueFieldAlias]: String(normalizedPrimaryOperatorObj.$nei).toLowerCase() });
112
116
  break;
117
+ }
113
118
  case '$gt':
114
119
  qb.andWhere(`${colExpr} > :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$gt });
115
120
  break;
@@ -134,12 +139,16 @@ export class CrudHelperService {
134
139
  case '$notContains':
135
140
  qb.andWhere(`${colExpr} NOT LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$notContains}%` });
136
141
  break;
137
- case '$containsi':
138
- qb.andWhere(`LOWER(${colExpr}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$containsi.toLowerCase()}%` });
142
+ case '$containsi': {
143
+ const castExpr = buildCastToText(this.getDriver(qb), colExpr);
144
+ qb.andWhere(`LOWER(${castExpr}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${String(normalizedPrimaryOperatorObj.$containsi).toLowerCase()}%` });
139
145
  break;
140
- case '$notContainsi':
141
- qb.andWhere(`LOWER(${colExpr}) NOT LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$notContainsi.toLowerCase()}%` });
146
+ }
147
+ case '$notContainsi': {
148
+ const castExpr = buildCastToText(this.getDriver(qb), colExpr);
149
+ qb.andWhere(`LOWER(${castExpr}) NOT LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${String(normalizedPrimaryOperatorObj.$notContainsi).toLowerCase()}%` });
142
150
  break;
151
+ }
143
152
  case '$null':
144
153
  qb.andWhere(`${colExpr} IS NULL`);
145
154
  break;
@@ -152,15 +161,19 @@ export class CrudHelperService {
152
161
  case '$startsWith':
153
162
  qb.andWhere(`${colExpr} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `${normalizedPrimaryOperatorObj.$startsWith}%` });
154
163
  break;
155
- case '$startsWithi':
156
- qb.andWhere(`LOWER(${colExpr}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `${normalizedPrimaryOperatorObj.$startsWithi.toLowerCase()}%` });
164
+ case '$startsWithi': {
165
+ const castExpr = buildCastToText(this.getDriver(qb), colExpr);
166
+ qb.andWhere(`LOWER(${castExpr}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `${String(normalizedPrimaryOperatorObj.$startsWithi).toLowerCase()}%` });
157
167
  break;
168
+ }
158
169
  case '$endsWith':
159
170
  qb.andWhere(`${colExpr} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$endsWith}` });
160
171
  break;
161
- case '$endsWithi':
162
- qb.andWhere(`LOWER(${colExpr}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$endsWithi.toLowerCase()}` });
172
+ case '$endsWithi': {
173
+ const castExpr = buildCastToText(this.getDriver(qb), colExpr);
174
+ qb.andWhere(`LOWER(${castExpr}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${String(normalizedPrimaryOperatorObj.$endsWithi).toLowerCase()}` });
163
175
  break;
176
+ }
164
177
  default:
165
178
  throw new Error(`Operator ${operator} is not supported`);
166
179
  }
@@ -34,6 +34,7 @@ import { SelectionDynamicFieldCrudManager } from "../helpers/field-crud-managers
34
34
  import { SelectionStaticFieldCrudManager } from "../helpers/field-crud-managers/SelectionStaticFieldCrudManager";
35
35
  import { ShortTextFieldCrudManager } from "../helpers/field-crud-managers/ShortTextFieldCrudManager";
36
36
  import { UUIDFieldCrudManager } from "../helpers/field-crud-managers/UUIDFieldCrudManager";
37
+ import { ModelMetadataHelperService } from "src/helpers/model-metadata-helper.service";
37
38
  import { FieldCrudManager, MediaWithFullUrl } from "../interfaces";
38
39
  import { CrudHelperService, FilterCombinator, UserIdFields } from "./crud-helper.service";
39
40
  import { HashingService } from "./hashing.service";
@@ -42,6 +43,7 @@ import { getMediaStorageProvider } from "./mediaStorageProviders";
42
43
  import { ModelMetadataService } from "./model-metadata.service";
43
44
  import { RequestContextService } from "./request-context.service";
44
45
 
46
+ const AUDIT_BEFORE_SNAPSHOT = '__auditBeforeSnapshot';
45
47
 
46
48
  export class CRUDService<T extends CommonEntity> { // Add two generic value i.e Person,CreatePersonDto, so we get the proper types in our service
47
49
 
@@ -185,7 +187,7 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
185
187
  }));
186
188
  }
187
189
 
188
- //TODO: Will the updates be partial i.e PATCH or full i.e PUT
190
+ //TODO: Will the updates be partial i.e PATCH or full i.e PUT
189
191
  async update(id: number, updateDto: any, files: Express.Multer.File[] = [], isPartialUpdate: boolean = false, solidRequestContext: any = {}, isUpdate: boolean = false): Promise<T> {
190
192
  if (!id) {
191
193
  throw new Error(ERROR_MESSAGES.ID_REQUIRED_FOR_UPDATE);
@@ -213,16 +215,8 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
213
215
  );
214
216
  }
215
217
 
216
- // // In some instances for legacy tables sometimes id is mapped as a bigint.
217
- // // in these cases the update method ends up attempting to insert records due to some type orm type mismatch issue.
218
- // const idFieldMetadata = model.fields.find(f => f.name === 'id');
219
- // updateDto.id = idFieldMetadata?.type === 'bigint' ? BigInt(id) : id;
220
-
221
- // This class will be extended by the generated service class i.e PersonService
222
- // The data required to identify the model and module name will be passed from the generate CrudService subclass
223
- //TODO: Algorithm to create the entity
224
- // 1. Fire a query and load all the fields in the provided model name for a particular module
225
- // FIXME This can be optimized to take in module name i.e (handle scenario wherein same model exists in multiple modules)
218
+ // Capture pre-update many-to-many relation state for audit tracking
219
+ await this.prepareManyToManyAuditSnapshot(entity,id,model.singularName);
226
220
  let hasMediaFields = false;
227
221
 
228
222
  const fieldsToProcess = [...model.fields];
@@ -249,6 +243,37 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
249
243
  return savedEntity;
250
244
  }
251
245
 
246
+ /**
247
+ * Captures the current state of audit-enabled many-to-many relations
248
+ * before the entity is updated. The snapshot is attached to the entity
249
+ * and can be used later for audit comparison.
250
+ */
251
+ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularName: string): Promise<void> {
252
+ const modelMetadataHelperService = this.moduleRef.get(ModelMetadataHelperService, { strict: false });
253
+ const auditRelationFields = (await modelMetadataHelperService.loadFieldHierarchy(modelSingularName)).filter(field =>
254
+ field.enableAuditTracking &&
255
+ field.type === 'relation' &&
256
+ field.relationType !== 'one-to-many'
257
+ );
258
+ if (auditRelationFields.length > 0) {
259
+ const relations: any = {};
260
+ auditRelationFields.forEach(field => relations[field.name] = true);
261
+ const auditBeforeEntity = await this.repo.findOne({
262
+ where: {
263
+ id: id,
264
+ } as unknown as FindOptionsWhere<T>,
265
+ relations: relations as any,
266
+ });
267
+ if (auditBeforeEntity) {
268
+ Object.defineProperty(entity, AUDIT_BEFORE_SNAPSHOT, {
269
+ configurable: true,
270
+ enumerable: false,
271
+ value: auditBeforeEntity,
272
+ writable: true,
273
+ });
274
+ }
275
+ }
276
+ }
252
277
  //TODO: Will the updates be partial i.e PATCH or full i.e PUT
253
278
  async delete(id: number, solidRequestContext: any = {}) {
254
279
  if (!id) {
@@ -39,6 +39,7 @@ export class MssqlDatasourceIntrospectionProviderService implements DatasourceIn
39
39
  c.name AS columnName,
40
40
  ty.name AS dataType,
41
41
  c.is_identity AS isAutoGenerated,
42
+ CASE WHEN pk.column_id IS NOT NULL THEN 1 ELSE 0 END AS isPrimaryKey,
42
43
  CASE WHEN c.is_nullable = 1 THEN 'YES' ELSE 'NO' END AS isNullable,
43
44
  dc.definition AS defaultValue,
44
45
  CASE
@@ -52,6 +53,16 @@ export class MssqlDatasourceIntrospectionProviderService implements DatasourceIn
52
53
  INNER JOIN sys.columns c ON c.object_id = t.object_id
53
54
  INNER JOIN sys.types ty ON ty.user_type_id = c.user_type_id
54
55
  LEFT JOIN sys.default_constraints dc ON dc.object_id = c.default_object_id
56
+ LEFT JOIN (
57
+ SELECT ic.object_id, ic.column_id
58
+ FROM sys.index_columns ic
59
+ INNER JOIN sys.key_constraints kc
60
+ ON kc.parent_object_id = ic.object_id
61
+ AND kc.unique_index_id = ic.index_id
62
+ WHERE kc.type = 'PK'
63
+ ) pk
64
+ ON pk.object_id = c.object_id
65
+ AND pk.column_id = c.column_id
55
66
  WHERE schema_name(t.schema_id) NOT IN ('sys', 'INFORMATION_SCHEMA')
56
67
  ORDER BY schema_name(t.schema_id), t.name, c.column_id
57
68
  `);
@@ -62,6 +73,7 @@ export class MssqlDatasourceIntrospectionProviderService implements DatasourceIn
62
73
  columnName: row.columnName,
63
74
  dataType: row.dataType,
64
75
  isAutoGenerated: Boolean(row.isAutoGenerated),
76
+ isPrimaryKey: Boolean(row.isPrimaryKey),
65
77
  isNullable: String(row.isNullable).toUpperCase() === "YES",
66
78
  defaultValue: row.defaultValue ?? null,
67
79
  characterMaximumLength: this.toNumberOrNull(row.characterMaximumLength),
@@ -39,6 +39,7 @@ export class MysqlDatasourceIntrospectionProviderService implements DatasourceIn
39
39
  COLUMN_NAME AS columnName,
40
40
  DATA_TYPE AS dataType,
41
41
  EXTRA AS extra,
42
+ COLUMN_KEY AS columnKey,
42
43
  IS_NULLABLE AS isNullable,
43
44
  COLUMN_DEFAULT AS defaultValue,
44
45
  CHARACTER_MAXIMUM_LENGTH AS characterMaximumLength,
@@ -56,6 +57,7 @@ export class MysqlDatasourceIntrospectionProviderService implements DatasourceIn
56
57
  columnName: row.columnName,
57
58
  dataType: row.dataType,
58
59
  isAutoGenerated: String(row.extra ?? "").toLowerCase().includes("auto_increment"),
60
+ isPrimaryKey: String(row.columnKey ?? "").toUpperCase() === "PRI",
59
61
  isNullable: String(row.isNullable).toUpperCase() === "YES",
60
62
  defaultValue: row.defaultValue ?? null,
61
63
  characterMaximumLength: this.toNumberOrNull(row.characterMaximumLength),
@@ -34,24 +34,36 @@ export class PostgresDatasourceIntrospectionProviderService implements Datasourc
34
34
  async listColumns(dataSource: DataSource): Promise<DatasourceIntrospectionColumn[]> {
35
35
  const rows = await dataSource.query(`
36
36
  SELECT
37
- TABLE_SCHEMA AS "tableSchema",
38
- TABLE_NAME AS "tableName",
39
- COLUMN_NAME AS "columnName",
40
- DATA_TYPE AS "dataType",
37
+ c.TABLE_SCHEMA AS "tableSchema",
38
+ c.TABLE_NAME AS "tableName",
39
+ c.COLUMN_NAME AS "columnName",
40
+ c.DATA_TYPE AS "dataType",
41
41
  CASE
42
- WHEN is_identity = 'YES' THEN true
43
- WHEN COLUMN_DEFAULT LIKE 'nextval(%' THEN true
42
+ WHEN c.is_identity = 'YES' THEN true
43
+ WHEN c.COLUMN_DEFAULT LIKE 'nextval(%' THEN true
44
44
  ELSE false
45
45
  END AS "isAutoGenerated",
46
- IS_NULLABLE AS "isNullable",
47
- COLUMN_DEFAULT AS "defaultValue",
48
- CHARACTER_MAXIMUM_LENGTH AS "characterMaximumLength",
49
- NUMERIC_PRECISION AS "numericPrecision",
50
- NUMERIC_SCALE AS "numericScale",
51
- ORDINAL_POSITION AS "ordinalPosition"
52
- FROM INFORMATION_SCHEMA.COLUMNS
53
- WHERE TABLE_SCHEMA NOT IN ('pg_catalog', 'information_schema')
54
- ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION
46
+ EXISTS (
47
+ SELECT 1
48
+ FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
49
+ INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
50
+ ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
51
+ AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
52
+ AND kcu.TABLE_NAME = tc.TABLE_NAME
53
+ WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
54
+ AND tc.TABLE_SCHEMA = c.TABLE_SCHEMA
55
+ AND tc.TABLE_NAME = c.TABLE_NAME
56
+ AND kcu.COLUMN_NAME = c.COLUMN_NAME
57
+ ) AS "isPrimaryKey",
58
+ c.IS_NULLABLE AS "isNullable",
59
+ c.COLUMN_DEFAULT AS "defaultValue",
60
+ c.CHARACTER_MAXIMUM_LENGTH AS "characterMaximumLength",
61
+ c.NUMERIC_PRECISION AS "numericPrecision",
62
+ c.NUMERIC_SCALE AS "numericScale",
63
+ c.ORDINAL_POSITION AS "ordinalPosition"
64
+ FROM INFORMATION_SCHEMA.COLUMNS c
65
+ WHERE c.TABLE_SCHEMA NOT IN ('pg_catalog', 'information_schema')
66
+ ORDER BY c.TABLE_SCHEMA, c.TABLE_NAME, c.ORDINAL_POSITION
55
67
  `);
56
68
 
57
69
  return rows.map((row: any) => ({
@@ -60,6 +72,7 @@ export class PostgresDatasourceIntrospectionProviderService implements Datasourc
60
72
  columnName: row.columnName,
61
73
  dataType: row.dataType,
62
74
  isAutoGenerated: Boolean(row.isAutoGenerated),
75
+ isPrimaryKey: Boolean(row.isPrimaryKey),
63
76
  isNullable: String(row.isNullable).toUpperCase() === "YES",
64
77
  defaultValue: row.defaultValue ?? null,
65
78
  characterMaximumLength: this.toNumberOrNull(row.characterMaximumLength),