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,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LoggingService = void 0;
4
+ class LoggingService {
5
+ accessLogRepo;
6
+ sessionLogRepo;
7
+ changeLogRepo;
8
+ exportLogRepo;
9
+ constructor(accessLogRepo, sessionLogRepo, changeLogRepo, exportLogRepo) {
10
+ this.accessLogRepo = accessLogRepo;
11
+ this.sessionLogRepo = sessionLogRepo;
12
+ this.changeLogRepo = changeLogRepo;
13
+ this.exportLogRepo = exportLogRepo;
14
+ }
15
+ // Access logs
16
+ async logPageView(data) {
17
+ return this.accessLogRepo.logPageView({
18
+ ...data,
19
+ browser: data.browser ?? {},
20
+ activityType: 'PAGE_VIEW',
21
+ activityName: `View ${data.pageTitle}`,
22
+ startTime: new Date(),
23
+ timestamp: new Date()
24
+ });
25
+ }
26
+ async logAction(data) {
27
+ return this.accessLogRepo.logAction({
28
+ ...data,
29
+ startTime: new Date(),
30
+ timestamp: new Date(),
31
+ browser: data.browser ?? {}
32
+ });
33
+ }
34
+ // Session logs
35
+ async startSession(data) {
36
+ return this.sessionLogRepo.logLogin({
37
+ ...data,
38
+ loginTime: new Date(),
39
+ timestamp: new Date(),
40
+ idleThreshold: data.idleThreshold || 5 * 60 * 1000
41
+ });
42
+ }
43
+ async endSession(sessionId, reason = 'USER') {
44
+ return this.sessionLogRepo.logLogout(sessionId, reason);
45
+ }
46
+ async recordActivity(sessionId) {
47
+ return this.sessionLogRepo.recordActivity(sessionId, new Date());
48
+ }
49
+ async recordHeartbeat(sessionId) {
50
+ return this.sessionLogRepo.recordHeartbeat(sessionId);
51
+ }
52
+ // Change logs
53
+ async logChange(data) {
54
+ return this.changeLogRepo.logChange({
55
+ ...data,
56
+ timestamp: new Date(),
57
+ changedBy: {
58
+ userId: data.userId,
59
+ role: data.userRole,
60
+ ipAddress: data.ipAddress
61
+ }
62
+ });
63
+ }
64
+ // Export logs
65
+ async logExport(data) {
66
+ return this.exportLogRepo.logExport({
67
+ ...data,
68
+ timestamp: new Date(),
69
+ status: 'IN_PROGRESS'
70
+ });
71
+ }
72
+ // Queries
73
+ async getUserTimeline(userId, dateRange) {
74
+ const [accessLogs, sessionLogs, changeLogs, exportLogs] = await Promise.all([
75
+ this.accessLogRepo.getUserTimeline(userId, dateRange),
76
+ this.sessionLogRepo.getUserSessions(userId, dateRange),
77
+ this.changeLogRepo.getUserChanges(userId),
78
+ this.exportLogRepo.getUserExports(userId)
79
+ ]);
80
+ return { accessLogs, sessionLogs, changeLogs, exportLogs };
81
+ }
82
+ async getEntityHistory(entityType, entityId) {
83
+ return this.changeLogRepo.getEntityHistory(entityType, entityId);
84
+ }
85
+ async getSessionDetails(sessionId) {
86
+ const [session, activities] = await Promise.all([
87
+ this.sessionLogRepo.findBySessionId(sessionId),
88
+ this.accessLogRepo.getSessionActivities(sessionId)
89
+ ]);
90
+ return { session, activities };
91
+ }
92
+ async getExportHistory(userId, exportType) {
93
+ return this.exportLogRepo.getUserExports(userId, exportType);
94
+ }
95
+ }
96
+ exports.LoggingService = LoggingService;
97
+ //# sourceMappingURL=LoggingService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoggingService.js","sourceRoot":"","sources":["../../../src/backend/services/LoggingService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare class Logger {
2
+ private readonly scope;
3
+ constructor(scope: string);
4
+ info(message: string, ...args: any[]): void;
5
+ warn(message: string, ...args: any[]): void;
6
+ error(message: string, ...args: any[]): void;
7
+ }
8
+ //# sourceMappingURL=Logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../../src/backend/utils/Logger.ts"],"names":[],"mappings":"AAAA,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,MAAM;IAE1C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAK3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAK3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAI7C"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Logger = void 0;
4
+ class Logger {
5
+ scope;
6
+ constructor(scope) {
7
+ this.scope = scope;
8
+ }
9
+ info(message, ...args) {
10
+ // eslint-disable-next-line no-console
11
+ console.log(`[${this.scope}] ${message}`, ...args);
12
+ }
13
+ warn(message, ...args) {
14
+ // eslint-disable-next-line no-console
15
+ console.warn(`[${this.scope}] ${message}`, ...args);
16
+ }
17
+ error(message, ...args) {
18
+ // eslint-disable-next-line no-console
19
+ console.error(`[${this.scope}] ${message}`, ...args);
20
+ }
21
+ }
22
+ exports.Logger = Logger;
23
+ //# sourceMappingURL=Logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../../src/backend/utils/Logger.ts"],"names":[],"mappings":";;;AAAA,MAAa,MAAM;IACY;IAA7B,YAA6B,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAE9C,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QACnC,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;CACF;AAjBD,wBAiBC"}
@@ -0,0 +1,29 @@
1
+ export declare class LogQueries {
2
+ private accessLogRepo;
3
+ private sessionLogRepo;
4
+ private changeLogRepo;
5
+ private exportLogRepo;
6
+ constructor(accessLogRepo: any, sessionLogRepo: any, changeLogRepo: any, exportLogRepo: any);
7
+ getUserDailyTimeline(userId: string, date: Date): Promise<any[]>;
8
+ getDailySessionSummary(userId: string, date: Date): Promise<any>;
9
+ getUserExportHistory(userId: string, filters?: any): Promise<any>;
10
+ getEntityChangeHistory(entityType: string, entityId: string): Promise<{
11
+ entityType: string;
12
+ entityId: string;
13
+ totalChanges: any;
14
+ changes: any;
15
+ fieldHistory: any;
16
+ }>;
17
+ getSessionActivityBreakdown(sessionId: string): Promise<{
18
+ session: {
19
+ loginTime: any;
20
+ logoutTime: any;
21
+ totalActiveDuration: any;
22
+ totalIdleDuration: any;
23
+ activityPeriods: any;
24
+ };
25
+ activities: any;
26
+ }>;
27
+ getUserActivityHeatmap(userId: string, startDate: Date, endDate: Date): Promise<any>;
28
+ }
29
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/examples/queries.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAU;IAEnB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,aAAa;gBAHb,aAAa,EAAE,GAAG,EAClB,cAAc,EAAE,GAAG,EACnB,aAAa,EAAE,GAAG,EAClB,aAAa,EAAE,GAAG;IAItB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI;IA6B/C,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI;IAwBjD,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;IAsBlD,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;IA8B3D,2BAA2B,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;IAwB7C,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI;CAyB5E"}
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogQueries = void 0;
4
+ class LogQueries {
5
+ accessLogRepo;
6
+ sessionLogRepo;
7
+ changeLogRepo;
8
+ exportLogRepo;
9
+ constructor(accessLogRepo, sessionLogRepo, changeLogRepo, exportLogRepo) {
10
+ this.accessLogRepo = accessLogRepo;
11
+ this.sessionLogRepo = sessionLogRepo;
12
+ this.changeLogRepo = changeLogRepo;
13
+ this.exportLogRepo = exportLogRepo;
14
+ }
15
+ // 1. Timeline-style drill-down per user per day
16
+ async getUserDailyTimeline(userId, date) {
17
+ const startOfDay = new Date(date);
18
+ startOfDay.setHours(0, 0, 0, 0);
19
+ const endOfDay = new Date(date);
20
+ endOfDay.setHours(23, 59, 59, 999);
21
+ const dateRange = { startDate: startOfDay, endDate: endOfDay };
22
+ // Get all logs for the day
23
+ const [accessLogs, sessionLogs, changeLogs, exportLogs] = await Promise.all([
24
+ this.accessLogRepo.getUserTimeline(userId, dateRange),
25
+ this.sessionLogRepo.getUserSessions(userId, dateRange),
26
+ this.changeLogRepo.getUserChanges(userId),
27
+ this.exportLogRepo.getUserExports(userId)
28
+ ]);
29
+ // Merge and sort by timestamp
30
+ const allLogs = [
31
+ ...accessLogs.map((log) => ({ ...log, logType: 'ACCESS' })),
32
+ ...sessionLogs.map((log) => ({ ...log, logType: 'SESSION' })),
33
+ ...changeLogs.map((log) => ({ ...log, logType: 'CHANGE' })),
34
+ ...exportLogs.map((log) => ({ ...log, logType: 'EXPORT' }))
35
+ ].sort((a, b) => b.timestamp - a.timestamp);
36
+ return allLogs;
37
+ }
38
+ // 2. Day-wise expandable session summary
39
+ async getDailySessionSummary(userId, date) {
40
+ const startOfDay = new Date(date);
41
+ startOfDay.setHours(0, 0, 0, 0);
42
+ const endOfDay = new Date(date);
43
+ endOfDay.setHours(23, 59, 59, 999);
44
+ const sessions = await this.sessionLogRepo.getUserSessions(userId, {
45
+ startDate: startOfDay,
46
+ endDate: endOfDay
47
+ });
48
+ return sessions.map((session) => ({
49
+ sessionId: session.sessionId,
50
+ loginTime: session.loginTime,
51
+ logoutTime: session.logoutTime,
52
+ totalActiveDuration: session.totalActiveDuration,
53
+ totalIdleDuration: session.totalIdleDuration,
54
+ activityPeriods: session.activityPeriods,
55
+ status: session.logoutTime ? 'COMPLETED' : 'ACTIVE'
56
+ }));
57
+ }
58
+ // 3. Per-user export history
59
+ async getUserExportHistory(userId, filters) {
60
+ const query = { userId };
61
+ if (filters?.exportType) {
62
+ query.exportType = filters.exportType;
63
+ }
64
+ if (filters?.startDate && filters?.endDate) {
65
+ query.timestamp = {
66
+ $gte: new Date(filters.startDate),
67
+ $lte: new Date(filters.endDate)
68
+ };
69
+ }
70
+ if (filters?.status) {
71
+ query.status = filters.status;
72
+ }
73
+ return this.exportLogRepo.paginate(query, filters?.page || 1, filters?.limit || 20);
74
+ }
75
+ // 4. Entity change history with field comparison
76
+ async getEntityChangeHistory(entityType, entityId) {
77
+ const changes = await this.changeLogRepo.getEntityHistory(entityType, entityId);
78
+ // Group changes by field
79
+ const fieldHistory = changes.reduce((acc, change) => {
80
+ change.changes.forEach((fieldChange) => {
81
+ if (!acc[fieldChange.field]) {
82
+ acc[fieldChange.field] = [];
83
+ }
84
+ acc[fieldChange.field].push({
85
+ timestamp: change.timestamp,
86
+ oldValue: fieldChange.oldValue,
87
+ newValue: fieldChange.newValue,
88
+ changedBy: change.changedBy,
89
+ reason: change.reason
90
+ });
91
+ });
92
+ return acc;
93
+ }, {});
94
+ return {
95
+ entityType,
96
+ entityId,
97
+ totalChanges: changes.length,
98
+ changes: changes.slice(0, 100), // Latest 100 changes
99
+ fieldHistory
100
+ };
101
+ }
102
+ // 5. Active vs inactive periods per session
103
+ async getSessionActivityBreakdown(sessionId) {
104
+ const session = await this.sessionLogRepo.findBySessionId(sessionId);
105
+ if (!session)
106
+ return null;
107
+ const activities = await this.accessLogRepo.getSessionActivities(sessionId);
108
+ return {
109
+ session: {
110
+ loginTime: session.loginTime,
111
+ logoutTime: session.logoutTime,
112
+ totalActiveDuration: session.totalActiveDuration,
113
+ totalIdleDuration: session.totalIdleDuration,
114
+ activityPeriods: session.activityPeriods
115
+ },
116
+ activities: activities.map((activity) => ({
117
+ timestamp: activity.timestamp,
118
+ activityType: activity.activityType,
119
+ activityName: activity.activityName,
120
+ duration: activity.activeDuration
121
+ }))
122
+ };
123
+ }
124
+ // 6. User activity heatmap (aggregate by hour)
125
+ async getUserActivityHeatmap(userId, startDate, endDate) {
126
+ // DocumentDB-safe aggregation
127
+ const pipeline = [
128
+ {
129
+ $match: {
130
+ userId,
131
+ timestamp: { $gte: startDate, $lte: endDate }
132
+ }
133
+ },
134
+ {
135
+ $group: {
136
+ _id: {
137
+ date: { $dateToString: { format: "%Y-%m-%d", date: "$timestamp" } },
138
+ hour: { $hour: "$timestamp" }
139
+ },
140
+ count: { $sum: 1 }
141
+ }
142
+ },
143
+ {
144
+ $sort: { "_id.date": 1, "_id.hour": 1 }
145
+ }
146
+ ];
147
+ return this.accessLogRepo.aggregate(pipeline);
148
+ }
149
+ }
150
+ exports.LogQueries = LogQueries;
151
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/examples/queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ export interface ActivityEvent {
2
+ type: 'PAGE_VIEW' | 'ACTION' | 'NAVIGATION' | 'API_CALL';
3
+ name: string;
4
+ data?: Record<string, any>;
5
+ timestamp: Date;
6
+ duration?: number;
7
+ }
8
+ export interface PageViewEvent {
9
+ pageId: string;
10
+ pageTitle: string;
11
+ pageUrl: string;
12
+ pageRoute: string;
13
+ previousPage?: string;
14
+ loadTime?: number;
15
+ domReadyTime?: number;
16
+ }
17
+ export interface ActionEvent {
18
+ actionType: string;
19
+ actionTarget: string;
20
+ actionData?: Record<string, any>;
21
+ }
22
+ export declare class ActivityMonitor {
23
+ private sessionId;
24
+ private userId;
25
+ private endpoint;
26
+ private batchSize;
27
+ private batchInterval;
28
+ private eventQueue;
29
+ private batchTimer?;
30
+ constructor(sessionId: string, userId: string, endpoint: string);
31
+ private initialize;
32
+ trackPageView(pageInfo?: Partial<PageViewEvent>): void;
33
+ trackAction(action: ActionEvent): void;
34
+ trackNavigation(from: string, to: string): void;
35
+ trackAPICall(endpoint: string, method: string, status: number, duration: number): void;
36
+ private queueEvent;
37
+ private startBatchProcessor;
38
+ private sendBatch;
39
+ private trackSPANavigation;
40
+ private getCurrentPageId;
41
+ private getPageLoadTime;
42
+ private getDOMReadyTime;
43
+ destroy(): void;
44
+ }
45
+ //# sourceMappingURL=ActivityMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivityMonitor.d.ts","sourceRoot":"","sources":["../../../src/frontend/activity-monitor/ActivityMonitor.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAAC,CAAiB;gBAExB,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAQ/D,OAAO,CAAC,UAAU;IAWX,aAAa,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAmBtD,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAWtC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAW/C,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAW7F,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,mBAAmB;YAQb,SAAS;IAyBvB,OAAO,CAAC,kBAAkB;IA4B1B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,eAAe;IAQhB,OAAO,IAAI,IAAI;CAUvB"}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActivityMonitor = void 0;
4
+ class ActivityMonitor {
5
+ sessionId;
6
+ userId;
7
+ endpoint;
8
+ batchSize = 10;
9
+ batchInterval = 5000; // 5 seconds
10
+ eventQueue = [];
11
+ batchTimer;
12
+ constructor(sessionId, userId, endpoint) {
13
+ this.sessionId = sessionId;
14
+ this.userId = userId;
15
+ this.endpoint = endpoint;
16
+ this.initialize();
17
+ }
18
+ initialize() {
19
+ // Start batch processing
20
+ this.startBatchProcessor();
21
+ // Track page views
22
+ this.trackPageView();
23
+ // Track SPA navigation
24
+ this.trackSPANavigation();
25
+ }
26
+ trackPageView(pageInfo) {
27
+ const event = {
28
+ type: 'PAGE_VIEW',
29
+ name: 'page_view',
30
+ data: {
31
+ pageId: pageInfo?.pageId || this.getCurrentPageId(),
32
+ pageTitle: pageInfo?.pageTitle || document.title,
33
+ pageUrl: pageInfo?.pageUrl || window.location.href,
34
+ pageRoute: pageInfo?.pageRoute || window.location.pathname,
35
+ previousPage: pageInfo?.previousPage || document.referrer,
36
+ loadTime: pageInfo?.loadTime || this.getPageLoadTime(),
37
+ domReadyTime: pageInfo?.domReadyTime || this.getDOMReadyTime()
38
+ },
39
+ timestamp: new Date()
40
+ };
41
+ this.queueEvent(event);
42
+ }
43
+ trackAction(action) {
44
+ const event = {
45
+ type: 'ACTION',
46
+ name: 'user_action',
47
+ data: action,
48
+ timestamp: new Date()
49
+ };
50
+ this.queueEvent(event);
51
+ }
52
+ trackNavigation(from, to) {
53
+ const event = {
54
+ type: 'NAVIGATION',
55
+ name: 'spa_navigation',
56
+ data: { from, to },
57
+ timestamp: new Date()
58
+ };
59
+ this.queueEvent(event);
60
+ }
61
+ trackAPICall(endpoint, method, status, duration) {
62
+ const event = {
63
+ type: 'API_CALL',
64
+ name: 'api_call',
65
+ data: { endpoint, method, status, duration },
66
+ timestamp: new Date()
67
+ };
68
+ this.queueEvent(event);
69
+ }
70
+ queueEvent(event) {
71
+ this.eventQueue.push(event);
72
+ // Send batch if queue reaches threshold
73
+ if (this.eventQueue.length >= this.batchSize) {
74
+ this.sendBatch();
75
+ }
76
+ }
77
+ startBatchProcessor() {
78
+ this.batchTimer = setInterval(() => {
79
+ if (this.eventQueue.length > 0) {
80
+ this.sendBatch();
81
+ }
82
+ }, this.batchInterval);
83
+ }
84
+ async sendBatch() {
85
+ if (this.eventQueue.length === 0)
86
+ return;
87
+ const batch = [...this.eventQueue];
88
+ this.eventQueue = [];
89
+ try {
90
+ await fetch(this.endpoint, {
91
+ method: 'POST',
92
+ headers: {
93
+ 'Content-Type': 'application/json',
94
+ },
95
+ body: JSON.stringify({
96
+ sessionId: this.sessionId,
97
+ userId: this.userId,
98
+ events: batch
99
+ })
100
+ });
101
+ }
102
+ catch (error) {
103
+ console.warn('Failed to send activity batch:', error);
104
+ // Requeue failed events
105
+ this.eventQueue.unshift(...batch);
106
+ }
107
+ }
108
+ trackSPANavigation() {
109
+ // Override pushState and replaceState for SPA tracking
110
+ const originalPushState = history.pushState;
111
+ const originalReplaceState = history.replaceState;
112
+ history.pushState = function (...args) {
113
+ const result = originalPushState.apply(this, args);
114
+ window.dispatchEvent(new Event('pushstate'));
115
+ window.dispatchEvent(new Event('locationchange'));
116
+ return result;
117
+ };
118
+ history.replaceState = function (...args) {
119
+ const result = originalReplaceState.apply(this, args);
120
+ window.dispatchEvent(new Event('replacestate'));
121
+ window.dispatchEvent(new Event('locationchange'));
122
+ return result;
123
+ };
124
+ window.addEventListener('popstate', () => {
125
+ window.dispatchEvent(new Event('locationchange'));
126
+ });
127
+ window.addEventListener('locationchange', () => {
128
+ this.trackPageView();
129
+ });
130
+ }
131
+ getCurrentPageId() {
132
+ return `${window.location.pathname}-${window.location.search}`;
133
+ }
134
+ getPageLoadTime() {
135
+ if (window.performance && window.performance.timing) {
136
+ const timing = window.performance.timing;
137
+ return timing.loadEventEnd - timing.navigationStart;
138
+ }
139
+ return 0;
140
+ }
141
+ getDOMReadyTime() {
142
+ if (window.performance && window.performance.timing) {
143
+ const timing = window.performance.timing;
144
+ return timing.domContentLoadedEventEnd - timing.navigationStart;
145
+ }
146
+ return 0;
147
+ }
148
+ destroy() {
149
+ if (this.batchTimer) {
150
+ clearInterval(this.batchTimer);
151
+ }
152
+ // Send any remaining events
153
+ if (this.eventQueue.length > 0) {
154
+ this.sendBatch();
155
+ }
156
+ }
157
+ }
158
+ exports.ActivityMonitor = ActivityMonitor;
159
+ //# sourceMappingURL=ActivityMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivityMonitor.js","sourceRoot":"","sources":["../../../src/frontend/activity-monitor/ActivityMonitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export type IdleTrackerOptions = {
2
+ /**
3
+ * Milliseconds of inactivity before we consider the user "idle".
4
+ * Default: 5 minutes.
5
+ */
6
+ idleThresholdMs?: number;
7
+ /**
8
+ * Called once when the tracker transitions from active -> idle.
9
+ */
10
+ onIdle?: () => void;
11
+ /**
12
+ * Called once when the tracker transitions from idle -> active.
13
+ */
14
+ onActive?: () => void;
15
+ /**
16
+ * DOM events that reset the idle timer.
17
+ */
18
+ activityEvents?: Array<keyof WindowEventMap>;
19
+ };
20
+ export declare class IdleTracker {
21
+ private idleThresholdMs;
22
+ private onIdle?;
23
+ private onActive?;
24
+ private activityEvents;
25
+ private timerId;
26
+ private isIdle;
27
+ private boundHandler;
28
+ constructor(options?: IdleTrackerOptions);
29
+ start(): void;
30
+ stop(): void;
31
+ recordActivity(): void;
32
+ private scheduleIdleCheck;
33
+ }
34
+ //# sourceMappingURL=IdleTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdleTracker.d.ts","sourceRoot":"","sources":["../../../src/frontend/idle-tracker/IdleTracker.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,cAAc,CAAC,CAAC;CAC9C,CAAC;AAEF,qBAAa,WAAW;IACtB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,MAAM,CAAC,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,cAAc,CAA8B;IAEpD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAa;gBAErB,OAAO,GAAE,kBAAuB;IAU5C,KAAK,IAAI,IAAI;IAUb,IAAI,IAAI,IAAI;IAWZ,cAAc,IAAI,IAAI;IAStB,OAAO,CAAC,iBAAiB;CAY1B"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IdleTracker = void 0;
4
+ class IdleTracker {
5
+ idleThresholdMs;
6
+ onIdle;
7
+ onActive;
8
+ activityEvents;
9
+ timerId = null;
10
+ isIdle = false;
11
+ boundHandler;
12
+ constructor(options = {}) {
13
+ this.idleThresholdMs = options.idleThresholdMs ?? 5 * 60 * 1000;
14
+ this.onIdle = options.onIdle;
15
+ this.onActive = options.onActive;
16
+ this.activityEvents =
17
+ options.activityEvents ?? ['mousemove', 'mousedown', 'keydown', 'scroll', 'touchstart'];
18
+ this.boundHandler = () => this.recordActivity();
19
+ }
20
+ start() {
21
+ this.stop();
22
+ for (const evt of this.activityEvents) {
23
+ window.addEventListener(evt, this.boundHandler, { passive: true });
24
+ }
25
+ this.scheduleIdleCheck();
26
+ }
27
+ stop() {
28
+ for (const evt of this.activityEvents) {
29
+ window.removeEventListener(evt, this.boundHandler);
30
+ }
31
+ if (this.timerId !== null) {
32
+ window.clearTimeout(this.timerId);
33
+ this.timerId = null;
34
+ }
35
+ }
36
+ recordActivity() {
37
+ if (this.isIdle) {
38
+ this.isIdle = false;
39
+ this.onActive?.();
40
+ }
41
+ this.scheduleIdleCheck();
42
+ }
43
+ scheduleIdleCheck() {
44
+ if (this.timerId !== null) {
45
+ window.clearTimeout(this.timerId);
46
+ }
47
+ this.timerId = window.setTimeout(() => {
48
+ if (!this.isIdle) {
49
+ this.isIdle = true;
50
+ this.onIdle?.();
51
+ }
52
+ }, this.idleThresholdMs);
53
+ }
54
+ }
55
+ exports.IdleTracker = IdleTracker;
56
+ //# sourceMappingURL=IdleTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdleTracker.js","sourceRoot":"","sources":["../../../src/frontend/idle-tracker/IdleTracker.ts"],"names":[],"mappings":";;;AAuBA,MAAa,WAAW;IACd,eAAe,CAAS;IACxB,MAAM,CAAc;IACpB,QAAQ,CAAc;IACtB,cAAc,CAA8B;IAE5C,OAAO,GAAkB,IAAI,CAAC;IAC9B,MAAM,GAAG,KAAK,CAAC;IACf,YAAY,CAAa;IAEjC,YAAY,UAA8B,EAAE;QAC1C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAChE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,cAAc;YACjB,OAAO,CAAC,cAAc,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAE1F,IAAI,CAAC,YAAY,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;IAClD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,EAAE,CAAC;QAEZ,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAS,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI;QACF,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,YAAmB,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;QACpB,CAAC;QAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3B,CAAC;CACF;AA9DD,kCA8DC"}