@nest-omni/core 3.1.2-7 → 3.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 (138) hide show
  1. package/audit/audit.module.d.ts +10 -0
  2. package/audit/audit.module.js +254 -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 +7 -0
  10. package/audit/decorators/audit-operation.decorator.js +25 -0
  11. package/audit/decorators/entity-audit.decorator.d.ts +10 -0
  12. package/audit/decorators/entity-audit.decorator.js +70 -0
  13. package/audit/decorators/index.d.ts +3 -0
  14. package/audit/decorators/index.js +19 -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 +23 -0
  28. package/audit/entities/entity-audit-log.entity.js +110 -0
  29. package/audit/entities/entity-transaction.entity.d.ts +21 -0
  30. package/audit/entities/entity-transaction.entity.js +80 -0
  31. package/audit/entities/index.d.ts +4 -0
  32. package/audit/entities/index.js +20 -0
  33. package/audit/entities/manual-operation-log.entity.d.ts +13 -0
  34. package/audit/entities/manual-operation-log.entity.js +65 -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 +42 -0
  38. package/audit/enums/audit.enums.js +53 -0
  39. package/audit/enums/index.d.ts +1 -0
  40. package/audit/enums/index.js +17 -0
  41. package/audit/index.d.ts +12 -0
  42. package/audit/index.js +48 -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 +180 -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 +65 -0
  56. package/audit/services/entity-audit.service.js +626 -0
  57. package/audit/services/index.d.ts +6 -0
  58. package/audit/services/index.js +22 -0
  59. package/audit/services/multi-database.service.d.ts +10 -0
  60. package/audit/services/multi-database.service.js +59 -0
  61. package/audit/services/operation-description.service.d.ts +21 -0
  62. package/audit/services/operation-description.service.js +213 -0
  63. package/audit/services/transaction-audit.service.d.ts +22 -0
  64. package/audit/services/transaction-audit.service.js +201 -0
  65. package/audit/subscribers/entity-audit.subscriber.d.ts +14 -0
  66. package/audit/subscribers/entity-audit.subscriber.js +136 -0
  67. package/audit/subscribers/index.d.ts +1 -0
  68. package/audit/subscribers/index.js +17 -0
  69. package/common/utils.d.ts +1 -0
  70. package/common/utils.js +6 -0
  71. package/http-client/config/http-client.config.d.ts +6 -0
  72. package/http-client/config/http-client.config.js +87 -0
  73. package/http-client/config/index.d.ts +1 -0
  74. package/http-client/config/index.js +17 -0
  75. package/http-client/decorators/http-client.decorators.d.ts +72 -0
  76. package/http-client/decorators/http-client.decorators.js +204 -0
  77. package/http-client/decorators/index.d.ts +1 -0
  78. package/http-client/decorators/index.js +17 -0
  79. package/http-client/entities/http-log.entity.d.ts +98 -0
  80. package/http-client/entities/http-log.entity.js +143 -0
  81. package/http-client/entities/index.d.ts +1 -0
  82. package/http-client/entities/index.js +17 -0
  83. package/http-client/errors/http-client.errors.d.ts +56 -0
  84. package/http-client/errors/http-client.errors.js +149 -0
  85. package/http-client/errors/index.d.ts +1 -0
  86. package/http-client/errors/index.js +17 -0
  87. package/http-client/examples/advanced-usage.example.d.ts +23 -0
  88. package/http-client/examples/advanced-usage.example.js +332 -0
  89. package/http-client/examples/auth-with-waiting-lock.example.d.ts +17 -0
  90. package/http-client/examples/auth-with-waiting-lock.example.js +336 -0
  91. package/http-client/examples/basic-usage.example.d.ts +53 -0
  92. package/http-client/examples/basic-usage.example.js +161 -0
  93. package/http-client/examples/index.d.ts +3 -0
  94. package/http-client/examples/index.js +19 -0
  95. package/http-client/examples/multi-api-configuration.example.d.ts +98 -0
  96. package/http-client/examples/multi-api-configuration.example.js +353 -0
  97. package/http-client/http-client.module.d.ts +11 -0
  98. package/http-client/http-client.module.js +257 -0
  99. package/http-client/index.d.ts +10 -0
  100. package/http-client/index.js +27 -0
  101. package/http-client/interfaces/api-client-config.interface.d.ts +152 -0
  102. package/http-client/interfaces/api-client-config.interface.js +12 -0
  103. package/http-client/interfaces/http-client-config.interface.d.ts +123 -0
  104. package/http-client/interfaces/http-client-config.interface.js +2 -0
  105. package/http-client/services/api-client-registry.service.d.ts +41 -0
  106. package/http-client/services/api-client-registry.service.js +412 -0
  107. package/http-client/services/cache.service.d.ts +24 -0
  108. package/http-client/services/cache.service.js +264 -0
  109. package/http-client/services/circuit-breaker.service.d.ts +33 -0
  110. package/http-client/services/circuit-breaker.service.js +180 -0
  111. package/http-client/services/http-client.service.d.ts +60 -0
  112. package/http-client/services/http-client.service.js +504 -0
  113. package/http-client/services/http-log-query.service.d.ts +76 -0
  114. package/http-client/services/http-log-query.service.js +590 -0
  115. package/http-client/services/http-replay.service.d.ts +58 -0
  116. package/http-client/services/http-replay.service.js +266 -0
  117. package/http-client/services/index.d.ts +7 -0
  118. package/http-client/services/index.js +23 -0
  119. package/http-client/services/log-cleanup.service.d.ts +64 -0
  120. package/http-client/services/log-cleanup.service.js +268 -0
  121. package/http-client/services/logging.service.d.ts +36 -0
  122. package/http-client/services/logging.service.js +445 -0
  123. package/http-client/utils/call-stack-extractor.util.d.ts +29 -0
  124. package/http-client/utils/call-stack-extractor.util.js +138 -0
  125. package/http-client/utils/context-extractor.util.d.ts +44 -0
  126. package/http-client/utils/context-extractor.util.js +173 -0
  127. package/http-client/utils/curl-generator.util.d.ts +9 -0
  128. package/http-client/utils/curl-generator.util.js +169 -0
  129. package/http-client/utils/index.d.ts +4 -0
  130. package/http-client/utils/index.js +20 -0
  131. package/http-client/utils/request-id.util.d.ts +4 -0
  132. package/http-client/utils/request-id.util.js +34 -0
  133. package/http-client/utils/retry-recorder.util.d.ts +30 -0
  134. package/http-client/utils/retry-recorder.util.js +143 -0
  135. package/index.d.ts +2 -0
  136. package/index.js +2 -0
  137. package/package.json +1 -1
  138. package/setup/bootstrap.setup.js +5 -1
@@ -0,0 +1,266 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var HttpReplayService_1;
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.HttpReplayService = void 0;
23
+ const common_1 = require("@nestjs/common");
24
+ const http_client_service_1 = require("./http-client.service");
25
+ const http_log_query_service_1 = require("./http-log-query.service");
26
+ let HttpReplayService = HttpReplayService_1 = class HttpReplayService {
27
+ constructor(httpClient, logQueryService) {
28
+ this.httpClient = httpClient;
29
+ this.logQueryService = logQueryService;
30
+ this.logger = new common_1.Logger(HttpReplayService_1.name);
31
+ }
32
+ replayByLogId(logId_1) {
33
+ return __awaiter(this, arguments, void 0, function* (logId, options = {}) {
34
+ const startTime = Date.now();
35
+ const replayId = this.generateReplayId();
36
+ try {
37
+ const originalLog = yield this.logQueryService.findLogById(logId, true);
38
+ if (!originalLog) {
39
+ throw new Error(`Log with ID ${logId} not found`);
40
+ }
41
+ const requestConfig = this.buildReplayConfig(originalLog, options);
42
+ if (options.logReplay !== false) {
43
+ this.logger.log(`Starting replay for log ${logId} (replay ID: ${replayId})`);
44
+ }
45
+ const response = yield this.executeReplayRequest(requestConfig, options);
46
+ const endTime = Date.now();
47
+ const responseTime = endTime - startTime;
48
+ const result = {
49
+ originalLog,
50
+ requestConfig,
51
+ response,
52
+ responseTime,
53
+ success: true,
54
+ replayTimestamp: new Date().toISOString(),
55
+ replayId,
56
+ };
57
+ if (options.logReplay !== false) {
58
+ this.logger.log(`Replay completed for log ${logId} (replay ID: ${replayId}) in ${responseTime}ms`);
59
+ }
60
+ return result;
61
+ }
62
+ catch (error) {
63
+ const endTime = Date.now();
64
+ const responseTime = endTime - startTime;
65
+ const result = {
66
+ originalLog: {},
67
+ requestConfig: {},
68
+ response: null,
69
+ responseTime,
70
+ success: false,
71
+ error: error.message,
72
+ replayTimestamp: new Date().toISOString(),
73
+ replayId,
74
+ };
75
+ this.logger.error(`Replay failed for log ${logId} (replay ID: ${replayId}): ${error.message}`, error);
76
+ return result;
77
+ }
78
+ });
79
+ }
80
+ replayByRequestId(requestId_1) {
81
+ return __awaiter(this, arguments, void 0, function* (requestId, options = {}) {
82
+ const originalLog = yield this.logQueryService.findLogByRequestId(requestId);
83
+ if (!originalLog) {
84
+ throw new Error(`Log with requestId ${requestId} not found`);
85
+ }
86
+ return this.replayByLogId(originalLog.id, options);
87
+ });
88
+ }
89
+ batchReplay(logIds_1) {
90
+ return __awaiter(this, arguments, void 0, function* (logIds, options = {}, concurrency = 5) {
91
+ const startTime = Date.now();
92
+ this.logger.log(`Starting batch replay for ${logIds.length} logs`);
93
+ const results = [];
94
+ const chunks = this.chunkArray(logIds, concurrency);
95
+ for (const chunk of chunks) {
96
+ const chunkPromises = chunk.map((logId) => __awaiter(this, void 0, void 0, function* () {
97
+ try {
98
+ return yield this.replayByLogId(logId, options);
99
+ }
100
+ catch (error) {
101
+ this.logger.error(`Failed to replay log ${logId}`, error);
102
+ return {
103
+ originalLog: {},
104
+ requestConfig: {},
105
+ response: null,
106
+ responseTime: 0,
107
+ success: false,
108
+ error: error.message,
109
+ replayTimestamp: new Date().toISOString(),
110
+ replayId: this.generateReplayId(),
111
+ };
112
+ }
113
+ }));
114
+ const chunkResults = yield Promise.all(chunkPromises);
115
+ results.push(...chunkResults);
116
+ }
117
+ const successfulRequests = results.filter((r) => r.success).length;
118
+ const failedRequests = results.length - successfulRequests;
119
+ const totalResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0);
120
+ const averageResponseTime = results.length > 0 ? totalResponseTime / results.length : 0;
121
+ const batchResult = {
122
+ totalRequests: results.length,
123
+ successfulRequests,
124
+ failedRequests,
125
+ successRate: results.length > 0 ? (successfulRequests / results.length) * 100 : 0,
126
+ totalResponseTime,
127
+ averageResponseTime,
128
+ results,
129
+ };
130
+ this.logger.log(`Batch replay completed: ${successfulRequests}/${results.length} successful in ${totalResponseTime}ms`);
131
+ return batchResult;
132
+ });
133
+ }
134
+ batchReplayByQuery() {
135
+ return __awaiter(this, arguments, void 0, function* (queryOptions = {}, replayOptions = {}, concurrency = 5) {
136
+ const limitedQueryOptions = Object.assign(Object.assign({}, queryOptions), { limit: Math.min(queryOptions.limit || 50, 100) });
137
+ const queryResult = yield this.logQueryService.findLogs(limitedQueryOptions);
138
+ const logIds = queryResult.logs.map((log) => log.id);
139
+ if (logIds.length === 0) {
140
+ this.logger.log('No logs found for replay query');
141
+ return {
142
+ totalRequests: 0,
143
+ successfulRequests: 0,
144
+ failedRequests: 0,
145
+ successRate: 0,
146
+ totalResponseTime: 0,
147
+ averageResponseTime: 0,
148
+ results: [],
149
+ };
150
+ }
151
+ this.logger.log(`Found ${logIds.length} logs for batch replay`);
152
+ return this.batchReplay(logIds, replayOptions, concurrency);
153
+ });
154
+ }
155
+ replayAndCompare(logId_1) {
156
+ return __awaiter(this, arguments, void 0, function* (logId, options = {}) {
157
+ var _a, _b, _c;
158
+ const originalLog = yield this.logQueryService.findLogById(logId, true);
159
+ if (!originalLog) {
160
+ throw new Error(`Log with ID ${logId} not found`);
161
+ }
162
+ const replayResult = yield this.replayByLogId(logId, options);
163
+ const comparison = {
164
+ statusMatch: originalLog.statusCode === ((_a = replayResult.response) === null || _a === void 0 ? void 0 : _a.status),
165
+ responseTimeDifference: replayResult.responseTime - originalLog.responseTime,
166
+ headersMatch: this.compareHeaders(originalLog.responseHeaders || {}, ((_b = replayResult.response) === null || _b === void 0 ? void 0 : _b.headers) || {}),
167
+ bodyMatch: this.compareBodies(originalLog.responseBody, (_c = replayResult.response) === null || _c === void 0 ? void 0 : _c.data),
168
+ };
169
+ return {
170
+ original: originalLog,
171
+ replay: replayResult,
172
+ comparison,
173
+ };
174
+ });
175
+ }
176
+ buildReplayConfig(log, options) {
177
+ const config = {
178
+ method: log.method,
179
+ url: log.url,
180
+ headers: Object.assign({}, log.headers),
181
+ params: Object.assign({}, log.params),
182
+ };
183
+ if (log.body) {
184
+ try {
185
+ config.data =
186
+ typeof log.body === 'string' ? JSON.parse(log.body) : log.body;
187
+ }
188
+ catch (_a) {
189
+ config.data = log.body;
190
+ }
191
+ }
192
+ if (options.overrideHeaders) {
193
+ config.headers = Object.assign(Object.assign({}, config.headers), options.additionalHeaders);
194
+ }
195
+ else if (options.additionalHeaders) {
196
+ config.headers = Object.assign(Object.assign({}, config.headers), options.additionalHeaders);
197
+ }
198
+ if (options.overrideBody && options.additionalHeaders) {
199
+ }
200
+ if (options.overrideParams && options.metadata) {
201
+ config.params = Object.assign(Object.assign({}, config.params), options.metadata);
202
+ }
203
+ if (options.timeout) {
204
+ config.timeout = options.timeout;
205
+ }
206
+ config.metadata = Object.assign({ originalLogId: log.id, originalRequestId: log.requestId, replayTimestamp: new Date().toISOString(), replayedBy: 'http-replay-service' }, options.metadata);
207
+ return config;
208
+ }
209
+ executeReplayRequest(config, options) {
210
+ return __awaiter(this, void 0, void 0, function* () {
211
+ try {
212
+ return yield this.httpClient.request(config);
213
+ }
214
+ catch (error) {
215
+ throw error;
216
+ }
217
+ });
218
+ }
219
+ generateReplayId() {
220
+ return `replay-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
221
+ }
222
+ chunkArray(array, size) {
223
+ const chunks = [];
224
+ for (let i = 0; i < array.length; i += size) {
225
+ chunks.push(array.slice(i, i + size));
226
+ }
227
+ return chunks;
228
+ }
229
+ compareHeaders(original, replay) {
230
+ const ignoreHeaders = ['date', 'expires', 'last-modified', 'etag'];
231
+ const originalFiltered = Object.keys(original)
232
+ .filter((key) => !ignoreHeaders.includes(key.toLowerCase()))
233
+ .reduce((obj, key) => {
234
+ obj[key] = original[key];
235
+ return obj;
236
+ }, {});
237
+ const replayFiltered = Object.keys(replay)
238
+ .filter((key) => !ignoreHeaders.includes(key.toLowerCase()))
239
+ .reduce((obj, key) => {
240
+ obj[key] = replay[key];
241
+ return obj;
242
+ }, {});
243
+ return JSON.stringify(originalFiltered) === JSON.stringify(replayFiltered);
244
+ }
245
+ compareBodies(original, replay) {
246
+ if (!original && !replay)
247
+ return true;
248
+ if (!original || !replay)
249
+ return false;
250
+ try {
251
+ const originalParsed = typeof original === 'string' ? JSON.parse(original) : original;
252
+ const replayString = typeof replay === 'string' ? replay : JSON.stringify(replay);
253
+ const replayParsed = JSON.parse(replayString);
254
+ return JSON.stringify(originalParsed) === JSON.stringify(replayParsed);
255
+ }
256
+ catch (_a) {
257
+ return original === replay;
258
+ }
259
+ }
260
+ };
261
+ exports.HttpReplayService = HttpReplayService;
262
+ exports.HttpReplayService = HttpReplayService = HttpReplayService_1 = __decorate([
263
+ (0, common_1.Injectable)(),
264
+ __metadata("design:paramtypes", [http_client_service_1.HttpClientService,
265
+ http_log_query_service_1.HttpLogQueryService])
266
+ ], HttpReplayService);
@@ -0,0 +1,7 @@
1
+ export * from './http-client.service';
2
+ export * from './circuit-breaker.service';
3
+ export * from './logging.service';
4
+ export * from './cache.service';
5
+ export * from './http-log-query.service';
6
+ export * from './log-cleanup.service';
7
+ export * from './api-client-registry.service';
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./http-client.service"), exports);
18
+ __exportStar(require("./circuit-breaker.service"), exports);
19
+ __exportStar(require("./logging.service"), exports);
20
+ __exportStar(require("./cache.service"), exports);
21
+ __exportStar(require("./http-log-query.service"), exports);
22
+ __exportStar(require("./log-cleanup.service"), exports);
23
+ __exportStar(require("./api-client-registry.service"), exports);
@@ -0,0 +1,64 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { CronExpression } from '@nestjs/schedule';
3
+ import { HttpLogQueryService } from './http-log-query.service';
4
+ export interface LogCleanupConfig {
5
+ enabled: boolean;
6
+ strategy: 'retention' | 'size' | 'combination';
7
+ retentionDays: number;
8
+ maxRecords?: number;
9
+ schedule?: CronExpression;
10
+ batchSize?: number;
11
+ preserveErrorLogs?: boolean;
12
+ errorLogRetentionDays?: number;
13
+ preserveImportantLogs?: boolean;
14
+ importantLogRetentionDays?: number;
15
+ preserveSlowRequests?: boolean;
16
+ slowRequestRetentionDays?: number;
17
+ slowRequestThreshold?: number;
18
+ }
19
+ export interface CleanupStats {
20
+ cleanupTime: Date;
21
+ strategy: string;
22
+ beforeCount: number;
23
+ afterCount: number;
24
+ deletedCount: number;
25
+ batchCount: number;
26
+ duration: number;
27
+ errors: string[];
28
+ }
29
+ export declare class HttpLogCleanupService implements OnModuleInit {
30
+ private readonly logQueryService;
31
+ private readonly logger;
32
+ private readonly defaultConfig;
33
+ constructor(logQueryService: HttpLogQueryService, config?: Partial<LogCleanupConfig>);
34
+ private get cleanupConfig();
35
+ onModuleInit(): void;
36
+ scheduledCleanup(): Promise<CleanupStats>;
37
+ manualCleanup(options?: Partial<LogCleanupConfig>): Promise<CleanupStats>;
38
+ getConfig(): LogCleanupConfig;
39
+ updateConfig(config: Partial<LogCleanupConfig>): void;
40
+ getCleanupStatus(): Promise<{
41
+ enabled: boolean;
42
+ config: LogCleanupConfig;
43
+ currentStats: any;
44
+ recommendations: string[];
45
+ }>;
46
+ previewCleanup(config?: Partial<LogCleanupConfig>): Promise<{
47
+ strategy: string;
48
+ currentRecords: number;
49
+ estimatedDeletion: number;
50
+ estimatedAfterCount: number;
51
+ cutoffDate: Date;
52
+ breakdown: {
53
+ normalLogs: number;
54
+ errorLogs: number;
55
+ slowRequests: number;
56
+ importantLogs: number;
57
+ };
58
+ }>;
59
+ private performCleanup;
60
+ private cleanupByRetention;
61
+ private cleanupBySize;
62
+ private cleanupByCombination;
63
+ private createCleanupStats;
64
+ }
@@ -0,0 +1,268 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var HttpLogCleanupService_1;
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.HttpLogCleanupService = void 0;
23
+ const common_1 = require("@nestjs/common");
24
+ const schedule_1 = require("@nestjs/schedule");
25
+ const http_log_query_service_1 = require("./http-log-query.service");
26
+ const schedule_decorator_1 = require("../../setup/schedule.decorator");
27
+ let HttpLogCleanupService = HttpLogCleanupService_1 = class HttpLogCleanupService {
28
+ constructor(logQueryService, config = {}) {
29
+ this.logQueryService = logQueryService;
30
+ this.logger = new common_1.Logger(HttpLogCleanupService_1.name);
31
+ this.defaultConfig = {
32
+ enabled: true,
33
+ strategy: 'retention',
34
+ retentionDays: 30,
35
+ maxRecords: 1000000,
36
+ schedule: schedule_1.CronExpression.EVERY_DAY_AT_2AM,
37
+ batchSize: 10000,
38
+ preserveErrorLogs: true,
39
+ errorLogRetentionDays: 90,
40
+ preserveImportantLogs: true,
41
+ importantLogRetentionDays: 60,
42
+ preserveSlowRequests: true,
43
+ slowRequestRetentionDays: 60,
44
+ slowRequestThreshold: 5000,
45
+ };
46
+ if (Object.keys(config).length > 0) {
47
+ Object.assign(this.defaultConfig, config);
48
+ }
49
+ }
50
+ get cleanupConfig() {
51
+ return this.defaultConfig;
52
+ }
53
+ onModuleInit() {
54
+ if (this.cleanupConfig.enabled) {
55
+ this.logger.log(`HTTP log cleanup enabled with strategy: ${this.cleanupConfig.strategy}`);
56
+ this.logger.log(`Schedule: ${this.cleanupConfig.schedule}`);
57
+ }
58
+ else {
59
+ this.logger.warn('HTTP log cleanup is disabled');
60
+ }
61
+ }
62
+ scheduledCleanup() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ if (!this.cleanupConfig.enabled) {
65
+ return this.createCleanupStats('scheduled', 0, 0, 0, 0, []);
66
+ }
67
+ this.logger.log('Starting scheduled HTTP log cleanup...');
68
+ return this.performCleanup();
69
+ });
70
+ }
71
+ manualCleanup(options) {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ const config = Object.assign(Object.assign({}, this.cleanupConfig), options);
74
+ if (!config.enabled) {
75
+ throw new Error('Log cleanup is disabled');
76
+ }
77
+ this.logger.log(`Starting manual HTTP log cleanup with strategy: ${config.strategy}`);
78
+ return this.performCleanup(config);
79
+ });
80
+ }
81
+ getConfig() {
82
+ return this.cleanupConfig;
83
+ }
84
+ updateConfig(config) {
85
+ Object.assign(this.defaultConfig, config);
86
+ this.logger.log('Cleanup configuration updated');
87
+ }
88
+ getCleanupStatus() {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ const config = this.cleanupConfig;
91
+ const stats = yield this.logQueryService.getStats();
92
+ const recommendations = [];
93
+ if (stats.totalRequests > (config.maxRecords || Infinity) * 0.9) {
94
+ recommendations.push('Current records approaching limit, consider adjusting retention policy');
95
+ }
96
+ if (stats.averageResponseTime > 1000) {
97
+ recommendations.push('High average response time detected, consider performance optimization');
98
+ }
99
+ if (stats.failedRequests / stats.totalRequests > 0.1) {
100
+ recommendations.push('High error rate detected, consider error handling improvements');
101
+ }
102
+ return {
103
+ enabled: config.enabled,
104
+ config,
105
+ currentStats: stats,
106
+ recommendations,
107
+ };
108
+ });
109
+ }
110
+ previewCleanup(config) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ const finalConfig = Object.assign(Object.assign({}, this.cleanupConfig), config);
113
+ const stats = yield this.logQueryService.getStats();
114
+ const cutoffDate = new Date();
115
+ cutoffDate.setDate(cutoffDate.getDate() - finalConfig.retentionDays);
116
+ return {
117
+ strategy: finalConfig.strategy,
118
+ currentRecords: stats.totalRequests,
119
+ estimatedDeletion: Math.max(0, stats.totalRequests - finalConfig.maxRecords || Infinity),
120
+ estimatedAfterCount: Math.min(stats.totalRequests, finalConfig.maxRecords || Infinity),
121
+ cutoffDate,
122
+ breakdown: {
123
+ normalLogs: Math.floor(stats.totalRequests * 0.7),
124
+ errorLogs: Math.floor(stats.totalRequests * 0.2),
125
+ slowRequests: Math.floor(stats.totalRequests * 0.05),
126
+ importantLogs: Math.floor(stats.totalRequests * 0.05),
127
+ },
128
+ };
129
+ });
130
+ }
131
+ performCleanup() {
132
+ return __awaiter(this, arguments, void 0, function* (config = this.cleanupConfig) {
133
+ const startTime = Date.now();
134
+ const errors = [];
135
+ let deletedCount = 0;
136
+ const batchCount = 0;
137
+ try {
138
+ const beforeStats = yield this.logQueryService.getStats();
139
+ const beforeCount = beforeStats.totalRequests;
140
+ switch (config.strategy) {
141
+ case 'retention':
142
+ deletedCount = yield this.cleanupByRetention(config, errors);
143
+ break;
144
+ case 'size':
145
+ deletedCount = yield this.cleanupBySize(config, errors);
146
+ break;
147
+ case 'combination':
148
+ deletedCount = yield this.cleanupByCombination(config, errors);
149
+ break;
150
+ default:
151
+ throw new Error(`Unknown cleanup strategy: ${config.strategy}`);
152
+ }
153
+ const afterStats = yield this.logQueryService.getStats();
154
+ const afterCount = afterStats.totalRequests;
155
+ const duration = Date.now() - startTime;
156
+ const stats = {
157
+ cleanupTime: new Date(),
158
+ strategy: config.strategy,
159
+ beforeCount,
160
+ afterCount,
161
+ deletedCount,
162
+ batchCount,
163
+ duration,
164
+ errors,
165
+ };
166
+ this.logger.log(`Cleanup completed: deleted ${deletedCount} records in ${duration}ms`);
167
+ if (errors.length > 0) {
168
+ this.logger.warn(`Cleanup completed with ${errors.length} errors`, errors);
169
+ }
170
+ return stats;
171
+ }
172
+ catch (error) {
173
+ const duration = Date.now() - startTime;
174
+ this.logger.error(`Cleanup failed after ${duration}ms`, error);
175
+ throw error;
176
+ }
177
+ });
178
+ }
179
+ cleanupByRetention(config, errors) {
180
+ return __awaiter(this, void 0, void 0, function* () {
181
+ let totalDeleted = 0;
182
+ const cutoffDate = new Date();
183
+ cutoffDate.setDate(cutoffDate.getDate() - config.retentionDays);
184
+ try {
185
+ const normalDeleted = yield this.logQueryService.deleteOldLogs(config.retentionDays);
186
+ totalDeleted += normalDeleted;
187
+ }
188
+ catch (error) {
189
+ errors.push(`Retention cleanup failed: ${error.message}`);
190
+ return 0;
191
+ }
192
+ if (config.preserveErrorLogs &&
193
+ config.errorLogRetentionDays > config.retentionDays) {
194
+ this.logger.log(`Preserving error logs for ${config.errorLogRetentionDays} days`);
195
+ }
196
+ if (config.preserveSlowRequests &&
197
+ config.slowRequestRetentionDays > config.retentionDays) {
198
+ this.logger.log(`Preserving slow requests for ${config.slowRequestRetentionDays} days`);
199
+ }
200
+ return totalDeleted;
201
+ });
202
+ }
203
+ cleanupBySize(config, errors) {
204
+ return __awaiter(this, void 0, void 0, function* () {
205
+ if (!config.maxRecords) {
206
+ errors.push('Max records not configured for size-based cleanup');
207
+ return 0;
208
+ }
209
+ const stats = yield this.logQueryService.getStats();
210
+ if (stats.totalRequests <= config.maxRecords) {
211
+ this.logger.log(`Current records (${stats.totalRequests}) within limit (${config.maxRecords})`);
212
+ return 0;
213
+ }
214
+ const excessCount = stats.totalRequests - config.maxRecords;
215
+ const targetCutoffDate = new Date();
216
+ const averageDailyRecords = stats.totalRequests / 30;
217
+ const daysToDelete = Math.ceil(excessCount / averageDailyRecords);
218
+ targetCutoffDate.setDate(targetCutoffDate.getDate() - daysToDelete);
219
+ try {
220
+ const deleted = yield this.logQueryService.deleteOldLogs(Math.ceil((Date.now() - targetCutoffDate.getTime()) / (24 * 60 * 60 * 1000)));
221
+ this.logger.log(`Size-based cleanup: deleted ${deleted} records, cutoff date: ${targetCutoffDate.toISOString()}`);
222
+ return deleted;
223
+ }
224
+ catch (error) {
225
+ errors.push(`Size-based cleanup failed: ${error.message}`);
226
+ return 0;
227
+ }
228
+ });
229
+ }
230
+ cleanupByCombination(config, errors) {
231
+ return __awaiter(this, void 0, void 0, function* () {
232
+ let totalDeleted = 0;
233
+ const retentionDeleted = yield this.cleanupByRetention(config, errors);
234
+ totalDeleted += retentionDeleted;
235
+ if (config.maxRecords) {
236
+ const stats = yield this.logQueryService.getStats();
237
+ if (stats.totalRequests > config.maxRecords) {
238
+ const sizeDeleted = yield this.cleanupBySize(config, errors);
239
+ totalDeleted += sizeDeleted;
240
+ }
241
+ }
242
+ return totalDeleted;
243
+ });
244
+ }
245
+ createCleanupStats(strategy, beforeCount, afterCount, deletedCount, batchCount, errors) {
246
+ return {
247
+ cleanupTime: new Date(),
248
+ strategy,
249
+ beforeCount,
250
+ afterCount,
251
+ deletedCount,
252
+ batchCount,
253
+ duration: 0,
254
+ errors,
255
+ };
256
+ }
257
+ };
258
+ exports.HttpLogCleanupService = HttpLogCleanupService;
259
+ __decorate([
260
+ (0, schedule_decorator_1.WorkerCronSmart)(schedule_1.CronExpression.EVERY_DAY_AT_2AM),
261
+ __metadata("design:type", Function),
262
+ __metadata("design:paramtypes", []),
263
+ __metadata("design:returntype", Promise)
264
+ ], HttpLogCleanupService.prototype, "scheduledCleanup", null);
265
+ exports.HttpLogCleanupService = HttpLogCleanupService = HttpLogCleanupService_1 = __decorate([
266
+ (0, common_1.Injectable)(),
267
+ __metadata("design:paramtypes", [http_log_query_service_1.HttpLogQueryService, Object])
268
+ ], HttpLogCleanupService);
@@ -0,0 +1,36 @@
1
+ import { DataSource } from 'typeorm';
2
+ import { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
3
+ import { HttpLogEntity } from '../entities/http-log.entity';
4
+ export declare class HttpLoggingService {
5
+ private readonly dataSource?;
6
+ private readonly logger;
7
+ private logRepository;
8
+ constructor(dataSource?: DataSource);
9
+ logRequestStart(config: AxiosRequestConfig, loggingOptions: any, requestId?: string): string;
10
+ logRequestSuccess(response: AxiosResponse, startTime: number, requestId: string, loggingOptions: any, databaseLogging?: boolean, retryRecords?: any[], cacheHit?: boolean, circuitBreakerState?: string, decoratorContext?: any): void;
11
+ logRequestError(error: AxiosError, startTime: number, requestId: string, attemptCount: number, loggingOptions: any, databaseLogging?: boolean, retryRecords?: any[], cacheHit?: boolean, circuitBreakerState?: string, decoratorContext?: any): void;
12
+ findLogs(options: {
13
+ requestId?: string;
14
+ userId?: string;
15
+ method?: string;
16
+ url?: string;
17
+ statusCode?: number;
18
+ success?: boolean;
19
+ startDate?: Date;
20
+ endDate?: Date;
21
+ limit?: number;
22
+ offset?: number;
23
+ }): Promise<HttpLogEntity[]>;
24
+ getStatistics(options: {
25
+ startDate?: Date;
26
+ endDate?: Date;
27
+ userId?: string;
28
+ }): Promise<any>;
29
+ private initializeDatabaseLogging;
30
+ private extractCallInfo;
31
+ private saveToDatabase;
32
+ private sanitizeBodyAsString;
33
+ private sanitizeHeaders;
34
+ private sanitizeBody;
35
+ private sanitizeObject;
36
+ }