enterprise-logging-system 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +16 -0
  2. package/dist/__tests__/exports.test.d.ts +2 -0
  3. package/dist/__tests__/exports.test.d.ts.map +1 -0
  4. package/dist/__tests__/exports.test.js +48 -0
  5. package/dist/__tests__/exports.test.js.map +1 -0
  6. package/dist/backend/config/database.d.ts +11 -0
  7. package/dist/backend/config/database.d.ts.map +1 -0
  8. package/dist/backend/config/database.js +65 -0
  9. package/dist/backend/config/database.js.map +1 -0
  10. package/dist/backend/config/logging.config.d.ts +28 -0
  11. package/dist/backend/config/logging.config.d.ts.map +1 -0
  12. package/dist/backend/config/logging.config.js +36 -0
  13. package/dist/backend/config/logging.config.js.map +1 -0
  14. package/dist/backend/controllers/LogController.d.ts +18 -0
  15. package/dist/backend/controllers/LogController.d.ts.map +1 -0
  16. package/dist/backend/controllers/LogController.js +159 -0
  17. package/dist/backend/controllers/LogController.js.map +1 -0
  18. package/dist/backend/index.d.ts +8 -0
  19. package/dist/backend/index.d.ts.map +1 -0
  20. package/dist/backend/index.js +24 -0
  21. package/dist/backend/index.js.map +1 -0
  22. package/dist/backend/middleware/loggingMiddleware.d.ts +8 -0
  23. package/dist/backend/middleware/loggingMiddleware.d.ts.map +1 -0
  24. package/dist/backend/middleware/loggingMiddleware.js +112 -0
  25. package/dist/backend/middleware/loggingMiddleware.js.map +1 -0
  26. package/dist/backend/models/AccessLog.d.ts +73 -0
  27. package/dist/backend/models/AccessLog.d.ts.map +1 -0
  28. package/dist/backend/models/AccessLog.js +10 -0
  29. package/dist/backend/models/AccessLog.js.map +1 -0
  30. package/dist/backend/models/ChangeLog.d.ts +81 -0
  31. package/dist/backend/models/ChangeLog.d.ts.map +1 -0
  32. package/dist/backend/models/ChangeLog.js +11 -0
  33. package/dist/backend/models/ChangeLog.js.map +1 -0
  34. package/dist/backend/models/ExportLog.d.ts +64 -0
  35. package/dist/backend/models/ExportLog.d.ts.map +1 -0
  36. package/dist/backend/models/ExportLog.js +10 -0
  37. package/dist/backend/models/ExportLog.js.map +1 -0
  38. package/dist/backend/models/SessionLog.d.ts +94 -0
  39. package/dist/backend/models/SessionLog.d.ts.map +1 -0
  40. package/dist/backend/models/SessionLog.js +11 -0
  41. package/dist/backend/models/SessionLog.js.map +1 -0
  42. package/dist/backend/models/index.d.ts +5 -0
  43. package/dist/backend/models/index.d.ts.map +1 -0
  44. package/dist/backend/models/index.js +21 -0
  45. package/dist/backend/models/index.js.map +1 -0
  46. package/dist/backend/repositories/AccessLogRepository.d.ts +14 -0
  47. package/dist/backend/repositories/AccessLogRepository.d.ts.map +1 -0
  48. package/dist/backend/repositories/AccessLogRepository.js +60 -0
  49. package/dist/backend/repositories/AccessLogRepository.js.map +1 -0
  50. package/dist/backend/repositories/BaseRepository.d.ts +28 -0
  51. package/dist/backend/repositories/BaseRepository.d.ts.map +1 -0
  52. package/dist/backend/repositories/BaseRepository.js +112 -0
  53. package/dist/backend/repositories/BaseRepository.js.map +1 -0
  54. package/dist/backend/repositories/ChangeLogRepository.d.ts +12 -0
  55. package/dist/backend/repositories/ChangeLogRepository.d.ts.map +1 -0
  56. package/dist/backend/repositories/ChangeLogRepository.js +47 -0
  57. package/dist/backend/repositories/ChangeLogRepository.js.map +1 -0
  58. package/dist/backend/repositories/ExportLogRepository.d.ts +11 -0
  59. package/dist/backend/repositories/ExportLogRepository.d.ts.map +1 -0
  60. package/dist/backend/repositories/ExportLogRepository.js +45 -0
  61. package/dist/backend/repositories/ExportLogRepository.js.map +1 -0
  62. package/dist/backend/repositories/SessionLogRepository.d.ts +20 -0
  63. package/dist/backend/repositories/SessionLogRepository.d.ts.map +1 -0
  64. package/dist/backend/repositories/SessionLogRepository.js +171 -0
  65. package/dist/backend/repositories/SessionLogRepository.js.map +1 -0
  66. package/dist/backend/repositories/index.d.ts +6 -0
  67. package/dist/backend/repositories/index.d.ts.map +1 -0
  68. package/dist/backend/repositories/index.js +22 -0
  69. package/dist/backend/repositories/index.js.map +1 -0
  70. package/dist/backend/services/LoggingService.d.ts +110 -0
  71. package/dist/backend/services/LoggingService.d.ts.map +1 -0
  72. package/dist/backend/services/LoggingService.js +97 -0
  73. package/dist/backend/services/LoggingService.js.map +1 -0
  74. package/dist/backend/utils/Logger.d.ts +8 -0
  75. package/dist/backend/utils/Logger.d.ts.map +1 -0
  76. package/dist/backend/utils/Logger.js +23 -0
  77. package/dist/backend/utils/Logger.js.map +1 -0
  78. package/dist/examples/queries.d.ts +29 -0
  79. package/dist/examples/queries.d.ts.map +1 -0
  80. package/dist/examples/queries.js +151 -0
  81. package/dist/examples/queries.js.map +1 -0
  82. package/dist/frontend/activity-monitor/ActivityMonitor.d.ts +45 -0
  83. package/dist/frontend/activity-monitor/ActivityMonitor.d.ts.map +1 -0
  84. package/dist/frontend/activity-monitor/ActivityMonitor.js +159 -0
  85. package/dist/frontend/activity-monitor/ActivityMonitor.js.map +1 -0
  86. package/dist/frontend/idle-tracker/IdleTracker.d.ts +34 -0
  87. package/dist/frontend/idle-tracker/IdleTracker.d.ts.map +1 -0
  88. package/dist/frontend/idle-tracker/IdleTracker.js +56 -0
  89. package/dist/frontend/idle-tracker/IdleTracker.js.map +1 -0
  90. package/dist/frontend/index.d.ts +3 -0
  91. package/dist/frontend/index.d.ts.map +1 -0
  92. package/dist/frontend/index.js +19 -0
  93. package/dist/frontend/index.js.map +1 -0
  94. package/dist/index.d.ts +15 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +72 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/shared/types/index.d.ts +41 -0
  99. package/dist/shared/types/index.d.ts.map +1 -0
  100. package/dist/shared/types/index.js +3 -0
  101. package/dist/shared/types/index.js.map +1 -0
  102. package/package.json +56 -0
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseRepository = void 0;
4
+ const Logger_1 = require("../utils/Logger");
5
+ class BaseRepository {
6
+ db;
7
+ collectionName;
8
+ indexes;
9
+ collection;
10
+ logger;
11
+ constructor(db, collectionName, indexes) {
12
+ this.db = db;
13
+ this.collectionName = collectionName;
14
+ this.indexes = indexes;
15
+ this.collection = db.collection(collectionName);
16
+ this.logger = new Logger_1.Logger(collectionName);
17
+ }
18
+ async initialize() {
19
+ try {
20
+ // Create indexes - DocumentDB safe
21
+ for (const index of this.indexes) {
22
+ await this.collection.createIndex(index.keys, {
23
+ name: index.name,
24
+ background: true,
25
+ expireAfterSeconds: index.expireAfterSeconds
26
+ });
27
+ }
28
+ this.logger.info(`Indexes created for ${this.collectionName}`);
29
+ }
30
+ catch (error) {
31
+ this.logger.error(`Failed to create indexes for ${this.collectionName}:`, error);
32
+ throw error;
33
+ }
34
+ }
35
+ // DocumentDB-safe CRUD operations
36
+ async create(document) {
37
+ try {
38
+ const result = await this.collection.insertOne(document);
39
+ return { ...document, _id: result.insertedId };
40
+ }
41
+ catch (error) {
42
+ this.logger.error(`Create failed in ${this.collectionName}:`, error);
43
+ throw error;
44
+ }
45
+ }
46
+ async findById(id) {
47
+ return (await this.collection.findOne({ _id: id }));
48
+ }
49
+ async find(filter, options) {
50
+ return (await this.collection.find(filter, options).toArray());
51
+ }
52
+ async findOne(filter) {
53
+ return (await this.collection.findOne(filter));
54
+ }
55
+ async update(id, update) {
56
+ const result = await this.collection.findOneAndUpdate({ _id: id }, { $set: update }, { returnDocument: 'after' });
57
+ return result.value;
58
+ }
59
+ async delete(id) {
60
+ const result = await this.collection.deleteOne({ _id: id });
61
+ return result.deletedCount > 0;
62
+ }
63
+ // DocumentDB-safe aggregation (simple pipelines only)
64
+ async aggregate(pipeline) {
65
+ // Validate pipeline doesn't contain forbidden operators
66
+ this.validateAggregationPipeline(pipeline);
67
+ try {
68
+ return await this.collection.aggregate(pipeline).toArray();
69
+ }
70
+ catch (error) {
71
+ this.logger.error(`Aggregation failed in ${this.collectionName}:`, error);
72
+ throw error;
73
+ }
74
+ }
75
+ validateAggregationPipeline(pipeline) {
76
+ const forbiddenOperators = ['$facet', '$graphLookup', '$changeStream', '$bucket', '$bucketAuto'];
77
+ for (const stage of pipeline) {
78
+ const stageKey = Object.keys(stage)[0];
79
+ if (forbiddenOperators.includes(stageKey)) {
80
+ throw new Error(`Forbidden aggregation operator ${stageKey} used. Not DocumentDB compatible.`);
81
+ }
82
+ // Check for complex $lookup (only simple equality joins allowed)
83
+ if (stageKey === '$lookup') {
84
+ const lookupStage = stage[stageKey];
85
+ if (lookupStage.pipeline && lookupStage.pipeline.length > 0) {
86
+ throw new Error('Complex $lookup with pipeline not DocumentDB compatible. Use simple equality joins only.');
87
+ }
88
+ }
89
+ }
90
+ }
91
+ // Pagination helper
92
+ async paginate(filter, page, limit, sort = { timestamp: -1 }) {
93
+ const skip = (page - 1) * limit;
94
+ const [data, total] = await Promise.all([
95
+ this.collection
96
+ .find(filter)
97
+ .sort(sort)
98
+ .skip(skip)
99
+ .limit(limit)
100
+ .toArray(),
101
+ this.collection.countDocuments(filter)
102
+ ]);
103
+ return {
104
+ data,
105
+ total,
106
+ page,
107
+ totalPages: Math.ceil(total / limit)
108
+ };
109
+ }
110
+ }
111
+ exports.BaseRepository = BaseRepository;
112
+ //# sourceMappingURL=BaseRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseRepository.js","sourceRoot":"","sources":["../../../src/backend/repositories/BaseRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Db } from 'mongodb';
2
+ import { BaseRepository } from './BaseRepository';
3
+ import { ChangeLog } from '../models/ChangeLog';
4
+ export declare class ChangeLogRepository extends BaseRepository<ChangeLog> {
5
+ constructor(db: Db);
6
+ logChange(log: Omit<ChangeLog, '_id' | 'indexes'>): Promise<ChangeLog>;
7
+ getEntityHistory(entityType: string, entityId: string): Promise<ChangeLog[]>;
8
+ getUserChanges(userId: string, entityType?: string): Promise<ChangeLog[]>;
9
+ getFieldChanges(entityType: string, field: string): Promise<ChangeLog[]>;
10
+ private generateId;
11
+ }
12
+ //# sourceMappingURL=ChangeLogRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangeLogRepository.d.ts","sourceRoot":"","sources":["../../../src/backend/repositories/ChangeLogRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAmC,MAAM,qBAAqB,CAAC;AAEjF,qBAAa,mBAAoB,SAAQ,cAAc,CAAC,SAAS,CAAC;gBACpD,EAAE,EAAE,EAAE;IAIZ,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IActE,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAO5E,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IASzE,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQ9E,OAAO,CAAC,UAAU;CAGnB"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChangeLogRepository = void 0;
4
+ const BaseRepository_1 = require("./BaseRepository");
5
+ const ChangeLog_1 = require("../models/ChangeLog");
6
+ class ChangeLogRepository extends BaseRepository_1.BaseRepository {
7
+ constructor(db) {
8
+ super(db, 'change_logs', ChangeLog_1.CHANGE_LOG_INDEXES);
9
+ }
10
+ async logChange(log) {
11
+ const changeLog = {
12
+ ...log,
13
+ _id: this.generateId(),
14
+ indexes: {
15
+ entity_lookup: `${log.entityType}_${log.entityId}`,
16
+ user_changes: `${log.userId}_${log.entityType}`,
17
+ date_entity: `${log.timestamp.getTime()}_${log.entityType}`
18
+ }
19
+ };
20
+ return this.create(changeLog);
21
+ }
22
+ async getEntityHistory(entityType, entityId) {
23
+ return this.find({
24
+ entityType,
25
+ entityId
26
+ }, { sort: { timestamp: -1 } });
27
+ }
28
+ async getUserChanges(userId, entityType) {
29
+ const filter = { userId };
30
+ if (entityType) {
31
+ filter.entityType = entityType;
32
+ }
33
+ return this.find(filter, { sort: { timestamp: -1 } });
34
+ }
35
+ async getFieldChanges(entityType, field) {
36
+ return this.aggregate([
37
+ { $match: { entityType, 'changes.field': field } },
38
+ { $sort: { timestamp: -1 } },
39
+ { $limit: 100 }
40
+ ]);
41
+ }
42
+ generateId() {
43
+ return `chg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
44
+ }
45
+ }
46
+ exports.ChangeLogRepository = ChangeLogRepository;
47
+ //# sourceMappingURL=ChangeLogRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangeLogRepository.js","sourceRoot":"","sources":["../../../src/backend/repositories/ChangeLogRepository.ts"],"names":[],"mappings":";;;AACA,qDAAkD;AAClD,mDAAiF;AAEjF,MAAa,mBAAoB,SAAQ,+BAAyB;IAChE,YAAY,EAAM;QAChB,KAAK,CAAC,EAAE,EAAE,aAAa,EAAE,8BAAkB,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAuC;QACrD,MAAM,SAAS,GAAc;YAC3B,GAAG,GAAG;YACN,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE;YACtB,OAAO,EAAE;gBACP,aAAa,EAAE,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,QAAQ,EAAE;gBAClD,YAAY,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE;gBAC/C,WAAW,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE;aAC5D;SACF,CAAC;QAEF,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,QAAgB;QACzD,OAAO,IAAI,CAAC,IAAI,CAAC;YACf,UAAU;YACV,QAAQ;SACT,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,MAAc,EAAE,UAAmB;QACtD,MAAM,MAAM,GAAQ,EAAE,MAAM,EAAE,CAAC;QAC/B,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QACjC,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,KAAa;QACrD,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE;YAClD,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;YAC5B,EAAE,MAAM,EAAE,GAAG,EAAE;SAChB,CAAC,CAAC;IACL,CAAC;IAEO,UAAU;QAChB,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACxE,CAAC;CACF;AA9CD,kDA8CC"}
@@ -0,0 +1,11 @@
1
+ import { Db } from 'mongodb';
2
+ import { BaseRepository } from './BaseRepository';
3
+ import { ExportLog } from '../models/ExportLog';
4
+ export declare class ExportLogRepository extends BaseRepository<ExportLog> {
5
+ constructor(db: Db);
6
+ logExport(log: Omit<ExportLog, '_id' | 'type' | 'indexes'>): Promise<ExportLog>;
7
+ updateExportStatus(logId: string, status: 'SUCCESS' | 'FAILED' | 'IN_PROGRESS', downloadUrl?: string, errorMessage?: string): Promise<ExportLog | null>;
8
+ getUserExports(userId: string, exportType?: string): Promise<ExportLog[]>;
9
+ private generateId;
10
+ }
11
+ //# sourceMappingURL=ExportLogRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportLogRepository.d.ts","sourceRoot":"","sources":["../../../src/backend/repositories/ExportLogRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAsB,MAAM,qBAAqB,CAAC;AAEpE,qBAAa,mBAAoB,SAAQ,cAAc,CAAC,SAAS,CAAC;gBACpD,EAAE,EAAE,EAAE;IAIZ,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAe/E,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAcvJ,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAS/E,OAAO,CAAC,UAAU;CAGnB"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExportLogRepository = void 0;
4
+ const BaseRepository_1 = require("./BaseRepository");
5
+ const ExportLog_1 = require("../models/ExportLog");
6
+ class ExportLogRepository extends BaseRepository_1.BaseRepository {
7
+ constructor(db) {
8
+ super(db, 'export_logs', ExportLog_1.EXPORT_LOG_INDEXES);
9
+ }
10
+ async logExport(log) {
11
+ const exportLog = {
12
+ ...log,
13
+ _id: this.generateId(),
14
+ type: 'DATA_EXPORT',
15
+ indexes: {
16
+ user_exports: `${log.userId}_${log.exportType}`,
17
+ date_status: `${log.timestamp.getTime()}_${log.status}`,
18
+ file_tracking: log.fileName
19
+ }
20
+ };
21
+ return this.create(exportLog);
22
+ }
23
+ async updateExportStatus(logId, status, downloadUrl, errorMessage) {
24
+ const update = { status };
25
+ if (downloadUrl) {
26
+ update.downloadUrl = downloadUrl;
27
+ }
28
+ if (errorMessage) {
29
+ update.errorMessage = errorMessage;
30
+ }
31
+ return this.update(logId, update);
32
+ }
33
+ async getUserExports(userId, exportType) {
34
+ const filter = { userId };
35
+ if (exportType) {
36
+ filter.exportType = exportType;
37
+ }
38
+ return this.find(filter, { sort: { timestamp: -1 } });
39
+ }
40
+ generateId() {
41
+ return `exp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
42
+ }
43
+ }
44
+ exports.ExportLogRepository = ExportLogRepository;
45
+ //# sourceMappingURL=ExportLogRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportLogRepository.js","sourceRoot":"","sources":["../../../src/backend/repositories/ExportLogRepository.ts"],"names":[],"mappings":";;;AACA,qDAAkD;AAClD,mDAAoE;AAEpE,MAAa,mBAAoB,SAAQ,+BAAyB;IAChE,YAAY,EAAM;QAChB,KAAK,CAAC,EAAE,EAAE,aAAa,EAAE,8BAAkB,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAgD;QAC9D,MAAM,SAAS,GAAc;YAC3B,GAAG,GAAG;YACN,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE;YACtB,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE;gBACP,YAAY,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE;gBAC/C,WAAW,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE;gBACvD,aAAa,EAAE,GAAG,CAAC,QAAQ;aAC5B;SACF,CAAC;QAEF,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,KAAa,EAAE,MAA4C,EAAE,WAAoB,EAAE,YAAqB;QAC/H,MAAM,MAAM,GAAuB,EAAE,MAAM,EAAE,CAAC;QAE9C,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;QACnC,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,MAAc,EAAE,UAAmB;QACtD,MAAM,MAAM,GAAQ,EAAE,MAAM,EAAE,CAAC;QAC/B,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QACjC,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,CAAC;IAEO,UAAU;QAChB,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACxE,CAAC;CACF;AA9CD,kDA8CC"}
@@ -0,0 +1,20 @@
1
+ import { Db } from 'mongodb';
2
+ import { BaseRepository } from './BaseRepository';
3
+ import { SessionLog } from '../models/SessionLog';
4
+ import { DateRange } from '../../shared/types';
5
+ export declare class SessionLogRepository extends BaseRepository<SessionLog> {
6
+ private readonly DEFAULT_IDLE_THRESHOLD;
7
+ constructor(db: Db);
8
+ logLogin(log: Omit<SessionLog, '_id' | 'type' | 'activityPeriods' | 'heartbeatCount' | 'lastHeartbeatTime' | 'visibilityChanges' | 'totalActiveDuration' | 'totalIdleDuration' | 'sessionDuration' | 'lastActivityTime' | 'indexes'>): Promise<SessionLog>;
9
+ logLogout(sessionId: string, reason?: 'USER' | 'TIMEOUT' | 'ERROR'): Promise<SessionLog | null>;
10
+ recordActivity(sessionId: string, activityTime: Date): Promise<SessionLog | null>;
11
+ recordHeartbeat(sessionId: string): Promise<SessionLog | null>;
12
+ recordVisibilityChange(sessionId: string, state: 'visible' | 'hidden'): Promise<SessionLog | null>;
13
+ getUserSessions(userId: string, dateRange: DateRange): Promise<SessionLog[]>;
14
+ getActiveSessions(): Promise<SessionLog[]>;
15
+ findBySessionId(sessionId: string): Promise<SessionLog | null>;
16
+ private closeLastActivityPeriod;
17
+ private calculateDurations;
18
+ private generateId;
19
+ }
20
+ //# sourceMappingURL=SessionLogRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionLogRepository.d.ts","sourceRoot":"","sources":["../../../src/backend/repositories/SessionLogRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAuC,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,qBAAa,oBAAqB,SAAQ,cAAc,CAAC,UAAU,CAAC;IAClE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAiB;gBAE5C,EAAE,EAAE,EAAE;IAIZ,QAAQ,CACZ,GAAG,EAAE,IAAI,CACP,UAAU,EACR,KAAK,GACL,MAAM,GACN,iBAAiB,GACjB,gBAAgB,GAChB,mBAAmB,GACnB,mBAAmB,GACnB,qBAAqB,GACrB,mBAAmB,GACnB,iBAAiB,GACjB,kBAAkB,GAClB,SAAS,CACZ,GACA,OAAO,CAAC,UAAU,CAAC;IA8BhB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,SAAS,GAAG,OAAgB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAyBvG,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAgDjF,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAY9D,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAgBlG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAO5E,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAM1C,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIpE,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,UAAU;CAGnB"}
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SessionLogRepository = void 0;
4
+ const BaseRepository_1 = require("./BaseRepository");
5
+ const SessionLog_1 = require("../models/SessionLog");
6
+ class SessionLogRepository extends BaseRepository_1.BaseRepository {
7
+ DEFAULT_IDLE_THRESHOLD = 5 * 60 * 1000; // 5 minutes
8
+ constructor(db) {
9
+ super(db, 'session_logs', SessionLog_1.SESSION_LOG_INDEXES);
10
+ }
11
+ async logLogin(log) {
12
+ const now = new Date();
13
+ const sessionLog = {
14
+ ...log,
15
+ _id: this.generateId(),
16
+ type: 'LOGIN',
17
+ activityPeriods: [{
18
+ startTime: now,
19
+ endTime: now,
20
+ duration: 0,
21
+ type: 'ACTIVE',
22
+ lastActivityTime: now
23
+ }],
24
+ heartbeatCount: 0,
25
+ lastHeartbeatTime: now,
26
+ visibilityChanges: [],
27
+ totalActiveDuration: 0,
28
+ totalIdleDuration: 0,
29
+ sessionDuration: 0,
30
+ lastActivityTime: now,
31
+ indexes: {
32
+ tenant_user_session: `${log.tenantId}_${log.userId}_${log.sessionId}`,
33
+ login_date: now.toISOString(),
34
+ session_duration: '0'
35
+ }
36
+ };
37
+ return this.create(sessionLog);
38
+ }
39
+ async logLogout(sessionId, reason = 'USER') {
40
+ const session = await this.findBySessionId(sessionId);
41
+ if (!session)
42
+ return null;
43
+ const now = new Date();
44
+ const loginTime = new Date(session.loginTime);
45
+ const sessionDuration = now.getTime() - loginTime.getTime();
46
+ // Close the last activity period
47
+ const updatedPeriods = this.closeLastActivityPeriod(session.activityPeriods, now);
48
+ // Calculate active/idle durations
49
+ const { activeDuration, idleDuration } = this.calculateDurations(updatedPeriods);
50
+ return this.update(session._id, {
51
+ type: 'LOGOUT',
52
+ logoutTime: now,
53
+ logoutReason: reason,
54
+ activityPeriods: updatedPeriods,
55
+ sessionDuration,
56
+ totalActiveDuration: activeDuration,
57
+ totalIdleDuration: idleDuration
58
+ });
59
+ }
60
+ async recordActivity(sessionId, activityTime) {
61
+ const session = await this.findBySessionId(sessionId);
62
+ if (!session)
63
+ return null;
64
+ const lastActivity = new Date(session.lastActivityTime);
65
+ const idleTime = activityTime.getTime() - lastActivity.getTime();
66
+ let updatedPeriods = [...session.activityPeriods];
67
+ // If idle time exceeds threshold, mark previous period as idle
68
+ if (idleTime > session.idleThreshold) {
69
+ // Close the last active period
70
+ updatedPeriods = this.closeLastActivityPeriod(updatedPeriods, lastActivity);
71
+ // Add idle period
72
+ updatedPeriods.push({
73
+ startTime: lastActivity,
74
+ endTime: activityTime,
75
+ duration: idleTime,
76
+ type: 'IDLE',
77
+ lastActivityTime: activityTime
78
+ });
79
+ }
80
+ // Add/update active period
81
+ const lastPeriod = updatedPeriods[updatedPeriods.length - 1];
82
+ if (lastPeriod.type === 'ACTIVE') {
83
+ // Extend the active period
84
+ lastPeriod.endTime = activityTime;
85
+ lastPeriod.duration = activityTime.getTime() - new Date(lastPeriod.startTime).getTime();
86
+ lastPeriod.lastActivityTime = activityTime;
87
+ }
88
+ else {
89
+ // Start new active period
90
+ updatedPeriods.push({
91
+ startTime: activityTime,
92
+ endTime: activityTime,
93
+ duration: 0,
94
+ type: 'ACTIVE',
95
+ lastActivityTime: activityTime
96
+ });
97
+ }
98
+ return this.update(session._id, {
99
+ activityPeriods: updatedPeriods,
100
+ lastActivityTime: activityTime
101
+ });
102
+ }
103
+ async recordHeartbeat(sessionId) {
104
+ const session = await this.findBySessionId(sessionId);
105
+ if (!session)
106
+ return null;
107
+ const now = new Date();
108
+ return this.update(session._id, {
109
+ heartbeatCount: session.heartbeatCount + 1,
110
+ lastHeartbeatTime: now
111
+ });
112
+ }
113
+ async recordVisibilityChange(sessionId, state) {
114
+ const session = await this.findBySessionId(sessionId);
115
+ if (!session)
116
+ return null;
117
+ const now = new Date();
118
+ const visibilityChanges = [...session.visibilityChanges, {
119
+ timestamp: now,
120
+ state,
121
+ duration: 0
122
+ }];
123
+ return this.update(session._id, {
124
+ visibilityChanges
125
+ });
126
+ }
127
+ async getUserSessions(userId, dateRange) {
128
+ return this.find({
129
+ userId,
130
+ loginTime: { $gte: dateRange.startDate, $lte: dateRange.endDate }
131
+ }, { sort: { loginTime: -1 } });
132
+ }
133
+ async getActiveSessions() {
134
+ return this.find({
135
+ logoutTime: { $exists: false }
136
+ });
137
+ }
138
+ async findBySessionId(sessionId) {
139
+ return this.findOne({ sessionId });
140
+ }
141
+ closeLastActivityPeriod(periods, endTime) {
142
+ if (periods.length === 0)
143
+ return periods;
144
+ const lastPeriod = periods[periods.length - 1];
145
+ const updatedPeriods = [...periods];
146
+ updatedPeriods[updatedPeriods.length - 1] = {
147
+ ...lastPeriod,
148
+ endTime,
149
+ duration: endTime.getTime() - new Date(lastPeriod.startTime).getTime()
150
+ };
151
+ return updatedPeriods;
152
+ }
153
+ calculateDurations(periods) {
154
+ let activeDuration = 0;
155
+ let idleDuration = 0;
156
+ for (const period of periods) {
157
+ if (period.type === 'ACTIVE') {
158
+ activeDuration += period.duration;
159
+ }
160
+ else {
161
+ idleDuration += period.duration;
162
+ }
163
+ }
164
+ return { activeDuration, idleDuration };
165
+ }
166
+ generateId() {
167
+ return `ses_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
168
+ }
169
+ }
170
+ exports.SessionLogRepository = SessionLogRepository;
171
+ //# sourceMappingURL=SessionLogRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionLogRepository.js","sourceRoot":"","sources":["../../../src/backend/repositories/SessionLogRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './AccessLogRepository';
2
+ export * from './SessionLogRepository';
3
+ export * from './ChangeLogRepository';
4
+ export * from './ExportLogRepository';
5
+ export * from './BaseRepository';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/backend/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./AccessLogRepository"), exports);
18
+ __exportStar(require("./SessionLogRepository"), exports);
19
+ __exportStar(require("./ChangeLogRepository"), exports);
20
+ __exportStar(require("./ExportLogRepository"), exports);
21
+ __exportStar(require("./BaseRepository"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/backend/repositories/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,yDAAuC;AACvC,wDAAsC;AACtC,wDAAsC;AACtC,mDAAiC"}
@@ -0,0 +1,110 @@
1
+ import type { AccessLog } from '../models/AccessLog';
2
+ import type { SessionLog } from '../models/SessionLog';
3
+ import type { ChangeLog } from '../models/ChangeLog';
4
+ import type { ExportLog } from '../models/ExportLog';
5
+ import type { DateRange } from '../../shared/types';
6
+ import { AccessLogRepository } from '../repositories/AccessLogRepository';
7
+ import { SessionLogRepository } from '../repositories/SessionLogRepository';
8
+ import { ChangeLogRepository } from '../repositories/ChangeLogRepository';
9
+ import { ExportLogRepository } from '../repositories/ExportLogRepository';
10
+ export declare class LoggingService {
11
+ private accessLogRepo;
12
+ private sessionLogRepo;
13
+ private changeLogRepo;
14
+ private exportLogRepo;
15
+ constructor(accessLogRepo: AccessLogRepository, sessionLogRepo: SessionLogRepository, changeLogRepo: ChangeLogRepository, exportLogRepo: ExportLogRepository);
16
+ logPageView(data: {
17
+ tenantId: string;
18
+ userId: string;
19
+ userRole: string;
20
+ sessionId: string;
21
+ ipAddress: string;
22
+ userAgent: string;
23
+ pageId: string;
24
+ pageTitle: string;
25
+ pageUrl: string;
26
+ pageRoute: string;
27
+ previousPage?: string;
28
+ browser?: any;
29
+ geoLocation?: any;
30
+ network?: any;
31
+ }): Promise<AccessLog>;
32
+ logAction(data: {
33
+ tenantId: string;
34
+ userId: string;
35
+ userRole: string;
36
+ sessionId: string;
37
+ ipAddress: string;
38
+ userAgent: string;
39
+ activityType: string;
40
+ activityName: string;
41
+ actionType: string;
42
+ actionTarget: string;
43
+ actionData?: Record<string, any>;
44
+ pageId?: string;
45
+ browser?: any;
46
+ }): Promise<AccessLog>;
47
+ startSession(data: {
48
+ tenantId: string;
49
+ userId: string;
50
+ userRole: string;
51
+ sessionId: string;
52
+ ipAddress: string;
53
+ userAgent: string;
54
+ idleThreshold?: number;
55
+ }): Promise<SessionLog>;
56
+ endSession(sessionId: string, reason?: 'USER' | 'TIMEOUT' | 'ERROR'): Promise<SessionLog | null>;
57
+ recordActivity(sessionId: string): Promise<SessionLog | null>;
58
+ recordHeartbeat(sessionId: string): Promise<SessionLog | null>;
59
+ logChange(data: {
60
+ tenantId: string;
61
+ userId: string;
62
+ userRole: string;
63
+ sessionId: string;
64
+ ipAddress: string;
65
+ userAgent: string;
66
+ entityType: string;
67
+ entityId: string;
68
+ type: 'CREATE' | 'UPDATE' | 'DELETE' | 'RESTORE';
69
+ changes: Array<{
70
+ field: string;
71
+ oldValue: any;
72
+ newValue: any;
73
+ type: string;
74
+ }>;
75
+ reason?: string;
76
+ comment?: string;
77
+ status: 'SUCCESS' | 'FAILURE';
78
+ errorMessage?: string;
79
+ parentEntityType?: string;
80
+ parentEntityId?: string;
81
+ }): Promise<ChangeLog>;
82
+ logExport(data: {
83
+ tenantId: string;
84
+ userId: string;
85
+ userRole: string;
86
+ sessionId: string;
87
+ ipAddress: string;
88
+ userAgent: string;
89
+ exportType: 'CSV' | 'EXCEL' | 'PDF' | 'JSON';
90
+ fileName: string;
91
+ recordCount: number;
92
+ entityType?: string;
93
+ entityIds?: string[];
94
+ filters?: Record<string, any>;
95
+ columns?: string[];
96
+ }): Promise<ExportLog>;
97
+ getUserTimeline(userId: string, dateRange: DateRange): Promise<{
98
+ accessLogs: AccessLog[];
99
+ sessionLogs: SessionLog[];
100
+ changeLogs: ChangeLog[];
101
+ exportLogs: ExportLog[];
102
+ }>;
103
+ getEntityHistory(entityType: string, entityId: string): Promise<ChangeLog[]>;
104
+ getSessionDetails(sessionId: string): Promise<{
105
+ session: SessionLog | null;
106
+ activities: AccessLog[];
107
+ }>;
108
+ getExportHistory(userId: string, exportType?: string): Promise<ExportLog[]>;
109
+ }
110
+ //# sourceMappingURL=LoggingService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoggingService.d.ts","sourceRoot":"","sources":["../../../src/backend/services/LoggingService.ts"],"names":[],"mappings":"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"}