@drax/audit-back 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/AuditController.js +54 -0
- package/dist/factory/services/AuditServiceFactory.js +15 -0
- package/dist/index.js +10 -0
- package/dist/interfaces/IAuditRepository.js +1 -0
- package/dist/models/AuditModel.js +38 -0
- package/dist/permissions/AuditPermissions.js +8 -0
- package/dist/repository/AuditRepository.js +12 -0
- package/dist/routes/AuditRoutes.js +15 -0
- package/dist/schemas/AuditSchema.js +31 -0
- package/dist/services/AuditService.js +8 -0
- package/dist/utils/RegisterCrudEvent.js +67 -0
- package/package.json +43 -0
- package/src/controllers/AuditController.ts +63 -0
- package/src/factory/services/AuditServiceFactory.ts +23 -0
- package/src/index.ts +26 -0
- package/src/interfaces/IAuditRepository.ts +11 -0
- package/src/models/AuditModel.ts +52 -0
- package/src/permissions/AuditPermissions.ts +12 -0
- package/src/repository/AuditRepository.ts +21 -0
- package/src/routes/AuditRoutes.ts +25 -0
- package/src/schemas/AuditSchema.ts +38 -0
- package/src/services/AuditService.ts +16 -0
- package/src/utils/RegisterCrudEvent.ts +88 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/types/controllers/AuditController.d.ts +13 -0
- package/types/controllers/AuditController.d.ts.map +1 -0
- package/types/factory/services/AuditServiceFactory.d.ts +8 -0
- package/types/factory/services/AuditServiceFactory.d.ts.map +1 -0
- package/types/index.d.ts +13 -0
- package/types/index.d.ts.map +1 -0
- package/types/interfaces/IAuditRepository.d.ts +6 -0
- package/types/interfaces/IAuditRepository.d.ts.map +1 -0
- package/types/models/AuditModel.d.ts +15 -0
- package/types/models/AuditModel.d.ts.map +1 -0
- package/types/permissions/AuditPermissions.d.ts +8 -0
- package/types/permissions/AuditPermissions.d.ts.map +1 -0
- package/types/repository/AuditRepository.d.ts +9 -0
- package/types/repository/AuditRepository.d.ts.map +1 -0
- package/types/routes/AuditRoutes.d.ts +4 -0
- package/types/routes/AuditRoutes.d.ts.map +1 -0
- package/types/schemas/AuditSchema.d.ts +189 -0
- package/types/schemas/AuditSchema.d.ts.map +1 -0
- package/types/services/AuditService.d.ts +10 -0
- package/types/services/AuditService.d.ts.map +1 -0
- package/types/utils/RegisterCrudEvent.d.ts +5 -0
- package/types/utils/RegisterCrudEvent.d.ts.map +1 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import AuditServiceFactory from "../factory/services/AuditServiceFactory.js";
|
|
2
|
+
import { AbstractFastifyController } from "@drax/crud-back";
|
|
3
|
+
import AuditPermissions from "../permissions/AuditPermissions.js";
|
|
4
|
+
import { MethodNotAllowedError } from "@drax/common-back";
|
|
5
|
+
class AuditController extends AbstractFastifyController {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(AuditServiceFactory.instance, AuditPermissions);
|
|
8
|
+
this.tenantField = "tenant.id";
|
|
9
|
+
this.userField = "user";
|
|
10
|
+
this.tenantFilter = true;
|
|
11
|
+
this.userFilter = false;
|
|
12
|
+
this.tenantSetter = false;
|
|
13
|
+
this.userSetter = false;
|
|
14
|
+
this.tenantAssert = false;
|
|
15
|
+
this.userAssert = false;
|
|
16
|
+
}
|
|
17
|
+
async create(request, reply) {
|
|
18
|
+
try {
|
|
19
|
+
throw new MethodNotAllowedError();
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
this.handleError(e, reply);
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
async update(request, reply) {
|
|
27
|
+
try {
|
|
28
|
+
throw new MethodNotAllowedError();
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
this.handleError(e, reply);
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
async updatePartial(request, reply) {
|
|
36
|
+
try {
|
|
37
|
+
throw new MethodNotAllowedError();
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
this.handleError(e, reply);
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
async delete(request, reply) {
|
|
45
|
+
try {
|
|
46
|
+
throw new MethodNotAllowedError();
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
this.handleError(e, reply);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export default AuditController;
|
|
54
|
+
export { AuditController };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import AuditRepository from '../../repository/AuditRepository.js';
|
|
2
|
+
import { AuditService } from '../../services/AuditService.js';
|
|
3
|
+
import { AuditBaseSchema } from "../../schemas/AuditSchema.js";
|
|
4
|
+
class AuditServiceFactory {
|
|
5
|
+
static get instance() {
|
|
6
|
+
if (!AuditServiceFactory.service) {
|
|
7
|
+
const repository = new AuditRepository();
|
|
8
|
+
const schema = AuditBaseSchema;
|
|
9
|
+
AuditServiceFactory.service = new AuditService(repository, schema);
|
|
10
|
+
}
|
|
11
|
+
return AuditServiceFactory.service;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export default AuditServiceFactory;
|
|
15
|
+
export { AuditServiceFactory };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import AuditPermissions from './permissions/AuditPermissions.js';
|
|
2
|
+
import AuditSchema from './schemas/AuditSchema.js';
|
|
3
|
+
import AuditModel from './models/AuditModel.js';
|
|
4
|
+
import AuditRepository from './repository/AuditRepository.js';
|
|
5
|
+
import AuditService from './services/AuditService.js';
|
|
6
|
+
import AuditServiceFactory from './factory/services/AuditServiceFactory.js';
|
|
7
|
+
import AuditController from './controllers/AuditController.js';
|
|
8
|
+
import AuditRoutes from './routes/AuditRoutes.js';
|
|
9
|
+
import { RegisterCrudEvent } from './utils/RegisterCrudEvent.js';
|
|
10
|
+
export { AuditPermissions, AuditSchema, AuditModel, AuditRepository, AuditService, AuditServiceFactory, AuditController, AuditRoutes, RegisterCrudEvent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { mongoose } from '@drax/common-back';
|
|
2
|
+
import uniqueValidator from 'mongoose-unique-validator';
|
|
3
|
+
import mongoosePaginate from 'mongoose-paginate-v2';
|
|
4
|
+
const AuditSchema = new mongoose.Schema({
|
|
5
|
+
entity: { type: String, required: true, index: true, unique: false },
|
|
6
|
+
user: {
|
|
7
|
+
id: { type: String, required: true, index: true, unique: false },
|
|
8
|
+
username: { type: String, required: true, index: false, unique: false },
|
|
9
|
+
rolName: { type: String, required: false, index: false, unique: false }
|
|
10
|
+
},
|
|
11
|
+
action: { type: String, required: true, index: true, unique: false },
|
|
12
|
+
ip: { type: String, required: false, index: false, unique: false },
|
|
13
|
+
userAgent: { type: String, required: false, index: false, unique: false },
|
|
14
|
+
changes: [{
|
|
15
|
+
field: { type: String, required: true, index: false, unique: false },
|
|
16
|
+
old: { type: String, required: false, index: false, unique: false },
|
|
17
|
+
new: { type: String, required: false, index: false, unique: false }
|
|
18
|
+
}],
|
|
19
|
+
sessionId: { type: String, required: false, index: true, unique: false },
|
|
20
|
+
requestId: { type: String, required: false, index: true, unique: false },
|
|
21
|
+
detail: { type: String, required: false, index: false, unique: false },
|
|
22
|
+
tenant: {
|
|
23
|
+
id: { type: String, required: false, index: true, unique: false },
|
|
24
|
+
name: { type: String, required: false, index: false, unique: false }
|
|
25
|
+
}
|
|
26
|
+
}, { timestamps: true });
|
|
27
|
+
AuditSchema.plugin(uniqueValidator, { message: 'validation.unique' });
|
|
28
|
+
AuditSchema.plugin(mongoosePaginate);
|
|
29
|
+
AuditSchema.virtual("id").get(function () {
|
|
30
|
+
return this._id.toString();
|
|
31
|
+
});
|
|
32
|
+
AuditSchema.set('toJSON', { getters: true, virtuals: true });
|
|
33
|
+
AuditSchema.set('toObject', { getters: true, virtuals: true });
|
|
34
|
+
const MODEL_NAME = 'Audit';
|
|
35
|
+
const COLLECTION_NAME = 'Audit';
|
|
36
|
+
const AuditModel = mongoose.model(MODEL_NAME, AuditSchema, COLLECTION_NAME);
|
|
37
|
+
export { AuditSchema, AuditModel };
|
|
38
|
+
export default AuditModel;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var AuditPermissions;
|
|
2
|
+
(function (AuditPermissions) {
|
|
3
|
+
AuditPermissions["View"] = "audit:view";
|
|
4
|
+
AuditPermissions["ViewAll"] = "audit:viewAll";
|
|
5
|
+
AuditPermissions["Manage"] = "audit:manage";
|
|
6
|
+
})(AuditPermissions || (AuditPermissions = {}));
|
|
7
|
+
export { AuditPermissions };
|
|
8
|
+
export default AuditPermissions;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AbstractMongoRepository } from "@drax/crud-back";
|
|
2
|
+
import { AuditModel } from "../models/AuditModel.js";
|
|
3
|
+
class AuditMongoRepository extends AbstractMongoRepository {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
this._model = AuditModel;
|
|
7
|
+
this._searchFields = ['entity', 'action', 'sessionId', 'requestId'];
|
|
8
|
+
this._populateFields = [];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export default AuditMongoRepository;
|
|
12
|
+
export { AuditMongoRepository };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import AuditController from "../controllers/AuditController.js";
|
|
2
|
+
import { CrudSchemaBuilder } from "@drax/crud-back";
|
|
3
|
+
import { AuditSchema, AuditBaseSchema } from '../schemas/AuditSchema.js';
|
|
4
|
+
async function AuditFastifyRoutes(fastify, options) {
|
|
5
|
+
const controller = new AuditController();
|
|
6
|
+
const schemas = new CrudSchemaBuilder(AuditSchema, AuditBaseSchema, AuditBaseSchema, 'Audit', 'openApi3', ['Audit']);
|
|
7
|
+
fastify.get('/api/audits', { schema: schemas.paginateSchema }, (req, rep) => controller.paginate(req, rep));
|
|
8
|
+
fastify.get('/api/audits/find', { schema: schemas.findSchema }, (req, rep) => controller.find(req, rep));
|
|
9
|
+
fastify.get('/api/audits/search', { schema: schemas.searchSchema }, (req, rep) => controller.search(req, rep));
|
|
10
|
+
fastify.get('/api/audits/:id', { schema: schemas.findByIdSchema }, (req, rep) => controller.findById(req, rep));
|
|
11
|
+
fastify.get('/api/audits/find-one', { schema: schemas.findOneSchema }, (req, rep) => controller.findOne(req, rep));
|
|
12
|
+
fastify.get('/api/audits/group-by', { schema: schemas.groupBySchema }, (req, rep) => controller.groupBy(req, rep));
|
|
13
|
+
}
|
|
14
|
+
export default AuditFastifyRoutes;
|
|
15
|
+
export { AuditFastifyRoutes };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const AuditBaseSchema = z.object({
|
|
3
|
+
entity: z.string().min(1, 'validation.required'),
|
|
4
|
+
user: z.object({
|
|
5
|
+
id: z.string().min(1, 'validation.required'),
|
|
6
|
+
username: z.string().min(1, 'validation.required'),
|
|
7
|
+
rolName: z.string().optional().nullable()
|
|
8
|
+
}),
|
|
9
|
+
action: z.string().min(1, 'validation.required'),
|
|
10
|
+
ip: z.string().optional().nullable(),
|
|
11
|
+
userAgent: z.string().optional().nullable(),
|
|
12
|
+
changes: z.array(z.object({
|
|
13
|
+
field: z.string().min(1, 'validation.required'),
|
|
14
|
+
old: z.string().optional().nullable(),
|
|
15
|
+
new: z.string().optional().nullable()
|
|
16
|
+
})).optional(),
|
|
17
|
+
sessionId: z.string().optional().nullable(),
|
|
18
|
+
requestId: z.string().optional().nullable(),
|
|
19
|
+
detail: z.string().optional().nullable(),
|
|
20
|
+
tenant: z.object({
|
|
21
|
+
id: z.string().optional().nullable(),
|
|
22
|
+
name: z.string().optional().nullable()
|
|
23
|
+
}).optional().nullable()
|
|
24
|
+
});
|
|
25
|
+
const AuditSchema = AuditBaseSchema
|
|
26
|
+
.extend({
|
|
27
|
+
_id: z.string(),
|
|
28
|
+
createdAt: z.date(),
|
|
29
|
+
});
|
|
30
|
+
export default AuditSchema;
|
|
31
|
+
export { AuditSchema, AuditBaseSchema };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AuditServiceFactory } from "../factory/services/AuditServiceFactory.js";
|
|
2
|
+
async function RegisterCrudEvent(crudEventData) {
|
|
3
|
+
function diff(preItem, postItem) {
|
|
4
|
+
const changes = [];
|
|
5
|
+
// Si no hay preItem (creación), no hay cambios que registrar
|
|
6
|
+
if (!preItem) {
|
|
7
|
+
return changes;
|
|
8
|
+
}
|
|
9
|
+
// Si no hay postItem (eliminación), registrar todos los campos como eliminados
|
|
10
|
+
if (!postItem) {
|
|
11
|
+
Object.keys(preItem).forEach(key => {
|
|
12
|
+
// Ignorar campos internos de MongoDB y timestamps
|
|
13
|
+
if (!key.startsWith('_') && key !== 'createdAt' && key !== 'updatedAt') {
|
|
14
|
+
changes.push({
|
|
15
|
+
field: key,
|
|
16
|
+
old: preItem[key],
|
|
17
|
+
new: undefined
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return changes;
|
|
22
|
+
}
|
|
23
|
+
// Obtener todas las claves únicas de ambos objetos
|
|
24
|
+
const allKeys = new Set([...Object.keys(preItem), ...Object.keys(postItem)]);
|
|
25
|
+
allKeys.forEach(key => {
|
|
26
|
+
// Ignorar campos internos de MongoDB y timestamps
|
|
27
|
+
if (key.startsWith('_') || key === 'createdAt' || key === 'updatedAt') {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const oldValue = preItem[key];
|
|
31
|
+
const newValue = postItem[key];
|
|
32
|
+
// Comparar valores
|
|
33
|
+
if (JSON.stringify(oldValue) !== JSON.stringify(newValue)) {
|
|
34
|
+
changes.push({
|
|
35
|
+
field: key,
|
|
36
|
+
old: oldValue,
|
|
37
|
+
new: newValue
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return changes;
|
|
42
|
+
}
|
|
43
|
+
let changes = diff(crudEventData.preItem, crudEventData.postItem);
|
|
44
|
+
let data = {
|
|
45
|
+
action: crudEventData.action,
|
|
46
|
+
changes: changes,
|
|
47
|
+
createdAt: crudEventData.timestamp,
|
|
48
|
+
detail: "",
|
|
49
|
+
entity: crudEventData.entity,
|
|
50
|
+
tenant: {
|
|
51
|
+
id: crudEventData.user.tenant.id,
|
|
52
|
+
name: crudEventData.user.tenant.name
|
|
53
|
+
},
|
|
54
|
+
user: {
|
|
55
|
+
id: crudEventData.user.id,
|
|
56
|
+
username: crudEventData.user.username,
|
|
57
|
+
rolName: crudEventData.user.role.name,
|
|
58
|
+
},
|
|
59
|
+
ip: crudEventData.ip,
|
|
60
|
+
userAgent: crudEventData.userAgent,
|
|
61
|
+
sessionId: crudEventData.user.session,
|
|
62
|
+
requestId: crudEventData.requestId
|
|
63
|
+
};
|
|
64
|
+
return await AuditServiceFactory.instance.create(data);
|
|
65
|
+
}
|
|
66
|
+
export { RegisterCrudEvent };
|
|
67
|
+
export default RegisterCrudEvent;
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drax/audit-back",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.38.0",
|
|
7
|
+
"description": "Audit backend",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "types/index.d.ts",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"prepublish": "tsc && npm run copygql",
|
|
13
|
+
"tscrun": "tsc",
|
|
14
|
+
"clean": "rm -rf dist",
|
|
15
|
+
"copygql": "copyfiles -u 1 ./**/*.graphql dist/",
|
|
16
|
+
"tsc": "tsc -b tsconfig.json",
|
|
17
|
+
"test": "node --import tsx --test test/**/*",
|
|
18
|
+
"testService": "node --import tsx --test test/services/*.ts",
|
|
19
|
+
"testExports": "node --import tsx --test test/exports/*.ts",
|
|
20
|
+
"testWorkers": "node --import tsx --test test/workers/*.ts"
|
|
21
|
+
},
|
|
22
|
+
"author": "Cristian Incarnato & Drax Team",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@drax/crud-back": "^0.38.0",
|
|
26
|
+
"@drax/crud-share": "^0.38.0",
|
|
27
|
+
"mongoose": "^8.6.3",
|
|
28
|
+
"mongoose-paginate-v2": "^1.8.3"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"dayjs": "^1.11.19",
|
|
32
|
+
"mongoose-paginate-v2": "^1.8.3"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^20.12.10",
|
|
36
|
+
"copyfiles": "^2.4.1",
|
|
37
|
+
"mongoose-paginate-v2": "^1.8.3",
|
|
38
|
+
"ts-node": "^10.9.2",
|
|
39
|
+
"tsc-alias": "^1.8.10",
|
|
40
|
+
"typescript": "^5.6.2"
|
|
41
|
+
},
|
|
42
|
+
"gitHead": "43c90f3c12165e7527edefbc80dd327a59236dd5"
|
|
43
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import AuditServiceFactory from "../factory/services/AuditServiceFactory.js";
|
|
2
|
+
import {AbstractFastifyController} from "@drax/crud-back";
|
|
3
|
+
import AuditPermissions from "../permissions/AuditPermissions.js";
|
|
4
|
+
import type {IAudit, IAuditBase} from "@drax/audit-share";
|
|
5
|
+
import type {FastifyReply, FastifyRequest} from "fastify";
|
|
6
|
+
import {MethodNotAllowedError} from "@drax/common-back";
|
|
7
|
+
|
|
8
|
+
class AuditController extends AbstractFastifyController<IAudit, IAuditBase, IAuditBase> {
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super(AuditServiceFactory.instance, AuditPermissions)
|
|
12
|
+
this.tenantField = "tenant.id";
|
|
13
|
+
this.userField = "user";
|
|
14
|
+
this.tenantFilter = true;
|
|
15
|
+
this.userFilter = false;
|
|
16
|
+
this.tenantSetter = false;
|
|
17
|
+
this.userSetter = false;
|
|
18
|
+
this.tenantAssert = false;
|
|
19
|
+
this.userAssert = false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async create(request: FastifyRequest, reply: FastifyReply): Promise<IAudit> {
|
|
23
|
+
try {
|
|
24
|
+
throw new MethodNotAllowedError()
|
|
25
|
+
} catch (e) {
|
|
26
|
+
this.handleError(e, reply)
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async update(request: FastifyRequest, reply: FastifyReply): Promise<IAudit> {
|
|
32
|
+
try {
|
|
33
|
+
throw new MethodNotAllowedError()
|
|
34
|
+
} catch (e) {
|
|
35
|
+
this.handleError(e, reply)
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async updatePartial(request: FastifyRequest, reply: FastifyReply): Promise<IAudit> {
|
|
41
|
+
try {
|
|
42
|
+
throw new MethodNotAllowedError()
|
|
43
|
+
} catch (e) {
|
|
44
|
+
this.handleError(e, reply)
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async delete(request: FastifyRequest, reply: FastifyReply) {
|
|
50
|
+
try {
|
|
51
|
+
throw new MethodNotAllowedError()
|
|
52
|
+
} catch (e) {
|
|
53
|
+
this.handleError(e, reply)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default AuditController;
|
|
60
|
+
export {
|
|
61
|
+
AuditController
|
|
62
|
+
}
|
|
63
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
import AuditRepository from '../../repository/AuditRepository.js'
|
|
3
|
+
import {AuditService} from '../../services/AuditService.js'
|
|
4
|
+
import {AuditBaseSchema} from "../../schemas/AuditSchema.js";
|
|
5
|
+
|
|
6
|
+
class AuditServiceFactory {
|
|
7
|
+
private static service: AuditService;
|
|
8
|
+
|
|
9
|
+
public static get instance(): AuditService {
|
|
10
|
+
if (!AuditServiceFactory.service) {
|
|
11
|
+
const repository = new AuditRepository();
|
|
12
|
+
const schema = AuditBaseSchema;
|
|
13
|
+
AuditServiceFactory.service = new AuditService(repository, schema);
|
|
14
|
+
}
|
|
15
|
+
return AuditServiceFactory.service;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default AuditServiceFactory
|
|
20
|
+
export {
|
|
21
|
+
AuditServiceFactory
|
|
22
|
+
}
|
|
23
|
+
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import AuditPermissions from './permissions/AuditPermissions.js'
|
|
2
|
+
import AuditSchema from './schemas/AuditSchema.js'
|
|
3
|
+
import AuditModel from './models/AuditModel.js'
|
|
4
|
+
import AuditRepository from './repository/AuditRepository.js'
|
|
5
|
+
import AuditService from './services/AuditService.js'
|
|
6
|
+
import AuditServiceFactory from './factory/services/AuditServiceFactory.js'
|
|
7
|
+
import AuditController from './controllers/AuditController.js'
|
|
8
|
+
import AuditRoutes from './routes/AuditRoutes.js'
|
|
9
|
+
import {RegisterCrudEvent} from './utils/RegisterCrudEvent.js'
|
|
10
|
+
import type {IAuditRepository} from './interfaces/IAuditRepository'
|
|
11
|
+
|
|
12
|
+
export type{
|
|
13
|
+
IAuditRepository
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
AuditPermissions,
|
|
18
|
+
AuditSchema,
|
|
19
|
+
AuditModel,
|
|
20
|
+
AuditRepository,
|
|
21
|
+
AuditService,
|
|
22
|
+
AuditServiceFactory,
|
|
23
|
+
AuditController,
|
|
24
|
+
AuditRoutes,
|
|
25
|
+
RegisterCrudEvent
|
|
26
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {mongoose} from '@drax/common-back';
|
|
2
|
+
import {PaginateModel} from "mongoose";
|
|
3
|
+
import uniqueValidator from 'mongoose-unique-validator';
|
|
4
|
+
import mongoosePaginate from 'mongoose-paginate-v2'
|
|
5
|
+
import type {IAudit} from '@drax/audit-share'
|
|
6
|
+
|
|
7
|
+
const AuditSchema = new mongoose.Schema<IAudit>({
|
|
8
|
+
entity: {type: String, required: true, index: true, unique: false},
|
|
9
|
+
user: {
|
|
10
|
+
id: {type: String, required: true, index: true, unique: false},
|
|
11
|
+
username: {type: String, required: true, index: false, unique: false},
|
|
12
|
+
rolName: {type: String, required: false, index: false, unique: false}
|
|
13
|
+
},
|
|
14
|
+
action: {type: String, required: true, index: true, unique: false},
|
|
15
|
+
ip: {type: String, required: false, index: false, unique: false},
|
|
16
|
+
userAgent: {type: String, required: false, index: false, unique: false},
|
|
17
|
+
changes: [{
|
|
18
|
+
field: {type: String, required: true, index: false, unique: false},
|
|
19
|
+
old: {type: String, required: false, index: false, unique: false},
|
|
20
|
+
new: {type: String, required: false, index: false, unique: false}
|
|
21
|
+
}],
|
|
22
|
+
sessionId: {type: String, required: false, index: true, unique: false},
|
|
23
|
+
requestId: {type: String, required: false, index: true, unique: false},
|
|
24
|
+
detail: {type: String, required: false, index: false, unique: false},
|
|
25
|
+
tenant: {
|
|
26
|
+
id: {type: String, required: false, index: true, unique: false},
|
|
27
|
+
name: {type: String, required: false, index: false, unique: false}
|
|
28
|
+
}
|
|
29
|
+
}, {timestamps: true});
|
|
30
|
+
|
|
31
|
+
AuditSchema.plugin(uniqueValidator, {message: 'validation.unique'});
|
|
32
|
+
AuditSchema.plugin(mongoosePaginate);
|
|
33
|
+
|
|
34
|
+
AuditSchema.virtual("id").get(function () {
|
|
35
|
+
return this._id.toString();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
AuditSchema.set('toJSON', {getters: true, virtuals: true});
|
|
40
|
+
|
|
41
|
+
AuditSchema.set('toObject', {getters: true, virtuals: true});
|
|
42
|
+
|
|
43
|
+
const MODEL_NAME = 'Audit';
|
|
44
|
+
const COLLECTION_NAME = 'Audit';
|
|
45
|
+
const AuditModel = mongoose.model<IAudit, PaginateModel<IAudit>>(MODEL_NAME, AuditSchema, COLLECTION_NAME);
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
AuditSchema,
|
|
49
|
+
AuditModel
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default AuditModel
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
import {AbstractMongoRepository} from "@drax/crud-back";
|
|
3
|
+
import {AuditModel} from "../models/AuditModel.js";
|
|
4
|
+
import type {IAuditRepository} from '../interfaces/IAuditRepository'
|
|
5
|
+
import type {IAudit, IAuditBase} from "@drax/audit-share";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AuditMongoRepository extends AbstractMongoRepository<IAudit, IAuditBase, IAuditBase> implements IAuditRepository {
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this._model = AuditModel;
|
|
13
|
+
this._searchFields = ['entity', 'action', 'sessionId', 'requestId'];
|
|
14
|
+
this._populateFields = [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default AuditMongoRepository
|
|
20
|
+
export {AuditMongoRepository}
|
|
21
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
import AuditController from "../controllers/AuditController.js";
|
|
3
|
+
import {CrudSchemaBuilder} from "@drax/crud-back";
|
|
4
|
+
import {AuditSchema, AuditBaseSchema} from '../schemas/AuditSchema.js'
|
|
5
|
+
|
|
6
|
+
async function AuditFastifyRoutes(fastify, options) {
|
|
7
|
+
|
|
8
|
+
const controller: AuditController = new AuditController()
|
|
9
|
+
const schemas = new CrudSchemaBuilder(AuditSchema, AuditBaseSchema,AuditBaseSchema, 'Audit', 'openApi3', ['Audit']);
|
|
10
|
+
|
|
11
|
+
fastify.get('/api/audits', {schema: schemas.paginateSchema}, (req,rep) => controller.paginate(req,rep))
|
|
12
|
+
|
|
13
|
+
fastify.get('/api/audits/find', {schema: schemas.findSchema}, (req,rep) => controller.find(req,rep))
|
|
14
|
+
fastify.get('/api/audits/search', {schema: schemas.searchSchema}, (req,rep) => controller.search(req,rep))
|
|
15
|
+
|
|
16
|
+
fastify.get('/api/audits/:id', {schema: schemas.findByIdSchema}, (req,rep) => controller.findById(req,rep))
|
|
17
|
+
fastify.get('/api/audits/find-one', {schema: schemas.findOneSchema}, (req,rep) => controller.findOne(req,rep))
|
|
18
|
+
|
|
19
|
+
fastify.get('/api/audits/group-by', {schema: schemas.groupBySchema}, (req,rep) => controller.groupBy(req,rep))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default AuditFastifyRoutes;
|
|
25
|
+
export {AuditFastifyRoutes}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {z} from 'zod';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const AuditBaseSchema = z.object({
|
|
5
|
+
entity: z.string().min(1, 'validation.required'),
|
|
6
|
+
user: z.object({
|
|
7
|
+
id: z.string().min(1, 'validation.required'),
|
|
8
|
+
username: z.string().min(1, 'validation.required'),
|
|
9
|
+
rolName: z.string().optional().nullable()
|
|
10
|
+
}),
|
|
11
|
+
action: z.string().min(1, 'validation.required'),
|
|
12
|
+
ip: z.string().optional().nullable(),
|
|
13
|
+
userAgent: z.string().optional().nullable(),
|
|
14
|
+
changes: z.array(
|
|
15
|
+
z.object({
|
|
16
|
+
field: z.string().min(1, 'validation.required'),
|
|
17
|
+
old: z.string().optional().nullable(),
|
|
18
|
+
new: z.string().optional().nullable()
|
|
19
|
+
})
|
|
20
|
+
).optional(),
|
|
21
|
+
sessionId: z.string().optional().nullable(),
|
|
22
|
+
requestId: z.string().optional().nullable(),
|
|
23
|
+
detail: z.string().optional().nullable(),
|
|
24
|
+
tenant: z.object({
|
|
25
|
+
id: z.string().optional().nullable(),
|
|
26
|
+
name: z.string().optional().nullable()
|
|
27
|
+
}).optional().nullable()
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const AuditSchema = AuditBaseSchema
|
|
31
|
+
.extend({
|
|
32
|
+
_id: z.string(),
|
|
33
|
+
createdAt: z.date(),
|
|
34
|
+
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
export default AuditSchema;
|
|
38
|
+
export {AuditSchema, AuditBaseSchema}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
import type{IAuditRepository} from "../interfaces/IAuditRepository";
|
|
3
|
+
import type {IAuditBase, IAudit} from "@drax/audit-share";
|
|
4
|
+
import {AbstractService} from "@drax/crud-back";
|
|
5
|
+
import type {ZodObject, ZodRawShape} from "zod";
|
|
6
|
+
|
|
7
|
+
class AuditService extends AbstractService<IAudit, IAuditBase, IAuditBase> {
|
|
8
|
+
|
|
9
|
+
constructor(AuditRepository: IAuditRepository, schema?: ZodObject<ZodRawShape>) {
|
|
10
|
+
super(AuditRepository, schema);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default AuditService
|
|
16
|
+
export {AuditService}
|