@solidxai/core 0.1.11-beta.2 → 0.1.11-beta.5

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 (145) hide show
  1. package/dist/commands/migrate-removed-fields.command.d.ts +19 -0
  2. package/dist/commands/migrate-removed-fields.command.d.ts.map +1 -0
  3. package/dist/commands/migrate-removed-fields.command.js +77 -0
  4. package/dist/commands/migrate-removed-fields.command.js.map +1 -0
  5. package/dist/controllers/datasource-introspection.controller.d.ts +38 -1
  6. package/dist/controllers/datasource-introspection.controller.d.ts.map +1 -1
  7. package/dist/controllers/datasource-introspection.controller.js +38 -0
  8. package/dist/controllers/datasource-introspection.controller.js.map +1 -1
  9. package/dist/dtos/datasource-introspection-mapping.dto.d.ts +5 -0
  10. package/dist/dtos/datasource-introspection-mapping.dto.d.ts.map +1 -1
  11. package/dist/dtos/datasource-introspection-mapping.dto.js +24 -2
  12. package/dist/dtos/datasource-introspection-mapping.dto.js.map +1 -1
  13. package/dist/entities/{legacy-common-with-id.entity.d.ts → legacy-common-with-generated-id.entity.d.ts} +2 -2
  14. package/dist/entities/legacy-common-with-generated-id.entity.d.ts.map +1 -0
  15. package/dist/entities/{legacy-common-with-id.entity.js → legacy-common-with-generated-id.entity.js} +4 -4
  16. package/dist/entities/legacy-common-with-generated-id.entity.js.map +1 -0
  17. package/dist/entities/{legacy-common.entity.d.ts → legacy-common.entity-with-existing-id.entity.d.ts} +1 -1
  18. package/dist/entities/legacy-common.entity-with-existing-id.entity.d.ts.map +1 -0
  19. package/dist/entities/{legacy-common.entity.js → legacy-common.entity-with-existing-id.entity.js} +1 -1
  20. package/dist/entities/legacy-common.entity-with-existing-id.entity.js.map +1 -0
  21. package/dist/helpers/command.service.d.ts +2 -0
  22. package/dist/helpers/command.service.d.ts.map +1 -1
  23. package/dist/helpers/command.service.js +6 -2
  24. package/dist/helpers/command.service.js.map +1 -1
  25. package/dist/helpers/model-metadata-helper.service.js +3 -3
  26. package/dist/helpers/model-metadata-helper.service.js.map +1 -1
  27. package/dist/helpers/nodemon-heartbeat.d.ts +5 -0
  28. package/dist/helpers/nodemon-heartbeat.d.ts.map +1 -0
  29. package/dist/helpers/nodemon-heartbeat.js +67 -0
  30. package/dist/helpers/nodemon-heartbeat.js.map +1 -0
  31. package/dist/index.d.ts +3 -2
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -2
  34. package/dist/index.js.map +1 -1
  35. package/dist/interfaces/datasource-introspection-provider.interface.d.ts +1 -0
  36. package/dist/interfaces/datasource-introspection-provider.interface.d.ts.map +1 -1
  37. package/dist/interfaces/datasource-introspection-provider.interface.js.map +1 -1
  38. package/dist/seeders/module-metadata-seeder.service.d.ts +7 -1
  39. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  40. package/dist/seeders/module-metadata-seeder.service.js +101 -1
  41. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  42. package/dist/seeders/seed-data/solid-core-metadata.json +121 -34
  43. package/dist/services/api-key.service.d.ts.map +1 -1
  44. package/dist/services/api-key.service.js.map +1 -1
  45. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts +4 -0
  46. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts.map +1 -1
  47. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js +18 -1
  48. package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js.map +1 -1
  49. package/dist/services/crud.service.d.ts +1 -0
  50. package/dist/services/crud.service.d.ts.map +1 -1
  51. package/dist/services/crud.service.js +27 -0
  52. package/dist/services/crud.service.js.map +1 -1
  53. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts.map +1 -1
  54. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js +12 -0
  55. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js.map +1 -1
  56. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts.map +1 -1
  57. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js +2 -0
  58. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js.map +1 -1
  59. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts.map +1 -1
  60. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js +28 -15
  61. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js.map +1 -1
  62. package/dist/services/datasource-introspection.service.d.ts +53 -2
  63. package/dist/services/datasource-introspection.service.d.ts.map +1 -1
  64. package/dist/services/datasource-introspection.service.js +559 -174
  65. package/dist/services/datasource-introspection.service.js.map +1 -1
  66. package/dist/services/import-transaction.service.d.ts.map +1 -1
  67. package/dist/services/import-transaction.service.js +3 -0
  68. package/dist/services/import-transaction.service.js.map +1 -1
  69. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +10 -10
  70. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
  71. package/dist/services/model-metadata.service.d.ts +1 -0
  72. package/dist/services/model-metadata.service.d.ts.map +1 -1
  73. package/dist/services/model-metadata.service.js +28 -0
  74. package/dist/services/model-metadata.service.js.map +1 -1
  75. package/dist/services/module-metadata.service.d.ts.map +1 -1
  76. package/dist/services/module-metadata.service.js +27 -0
  77. package/dist/services/module-metadata.service.js.map +1 -1
  78. package/dist/services/removed-field-migration.service.d.ts +30 -0
  79. package/dist/services/removed-field-migration.service.d.ts.map +1 -0
  80. package/dist/services/removed-field-migration.service.js +319 -0
  81. package/dist/services/removed-field-migration.service.js.map +1 -0
  82. package/dist/solid-core.module.d.ts.map +1 -1
  83. package/dist/solid-core.module.js +4 -0
  84. package/dist/solid-core.module.js.map +1 -1
  85. package/dist/subscribers/audit.subscriber.d.ts +4 -1
  86. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  87. package/dist/subscribers/audit.subscriber.js +54 -6
  88. package/dist/subscribers/audit.subscriber.js.map +1 -1
  89. package/dist-tests/api/authenticate.spec.js +119 -0
  90. package/dist-tests/api/authenticate.spec.js.map +1 -0
  91. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
  92. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
  93. package/dist-tests/api/ping.spec.js +21 -0
  94. package/dist-tests/api/ping.spec.js.map +1 -0
  95. package/dist-tests/helpers/auth.js +41 -0
  96. package/dist-tests/helpers/auth.js.map +1 -0
  97. package/dist-tests/helpers/env.js +11 -0
  98. package/dist-tests/helpers/env.js.map +1 -0
  99. package/docs/agent-hub-grooming.md +301 -0
  100. package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +438 -0
  101. package/docs/dashboards/dashboard-curl-smoke-tests.txt +146 -0
  102. package/docs/dashboards/delete-legacy-dashboard-metadata.sql +172 -0
  103. package/docs/datasource-introspection-ddl-analysis.md +326 -0
  104. package/docs/datasource-introspection-implementation-plan.md +306 -0
  105. package/docs/grouping-enhancements.md +89 -0
  106. package/docs/java-spring/README.md +3 -0
  107. package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
  108. package/docs/module-package-import-handoff.md +691 -0
  109. package/docs/seed-changes.md +65 -0
  110. package/docs/test-data-workflow.md +200 -0
  111. package/docs/type-declaration-import-issue.md +24 -0
  112. package/package.json +1 -1
  113. package/src/commands/migrate-removed-fields.command.ts +81 -0
  114. package/src/controllers/datasource-introspection.controller.ts +27 -1
  115. package/src/dtos/datasource-introspection-mapping.dto.ts +15 -0
  116. package/src/entities/{legacy-common-with-id.entity.ts → legacy-common-with-generated-id.entity.ts} +1 -1
  117. package/src/helpers/command.service.ts +10 -2
  118. package/src/helpers/model-metadata-helper.service.ts +1 -1
  119. package/src/helpers/nodemon-heartbeat.ts +59 -0
  120. package/src/index.ts +3 -2
  121. package/src/interfaces/datasource-introspection-provider.interface.ts +1 -0
  122. package/src/seeders/module-metadata-seeder.service.ts +118 -0
  123. package/src/seeders/seed-data/solid-core-metadata.json +121 -34
  124. package/src/services/api-key.service.ts +36 -36
  125. package/src/services/computed-fields/entity/concat-entity-computed-field-provider.service.ts +15 -1
  126. package/src/services/crud.service.ts +36 -11
  127. package/src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts +12 -0
  128. package/src/services/datasource-introspection/mysql-datasource-introspection-provider.service.ts +2 -0
  129. package/src/services/datasource-introspection/postgres-datasource-introspection-provider.service.ts +28 -15
  130. package/src/services/datasource-introspection.service.ts +653 -150
  131. package/src/services/import-transaction.service.ts +5 -0
  132. package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +2 -2
  133. package/src/services/model-metadata.service.ts +45 -1
  134. package/src/services/module-metadata.service.ts +35 -0
  135. package/src/services/removed-field-migration.service.ts +334 -0
  136. package/src/solid-core.module.ts +4 -0
  137. package/src/subscribers/audit.subscriber.ts +70 -5
  138. package/.claude/settings.local.json +0 -15
  139. package/CLAUDE.md +0 -26
  140. package/dist/entities/legacy-common-with-id.entity.d.ts.map +0 -1
  141. package/dist/entities/legacy-common-with-id.entity.js.map +0 -1
  142. package/dist/entities/legacy-common.entity.d.ts.map +0 -1
  143. package/dist/entities/legacy-common.entity.js.map +0 -1
  144. package/src/services/1.js +0 -6
  145. /package/src/entities/{legacy-common.entity.ts → legacy-common.entity-with-existing-id.entity.ts} +0 -0
@@ -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),