@trafficgroup/knex-rel 0.1.7 → 0.1.8
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/dao/VideoMinuteResultDAO.d.ts +37 -0
- package/dist/dao/VideoMinuteResultDAO.js +146 -0
- package/dist/dao/VideoMinuteResultDAO.js.map +1 -1
- package/dist/dao/batch/batch.dao.d.ts +27 -0
- package/dist/dao/batch/batch.dao.js +135 -0
- package/dist/dao/batch/batch.dao.js.map +1 -0
- package/dist/dao/video/video.dao.d.ts +23 -0
- package/dist/dao/video/video.dao.js +80 -0
- package/dist/dao/video/video.dao.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/batch/batch.interfaces.d.ts +13 -0
- package/dist/interfaces/batch/batch.interfaces.js +3 -0
- package/dist/interfaces/batch/batch.interfaces.js.map +1 -0
- package/dist/interfaces/video/video.interfaces.d.ts +8 -0
- package/migrations/20251020225758_migration.ts +135 -0
- package/package.json +1 -1
- package/plan.md +684 -0
- package/src/dao/VideoMinuteResultDAO.ts +232 -0
- package/src/dao/batch/batch.dao.ts +121 -0
- package/src/dao/video/video.dao.ts +90 -0
- package/src/index.ts +11 -1
- package/src/interfaces/batch/batch.interfaces.ts +14 -0
- package/src/interfaces/video/video.interfaces.ts +12 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { AuthDAO } from "./dao/auth/auth.dao";
|
|
2
|
+
export { BatchDAO } from "./dao/batch/batch.dao";
|
|
2
3
|
export { CameraDAO } from "./dao/camera/camera.dao";
|
|
3
4
|
export { ChatDAO } from "./dao/chat/chat.dao";
|
|
4
5
|
export { FolderDAO } from "./dao/folder/folder.dao";
|
|
@@ -11,6 +12,7 @@ export { VideoDAO } from "./dao/video/video.dao";
|
|
|
11
12
|
export { VideoMinuteResultDAO } from "./dao/VideoMinuteResultDAO";
|
|
12
13
|
export { IDataPaginator } from "./d.types";
|
|
13
14
|
export { IAuth } from "./interfaces/auth/auth.interfaces";
|
|
15
|
+
export { IBatch } from "./interfaces/batch/batch.interfaces";
|
|
14
16
|
export { ICamera } from "./interfaces/camera/camera.interfaces";
|
|
15
17
|
export { IChat, IChatCreate, IChatUpdate, } from "./interfaces/chat/chat.interfaces";
|
|
16
18
|
export { IFolder } from "./interfaces/folder/folder.interfaces";
|
|
@@ -19,7 +21,8 @@ export { IReportConfiguration, IReportConfigurationData, IReportConfigurationInp
|
|
|
19
21
|
export { IStudy } from "./interfaces/study/study.interfaces";
|
|
20
22
|
export { IUser } from "./interfaces/user/user.interfaces";
|
|
21
23
|
export { IUserPushNotificationToken } from "./interfaces/user-push-notification-token/user-push-notification-token.interfaces";
|
|
22
|
-
export { IVideo } from "./interfaces/video/video.interfaces";
|
|
24
|
+
export { IVideo, ITrimPeriod } from "./interfaces/video/video.interfaces";
|
|
23
25
|
export { IVideoMinuteResult, IVideoMinuteResultInput, IVideoMinuteBatch, } from "./entities/VideoMinuteResult";
|
|
26
|
+
export type { IStudyTimeGroupResult, IGroupedStudyResponse, IGroupedResponse, IGroupedResult, ITMCResult, IATRResult, } from "./dao/VideoMinuteResultDAO";
|
|
24
27
|
import KnexManager from "./KnexConnection";
|
|
25
28
|
export { KnexManager };
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.KnexManager = exports.VideoMinuteResultDAO = exports.VideoDAO = exports.UserPushNotificationTokenDAO = exports.UserDAO = exports.StudyDAO = exports.ReportConfigurationDAO = exports.MessageDAO = exports.FolderDAO = exports.ChatDAO = exports.CameraDAO = exports.AuthDAO = void 0;
|
|
6
|
+
exports.KnexManager = exports.VideoMinuteResultDAO = exports.VideoDAO = exports.UserPushNotificationTokenDAO = exports.UserDAO = exports.StudyDAO = exports.ReportConfigurationDAO = exports.MessageDAO = exports.FolderDAO = exports.ChatDAO = exports.CameraDAO = exports.BatchDAO = exports.AuthDAO = void 0;
|
|
7
7
|
// DAOs
|
|
8
8
|
var auth_dao_1 = require("./dao/auth/auth.dao");
|
|
9
9
|
Object.defineProperty(exports, "AuthDAO", { enumerable: true, get: function () { return auth_dao_1.AuthDAO; } });
|
|
10
|
+
var batch_dao_1 = require("./dao/batch/batch.dao");
|
|
11
|
+
Object.defineProperty(exports, "BatchDAO", { enumerable: true, get: function () { return batch_dao_1.BatchDAO; } });
|
|
10
12
|
var camera_dao_1 = require("./dao/camera/camera.dao");
|
|
11
13
|
Object.defineProperty(exports, "CameraDAO", { enumerable: true, get: function () { return camera_dao_1.CameraDAO; } });
|
|
12
14
|
var chat_dao_1 = require("./dao/chat/chat.dao");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO;AACP,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,sDAAoD;AAA3C,uGAAA,SAAS,OAAA;AAClB,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,sDAAoD;AAA3C,uGAAA,SAAS,OAAA;AAClB,yDAAuD;AAA9C,yGAAA,UAAU,OAAA;AACnB,gGAA6F;AAApF,kIAAA,sBAAsB,OAAA;AAC/B,mDAAiD;AAAxC,qGAAA,QAAQ,OAAA;AACjB,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,wHAAmH;AAA1G,gJAAA,4BAA4B,OAAA;AACrC,mDAAiD;AAAxC,qGAAA,QAAQ,OAAA;AACjB,mEAAkE;AAAzD,4HAAA,oBAAoB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO;AACP,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,mDAAiD;AAAxC,qGAAA,QAAQ,OAAA;AACjB,sDAAoD;AAA3C,uGAAA,SAAS,OAAA;AAClB,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,sDAAoD;AAA3C,uGAAA,SAAS,OAAA;AAClB,yDAAuD;AAA9C,yGAAA,UAAU,OAAA;AACnB,gGAA6F;AAApF,kIAAA,sBAAsB,OAAA;AAC/B,mDAAiD;AAAxC,qGAAA,QAAQ,OAAA;AACjB,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,wHAAmH;AAA1G,gJAAA,4BAA4B,OAAA;AACrC,mDAAiD;AAAxC,qGAAA,QAAQ,OAAA;AACjB,mEAAkE;AAAzD,4HAAA,oBAAoB,OAAA;AA2C7B,sEAA2C;AAClC,sBADF,wBAAW,CACE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IFolder } from "../folder/folder.interfaces";
|
|
2
|
+
export interface IBatch {
|
|
3
|
+
id: number;
|
|
4
|
+
uuid: string;
|
|
5
|
+
folderId: number;
|
|
6
|
+
status: "PENDING" | "IN_PROGRESS" | "COMPLETED" | "FAILED";
|
|
7
|
+
totalVideos: number;
|
|
8
|
+
completedVideos: number;
|
|
9
|
+
failedVideos: number;
|
|
10
|
+
created_at: string;
|
|
11
|
+
updated_at: string;
|
|
12
|
+
folder?: IFolder;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/batch/batch.interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { IFolder } from "../folder/folder.interfaces";
|
|
2
|
+
export interface ITrimPeriod {
|
|
3
|
+
startTime: string;
|
|
4
|
+
endTime: string;
|
|
5
|
+
}
|
|
2
6
|
export interface IVideo {
|
|
3
7
|
id: number;
|
|
4
8
|
uuid: string;
|
|
@@ -20,6 +24,10 @@ export interface IVideo {
|
|
|
20
24
|
hlsPlaylist: string | null;
|
|
21
25
|
videoSizeMB: number | null;
|
|
22
26
|
streamingMetadata: Record<string, any> | null;
|
|
27
|
+
recordingStartedAt?: Date;
|
|
28
|
+
trimEnabled?: boolean;
|
|
29
|
+
trimPeriods?: ITrimPeriod[] | null;
|
|
30
|
+
batchId?: number | null;
|
|
23
31
|
created_at: string;
|
|
24
32
|
updated_at: string;
|
|
25
33
|
folder?: IFolder;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { Knex } from "knex";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Migration: Add Recording Time, Video Trimming, and Batch Upload Features
|
|
5
|
+
*
|
|
6
|
+
* This migration implements three major features:
|
|
7
|
+
* 1. Recording Start Time - REQUIRED field for all videos (TIMESTAMPTZ in UTC)
|
|
8
|
+
* 2. Video Trimming - Optional datetime-based trimming with frame-skipping
|
|
9
|
+
* 3. Batch Upload - Up to 50 videos in all-or-nothing transaction
|
|
10
|
+
*
|
|
11
|
+
* FK Pattern: video_batch table uses id (INTEGER) for FKs, uuid (UUID) for external API
|
|
12
|
+
*/
|
|
13
|
+
export async function up(knex: Knex): Promise<void> {
|
|
14
|
+
// Step 1: Create video_batch table with proper id/uuid pattern
|
|
15
|
+
await knex.schema.createTable("video_batch", (table) => {
|
|
16
|
+
table
|
|
17
|
+
.increments("id")
|
|
18
|
+
.primary()
|
|
19
|
+
.comment("Primary key for internal foreign key relationships");
|
|
20
|
+
|
|
21
|
+
table
|
|
22
|
+
.uuid("uuid")
|
|
23
|
+
.notNullable()
|
|
24
|
+
.unique()
|
|
25
|
+
.defaultTo(knex.raw("uuid_generate_v4()"))
|
|
26
|
+
.comment("UUID for external API communication");
|
|
27
|
+
|
|
28
|
+
table
|
|
29
|
+
.integer("folderId")
|
|
30
|
+
.unsigned()
|
|
31
|
+
.notNullable()
|
|
32
|
+
.references("id")
|
|
33
|
+
.inTable("folders")
|
|
34
|
+
.onDelete("CASCADE")
|
|
35
|
+
.comment("Foreign key to folders table");
|
|
36
|
+
|
|
37
|
+
table
|
|
38
|
+
.enu("status", ["PENDING", "IN_PROGRESS", "COMPLETED", "FAILED"])
|
|
39
|
+
.notNullable()
|
|
40
|
+
.defaultTo("PENDING")
|
|
41
|
+
.comment("Status of the batch upload");
|
|
42
|
+
|
|
43
|
+
table
|
|
44
|
+
.integer("totalVideos")
|
|
45
|
+
.notNullable()
|
|
46
|
+
.defaultTo(0)
|
|
47
|
+
.comment("Total number of videos in batch");
|
|
48
|
+
|
|
49
|
+
table
|
|
50
|
+
.integer("completedVideos")
|
|
51
|
+
.notNullable()
|
|
52
|
+
.defaultTo(0)
|
|
53
|
+
.comment("Number of successfully created videos");
|
|
54
|
+
|
|
55
|
+
table
|
|
56
|
+
.integer("failedVideos")
|
|
57
|
+
.notNullable()
|
|
58
|
+
.defaultTo(0)
|
|
59
|
+
.comment("Number of failed videos");
|
|
60
|
+
|
|
61
|
+
table.timestamps(true, true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Step 2: Add recording time, trimming, and batch columns to video table
|
|
65
|
+
await knex.schema.alterTable("video", (table) => {
|
|
66
|
+
table
|
|
67
|
+
.timestamp("recordingStartedAt", { useTz: true })
|
|
68
|
+
.nullable()
|
|
69
|
+
.comment("Recording start time in UTC - null for backward compatibility");
|
|
70
|
+
|
|
71
|
+
table
|
|
72
|
+
.boolean("trimEnabled")
|
|
73
|
+
.notNullable()
|
|
74
|
+
.defaultTo(false)
|
|
75
|
+
.comment("Whether video trimming is enabled");
|
|
76
|
+
|
|
77
|
+
table
|
|
78
|
+
.jsonb("trimPeriods")
|
|
79
|
+
.nullable()
|
|
80
|
+
.comment(
|
|
81
|
+
"Array of trim periods with startTime and endTime in ISO 8601 format",
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
table
|
|
85
|
+
.integer("batchId")
|
|
86
|
+
.unsigned()
|
|
87
|
+
.nullable()
|
|
88
|
+
.references("id")
|
|
89
|
+
.inTable("video_batch")
|
|
90
|
+
.withKeyName("fk_video_batch")
|
|
91
|
+
.onDelete("SET NULL")
|
|
92
|
+
.comment("Foreign key to video_batch table (numerical ID, NOT UUID)");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Step 3: Create indices for performance optimization
|
|
96
|
+
|
|
97
|
+
// Index for chronological queries by folder and recording time
|
|
98
|
+
await knex.raw(`
|
|
99
|
+
CREATE INDEX idx_videos_folder_recording
|
|
100
|
+
ON video("folderId", "recordingStartedAt")
|
|
101
|
+
WHERE "recordingStartedAt" IS NOT NULL
|
|
102
|
+
`);
|
|
103
|
+
|
|
104
|
+
// Index for batch operations
|
|
105
|
+
await knex.raw(`
|
|
106
|
+
CREATE INDEX idx_videos_batch
|
|
107
|
+
ON video("batchId")
|
|
108
|
+
WHERE "batchId" IS NOT NULL
|
|
109
|
+
`);
|
|
110
|
+
|
|
111
|
+
// Index for trimming filter
|
|
112
|
+
await knex.raw(`
|
|
113
|
+
CREATE INDEX idx_videos_trimming
|
|
114
|
+
ON video("trimEnabled")
|
|
115
|
+
WHERE "trimEnabled" = true
|
|
116
|
+
`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function down(knex: Knex): Promise<void> {
|
|
120
|
+
// Drop indices first
|
|
121
|
+
await knex.raw(`DROP INDEX IF EXISTS idx_videos_folder_recording`);
|
|
122
|
+
await knex.raw(`DROP INDEX IF EXISTS idx_videos_batch`);
|
|
123
|
+
await knex.raw(`DROP INDEX IF EXISTS idx_videos_trimming`);
|
|
124
|
+
|
|
125
|
+
// Drop columns from video table
|
|
126
|
+
await knex.schema.alterTable("video", (table) => {
|
|
127
|
+
table.dropColumn("recordingStartedAt");
|
|
128
|
+
table.dropColumn("trimEnabled");
|
|
129
|
+
table.dropColumn("trimPeriods");
|
|
130
|
+
table.dropColumn("batchId");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Drop video_batch table
|
|
134
|
+
await knex.schema.dropTableIfExists("video_batch");
|
|
135
|
+
}
|