@carlonicora/nestjs-neo4jsonapi 4.14.0 → 4.16.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 (158) hide show
  1. package/README.md +2 -0
  2. package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
  3. package/dist/bootstrap/app.module.factory.js +1 -0
  4. package/dist/bootstrap/app.module.factory.js.map +1 -1
  5. package/dist/bootstrap/bootstrap.options.d.ts +22 -0
  6. package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
  7. package/dist/config/base.config.d.ts.map +1 -1
  8. package/dist/config/base.config.js +9 -0
  9. package/dist/config/base.config.js.map +1 -1
  10. package/dist/config/enums/queue.id.d.ts +1 -0
  11. package/dist/config/enums/queue.id.d.ts.map +1 -1
  12. package/dist/config/enums/queue.id.js +1 -0
  13. package/dist/config/enums/queue.id.js.map +1 -1
  14. package/dist/config/interfaces/base.config.interface.d.ts +2 -0
  15. package/dist/config/interfaces/base.config.interface.d.ts.map +1 -1
  16. package/dist/config/interfaces/config.analytics.interface.d.ts +13 -0
  17. package/dist/config/interfaces/config.analytics.interface.d.ts.map +1 -0
  18. package/dist/config/interfaces/config.analytics.interface.js +3 -0
  19. package/dist/config/interfaces/config.analytics.interface.js.map +1 -0
  20. package/dist/config/interfaces/config.s3.interface.d.ts +5 -0
  21. package/dist/config/interfaces/config.s3.interface.d.ts.map +1 -1
  22. package/dist/config/interfaces/index.d.ts +1 -0
  23. package/dist/config/interfaces/index.d.ts.map +1 -1
  24. package/dist/config/interfaces/index.js +1 -0
  25. package/dist/config/interfaces/index.js.map +1 -1
  26. package/dist/foundations/analytics/analytics.module.d.ts +39 -0
  27. package/dist/foundations/analytics/analytics.module.d.ts.map +1 -0
  28. package/dist/foundations/analytics/analytics.module.js +122 -0
  29. package/dist/foundations/analytics/analytics.module.js.map +1 -0
  30. package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts +32 -0
  31. package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts.map +1 -0
  32. package/dist/foundations/analytics/controllers/analytics.admin.controller.js +197 -0
  33. package/dist/foundations/analytics/controllers/analytics.admin.controller.js.map +1 -0
  34. package/dist/foundations/analytics/controllers/analytics.controller.d.ts +29 -0
  35. package/dist/foundations/analytics/controllers/analytics.controller.d.ts.map +1 -0
  36. package/dist/foundations/analytics/controllers/analytics.controller.js +85 -0
  37. package/dist/foundations/analytics/controllers/analytics.controller.js.map +1 -0
  38. package/dist/foundations/analytics/cron/analytics-retention.cron.d.ts +13 -0
  39. package/dist/foundations/analytics/cron/analytics-retention.cron.d.ts.map +1 -0
  40. package/dist/foundations/analytics/cron/analytics-retention.cron.js +61 -0
  41. package/dist/foundations/analytics/cron/analytics-retention.cron.js.map +1 -0
  42. package/dist/foundations/analytics/dtos/analytics-event.post.dto.d.ts +21 -0
  43. package/dist/foundations/analytics/dtos/analytics-event.post.dto.d.ts.map +1 -0
  44. package/dist/foundations/analytics/dtos/analytics-event.post.dto.js +105 -0
  45. package/dist/foundations/analytics/dtos/analytics-event.post.dto.js.map +1 -0
  46. package/dist/foundations/analytics/entities/analytics-breakdown.d.ts +17 -0
  47. package/dist/foundations/analytics/entities/analytics-breakdown.d.ts.map +1 -0
  48. package/dist/foundations/analytics/entities/analytics-breakdown.js +18 -0
  49. package/dist/foundations/analytics/entities/analytics-breakdown.js.map +1 -0
  50. package/dist/foundations/analytics/entities/analytics-breakdown.meta.d.ts +3 -0
  51. package/dist/foundations/analytics/entities/analytics-breakdown.meta.d.ts.map +1 -0
  52. package/dist/foundations/analytics/entities/analytics-breakdown.meta.js +10 -0
  53. package/dist/foundations/analytics/entities/analytics-breakdown.meta.js.map +1 -0
  54. package/dist/foundations/analytics/entities/analytics-daily-summary.d.ts +30 -0
  55. package/dist/foundations/analytics/entities/analytics-daily-summary.d.ts.map +1 -0
  56. package/dist/foundations/analytics/entities/analytics-daily-summary.js +28 -0
  57. package/dist/foundations/analytics/entities/analytics-daily-summary.js.map +1 -0
  58. package/dist/foundations/analytics/entities/analytics-daily-summary.meta.d.ts +3 -0
  59. package/dist/foundations/analytics/entities/analytics-daily-summary.meta.d.ts.map +1 -0
  60. package/dist/foundations/analytics/entities/analytics-daily-summary.meta.js +10 -0
  61. package/dist/foundations/analytics/entities/analytics-daily-summary.meta.js.map +1 -0
  62. package/dist/foundations/analytics/entities/analytics-event.meta.d.ts +8 -0
  63. package/dist/foundations/analytics/entities/analytics-event.meta.d.ts.map +1 -0
  64. package/dist/foundations/analytics/entities/analytics-event.meta.js +15 -0
  65. package/dist/foundations/analytics/entities/analytics-event.meta.js.map +1 -0
  66. package/dist/foundations/analytics/entities/analytics-page-view.d.ts +39 -0
  67. package/dist/foundations/analytics/entities/analytics-page-view.d.ts.map +1 -0
  68. package/dist/foundations/analytics/entities/analytics-page-view.js +38 -0
  69. package/dist/foundations/analytics/entities/analytics-page-view.js.map +1 -0
  70. package/dist/foundations/analytics/entities/analytics-page-view.meta.d.ts +3 -0
  71. package/dist/foundations/analytics/entities/analytics-page-view.meta.d.ts.map +1 -0
  72. package/dist/foundations/analytics/entities/analytics-page-view.meta.js +10 -0
  73. package/dist/foundations/analytics/entities/analytics-page-view.meta.js.map +1 -0
  74. package/dist/foundations/analytics/entities/analytics-session.d.ts +52 -0
  75. package/dist/foundations/analytics/entities/analytics-session.d.ts.map +1 -0
  76. package/dist/foundations/analytics/entities/analytics-session.js +47 -0
  77. package/dist/foundations/analytics/entities/analytics-session.js.map +1 -0
  78. package/dist/foundations/analytics/entities/analytics-session.meta.d.ts +3 -0
  79. package/dist/foundations/analytics/entities/analytics-session.meta.d.ts.map +1 -0
  80. package/dist/foundations/analytics/entities/analytics-session.meta.js +10 -0
  81. package/dist/foundations/analytics/entities/analytics-session.meta.js.map +1 -0
  82. package/dist/foundations/analytics/entities/analytics-summary.d.ts +24 -0
  83. package/dist/foundations/analytics/entities/analytics-summary.d.ts.map +1 -0
  84. package/dist/foundations/analytics/entities/analytics-summary.js +20 -0
  85. package/dist/foundations/analytics/entities/analytics-summary.js.map +1 -0
  86. package/dist/foundations/analytics/entities/analytics-summary.meta.d.ts +3 -0
  87. package/dist/foundations/analytics/entities/analytics-summary.meta.d.ts.map +1 -0
  88. package/dist/foundations/analytics/entities/analytics-summary.meta.js +10 -0
  89. package/dist/foundations/analytics/entities/analytics-summary.meta.js.map +1 -0
  90. package/dist/foundations/analytics/entities/analytics-timeline.d.ts +20 -0
  91. package/dist/foundations/analytics/entities/analytics-timeline.d.ts.map +1 -0
  92. package/dist/foundations/analytics/entities/analytics-timeline.js +18 -0
  93. package/dist/foundations/analytics/entities/analytics-timeline.js.map +1 -0
  94. package/dist/foundations/analytics/entities/analytics-timeline.meta.d.ts +3 -0
  95. package/dist/foundations/analytics/entities/analytics-timeline.meta.d.ts.map +1 -0
  96. package/dist/foundations/analytics/entities/analytics-timeline.meta.js +10 -0
  97. package/dist/foundations/analytics/entities/analytics-timeline.meta.js.map +1 -0
  98. package/dist/foundations/analytics/index.d.ts +27 -0
  99. package/dist/foundations/analytics/index.d.ts.map +1 -0
  100. package/dist/foundations/analytics/index.js +54 -0
  101. package/dist/foundations/analytics/index.js.map +1 -0
  102. package/dist/foundations/analytics/interfaces/analytics.config.interface.d.ts +80 -0
  103. package/dist/foundations/analytics/interfaces/analytics.config.interface.d.ts.map +1 -0
  104. package/dist/foundations/analytics/interfaces/analytics.config.interface.js +28 -0
  105. package/dist/foundations/analytics/interfaces/analytics.config.interface.js.map +1 -0
  106. package/dist/foundations/analytics/interfaces/analytics.page-view.input.d.ts +30 -0
  107. package/dist/foundations/analytics/interfaces/analytics.page-view.input.d.ts.map +1 -0
  108. package/dist/foundations/analytics/interfaces/analytics.page-view.input.js +3 -0
  109. package/dist/foundations/analytics/interfaces/analytics.page-view.input.js.map +1 -0
  110. package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.d.ts +30 -0
  111. package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.d.ts.map +1 -0
  112. package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.js +3 -0
  113. package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.js.map +1 -0
  114. package/dist/foundations/analytics/processors/analytics.processor.d.ts +33 -0
  115. package/dist/foundations/analytics/processors/analytics.processor.d.ts.map +1 -0
  116. package/dist/foundations/analytics/processors/analytics.processor.js +126 -0
  117. package/dist/foundations/analytics/processors/analytics.processor.js.map +1 -0
  118. package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.d.ts +38 -0
  119. package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.d.ts.map +1 -0
  120. package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.js +142 -0
  121. package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.js.map +1 -0
  122. package/dist/foundations/analytics/repositories/analytics-page-view.repository.d.ts +30 -0
  123. package/dist/foundations/analytics/repositories/analytics-page-view.repository.d.ts.map +1 -0
  124. package/dist/foundations/analytics/repositories/analytics-page-view.repository.js +62 -0
  125. package/dist/foundations/analytics/repositories/analytics-page-view.repository.js.map +1 -0
  126. package/dist/foundations/analytics/repositories/analytics-session.repository.d.ts +87 -0
  127. package/dist/foundations/analytics/repositories/analytics-session.repository.d.ts.map +1 -0
  128. package/dist/foundations/analytics/repositories/analytics-session.repository.js +261 -0
  129. package/dist/foundations/analytics/repositories/analytics-session.repository.js.map +1 -0
  130. package/dist/foundations/analytics/repositories/analytics.admin.repository.d.ts +145 -0
  131. package/dist/foundations/analytics/repositories/analytics.admin.repository.d.ts.map +1 -0
  132. package/dist/foundations/analytics/repositories/analytics.admin.repository.js +490 -0
  133. package/dist/foundations/analytics/repositories/analytics.admin.repository.js.map +1 -0
  134. package/dist/foundations/analytics/services/analytics.admin.service.d.ts +74 -0
  135. package/dist/foundations/analytics/services/analytics.admin.service.d.ts.map +1 -0
  136. package/dist/foundations/analytics/services/analytics.admin.service.js +126 -0
  137. package/dist/foundations/analytics/services/analytics.admin.service.js.map +1 -0
  138. package/dist/foundations/analytics/services/analytics.service.d.ts +31 -0
  139. package/dist/foundations/analytics/services/analytics.service.d.ts.map +1 -0
  140. package/dist/foundations/analytics/services/analytics.service.js +57 -0
  141. package/dist/foundations/analytics/services/analytics.service.js.map +1 -0
  142. package/dist/foundations/analytics/services/analytics.visitor-id.service.d.ts +34 -0
  143. package/dist/foundations/analytics/services/analytics.visitor-id.service.d.ts.map +1 -0
  144. package/dist/foundations/analytics/services/analytics.visitor-id.service.js +93 -0
  145. package/dist/foundations/analytics/services/analytics.visitor-id.service.js.map +1 -0
  146. package/dist/foundations/foundations.modules.d.ts +3 -0
  147. package/dist/foundations/foundations.modules.d.ts.map +1 -1
  148. package/dist/foundations/foundations.modules.js +3 -1
  149. package/dist/foundations/foundations.modules.js.map +1 -1
  150. package/dist/foundations/index.d.ts +1 -0
  151. package/dist/foundations/index.d.ts.map +1 -1
  152. package/dist/foundations/index.js +1 -0
  153. package/dist/foundations/index.js.map +1 -1
  154. package/dist/foundations/s3/services/s3.service.d.ts +0 -1
  155. package/dist/foundations/s3/services/s3.service.d.ts.map +1 -1
  156. package/dist/foundations/s3/services/s3.service.js +6 -6
  157. package/dist/foundations/s3/services/s3.service.js.map +1 -1
  158. package/package.json +1 -1
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_ANALYTICS_CONFIG = exports.ANALYTICS_QUEUE = exports.ANALYTICS_CONFIG = exports.AnalyticsRetentionCron = exports.AnalyticsProcessor = exports.AnalyticsAdminService = exports.AnalyticsService = exports.AnalyticsVisitorIdService = exports.AnalyticsAdminRepository = exports.AnalyticsDailySummaryRepository = exports.AnalyticsPageViewRepository = exports.AnalyticsSessionRepository = exports.analyticsEventMeta = exports.analyticsBreakdownMeta = exports.AnalyticsBreakdownDescriptor = exports.analyticsTimelineMeta = exports.AnalyticsTimelineDescriptor = exports.analyticsSummaryMeta = exports.AnalyticsSummaryDescriptor = exports.analyticsDailySummaryMeta = exports.AnalyticsDailySummaryDescriptor = exports.analyticsPageViewMeta = exports.AnalyticsPageViewDescriptor = exports.analyticsSessionMeta = exports.AnalyticsSessionDescriptor = exports.AnalyticsModule = void 0;
4
+ var analytics_module_1 = require("./analytics.module");
5
+ Object.defineProperty(exports, "AnalyticsModule", { enumerable: true, get: function () { return analytics_module_1.AnalyticsModule; } });
6
+ var analytics_session_1 = require("./entities/analytics-session");
7
+ Object.defineProperty(exports, "AnalyticsSessionDescriptor", { enumerable: true, get: function () { return analytics_session_1.AnalyticsSessionDescriptor; } });
8
+ var analytics_session_meta_1 = require("./entities/analytics-session.meta");
9
+ Object.defineProperty(exports, "analyticsSessionMeta", { enumerable: true, get: function () { return analytics_session_meta_1.analyticsSessionMeta; } });
10
+ var analytics_page_view_1 = require("./entities/analytics-page-view");
11
+ Object.defineProperty(exports, "AnalyticsPageViewDescriptor", { enumerable: true, get: function () { return analytics_page_view_1.AnalyticsPageViewDescriptor; } });
12
+ var analytics_page_view_meta_1 = require("./entities/analytics-page-view.meta");
13
+ Object.defineProperty(exports, "analyticsPageViewMeta", { enumerable: true, get: function () { return analytics_page_view_meta_1.analyticsPageViewMeta; } });
14
+ var analytics_daily_summary_1 = require("./entities/analytics-daily-summary");
15
+ Object.defineProperty(exports, "AnalyticsDailySummaryDescriptor", { enumerable: true, get: function () { return analytics_daily_summary_1.AnalyticsDailySummaryDescriptor; } });
16
+ var analytics_daily_summary_meta_1 = require("./entities/analytics-daily-summary.meta");
17
+ Object.defineProperty(exports, "analyticsDailySummaryMeta", { enumerable: true, get: function () { return analytics_daily_summary_meta_1.analyticsDailySummaryMeta; } });
18
+ var analytics_summary_1 = require("./entities/analytics-summary");
19
+ Object.defineProperty(exports, "AnalyticsSummaryDescriptor", { enumerable: true, get: function () { return analytics_summary_1.AnalyticsSummaryDescriptor; } });
20
+ var analytics_summary_meta_1 = require("./entities/analytics-summary.meta");
21
+ Object.defineProperty(exports, "analyticsSummaryMeta", { enumerable: true, get: function () { return analytics_summary_meta_1.analyticsSummaryMeta; } });
22
+ var analytics_timeline_1 = require("./entities/analytics-timeline");
23
+ Object.defineProperty(exports, "AnalyticsTimelineDescriptor", { enumerable: true, get: function () { return analytics_timeline_1.AnalyticsTimelineDescriptor; } });
24
+ var analytics_timeline_meta_1 = require("./entities/analytics-timeline.meta");
25
+ Object.defineProperty(exports, "analyticsTimelineMeta", { enumerable: true, get: function () { return analytics_timeline_meta_1.analyticsTimelineMeta; } });
26
+ var analytics_breakdown_1 = require("./entities/analytics-breakdown");
27
+ Object.defineProperty(exports, "AnalyticsBreakdownDescriptor", { enumerable: true, get: function () { return analytics_breakdown_1.AnalyticsBreakdownDescriptor; } });
28
+ var analytics_breakdown_meta_1 = require("./entities/analytics-breakdown.meta");
29
+ Object.defineProperty(exports, "analyticsBreakdownMeta", { enumerable: true, get: function () { return analytics_breakdown_meta_1.analyticsBreakdownMeta; } });
30
+ var analytics_event_meta_1 = require("./entities/analytics-event.meta");
31
+ Object.defineProperty(exports, "analyticsEventMeta", { enumerable: true, get: function () { return analytics_event_meta_1.analyticsEventMeta; } });
32
+ var analytics_session_repository_1 = require("./repositories/analytics-session.repository");
33
+ Object.defineProperty(exports, "AnalyticsSessionRepository", { enumerable: true, get: function () { return analytics_session_repository_1.AnalyticsSessionRepository; } });
34
+ var analytics_page_view_repository_1 = require("./repositories/analytics-page-view.repository");
35
+ Object.defineProperty(exports, "AnalyticsPageViewRepository", { enumerable: true, get: function () { return analytics_page_view_repository_1.AnalyticsPageViewRepository; } });
36
+ var analytics_daily_summary_repository_1 = require("./repositories/analytics-daily-summary.repository");
37
+ Object.defineProperty(exports, "AnalyticsDailySummaryRepository", { enumerable: true, get: function () { return analytics_daily_summary_repository_1.AnalyticsDailySummaryRepository; } });
38
+ var analytics_admin_repository_1 = require("./repositories/analytics.admin.repository");
39
+ Object.defineProperty(exports, "AnalyticsAdminRepository", { enumerable: true, get: function () { return analytics_admin_repository_1.AnalyticsAdminRepository; } });
40
+ var analytics_visitor_id_service_1 = require("./services/analytics.visitor-id.service");
41
+ Object.defineProperty(exports, "AnalyticsVisitorIdService", { enumerable: true, get: function () { return analytics_visitor_id_service_1.AnalyticsVisitorIdService; } });
42
+ var analytics_service_1 = require("./services/analytics.service");
43
+ Object.defineProperty(exports, "AnalyticsService", { enumerable: true, get: function () { return analytics_service_1.AnalyticsService; } });
44
+ var analytics_admin_service_1 = require("./services/analytics.admin.service");
45
+ Object.defineProperty(exports, "AnalyticsAdminService", { enumerable: true, get: function () { return analytics_admin_service_1.AnalyticsAdminService; } });
46
+ var analytics_processor_1 = require("./processors/analytics.processor");
47
+ Object.defineProperty(exports, "AnalyticsProcessor", { enumerable: true, get: function () { return analytics_processor_1.AnalyticsProcessor; } });
48
+ var analytics_retention_cron_1 = require("./cron/analytics-retention.cron");
49
+ Object.defineProperty(exports, "AnalyticsRetentionCron", { enumerable: true, get: function () { return analytics_retention_cron_1.AnalyticsRetentionCron; } });
50
+ var analytics_config_interface_1 = require("./interfaces/analytics.config.interface");
51
+ Object.defineProperty(exports, "ANALYTICS_CONFIG", { enumerable: true, get: function () { return analytics_config_interface_1.ANALYTICS_CONFIG; } });
52
+ Object.defineProperty(exports, "ANALYTICS_QUEUE", { enumerable: true, get: function () { return analytics_config_interface_1.ANALYTICS_QUEUE; } });
53
+ Object.defineProperty(exports, "DEFAULT_ANALYTICS_CONFIG", { enumerable: true, get: function () { return analytics_config_interface_1.DEFAULT_ANALYTICS_CONFIG; } });
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/foundations/analytics/index.ts"],"names":[],"mappings":";;;AAAA,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AACxB,kEAIsC;AAFpC,+HAAA,0BAA0B,OAAA;AAG5B,4EAAyE;AAAhE,8HAAA,oBAAoB,OAAA;AAC7B,sEAIwC;AAFtC,kIAAA,2BAA2B,OAAA;AAG7B,gFAA4E;AAAnE,iIAAA,qBAAqB,OAAA;AAC9B,8EAI4C;AAF1C,0IAAA,+BAA+B,OAAA;AAGjC,wFAAoF;AAA3E,yIAAA,yBAAyB,OAAA;AAClC,kEAIsC;AAFpC,+HAAA,0BAA0B,OAAA;AAG5B,4EAAyE;AAAhE,8HAAA,oBAAoB,OAAA;AAC7B,oEAIuC;AAFrC,iIAAA,2BAA2B,OAAA;AAG7B,8EAA2E;AAAlE,gIAAA,qBAAqB,OAAA;AAC9B,sEAIwC;AAFtC,mIAAA,4BAA4B,OAAA;AAG9B,gFAA6E;AAApE,kIAAA,sBAAsB,OAAA;AAC/B,wEAAqE;AAA5D,0HAAA,kBAAkB,OAAA;AAC3B,4FAAyF;AAAhF,0IAAA,0BAA0B,OAAA;AACnC,gGAA4F;AAAnF,6IAAA,2BAA2B,OAAA;AACpC,wGAAoG;AAA3F,qJAAA,+BAA+B,OAAA;AACxC,wFAAqF;AAA5E,sIAAA,wBAAwB,OAAA;AACjC,wFAAoF;AAA3E,yIAAA,yBAAyB,OAAA;AAClC,kEAAgE;AAAvD,qHAAA,gBAAgB,OAAA;AACzB,8EAA2E;AAAlE,gIAAA,qBAAqB,OAAA;AAC9B,wEAAsE;AAA7D,yHAAA,kBAAkB,OAAA;AAC3B,4EAAyE;AAAhE,kIAAA,sBAAsB,OAAA;AAG/B,sFAKiD;AAH/C,8HAAA,gBAAgB,OAAA;AAChB,6HAAA,eAAe,OAAA;AACf,sIAAA,wBAAwB,OAAA"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Configuration interface for the AnalyticsModule.
3
+ *
4
+ * The normal way to configure analytics is the environment: `ANALYTICS_ENABLED`,
5
+ * `ANALYTICS_RETENTION_MONTHS` and `ANALYTICS_SESSION_TIMEOUT_MINUTES`, read
6
+ * through `baseConfig.analytics`. Values passed here are an override and win
7
+ * over the environment. With the variable unset and no override, nothing is
8
+ * registered: no controller, no queue and no processor.
9
+ */
10
+ export interface AnalyticsModuleConfig {
11
+ /**
12
+ * When true, the module registers the public event endpoint, the admin
13
+ * endpoints, the queue, the processor and the retention cron.
14
+ *
15
+ * Normally set through `ANALYTICS_ENABLED=true`; a value here overrides the
16
+ * environment. Default false: analytics collection is an app-visible
17
+ * behaviour change and must be opted into explicitly.
18
+ *
19
+ * @default false (env: ANALYTICS_ENABLED)
20
+ */
21
+ enabled?: boolean;
22
+ /**
23
+ * How many months raw sessions and page views are kept before the retention
24
+ * cron rolls them up into daily summaries and deletes them.
25
+ *
26
+ * @default 13 (env: ANALYTICS_RETENTION_MONTHS)
27
+ */
28
+ retentionMonths?: number;
29
+ /**
30
+ * Inactivity window after which the next event from the same visitor starts
31
+ * a new session.
32
+ *
33
+ * @default 30 (env: ANALYTICS_SESSION_TIMEOUT_MINUTES)
34
+ */
35
+ sessionTimeoutMinutes?: number;
36
+ /**
37
+ * BullMQ queue the producer (`AnalyticsService.track()`) enqueues onto.
38
+ *
39
+ * The module registers this queue itself (`BullModule.registerQueue`), so an
40
+ * app does not have to add it to its own queue configuration.
41
+ *
42
+ * NOTE: the worker side (`AnalyticsProcessor`) binds to `QueueId.ANALYTICS`
43
+ * through the `@Processor()` decorator, which BullMQ evaluates at class-decoration
44
+ * time and therefore cannot read from this config. Overriding `queueId` with a
45
+ * different value moves the producer only — the consuming app must then run its
46
+ * own worker for that queue. Every package processor has the same constraint
47
+ * (see `CompanyProcessor`, `HowToProcessor`, `ChunkProcessor`).
48
+ *
49
+ * @default QueueId.ANALYTICS ("analytics")
50
+ */
51
+ queueId?: string;
52
+ /**
53
+ * BullMQ job name used for the enqueue/dispatch handshake between
54
+ * `AnalyticsService.track()` and `AnalyticsProcessor.process()`.
55
+ *
56
+ * Both sides read this same value, so an app may rename it freely (e.g. to
57
+ * match its own `JobName` enum) as long as it is configured once here.
58
+ *
59
+ * @default "analytics:pageView"
60
+ */
61
+ jobName?: string;
62
+ }
63
+ /**
64
+ * Injection token for the resolved analytics configuration.
65
+ * Always resolves to a `Required<AnalyticsModuleConfig>` (defaults merged in).
66
+ */
67
+ export declare const ANALYTICS_CONFIG: unique symbol;
68
+ /**
69
+ * Injection token for the BullMQ queue the module was configured with.
70
+ *
71
+ * `@InjectQueue()` cannot be used directly because the queue name is only known
72
+ * at `forRoot()` time; the module aliases the configured BullMQ queue token onto
73
+ * this stable token instead.
74
+ */
75
+ export declare const ANALYTICS_QUEUE: unique symbol;
76
+ /**
77
+ * Default configuration values.
78
+ */
79
+ export declare const DEFAULT_ANALYTICS_CONFIG: Required<AnalyticsModuleConfig>;
80
+ //# sourceMappingURL=analytics.config.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.config.interface.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/interfaces/analytics.config.interface.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,eAA6B,CAAC;AAE3D;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,qBAAqB,CAMpE,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_ANALYTICS_CONFIG = exports.ANALYTICS_QUEUE = exports.ANALYTICS_CONFIG = void 0;
4
+ const queue_id_1 = require("../../../config/enums/queue.id");
5
+ /**
6
+ * Injection token for the resolved analytics configuration.
7
+ * Always resolves to a `Required<AnalyticsModuleConfig>` (defaults merged in).
8
+ */
9
+ exports.ANALYTICS_CONFIG = Symbol("ANALYTICS_CONFIG");
10
+ /**
11
+ * Injection token for the BullMQ queue the module was configured with.
12
+ *
13
+ * `@InjectQueue()` cannot be used directly because the queue name is only known
14
+ * at `forRoot()` time; the module aliases the configured BullMQ queue token onto
15
+ * this stable token instead.
16
+ */
17
+ exports.ANALYTICS_QUEUE = Symbol("ANALYTICS_QUEUE");
18
+ /**
19
+ * Default configuration values.
20
+ */
21
+ exports.DEFAULT_ANALYTICS_CONFIG = {
22
+ enabled: false,
23
+ retentionMonths: 13,
24
+ sessionTimeoutMinutes: 30,
25
+ queueId: queue_id_1.QueueId.ANALYTICS,
26
+ jobName: "analytics:pageView",
27
+ };
28
+ //# sourceMappingURL=analytics.config.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.config.interface.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/interfaces/analytics.config.interface.ts"],"names":[],"mappings":";;;AAAA,6DAAyD;AAqEzD;;;GAGG;AACU,QAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE3D;;;;;;GAMG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,wBAAwB,GAAoC;IACvE,OAAO,EAAE,KAAK;IACd,eAAe,EAAE,EAAE;IACnB,qBAAqB,EAAE,EAAE;IACzB,OAAO,EAAE,kBAAO,CAAC,SAAS;IAC1B,OAAO,EAAE,oBAAoB;CAC9B,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Input accepted by `AnalyticsService.track()` and queued as the BullMQ job
3
+ * payload consumed by `AnalyticsProcessor`.
4
+ *
5
+ * `clientIp` and `userAgent` travel only as far as the worker: they are hashed
6
+ * into the daily visitor id and classified into a `deviceType`, then discarded.
7
+ * Neither ever reaches Neo4j.
8
+ */
9
+ export interface AnalyticsPageViewInput {
10
+ path: string;
11
+ section: "public" | "app";
12
+ referrer?: string;
13
+ utmSource?: string;
14
+ utmMedium?: string;
15
+ utmCampaign?: string;
16
+ utmTerm?: string;
17
+ utmContent?: string;
18
+ /** UUID from the consent cookie; absent when the visitor has not consented. */
19
+ visitorId?: string;
20
+ screenWidth?: number;
21
+ /** First `X-Forwarded-For` hop or `request.ip`. Hashed in the worker, never stored. */
22
+ clientIp: string;
23
+ /** Hashed and classified in the worker, never stored. */
24
+ userAgent: string;
25
+ /** Set by `OptionalJwtAuthGuard` when the request carries a valid token. */
26
+ userId?: string;
27
+ /** ISO instant set by the controller when the request arrived. */
28
+ receivedAt: string;
29
+ }
30
+ //# sourceMappingURL=analytics.page-view.input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.page-view.input.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/interfaces/analytics.page-view.input.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=analytics.page-view.input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.page-view.input.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/interfaces/analytics.page-view.input.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Input accepted by `AnalyticsSessionRepository.recordPageView()`.
3
+ *
4
+ * Built by `AnalyticsProcessor` from an `AnalyticsPageViewInput` once the
5
+ * visitor id is resolved, the route normalised and the user agent reduced to a
6
+ * `deviceType`. Optional values are `null` rather than `undefined` so they can
7
+ * be bound straight into Cypher parameters.
8
+ */
9
+ export interface AnalyticsResolvedPageView {
10
+ /** `c:<uuid>` from the consent cookie or `d:<sha256>` daily hash. */
11
+ visitorId: string;
12
+ consented: boolean;
13
+ path: string;
14
+ /** `path` with UUID segments replaced by `:id`. */
15
+ route: string;
16
+ section: "public" | "app";
17
+ /** Hostname of the external referrer, `null` for internal or missing referrers. */
18
+ referrerHost: string | null;
19
+ utmSource: string | null;
20
+ utmMedium: string | null;
21
+ utmCampaign: string | null;
22
+ utmTerm: string | null;
23
+ utmContent: string | null;
24
+ deviceType: string;
25
+ userId: string | null;
26
+ /** ISO instant; becomes the page view's `createdAt` and the session's `lastSeenAt`. */
27
+ receivedAt: string;
28
+ sessionTimeoutMinutes: number;
29
+ }
30
+ //# sourceMappingURL=analytics.resolved-page-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.resolved-page-view.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/interfaces/analytics.resolved-page-view.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC1B,mFAAmF;IACnF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uFAAuF;IACvF,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,MAAM,CAAC;CAC/B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=analytics.resolved-page-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.resolved-page-view.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/interfaces/analytics.resolved-page-view.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import { WorkerHost } from "@nestjs/bullmq";
2
+ import { Job } from "bullmq";
3
+ import { ClsService } from "nestjs-cls";
4
+ import { AppLoggingService } from "../../../core/logging/services/logging.service";
5
+ import { AnalyticsModuleConfig } from "../interfaces/analytics.config.interface";
6
+ import { AnalyticsPageViewInput } from "../interfaces/analytics.page-view.input";
7
+ import { AnalyticsSessionRepository } from "../repositories/analytics-session.repository";
8
+ import { AnalyticsVisitorIdService } from "../services/analytics.visitor-id.service";
9
+ /**
10
+ * Worker-side of `AnalyticsService.track()`.
11
+ *
12
+ * The queue name must be a compile-time constant because `@Processor()` is
13
+ * evaluated at class-decoration time — the same constraint every other package
14
+ * processor lives with (CompanyProcessor, HowToProcessor, ChunkProcessor). The
15
+ * job name, by contrast, is read from `ANALYTICS_CONFIG` at construction
16
+ * time, so producer and consumer always agree on it.
17
+ *
18
+ * Concurrency 1 so two events from one visitor can never both create a session.
19
+ */
20
+ export declare class AnalyticsProcessor extends WorkerHost {
21
+ private readonly logger;
22
+ private readonly repository;
23
+ private readonly visitorIds;
24
+ private readonly cls;
25
+ private readonly jobName;
26
+ private readonly sessionTimeoutMinutes;
27
+ constructor(logger: AppLoggingService, repository: AnalyticsSessionRepository, visitorIds: AnalyticsVisitorIdService, cls: ClsService, config: Required<AnalyticsModuleConfig>);
28
+ onError(job: Job): void;
29
+ process(job: Job<AnalyticsPageViewInput>): Promise<void>;
30
+ private normaliseRoute;
31
+ private referrerHost;
32
+ }
33
+ //# sourceMappingURL=analytics.processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.processor.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/processors/analytics.processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,EAAoB,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAEjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AAC1F,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAQrF;;;;;;;;;;GAUG;AACH,qBACa,kBAAmB,SAAQ,UAAU;IAK9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAPtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;gBAG5B,MAAM,EAAE,iBAAiB,EACzB,UAAU,EAAE,0BAA0B,EACtC,UAAU,EAAE,yBAAyB,EACrC,GAAG,EAAE,UAAU,EACN,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC;IAQnE,OAAO,CAAC,GAAG,EAAE,GAAG;IAIV,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD9D,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;CAQrB"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AnalyticsProcessor = void 0;
16
+ const bullmq_1 = require("@nestjs/bullmq");
17
+ const common_1 = require("@nestjs/common");
18
+ const bullmq_2 = require("bullmq");
19
+ const nestjs_cls_1 = require("nestjs-cls");
20
+ const queue_id_1 = require("../../../config/enums/queue.id");
21
+ const logging_service_1 = require("../../../core/logging/services/logging.service");
22
+ const analytics_config_interface_1 = require("../interfaces/analytics.config.interface");
23
+ const analytics_session_repository_1 = require("../repositories/analytics-session.repository");
24
+ const analytics_visitor_id_service_1 = require("../services/analytics.visitor-id.service");
25
+ /**
26
+ * UUID v1–v5 path segment. Same regex as the web helper
27
+ * (`nextjs-jsonapi/src/features/analytics/lib/routeNormaliser.ts`).
28
+ */
29
+ const UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
30
+ /**
31
+ * Worker-side of `AnalyticsService.track()`.
32
+ *
33
+ * The queue name must be a compile-time constant because `@Processor()` is
34
+ * evaluated at class-decoration time — the same constraint every other package
35
+ * processor lives with (CompanyProcessor, HowToProcessor, ChunkProcessor). The
36
+ * job name, by contrast, is read from `ANALYTICS_CONFIG` at construction
37
+ * time, so producer and consumer always agree on it.
38
+ *
39
+ * Concurrency 1 so two events from one visitor can never both create a session.
40
+ */
41
+ let AnalyticsProcessor = class AnalyticsProcessor extends bullmq_1.WorkerHost {
42
+ constructor(logger, repository, visitorIds, cls, config) {
43
+ super();
44
+ this.logger = logger;
45
+ this.repository = repository;
46
+ this.visitorIds = visitorIds;
47
+ this.cls = cls;
48
+ this.jobName = config.jobName;
49
+ this.sessionTimeoutMinutes = config.sessionTimeoutMinutes;
50
+ }
51
+ onError(job) {
52
+ this.logger.error(`Analytics pageView failed (jobId=${job.id}): ${job.failedReason ?? "unknown"}`);
53
+ }
54
+ async process(job) {
55
+ if (job.name !== this.jobName) {
56
+ throw new Error(`Job ${job.name} not handled by AnalyticsProcessor`);
57
+ }
58
+ const input = job.data;
59
+ if (this.visitorIds.isBot(input.userAgent)) {
60
+ this.logger.debug(`analytics pageView dropped reason=bot path=${input.path}`);
61
+ return;
62
+ }
63
+ // The worker runs outside any HTTP request, so CLS is empty: seed it
64
+ // explicitly or SecurityService has no context to work from.
65
+ await this.cls.run(async () => {
66
+ this.cls.set("isAutomatedJob", true);
67
+ const { visitorId, consented } = await this.visitorIds.resolve({
68
+ visitorId: input.visitorId,
69
+ clientIp: input.clientIp,
70
+ userAgent: input.userAgent,
71
+ receivedAt: input.receivedAt,
72
+ });
73
+ const resolved = {
74
+ visitorId,
75
+ consented,
76
+ path: input.path,
77
+ route: this.normaliseRoute(input.path),
78
+ section: input.section,
79
+ referrerHost: this.referrerHost(input.referrer),
80
+ utmSource: input.utmSource ?? null,
81
+ utmMedium: input.utmMedium ?? null,
82
+ utmCampaign: input.utmCampaign ?? null,
83
+ utmTerm: input.utmTerm ?? null,
84
+ utmContent: input.utmContent ?? null,
85
+ deviceType: this.visitorIds.deviceType(input.userAgent),
86
+ userId: input.userId ?? null,
87
+ receivedAt: input.receivedAt,
88
+ sessionTimeoutMinutes: this.sessionTimeoutMinutes,
89
+ };
90
+ const { sessionId, created } = await this.repository.recordPageView(resolved);
91
+ this.logger.debug(`analytics pageView visitor=${visitorId} session=${sessionId} created=${created}`);
92
+ });
93
+ }
94
+ normaliseRoute(path) {
95
+ return path
96
+ .split("/")
97
+ .map((segment) => (UUID_SEGMENT.test(segment) ? ":id" : segment))
98
+ .join("/");
99
+ }
100
+ referrerHost(referrer) {
101
+ if (!referrer)
102
+ return null;
103
+ try {
104
+ return new URL(referrer).hostname || null;
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ }
110
+ };
111
+ exports.AnalyticsProcessor = AnalyticsProcessor;
112
+ __decorate([
113
+ (0, bullmq_1.OnWorkerEvent)("failed"),
114
+ __metadata("design:type", Function),
115
+ __metadata("design:paramtypes", [bullmq_2.Job]),
116
+ __metadata("design:returntype", void 0)
117
+ ], AnalyticsProcessor.prototype, "onError", null);
118
+ exports.AnalyticsProcessor = AnalyticsProcessor = __decorate([
119
+ (0, bullmq_1.Processor)(queue_id_1.QueueId.ANALYTICS, { concurrency: 1 }),
120
+ __param(4, (0, common_1.Inject)(analytics_config_interface_1.ANALYTICS_CONFIG)),
121
+ __metadata("design:paramtypes", [logging_service_1.AppLoggingService,
122
+ analytics_session_repository_1.AnalyticsSessionRepository,
123
+ analytics_visitor_id_service_1.AnalyticsVisitorIdService,
124
+ nestjs_cls_1.ClsService, Object])
125
+ ], AnalyticsProcessor);
126
+ //# sourceMappingURL=analytics.processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.processor.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/processors/analytics.processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { ClsService } from "nestjs-cls";
2
+ import { AbstractRepository } from "../../../core/neo4j/abstracts/abstract.repository";
3
+ import { Neo4jService } from "../../../core/neo4j/services/neo4j.service";
4
+ import { SecurityService } from "../../../core/security/services/security.service";
5
+ import { AnalyticsDailySummary, AnalyticsDailySummaryDescriptor } from "../entities/analytics-daily-summary";
6
+ /**
7
+ * Daily roll-ups written by the retention job before a day's raw sessions and
8
+ * page views are deleted. Platform-level, written outside HTTP/CLS context.
9
+ *
10
+ * The aggregate reads RETURN scalar columns, not graph nodes, so
11
+ * readOne()/readMany() cannot map them; they read the columns off the driver
12
+ * result, the same shape and rationale as TokenUsageAdminRepository.
13
+ */
14
+ export declare class AnalyticsDailySummaryRepository extends AbstractRepository<AnalyticsDailySummary, typeof AnalyticsDailySummaryDescriptor.relationships> {
15
+ protected readonly descriptor: import("../../..").EntityDescriptor<AnalyticsDailySummary, {}>;
16
+ constructor(neo4j: Neo4jService, securityService: SecurityService, clsService: ClsService);
17
+ /** Adds the (date, dimension) index on top of the id constraint AbstractRepository creates from the descriptor. */
18
+ onModuleInit(): Promise<void>;
19
+ /**
20
+ * MERGEs one row per (section, dimension, key) for the sessions that started
21
+ * on `date`: `total` plus source, medium, campaign, referrer and landing from
22
+ * the sessions, and route from their page views. Sessions without a value for
23
+ * a dimension (no UTM, no external referrer) are written under the key
24
+ * '(none)', the same key AnalyticsAdminRepository's breakdown uses for raw
25
+ * rows, so raw and summarised rows merge.
26
+ *
27
+ * Every property is set ON CREATE only, so an existing row is never
28
+ * overwritten. That keeps a re-run idempotent after a crash part-way through
29
+ * the raw delete: the next night's rollup sees only the sessions that
30
+ * survived, and a plain SET would replace the stored totals with those
31
+ * smaller counts.
32
+ * Returns the number of rows written.
33
+ */
34
+ rollupDay(params: {
35
+ date: string;
36
+ }): Promise<number>;
37
+ }
38
+ //# sourceMappingURL=analytics-daily-summary.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-daily-summary.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/repositories/analytics-daily-summary.repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,kDAAkD,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AA4B7G;;;;;;;GAOG;AACH,qBACa,+BAAgC,SAAQ,kBAAkB,CACrE,qBAAqB,EACrB,OAAO,+BAA+B,CAAC,aAAa,CACrD;IACC,SAAS,CAAC,QAAQ,CAAC,UAAU,iEAAmC;gBAEpD,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU;IAIzF,mHAAmH;IACpG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5C;;;;;;;;;;;;;;OAcG;IACG,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA6E3D"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AnalyticsDailySummaryRepository = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const nestjs_cls_1 = require("nestjs-cls");
15
+ const abstract_repository_1 = require("../../../core/neo4j/abstracts/abstract.repository");
16
+ const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
17
+ const security_service_1 = require("../../../core/security/services/security.service");
18
+ const analytics_daily_summary_1 = require("../entities/analytics-daily-summary");
19
+ const analytics_page_view_meta_1 = require("../entities/analytics-page-view.meta");
20
+ const analytics_session_meta_1 = require("../entities/analytics-session.meta");
21
+ const toNumber = (v) => {
22
+ if (v === null || v === undefined)
23
+ return 0;
24
+ if (typeof v === "number")
25
+ return v;
26
+ if (typeof v.toNumber === "function")
27
+ return v.toNumber();
28
+ return Number(v) || 0;
29
+ };
30
+ const S = analytics_session_meta_1.analyticsSessionMeta.nodeName; // "analyticsSession"
31
+ const PV = analytics_page_view_meta_1.analyticsPageViewMeta.nodeName; // "analyticsPageView"
32
+ /** Key for a session with no value for a dimension; must match AnalyticsAdminRepository's coalesce. */
33
+ const NONE_KEY = "(none)";
34
+ /**
35
+ * Daily roll-ups written by the retention job before a day's raw sessions and
36
+ * page views are deleted. Platform-level, written outside HTTP/CLS context.
37
+ *
38
+ * The aggregate reads RETURN scalar columns, not graph nodes, so
39
+ * readOne()/readMany() cannot map them; they read the columns off the driver
40
+ * result, the same shape and rationale as TokenUsageAdminRepository.
41
+ */
42
+ let AnalyticsDailySummaryRepository = class AnalyticsDailySummaryRepository extends abstract_repository_1.AbstractRepository {
43
+ constructor(neo4j, securityService, clsService) {
44
+ super(neo4j, securityService, clsService);
45
+ this.descriptor = analytics_daily_summary_1.AnalyticsDailySummaryDescriptor;
46
+ }
47
+ /** Adds the (date, dimension) index on top of the id constraint AbstractRepository creates from the descriptor. */
48
+ async onModuleInit() {
49
+ await super.onModuleInit();
50
+ const { nodeName, labelName } = this.descriptor.model;
51
+ await this.neo4j.writeOne({
52
+ query: `CREATE INDEX ${nodeName}_date_dimension IF NOT EXISTS FOR (${nodeName}:${labelName}) ON (${nodeName}.date, ${nodeName}.dimension)`,
53
+ });
54
+ }
55
+ /**
56
+ * MERGEs one row per (section, dimension, key) for the sessions that started
57
+ * on `date`: `total` plus source, medium, campaign, referrer and landing from
58
+ * the sessions, and route from their page views. Sessions without a value for
59
+ * a dimension (no UTM, no external referrer) are written under the key
60
+ * '(none)', the same key AnalyticsAdminRepository's breakdown uses for raw
61
+ * rows, so raw and summarised rows merge.
62
+ *
63
+ * Every property is set ON CREATE only, so an existing row is never
64
+ * overwritten. That keeps a re-run idempotent after a crash part-way through
65
+ * the raw delete: the next night's rollup sees only the sessions that
66
+ * survived, and a plain SET would replace the stored totals with those
67
+ * smaller counts.
68
+ * Returns the number of rows written.
69
+ */
70
+ async rollupDay(params) {
71
+ const sessionResult = await this.neo4j.read(`
72
+ MATCH (${S}:${analytics_session_meta_1.analyticsSessionMeta.labelName})
73
+ WHERE date(${S}.startedAt) = date($date)
74
+ UNWIND [
75
+ ['total', ''],
76
+ ['source', coalesce(${S}.utmSource, $noneKey)],
77
+ ['medium', coalesce(${S}.utmMedium, $noneKey)],
78
+ ['campaign', coalesce(${S}.utmCampaign, $noneKey)],
79
+ ['referrer', coalesce(${S}.referrerHost, $noneKey)],
80
+ ['landing', coalesce(${S}.landingRoute, $noneKey)]
81
+ ] AS pair
82
+ WITH ${S}, pair[0] AS dimension, pair[1] AS key
83
+ RETURN ${S}.section AS section,
84
+ dimension,
85
+ key,
86
+ count(DISTINCT ${S}.visitorId) AS visitors,
87
+ count(DISTINCT ${S}) AS sessions,
88
+ sum(${S}.pageViews) AS pageViews
89
+ `, { date: params.date, noneKey: NONE_KEY });
90
+ const pageViewResult = await this.neo4j.read(`
91
+ MATCH (${PV}:${analytics_page_view_meta_1.analyticsPageViewMeta.labelName})-[:IN_SESSION]->(${S}:${analytics_session_meta_1.analyticsSessionMeta.labelName})
92
+ WHERE date(${S}.startedAt) = date($date)
93
+ RETURN ${PV}.section AS section,
94
+ 'route' AS dimension,
95
+ ${PV}.route AS key,
96
+ count(DISTINCT ${S}.visitorId) AS visitors,
97
+ count(DISTINCT ${S}) AS sessions,
98
+ count(${PV}) AS pageViews
99
+ `, { date: params.date });
100
+ const rows = [...sessionResult.records, ...pageViewResult.records].map((r) => {
101
+ const section = r.get("section");
102
+ const dimension = r.get("dimension");
103
+ const key = r.get("key") ?? "";
104
+ return {
105
+ id: `${params.date}|${section}|${dimension}|${key}`,
106
+ section,
107
+ dimension,
108
+ key,
109
+ visitors: toNumber(r.get("visitors")),
110
+ sessions: toNumber(r.get("sessions")),
111
+ pageViews: toNumber(r.get("pageViews")),
112
+ };
113
+ });
114
+ if (rows.length === 0)
115
+ return 0;
116
+ const { nodeName, labelName } = this.descriptor.model;
117
+ const query = this.neo4j.initQuery();
118
+ query.queryParams = { ...query.queryParams, date: params.date, rows };
119
+ query.query = `
120
+ UNWIND $rows AS row
121
+ MERGE (${nodeName}:${labelName} {id: row.id})
122
+ ON CREATE SET
123
+ ${nodeName}.date = date(left($date, 10)),
124
+ ${nodeName}.section = row.section,
125
+ ${nodeName}.dimension = row.dimension,
126
+ ${nodeName}.key = row.key,
127
+ ${nodeName}.visitors = row.visitors,
128
+ ${nodeName}.sessions = row.sessions,
129
+ ${nodeName}.pageViews = row.pageViews,
130
+ ${nodeName}.createdAt = datetime(),
131
+ ${nodeName}.updatedAt = datetime()
132
+ `;
133
+ await this.neo4j.writeOne(query);
134
+ return rows.length;
135
+ }
136
+ };
137
+ exports.AnalyticsDailySummaryRepository = AnalyticsDailySummaryRepository;
138
+ exports.AnalyticsDailySummaryRepository = AnalyticsDailySummaryRepository = __decorate([
139
+ (0, common_1.Injectable)(),
140
+ __metadata("design:paramtypes", [neo4j_service_1.Neo4jService, security_service_1.SecurityService, nestjs_cls_1.ClsService])
141
+ ], AnalyticsDailySummaryRepository);
142
+ //# sourceMappingURL=analytics-daily-summary.repository.js.map