@nest-omni/core 3.1.2-9 → 4.1.2
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.
- package/audit/audit.module.js +1 -24
- package/audit/decorators/audit-controller.decorator.d.ts +1 -1
- package/audit/decorators/audit-controller.decorator.js +2 -2
- package/audit/decorators/audit-operation.decorator.d.ts +0 -2
- package/audit/decorators/audit-operation.decorator.js +1 -3
- package/audit/decorators/entity-audit.decorator.d.ts +1 -6
- package/audit/decorators/entity-audit.decorator.js +4 -55
- package/audit/decorators/index.d.ts +0 -1
- package/audit/decorators/index.js +0 -1
- package/audit/entities/entity-audit-log.entity.d.ts +0 -5
- package/audit/entities/entity-audit-log.entity.js +1 -30
- package/audit/entities/entity-transaction.entity.d.ts +0 -7
- package/audit/entities/entity-transaction.entity.js +1 -30
- package/audit/entities/index.d.ts +0 -2
- package/audit/entities/index.js +0 -2
- package/audit/entities/manual-operation-log.entity.d.ts +2 -0
- package/audit/entities/manual-operation-log.entity.js +19 -2
- package/audit/enums/audit.enums.d.ts +3 -18
- package/audit/enums/audit.enums.js +4 -22
- package/audit/index.d.ts +1 -3
- package/audit/index.js +1 -23
- package/audit/interfaces/audit.interfaces.d.ts +2 -63
- package/audit/services/entity-audit.service.d.ts +3 -31
- package/audit/services/entity-audit.service.js +6 -148
- package/audit/services/index.d.ts +0 -1
- package/audit/services/index.js +0 -1
- package/audit/services/manual-audit-log.service.d.ts +29 -0
- package/audit/services/manual-audit-log.service.js +184 -0
- package/common/boilerplate.polyfill.d.ts +4 -0
- package/common/boilerplate.polyfill.js +100 -7
- package/package.json +1 -1
package/audit/audit.module.js
CHANGED
|
@@ -58,20 +58,6 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
58
58
|
},
|
|
59
59
|
inject: [(0, typeorm_1.getDataSourceToken)(auditConnectionName)],
|
|
60
60
|
},
|
|
61
|
-
{
|
|
62
|
-
provide: (0, typeorm_1.getRepositoryToken)(entities_1.OperationTemplateEntity),
|
|
63
|
-
useFactory: (dataSource) => {
|
|
64
|
-
return dataSource.getRepository(entities_1.OperationTemplateEntity);
|
|
65
|
-
},
|
|
66
|
-
inject: [(0, typeorm_1.getDataSourceToken)(auditConnectionName)],
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
provide: (0, typeorm_1.getRepositoryToken)(entities_1.ManualOperationLogEntity),
|
|
70
|
-
useFactory: (dataSource) => {
|
|
71
|
-
return dataSource.getRepository(entities_1.ManualOperationLogEntity);
|
|
72
|
-
},
|
|
73
|
-
inject: [(0, typeorm_1.getDataSourceToken)(auditConnectionName)],
|
|
74
|
-
},
|
|
75
61
|
{
|
|
76
62
|
provide: 'AUDIT_ENTITY_MANAGER',
|
|
77
63
|
useFactory: (dataSource) => {
|
|
@@ -83,12 +69,7 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
83
69
|
return {
|
|
84
70
|
module: AuditModule_1,
|
|
85
71
|
imports: [
|
|
86
|
-
typeorm_1.TypeOrmModule.forFeature([
|
|
87
|
-
entities_1.EntityAuditLogEntity,
|
|
88
|
-
entities_1.EntityTransactionEntity,
|
|
89
|
-
entities_1.OperationTemplateEntity,
|
|
90
|
-
entities_1.ManualOperationLogEntity,
|
|
91
|
-
], auditConnectionName),
|
|
72
|
+
typeorm_1.TypeOrmModule.forFeature([entities_1.EntityAuditLogEntity, entities_1.EntityTransactionEntity], auditConnectionName),
|
|
92
73
|
nestjs_cls_1.ClsModule.forRoot({
|
|
93
74
|
global: true,
|
|
94
75
|
middleware: { mount: true },
|
|
@@ -114,7 +95,6 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
114
95
|
...repositoryProviders,
|
|
115
96
|
services_1.EntityAuditService,
|
|
116
97
|
services_1.TransactionAuditService,
|
|
117
|
-
services_1.OperationDescriptionService,
|
|
118
98
|
interceptors_1.AuditInterceptor,
|
|
119
99
|
...subscriberProviders,
|
|
120
100
|
],
|
|
@@ -124,7 +104,6 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
124
104
|
services_1.MultiDatabaseService,
|
|
125
105
|
services_1.EntityAuditService,
|
|
126
106
|
services_1.TransactionAuditService,
|
|
127
|
-
services_1.OperationDescriptionService,
|
|
128
107
|
interceptors_1.AuditInterceptor,
|
|
129
108
|
],
|
|
130
109
|
};
|
|
@@ -232,7 +211,6 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
232
211
|
...repositoryProviders,
|
|
233
212
|
services_1.EntityAuditService,
|
|
234
213
|
services_1.TransactionAuditService,
|
|
235
|
-
services_1.OperationDescriptionService,
|
|
236
214
|
interceptors_1.AuditInterceptor,
|
|
237
215
|
],
|
|
238
216
|
exports: [
|
|
@@ -241,7 +219,6 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
241
219
|
services_1.MultiDatabaseService,
|
|
242
220
|
services_1.EntityAuditService,
|
|
243
221
|
services_1.TransactionAuditService,
|
|
244
|
-
services_1.OperationDescriptionService,
|
|
245
222
|
interceptors_1.AuditInterceptor,
|
|
246
223
|
],
|
|
247
224
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ControllerAuditOptions, MethodAuditOptions } from '../interfaces';
|
|
2
2
|
export declare const CONTROLLER_AUDIT_OPTIONS: unique symbol;
|
|
3
3
|
export declare const METHOD_AUDIT_OPTIONS: unique symbol;
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function EntityAuditController(options?: ControllerAuditOptions): ClassDecorator;
|
|
5
5
|
export declare function AuditMethod(options?: MethodAuditOptions): MethodDecorator;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.METHOD_AUDIT_OPTIONS = exports.CONTROLLER_AUDIT_OPTIONS = void 0;
|
|
4
|
-
exports.
|
|
4
|
+
exports.EntityAuditController = EntityAuditController;
|
|
5
5
|
exports.AuditMethod = AuditMethod;
|
|
6
6
|
exports.CONTROLLER_AUDIT_OPTIONS = Symbol('CONTROLLER_AUDIT_OPTIONS');
|
|
7
7
|
exports.METHOD_AUDIT_OPTIONS = Symbol('METHOD_AUDIT_OPTIONS');
|
|
8
|
-
function
|
|
8
|
+
function EntityAuditController(options) {
|
|
9
9
|
return (target) => {
|
|
10
10
|
Reflect.defineMetadata(exports.CONTROLLER_AUDIT_OPTIONS, options || {}, target);
|
|
11
11
|
};
|
|
@@ -3,5 +3,3 @@ export declare const AUDIT_OPERATION_OPTIONS: unique symbol;
|
|
|
3
3
|
export declare function AuditLog(options: AuditOperationOptions): MethodDecorator;
|
|
4
4
|
export declare function getAuditOperationConfig(target: any, propertyKey: string | symbol): AuditOperationOptions | undefined;
|
|
5
5
|
export declare function hasAuditOperation(target: any, propertyKey: string | symbol): boolean;
|
|
6
|
-
export declare const LogOperation: typeof AuditLog;
|
|
7
|
-
export declare const AuditOperation: typeof AuditLog;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.AUDIT_OPERATION_OPTIONS = void 0;
|
|
4
4
|
exports.AuditLog = AuditLog;
|
|
5
5
|
exports.getAuditOperationConfig = getAuditOperationConfig;
|
|
6
6
|
exports.hasAuditOperation = hasAuditOperation;
|
|
@@ -21,5 +21,3 @@ function getAuditOperationConfig(target, propertyKey) {
|
|
|
21
21
|
function hasAuditOperation(target, propertyKey) {
|
|
22
22
|
return Reflect.hasMetadata(exports.AUDIT_OPERATION_OPTIONS, target, propertyKey);
|
|
23
23
|
}
|
|
24
|
-
exports.LogOperation = AuditLog;
|
|
25
|
-
exports.AuditOperation = AuditLog;
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { EntityAuditConfig, FieldDisplayOptions } from '../interfaces';
|
|
2
2
|
export declare const ENTITY_AUDIT_OPTIONS: unique symbol;
|
|
3
3
|
export declare const FIELD_AUDIT_OPTIONS: unique symbol;
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function EntityAudit(options?: EntityAuditConfig): ClassDecorator;
|
|
5
5
|
export declare function AuditField(options?: FieldDisplayOptions): PropertyDecorator;
|
|
6
|
-
export declare function getEntityAuditConfig(target: any): EntityAuditConfig;
|
|
7
|
-
export declare function getFieldAuditConfig(target: any): Record<string, FieldDisplayOptions>;
|
|
8
|
-
export declare function getFieldLabel(target: any, fieldName: string, language?: string): string;
|
|
9
|
-
export declare function getFieldValueLabel(target: any, fieldName: string, value: any, language?: string): string;
|
|
10
|
-
export declare const EntityAudit: typeof AuditEntity;
|
|
@@ -1,32 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.FIELD_AUDIT_OPTIONS = exports.ENTITY_AUDIT_OPTIONS = void 0;
|
|
4
|
+
exports.EntityAudit = EntityAudit;
|
|
5
5
|
exports.AuditField = AuditField;
|
|
6
|
-
exports.getEntityAuditConfig = getEntityAuditConfig;
|
|
7
|
-
exports.getFieldAuditConfig = getFieldAuditConfig;
|
|
8
|
-
exports.getFieldLabel = getFieldLabel;
|
|
9
|
-
exports.getFieldValueLabel = getFieldValueLabel;
|
|
10
6
|
exports.ENTITY_AUDIT_OPTIONS = Symbol('ENTITY_AUDIT_OPTIONS');
|
|
11
7
|
exports.FIELD_AUDIT_OPTIONS = Symbol('FIELD_AUDIT_OPTIONS');
|
|
12
|
-
function
|
|
8
|
+
function EntityAudit(options) {
|
|
13
9
|
return (target) => {
|
|
14
|
-
|
|
15
|
-
...((options === null || options === void 0 ? void 0 : options.maskFields) || []),
|
|
16
|
-
...((options === null || options === void 0 ? void 0 : options.sensitiveFields) || []),
|
|
17
|
-
] });
|
|
18
|
-
if (mergedOptions.maskFields && mergedOptions.maskFields.length > 0) {
|
|
19
|
-
mergedOptions.maskFields = [...new Set(mergedOptions.maskFields)];
|
|
20
|
-
}
|
|
21
|
-
Reflect.defineMetadata(exports.ENTITY_AUDIT_OPTIONS, mergedOptions, target);
|
|
22
|
-
if (mergedOptions.templateKey) {
|
|
23
|
-
Reflect.defineMetadata('entity-log:enabled', true, target);
|
|
24
|
-
Reflect.defineMetadata('entity-log:options', {
|
|
25
|
-
templateKey: mergedOptions.templateKey,
|
|
26
|
-
excludeFields: mergedOptions.excludeFields,
|
|
27
|
-
sensitiveFields: mergedOptions.maskFields,
|
|
28
|
-
}, target);
|
|
29
|
-
}
|
|
10
|
+
Reflect.defineMetadata(exports.ENTITY_AUDIT_OPTIONS, options || {}, target);
|
|
30
11
|
};
|
|
31
12
|
}
|
|
32
13
|
function AuditField(options) {
|
|
@@ -36,35 +17,3 @@ function AuditField(options) {
|
|
|
36
17
|
Reflect.defineMetadata(exports.FIELD_AUDIT_OPTIONS, existingOptions, target.constructor);
|
|
37
18
|
};
|
|
38
19
|
}
|
|
39
|
-
function getEntityAuditConfig(target) {
|
|
40
|
-
return Reflect.getMetadata(exports.ENTITY_AUDIT_OPTIONS, target) || {};
|
|
41
|
-
}
|
|
42
|
-
function getFieldAuditConfig(target) {
|
|
43
|
-
return Reflect.getMetadata(exports.FIELD_AUDIT_OPTIONS, target) || {};
|
|
44
|
-
}
|
|
45
|
-
function getFieldLabel(target, fieldName, language = 'zh') {
|
|
46
|
-
var _a;
|
|
47
|
-
const fieldConfig = getFieldAuditConfig(target);
|
|
48
|
-
const label = (_a = fieldConfig[fieldName]) === null || _a === void 0 ? void 0 : _a.label;
|
|
49
|
-
if (!label) {
|
|
50
|
-
return fieldName;
|
|
51
|
-
}
|
|
52
|
-
if (typeof label === 'string') {
|
|
53
|
-
return label;
|
|
54
|
-
}
|
|
55
|
-
return label[language] || label['zh'] || fieldName;
|
|
56
|
-
}
|
|
57
|
-
function getFieldValueLabel(target, fieldName, value, language = 'zh') {
|
|
58
|
-
var _a;
|
|
59
|
-
const fieldConfig = getFieldAuditConfig(target);
|
|
60
|
-
const valueLabels = (_a = fieldConfig[fieldName]) === null || _a === void 0 ? void 0 : _a.valueLabels;
|
|
61
|
-
if (!valueLabels || !valueLabels[value]) {
|
|
62
|
-
return value;
|
|
63
|
-
}
|
|
64
|
-
const labelMap = valueLabels[value];
|
|
65
|
-
if (typeof labelMap === 'string') {
|
|
66
|
-
return labelMap;
|
|
67
|
-
}
|
|
68
|
-
return labelMap[language] || labelMap['zh'] || value;
|
|
69
|
-
}
|
|
70
|
-
exports.EntityAudit = AuditEntity;
|
|
@@ -16,4 +16,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./entity-audit.decorator"), exports);
|
|
18
18
|
__exportStar(require("./audit-controller.decorator"), exports);
|
|
19
|
-
__exportStar(require("./audit-operation.decorator"), exports);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AbstractUuidPrimaryEntity } from '../../common/abstract.entity';
|
|
2
2
|
import { AuditOperation } from '../enums';
|
|
3
|
-
import { ChangeDetail, RollbackAction } from '../interfaces';
|
|
4
3
|
export declare class EntityAuditLogEntity extends AbstractUuidPrimaryEntity {
|
|
5
4
|
entityType: string;
|
|
6
5
|
entityId: string;
|
|
@@ -16,8 +15,4 @@ export declare class EntityAuditLogEntity extends AbstractUuidPrimaryEntity {
|
|
|
16
15
|
userAgent: string;
|
|
17
16
|
description: string;
|
|
18
17
|
hashChain: Record<string, any>;
|
|
19
|
-
operationTemplateKey: string;
|
|
20
|
-
descriptionParams: Record<string, any>;
|
|
21
|
-
changeDetails: ChangeDetail[];
|
|
22
|
-
rollbackActions: RollbackAction[];
|
|
23
18
|
}
|
|
@@ -72,39 +72,10 @@ __decorate([
|
|
|
72
72
|
(0, typeorm_1.Column)({ type: 'json', nullable: true, comment: '哈希链' }),
|
|
73
73
|
__metadata("design:type", Object)
|
|
74
74
|
], EntityAuditLogEntity.prototype, "hashChain", void 0);
|
|
75
|
-
__decorate([
|
|
76
|
-
(0, typeorm_1.Column)({ nullable: true, comment: '操作模板键,用于动态生成描述' }),
|
|
77
|
-
__metadata("design:type", String)
|
|
78
|
-
], EntityAuditLogEntity.prototype, "operationTemplateKey", void 0);
|
|
79
|
-
__decorate([
|
|
80
|
-
(0, typeorm_1.Column)({
|
|
81
|
-
type: 'json',
|
|
82
|
-
nullable: true,
|
|
83
|
-
comment: '描述参数,用于填充模板占位符',
|
|
84
|
-
}),
|
|
85
|
-
__metadata("design:type", Object)
|
|
86
|
-
], EntityAuditLogEntity.prototype, "descriptionParams", void 0);
|
|
87
|
-
__decorate([
|
|
88
|
-
(0, typeorm_1.Column)({
|
|
89
|
-
type: 'json',
|
|
90
|
-
nullable: true,
|
|
91
|
-
comment: '结构化变更详情列表(包含多语言支持)',
|
|
92
|
-
}),
|
|
93
|
-
__metadata("design:type", Array)
|
|
94
|
-
], EntityAuditLogEntity.prototype, "changeDetails", void 0);
|
|
95
|
-
__decorate([
|
|
96
|
-
(0, typeorm_1.Column)({
|
|
97
|
-
type: 'json',
|
|
98
|
-
nullable: true,
|
|
99
|
-
comment: '回滚操作列表',
|
|
100
|
-
}),
|
|
101
|
-
__metadata("design:type", Array)
|
|
102
|
-
], EntityAuditLogEntity.prototype, "rollbackActions", void 0);
|
|
103
75
|
exports.EntityAuditLogEntity = EntityAuditLogEntity = __decorate([
|
|
104
76
|
(0, typeorm_1.Entity)('entity_audit_log'),
|
|
105
77
|
(0, typeorm_1.Index)('idx_entity_relation', ['entityType', 'entityId']),
|
|
106
78
|
(0, typeorm_1.Index)('idx_operation', ['operation']),
|
|
107
79
|
(0, typeorm_1.Index)('idx_user', ['userId']),
|
|
108
|
-
(0, typeorm_1.Index)('idx_created_at', ['createdAt'])
|
|
109
|
-
(0, typeorm_1.Index)('idx_template_key', ['operationTemplateKey'])
|
|
80
|
+
(0, typeorm_1.Index)('idx_created_at', ['createdAt'])
|
|
110
81
|
], EntityAuditLogEntity);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AbstractUuidPrimaryEntity } from '../../common/abstract.entity';
|
|
2
2
|
import { AuditOperation, TransactionStatus } from '../enums';
|
|
3
|
-
import { ManualOperationLogEntity } from './manual-operation-log.entity';
|
|
4
3
|
export declare class EntityTransactionEntity extends AbstractUuidPrimaryEntity {
|
|
5
4
|
description: string;
|
|
6
5
|
status: TransactionStatus;
|
|
@@ -12,10 +11,4 @@ export declare class EntityTransactionEntity extends AbstractUuidPrimaryEntity {
|
|
|
12
11
|
userId: string;
|
|
13
12
|
username: string;
|
|
14
13
|
dependencyGraph: Record<string, any>;
|
|
15
|
-
operationTemplateKey: string;
|
|
16
|
-
descriptionParams: Record<string, any>;
|
|
17
|
-
requestIp: string;
|
|
18
|
-
metadata: Record<string, any>;
|
|
19
|
-
completedAt: Date;
|
|
20
|
-
manualOperations: ManualOperationLogEntity[];
|
|
21
14
|
}
|
|
@@ -43,38 +43,9 @@ __decorate([
|
|
|
43
43
|
(0, typeorm_1.Column)({ type: 'json', nullable: true, comment: '依赖图' }),
|
|
44
44
|
__metadata("design:type", Object)
|
|
45
45
|
], EntityTransactionEntity.prototype, "dependencyGraph", void 0);
|
|
46
|
-
__decorate([
|
|
47
|
-
(0, typeorm_1.Column)({ nullable: true, comment: '操作模板键(事务级别)' }),
|
|
48
|
-
__metadata("design:type", String)
|
|
49
|
-
], EntityTransactionEntity.prototype, "operationTemplateKey", void 0);
|
|
50
|
-
__decorate([
|
|
51
|
-
(0, typeorm_1.Column)({
|
|
52
|
-
type: 'json',
|
|
53
|
-
nullable: true,
|
|
54
|
-
comment: '描述参数,用于填充事务级别的模板占位符',
|
|
55
|
-
}),
|
|
56
|
-
__metadata("design:type", Object)
|
|
57
|
-
], EntityTransactionEntity.prototype, "descriptionParams", void 0);
|
|
58
|
-
__decorate([
|
|
59
|
-
(0, typeorm_1.Column)({ nullable: true, comment: '请求IP' }),
|
|
60
|
-
__metadata("design:type", String)
|
|
61
|
-
], EntityTransactionEntity.prototype, "requestIp", void 0);
|
|
62
|
-
__decorate([
|
|
63
|
-
(0, typeorm_1.Column)({ type: 'json', nullable: true, comment: '事务元数据' }),
|
|
64
|
-
__metadata("design:type", Object)
|
|
65
|
-
], EntityTransactionEntity.prototype, "metadata", void 0);
|
|
66
|
-
__decorate([
|
|
67
|
-
(0, typeorm_1.Column)({ type: 'timestamp', nullable: true, comment: '完成时间' }),
|
|
68
|
-
__metadata("design:type", Date)
|
|
69
|
-
], EntityTransactionEntity.prototype, "completedAt", void 0);
|
|
70
|
-
__decorate([
|
|
71
|
-
(0, typeorm_1.OneToMany)('ManualOperationLogEntity', (log) => log.transaction),
|
|
72
|
-
__metadata("design:type", Array)
|
|
73
|
-
], EntityTransactionEntity.prototype, "manualOperations", void 0);
|
|
74
46
|
exports.EntityTransactionEntity = EntityTransactionEntity = __decorate([
|
|
75
47
|
(0, typeorm_1.Entity)('entity_transaction'),
|
|
76
48
|
(0, typeorm_1.Index)('idx_status', ['status']),
|
|
77
49
|
(0, typeorm_1.Index)('idx_user', ['userId']),
|
|
78
|
-
(0, typeorm_1.Index)('idx_created_at', ['createdAt'])
|
|
79
|
-
(0, typeorm_1.Index)('idx_template_key', ['operationTemplateKey'])
|
|
50
|
+
(0, typeorm_1.Index)('idx_created_at', ['createdAt'])
|
|
80
51
|
], EntityTransactionEntity);
|
package/audit/entities/index.js
CHANGED
|
@@ -16,5 +16,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./entity-audit-log.entity"), exports);
|
|
18
18
|
__exportStar(require("./entity-transaction.entity"), exports);
|
|
19
|
-
__exportStar(require("./operation-template.entity"), exports);
|
|
20
|
-
__exportStar(require("./manual-operation-log.entity"), exports);
|
|
@@ -5,6 +5,8 @@ export declare class ManualOperationLogEntity extends AbstractUuidPrimaryEntity
|
|
|
5
5
|
transactionId: string;
|
|
6
6
|
operationTemplateKey: string;
|
|
7
7
|
descriptionParams: Record<string, any>;
|
|
8
|
+
directDescription: string | Record<string, string>;
|
|
9
|
+
inlineTemplate: Record<string, string>;
|
|
8
10
|
userId: string;
|
|
9
11
|
username: string;
|
|
10
12
|
requestIp: string;
|
|
@@ -17,20 +17,37 @@ let ManualOperationLogEntity = class ManualOperationLogEntity extends abstract_e
|
|
|
17
17
|
};
|
|
18
18
|
exports.ManualOperationLogEntity = ManualOperationLogEntity;
|
|
19
19
|
__decorate([
|
|
20
|
-
(0, typeorm_1.Column)({ comment: '关联的事务ID' }),
|
|
20
|
+
(0, typeorm_1.Column)({ nullable: true, comment: '关联的事务ID' }),
|
|
21
21
|
__metadata("design:type", String)
|
|
22
22
|
], ManualOperationLogEntity.prototype, "transactionId", void 0);
|
|
23
23
|
__decorate([
|
|
24
|
-
(0, typeorm_1.Column)({ comment: '
|
|
24
|
+
(0, typeorm_1.Column)({ nullable: true, comment: '操作模板键(模板键模式)' }),
|
|
25
25
|
__metadata("design:type", String)
|
|
26
26
|
], ManualOperationLogEntity.prototype, "operationTemplateKey", void 0);
|
|
27
27
|
__decorate([
|
|
28
28
|
(0, typeorm_1.Column)({
|
|
29
29
|
type: 'json',
|
|
30
|
+
nullable: true,
|
|
30
31
|
comment: '描述参数,用于填充模板占位符',
|
|
31
32
|
}),
|
|
32
33
|
__metadata("design:type", Object)
|
|
33
34
|
], ManualOperationLogEntity.prototype, "descriptionParams", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, typeorm_1.Column)({
|
|
37
|
+
type: 'json',
|
|
38
|
+
nullable: true,
|
|
39
|
+
comment: '直接描述(直接描述模式),可以是字符串或多语言对象',
|
|
40
|
+
}),
|
|
41
|
+
__metadata("design:type", Object)
|
|
42
|
+
], ManualOperationLogEntity.prototype, "directDescription", void 0);
|
|
43
|
+
__decorate([
|
|
44
|
+
(0, typeorm_1.Column)({
|
|
45
|
+
type: 'json',
|
|
46
|
+
nullable: true,
|
|
47
|
+
comment: '内联模板(内联模板模式),多语言模板对象',
|
|
48
|
+
}),
|
|
49
|
+
__metadata("design:type", Object)
|
|
50
|
+
], ManualOperationLogEntity.prototype, "inlineTemplate", void 0);
|
|
34
51
|
__decorate([
|
|
35
52
|
(0, typeorm_1.Column)({ nullable: true, comment: '操作用户ID' }),
|
|
36
53
|
__metadata("design:type", String)
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
export declare enum OperationType {
|
|
2
|
-
CREATE = "create",
|
|
3
|
-
UPDATE = "update",
|
|
4
|
-
DELETE = "delete"
|
|
5
|
-
}
|
|
6
1
|
export declare enum AuditOperation {
|
|
7
2
|
CREATE = "CREATE",
|
|
8
3
|
UPDATE = "UPDATE",
|
|
@@ -10,9 +5,9 @@ export declare enum AuditOperation {
|
|
|
10
5
|
RESTORE = "RESTORE"
|
|
11
6
|
}
|
|
12
7
|
export declare enum TransactionStatus {
|
|
13
|
-
PENDING = "
|
|
14
|
-
COMMITTED = "
|
|
15
|
-
ROLLED_BACK = "
|
|
8
|
+
PENDING = "PENDING",
|
|
9
|
+
COMMITTED = "COMMITTED",
|
|
10
|
+
ROLLED_BACK = "ROLLED_BACK"
|
|
16
11
|
}
|
|
17
12
|
export declare enum RecoveryStrategy {
|
|
18
13
|
ENTITY_ONLY = "ENTITY_ONLY",
|
|
@@ -30,13 +25,3 @@ export declare enum MaskingStrategy {
|
|
|
30
25
|
MASK = "MASK",
|
|
31
26
|
PARTIAL = "PARTIAL"
|
|
32
27
|
}
|
|
33
|
-
export declare enum RollbackActionType {
|
|
34
|
-
ENTITY = "entity",
|
|
35
|
-
FILE = "file",
|
|
36
|
-
CUSTOM = "custom"
|
|
37
|
-
}
|
|
38
|
-
export declare enum ChangeType {
|
|
39
|
-
ADDED = "added",
|
|
40
|
-
REMOVED = "removed",
|
|
41
|
-
MODIFIED = "modified"
|
|
42
|
-
}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
var OperationType;
|
|
5
|
-
(function (OperationType) {
|
|
6
|
-
OperationType["CREATE"] = "create";
|
|
7
|
-
OperationType["UPDATE"] = "update";
|
|
8
|
-
OperationType["DELETE"] = "delete";
|
|
9
|
-
})(OperationType || (exports.OperationType = OperationType = {}));
|
|
3
|
+
exports.MaskingStrategy = exports.RecordStrategy = exports.RecoveryStrategy = exports.TransactionStatus = exports.AuditOperation = void 0;
|
|
10
4
|
var AuditOperation;
|
|
11
5
|
(function (AuditOperation) {
|
|
12
6
|
AuditOperation["CREATE"] = "CREATE";
|
|
@@ -16,9 +10,9 @@ var AuditOperation;
|
|
|
16
10
|
})(AuditOperation || (exports.AuditOperation = AuditOperation = {}));
|
|
17
11
|
var TransactionStatus;
|
|
18
12
|
(function (TransactionStatus) {
|
|
19
|
-
TransactionStatus["PENDING"] = "
|
|
20
|
-
TransactionStatus["COMMITTED"] = "
|
|
21
|
-
TransactionStatus["ROLLED_BACK"] = "
|
|
13
|
+
TransactionStatus["PENDING"] = "PENDING";
|
|
14
|
+
TransactionStatus["COMMITTED"] = "COMMITTED";
|
|
15
|
+
TransactionStatus["ROLLED_BACK"] = "ROLLED_BACK";
|
|
22
16
|
})(TransactionStatus || (exports.TransactionStatus = TransactionStatus = {}));
|
|
23
17
|
var RecoveryStrategy;
|
|
24
18
|
(function (RecoveryStrategy) {
|
|
@@ -39,15 +33,3 @@ var MaskingStrategy;
|
|
|
39
33
|
MaskingStrategy["MASK"] = "MASK";
|
|
40
34
|
MaskingStrategy["PARTIAL"] = "PARTIAL";
|
|
41
35
|
})(MaskingStrategy || (exports.MaskingStrategy = MaskingStrategy = {}));
|
|
42
|
-
var RollbackActionType;
|
|
43
|
-
(function (RollbackActionType) {
|
|
44
|
-
RollbackActionType["ENTITY"] = "entity";
|
|
45
|
-
RollbackActionType["FILE"] = "file";
|
|
46
|
-
RollbackActionType["CUSTOM"] = "custom";
|
|
47
|
-
})(RollbackActionType || (exports.RollbackActionType = RollbackActionType = {}));
|
|
48
|
-
var ChangeType;
|
|
49
|
-
(function (ChangeType) {
|
|
50
|
-
ChangeType["ADDED"] = "added";
|
|
51
|
-
ChangeType["REMOVED"] = "removed";
|
|
52
|
-
ChangeType["MODIFIED"] = "modified";
|
|
53
|
-
})(ChangeType || (exports.ChangeType = ChangeType = {}));
|
package/audit/index.d.ts
CHANGED
|
@@ -2,9 +2,7 @@ export * from './entities';
|
|
|
2
2
|
export * from './enums';
|
|
3
3
|
export * from './interfaces';
|
|
4
4
|
export * from './dto';
|
|
5
|
-
export
|
|
6
|
-
export { AuditController, AuditMethod, CONTROLLER_AUDIT_OPTIONS, METHOD_AUDIT_OPTIONS, } from './decorators/audit-controller.decorator';
|
|
7
|
-
export { AuditLog, LogOperation, AuditOperation, getAuditOperationConfig, hasAuditOperation, AUDIT_OPERATION_OPTIONS, } from './decorators/audit-operation.decorator';
|
|
5
|
+
export * from './decorators';
|
|
8
6
|
export * from './services';
|
|
9
7
|
export * from './subscribers';
|
|
10
8
|
export * from './interceptors';
|
package/audit/index.js
CHANGED
|
@@ -14,33 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.AUDIT_OPERATION_OPTIONS = exports.hasAuditOperation = exports.getAuditOperationConfig = exports.AuditOperation = exports.LogOperation = exports.AuditLog = exports.METHOD_AUDIT_OPTIONS = exports.CONTROLLER_AUDIT_OPTIONS = exports.AuditMethod = exports.AuditController = exports.FIELD_AUDIT_OPTIONS = exports.ENTITY_AUDIT_OPTIONS = exports.getFieldValueLabel = exports.getFieldLabel = exports.getFieldAuditConfig = exports.getEntityAuditConfig = exports.AuditField = exports.EntityAudit = exports.AuditEntity = void 0;
|
|
18
17
|
__exportStar(require("./entities"), exports);
|
|
19
18
|
__exportStar(require("./enums"), exports);
|
|
20
19
|
__exportStar(require("./interfaces"), exports);
|
|
21
20
|
__exportStar(require("./dto"), exports);
|
|
22
|
-
|
|
23
|
-
Object.defineProperty(exports, "AuditEntity", { enumerable: true, get: function () { return entity_audit_decorator_1.AuditEntity; } });
|
|
24
|
-
Object.defineProperty(exports, "EntityAudit", { enumerable: true, get: function () { return entity_audit_decorator_1.EntityAudit; } });
|
|
25
|
-
Object.defineProperty(exports, "AuditField", { enumerable: true, get: function () { return entity_audit_decorator_1.AuditField; } });
|
|
26
|
-
Object.defineProperty(exports, "getEntityAuditConfig", { enumerable: true, get: function () { return entity_audit_decorator_1.getEntityAuditConfig; } });
|
|
27
|
-
Object.defineProperty(exports, "getFieldAuditConfig", { enumerable: true, get: function () { return entity_audit_decorator_1.getFieldAuditConfig; } });
|
|
28
|
-
Object.defineProperty(exports, "getFieldLabel", { enumerable: true, get: function () { return entity_audit_decorator_1.getFieldLabel; } });
|
|
29
|
-
Object.defineProperty(exports, "getFieldValueLabel", { enumerable: true, get: function () { return entity_audit_decorator_1.getFieldValueLabel; } });
|
|
30
|
-
Object.defineProperty(exports, "ENTITY_AUDIT_OPTIONS", { enumerable: true, get: function () { return entity_audit_decorator_1.ENTITY_AUDIT_OPTIONS; } });
|
|
31
|
-
Object.defineProperty(exports, "FIELD_AUDIT_OPTIONS", { enumerable: true, get: function () { return entity_audit_decorator_1.FIELD_AUDIT_OPTIONS; } });
|
|
32
|
-
var audit_controller_decorator_1 = require("./decorators/audit-controller.decorator");
|
|
33
|
-
Object.defineProperty(exports, "AuditController", { enumerable: true, get: function () { return audit_controller_decorator_1.AuditController; } });
|
|
34
|
-
Object.defineProperty(exports, "AuditMethod", { enumerable: true, get: function () { return audit_controller_decorator_1.AuditMethod; } });
|
|
35
|
-
Object.defineProperty(exports, "CONTROLLER_AUDIT_OPTIONS", { enumerable: true, get: function () { return audit_controller_decorator_1.CONTROLLER_AUDIT_OPTIONS; } });
|
|
36
|
-
Object.defineProperty(exports, "METHOD_AUDIT_OPTIONS", { enumerable: true, get: function () { return audit_controller_decorator_1.METHOD_AUDIT_OPTIONS; } });
|
|
37
|
-
var audit_operation_decorator_1 = require("./decorators/audit-operation.decorator");
|
|
38
|
-
Object.defineProperty(exports, "AuditLog", { enumerable: true, get: function () { return audit_operation_decorator_1.AuditLog; } });
|
|
39
|
-
Object.defineProperty(exports, "LogOperation", { enumerable: true, get: function () { return audit_operation_decorator_1.LogOperation; } });
|
|
40
|
-
Object.defineProperty(exports, "AuditOperation", { enumerable: true, get: function () { return audit_operation_decorator_1.AuditOperation; } });
|
|
41
|
-
Object.defineProperty(exports, "getAuditOperationConfig", { enumerable: true, get: function () { return audit_operation_decorator_1.getAuditOperationConfig; } });
|
|
42
|
-
Object.defineProperty(exports, "hasAuditOperation", { enumerable: true, get: function () { return audit_operation_decorator_1.hasAuditOperation; } });
|
|
43
|
-
Object.defineProperty(exports, "AUDIT_OPERATION_OPTIONS", { enumerable: true, get: function () { return audit_operation_decorator_1.AUDIT_OPERATION_OPTIONS; } });
|
|
21
|
+
__exportStar(require("./decorators"), exports);
|
|
44
22
|
__exportStar(require("./services"), exports);
|
|
45
23
|
__exportStar(require("./subscribers"), exports);
|
|
46
24
|
__exportStar(require("./interceptors"), exports);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuditOperation, MaskingStrategy, RecordStrategy
|
|
1
|
+
import { AuditOperation, MaskingStrategy, RecordStrategy } from '../enums/audit.enums';
|
|
2
2
|
export interface AuditContext {
|
|
3
3
|
userId?: string;
|
|
4
4
|
username?: string;
|
|
@@ -100,16 +100,13 @@ export interface EntityAuditConfig {
|
|
|
100
100
|
includeFields?: string[];
|
|
101
101
|
excludeFields?: string[];
|
|
102
102
|
maskFields?: string[];
|
|
103
|
-
templateKey?: string;
|
|
104
|
-
sensitiveFields?: string[];
|
|
105
103
|
}
|
|
106
104
|
export interface OperationAuditConfig {
|
|
107
105
|
enabled?: boolean;
|
|
108
106
|
strategy?: RecordStrategy;
|
|
109
107
|
}
|
|
110
108
|
export interface FieldDisplayOptions {
|
|
111
|
-
|
|
112
|
-
valueLabels?: Record<string, Record<string, string>>;
|
|
109
|
+
displayName?: string;
|
|
113
110
|
sensitive?: boolean;
|
|
114
111
|
formatter?: (value: any) => string;
|
|
115
112
|
}
|
|
@@ -120,61 +117,3 @@ export interface ControllerAuditOptions {
|
|
|
120
117
|
export interface MethodAuditOptions {
|
|
121
118
|
enabled?: boolean;
|
|
122
119
|
}
|
|
123
|
-
export interface ChangeDetail {
|
|
124
|
-
fieldName: string;
|
|
125
|
-
fieldLabels?: Record<string, string>;
|
|
126
|
-
oldValue: any;
|
|
127
|
-
newValue: any;
|
|
128
|
-
displayOldValue?: Record<string, string>;
|
|
129
|
-
displayNewValue?: Record<string, string>;
|
|
130
|
-
changeType: ChangeType;
|
|
131
|
-
}
|
|
132
|
-
export interface RollbackAction {
|
|
133
|
-
type: RollbackActionType;
|
|
134
|
-
action: string;
|
|
135
|
-
params: Record<string, any>;
|
|
136
|
-
order: number;
|
|
137
|
-
handler?: string;
|
|
138
|
-
}
|
|
139
|
-
export interface OperationTemplateData {
|
|
140
|
-
key: string;
|
|
141
|
-
entityName: string;
|
|
142
|
-
operation: AuditOperation;
|
|
143
|
-
nameTemplates: Record<string, string>;
|
|
144
|
-
descriptionTemplates: Record<string, string>;
|
|
145
|
-
fieldLabels?: Record<string, Record<string, string>>;
|
|
146
|
-
valueDisplays?: Record<string, Record<string, Record<string, string>>>;
|
|
147
|
-
}
|
|
148
|
-
export interface ManualOperationData {
|
|
149
|
-
transactionId: string;
|
|
150
|
-
operationTemplateKey: string;
|
|
151
|
-
descriptionParams: Record<string, any>;
|
|
152
|
-
userId?: string;
|
|
153
|
-
username?: string;
|
|
154
|
-
requestIp?: string;
|
|
155
|
-
rollbackActions?: RollbackAction[];
|
|
156
|
-
}
|
|
157
|
-
export interface AuditOperationOptions {
|
|
158
|
-
templateKey: string;
|
|
159
|
-
descriptionParams?: (args: any[], result: any, context: any) => Record<string, any>;
|
|
160
|
-
rollbackActions?: (args: any[], result: any, context: any) => RollbackAction[];
|
|
161
|
-
autoTransaction?: boolean;
|
|
162
|
-
}
|
|
163
|
-
export interface EnhancedEntityAuditConfig extends EntityAuditConfig {
|
|
164
|
-
templateKey?: string;
|
|
165
|
-
fieldLabels?: Record<string, Record<string, string>>;
|
|
166
|
-
valueDisplays?: Record<string, Record<string, Record<string, string>>>;
|
|
167
|
-
}
|
|
168
|
-
export interface TransactionDescription {
|
|
169
|
-
operationName: string;
|
|
170
|
-
description: string;
|
|
171
|
-
changes: Array<{
|
|
172
|
-
entityName?: string;
|
|
173
|
-
entityId?: string;
|
|
174
|
-
operation?: AuditOperation;
|
|
175
|
-
type?: string;
|
|
176
|
-
description: string;
|
|
177
|
-
details: any;
|
|
178
|
-
createdAt: Date;
|
|
179
|
-
}>;
|
|
180
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Repository, EntityManager } from 'typeorm';
|
|
2
|
-
import { EntityAuditLogEntity, EntityTransactionEntity
|
|
2
|
+
import { EntityAuditLogEntity, EntityTransactionEntity } from '../entities';
|
|
3
3
|
import { AuditOperation } from '../enums';
|
|
4
|
-
import { AuditConfig, IAuditStrategy, EntityDifference, RestoreOptions, RestoreResult, PreCheckResult
|
|
4
|
+
import { AuditConfig, IAuditStrategy, EntityDifference, RestoreOptions, RestoreResult, PreCheckResult } from '../interfaces';
|
|
5
5
|
import { AuditContextService } from './audit-context.service';
|
|
6
6
|
import { MultiDatabaseService } from './multi-database.service';
|
|
7
7
|
import { PageDto } from '../../common/dto';
|
|
@@ -9,14 +9,13 @@ import { AuditLogQueryDto } from '../dto';
|
|
|
9
9
|
export declare class EntityAuditService {
|
|
10
10
|
private readonly auditLogRepository;
|
|
11
11
|
private readonly transactionRepository;
|
|
12
|
-
private readonly manualOperationRepository;
|
|
13
12
|
private readonly entityManager;
|
|
14
13
|
private readonly contextService;
|
|
15
14
|
private readonly multiDbService;
|
|
16
15
|
private readonly auditStrategy;
|
|
17
16
|
private readonly config?;
|
|
18
17
|
private readonly auditConnectionName;
|
|
19
|
-
constructor(auditLogRepository: Repository<EntityAuditLogEntity>, transactionRepository: Repository<EntityTransactionEntity>,
|
|
18
|
+
constructor(auditLogRepository: Repository<EntityAuditLogEntity>, transactionRepository: Repository<EntityTransactionEntity>, entityManager: EntityManager, contextService: AuditContextService, multiDbService: MultiDatabaseService, auditStrategy?: IAuditStrategy, config?: AuditConfig, auditConnectionName?: string);
|
|
20
19
|
logEntityChange(entityType: string, entityId: string, operation: AuditOperation, oldValue: Record<string, any>, newValue: Record<string, any>, metadata?: Record<string, any>): Promise<EntityAuditLogEntity | null>;
|
|
21
20
|
getAuditLogs(query: AuditLogQueryDto): Promise<PageDto<EntityAuditLogEntity>>;
|
|
22
21
|
compareEntities(entityType: string, entityId: string, fromLogId?: string, toLogId?: string): Promise<EntityDifference>;
|
|
@@ -35,31 +34,4 @@ export declare class EntityAuditService {
|
|
|
35
34
|
private generateHashChain;
|
|
36
35
|
private generateDescription;
|
|
37
36
|
private detectConflicts;
|
|
38
|
-
logEntityChangeWithTemplate(data: {
|
|
39
|
-
entityType: string;
|
|
40
|
-
entityId: string;
|
|
41
|
-
operation: AuditOperation;
|
|
42
|
-
oldValue?: Record<string, any>;
|
|
43
|
-
newValue?: Record<string, any>;
|
|
44
|
-
changedFields?: string[];
|
|
45
|
-
operationTemplateKey?: string;
|
|
46
|
-
descriptionParams?: Record<string, any>;
|
|
47
|
-
changeDetails?: ChangeDetail[];
|
|
48
|
-
rollbackActions?: RollbackAction[];
|
|
49
|
-
metadata?: Record<string, any>;
|
|
50
|
-
}): Promise<EntityAuditLogEntity | null>;
|
|
51
|
-
logManualOperation(data: ManualOperationData): Promise<ManualOperationLogEntity>;
|
|
52
|
-
withTransaction<T>(fn: (transactionId: string) => Promise<T>, options?: {
|
|
53
|
-
userId?: string;
|
|
54
|
-
username?: string;
|
|
55
|
-
requestIp?: string;
|
|
56
|
-
operationTemplateKey?: string;
|
|
57
|
-
descriptionParams?: Record<string, any>;
|
|
58
|
-
metadata?: Record<string, any>;
|
|
59
|
-
}): Promise<T>;
|
|
60
|
-
getCurrentTransactionId(): Promise<string | null>;
|
|
61
|
-
setCurrentTransactionId(transactionId: string | null): Promise<void>;
|
|
62
|
-
beginTransaction(userId?: string, userName?: string, ip?: string, operationTemplateKey?: string, descriptionParams?: Record<string, any>): Promise<string>;
|
|
63
|
-
commitTransaction(transactionId: string): Promise<void>;
|
|
64
|
-
rollbackTransaction(transactionId: string): Promise<void>;
|
|
65
37
|
}
|
|
@@ -33,10 +33,9 @@ const audit_strategy_service_1 = require("./audit-strategy.service");
|
|
|
33
33
|
const multi_database_service_1 = require("./multi-database.service");
|
|
34
34
|
const dto_1 = require("../../common/dto");
|
|
35
35
|
let EntityAuditService = class EntityAuditService {
|
|
36
|
-
constructor(auditLogRepository, transactionRepository,
|
|
36
|
+
constructor(auditLogRepository, transactionRepository, entityManager, contextService, multiDbService, auditStrategy = new audit_strategy_service_1.DefaultAuditStrategy(), config, auditConnectionName) {
|
|
37
37
|
this.auditLogRepository = auditLogRepository;
|
|
38
38
|
this.transactionRepository = transactionRepository;
|
|
39
|
-
this.manualOperationRepository = manualOperationRepository;
|
|
40
39
|
this.entityManager = entityManager;
|
|
41
40
|
this.contextService = contextService;
|
|
42
41
|
this.multiDbService = multiDbService;
|
|
@@ -464,161 +463,20 @@ let EntityAuditService = class EntityAuditService {
|
|
|
464
463
|
}
|
|
465
464
|
return conflicts;
|
|
466
465
|
}
|
|
467
|
-
logEntityChangeWithTemplate(data) {
|
|
468
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
469
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
470
|
-
if (!this.auditStrategy.shouldRecord(data.entityType, data.operation)) {
|
|
471
|
-
return null;
|
|
472
|
-
}
|
|
473
|
-
const recordStrategy = this.auditStrategy.getRecordStrategy(data.entityType, data.operation);
|
|
474
|
-
if (recordStrategy === enums_1.RecordStrategy.DISABLED) {
|
|
475
|
-
return null;
|
|
476
|
-
}
|
|
477
|
-
const fieldFilter = this.auditStrategy.getFieldFilter(data.entityType);
|
|
478
|
-
const filteredOldValue = this.filterAndMaskFields(data.oldValue || {}, fieldFilter);
|
|
479
|
-
const filteredNewValue = this.filterAndMaskFields(data.newValue || {}, fieldFilter);
|
|
480
|
-
const changedFields = data.changedFields || this.calculateChangedFields(filteredOldValue, filteredNewValue);
|
|
481
|
-
const changedFieldPaths = this.calculateChangedFieldPaths(filteredOldValue, filteredNewValue);
|
|
482
|
-
const context = yield this.contextService.getCurrentContext();
|
|
483
|
-
const operationTemplateKey = data.operationTemplateKey || `${data.entityType}.${data.operation}`;
|
|
484
|
-
const descriptionParams = data.descriptionParams || Object.assign(Object.assign(Object.assign({}, filteredOldValue), filteredNewValue), { changedFields, changedFieldsCount: changedFields.length });
|
|
485
|
-
const auditLog = this.auditLogRepository.create({
|
|
486
|
-
entityType: data.entityType,
|
|
487
|
-
entityId: data.entityId,
|
|
488
|
-
operation: data.operation,
|
|
489
|
-
oldValue: filteredOldValue,
|
|
490
|
-
newValue: filteredNewValue,
|
|
491
|
-
changedFields,
|
|
492
|
-
changedFieldPaths: changedFieldPaths.join(','),
|
|
493
|
-
userId: context.userId || ((_a = data.metadata) === null || _a === void 0 ? void 0 : _a.userId),
|
|
494
|
-
username: context.username || ((_b = data.metadata) === null || _b === void 0 ? void 0 : _b.username),
|
|
495
|
-
requestId: context.requestId || ((_c = data.metadata) === null || _c === void 0 ? void 0 : _c.requestId),
|
|
496
|
-
requestIp: context.requestIp || ((_d = data.metadata) === null || _d === void 0 ? void 0 : _d.requestIp),
|
|
497
|
-
userAgent: context.userAgent || ((_e = data.metadata) === null || _e === void 0 ? void 0 : _e.userAgent),
|
|
498
|
-
description: this.generateDescription(data.operation, data.entityType, data.entityId, changedFields),
|
|
499
|
-
hashChain: ((_g = (_f = this.config) === null || _f === void 0 ? void 0 : _f.security) === null || _g === void 0 ? void 0 : _g.hashChainEnabled)
|
|
500
|
-
? yield this.generateHashChain(data.entityType, data.entityId, filteredNewValue)
|
|
501
|
-
: undefined,
|
|
502
|
-
operationTemplateKey,
|
|
503
|
-
descriptionParams,
|
|
504
|
-
changeDetails: data.changeDetails,
|
|
505
|
-
rollbackActions: data.rollbackActions,
|
|
506
|
-
});
|
|
507
|
-
const savedLog = yield this.auditLogRepository.save(auditLog);
|
|
508
|
-
return savedLog;
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
logManualOperation(data) {
|
|
512
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
513
|
-
const context = yield this.contextService.getCurrentContext();
|
|
514
|
-
const manualLog = this.manualOperationRepository.create({
|
|
515
|
-
transactionId: data.transactionId,
|
|
516
|
-
operationTemplateKey: data.operationTemplateKey,
|
|
517
|
-
descriptionParams: data.descriptionParams,
|
|
518
|
-
userId: data.userId || context.userId,
|
|
519
|
-
username: data.username || context.username,
|
|
520
|
-
requestIp: data.requestIp || context.requestIp,
|
|
521
|
-
rollbackActions: data.rollbackActions || [],
|
|
522
|
-
});
|
|
523
|
-
return yield this.manualOperationRepository.save(manualLog);
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
withTransaction(fn, options) {
|
|
527
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
528
|
-
var _a;
|
|
529
|
-
const context = yield this.contextService.getCurrentContext();
|
|
530
|
-
const transaction = this.transactionRepository.create({
|
|
531
|
-
description: ((_a = options === null || options === void 0 ? void 0 : options.descriptionParams) === null || _a === void 0 ? void 0 : _a.description) || 'Transaction',
|
|
532
|
-
status: 'PENDING',
|
|
533
|
-
entities: [],
|
|
534
|
-
userId: (options === null || options === void 0 ? void 0 : options.userId) || context.userId,
|
|
535
|
-
username: (options === null || options === void 0 ? void 0 : options.username) || context.username,
|
|
536
|
-
requestIp: (options === null || options === void 0 ? void 0 : options.requestIp) || context.requestIp,
|
|
537
|
-
operationTemplateKey: options === null || options === void 0 ? void 0 : options.operationTemplateKey,
|
|
538
|
-
descriptionParams: options === null || options === void 0 ? void 0 : options.descriptionParams,
|
|
539
|
-
metadata: options === null || options === void 0 ? void 0 : options.metadata,
|
|
540
|
-
});
|
|
541
|
-
const savedTransaction = yield this.transactionRepository.save(transaction);
|
|
542
|
-
const transactionId = savedTransaction.id;
|
|
543
|
-
try {
|
|
544
|
-
yield this.contextService.setContext(Object.assign(Object.assign({}, context), { transactionId }));
|
|
545
|
-
const result = yield fn(transactionId);
|
|
546
|
-
yield this.transactionRepository.update(transactionId, {
|
|
547
|
-
status: 'COMMITTED',
|
|
548
|
-
completedAt: new Date(),
|
|
549
|
-
});
|
|
550
|
-
return result;
|
|
551
|
-
}
|
|
552
|
-
catch (error) {
|
|
553
|
-
yield this.transactionRepository.update(transactionId, {
|
|
554
|
-
status: 'ROLLED_BACK',
|
|
555
|
-
completedAt: new Date(),
|
|
556
|
-
});
|
|
557
|
-
throw error;
|
|
558
|
-
}
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
getCurrentTransactionId() {
|
|
562
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
563
|
-
const context = yield this.contextService.getCurrentContext();
|
|
564
|
-
return context.transactionId || null;
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
setCurrentTransactionId(transactionId) {
|
|
568
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
569
|
-
const context = yield this.contextService.getCurrentContext();
|
|
570
|
-
yield this.contextService.setContext(Object.assign(Object.assign({}, context), { transactionId }));
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
beginTransaction(userId, userName, ip, operationTemplateKey, descriptionParams) {
|
|
574
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
575
|
-
const context = yield this.contextService.getCurrentContext();
|
|
576
|
-
const transaction = this.transactionRepository.create({
|
|
577
|
-
description: (descriptionParams === null || descriptionParams === void 0 ? void 0 : descriptionParams.description) || 'Transaction',
|
|
578
|
-
status: 'pending',
|
|
579
|
-
entities: [],
|
|
580
|
-
userId: userId || context.userId,
|
|
581
|
-
username: userName || context.username,
|
|
582
|
-
requestIp: ip || context.requestIp,
|
|
583
|
-
operationTemplateKey,
|
|
584
|
-
descriptionParams,
|
|
585
|
-
});
|
|
586
|
-
const savedTransaction = yield this.transactionRepository.save(transaction);
|
|
587
|
-
return savedTransaction.id;
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
commitTransaction(transactionId) {
|
|
591
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
592
|
-
yield this.transactionRepository.update(transactionId, {
|
|
593
|
-
status: 'committed',
|
|
594
|
-
completedAt: new Date(),
|
|
595
|
-
});
|
|
596
|
-
});
|
|
597
|
-
}
|
|
598
|
-
rollbackTransaction(transactionId) {
|
|
599
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
600
|
-
yield this.transactionRepository.update(transactionId, {
|
|
601
|
-
status: 'rolled_back',
|
|
602
|
-
completedAt: new Date(),
|
|
603
|
-
});
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
466
|
};
|
|
607
467
|
exports.EntityAuditService = EntityAuditService;
|
|
608
468
|
exports.EntityAuditService = EntityAuditService = __decorate([
|
|
609
469
|
(0, common_1.Injectable)(),
|
|
610
470
|
__param(0, (0, typeorm_1.InjectRepository)(entities_1.EntityAuditLogEntity)),
|
|
611
471
|
__param(1, (0, typeorm_1.InjectRepository)(entities_1.EntityTransactionEntity)),
|
|
612
|
-
__param(2, (0,
|
|
613
|
-
__param(
|
|
472
|
+
__param(2, (0, common_1.Inject)('AUDIT_ENTITY_MANAGER')),
|
|
473
|
+
__param(5, (0, common_1.Optional)()),
|
|
474
|
+
__param(5, (0, common_1.Inject)('AUDIT_STRATEGY')),
|
|
614
475
|
__param(6, (0, common_1.Optional)()),
|
|
615
|
-
__param(6, (0, common_1.Inject)('
|
|
476
|
+
__param(6, (0, common_1.Inject)('AUDIT_CONFIG')),
|
|
616
477
|
__param(7, (0, common_1.Optional)()),
|
|
617
|
-
__param(7, (0, common_1.Inject)('
|
|
618
|
-
__param(8, (0, common_1.Optional)()),
|
|
619
|
-
__param(8, (0, common_1.Inject)('AUDIT_CONNECTION_NAME')),
|
|
478
|
+
__param(7, (0, common_1.Inject)('AUDIT_CONNECTION_NAME')),
|
|
620
479
|
__metadata("design:paramtypes", [typeorm_2.Repository,
|
|
621
|
-
typeorm_2.Repository,
|
|
622
480
|
typeorm_2.Repository,
|
|
623
481
|
typeorm_2.EntityManager,
|
|
624
482
|
audit_context_service_1.AuditContextService,
|
package/audit/services/index.js
CHANGED
|
@@ -19,4 +19,3 @@ __exportStar(require("./audit-strategy.service"), exports);
|
|
|
19
19
|
__exportStar(require("./entity-audit.service"), exports);
|
|
20
20
|
__exportStar(require("./transaction-audit.service"), exports);
|
|
21
21
|
__exportStar(require("./multi-database.service"), exports);
|
|
22
|
-
__exportStar(require("./operation-description.service"), exports);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Repository, DataSource } from 'typeorm';
|
|
2
|
+
import { ManualOperationLogEntity, EntityTransactionEntity } from '../entities';
|
|
3
|
+
import { AuditContextService } from './audit-context.service';
|
|
4
|
+
import { ManualLogOptions } from '../interfaces';
|
|
5
|
+
export declare class ManualAuditLogService {
|
|
6
|
+
private readonly manualLogRepository;
|
|
7
|
+
private readonly transactionRepository;
|
|
8
|
+
private readonly contextService;
|
|
9
|
+
private readonly dataSource;
|
|
10
|
+
private static instance;
|
|
11
|
+
constructor(manualLogRepository: Repository<ManualOperationLogEntity>, transactionRepository: Repository<EntityTransactionEntity>, contextService: AuditContextService, dataSource: DataSource);
|
|
12
|
+
static log(options: ManualLogOptions): Promise<ManualOperationLogEntity>;
|
|
13
|
+
logOperation(options: ManualLogOptions): Promise<ManualOperationLogEntity>;
|
|
14
|
+
static beginTransaction(userId?: string, username?: string): Promise<string>;
|
|
15
|
+
static commitTransaction(transactionId: string): Promise<void>;
|
|
16
|
+
static rollbackTransaction(transactionId: string): Promise<void>;
|
|
17
|
+
private createTransaction;
|
|
18
|
+
private updateTransactionStatus;
|
|
19
|
+
private generateTransactionId;
|
|
20
|
+
static logBatch(operations: ManualLogOptions[], sharedTransactionId?: string): Promise<ManualOperationLogEntity[]>;
|
|
21
|
+
static findLogs(options: {
|
|
22
|
+
templateKey?: string;
|
|
23
|
+
userId?: string;
|
|
24
|
+
transactionId?: string;
|
|
25
|
+
startTime?: Date;
|
|
26
|
+
endTime?: Date;
|
|
27
|
+
limit?: number;
|
|
28
|
+
}): Promise<ManualOperationLogEntity[]>;
|
|
29
|
+
}
|
|
@@ -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);
|
|
@@ -16,6 +16,10 @@ declare global {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
declare module 'typeorm' {
|
|
19
|
+
interface Repository<Entity extends ObjectLiteral> {
|
|
20
|
+
saveWithPk(this: Repository<Entity>, entity: Entity | Entity[]): Promise<Entity | Entity[]>;
|
|
21
|
+
getPrimaryKeyFields(this: Repository<Entity>): string[];
|
|
22
|
+
}
|
|
19
23
|
interface SelectQueryBuilder<Entity> {
|
|
20
24
|
searchByString(q: string, columnNames: string[], options?: {
|
|
21
25
|
formStart: boolean;
|
|
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
require("source-map-support/register");
|
|
26
26
|
const lodash_1 = require("lodash");
|
|
27
27
|
const typeorm_1 = require("typeorm");
|
|
28
|
+
const typeorm_2 = require("typeorm");
|
|
28
29
|
const page_dto_1 = require("./dto/page.dto");
|
|
29
30
|
const page_meta_dto_1 = require("./dto/page-meta.dto");
|
|
30
31
|
const providers_1 = require("../providers");
|
|
@@ -43,11 +44,11 @@ Array.prototype.getByLanguage = function (languageCode) {
|
|
|
43
44
|
Array.prototype.toPageDto = function (pageMetaDto, options) {
|
|
44
45
|
return new page_dto_1.PageDto(this.toDtos(options), pageMetaDto);
|
|
45
46
|
};
|
|
46
|
-
|
|
47
|
+
typeorm_2.SelectQueryBuilder.prototype.searchByString = function (q, columnNames, options) {
|
|
47
48
|
if (!q) {
|
|
48
49
|
return this;
|
|
49
50
|
}
|
|
50
|
-
this.andWhere(new
|
|
51
|
+
this.andWhere(new typeorm_2.Brackets((qb) => {
|
|
51
52
|
for (const item of columnNames) {
|
|
52
53
|
qb.orWhere(`${item} ILIKE :q`);
|
|
53
54
|
}
|
|
@@ -60,7 +61,7 @@ typeorm_1.SelectQueryBuilder.prototype.searchByString = function (q, columnNames
|
|
|
60
61
|
}
|
|
61
62
|
return this;
|
|
62
63
|
};
|
|
63
|
-
|
|
64
|
+
typeorm_2.SelectQueryBuilder.prototype.paginate = function (pageOptionsDto, options) {
|
|
64
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
65
66
|
if (!(options === null || options === void 0 ? void 0 : options.takeAll)) {
|
|
66
67
|
this.skip(pageOptionsDto.skip).take(pageOptionsDto.pageSize);
|
|
@@ -77,7 +78,7 @@ typeorm_1.SelectQueryBuilder.prototype.paginate = function (pageOptionsDto, opti
|
|
|
77
78
|
return [entities, pageMetaDto];
|
|
78
79
|
});
|
|
79
80
|
};
|
|
80
|
-
|
|
81
|
+
typeorm_2.SelectQueryBuilder.prototype.paginateAndMap = function (pageOptionsDto, options) {
|
|
81
82
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
83
|
const [entities, pageMetaDto] = yield this.paginate(pageOptionsDto, {
|
|
83
84
|
skipCount: options === null || options === void 0 ? void 0 : options.skipCount,
|
|
@@ -90,7 +91,7 @@ typeorm_1.SelectQueryBuilder.prototype.paginateAndMap = function (pageOptionsDto
|
|
|
90
91
|
return transformedEntities.toPageDto(pageMetaDto, options === null || options === void 0 ? void 0 : options.dtoOptions);
|
|
91
92
|
});
|
|
92
93
|
};
|
|
93
|
-
|
|
94
|
+
typeorm_2.SelectQueryBuilder.prototype.withTenant = function (tenantId, tenantFieldName = 'tenantId') {
|
|
94
95
|
var _a;
|
|
95
96
|
if (!tenantId) {
|
|
96
97
|
tenantId = providers_1.ContextProvider.getTenantId();
|
|
@@ -106,7 +107,7 @@ typeorm_1.SelectQueryBuilder.prototype.withTenant = function (tenantId, tenantFi
|
|
|
106
107
|
}
|
|
107
108
|
return this;
|
|
108
109
|
};
|
|
109
|
-
|
|
110
|
+
typeorm_2.SelectQueryBuilder.prototype.iterate = function (options) {
|
|
110
111
|
return __asyncGenerator(this, arguments, function* () {
|
|
111
112
|
const batchSize = (options === null || options === void 0 ? void 0 : options.batchSize) || 100;
|
|
112
113
|
let offset = 0;
|
|
@@ -124,7 +125,7 @@ typeorm_1.SelectQueryBuilder.prototype.iterate = function (options) {
|
|
|
124
125
|
}
|
|
125
126
|
});
|
|
126
127
|
};
|
|
127
|
-
|
|
128
|
+
typeorm_2.SelectQueryBuilder.prototype.eachBatch = function (callback, options) {
|
|
128
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
129
130
|
const batchSize = (options === null || options === void 0 ? void 0 : options.batchSize) || 100;
|
|
130
131
|
const mode = (options === null || options === void 0 ? void 0 : options.mode) || 'batch';
|
|
@@ -150,3 +151,95 @@ typeorm_1.SelectQueryBuilder.prototype.eachBatch = function (callback, options)
|
|
|
150
151
|
}
|
|
151
152
|
});
|
|
152
153
|
};
|
|
154
|
+
const insertWithPk = function (entity) {
|
|
155
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
156
|
+
if (!this.metadata) {
|
|
157
|
+
throw new Error('Repository metadata is not available. Make sure the repository is properly initialized.');
|
|
158
|
+
}
|
|
159
|
+
const tableName = this.metadata.tableName;
|
|
160
|
+
const columns = this.metadata.columns;
|
|
161
|
+
const columnNames = [];
|
|
162
|
+
const columnValues = [];
|
|
163
|
+
const valuePlaceholders = [];
|
|
164
|
+
for (const column of columns) {
|
|
165
|
+
const propertyName = column.propertyName;
|
|
166
|
+
const value = entity[propertyName];
|
|
167
|
+
if (value === undefined) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const columnName = column.databaseName;
|
|
171
|
+
if (columnName) {
|
|
172
|
+
columnNames.push(columnName);
|
|
173
|
+
columnValues.push(value);
|
|
174
|
+
valuePlaceholders.push(`$${columnValues.length}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const sql = `INSERT INTO ${tableName} (${columnNames.join(', ')}) VALUES (${valuePlaceholders.join(', ')}) RETURNING *`;
|
|
178
|
+
try {
|
|
179
|
+
const result = yield this.query(sql, columnValues);
|
|
180
|
+
return result[0];
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.warn(`Native SQL insert failed for ${tableName}, falling back to regular save:`, error);
|
|
184
|
+
return yield this.save(entity);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
typeorm_1.Repository.prototype.getPrimaryKeyFields = function () {
|
|
189
|
+
if (!this.metadata) {
|
|
190
|
+
throw new Error('Repository metadata is not available. Make sure the repository is properly initialized.');
|
|
191
|
+
}
|
|
192
|
+
const primaryKeys = this.metadata.primaryColumns;
|
|
193
|
+
if (!primaryKeys || primaryKeys.length === 0) {
|
|
194
|
+
throw new Error(`Entity ${this.metadata.targetName} does not have any primary key columns defined.`);
|
|
195
|
+
}
|
|
196
|
+
return primaryKeys.map(column => column.propertyName);
|
|
197
|
+
};
|
|
198
|
+
typeorm_1.Repository.prototype.saveWithPk = function (entity) {
|
|
199
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
+
const isArray = Array.isArray(entity);
|
|
201
|
+
const entities = isArray ? entity : [entity];
|
|
202
|
+
if (entities.length === 0) {
|
|
203
|
+
return isArray ? [] : null;
|
|
204
|
+
}
|
|
205
|
+
const pkFields = this.getPrimaryKeyFields();
|
|
206
|
+
const results = yield Promise.all(entities.map((singleEntity) => __awaiter(this, void 0, void 0, function* () {
|
|
207
|
+
const hasPkValues = pkFields.every(pkField => {
|
|
208
|
+
const value = singleEntity[pkField];
|
|
209
|
+
return value !== undefined && value !== null && value !== '';
|
|
210
|
+
});
|
|
211
|
+
if (hasPkValues) {
|
|
212
|
+
try {
|
|
213
|
+
const existingEntity = yield this.findOne({
|
|
214
|
+
where: pkFields.reduce((acc, pkField) => {
|
|
215
|
+
acc[pkField] = singleEntity[pkField];
|
|
216
|
+
return acc;
|
|
217
|
+
}, {})
|
|
218
|
+
});
|
|
219
|
+
if (existingEntity) {
|
|
220
|
+
yield this.update(pkFields.reduce((acc, pkField) => {
|
|
221
|
+
acc[pkField] = singleEntity[pkField];
|
|
222
|
+
return acc;
|
|
223
|
+
}, {}), singleEntity);
|
|
224
|
+
return yield this.findOne({
|
|
225
|
+
where: pkFields.reduce((acc, pkField) => {
|
|
226
|
+
acc[pkField] = singleEntity[pkField];
|
|
227
|
+
return acc;
|
|
228
|
+
}, {})
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
return yield insertWithPk.call(this, singleEntity);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
return yield insertWithPk.call(this, singleEntity);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
return yield this.save(singleEntity);
|
|
241
|
+
}
|
|
242
|
+
})));
|
|
243
|
+
return isArray ? results : results[0];
|
|
244
|
+
});
|
|
245
|
+
};
|
package/package.json
CHANGED