@nest-omni/core 3.1.2-8 → 4.1.2-9

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 (94) hide show
  1. package/audit/audit.module.d.ts +10 -0
  2. package/audit/audit.module.js +231 -0
  3. package/audit/controllers/audit.controller.d.ts +20 -0
  4. package/audit/controllers/audit.controller.js +142 -0
  5. package/audit/controllers/index.d.ts +1 -0
  6. package/audit/controllers/index.js +17 -0
  7. package/audit/decorators/audit-controller.decorator.d.ts +5 -0
  8. package/audit/decorators/audit-controller.decorator.js +17 -0
  9. package/audit/decorators/audit-operation.decorator.d.ts +5 -0
  10. package/audit/decorators/audit-operation.decorator.js +23 -0
  11. package/audit/decorators/entity-audit.decorator.d.ts +5 -0
  12. package/audit/decorators/entity-audit.decorator.js +19 -0
  13. package/audit/decorators/index.d.ts +2 -0
  14. package/audit/decorators/index.js +18 -0
  15. package/audit/dto/audit-log-query.dto.d.ts +14 -0
  16. package/audit/dto/audit-log-query.dto.js +95 -0
  17. package/audit/dto/begin-transaction.dto.d.ts +3 -0
  18. package/audit/dto/begin-transaction.dto.js +22 -0
  19. package/audit/dto/compare-entities.dto.d.ts +6 -0
  20. package/audit/dto/compare-entities.dto.js +44 -0
  21. package/audit/dto/index.d.ts +5 -0
  22. package/audit/dto/index.js +21 -0
  23. package/audit/dto/pre-check-restore.dto.d.ts +5 -0
  24. package/audit/dto/pre-check-restore.dto.js +32 -0
  25. package/audit/dto/restore-entity.dto.d.ts +9 -0
  26. package/audit/dto/restore-entity.dto.js +53 -0
  27. package/audit/entities/entity-audit-log.entity.d.ts +18 -0
  28. package/audit/entities/entity-audit-log.entity.js +81 -0
  29. package/audit/entities/entity-transaction.entity.d.ts +14 -0
  30. package/audit/entities/entity-transaction.entity.js +51 -0
  31. package/audit/entities/index.d.ts +2 -0
  32. package/audit/entities/index.js +18 -0
  33. package/audit/entities/manual-operation-log.entity.d.ts +15 -0
  34. package/audit/entities/manual-operation-log.entity.js +82 -0
  35. package/audit/entities/operation-template.entity.d.ts +11 -0
  36. package/audit/entities/operation-template.entity.js +65 -0
  37. package/audit/enums/audit.enums.d.ts +27 -0
  38. package/audit/enums/audit.enums.js +35 -0
  39. package/audit/enums/index.d.ts +1 -0
  40. package/audit/enums/index.js +17 -0
  41. package/audit/index.d.ts +10 -0
  42. package/audit/index.js +26 -0
  43. package/audit/interceptors/audit.interceptor.d.ts +12 -0
  44. package/audit/interceptors/audit.interceptor.js +95 -0
  45. package/audit/interceptors/index.d.ts +1 -0
  46. package/audit/interceptors/index.js +17 -0
  47. package/audit/interfaces/audit.interfaces.d.ts +119 -0
  48. package/audit/interfaces/audit.interfaces.js +2 -0
  49. package/audit/interfaces/index.d.ts +1 -0
  50. package/audit/interfaces/index.js +17 -0
  51. package/audit/services/audit-context.service.d.ts +10 -0
  52. package/audit/services/audit-context.service.js +55 -0
  53. package/audit/services/audit-strategy.service.d.ts +19 -0
  54. package/audit/services/audit-strategy.service.js +89 -0
  55. package/audit/services/entity-audit.service.d.ts +37 -0
  56. package/audit/services/entity-audit.service.js +484 -0
  57. package/audit/services/index.d.ts +5 -0
  58. package/audit/services/index.js +21 -0
  59. package/audit/services/manual-audit-log.service.d.ts +29 -0
  60. package/audit/services/manual-audit-log.service.js +184 -0
  61. package/audit/services/multi-database.service.d.ts +10 -0
  62. package/audit/services/multi-database.service.js +59 -0
  63. package/audit/services/operation-description.service.d.ts +21 -0
  64. package/audit/services/operation-description.service.js +213 -0
  65. package/audit/services/transaction-audit.service.d.ts +22 -0
  66. package/audit/services/transaction-audit.service.js +201 -0
  67. package/audit/subscribers/entity-audit.subscriber.d.ts +14 -0
  68. package/audit/subscribers/entity-audit.subscriber.js +136 -0
  69. package/audit/subscribers/index.d.ts +1 -0
  70. package/audit/subscribers/index.js +17 -0
  71. package/common/abstract.entity.js +1 -1
  72. package/http-client/examples/advanced-usage.example.js +14 -1
  73. package/http-client/examples/auth-with-waiting-lock.example.d.ts +17 -0
  74. package/http-client/examples/auth-with-waiting-lock.example.js +336 -0
  75. package/http-client/examples/basic-usage.example.d.ts +1 -9
  76. package/http-client/examples/basic-usage.example.js +4 -14
  77. package/http-client/examples/multi-api-configuration.example.js +4 -4
  78. package/http-client/http-client.module.js +7 -4
  79. package/http-client/services/api-client-registry.service.d.ts +2 -1
  80. package/http-client/services/api-client-registry.service.js +2 -1
  81. package/http-client/services/http-client.service.d.ts +18 -1
  82. package/http-client/services/http-client.service.js +123 -3
  83. package/http-client/services/http-log-query.service.d.ts +20 -0
  84. package/http-client/services/http-log-query.service.js +176 -0
  85. package/http-client/services/http-replay.service.d.ts +58 -0
  86. package/http-client/services/http-replay.service.js +266 -0
  87. package/http-client/services/log-cleanup.service.js +2 -2
  88. package/http-client/services/logging.service.js +1 -1
  89. package/http-client/utils/request-id.util.d.ts +4 -0
  90. package/http-client/utils/request-id.util.js +34 -0
  91. package/index.d.ts +1 -0
  92. package/index.js +1 -0
  93. package/package.json +1 -1
  94. package/setup/bootstrap.setup.js +5 -1
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ var ManualAuditLogService_1;
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.ManualAuditLogService = void 0;
26
+ const common_1 = require("@nestjs/common");
27
+ const typeorm_1 = require("@nestjs/typeorm");
28
+ const typeorm_2 = require("typeorm");
29
+ const entities_1 = require("../entities");
30
+ const audit_context_service_1 = require("./audit-context.service");
31
+ const enums_1 = require("../enums");
32
+ const crypto_1 = require("crypto");
33
+ let ManualAuditLogService = ManualAuditLogService_1 = class ManualAuditLogService {
34
+ constructor(manualLogRepository, transactionRepository, contextService, dataSource) {
35
+ this.manualLogRepository = manualLogRepository;
36
+ this.transactionRepository = transactionRepository;
37
+ this.contextService = contextService;
38
+ this.dataSource = dataSource;
39
+ ManualAuditLogService_1.instance = this;
40
+ }
41
+ static log(options) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ if (!ManualAuditLogService_1.instance) {
44
+ throw new Error('ManualAuditLogService is not initialized. Make sure AuditModule is imported.');
45
+ }
46
+ return ManualAuditLogService_1.instance.logOperation(options);
47
+ });
48
+ }
49
+ logOperation(options) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ const { templateKey, description, descriptionTemplate, descriptionParams, userId, username, requestIp, rollbackActions, transactionId, autoCreateTransaction = true, } = options;
52
+ if (!templateKey && !description && !descriptionTemplate) {
53
+ throw new Error('ManualAuditLogService.log() requires one of: templateKey, description, or descriptionTemplate');
54
+ }
55
+ const modeCount = [templateKey, description, descriptionTemplate].filter(Boolean).length;
56
+ if (modeCount > 1) {
57
+ throw new Error('ManualAuditLogService.log() accepts only one mode: use either templateKey, description, or descriptionTemplate');
58
+ }
59
+ const context = yield this.contextService.getCurrentContext();
60
+ const finalUserId = userId || context.userId || 'system';
61
+ const finalUsername = username || context.username || 'system';
62
+ const finalRequestIp = requestIp || context.requestIp || 'unknown';
63
+ let finalTransactionId = transactionId || context.transactionId;
64
+ if (!finalTransactionId && autoCreateTransaction) {
65
+ finalTransactionId = yield this.createTransaction(finalUserId, finalUsername);
66
+ }
67
+ const manualLog = this.manualLogRepository.create({
68
+ transactionId: finalTransactionId,
69
+ operationTemplateKey: templateKey || null,
70
+ descriptionParams: descriptionParams || null,
71
+ directDescription: description || null,
72
+ inlineTemplate: descriptionTemplate || null,
73
+ userId: finalUserId,
74
+ username: finalUsername,
75
+ requestIp: finalRequestIp,
76
+ rollbackActions: rollbackActions || [],
77
+ });
78
+ return this.manualLogRepository.save(manualLog);
79
+ });
80
+ }
81
+ static beginTransaction(userId, username) {
82
+ return __awaiter(this, void 0, void 0, function* () {
83
+ if (!ManualAuditLogService_1.instance) {
84
+ throw new Error('ManualAuditLogService is not initialized');
85
+ }
86
+ return ManualAuditLogService_1.instance.createTransaction(userId, username);
87
+ });
88
+ }
89
+ static commitTransaction(transactionId) {
90
+ return __awaiter(this, void 0, void 0, function* () {
91
+ if (!ManualAuditLogService_1.instance) {
92
+ throw new Error('ManualAuditLogService is not initialized');
93
+ }
94
+ yield ManualAuditLogService_1.instance.updateTransactionStatus(transactionId, enums_1.TransactionStatus.COMMITTED);
95
+ });
96
+ }
97
+ static rollbackTransaction(transactionId) {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ if (!ManualAuditLogService_1.instance) {
100
+ throw new Error('ManualAuditLogService is not initialized');
101
+ }
102
+ yield ManualAuditLogService_1.instance.updateTransactionStatus(transactionId, enums_1.TransactionStatus.ROLLED_BACK);
103
+ });
104
+ }
105
+ createTransaction(userId, username) {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ const context = yield this.contextService.getCurrentContext();
108
+ const transaction = this.transactionRepository.create({
109
+ description: 'Manual operation transaction',
110
+ userId: userId || context.userId || 'system',
111
+ username: username || context.username || 'system',
112
+ requestIp: context.requestIp || 'unknown',
113
+ status: enums_1.TransactionStatus.PENDING,
114
+ entities: [],
115
+ });
116
+ const saved = yield this.transactionRepository.save(transaction);
117
+ return saved.id;
118
+ });
119
+ }
120
+ updateTransactionStatus(transactionId, status) {
121
+ return __awaiter(this, void 0, void 0, function* () {
122
+ yield this.transactionRepository.update({ id: transactionId }, { status });
123
+ });
124
+ }
125
+ generateTransactionId() {
126
+ return `txn-${Date.now()}-${(0, crypto_1.randomBytes)(8).toString('hex')}`;
127
+ }
128
+ static logBatch(operations, sharedTransactionId) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ if (!ManualAuditLogService_1.instance) {
131
+ throw new Error('ManualAuditLogService is not initialized');
132
+ }
133
+ const transactionId = sharedTransactionId ||
134
+ (yield ManualAuditLogService_1.instance.createTransaction());
135
+ const results = [];
136
+ for (const operation of operations) {
137
+ const result = yield ManualAuditLogService_1.instance.logOperation(Object.assign(Object.assign({}, operation), { transactionId, autoCreateTransaction: false }));
138
+ results.push(result);
139
+ }
140
+ if (!sharedTransactionId) {
141
+ yield ManualAuditLogService_1.instance.updateTransactionStatus(transactionId, enums_1.TransactionStatus.COMMITTED);
142
+ }
143
+ return results;
144
+ });
145
+ }
146
+ static findLogs(options) {
147
+ return __awaiter(this, void 0, void 0, function* () {
148
+ if (!ManualAuditLogService_1.instance) {
149
+ throw new Error('ManualAuditLogService is not initialized');
150
+ }
151
+ const { templateKey, userId, transactionId, startTime, endTime, limit = 100 } = options;
152
+ const query = ManualAuditLogService_1.instance.manualLogRepository
153
+ .createQueryBuilder('log')
154
+ .orderBy('log.createdAt', 'DESC')
155
+ .take(limit);
156
+ if (templateKey) {
157
+ query.andWhere('log.operationTemplateKey = :templateKey', { templateKey });
158
+ }
159
+ if (userId) {
160
+ query.andWhere('log.userId = :userId', { userId });
161
+ }
162
+ if (transactionId) {
163
+ query.andWhere('log.transactionId = :transactionId', { transactionId });
164
+ }
165
+ if (startTime) {
166
+ query.andWhere('log.createdAt >= :startTime', { startTime });
167
+ }
168
+ if (endTime) {
169
+ query.andWhere('log.createdAt <= :endTime', { endTime });
170
+ }
171
+ return query.getMany();
172
+ });
173
+ }
174
+ };
175
+ exports.ManualAuditLogService = ManualAuditLogService;
176
+ exports.ManualAuditLogService = ManualAuditLogService = ManualAuditLogService_1 = __decorate([
177
+ (0, common_1.Injectable)(),
178
+ __param(0, (0, typeorm_1.InjectRepository)(entities_1.ManualOperationLogEntity, 'audit')),
179
+ __param(1, (0, typeorm_1.InjectRepository)(entities_1.EntityTransactionEntity, 'audit')),
180
+ __metadata("design:paramtypes", [typeorm_2.Repository,
181
+ typeorm_2.Repository,
182
+ audit_context_service_1.AuditContextService,
183
+ typeorm_2.DataSource])
184
+ ], ManualAuditLogService);
@@ -0,0 +1,10 @@
1
+ import { DataSource } from 'typeorm';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ export declare class MultiDatabaseService {
4
+ private readonly moduleRef;
5
+ private readonly config?;
6
+ constructor(moduleRef: ModuleRef, config?: any);
7
+ getDataSource(connectionName?: string): Promise<DataSource>;
8
+ getMonitoredConnections(): string[];
9
+ getAuditConnection(): string;
10
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.MultiDatabaseService = void 0;
25
+ const common_1 = require("@nestjs/common");
26
+ const typeorm_1 = require("@nestjs/typeorm");
27
+ const core_1 = require("@nestjs/core");
28
+ let MultiDatabaseService = class MultiDatabaseService {
29
+ constructor(moduleRef, config) {
30
+ this.moduleRef = moduleRef;
31
+ this.config = config;
32
+ }
33
+ getDataSource() {
34
+ return __awaiter(this, arguments, void 0, function* (connectionName = 'default') {
35
+ try {
36
+ const dataSource = this.moduleRef.get((0, typeorm_1.getDataSourceToken)(connectionName), { strict: false });
37
+ return dataSource;
38
+ }
39
+ catch (error) {
40
+ throw new Error(`Failed to get DataSource for connection: ${connectionName}`);
41
+ }
42
+ });
43
+ }
44
+ getMonitoredConnections() {
45
+ var _a, _b;
46
+ return ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.connections) === null || _b === void 0 ? void 0 : _b.monitored) || ['default'];
47
+ }
48
+ getAuditConnection() {
49
+ var _a, _b;
50
+ return ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.connections) === null || _b === void 0 ? void 0 : _b.audit) || 'default';
51
+ }
52
+ };
53
+ exports.MultiDatabaseService = MultiDatabaseService;
54
+ exports.MultiDatabaseService = MultiDatabaseService = __decorate([
55
+ (0, common_1.Injectable)(),
56
+ __param(1, (0, common_1.Optional)()),
57
+ __param(1, (0, common_1.Inject)('AUDIT_CONFIG')),
58
+ __metadata("design:paramtypes", [core_1.ModuleRef, Object])
59
+ ], MultiDatabaseService);
@@ -0,0 +1,21 @@
1
+ import { Repository } from 'typeorm';
2
+ import { OperationTemplateEntity, EntityTransactionEntity, EntityAuditLogEntity, ManualOperationLogEntity } from '../entities';
3
+ import { ChangeDetail, TransactionDescription } from '../interfaces';
4
+ export declare class OperationDescriptionService {
5
+ private readonly templateRepository;
6
+ private readonly transactionRepository;
7
+ private readonly auditLogRepository;
8
+ private readonly manualOperationRepository;
9
+ private templateCache;
10
+ constructor(templateRepository: Repository<OperationTemplateEntity>, transactionRepository: Repository<EntityTransactionEntity>, auditLogRepository: Repository<EntityAuditLogEntity>, manualOperationRepository: Repository<ManualOperationLogEntity>);
11
+ generateOperationName(templateKey: string, language?: string): Promise<string>;
12
+ generateDescription(templateKey: string, descriptionParams: Record<string, any>, language?: string): Promise<string>;
13
+ generateChangeDetails(changeDetails: ChangeDetail[], language?: string): Promise<any[]>;
14
+ getTransactionDescription(transactionId: string, language?: string): Promise<TransactionDescription>;
15
+ batchGetTransactionDescriptions(transactionIds: string[], language?: string): Promise<Record<string, TransactionDescription>>;
16
+ private fillTemplate;
17
+ private formatDisplayValue;
18
+ private getOperationTemplate;
19
+ clearTemplateCache(): void;
20
+ preloadTemplates(templateKeys: string[]): Promise<void>;
21
+ }
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.OperationDescriptionService = void 0;
25
+ const common_1 = require("@nestjs/common");
26
+ const typeorm_1 = require("@nestjs/typeorm");
27
+ const typeorm_2 = require("typeorm");
28
+ const entities_1 = require("../entities");
29
+ let OperationDescriptionService = class OperationDescriptionService {
30
+ constructor(templateRepository, transactionRepository, auditLogRepository, manualOperationRepository) {
31
+ this.templateRepository = templateRepository;
32
+ this.transactionRepository = transactionRepository;
33
+ this.auditLogRepository = auditLogRepository;
34
+ this.manualOperationRepository = manualOperationRepository;
35
+ this.templateCache = new Map();
36
+ }
37
+ generateOperationName(templateKey_1) {
38
+ return __awaiter(this, arguments, void 0, function* (templateKey, language = 'zh') {
39
+ const template = yield this.getOperationTemplate(templateKey);
40
+ if (!template) {
41
+ return templateKey;
42
+ }
43
+ return template.nameTemplates[language] || template.nameTemplates['zh'] || templateKey;
44
+ });
45
+ }
46
+ generateDescription(templateKey_1, descriptionParams_1) {
47
+ return __awaiter(this, arguments, void 0, function* (templateKey, descriptionParams, language = 'zh') {
48
+ const template = yield this.getOperationTemplate(templateKey);
49
+ if (!template) {
50
+ return templateKey;
51
+ }
52
+ const templateStr = template.descriptionTemplates[language] || template.descriptionTemplates['zh'] || templateKey;
53
+ return this.fillTemplate(templateStr, descriptionParams);
54
+ });
55
+ }
56
+ generateChangeDetails(changeDetails_1) {
57
+ return __awaiter(this, arguments, void 0, function* (changeDetails, language = 'zh') {
58
+ return changeDetails.map((detail) => {
59
+ var _a, _b, _c;
60
+ return ({
61
+ fieldName: detail.fieldName,
62
+ fieldLabel: ((_a = detail.fieldLabels) === null || _a === void 0 ? void 0 : _a[language]) || detail.fieldName,
63
+ oldValue: this.formatDisplayValue(detail.oldValue, (_b = detail.displayOldValue) === null || _b === void 0 ? void 0 : _b[language]),
64
+ newValue: this.formatDisplayValue(detail.newValue, (_c = detail.displayNewValue) === null || _c === void 0 ? void 0 : _c[language]),
65
+ changeType: detail.changeType,
66
+ });
67
+ });
68
+ });
69
+ }
70
+ getTransactionDescription(transactionId_1) {
71
+ return __awaiter(this, arguments, void 0, function* (transactionId, language = 'zh') {
72
+ const transaction = yield this.transactionRepository.findOne({
73
+ where: { id: transactionId },
74
+ });
75
+ if (!transaction) {
76
+ throw new Error(`Transaction ${transactionId} not found`);
77
+ }
78
+ const auditLogs = yield this.auditLogRepository.find({
79
+ where: { requestId: transactionId },
80
+ order: { createdAt: 'ASC' },
81
+ });
82
+ const manualOperations = yield this.manualOperationRepository.find({
83
+ where: { transactionId },
84
+ order: { createdAt: 'ASC' },
85
+ });
86
+ let operationName;
87
+ let description;
88
+ if (transaction.operationTemplateKey) {
89
+ operationName = yield this.generateOperationName(transaction.operationTemplateKey, language);
90
+ description = yield this.generateDescription(transaction.operationTemplateKey, transaction.descriptionParams || {}, language);
91
+ }
92
+ else {
93
+ const firstLog = auditLogs[0];
94
+ if (firstLog && firstLog.operationTemplateKey) {
95
+ operationName = yield this.generateOperationName(firstLog.operationTemplateKey, language);
96
+ description = yield this.generateDescription(firstLog.operationTemplateKey, firstLog.descriptionParams || {}, language);
97
+ }
98
+ else {
99
+ operationName = 'Unknown Operation';
100
+ description = transaction.description || 'Unknown operation';
101
+ }
102
+ }
103
+ const changes = [];
104
+ for (const log of auditLogs) {
105
+ const changeDescription = log.operationTemplateKey
106
+ ? yield this.generateDescription(log.operationTemplateKey, log.descriptionParams || {}, language)
107
+ : log.description || '';
108
+ const changeDetails = log.changeDetails
109
+ ? yield this.generateChangeDetails(log.changeDetails, language)
110
+ : [];
111
+ changes.push({
112
+ entityName: log.entityType,
113
+ entityId: log.entityId,
114
+ operation: log.operation,
115
+ description: changeDescription,
116
+ details: changeDetails,
117
+ createdAt: log.createdAt,
118
+ });
119
+ }
120
+ for (const manualOp of manualOperations) {
121
+ const opName = yield this.generateOperationName(manualOp.operationTemplateKey, language);
122
+ const opDescription = yield this.generateDescription(manualOp.operationTemplateKey, manualOp.descriptionParams, language);
123
+ changes.push({
124
+ type: 'manual',
125
+ description: `${opName}: ${opDescription}`,
126
+ details: manualOp.descriptionParams,
127
+ createdAt: manualOp.createdAt,
128
+ });
129
+ }
130
+ changes.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
131
+ return {
132
+ operationName,
133
+ description,
134
+ changes,
135
+ };
136
+ });
137
+ }
138
+ batchGetTransactionDescriptions(transactionIds_1) {
139
+ return __awaiter(this, arguments, void 0, function* (transactionIds, language = 'zh') {
140
+ const results = {};
141
+ for (const transactionId of transactionIds) {
142
+ try {
143
+ results[transactionId] = yield this.getTransactionDescription(transactionId, language);
144
+ }
145
+ catch (error) {
146
+ console.error(`Failed to get description for transaction ${transactionId}:`, error);
147
+ }
148
+ }
149
+ return results;
150
+ });
151
+ }
152
+ fillTemplate(template, params) {
153
+ if (!template)
154
+ return '';
155
+ let result = template;
156
+ for (const [key, value] of Object.entries(params || {})) {
157
+ const placeholder = `{${key}}`;
158
+ if (result.includes(placeholder)) {
159
+ result = result.replace(new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), String(value || ''));
160
+ }
161
+ }
162
+ return result;
163
+ }
164
+ formatDisplayValue(value, displayValue) {
165
+ if (displayValue !== undefined) {
166
+ return displayValue;
167
+ }
168
+ if (value === null || value === undefined) {
169
+ return '';
170
+ }
171
+ return String(value);
172
+ }
173
+ getOperationTemplate(templateKey) {
174
+ return __awaiter(this, void 0, void 0, function* () {
175
+ if (this.templateCache.has(templateKey)) {
176
+ return this.templateCache.get(templateKey);
177
+ }
178
+ const template = yield this.templateRepository.findOne({
179
+ where: { key: templateKey },
180
+ });
181
+ if (template) {
182
+ this.templateCache.set(templateKey, template);
183
+ }
184
+ return template;
185
+ });
186
+ }
187
+ clearTemplateCache() {
188
+ this.templateCache.clear();
189
+ }
190
+ preloadTemplates(templateKeys) {
191
+ return __awaiter(this, void 0, void 0, function* () {
192
+ const templates = yield this.templateRepository
193
+ .createQueryBuilder('template')
194
+ .where('template.key IN (:...keys)', { keys: templateKeys })
195
+ .getMany();
196
+ for (const template of templates) {
197
+ this.templateCache.set(template.key, template);
198
+ }
199
+ });
200
+ }
201
+ };
202
+ exports.OperationDescriptionService = OperationDescriptionService;
203
+ exports.OperationDescriptionService = OperationDescriptionService = __decorate([
204
+ (0, common_1.Injectable)(),
205
+ __param(0, (0, typeorm_1.InjectRepository)(entities_1.OperationTemplateEntity)),
206
+ __param(1, (0, typeorm_1.InjectRepository)(entities_1.EntityTransactionEntity)),
207
+ __param(2, (0, typeorm_1.InjectRepository)(entities_1.EntityAuditLogEntity)),
208
+ __param(3, (0, typeorm_1.InjectRepository)(entities_1.ManualOperationLogEntity)),
209
+ __metadata("design:paramtypes", [typeorm_2.Repository,
210
+ typeorm_2.Repository,
211
+ typeorm_2.Repository,
212
+ typeorm_2.Repository])
213
+ ], OperationDescriptionService);
@@ -0,0 +1,22 @@
1
+ import { Repository } from 'typeorm';
2
+ import { EntityTransactionEntity } from '../entities';
3
+ import { AuditOperation } from '../enums';
4
+ import { AuditContextService } from './audit-context.service';
5
+ import { EntityAuditService } from './entity-audit.service';
6
+ import { MultiDatabaseService } from './multi-database.service';
7
+ export declare class TransactionAuditService {
8
+ private readonly transactionRepository;
9
+ private readonly contextService;
10
+ private readonly auditService;
11
+ private readonly multiDbService;
12
+ constructor(transactionRepository: Repository<EntityTransactionEntity>, contextService: AuditContextService, auditService: EntityAuditService, multiDbService: MultiDatabaseService);
13
+ beginTransaction(description: string): Promise<string>;
14
+ commitTransaction(transactionId: string): Promise<void>;
15
+ rollbackTransaction(transactionId: string): Promise<void>;
16
+ addEntityToTransaction(transactionId: string, entityType: string, entityId: string, operation: AuditOperation): Promise<void>;
17
+ private performRollback;
18
+ private groupEntitiesByConnection;
19
+ private rollbackEntitiesInConnection;
20
+ private rollbackSingleEntity;
21
+ private getLatestAuditLog;
22
+ }