vidspotai-shared 1.0.52 → 1.0.53
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/lib/models/analytics.model.d.ts +35 -0
- package/lib/models/analytics.model.d.ts.map +1 -0
- package/lib/models/analytics.model.js +2 -0
- package/lib/models/index.d.ts +1 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +1 -0
- package/lib/services/analytics.service.d.ts +23 -0
- package/lib/services/analytics.service.d.ts.map +1 -0
- package/lib/services/analytics.service.js +69 -0
- package/lib/services/gcp/gcp.service.js +2 -2
- package/lib/services/gcp/gsheet.service.js +2 -2
- package/lib/services/index.d.ts +1 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { FieldValue } from "firebase-admin/firestore";
|
|
2
|
+
/**
|
|
3
|
+
* Daily rollup keyed by `${YYYY-MM-DD}_${modelKey}`.
|
|
4
|
+
* Written via FieldValue.increment from job finalization so that the
|
|
5
|
+
* admin dashboard never has to scan `videoJobs` for per-model stats.
|
|
6
|
+
*/
|
|
7
|
+
export interface IAnalyticsDailyModel {
|
|
8
|
+
date: string;
|
|
9
|
+
modelKey: string;
|
|
10
|
+
jobsCompleted: number;
|
|
11
|
+
jobsFailed: number;
|
|
12
|
+
jobsPartial: number;
|
|
13
|
+
scenesCompleted: number;
|
|
14
|
+
scenesFailed: number;
|
|
15
|
+
scenesTimedOut: number;
|
|
16
|
+
totalCreditsUsed: number;
|
|
17
|
+
totalDurationSeconds: number;
|
|
18
|
+
jobLatencyMsSum: number;
|
|
19
|
+
jobLatencyMsCount: number;
|
|
20
|
+
updatedAt: FieldValue;
|
|
21
|
+
}
|
|
22
|
+
/** Cross-model daily rollup for summary cards. */
|
|
23
|
+
export interface IAnalyticsDailyGlobalModel {
|
|
24
|
+
date: string;
|
|
25
|
+
jobsCompleted: number;
|
|
26
|
+
jobsFailed: number;
|
|
27
|
+
jobsPartial: number;
|
|
28
|
+
scenesCompleted: number;
|
|
29
|
+
scenesFailed: number;
|
|
30
|
+
totalCreditsUsed: number;
|
|
31
|
+
jobLatencyMsSum: number;
|
|
32
|
+
jobLatencyMsCount: number;
|
|
33
|
+
updatedAt: FieldValue;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=analytics.model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.model.d.ts","sourceRoot":"","sources":["../../src/models/analytics.model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,kDAAkD;AAClD,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,UAAU,CAAC;CACvB"}
|
package/lib/models/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC"}
|
package/lib/models/index.js
CHANGED
|
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./video.model"), exports);
|
|
18
18
|
__exportStar(require("./user.model"), exports);
|
|
19
19
|
__exportStar(require("./script.model"), exports);
|
|
20
|
+
__exportStar(require("./analytics.model"), exports);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EVideoJobStatus } from "../globals/types";
|
|
2
|
+
import { IVideoScene } from "../models/video.model";
|
|
3
|
+
export interface RecordJobOutcomeParams {
|
|
4
|
+
modelKey: string;
|
|
5
|
+
finalStatus: EVideoJobStatus;
|
|
6
|
+
scenes: IVideoScene[];
|
|
7
|
+
totalCreditsUsed: number;
|
|
8
|
+
/** ms between job creation and finalization */
|
|
9
|
+
jobLatencyMs?: number;
|
|
10
|
+
/** Defaults to now (UTC). Override only when backfilling. */
|
|
11
|
+
finalizedAt?: Date;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* AnalyticsService
|
|
15
|
+
* ----------------
|
|
16
|
+
* Write-side helper for incrementing daily rollup counters. Reads happen
|
|
17
|
+
* from the admin app (server side) — kept here so a future BigQuery export
|
|
18
|
+
* has a single source of truth for shape.
|
|
19
|
+
*/
|
|
20
|
+
export declare class AnalyticsService {
|
|
21
|
+
static recordJobOutcome(p: RecordJobOutcomeParams): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=analytics.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.service.d.ts","sourceRoot":"","sources":["../../src/services/analytics.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAqB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAUpD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,eAAe,CAAC;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED;;;;;;GAMG;AACH,qBAAa,gBAAgB;WACd,gBAAgB,CAAC,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAqDxE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnalyticsService = void 0;
|
|
4
|
+
const firestore_1 = require("firebase-admin/firestore");
|
|
5
|
+
const firebase_1 = require("../libs/firebase");
|
|
6
|
+
const types_1 = require("../globals/types");
|
|
7
|
+
const DAILY_COL = "analytics_daily";
|
|
8
|
+
const DAILY_GLOBAL_COL = "analytics_daily_global";
|
|
9
|
+
function dateKey(d = new Date()) {
|
|
10
|
+
// UTC YYYY-MM-DD
|
|
11
|
+
return d.toISOString().slice(0, 10);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* AnalyticsService
|
|
15
|
+
* ----------------
|
|
16
|
+
* Write-side helper for incrementing daily rollup counters. Reads happen
|
|
17
|
+
* from the admin app (server side) — kept here so a future BigQuery export
|
|
18
|
+
* has a single source of truth for shape.
|
|
19
|
+
*/
|
|
20
|
+
class AnalyticsService {
|
|
21
|
+
static async recordJobOutcome(p) {
|
|
22
|
+
const date = dateKey(p.finalizedAt);
|
|
23
|
+
const completed = p.scenes.filter((s) => s.status === types_1.EVideoSceneStatus.COMPLETED).length;
|
|
24
|
+
const failed = p.scenes.filter((s) => s.status === types_1.EVideoSceneStatus.FAILED).length;
|
|
25
|
+
const timedOut = p.scenes.filter((s) => s.status === types_1.EVideoSceneStatus.TIMED_OUT).length;
|
|
26
|
+
const totalDuration = p.scenes
|
|
27
|
+
.filter((s) => s.status === types_1.EVideoSceneStatus.COMPLETED)
|
|
28
|
+
.reduce((sum, s) => sum + (s.duration ?? 0), 0);
|
|
29
|
+
const jobsCompleted = p.finalStatus === types_1.EVideoJobStatus.COMPLETED ? 1 : 0;
|
|
30
|
+
const jobsFailed = p.finalStatus === types_1.EVideoJobStatus.FAILED ? 1 : 0;
|
|
31
|
+
const jobsPartial = p.finalStatus === types_1.EVideoJobStatus.PARTIALLY_COMPLETED ? 1 : 0;
|
|
32
|
+
const inc = firestore_1.FieldValue.increment;
|
|
33
|
+
const latencyMs = p.jobLatencyMs ?? 0;
|
|
34
|
+
const perModelRef = firebase_1.firestore.collection(DAILY_COL).doc(`${date}_${p.modelKey}`);
|
|
35
|
+
const globalRef = firebase_1.firestore.collection(DAILY_GLOBAL_COL).doc(date);
|
|
36
|
+
const perModelPayload = {
|
|
37
|
+
date,
|
|
38
|
+
modelKey: p.modelKey,
|
|
39
|
+
jobsCompleted: inc(jobsCompleted),
|
|
40
|
+
jobsFailed: inc(jobsFailed),
|
|
41
|
+
jobsPartial: inc(jobsPartial),
|
|
42
|
+
scenesCompleted: inc(completed),
|
|
43
|
+
scenesFailed: inc(failed),
|
|
44
|
+
scenesTimedOut: inc(timedOut),
|
|
45
|
+
totalCreditsUsed: inc(p.totalCreditsUsed),
|
|
46
|
+
totalDurationSeconds: inc(totalDuration),
|
|
47
|
+
jobLatencyMsSum: inc(latencyMs),
|
|
48
|
+
jobLatencyMsCount: inc(latencyMs > 0 ? 1 : 0),
|
|
49
|
+
updatedAt: firestore_1.FieldValue.serverTimestamp(),
|
|
50
|
+
};
|
|
51
|
+
const globalPayload = {
|
|
52
|
+
date,
|
|
53
|
+
jobsCompleted: inc(jobsCompleted),
|
|
54
|
+
jobsFailed: inc(jobsFailed),
|
|
55
|
+
jobsPartial: inc(jobsPartial),
|
|
56
|
+
scenesCompleted: inc(completed),
|
|
57
|
+
scenesFailed: inc(failed),
|
|
58
|
+
totalCreditsUsed: inc(p.totalCreditsUsed),
|
|
59
|
+
jobLatencyMsSum: inc(latencyMs),
|
|
60
|
+
jobLatencyMsCount: inc(latencyMs > 0 ? 1 : 0),
|
|
61
|
+
updatedAt: firestore_1.FieldValue.serverTimestamp(),
|
|
62
|
+
};
|
|
63
|
+
const batch = firebase_1.firestore.batch();
|
|
64
|
+
batch.set(perModelRef, perModelPayload, { merge: true });
|
|
65
|
+
batch.set(globalRef, globalPayload, { merge: true });
|
|
66
|
+
await batch.commit();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.AnalyticsService = AnalyticsService;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GCPService = void 0;
|
|
4
|
-
const
|
|
4
|
+
const sheets_1 = require("@googleapis/sheets");
|
|
5
5
|
class GCPService {
|
|
6
6
|
constructor() {
|
|
7
7
|
if (!process.env.GOOGLE_CLIENT_EMAIL || !process.env.GOOGLE_PRIVATE_KEY) {
|
|
8
8
|
throw new Error("Missing GCP credentials");
|
|
9
9
|
}
|
|
10
|
-
this.auth = new
|
|
10
|
+
this.auth = new sheets_1.auth.JWT({
|
|
11
11
|
email: process.env.GOOGLE_CLIENT_EMAIL,
|
|
12
12
|
key: process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n"),
|
|
13
13
|
scopes: ["https://www.googleapis.com/auth/spreadsheets"],
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GSheetService = void 0;
|
|
4
|
-
const
|
|
4
|
+
const sheets_1 = require("@googleapis/sheets");
|
|
5
5
|
const gcp_service_1 = require("./gcp.service");
|
|
6
6
|
class GSheetService extends gcp_service_1.GCPService {
|
|
7
7
|
constructor() {
|
|
8
8
|
super();
|
|
9
|
-
this.sheets =
|
|
9
|
+
this.sheets = (0, sheets_1.sheets)({
|
|
10
10
|
version: "v4",
|
|
11
11
|
auth: this.auth,
|
|
12
12
|
});
|
package/lib/services/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC"}
|
package/lib/services/index.js
CHANGED
|
@@ -20,4 +20,5 @@ __exportStar(require("./aiGen"), exports);
|
|
|
20
20
|
__exportStar(require("./bullmq.service"), exports);
|
|
21
21
|
__exportStar(require("./gcp"), exports);
|
|
22
22
|
__exportStar(require("./credit.service"), exports);
|
|
23
|
+
__exportStar(require("./analytics.service"), exports);
|
|
23
24
|
__exportStar(require("./tts"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vidspotai-shared",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.53",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@google-cloud/storage": "*",
|
|
18
18
|
"@google/genai": "^1.22.0",
|
|
19
|
+
"@googleapis/sheets": "^13.0.1",
|
|
19
20
|
"@runwayml/sdk": "^2.11.0",
|
|
20
21
|
"axios": "^1.12.2",
|
|
21
22
|
"bullmq": "^5.61.0",
|
|
22
23
|
"firebase-admin": "^13.5.0",
|
|
23
24
|
"fs-extra": "^11.3.2",
|
|
24
|
-
"googleapis": "^170.0.0",
|
|
25
25
|
"ioredis": "^5.8.0",
|
|
26
26
|
"jsonwebtoken": "^9.0.2",
|
|
27
27
|
"logform": "^2.7.0",
|