@carlonicora/nestjs-neo4jsonapi 1.57.0 → 1.58.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 (54) hide show
  1. package/dist/common/decorators/audit.decorator.d.ts +1 -1
  2. package/dist/common/decorators/audit.decorator.js +2 -2
  3. package/dist/common/decorators/audit.decorator.js.map +1 -1
  4. package/dist/common/decorators/index.d.ts +0 -1
  5. package/dist/common/decorators/index.d.ts.map +1 -1
  6. package/dist/common/decorators/index.js +0 -1
  7. package/dist/common/decorators/index.js.map +1 -1
  8. package/dist/common/guards/jwt.auth.guard.d.ts.map +1 -1
  9. package/dist/common/guards/jwt.auth.guard.js +1 -0
  10. package/dist/common/guards/jwt.auth.guard.js.map +1 -1
  11. package/dist/core/neo4j/abstracts/abstract.service.d.ts +3 -1
  12. package/dist/core/neo4j/abstracts/abstract.service.d.ts.map +1 -1
  13. package/dist/core/neo4j/abstracts/abstract.service.js +36 -1
  14. package/dist/core/neo4j/abstracts/abstract.service.js.map +1 -1
  15. package/dist/foundations/audit/audit.module.js +1 -1
  16. package/dist/foundations/audit/audit.module.js.map +1 -1
  17. package/dist/foundations/audit/controllers/audit.controller.d.ts +3 -2
  18. package/dist/foundations/audit/controllers/audit.controller.d.ts.map +1 -1
  19. package/dist/foundations/audit/controllers/audit.controller.js +27 -7
  20. package/dist/foundations/audit/controllers/audit.controller.js.map +1 -1
  21. package/dist/foundations/audit/entities/audit.entity.d.ts +9 -3
  22. package/dist/foundations/audit/entities/audit.entity.d.ts.map +1 -1
  23. package/dist/foundations/audit/entities/audit.map.d.ts +3 -3
  24. package/dist/foundations/audit/entities/audit.map.d.ts.map +1 -1
  25. package/dist/foundations/audit/entities/audit.map.js +11 -6
  26. package/dist/foundations/audit/entities/audit.map.js.map +1 -1
  27. package/dist/foundations/audit/entities/audit.meta.d.ts +1 -1
  28. package/dist/foundations/audit/entities/audit.meta.d.ts.map +1 -1
  29. package/dist/foundations/audit/entities/audit.meta.js +6 -6
  30. package/dist/foundations/audit/entities/audit.meta.js.map +1 -1
  31. package/dist/foundations/audit/entities/audit.model.d.ts +2 -2
  32. package/dist/foundations/audit/entities/audit.model.d.ts.map +1 -1
  33. package/dist/foundations/audit/entities/audit.model.js +7 -8
  34. package/dist/foundations/audit/entities/audit.model.js.map +1 -1
  35. package/dist/foundations/audit/index.d.ts +3 -3
  36. package/dist/foundations/audit/index.d.ts.map +1 -1
  37. package/dist/foundations/audit/index.js +3 -3
  38. package/dist/foundations/audit/index.js.map +1 -1
  39. package/dist/foundations/audit/repositories/audit.repository.d.ts +18 -8
  40. package/dist/foundations/audit/repositories/audit.repository.d.ts.map +1 -1
  41. package/dist/foundations/audit/repositories/audit.repository.js +68 -27
  42. package/dist/foundations/audit/repositories/audit.repository.js.map +1 -1
  43. package/dist/foundations/audit/serialisers/audit.serialiser.d.ts.map +1 -1
  44. package/dist/foundations/audit/serialisers/audit.serialiser.js +10 -4
  45. package/dist/foundations/audit/serialisers/audit.serialiser.js.map +1 -1
  46. package/dist/foundations/audit/services/audit.service.d.ts +26 -6
  47. package/dist/foundations/audit/services/audit.service.d.ts.map +1 -1
  48. package/dist/foundations/audit/services/audit.service.js +126 -17
  49. package/dist/foundations/audit/services/audit.service.js.map +1 -1
  50. package/package.json +1 -1
  51. package/dist/common/decorators/write-audit.decorator.d.ts +0 -10
  52. package/dist/common/decorators/write-audit.decorator.d.ts.map +0 -1
  53. package/dist/common/decorators/write-audit.decorator.js +0 -55
  54. package/dist/common/decorators/write-audit.decorator.js.map +0 -1
@@ -1,21 +1,31 @@
1
1
  import { OnModuleInit } from "@nestjs/common";
2
2
  import { JsonApiCursorInterface } from "../../../core/jsonapi/interfaces/jsonapi.cursor.interface";
3
3
  import { Neo4jService } from "../../../core/neo4j/services/neo4j.service";
4
- import { Audit } from "../../audit/entities/audit.entity";
4
+ import { AuditLog } from "../entities/audit.entity";
5
5
  export declare class AuditRepository implements OnModuleInit {
6
6
  private readonly neo4jService;
7
7
  constructor(neo4jService: Neo4jService);
8
8
  onModuleInit(): Promise<void>;
9
- findByUser(params: {
10
- userId: string;
11
- cursor?: JsonApiCursorInterface;
12
- }): Promise<Audit[]>;
13
- create(params: {
9
+ createEntry(params: {
14
10
  userId: string;
11
+ companyId: string;
12
+ ipAddress: string;
13
+ action: string;
15
14
  entityType: string;
16
15
  entityId: string;
17
- auditType: string;
18
- changes?: string;
16
+ fieldName: string | null;
17
+ oldValue: string | null;
18
+ newValue: string | null;
19
19
  }): Promise<void>;
20
+ findByEntity(params: {
21
+ entityType: string;
22
+ entityId: string;
23
+ companyId: string;
24
+ cursor?: JsonApiCursorInterface;
25
+ }): Promise<AuditLog[]>;
26
+ findByUser(params: {
27
+ userId: string;
28
+ cursor?: JsonApiCursorInterface;
29
+ }): Promise<AuditLog[]>;
20
30
  }
21
31
  //# sourceMappingURL=audit.repository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/audit/repositories/audit.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2DAA2D,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAK1D,qBACa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,YAAY;IAEjD,YAAY;IAMZ,UAAU,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,sBAAsB,CAAA;KAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAkBzF,MAAM,CAAC,MAAM,EAAE;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,IAAI,CAAC;CA4BlB"}
1
+ {"version":3,"file":"audit.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/audit/repositories/audit.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2DAA2D,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAKpD,qBACa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,YAAY;IAEjD,YAAY;IAYZ,WAAW,CAAC,MAAM,EAAE;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CX,YAAY,CAAC,MAAM,EAAE;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,sBAAsB,CAAC;KACjC,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAwBjB,UAAU,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,sBAAsB,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAiBnG"}
@@ -13,8 +13,8 @@ exports.AuditRepository = void 0;
13
13
  const common_1 = require("@nestjs/common");
14
14
  const crypto_1 = require("crypto");
15
15
  const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
16
- const audit_meta_1 = require("../../audit/entities/audit.meta");
17
- const audit_model_1 = require("../../audit/entities/audit.model");
16
+ const audit_meta_1 = require("../entities/audit.meta");
17
+ const audit_model_1 = require("../entities/audit.model");
18
18
  const user_meta_1 = require("../../user/entities/user.meta");
19
19
  let AuditRepository = class AuditRepository {
20
20
  constructor(neo4jService) {
@@ -22,49 +22,90 @@ let AuditRepository = class AuditRepository {
22
22
  }
23
23
  async onModuleInit() {
24
24
  await this.neo4jService.writeOne({
25
- query: `CREATE CONSTRAINT ${audit_meta_1.auditMeta.nodeName}_id IF NOT EXISTS FOR (${audit_meta_1.auditMeta.nodeName}:${audit_meta_1.auditMeta.labelName}) REQUIRE ${audit_meta_1.auditMeta.nodeName}.id IS UNIQUE`,
25
+ query: `CREATE CONSTRAINT ${audit_meta_1.auditLogMeta.nodeName}_id IF NOT EXISTS FOR (${audit_meta_1.auditLogMeta.nodeName}:${audit_meta_1.auditLogMeta.labelName}) REQUIRE ${audit_meta_1.auditLogMeta.nodeName}.id IS UNIQUE`,
26
+ });
27
+ await this.neo4jService.writeOne({
28
+ query: `CREATE INDEX audit_entity IF NOT EXISTS FOR (a:${audit_meta_1.auditLogMeta.labelName}) ON (a.entity_type, a.entity_id)`,
29
+ });
30
+ await this.neo4jService.writeOne({
31
+ query: `CREATE INDEX audit_timestamp IF NOT EXISTS FOR (a:${audit_meta_1.auditLogMeta.labelName}) ON (a.company_id, a.createdAt)`,
26
32
  });
27
33
  }
28
- async findByUser(params) {
29
- const query = this.neo4jService.initQuery({ serialiser: audit_model_1.auditModel, cursor: params.cursor });
30
- query.queryParams = {
31
- ...query.queryParams,
32
- userId: params.userId,
33
- };
34
- query.query = `
35
- MATCH (audit_user:${user_meta_1.userMeta.labelName} {id: $userId})-[:INITIATED]->(audit:${audit_meta_1.auditMeta.labelName})
36
- OPTIONAL MATCH (audit)-[:AUDITED]->(audit_audited)
37
- RETURN audit, audit_user, audit_audited, labels(audit_audited) as audit_audited_labels
38
- ORDER BY audit.createdAt DESC
39
- `;
40
- return this.neo4jService.readMany(query);
41
- }
42
- async create(params) {
34
+ async createEntry(params) {
43
35
  const query = this.neo4jService.initQuery();
44
36
  query.queryParams = {
45
37
  ...query.queryParams,
46
38
  id: (0, crypto_1.randomUUID)(),
47
39
  userId: params.userId,
40
+ companyId: params.companyId,
41
+ ipAddress: params.ipAddress,
42
+ action: params.action,
43
+ entityType: params.entityType,
48
44
  entityId: params.entityId,
49
- auditType: params.auditType,
50
- changes: params.changes ?? null,
45
+ fieldName: params.fieldName,
46
+ oldValue: params.oldValue,
47
+ newValue: params.newValue,
51
48
  };
52
49
  query.query += `
53
50
  MATCH (${user_meta_1.userMeta.nodeName}:${user_meta_1.userMeta.labelName} {id: $userId})
54
- MATCH (audited:${params.entityType} {id: $entityId})
55
- CREATE (${audit_meta_1.auditMeta.nodeName}:${audit_meta_1.auditMeta.labelName} {
51
+ CREATE (${audit_meta_1.auditLogMeta.nodeName}:${audit_meta_1.auditLogMeta.labelName} {
56
52
  id: $id,
57
- auditType: $auditType,
58
- changes: $changes,
53
+ action: $action,
54
+ entity_type: $entityType,
55
+ entity_id: $entityId,
56
+ field_name: $fieldName,
57
+ old_value: $oldValue,
58
+ new_value: $newValue,
59
+ ip_address: $ipAddress,
60
+ company_id: $companyId,
59
61
  createdAt: datetime(),
60
62
  updatedAt: datetime()
61
63
  })
62
- WITH ${user_meta_1.userMeta.nodeName}, ${audit_meta_1.auditMeta.nodeName}, audited
63
- CREATE (${user_meta_1.userMeta.nodeName})-[:INITIATED]->(${audit_meta_1.auditMeta.nodeName})
64
- CREATE (${audit_meta_1.auditMeta.nodeName})-[:AUDITED]->(audited)
64
+ WITH ${user_meta_1.userMeta.nodeName}, ${audit_meta_1.auditLogMeta.nodeName}
65
+ CREATE (${user_meta_1.userMeta.nodeName})-[:PERFORMED]->(${audit_meta_1.auditLogMeta.nodeName})
66
+ WITH ${audit_meta_1.auditLogMeta.nodeName}
67
+ OPTIONAL MATCH (audited {id: $entityId})
68
+ WHERE $entityType IN labels(audited)
69
+ FOREACH (_ IN CASE WHEN audited IS NOT NULL THEN [1] ELSE [] END |
70
+ CREATE (${audit_meta_1.auditLogMeta.nodeName})-[:AUDITED]->(audited)
71
+ )
65
72
  `;
66
73
  await this.neo4jService.writeOne(query);
67
74
  }
75
+ async findByEntity(params) {
76
+ const query = this.neo4jService.initQuery({ serialiser: audit_model_1.auditLogModel, cursor: params.cursor });
77
+ query.queryParams = {
78
+ ...query.queryParams,
79
+ entityType: params.entityType,
80
+ entityId: params.entityId,
81
+ companyId: params.companyId,
82
+ };
83
+ query.query = `
84
+ MATCH (${audit_meta_1.auditLogMeta.nodeName}_user:${user_meta_1.userMeta.labelName})-[:PERFORMED]->(${audit_meta_1.auditLogMeta.nodeName}:${audit_meta_1.auditLogMeta.labelName} {
85
+ entity_type: $entityType,
86
+ entity_id: $entityId,
87
+ company_id: $companyId
88
+ })
89
+ OPTIONAL MATCH (${audit_meta_1.auditLogMeta.nodeName})-[:AUDITED]->(${audit_meta_1.auditLogMeta.nodeName}_audited)
90
+ RETURN ${audit_meta_1.auditLogMeta.nodeName}, ${audit_meta_1.auditLogMeta.nodeName}_user, ${audit_meta_1.auditLogMeta.nodeName}_audited, labels(${audit_meta_1.auditLogMeta.nodeName}_audited) as ${audit_meta_1.auditLogMeta.nodeName}_audited_labels
91
+ ORDER BY ${audit_meta_1.auditLogMeta.nodeName}.createdAt DESC
92
+ `;
93
+ return this.neo4jService.readMany(query);
94
+ }
95
+ async findByUser(params) {
96
+ const query = this.neo4jService.initQuery({ serialiser: audit_model_1.auditLogModel, cursor: params.cursor });
97
+ query.queryParams = {
98
+ ...query.queryParams,
99
+ userId: params.userId,
100
+ };
101
+ query.query = `
102
+ MATCH (${audit_meta_1.auditLogMeta.nodeName}_user:${user_meta_1.userMeta.labelName} {id: $userId})-[:PERFORMED]->(${audit_meta_1.auditLogMeta.nodeName}:${audit_meta_1.auditLogMeta.labelName})
103
+ OPTIONAL MATCH (${audit_meta_1.auditLogMeta.nodeName})-[:AUDITED]->(${audit_meta_1.auditLogMeta.nodeName}_audited)
104
+ RETURN ${audit_meta_1.auditLogMeta.nodeName}, ${audit_meta_1.auditLogMeta.nodeName}_user, ${audit_meta_1.auditLogMeta.nodeName}_audited, labels(${audit_meta_1.auditLogMeta.nodeName}_audited) as ${audit_meta_1.auditLogMeta.nodeName}_audited_labels
105
+ ORDER BY ${audit_meta_1.auditLogMeta.nodeName}.createdAt DESC
106
+ `;
107
+ return this.neo4jService.readMany(query);
108
+ }
68
109
  };
69
110
  exports.AuditRepository = AuditRepository;
70
111
  exports.AuditRepository = AuditRepository = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"audit.repository.js","sourceRoot":"","sources":["../../../../src/foundations/audit/repositories/audit.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA0D;AAC1D,mCAAoC;AAEpC,8EAA0E;AAE1E,gEAA4D;AAC5D,kEAA8D;AAC9D,6DAAyD;AAGlD,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,YAA6B,YAA0B;QAA1B,iBAAY,GAAZ,YAAY,CAAc;IAAG,CAAC;IAE3D,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;YAC/B,KAAK,EAAE,qBAAqB,sBAAS,CAAC,QAAQ,0BAA0B,sBAAS,CAAC,QAAQ,IAAI,sBAAS,CAAC,SAAS,aAAa,sBAAS,CAAC,QAAQ,eAAe;SAChK,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAA2D;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,wBAAU,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAE7F,KAAK,CAAC,WAAW,GAAG;YAClB,GAAG,KAAK,CAAC,WAAW;YACpB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC;QAEF,KAAK,CAAC,KAAK,GAAG;4BACU,oBAAQ,CAAC,SAAS,wCAAwC,sBAAS,CAAC,SAAS;;;;KAIpG,CAAC;QAEF,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAMZ;QACC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;QAC5C,KAAK,CAAC,WAAW,GAAG;YAClB,GAAG,KAAK,CAAC,WAAW;YACpB,EAAE,EAAE,IAAA,mBAAU,GAAE;YAChB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;SAChC,CAAC;QAEF,KAAK,CAAC,KAAK,IAAI;iBACF,oBAAQ,CAAC,QAAQ,IAAI,oBAAQ,CAAC,SAAS;yBAC/B,MAAM,CAAC,UAAU;kBACxB,sBAAS,CAAC,QAAQ,IAAI,sBAAS,CAAC,SAAS;;;;;;;eAO5C,oBAAQ,CAAC,QAAQ,KAAK,sBAAS,CAAC,QAAQ;kBACrC,oBAAQ,CAAC,QAAQ,oBAAoB,sBAAS,CAAC,QAAQ;kBACvD,sBAAS,CAAC,QAAQ;KAC/B,CAAC;QAEF,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;CACF,CAAA;AA7DY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;qCAEgC,4BAAY;GAD5C,eAAe,CA6D3B"}
1
+ {"version":3,"file":"audit.repository.js","sourceRoot":"","sources":["../../../../src/foundations/audit/repositories/audit.repository.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"audit.serialiser.d.ts","sourceRoot":"","sources":["../../../../src/foundations/audit/serialisers/audit.serialiser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6DAA6D,CAAC;AACxG,OAAO,EAAE,0BAA0B,EAAE,MAAM,8DAA8D,CAAC;AAC1G,OAAO,EAAE,wBAAwB,EAAE,MAAM,4DAA4D,CAAC;AACtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,yDAAyD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AAIrG,qBACa,eAAgB,SAAQ,yBAA0B,YAAW,uBAAuB;IAG7F,OAAO,CAAC,QAAQ,CAAC,0BAA0B;gBAD3C,iBAAiB,EAAE,wBAAwB,EAC1B,0BAA0B,EAAE,0BAA0B,EACvE,aAAa,EAAE,aAAa,CAAC,mBAAmB,CAAC;IAKnD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,MAAM,IAAI,oBAAoB;CAoB/B"}
1
+ {"version":3,"file":"audit.serialiser.d.ts","sourceRoot":"","sources":["../../../../src/foundations/audit/serialisers/audit.serialiser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6DAA6D,CAAC;AACxG,OAAO,EAAE,0BAA0B,EAAE,MAAM,8DAA8D,CAAC;AAC1G,OAAO,EAAE,wBAAwB,EAAE,MAAM,4DAA4D,CAAC;AACtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,yDAAyD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AAIrG,qBACa,eAAgB,SAAQ,yBAA0B,YAAW,uBAAuB;IAG7F,OAAO,CAAC,QAAQ,CAAC,0BAA0B;gBAD3C,iBAAiB,EAAE,wBAAwB,EAC1B,0BAA0B,EAAE,0BAA0B,EACvE,aAAa,EAAE,aAAa,CAAC,mBAAmB,CAAC;IAKnD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,MAAM,IAAI,oBAAoB;CA0B/B"}
@@ -15,7 +15,7 @@ const config_1 = require("@nestjs/config");
15
15
  const abstract_jsonapi_serialiser_1 = require("../../../core/jsonapi/abstracts/abstract.jsonapi.serialiser");
16
16
  const dynamic_relationship_factory_1 = require("../../../core/jsonapi/factories/dynamic.relationship.factory");
17
17
  const jsonapi_serialiser_factory_1 = require("../../../core/jsonapi/factories/jsonapi.serialiser.factory");
18
- const audit_meta_1 = require("../../audit/entities/audit.meta");
18
+ const audit_meta_1 = require("../entities/audit.meta");
19
19
  const user_1 = require("../../user/entities/user");
20
20
  let AuditSerialiser = class AuditSerialiser extends abstract_jsonapi_serialiser_1.AbstractJsonApiSerialiser {
21
21
  constructor(serialiserFactory, dynamicRelationshipFactory, configService) {
@@ -23,12 +23,18 @@ let AuditSerialiser = class AuditSerialiser extends abstract_jsonapi_serialiser_
23
23
  this.dynamicRelationshipFactory = dynamicRelationshipFactory;
24
24
  }
25
25
  get type() {
26
- return audit_meta_1.auditMeta.endpoint;
26
+ return audit_meta_1.auditLogMeta.endpoint;
27
27
  }
28
28
  create() {
29
29
  this.attributes = {
30
- auditType: "auditType",
31
- changes: "changes",
30
+ action: "action",
31
+ entityType: "entity_type",
32
+ entityId: "entity_id",
33
+ fieldName: "field_name",
34
+ oldValue: "old_value",
35
+ newValue: "new_value",
36
+ ipAddress: "ip_address",
37
+ companyId: "company_id",
32
38
  };
33
39
  const dynamicRel = this.dynamicRelationshipFactory.createDynamicRelationship(null);
34
40
  this.relationships = {
@@ -1 +1 @@
1
- {"version":3,"file":"audit.serialiser.js","sourceRoot":"","sources":["../../../../src/foundations/audit/serialisers/audit.serialiser.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAA+C;AAE/C,6GAAwG;AACxG,+GAA0G;AAC1G,2GAAsG;AAGtG,gEAA4D;AAC5D,mDAA0D;AAGnD,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,uDAAyB;IAC5D,YACE,iBAA2C,EAC1B,0BAAsD,EACvE,aAAiD;QAEjD,KAAK,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;QAHvB,+BAA0B,GAA1B,0BAA0B,CAA4B;IAIzE,CAAC;IAED,IAAI,IAAI;QACN,OAAO,sBAAS,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,UAAU,GAAG;YAChB,SAAS,EAAE,WAAW;YACtB,OAAO,EAAE,SAAS;SACnB,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,0BAA0B,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAEnF,IAAI,CAAC,aAAa,GAAG;YACnB,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,qBAAc,CAAC,KAAK,CAAC;aAC1D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,UAAU;gBAChB,cAAc,EAAE,IAAI,CAAC,0BAA0B;aAChD;SACF,CAAC;QAEF,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC;CACF,CAAA;AAjCY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;qCAGU,qDAAwB;QACE,yDAA0B;QACxD,sBAAa;GAJnB,eAAe,CAiC3B"}
1
+ {"version":3,"file":"audit.serialiser.js","sourceRoot":"","sources":["../../../../src/foundations/audit/serialisers/audit.serialiser.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAA+C;AAE/C,6GAAwG;AACxG,+GAA0G;AAC1G,2GAAsG;AAGtG,uDAAsD;AACtD,mDAA0D;AAGnD,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,uDAAyB;IAC5D,YACE,iBAA2C,EAC1B,0BAAsD,EACvE,aAAiD;QAEjD,KAAK,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;QAHvB,+BAA0B,GAA1B,0BAA0B,CAA4B;IAIzE,CAAC;IAED,IAAI,IAAI;QACN,OAAO,yBAAY,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,UAAU,GAAG;YAChB,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,WAAW;YACrB,SAAS,EAAE,YAAY;YACvB,QAAQ,EAAE,WAAW;YACrB,QAAQ,EAAE,WAAW;YACrB,SAAS,EAAE,YAAY;YACvB,SAAS,EAAE,YAAY;SACxB,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,0BAA0B,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAEnF,IAAI,CAAC,aAAa,GAAG;YACnB,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,qBAAc,CAAC,KAAK,CAAC;aAC1D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,UAAU;gBAChB,cAAc,EAAE,IAAI,CAAC,0BAA0B;aAChD;SACF,CAAC;QAEF,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC;CACF,CAAA;AAvCY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;qCAGU,qDAAwB;QACE,yDAA0B;QACxD,sBAAa;GAJnB,eAAe,CAuC3B"}
@@ -1,24 +1,44 @@
1
1
  import { ClsService } from "nestjs-cls";
2
+ import { EntityDescriptor } from "../../../common/interfaces/entity.schema.interface";
2
3
  import { JsonApiService } from "../../../core/jsonapi/services/jsonapi.service";
3
- import { AuditRepository } from "../../audit/repositories/audit.repository";
4
+ import { AuditRepository } from "../repositories/audit.repository";
4
5
  export declare class AuditService {
5
6
  private readonly builder;
6
7
  private readonly auditRepository;
7
8
  private readonly clsService;
8
9
  constructor(builder: JsonApiService, auditRepository: AuditRepository, clsService: ClsService);
9
- createAuditEntry(params: {
10
+ logCreate(params: {
10
11
  entityType: string;
11
12
  entityId: string;
12
13
  }): Promise<void>;
13
- createWriteAuditEntry(params: {
14
+ logRead(params: {
14
15
  entityType: string;
15
16
  entityId: string;
16
- auditType: "create" | "edit";
17
- changes?: string;
18
17
  }): Promise<void>;
18
+ logUpdate(params: {
19
+ entityType: string;
20
+ entityId: string;
21
+ before: any;
22
+ after: Record<string, any>;
23
+ descriptor: EntityDescriptor<any, any>;
24
+ }): Promise<void>;
25
+ logDelete(params: {
26
+ entityType: string;
27
+ entityId: string;
28
+ snapshot: any;
29
+ descriptor: EntityDescriptor<any, any>;
30
+ }): Promise<void>;
31
+ findByEntity(params: {
32
+ entityType: string;
33
+ entityId: string;
34
+ query: any;
35
+ }): Promise<any>;
19
36
  findByUser(params: {
20
37
  query: any;
21
38
  userId: string;
22
- }): Promise<void>;
39
+ }): Promise<any>;
40
+ private diffChanges;
41
+ private snapshotEntity;
42
+ private stringify;
23
43
  }
24
44
  //# sourceMappingURL=audit.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/audit/services/audit.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAEhF,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAE5E,qBACa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAFV,OAAO,EAAE,cAAc,EACvB,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU;IAGnC,gBAAgB,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAajF,qBAAqB,CAAC,MAAM,EAAE;QAClC,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,QAAQ,GAAG,MAAM,CAAC;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,IAAI,CAAC;IAaX,UAAU,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAcxE"}
1
+ {"version":3,"file":"audit.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/audit/services/audit.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAEhF,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AASnE,qBACa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAFV,OAAO,EAAE,cAAc,EACvB,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU;IAGnC,SAAS,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1E,OAAO,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxE,SAAS,CAAC,MAAM,EAAE;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,GAAG,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,UAAU,EAAE,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;KACxC,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBX,SAAS,CAAC,MAAM,EAAE;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,GAAG,CAAC;QACd,UAAU,EAAE,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;KACxC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBX,YAAY,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAexF,UAAU,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAatE,OAAO,CAAC,WAAW;IAiDnB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,SAAS;CAKlB"}
@@ -14,47 +14,156 @@ const common_1 = require("@nestjs/common");
14
14
  const nestjs_cls_1 = require("nestjs-cls");
15
15
  const jsonapi_paginator_1 = require("../../../core/jsonapi/serialisers/jsonapi.paginator");
16
16
  const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
17
- const audit_model_1 = require("../../audit/entities/audit.model");
18
- const audit_repository_1 = require("../../audit/repositories/audit.repository");
17
+ const audit_model_1 = require("../entities/audit.model");
18
+ const audit_repository_1 = require("../repositories/audit.repository");
19
19
  let AuditService = class AuditService {
20
20
  constructor(builder, auditRepository, clsService) {
21
21
  this.builder = builder;
22
22
  this.auditRepository = auditRepository;
23
23
  this.clsService = clsService;
24
24
  }
25
- async createAuditEntry(params) {
25
+ async logCreate(params) {
26
26
  const userId = this.clsService.get("userId");
27
27
  if (!userId)
28
28
  return;
29
- await this.auditRepository.create({
30
- userId: userId,
29
+ await this.auditRepository.createEntry({
30
+ userId,
31
+ companyId: this.clsService.get("companyId"),
32
+ ipAddress: this.clsService.get("ipAddress") ?? "",
33
+ action: "create",
31
34
  entityType: params.entityType,
32
35
  entityId: params.entityId,
33
- auditType: "read",
34
- changes: undefined,
36
+ fieldName: null,
37
+ oldValue: null,
38
+ newValue: null,
35
39
  });
36
40
  }
37
- async createWriteAuditEntry(params) {
41
+ async logRead(params) {
38
42
  const userId = this.clsService.get("userId");
39
43
  if (!userId)
40
44
  return;
41
- await this.auditRepository.create({
42
- userId: userId,
45
+ await this.auditRepository.createEntry({
46
+ userId,
47
+ companyId: this.clsService.get("companyId"),
48
+ ipAddress: this.clsService.get("ipAddress") ?? "",
49
+ action: "read",
43
50
  entityType: params.entityType,
44
51
  entityId: params.entityId,
45
- auditType: params.auditType,
46
- changes: params.changes,
52
+ fieldName: null,
53
+ oldValue: null,
54
+ newValue: null,
47
55
  });
48
56
  }
57
+ async logUpdate(params) {
58
+ const userId = this.clsService.get("userId");
59
+ if (!userId)
60
+ return;
61
+ const changes = this.diffChanges(params.before, params.after, params.descriptor);
62
+ if (changes.length === 0)
63
+ return;
64
+ const companyId = this.clsService.get("companyId");
65
+ const ipAddress = this.clsService.get("ipAddress") ?? "";
66
+ for (const change of changes) {
67
+ await this.auditRepository.createEntry({
68
+ userId,
69
+ companyId,
70
+ ipAddress,
71
+ action: change.isStatusChange ? "status_change" : "update",
72
+ entityType: params.entityType,
73
+ entityId: params.entityId,
74
+ fieldName: change.fieldName,
75
+ oldValue: change.oldValue,
76
+ newValue: change.newValue,
77
+ });
78
+ }
79
+ }
80
+ async logDelete(params) {
81
+ const userId = this.clsService.get("userId");
82
+ if (!userId)
83
+ return;
84
+ const snapshotStr = this.snapshotEntity(params.snapshot, params.descriptor);
85
+ await this.auditRepository.createEntry({
86
+ userId,
87
+ companyId: this.clsService.get("companyId"),
88
+ ipAddress: this.clsService.get("ipAddress") ?? "",
89
+ action: "delete",
90
+ entityType: params.entityType,
91
+ entityId: params.entityId,
92
+ fieldName: null,
93
+ oldValue: snapshotStr,
94
+ newValue: null,
95
+ });
96
+ }
97
+ async findByEntity(params) {
98
+ const paginator = new jsonapi_paginator_1.JsonApiPaginator(params.query);
99
+ return this.builder.buildList(audit_model_1.auditLogModel, await this.auditRepository.findByEntity({
100
+ entityType: params.entityType,
101
+ entityId: params.entityId,
102
+ companyId: this.clsService.get("companyId"),
103
+ cursor: paginator.generateCursor(),
104
+ }), paginator);
105
+ }
49
106
  async findByUser(params) {
50
107
  const paginator = new jsonapi_paginator_1.JsonApiPaginator(params.query);
51
- try {
52
- return this.builder.buildList(audit_model_1.auditModel, await this.auditRepository.findByUser({ userId: params.userId, cursor: paginator.generateCursor() }), paginator);
108
+ return this.builder.buildList(audit_model_1.auditLogModel, await this.auditRepository.findByUser({
109
+ userId: params.userId,
110
+ cursor: paginator.generateCursor(),
111
+ }), paginator);
112
+ }
113
+ diffChanges(before, after, descriptor) {
114
+ const changes = [];
115
+ // Diff attribute fields
116
+ for (const fieldName of descriptor.fieldNames) {
117
+ if (!(fieldName in after))
118
+ continue;
119
+ const oldVal = before[fieldName];
120
+ const newVal = after[fieldName];
121
+ const oldStr = this.stringify(oldVal);
122
+ const newStr = this.stringify(newVal);
123
+ if (oldStr !== newStr) {
124
+ changes.push({
125
+ fieldName,
126
+ oldValue: oldStr,
127
+ newValue: newStr,
128
+ isStatusChange: fieldName === "status",
129
+ });
130
+ }
53
131
  }
54
- catch (error) {
55
- console.error("Error in findByUser:", error);
56
- throw error;
132
+ // Diff relationships
133
+ for (const [relationshipKey, _relationshipDef] of Object.entries(descriptor.relationships)) {
134
+ if (!(relationshipKey in after))
135
+ continue;
136
+ const oldRel = before[relationshipKey];
137
+ const newRel = after[relationshipKey];
138
+ // Extract ID from old relationship (could be object with .id or just a string)
139
+ const oldId = typeof oldRel === "object" && oldRel !== null ? oldRel.id : oldRel;
140
+ const newId = typeof newRel === "object" && newRel !== null ? newRel.id : newRel;
141
+ const oldStr = this.stringify(oldId);
142
+ const newStr = this.stringify(newId);
143
+ if (oldStr !== newStr) {
144
+ changes.push({
145
+ fieldName: relationshipKey,
146
+ oldValue: oldStr,
147
+ newValue: newStr,
148
+ isStatusChange: false,
149
+ });
150
+ }
57
151
  }
152
+ return changes;
153
+ }
154
+ snapshotEntity(entity, descriptor) {
155
+ const snapshot = {};
156
+ for (const fieldName of descriptor.fieldNames) {
157
+ snapshot[fieldName] = entity[fieldName] ?? null;
158
+ }
159
+ return JSON.stringify(snapshot);
160
+ }
161
+ stringify(value) {
162
+ if (value === undefined || value === null)
163
+ return null;
164
+ if (typeof value === "string")
165
+ return value;
166
+ return JSON.stringify(value);
58
167
  }
59
168
  };
60
169
  exports.AuditService = AuditService;
@@ -1 +1 @@
1
- {"version":3,"file":"audit.service.js","sourceRoot":"","sources":["../../../../src/foundations/audit/services/audit.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAAwC;AACxC,2FAAuF;AACvF,oFAAgF;AAChF,kEAA8D;AAC9D,gFAA4E;AAGrE,IAAM,YAAY,GAAlB,MAAM,YAAY;IACvB,YACmB,OAAuB,EACvB,eAAgC,EAChC,UAAsB;QAFtB,YAAO,GAAP,OAAO,CAAgB;QACvB,oBAAe,GAAf,eAAe,CAAiB;QAChC,eAAU,GAAV,UAAU,CAAY;IACtC,CAAC;IAEJ,KAAK,CAAC,gBAAgB,CAAC,MAAgD;QACrE,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;YAChC,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,MAK3B;QACC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;YAChC,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAsC;QACrD,MAAM,SAAS,GAAqB,IAAI,oCAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEvE,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAC3B,wBAAU,EACV,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,CAAC,EACpG,SAAS,CACV,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF,CAAA;AApDY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAGiB,gCAAc;QACN,kCAAe;QACpB,uBAAU;GAJ9B,YAAY,CAoDxB"}
1
+ {"version":3,"file":"audit.service.js","sourceRoot":"","sources":["../../../../src/foundations/audit/services/audit.service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carlonicora/nestjs-neo4jsonapi",
3
- "version": "1.57.0",
3
+ "version": "1.58.0",
4
4
  "description": "NestJS foundation package with JSON:API, Neo4j, Redis, LangChain agents, and common utilities",
5
5
  "author": "Carlo Nicora",
6
6
  "license": "GPL-3.0-or-later",
@@ -1,10 +0,0 @@
1
- import { DataMeta } from "../interfaces/datamodel.interface";
2
- /**
3
- * Decorator that automatically logs a write audit entry after the method executes.
4
- * Captures the submitted JSON:API body data (attributes + relationships) as the changes record.
5
- *
6
- * @param meta - The entity metadata (provides labelName for audit)
7
- * @param auditType - The type of write operation: "create" or "edit"
8
- */
9
- export declare function WriteAudit(meta: DataMeta, auditType: "create" | "edit"): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
10
- //# sourceMappingURL=write-audit.decorator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"write-audit.decorator.d.ts","sourceRoot":"","sources":["../../../src/common/decorators/write-audit.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAY7D;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAG,MAAM,IACpD,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,wBAqClF"}
@@ -1,55 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WriteAudit = WriteAudit;
4
- const REDACTED_FIELDS = new Set([
5
- "password",
6
- "passwordHash",
7
- "token",
8
- "secret",
9
- "apiKey",
10
- "refreshToken",
11
- "accessToken",
12
- ]);
13
- /**
14
- * Decorator that automatically logs a write audit entry after the method executes.
15
- * Captures the submitted JSON:API body data (attributes + relationships) as the changes record.
16
- *
17
- * @param meta - The entity metadata (provides labelName for audit)
18
- * @param auditType - The type of write operation: "create" or "edit"
19
- */
20
- function WriteAudit(meta, auditType) {
21
- return function (target, propertyKey, descriptor) {
22
- const originalMethod = descriptor.value;
23
- descriptor.value = async function (...args) {
24
- const result = await originalMethod.apply(this, args);
25
- // Extract entity ID and body data from request body (JSON:API format)
26
- const body = args.find((arg) => arg?.data?.id || arg?.data?.type);
27
- const entityId = body?.data?.id;
28
- if (entityId && this.auditService) {
29
- // Capture the submitted data as changes
30
- const changes = {};
31
- if (body.data.attributes) {
32
- const sanitised = { ...body.data.attributes };
33
- for (const key of Object.keys(sanitised)) {
34
- if (REDACTED_FIELDS.has(key)) {
35
- sanitised[key] = "[REDACTED]";
36
- }
37
- }
38
- changes.attributes = sanitised;
39
- }
40
- if (body.data.relationships) {
41
- changes.relationships = body.data.relationships;
42
- }
43
- await this.auditService.createWriteAuditEntry({
44
- entityType: meta.labelName,
45
- entityId: entityId,
46
- auditType,
47
- changes: Object.keys(changes).length > 0 ? JSON.stringify(changes) : undefined,
48
- });
49
- }
50
- return result;
51
- };
52
- return descriptor;
53
- };
54
- }
55
- //# sourceMappingURL=write-audit.decorator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"write-audit.decorator.js","sourceRoot":"","sources":["../../../src/common/decorators/write-audit.decorator.ts"],"names":[],"mappings":";;AAmBA,gCAsCC;AAvDD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,UAAU;IACV,cAAc;IACd,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,cAAc;IACd,aAAa;CACd,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,SAAgB,UAAU,CAAC,IAAc,EAAE,SAA4B;IACrE,OAAO,UAAU,MAAW,EAAE,WAAmB,EAAE,UAA8B;QAC/E,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QACxC,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAG,IAAW;YAC/C,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAEtD,sEAAsE;YACtE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAClE,MAAM,QAAQ,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YAEhC,IAAI,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClC,wCAAwC;gBACxC,MAAM,OAAO,GAAwB,EAAE,CAAC;gBACxC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBACzB,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBAC9C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;wBACzC,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;4BAC7B,SAAS,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;wBAChC,CAAC;oBACH,CAAC;oBACD,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;gBACjC,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;gBAClD,CAAC;gBAED,MAAM,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC;oBAC5C,UAAU,EAAE,IAAI,CAAC,SAAS;oBAC1B,QAAQ,EAAE,QAAkB;oBAC5B,SAAS;oBACT,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;iBAC/E,CAAC,CAAC;YACL,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QACF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC"}