@carlonicora/nestjs-neo4jsonapi 4.13.0 → 4.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
- package/dist/bootstrap/app.module.factory.js +1 -0
- package/dist/bootstrap/app.module.factory.js.map +1 -1
- package/dist/bootstrap/bootstrap.options.d.ts +22 -0
- package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
- package/dist/config/base.config.d.ts.map +1 -1
- package/dist/config/base.config.js +5 -0
- package/dist/config/base.config.js.map +1 -1
- package/dist/config/enums/queue.id.d.ts +1 -0
- package/dist/config/enums/queue.id.d.ts.map +1 -1
- package/dist/config/enums/queue.id.js +1 -0
- package/dist/config/enums/queue.id.js.map +1 -1
- package/dist/config/interfaces/base.config.interface.d.ts +2 -0
- package/dist/config/interfaces/base.config.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.analytics.interface.d.ts +13 -0
- package/dist/config/interfaces/config.analytics.interface.d.ts.map +1 -0
- package/dist/config/interfaces/config.analytics.interface.js +3 -0
- package/dist/config/interfaces/config.analytics.interface.js.map +1 -0
- package/dist/config/interfaces/index.d.ts +1 -0
- package/dist/config/interfaces/index.d.ts.map +1 -1
- package/dist/config/interfaces/index.js +1 -0
- package/dist/config/interfaces/index.js.map +1 -1
- package/dist/foundations/analytics/analytics.module.d.ts +39 -0
- package/dist/foundations/analytics/analytics.module.d.ts.map +1 -0
- package/dist/foundations/analytics/analytics.module.js +122 -0
- package/dist/foundations/analytics/analytics.module.js.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts +32 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.js +197 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.js.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.controller.d.ts +29 -0
- package/dist/foundations/analytics/controllers/analytics.controller.d.ts.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.controller.js +85 -0
- package/dist/foundations/analytics/controllers/analytics.controller.js.map +1 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.d.ts +13 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.d.ts.map +1 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.js +61 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.js.map +1 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.d.ts +21 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.d.ts.map +1 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.js +105 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.d.ts +17 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.js +18 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.d.ts +30 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.js +28 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.d.ts +8 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.js +15 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.d.ts +39 -0
- package/dist/foundations/analytics/entities/analytics-page-view.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.js +38 -0
- package/dist/foundations/analytics/entities/analytics-page-view.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.d.ts +52 -0
- package/dist/foundations/analytics/entities/analytics-session.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.js +47 -0
- package/dist/foundations/analytics/entities/analytics-session.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.d.ts +24 -0
- package/dist/foundations/analytics/entities/analytics-summary.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.js +20 -0
- package/dist/foundations/analytics/entities/analytics-summary.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.d.ts +20 -0
- package/dist/foundations/analytics/entities/analytics-timeline.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.js +18 -0
- package/dist/foundations/analytics/entities/analytics-timeline.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.js.map +1 -0
- package/dist/foundations/analytics/index.d.ts +27 -0
- package/dist/foundations/analytics/index.d.ts.map +1 -0
- package/dist/foundations/analytics/index.js +54 -0
- package/dist/foundations/analytics/index.js.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.d.ts +80 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.d.ts.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.js +28 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.js.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.d.ts +30 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.d.ts.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.js +3 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.js.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.d.ts +30 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.d.ts.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.js +3 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.js.map +1 -0
- package/dist/foundations/analytics/processors/analytics.processor.d.ts +33 -0
- package/dist/foundations/analytics/processors/analytics.processor.d.ts.map +1 -0
- package/dist/foundations/analytics/processors/analytics.processor.js +126 -0
- package/dist/foundations/analytics/processors/analytics.processor.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.d.ts +38 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.js +142 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.d.ts +30 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.js +62 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.d.ts +87 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.js +261 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.d.ts +145 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.js +490 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.js.map +1 -0
- package/dist/foundations/analytics/services/analytics.admin.service.d.ts +74 -0
- package/dist/foundations/analytics/services/analytics.admin.service.d.ts.map +1 -0
- package/dist/foundations/analytics/services/analytics.admin.service.js +126 -0
- package/dist/foundations/analytics/services/analytics.admin.service.js.map +1 -0
- package/dist/foundations/analytics/services/analytics.service.d.ts +31 -0
- package/dist/foundations/analytics/services/analytics.service.d.ts.map +1 -0
- package/dist/foundations/analytics/services/analytics.service.js +57 -0
- package/dist/foundations/analytics/services/analytics.service.js.map +1 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.d.ts +34 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.d.ts.map +1 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.js +93 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.js.map +1 -0
- package/dist/foundations/foundations.modules.d.ts +3 -0
- package/dist/foundations/foundations.modules.d.ts.map +1 -1
- package/dist/foundations/foundations.modules.js +3 -1
- package/dist/foundations/foundations.modules.js.map +1 -1
- package/dist/foundations/index.d.ts +1 -0
- package/dist/foundations/index.d.ts.map +1 -1
- package/dist/foundations/index.js +1 -0
- package/dist/foundations/index.js.map +1 -1
- package/dist/foundations/s3/services/s3.service.d.ts +1 -0
- package/dist/foundations/s3/services/s3.service.d.ts.map +1 -1
- package/dist/foundations/s3/services/s3.service.js +10 -3
- package/dist/foundations/s3/services/s3.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-daily-summary.repository.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/repositories/analytics-daily-summary.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAAwC;AACxC,2FAAuF;AACvF,8EAA0E;AAC1E,uFAAmF;AACnF,iFAA6G;AAC7G,mFAA6E;AAC7E,+EAA0E;AAY1E,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAU,EAAE;IACtC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IACpC,IAAI,OAAQ,CAAiC,CAAC,QAAQ,KAAK,UAAU;QACnE,OAAQ,CAAgC,CAAC,QAAQ,EAAE,CAAC;IACtD,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,GAAG,6CAAoB,CAAC,QAAQ,CAAC,CAAC,qBAAqB;AAC9D,MAAM,EAAE,GAAG,gDAAqB,CAAC,QAAQ,CAAC,CAAC,sBAAsB;AAEjE,uGAAuG;AACvG,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAE1B;;;;;;;GAOG;AAEI,IAAM,+BAA+B,GAArC,MAAM,+BAAgC,SAAQ,wCAGpD;IAGC,YAAY,KAAmB,EAAE,eAAgC,EAAE,UAAsB;QACvF,KAAK,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;QAHzB,eAAU,GAAG,yDAA+B,CAAC;IAIhE,CAAC;IAED,mHAAmH;IAC1G,KAAK,CAAC,YAAY;QACzB,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;QAE3B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAEtD,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACxB,KAAK,EAAE,gBAAgB,QAAQ,sCAAsC,QAAQ,IAAI,SAAS,SAAS,QAAQ,UAAU,QAAQ,aAAa;SAC3I,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,SAAS,CAAC,MAAwB;QACtC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CACzC;iBACW,CAAC,IAAI,6CAAoB,CAAC,SAAS;qBAC/B,CAAC;;;gCAGU,CAAC;gCACD,CAAC;kCACC,CAAC;kCACD,CAAC;iCACF,CAAC;;eAEnB,CAAC;iBACC,CAAC;;;2BAGS,CAAC;2BACD,CAAC;gBACZ,CAAC;OACV,EACD,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CACzC,CAAC;QAEF,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAC1C;iBACW,EAAE,IAAI,gDAAqB,CAAC,SAAS,qBAAqB,CAAC,IAAI,6CAAoB,CAAC,SAAS;qBACzF,CAAC;iBACL,EAAE;;YAEP,EAAE;2BACa,CAAC;2BACD,CAAC;kBACV,EAAE;OACb,EACD,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CACtB,CAAC;QAEF,MAAM,IAAI,GAAiB,CAAC,GAAG,aAAa,CAAC,OAAO,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;YAC9F,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAW,CAAC;YAC3C,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAW,CAAC;YAC/C,MAAM,GAAG,GAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAY,IAAI,EAAE,CAAC;YAC3C,OAAO;gBACL,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,IAAI,SAAS,IAAI,GAAG,EAAE;gBACnD,OAAO;gBACP,SAAS;gBACT,GAAG;gBACH,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACrC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACrC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;aACxC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEhC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACrC,KAAK,CAAC,WAAW,GAAG,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACtE,KAAK,CAAC,KAAK,GAAG;;eAEH,QAAQ,IAAI,SAAS;;UAE1B,QAAQ;UACR,QAAQ;UACR,QAAQ;UACR,QAAQ;UACR,QAAQ;UACR,QAAQ;UACR,QAAQ;UACR,QAAQ;UACR,QAAQ;KACb,CAAC;QAEF,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEjC,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF,CAAA;AAjHY,0EAA+B;0CAA/B,+BAA+B;IAD3C,IAAA,mBAAU,GAAE;qCAOQ,4BAAY,EAAmB,kCAAe,EAAc,uBAAU;GAN9E,+BAA+B,CAiH3C"}
|
|
@@ -0,0 +1,30 @@
|
|
|
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 { AnalyticsPageView, AnalyticsPageViewDescriptor } from "../entities/analytics-page-view";
|
|
6
|
+
/**
|
|
7
|
+
* Page views are created by AnalyticsSessionRepository.recordPageView() in the
|
|
8
|
+
* same transaction as their session; this repository only owns the createdAt
|
|
9
|
+
* index and the per-session journey read.
|
|
10
|
+
*/
|
|
11
|
+
export declare class AnalyticsPageViewRepository extends AbstractRepository<AnalyticsPageView, typeof AnalyticsPageViewDescriptor.relationships> {
|
|
12
|
+
protected readonly descriptor: import("../../..").EntityDescriptor<AnalyticsPageView, {
|
|
13
|
+
session: {
|
|
14
|
+
model: import("../../..").DataMeta;
|
|
15
|
+
direction: "out";
|
|
16
|
+
relationship: string;
|
|
17
|
+
cardinality: "one";
|
|
18
|
+
required: true;
|
|
19
|
+
dtoKey: string;
|
|
20
|
+
};
|
|
21
|
+
}>;
|
|
22
|
+
constructor(neo4j: Neo4jService, securityService: SecurityService, clsService: ClsService);
|
|
23
|
+
/** Adds the createdAt index on top of the id constraint AbstractRepository creates from the descriptor. */
|
|
24
|
+
onModuleInit(): Promise<void>;
|
|
25
|
+
/** Every page view of one session, in the order they were visited. */
|
|
26
|
+
findBySession(params: {
|
|
27
|
+
sessionId: string;
|
|
28
|
+
}): Promise<AnalyticsPageView[]>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=analytics-page-view.repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-page-view.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/repositories/analytics-page-view.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,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAGjG;;;;GAIG;AACH,qBACa,2BAA4B,SAAQ,kBAAkB,CACjE,iBAAiB,EACjB,OAAO,2BAA2B,CAAC,aAAa,CACjD;IACC,SAAS,CAAC,QAAQ,CAAC,UAAU;;;;;;;;;OAA+B;gBAEhD,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU;IAIzF,2GAA2G;IAC5F,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5C,sEAAsE;IAChE,aAAa,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAoBjF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
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.AnalyticsPageViewRepository = 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_page_view_1 = require("../entities/analytics-page-view");
|
|
19
|
+
const analytics_session_meta_1 = require("../entities/analytics-session.meta");
|
|
20
|
+
/**
|
|
21
|
+
* Page views are created by AnalyticsSessionRepository.recordPageView() in the
|
|
22
|
+
* same transaction as their session; this repository only owns the createdAt
|
|
23
|
+
* index and the per-session journey read.
|
|
24
|
+
*/
|
|
25
|
+
let AnalyticsPageViewRepository = class AnalyticsPageViewRepository extends abstract_repository_1.AbstractRepository {
|
|
26
|
+
constructor(neo4j, securityService, clsService) {
|
|
27
|
+
super(neo4j, securityService, clsService);
|
|
28
|
+
this.descriptor = analytics_page_view_1.AnalyticsPageViewDescriptor;
|
|
29
|
+
}
|
|
30
|
+
/** Adds the createdAt index on top of the id constraint AbstractRepository creates from the descriptor. */
|
|
31
|
+
async onModuleInit() {
|
|
32
|
+
await super.onModuleInit();
|
|
33
|
+
const { nodeName, labelName } = this.descriptor.model;
|
|
34
|
+
await this.neo4j.writeOne({
|
|
35
|
+
query: `CREATE INDEX ${nodeName}_createdAt IF NOT EXISTS FOR (${nodeName}:${labelName}) ON (${nodeName}.createdAt)`,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/** Every page view of one session, in the order they were visited. */
|
|
39
|
+
async findBySession(params) {
|
|
40
|
+
const { nodeName } = this.descriptor.model;
|
|
41
|
+
const query = this.neo4j.initQuery({ serialiser: this.descriptor.model });
|
|
42
|
+
query.queryParams = {
|
|
43
|
+
...query.queryParams,
|
|
44
|
+
sessionId: params.sessionId,
|
|
45
|
+
...this.getPolyLabelParams(),
|
|
46
|
+
};
|
|
47
|
+
query.query += `
|
|
48
|
+
${this.buildDefaultMatch()}
|
|
49
|
+
MATCH (${nodeName})-[:IN_SESSION]->(:${analytics_session_meta_1.analyticsSessionMeta.labelName} {id: $sessionId})
|
|
50
|
+
WITH ${nodeName}
|
|
51
|
+
${this.buildReturnStatement()}
|
|
52
|
+
ORDER BY ${nodeName}.createdAt ASC
|
|
53
|
+
`;
|
|
54
|
+
return this.neo4j.readMany(query);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
exports.AnalyticsPageViewRepository = AnalyticsPageViewRepository;
|
|
58
|
+
exports.AnalyticsPageViewRepository = AnalyticsPageViewRepository = __decorate([
|
|
59
|
+
(0, common_1.Injectable)(),
|
|
60
|
+
__metadata("design:paramtypes", [neo4j_service_1.Neo4jService, security_service_1.SecurityService, nestjs_cls_1.ClsService])
|
|
61
|
+
], AnalyticsPageViewRepository);
|
|
62
|
+
//# sourceMappingURL=analytics-page-view.repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-page-view.repository.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/repositories/analytics-page-view.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAAwC;AACxC,2FAAuF;AACvF,8EAA0E;AAC1E,uFAAmF;AACnF,yEAAiG;AACjG,+EAA0E;AAE1E;;;;GAIG;AAEI,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,wCAGhD;IAGC,YAAY,KAAmB,EAAE,eAAgC,EAAE,UAAsB;QACvF,KAAK,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;QAHzB,eAAU,GAAG,iDAA2B,CAAC;IAI5D,CAAC;IAED,2GAA2G;IAClG,KAAK,CAAC,YAAY;QACzB,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;QAE3B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAEtD,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACxB,KAAK,EAAE,gBAAgB,QAAQ,iCAAiC,QAAQ,IAAI,SAAS,SAAS,QAAQ,aAAa;SACpH,CAAC,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,aAAa,CAAC,MAA6B;QAC/C,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAE1E,KAAK,CAAC,WAAW,GAAG;YAClB,GAAG,KAAK,CAAC,WAAW;YACpB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,GAAG,IAAI,CAAC,kBAAkB,EAAE;SAC7B,CAAC;QAEF,KAAK,CAAC,KAAK,IAAI;QACX,IAAI,CAAC,iBAAiB,EAAE;eACjB,QAAQ,sBAAsB,6CAAoB,CAAC,SAAS;aAC9D,QAAQ;QACb,IAAI,CAAC,oBAAoB,EAAE;iBAClB,QAAQ;KACpB,CAAC;QAEF,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;CACF,CAAA;AA1CY,kEAA2B;sCAA3B,2BAA2B;IADvC,IAAA,mBAAU,GAAE;qCAOQ,4BAAY,EAAmB,kCAAe,EAAc,uBAAU;GAN9E,2BAA2B,CA0CvC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ClsService } from "nestjs-cls";
|
|
2
|
+
import { JsonApiCursorInterface } from "../../../core/jsonapi/interfaces/jsonapi.cursor.interface";
|
|
3
|
+
import { AbstractRepository } from "../../../core/neo4j/abstracts/abstract.repository";
|
|
4
|
+
import { Neo4jService } from "../../../core/neo4j/services/neo4j.service";
|
|
5
|
+
import { SecurityService } from "../../../core/security/services/security.service";
|
|
6
|
+
import { AnalyticsSession, AnalyticsSessionDescriptor } from "../entities/analytics-session";
|
|
7
|
+
import { AnalyticsResolvedPageView } from "../interfaces/analytics.resolved-page-view";
|
|
8
|
+
/**
|
|
9
|
+
* Sessions are platform-level (`isCompanyScoped: false`) and are written from
|
|
10
|
+
* the BullMQ worker (see AnalyticsProcessor), outside HTTP/CLS context, so the
|
|
11
|
+
* writes are fully custom Cypher, as UserActivityRepository.createActivity()
|
|
12
|
+
* does. Every datetime write casts with `datetime($receivedAt)`.
|
|
13
|
+
*
|
|
14
|
+
* The retention methods (deleteDay, unlinkDeletedUsers, findExpiredDays) return
|
|
15
|
+
* scalar counts or days rather than graph nodes, so readOne()/readMany() cannot
|
|
16
|
+
* map them; they read the scalar columns off the driver result, the same shape
|
|
17
|
+
* and rationale as TokenUsageAdminRepository.
|
|
18
|
+
*/
|
|
19
|
+
export declare class AnalyticsSessionRepository extends AbstractRepository<AnalyticsSession, typeof AnalyticsSessionDescriptor.relationships> {
|
|
20
|
+
protected readonly descriptor: import("../../..").EntityDescriptor<AnalyticsSession, {
|
|
21
|
+
user: {
|
|
22
|
+
model: import("../../..").DataMeta;
|
|
23
|
+
direction: "out";
|
|
24
|
+
relationship: string;
|
|
25
|
+
cardinality: "one";
|
|
26
|
+
required: false;
|
|
27
|
+
dtoKey: string;
|
|
28
|
+
};
|
|
29
|
+
}>;
|
|
30
|
+
constructor(neo4j: Neo4jService, securityService: SecurityService, clsService: ClsService);
|
|
31
|
+
/**
|
|
32
|
+
* Adds the session lookup index (visitor + recency, used by recordPageView)
|
|
33
|
+
* and the startedAt index (admin lists, retention) on top of the id
|
|
34
|
+
* constraint AbstractRepository creates from the descriptor.
|
|
35
|
+
*/
|
|
36
|
+
onModuleInit(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* One transaction for the whole session resolution of spec §4: find the
|
|
39
|
+
* visitor's open session (lastSeenAt within the timeout), create it with this
|
|
40
|
+
* event's attribution when there is none, otherwise bump lastSeenAt and
|
|
41
|
+
* pageViews; then create the page view and, when the event carries a user
|
|
42
|
+
* and the session has none yet, the BY_USER edge.
|
|
43
|
+
*
|
|
44
|
+
* The new session id is generated here, so `created` is simply whether the
|
|
45
|
+
* returned session carries it. The session is returned through the
|
|
46
|
+
* descriptor serialiser (writeOne + serialiser), never as a raw record.
|
|
47
|
+
*/
|
|
48
|
+
recordPageView(input: AnalyticsResolvedPageView): Promise<{
|
|
49
|
+
sessionId: string;
|
|
50
|
+
created: boolean;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Administration list, newest first, with the `user` relationship included.
|
|
54
|
+
* Never binds its own companyId: the only one present is what initQuery()
|
|
55
|
+
* seeds from CLS for the calling administrator.
|
|
56
|
+
*/
|
|
57
|
+
findForAdmin(params: {
|
|
58
|
+
cursor: JsonApiCursorInterface;
|
|
59
|
+
from: string;
|
|
60
|
+
to: string;
|
|
61
|
+
section: "all" | "public" | "app";
|
|
62
|
+
visitorId?: string;
|
|
63
|
+
userId?: string;
|
|
64
|
+
}): Promise<AnalyticsSession[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Deletes the page views, then the sessions, of every session that started
|
|
67
|
+
* on `date`, at most DELETE_BATCH_SIZE nodes per transaction. A loop of
|
|
68
|
+
* batched transactions rather than `CALL { } IN TRANSACTIONS`: the latter
|
|
69
|
+
* only runs in an implicit (auto-commit) transaction, and every
|
|
70
|
+
* Neo4jService write path opens an explicit one.
|
|
71
|
+
*/
|
|
72
|
+
deleteDay(params: {
|
|
73
|
+
date: string;
|
|
74
|
+
}): Promise<{
|
|
75
|
+
sessions: number;
|
|
76
|
+
pageViews: number;
|
|
77
|
+
}>;
|
|
78
|
+
/** Removes every BY_USER edge whose user has been soft-deleted. Returns the edges removed. */
|
|
79
|
+
unlinkDeletedUsers(): Promise<number>;
|
|
80
|
+
/** Distinct calendar days (`YYYY-MM-DD`) with raw sessions before `cutoff`, oldest first. */
|
|
81
|
+
findExpiredDays(params: {
|
|
82
|
+
cutoff: string;
|
|
83
|
+
limit: number;
|
|
84
|
+
}): Promise<string[]>;
|
|
85
|
+
private _deleteInBatches;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=analytics-session.repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-session.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/repositories/analytics-session.repository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2DAA2D,CAAC;AACnG,OAAO,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,kDAAkD,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE7F,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AAavF;;;;;;;;;;GAUG;AACH,qBACa,0BAA2B,SAAQ,kBAAkB,CAChE,gBAAgB,EAChB,OAAO,0BAA0B,CAAC,aAAa,CAChD;IACC,SAAS,CAAC,QAAQ,CAAC,UAAU;;;;;;;;;OAA8B;gBAE/C,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU;IAIzF;;;;OAIG;IACY,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5C;;;;;;;;;;OAUG;IACG,cAAc,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IA+ExG;;;;OAIG;IACG,YAAY,CAAC,MAAM,EAAE;QACzB,MAAM,EAAE,sBAAsB,CAAC;QAC/B,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAC;QAClC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA8B/B;;;;;;OAMG;IACG,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IA+B3F,8FAA8F;IACxF,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAe3C,6FAA6F;IACvF,eAAe,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAkBrE,gBAAgB;CAc/B"}
|
|
@@ -0,0 +1,261 @@
|
|
|
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.AnalyticsSessionRepository = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const crypto_1 = require("crypto");
|
|
15
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
16
|
+
const define_entity_1 = require("../../../common/helpers/define-entity");
|
|
17
|
+
const abstract_repository_1 = require("../../../core/neo4j/abstracts/abstract.repository");
|
|
18
|
+
const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
|
|
19
|
+
const security_service_1 = require("../../../core/security/services/security.service");
|
|
20
|
+
const user_meta_1 = require("../../user/entities/user.meta");
|
|
21
|
+
const analytics_session_1 = require("../entities/analytics-session");
|
|
22
|
+
const analytics_page_view_meta_1 = require("../entities/analytics-page-view.meta");
|
|
23
|
+
/** Nodes deleted per transaction by the retention job. */
|
|
24
|
+
const DELETE_BATCH_SIZE = 1000;
|
|
25
|
+
const toNumber = (v) => {
|
|
26
|
+
if (v === null || v === undefined)
|
|
27
|
+
return 0;
|
|
28
|
+
if (typeof v === "number")
|
|
29
|
+
return v;
|
|
30
|
+
if (typeof v.toNumber === "function")
|
|
31
|
+
return v.toNumber();
|
|
32
|
+
return Number(v) || 0;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Sessions are platform-level (`isCompanyScoped: false`) and are written from
|
|
36
|
+
* the BullMQ worker (see AnalyticsProcessor), outside HTTP/CLS context, so the
|
|
37
|
+
* writes are fully custom Cypher, as UserActivityRepository.createActivity()
|
|
38
|
+
* does. Every datetime write casts with `datetime($receivedAt)`.
|
|
39
|
+
*
|
|
40
|
+
* The retention methods (deleteDay, unlinkDeletedUsers, findExpiredDays) return
|
|
41
|
+
* scalar counts or days rather than graph nodes, so readOne()/readMany() cannot
|
|
42
|
+
* map them; they read the scalar columns off the driver result, the same shape
|
|
43
|
+
* and rationale as TokenUsageAdminRepository.
|
|
44
|
+
*/
|
|
45
|
+
let AnalyticsSessionRepository = class AnalyticsSessionRepository extends abstract_repository_1.AbstractRepository {
|
|
46
|
+
constructor(neo4j, securityService, clsService) {
|
|
47
|
+
super(neo4j, securityService, clsService);
|
|
48
|
+
this.descriptor = analytics_session_1.AnalyticsSessionDescriptor;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Adds the session lookup index (visitor + recency, used by recordPageView)
|
|
52
|
+
* and the startedAt index (admin lists, retention) on top of the id
|
|
53
|
+
* constraint AbstractRepository creates from the descriptor.
|
|
54
|
+
*/
|
|
55
|
+
async onModuleInit() {
|
|
56
|
+
await super.onModuleInit();
|
|
57
|
+
const { nodeName, labelName } = this.descriptor.model;
|
|
58
|
+
await this.neo4j.writeOne({
|
|
59
|
+
query: `CREATE INDEX ${nodeName}_visitorId_lastSeenAt IF NOT EXISTS FOR (${nodeName}:${labelName}) ON (${nodeName}.visitorId, ${nodeName}.lastSeenAt)`,
|
|
60
|
+
});
|
|
61
|
+
await this.neo4j.writeOne({
|
|
62
|
+
query: `CREATE INDEX ${nodeName}_startedAt IF NOT EXISTS FOR (${nodeName}:${labelName}) ON (${nodeName}.startedAt)`,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* One transaction for the whole session resolution of spec §4: find the
|
|
67
|
+
* visitor's open session (lastSeenAt within the timeout), create it with this
|
|
68
|
+
* event's attribution when there is none, otherwise bump lastSeenAt and
|
|
69
|
+
* pageViews; then create the page view and, when the event carries a user
|
|
70
|
+
* and the session has none yet, the BY_USER edge.
|
|
71
|
+
*
|
|
72
|
+
* The new session id is generated here, so `created` is simply whether the
|
|
73
|
+
* returned session carries it. The session is returned through the
|
|
74
|
+
* descriptor serialiser (writeOne + serialiser), never as a raw record.
|
|
75
|
+
*/
|
|
76
|
+
async recordPageView(input) {
|
|
77
|
+
const { nodeName, labelName } = this.descriptor.model;
|
|
78
|
+
const newSessionId = (0, crypto_1.randomUUID)();
|
|
79
|
+
const query = this.neo4j.initQuery({ serialiser: this.descriptor.model });
|
|
80
|
+
query.queryParams = {
|
|
81
|
+
...query.queryParams,
|
|
82
|
+
newSessionId,
|
|
83
|
+
pageViewId: (0, crypto_1.randomUUID)(),
|
|
84
|
+
visitorId: input.visitorId,
|
|
85
|
+
consented: input.consented,
|
|
86
|
+
path: input.path,
|
|
87
|
+
route: input.route,
|
|
88
|
+
section: input.section,
|
|
89
|
+
referrerHost: input.referrerHost ?? null,
|
|
90
|
+
utmSource: input.utmSource ?? null,
|
|
91
|
+
utmMedium: input.utmMedium ?? null,
|
|
92
|
+
utmCampaign: input.utmCampaign ?? null,
|
|
93
|
+
utmTerm: input.utmTerm ?? null,
|
|
94
|
+
utmContent: input.utmContent ?? null,
|
|
95
|
+
deviceType: input.deviceType,
|
|
96
|
+
userId: input.userId ?? null,
|
|
97
|
+
receivedAt: input.receivedAt,
|
|
98
|
+
sessionTimeoutMinutes: input.sessionTimeoutMinutes,
|
|
99
|
+
...this.getPolyLabelParams(),
|
|
100
|
+
};
|
|
101
|
+
query.query = `
|
|
102
|
+
OPTIONAL MATCH (openSession:${labelName} {visitorId: $visitorId})
|
|
103
|
+
WHERE openSession.lastSeenAt >= datetime($receivedAt) - duration({minutes: $sessionTimeoutMinutes})
|
|
104
|
+
WITH openSession
|
|
105
|
+
ORDER BY openSession.lastSeenAt DESC
|
|
106
|
+
LIMIT 1
|
|
107
|
+
MERGE (${nodeName}:${labelName} {id: coalesce(openSession.id, $newSessionId)})
|
|
108
|
+
ON CREATE SET ${nodeName} += {
|
|
109
|
+
visitorId: $visitorId,
|
|
110
|
+
consented: $consented,
|
|
111
|
+
startedAt: datetime($receivedAt),
|
|
112
|
+
pageViews: 0,
|
|
113
|
+
section: $section,
|
|
114
|
+
landingRoute: $route,
|
|
115
|
+
referrerHost: $referrerHost,
|
|
116
|
+
utmSource: $utmSource,
|
|
117
|
+
utmMedium: $utmMedium,
|
|
118
|
+
utmCampaign: $utmCampaign,
|
|
119
|
+
utmTerm: $utmTerm,
|
|
120
|
+
utmContent: $utmContent,
|
|
121
|
+
deviceType: $deviceType,
|
|
122
|
+
createdAt: datetime($receivedAt)
|
|
123
|
+
}
|
|
124
|
+
SET ${nodeName}.lastSeenAt = datetime($receivedAt),
|
|
125
|
+
${nodeName}.pageViews = ${nodeName}.pageViews + 1,
|
|
126
|
+
${nodeName}.updatedAt = datetime($receivedAt)
|
|
127
|
+
CREATE (${analytics_page_view_meta_1.analyticsPageViewMeta.nodeName}:${analytics_page_view_meta_1.analyticsPageViewMeta.labelName} {
|
|
128
|
+
id: $pageViewId,
|
|
129
|
+
path: $path,
|
|
130
|
+
route: $route,
|
|
131
|
+
section: $section,
|
|
132
|
+
createdAt: datetime($receivedAt),
|
|
133
|
+
updatedAt: datetime($receivedAt)
|
|
134
|
+
})-[:IN_SESSION]->(${nodeName})
|
|
135
|
+
WITH ${nodeName}
|
|
136
|
+
OPTIONAL MATCH (${user_meta_1.userMeta.nodeName}:${user_meta_1.userMeta.labelName} {id: $userId})
|
|
137
|
+
WITH ${nodeName}, ${user_meta_1.userMeta.nodeName}
|
|
138
|
+
FOREACH (_ IN CASE
|
|
139
|
+
WHEN $userId IS NOT NULL AND ${user_meta_1.userMeta.nodeName} IS NOT NULL AND NOT EXISTS { (${nodeName})-[:BY_USER]->(:${user_meta_1.userMeta.labelName}) }
|
|
140
|
+
THEN [1] ELSE [] END |
|
|
141
|
+
MERGE (${nodeName})-[:BY_USER]->(${user_meta_1.userMeta.nodeName})
|
|
142
|
+
)
|
|
143
|
+
WITH ${nodeName}
|
|
144
|
+
${this.buildReturnStatement()}
|
|
145
|
+
`;
|
|
146
|
+
const session = await this.neo4j.writeOne(query);
|
|
147
|
+
if (!session)
|
|
148
|
+
throw new Error(`Analytics page view for ${input.visitorId} returned no session`);
|
|
149
|
+
return { sessionId: session.id, created: session.id === newSessionId };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Administration list, newest first, with the `user` relationship included.
|
|
153
|
+
* Never binds its own companyId: the only one present is what initQuery()
|
|
154
|
+
* seeds from CLS for the calling administrator.
|
|
155
|
+
*/
|
|
156
|
+
async findForAdmin(params) {
|
|
157
|
+
const { nodeName } = this.descriptor.model;
|
|
158
|
+
const query = this.neo4j.initQuery({ serialiser: this.descriptor.model, cursor: params.cursor });
|
|
159
|
+
query.queryParams = {
|
|
160
|
+
...query.queryParams,
|
|
161
|
+
from: params.from,
|
|
162
|
+
to: params.to,
|
|
163
|
+
section: params.section,
|
|
164
|
+
visitorId: params.visitorId ?? null,
|
|
165
|
+
userId: params.userId ?? null,
|
|
166
|
+
...this.getPolyLabelParams(),
|
|
167
|
+
};
|
|
168
|
+
query.query += `
|
|
169
|
+
${this.buildDefaultMatch()}
|
|
170
|
+
WHERE ${nodeName}.startedAt >= datetime($from)
|
|
171
|
+
AND ${nodeName}.startedAt <= datetime($to)
|
|
172
|
+
AND ($section = 'all' OR ${nodeName}.section = $section)
|
|
173
|
+
AND ($visitorId IS NULL OR ${nodeName}.visitorId = $visitorId)
|
|
174
|
+
AND ($userId IS NULL OR EXISTS { (${nodeName})-[:BY_USER]->(:${user_meta_1.userMeta.labelName} {id: $userId}) })
|
|
175
|
+
WITH ${nodeName}
|
|
176
|
+
ORDER BY ${nodeName}.startedAt DESC
|
|
177
|
+
{CURSOR}
|
|
178
|
+
${this.buildReturnStatement()}
|
|
179
|
+
`;
|
|
180
|
+
return this.neo4j.readMany(query);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Deletes the page views, then the sessions, of every session that started
|
|
184
|
+
* on `date`, at most DELETE_BATCH_SIZE nodes per transaction. A loop of
|
|
185
|
+
* batched transactions rather than `CALL { } IN TRANSACTIONS`: the latter
|
|
186
|
+
* only runs in an implicit (auto-commit) transaction, and every
|
|
187
|
+
* Neo4jService write path opens an explicit one.
|
|
188
|
+
*/
|
|
189
|
+
async deleteDay(params) {
|
|
190
|
+
const { nodeName, labelName } = this.descriptor.model;
|
|
191
|
+
const pv = analytics_page_view_meta_1.analyticsPageViewMeta;
|
|
192
|
+
const pageViews = await this._deleteInBatches({
|
|
193
|
+
date: params.date,
|
|
194
|
+
query: `
|
|
195
|
+
MATCH (${pv.nodeName}:${pv.labelName})-[:IN_SESSION]->(${nodeName}:${labelName})
|
|
196
|
+
WHERE date(${nodeName}.startedAt) = date($date)
|
|
197
|
+
WITH ${pv.nodeName}
|
|
198
|
+
LIMIT toInteger($batchSize)
|
|
199
|
+
DETACH DELETE ${pv.nodeName}
|
|
200
|
+
RETURN count(*) AS deleted
|
|
201
|
+
`,
|
|
202
|
+
});
|
|
203
|
+
const sessions = await this._deleteInBatches({
|
|
204
|
+
date: params.date,
|
|
205
|
+
query: `
|
|
206
|
+
MATCH (${nodeName}:${labelName})
|
|
207
|
+
WHERE date(${nodeName}.startedAt) = date($date)
|
|
208
|
+
WITH ${nodeName}
|
|
209
|
+
LIMIT toInteger($batchSize)
|
|
210
|
+
DETACH DELETE ${nodeName}
|
|
211
|
+
RETURN count(*) AS deleted
|
|
212
|
+
`,
|
|
213
|
+
});
|
|
214
|
+
return { sessions, pageViews };
|
|
215
|
+
}
|
|
216
|
+
/** Removes every BY_USER edge whose user has been soft-deleted. Returns the edges removed. */
|
|
217
|
+
async unlinkDeletedUsers() {
|
|
218
|
+
const [result] = await this.neo4j.executeInTransaction([
|
|
219
|
+
{
|
|
220
|
+
query: `
|
|
221
|
+
MATCH (:${this.descriptor.model.labelName})-[r:BY_USER]->(${user_meta_1.userMeta.nodeName}:${user_meta_1.userMeta.labelName} {isDeleted: true})
|
|
222
|
+
DELETE r
|
|
223
|
+
RETURN count(*) AS unlinked
|
|
224
|
+
`,
|
|
225
|
+
params: {},
|
|
226
|
+
},
|
|
227
|
+
]);
|
|
228
|
+
return toNumber(result?.records?.[0]?.get("unlinked"));
|
|
229
|
+
}
|
|
230
|
+
/** Distinct calendar days (`YYYY-MM-DD`) with raw sessions before `cutoff`, oldest first. */
|
|
231
|
+
async findExpiredDays(params) {
|
|
232
|
+
const { nodeName, labelName } = this.descriptor.model;
|
|
233
|
+
const result = await this.neo4j.read(`
|
|
234
|
+
MATCH (${nodeName}:${labelName})
|
|
235
|
+
WHERE date(${nodeName}.startedAt) < date($cutoff)
|
|
236
|
+
WITH DISTINCT date(${nodeName}.startedAt) AS day
|
|
237
|
+
RETURN day
|
|
238
|
+
ORDER BY day ASC
|
|
239
|
+
LIMIT toInteger($limit)
|
|
240
|
+
`, { cutoff: params.cutoff, limit: params.limit });
|
|
241
|
+
return result.records.map((r) => (0, define_entity_1.convertFieldValue)(r.get("day"), "date"));
|
|
242
|
+
}
|
|
243
|
+
async _deleteInBatches(params) {
|
|
244
|
+
let total = 0;
|
|
245
|
+
let deleted;
|
|
246
|
+
do {
|
|
247
|
+
const [result] = await this.neo4j.executeInTransaction([
|
|
248
|
+
{ query: params.query, params: { date: params.date, batchSize: DELETE_BATCH_SIZE } },
|
|
249
|
+
]);
|
|
250
|
+
deleted = toNumber(result?.records?.[0]?.get("deleted"));
|
|
251
|
+
total += deleted;
|
|
252
|
+
} while (deleted >= DELETE_BATCH_SIZE);
|
|
253
|
+
return total;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
exports.AnalyticsSessionRepository = AnalyticsSessionRepository;
|
|
257
|
+
exports.AnalyticsSessionRepository = AnalyticsSessionRepository = __decorate([
|
|
258
|
+
(0, common_1.Injectable)(),
|
|
259
|
+
__metadata("design:paramtypes", [neo4j_service_1.Neo4jService, security_service_1.SecurityService, nestjs_cls_1.ClsService])
|
|
260
|
+
], AnalyticsSessionRepository);
|
|
261
|
+
//# sourceMappingURL=analytics-session.repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-session.repository.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/repositories/analytics-session.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
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 { AnalyticsBreakdownEntity } from "../entities/analytics-breakdown";
|
|
6
|
+
import { AnalyticsSession, AnalyticsSessionDescriptor } from "../entities/analytics-session";
|
|
7
|
+
import { AnalyticsSummaryEntity } from "../entities/analytics-summary";
|
|
8
|
+
import { AnalyticsTimelineEntity } from "../entities/analytics-timeline";
|
|
9
|
+
/**
|
|
10
|
+
* The closed sets of values the admin endpoints accept. The controller
|
|
11
|
+
* validates query params against these tuples and the unions below are derived
|
|
12
|
+
* from them, so there is one declaration of each set.
|
|
13
|
+
*/
|
|
14
|
+
export declare const SECTIONS: readonly ["all", "public", "app"];
|
|
15
|
+
export declare const GRANULARITIES: readonly ["day", "week", "month"];
|
|
16
|
+
export declare const DIMENSIONS: readonly ["source", "medium", "campaign", "referrer", "route", "landing"];
|
|
17
|
+
export type Section = (typeof SECTIONS)[number];
|
|
18
|
+
export type Granularity = (typeof GRANULARITIES)[number];
|
|
19
|
+
export type Dimension = (typeof DIMENSIONS)[number];
|
|
20
|
+
/**
|
|
21
|
+
* Platform-wide reporting queries behind /analytics/administration/*.
|
|
22
|
+
*
|
|
23
|
+
* Extends AbstractRepository for the shared Neo4j/security/CLS plumbing and the
|
|
24
|
+
* descriptor typing; none of the inherited finders are used, for the reasons in
|
|
25
|
+
* the file header, and it deliberately does NOT override onModuleInit — the
|
|
26
|
+
* analytics indexes belong to the session, page-view and daily-summary
|
|
27
|
+
* repositories.
|
|
28
|
+
*
|
|
29
|
+
* Every aggregate is two reads merged in JS: the RAW part (sessions / page views
|
|
30
|
+
* on or after `retentionCutoff`) and the SUMMARISED part (daily summaries before
|
|
31
|
+
* it). Raw visitors are `count(DISTINCT visitorId)`; summarised visitors are the
|
|
32
|
+
* stored per-day distinct counts, summed — so a multi-day bucket over summarised
|
|
33
|
+
* data sums daily distinct visitors. The summary adds a third raw read for the
|
|
34
|
+
* cross-section visitor total (see _sectionTotals).
|
|
35
|
+
*/
|
|
36
|
+
export declare class AnalyticsAdminRepository extends AbstractRepository<AnalyticsSession, typeof AnalyticsSessionDescriptor.relationships> {
|
|
37
|
+
protected readonly descriptor: import("../../..").EntityDescriptor<AnalyticsSession, {
|
|
38
|
+
user: {
|
|
39
|
+
model: import("../../..").DataMeta;
|
|
40
|
+
direction: "out";
|
|
41
|
+
relationship: string;
|
|
42
|
+
cardinality: "one";
|
|
43
|
+
required: false;
|
|
44
|
+
dtoKey: string;
|
|
45
|
+
};
|
|
46
|
+
}>;
|
|
47
|
+
constructor(neo4j: Neo4jService, securityService: SecurityService, clsService: ClsService);
|
|
48
|
+
/**
|
|
49
|
+
* Six rows: {public, app, total} × {current, previous}. The previous window is
|
|
50
|
+
* the equal-length span immediately preceding `from`, which is what the KPI
|
|
51
|
+
* tiles' deltas are computed against.
|
|
52
|
+
*/
|
|
53
|
+
findSummary(params: {
|
|
54
|
+
from: string;
|
|
55
|
+
to: string;
|
|
56
|
+
section: Section;
|
|
57
|
+
retentionCutoff: string;
|
|
58
|
+
}): Promise<AnalyticsSummaryEntity[]>;
|
|
59
|
+
findTimeline(params: {
|
|
60
|
+
from: string;
|
|
61
|
+
to: string;
|
|
62
|
+
section: Section;
|
|
63
|
+
granularity: Granularity;
|
|
64
|
+
retentionCutoff: string;
|
|
65
|
+
}): Promise<AnalyticsTimelineEntity[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Ranked rows, descending by visitors, truncated to `limit` with the exact
|
|
68
|
+
* remainder folded into a single "other" row. The full ordered set is fetched
|
|
69
|
+
* and sliced in JS so the remainder is exact rather than a second query's
|
|
70
|
+
* approximation.
|
|
71
|
+
*/
|
|
72
|
+
findBreakdown(params: {
|
|
73
|
+
from: string;
|
|
74
|
+
to: string;
|
|
75
|
+
section: Section;
|
|
76
|
+
dimension: Dimension;
|
|
77
|
+
limit: number;
|
|
78
|
+
retentionCutoff: string;
|
|
79
|
+
}): Promise<AnalyticsBreakdownEntity[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Raw + summarised totals split by section for one window, plus the window's
|
|
82
|
+
* total visitor count.
|
|
83
|
+
*
|
|
84
|
+
* `totalVisitors` cannot be the sum of the two sections: one visitor with
|
|
85
|
+
* sessions in both public and app would count twice. Its raw part is a third
|
|
86
|
+
* read with no section grouping (`count(DISTINCT visitorId)` across both); its
|
|
87
|
+
* summarised part is the stored per-day `total` rows summed, as for the
|
|
88
|
+
* sections, because summaries keep no visitor ids to de-duplicate.
|
|
89
|
+
*/
|
|
90
|
+
private _sectionTotals;
|
|
91
|
+
/**
|
|
92
|
+
* Guarantees both sections are present (zero-filled when a window has no
|
|
93
|
+
* rows) and appends the "total" section, so the tiles never have to branch on
|
|
94
|
+
* a missing row. Total sessions and page views are the sections' sum; total
|
|
95
|
+
* visitors is the de-duplicated count from _sectionTotals. Consent share is
|
|
96
|
+
* measured on the raw part only: daily summaries carry no consent split.
|
|
97
|
+
*/
|
|
98
|
+
private _withTotal;
|
|
99
|
+
/** Raw sessions inside the request range and on or after the retention cutoff. */
|
|
100
|
+
private _rawSessionWindow;
|
|
101
|
+
/** Summarised days inside the request range and before the retention cutoff. */
|
|
102
|
+
private _summaryWindow;
|
|
103
|
+
/**
|
|
104
|
+
* The query seed every aggregation in this file MUST use.
|
|
105
|
+
*
|
|
106
|
+
* It deliberately does NOT call `Neo4jService.initQuery()`. initQuery()
|
|
107
|
+
* PREPENDS `MATCH (company:Company {id: $companyId})` (plus a currentUser
|
|
108
|
+
* match hanging off it) whenever the CALLER's CLS session carries a
|
|
109
|
+
* `companyId` — the same CLS scoping the file header explains this dashboard
|
|
110
|
+
* must not have, reintroduced through a less obvious door than
|
|
111
|
+
* buildDefaultMatch().
|
|
112
|
+
*
|
|
113
|
+
* Reachable only for an Administrator who ALSO belongs to a company (CLS has
|
|
114
|
+
* no companyId otherwise), which is exactly the dual-role shape the platform
|
|
115
|
+
* admin fixture — and real deployments — have. In the token-usage dashboard
|
|
116
|
+
* that prepended MATCH reduced every aggregation to zero rows and the
|
|
117
|
+
* zero-fill rendered a successful, empty page (ADM-53..57).
|
|
118
|
+
*
|
|
119
|
+
* Analytics nodes have no company at all, so this seed binds no `companyId`
|
|
120
|
+
* parameter of any kind. `section`, `granularity` and `dimension` are bound
|
|
121
|
+
* only when the caller supplies them, and only with values echoed from this
|
|
122
|
+
* file's lookup tables.
|
|
123
|
+
*/
|
|
124
|
+
private _adminQuery;
|
|
125
|
+
/** The equal-length span immediately preceding `from`. */
|
|
126
|
+
private _previousWindow;
|
|
127
|
+
/**
|
|
128
|
+
* Resolves a granularity to the `date.truncate` unit it may emit. Throws
|
|
129
|
+
* rather than interpolating anything the table does not know about.
|
|
130
|
+
*/
|
|
131
|
+
private _truncationUnit;
|
|
132
|
+
/**
|
|
133
|
+
* Resolves the requested section to the value it binds (`null` for `all`).
|
|
134
|
+
* Returns the TABLE'S OWN string, never the caller's.
|
|
135
|
+
*/
|
|
136
|
+
private _section;
|
|
137
|
+
/**
|
|
138
|
+
* Resolves the requested dimension against the whitelist. Returns the table's
|
|
139
|
+
* own key and expression, never the caller's string.
|
|
140
|
+
*/
|
|
141
|
+
private _dimension;
|
|
142
|
+
private _add;
|
|
143
|
+
private _metrics;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=analytics.admin.repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.admin.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/repositories/analytics.admin.repository.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,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,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAG3E,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE7F,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAA+B,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEtG;;;;GAIG;AACH,eAAO,MAAM,QAAQ,mCAAoC,CAAC;AAC1D,eAAO,MAAM,aAAa,mCAAoC,CAAC;AAC/D,eAAO,MAAM,UAAU,2EAA4E,CAAC;AAEpG,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAChD,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AACzD,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAuEpD;;;;;;;;;;;;;;;GAeG;AACH,qBACa,wBAAyB,SAAQ,kBAAkB,CAC9D,gBAAgB,EAChB,OAAO,0BAA0B,CAAC,aAAa,CAChD;IACC,SAAS,CAAC,QAAQ,CAAC,UAAU;;;;;;;;;OAA8B;gBAE/C,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU;IAIzF;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAY/B,YAAY,CAAC,MAAM,EAAE;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,WAAW,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC;IA8EtC;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE;QAC1B,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC;IA+EvC;;;;;;;;;OASG;YACW,cAAc;IA+E5B;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAuClB,kFAAkF;IAClF,OAAO,CAAC,iBAAiB;IAKzB,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAKtB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,WAAW;IAwBnB,0DAA0D;IAC1D,OAAO,CAAC,eAAe;IAOvB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAQvB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAMhB;;;OAGG;IACH,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,QAAQ;CAOjB"}
|