@tmscloud/tbt-knex 0.0.1

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 (58) hide show
  1. package/dist/KnexConnection.d.ts +17 -0
  2. package/dist/KnexConnection.js +81 -0
  3. package/dist/KnexConnection.js.map +1 -0
  4. package/dist/d.types.d.ts +16 -0
  5. package/dist/d.types.js +3 -0
  6. package/dist/d.types.js.map +1 -0
  7. package/dist/dao/driver-tracking/driver-tracking.dao.d.ts +42 -0
  8. package/dist/dao/driver-tracking/driver-tracking.dao.js +329 -0
  9. package/dist/dao/driver-tracking/driver-tracking.dao.js.map +1 -0
  10. package/dist/dao/gps-location/gps-location.dao.d.ts +76 -0
  11. package/dist/dao/gps-location/gps-location.dao.js +364 -0
  12. package/dist/dao/gps-location/gps-location.dao.js.map +1 -0
  13. package/dist/dao/role/role.dao.d.ts +38 -0
  14. package/dist/dao/role/role.dao.js +146 -0
  15. package/dist/dao/role/role.dao.js.map +1 -0
  16. package/dist/dao/route/route.dao.d.ts +38 -0
  17. package/dist/dao/route/route.dao.js +167 -0
  18. package/dist/dao/route/route.dao.js.map +1 -0
  19. package/dist/dao/route-assignment/route-assignment.dao.d.ts +58 -0
  20. package/dist/dao/route-assignment/route-assignment.dao.js +330 -0
  21. package/dist/dao/route-assignment/route-assignment.dao.js.map +1 -0
  22. package/dist/dao/sundays-package-version/sundays-package-version.dao.d.ts +11 -0
  23. package/dist/dao/sundays-package-version/sundays-package-version.dao.js +88 -0
  24. package/dist/dao/sundays-package-version/sundays-package-version.dao.js.map +1 -0
  25. package/dist/dao/trip/trip.dao.d.ts +102 -0
  26. package/dist/dao/trip/trip.dao.js +502 -0
  27. package/dist/dao/trip/trip.dao.js.map +1 -0
  28. package/dist/dao/user/user.dao.d.ts +74 -0
  29. package/dist/dao/user/user.dao.js +287 -0
  30. package/dist/dao/user/user.dao.js.map +1 -0
  31. package/dist/index.d.ts +19 -0
  32. package/dist/index.js +26 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/interfaces/driver-tracking/driver-tracking.interfaces.d.ts +102 -0
  35. package/dist/interfaces/driver-tracking/driver-tracking.interfaces.js +3 -0
  36. package/dist/interfaces/driver-tracking/driver-tracking.interfaces.js.map +1 -0
  37. package/dist/interfaces/gps-location/gps-location.interfaces.d.ts +30 -0
  38. package/dist/interfaces/gps-location/gps-location.interfaces.js +3 -0
  39. package/dist/interfaces/gps-location/gps-location.interfaces.js.map +1 -0
  40. package/dist/interfaces/role/role.interfaces.d.ts +8 -0
  41. package/dist/interfaces/role/role.interfaces.js +3 -0
  42. package/dist/interfaces/role/role.interfaces.js.map +1 -0
  43. package/dist/interfaces/route/route.interfaces.d.ts +23 -0
  44. package/dist/interfaces/route/route.interfaces.js +3 -0
  45. package/dist/interfaces/route/route.interfaces.js.map +1 -0
  46. package/dist/interfaces/route-assignment/route-assignment.interfaces.d.ts +18 -0
  47. package/dist/interfaces/route-assignment/route-assignment.interfaces.js +3 -0
  48. package/dist/interfaces/route-assignment/route-assignment.interfaces.js.map +1 -0
  49. package/dist/interfaces/sundays-package-version/sundays-package-version.interfaces.d.ts +6 -0
  50. package/dist/interfaces/sundays-package-version/sundays-package-version.interfaces.js +3 -0
  51. package/dist/interfaces/sundays-package-version/sundays-package-version.interfaces.js.map +1 -0
  52. package/dist/interfaces/trip/trip.interfaces.d.ts +46 -0
  53. package/dist/interfaces/trip/trip.interfaces.js +3 -0
  54. package/dist/interfaces/trip/trip.interfaces.js.map +1 -0
  55. package/dist/interfaces/user/user.interfaces.d.ts +25 -0
  56. package/dist/interfaces/user/user.interfaces.js +3 -0
  57. package/dist/interfaces/user/user.interfaces.js.map +1 -0
  58. package/package.json +52 -0
@@ -0,0 +1,17 @@
1
+ import { Knex } from "knex";
2
+ declare class KnexManager {
3
+ private static knexInstance;
4
+ /**
5
+ * Open a new connection. Reuse the already existing one if there's any.
6
+ */
7
+ static connect(config?: Knex.Config, connections?: number): Promise<Knex<any, unknown[]>>;
8
+ /**
9
+ * Devuelve la conexión activa.
10
+ */
11
+ static getConnection(): Knex<any, unknown[]>;
12
+ /**
13
+ * Cierra la conexión y destruye la instancia.
14
+ */
15
+ static disconnect(): Promise<void>;
16
+ }
17
+ export default KnexManager;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const knex_1 = require("knex");
13
+ class KnexManager {
14
+ /**
15
+ * Open a new connection. Reuse the already existing one if there's any.
16
+ */
17
+ static connect(config, connections) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ if (!KnexManager.knexInstance) {
20
+ const isLocalhost = process.env.SQL_HOST === "localhost" ||
21
+ process.env.SQL_HOST === "127.0.0.1";
22
+ const defaultConfig = {
23
+ client: "pg",
24
+ connection: {
25
+ host: process.env.SQL_HOST,
26
+ user: process.env.SQL_USER,
27
+ password: process.env.SQL_PASSWORD,
28
+ database: process.env.SQL_DB_NAME,
29
+ charset: "utf8mb4",
30
+ port: Number(process.env.SQL_PORT) || 5432,
31
+ ssl: isLocalhost ? false : { rejectUnauthorized: false },
32
+ },
33
+ pool: {
34
+ min: 1,
35
+ max: connections || 15,
36
+ idleTimeoutMillis: 20000,
37
+ acquireTimeoutMillis: 30000,
38
+ },
39
+ migrations: {
40
+ tableName: "knex_migrations",
41
+ },
42
+ };
43
+ KnexManager.knexInstance = (0, knex_1.knex)(config || defaultConfig);
44
+ try {
45
+ yield KnexManager.knexInstance.raw("SELECT 1");
46
+ console.info(`Knex connection established`);
47
+ }
48
+ catch (error) {
49
+ console.error(`Failed to establish Knex connection:`, error);
50
+ KnexManager.knexInstance = null;
51
+ throw error;
52
+ }
53
+ }
54
+ return KnexManager.knexInstance;
55
+ });
56
+ }
57
+ /**
58
+ * Devuelve la conexión activa.
59
+ */
60
+ static getConnection() {
61
+ if (!KnexManager.knexInstance) {
62
+ throw new Error("Knex connection has not been established. Call connect() first.");
63
+ }
64
+ return KnexManager.knexInstance;
65
+ }
66
+ /**
67
+ * Cierra la conexión y destruye la instancia.
68
+ */
69
+ static disconnect() {
70
+ return __awaiter(this, void 0, void 0, function* () {
71
+ if (KnexManager.knexInstance) {
72
+ yield KnexManager.knexInstance.destroy();
73
+ KnexManager.knexInstance = null;
74
+ console.info(`Knex connection closed`);
75
+ }
76
+ });
77
+ }
78
+ }
79
+ KnexManager.knexInstance = null;
80
+ exports.default = KnexManager;
81
+ //# sourceMappingURL=KnexConnection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KnexConnection.js","sourceRoot":"","sources":["../src/KnexConnection.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+BAAkC;AAElC,MAAM,WAAW;IAGf;;OAEG;IACH,MAAM,CAAO,OAAO,CAClB,MAAoB,EACpB,WAAoB;;YAEpB,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;gBAC9B,MAAM,WAAW,GACf,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,WAAW;oBACpC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,WAAW,CAAC;gBACvC,MAAM,aAAa,GAAG;oBACpB,MAAM,EAAE,IAAI;oBACZ,UAAU,EAAE;wBACV,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;wBAC1B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;wBAC1B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;wBAClC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;wBACjC,OAAO,EAAE,SAAS;wBAClB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI;wBAC1C,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE;qBACzD;oBACD,IAAI,EAAE;wBACJ,GAAG,EAAE,CAAC;wBACN,GAAG,EAAE,WAAW,IAAI,EAAE;wBACtB,iBAAiB,EAAE,KAAK;wBACxB,oBAAoB,EAAE,KAAK;qBAC5B;oBACD,UAAU,EAAE;wBACV,SAAS,EAAE,iBAAiB;qBAC7B;iBACF,CAAC;gBACF,WAAW,CAAC,YAAY,GAAG,IAAA,WAAI,EAAC,MAAM,IAAI,aAAa,CAAC,CAAC;gBACzD,IAAI,CAAC;oBACH,MAAM,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBAC/C,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;gBAC9C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;oBAC7D,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC;oBAChC,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YAED,OAAO,WAAW,CAAC,YAAY,CAAC;QAClC,CAAC;KAAA;IAED;;OAEG;IACH,MAAM,CAAC,aAAa;QAClB,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;QACJ,CAAC;QACD,OAAO,WAAW,CAAC,YAAY,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,MAAM,CAAO,UAAU;;YACrB,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;gBAC7B,MAAM,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBACzC,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC;gBAChC,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;KAAA;;AArEc,wBAAY,GAAgC,IAAI,CAAC;AAwElE,kBAAe,WAAW,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface IBaseDAO<T> {
2
+ create(item: T): Promise<T>;
3
+ getById(id: number): Promise<T | null>;
4
+ update(id: number, item: Partial<T>): Promise<T | null>;
5
+ delete(id: number): Promise<boolean>;
6
+ getAll(page: number, limit: number): Promise<IDataPaginator<T>>;
7
+ }
8
+ export interface IDataPaginator<T> {
9
+ success: boolean;
10
+ data: T[];
11
+ page: number;
12
+ limit: number;
13
+ count: number;
14
+ totalCount: number;
15
+ totalPages: number;
16
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=d.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"d.types.js","sourceRoot":"","sources":["../src/d.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { IDriverTracking, IDriverTrackingCreate, IDriverTrackingBatchCreate, IActiveDriver, ITrackingSession, ITrackingFilters } from "../../interfaces/driver-tracking/driver-tracking.interfaces";
2
+ import { IDataPaginator } from "../../d.types";
3
+ export declare class DriverTrackingDAO {
4
+ private _knex?;
5
+ private get knex();
6
+ /**
7
+ * Create a single tracking point
8
+ */
9
+ create(data: IDriverTrackingCreate): Promise<IDriverTracking>;
10
+ /**
11
+ * Batch create tracking points (for mobile uploads)
12
+ */
13
+ createBatch(userId: number, batch: IDriverTrackingBatchCreate): Promise<number>;
14
+ /**
15
+ * Get tracking points by session ID (for playback)
16
+ */
17
+ getBySessionId(sessionId: string, page?: number, limit?: number): Promise<IDataPaginator<IDriverTracking>>;
18
+ /**
19
+ * Get tracking points with filters
20
+ */
21
+ getWithFilters(filters: ITrackingFilters, page?: number, limit?: number): Promise<IDataPaginator<IDriverTracking>>;
22
+ /**
23
+ * Get all active drivers (currently navigating)
24
+ */
25
+ getActiveDrivers(): Promise<IActiveDriver[]>;
26
+ /**
27
+ * Get tracking sessions list
28
+ */
29
+ getSessions(filters: ITrackingFilters, page?: number, limit?: number): Promise<IDataPaginator<ITrackingSession>>;
30
+ /**
31
+ * End a tracking session (mark points as not navigating)
32
+ */
33
+ endSession(sessionId: string, userId: number): Promise<number>;
34
+ /**
35
+ * Get latest location for a user
36
+ */
37
+ getLatestLocationByUserId(userId: number): Promise<IDriverTracking | null>;
38
+ /**
39
+ * Delete old tracking data (cleanup)
40
+ */
41
+ deleteOlderThan(days: number): Promise<number>;
42
+ }
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DriverTrackingDAO = void 0;
16
+ const uuid_1 = require("uuid");
17
+ const KnexConnection_1 = __importDefault(require("../../KnexConnection"));
18
+ class DriverTrackingDAO {
19
+ get knex() {
20
+ if (!this._knex) {
21
+ this._knex = KnexConnection_1.default.getConnection();
22
+ }
23
+ return this._knex;
24
+ }
25
+ /**
26
+ * Create a single tracking point
27
+ */
28
+ create(data) {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ var _a;
31
+ const [result] = yield this.knex("driver_tracking")
32
+ .insert({
33
+ uuid: (0, uuid_1.v4)(),
34
+ user_id: data.user_id,
35
+ assignment_id: data.assignment_id || null,
36
+ route_id: data.route_id || null,
37
+ session_id: data.session_id,
38
+ latitude: data.latitude,
39
+ longitude: data.longitude,
40
+ accuracy: data.accuracy || null,
41
+ altitude: data.altitude || null,
42
+ speed: data.speed || null,
43
+ heading: data.heading || null,
44
+ recorded_at: data.recorded_at,
45
+ is_navigating: (_a = data.is_navigating) !== null && _a !== void 0 ? _a : true,
46
+ metadata: data.metadata ? JSON.stringify(data.metadata) : null,
47
+ })
48
+ .returning("*");
49
+ return result;
50
+ });
51
+ }
52
+ /**
53
+ * Batch create tracking points (for mobile uploads)
54
+ */
55
+ createBatch(userId, batch) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const records = batch.points.map((point) => ({
58
+ uuid: (0, uuid_1.v4)(),
59
+ user_id: userId,
60
+ assignment_id: batch.assignment_id || null,
61
+ route_id: batch.route_id || null,
62
+ session_id: batch.session_id,
63
+ latitude: point.latitude,
64
+ longitude: point.longitude,
65
+ accuracy: point.accuracy || null,
66
+ altitude: point.altitude || null,
67
+ speed: point.speed || null,
68
+ heading: point.heading || null,
69
+ recorded_at: point.recorded_at,
70
+ is_navigating: true,
71
+ metadata: point.metadata ? JSON.stringify(point.metadata) : null,
72
+ }));
73
+ const result = yield this.knex("driver_tracking").insert(records);
74
+ return records.length;
75
+ });
76
+ }
77
+ /**
78
+ * Get tracking points by session ID (for playback)
79
+ */
80
+ getBySessionId(sessionId_1) {
81
+ return __awaiter(this, arguments, void 0, function* (sessionId, page = 1, limit = 1000) {
82
+ const offset = (page - 1) * limit;
83
+ const data = yield this.knex("driver_tracking")
84
+ .where("session_id", sessionId)
85
+ .orderBy("recorded_at", "asc")
86
+ .limit(limit)
87
+ .offset(offset);
88
+ const totalCountResult = yield this.knex("driver_tracking")
89
+ .where("session_id", sessionId)
90
+ .count("* as count")
91
+ .first();
92
+ const totalCount = Number((totalCountResult === null || totalCountResult === void 0 ? void 0 : totalCountResult.count) || 0);
93
+ const totalPages = Math.ceil(totalCount / limit);
94
+ return {
95
+ success: true,
96
+ data,
97
+ page,
98
+ limit,
99
+ count: data.length,
100
+ totalCount,
101
+ totalPages,
102
+ };
103
+ });
104
+ }
105
+ /**
106
+ * Get tracking points with filters
107
+ */
108
+ getWithFilters(filters_1) {
109
+ return __awaiter(this, arguments, void 0, function* (filters, page = 1, limit = 100) {
110
+ const offset = (page - 1) * limit;
111
+ let query = this.knex("driver_tracking as dt")
112
+ .leftJoin("users as u", "dt.user_id", "u.id")
113
+ .select("dt.*", this.knex.raw(`jsonb_build_object(
114
+ 'id', u.id,
115
+ 'uuid', u.uuid,
116
+ 'email', u.email,
117
+ 'username', u.username,
118
+ 'first_name', u.first_name,
119
+ 'last_name', u.last_name
120
+ ) as user`));
121
+ // Apply filters
122
+ if (filters.user_id) {
123
+ query = query.where("dt.user_id", filters.user_id);
124
+ }
125
+ if (filters.assignment_id) {
126
+ query = query.where("dt.assignment_id", filters.assignment_id);
127
+ }
128
+ if (filters.route_id) {
129
+ query = query.where("dt.route_id", filters.route_id);
130
+ }
131
+ if (filters.session_id) {
132
+ query = query.where("dt.session_id", filters.session_id);
133
+ }
134
+ if (filters.from_date) {
135
+ query = query.where("dt.recorded_at", ">=", filters.from_date);
136
+ }
137
+ if (filters.to_date) {
138
+ query = query.where("dt.recorded_at", "<=", filters.to_date);
139
+ }
140
+ if (filters.is_navigating !== undefined) {
141
+ query = query.where("dt.is_navigating", filters.is_navigating);
142
+ }
143
+ // Get count before pagination
144
+ const countQuery = query.clone();
145
+ const totalCountResult = yield countQuery
146
+ .clearSelect()
147
+ .count("dt.id as count")
148
+ .first();
149
+ const totalCount = Number((totalCountResult === null || totalCountResult === void 0 ? void 0 : totalCountResult.count) || 0);
150
+ // Get paginated data
151
+ const data = yield query
152
+ .orderBy("dt.recorded_at", "desc")
153
+ .limit(limit)
154
+ .offset(offset);
155
+ const totalPages = Math.ceil(totalCount / limit);
156
+ return {
157
+ success: true,
158
+ data,
159
+ page,
160
+ limit,
161
+ count: data.length,
162
+ totalCount,
163
+ totalPages,
164
+ };
165
+ });
166
+ }
167
+ /**
168
+ * Get all active drivers (currently navigating)
169
+ */
170
+ getActiveDrivers() {
171
+ return __awaiter(this, void 0, void 0, function* () {
172
+ // Get the latest tracking point for each user who is currently navigating
173
+ const subquery = this.knex("driver_tracking")
174
+ .select("user_id")
175
+ .max("recorded_at as max_recorded_at")
176
+ .where("is_navigating", true)
177
+ .where("recorded_at", ">", this.knex.raw("NOW() - INTERVAL '5 minutes'"))
178
+ .groupBy("user_id");
179
+ const results = yield this.knex("driver_tracking as dt")
180
+ .join(subquery.as("latest"), function () {
181
+ this.on("dt.user_id", "=", "latest.user_id").andOn("dt.recorded_at", "=", "latest.max_recorded_at");
182
+ })
183
+ .leftJoin("users as u", "dt.user_id", "u.id")
184
+ .leftJoin("route_assignments as ra", "dt.assignment_id", "ra.id")
185
+ .leftJoin("routes as r", "ra.route_id", "r.id")
186
+ .select("dt.user_id", "dt.session_id", "dt.assignment_id", "dt.latitude", "dt.longitude", "dt.heading", "dt.speed", "dt.recorded_at", "dt.is_navigating", this.knex.raw(`jsonb_build_object(
187
+ 'id', u.id,
188
+ 'uuid', u.uuid,
189
+ 'email', u.email,
190
+ 'username', u.username,
191
+ 'first_name', u.first_name,
192
+ 'last_name', u.last_name
193
+ ) as user`), this.knex.raw(`CASE WHEN ra.id IS NOT NULL THEN jsonb_build_object(
194
+ 'id', ra.id,
195
+ 'uuid', ra.uuid,
196
+ 'status', ra.status,
197
+ 'route', jsonb_build_object('id', r.id, 'uuid', r.uuid, 'name', r.name)
198
+ ) ELSE NULL END as assignment`));
199
+ return results.map((row) => ({
200
+ user_id: row.user_id,
201
+ user: row.user,
202
+ session_id: row.session_id,
203
+ assignment_id: row.assignment_id,
204
+ assignment: row.assignment,
205
+ current_location: {
206
+ latitude: parseFloat(row.latitude),
207
+ longitude: parseFloat(row.longitude),
208
+ heading: row.heading ? parseFloat(row.heading) : null,
209
+ speed: row.speed ? parseFloat(row.speed) : null,
210
+ recorded_at: row.recorded_at,
211
+ },
212
+ is_navigating: row.is_navigating,
213
+ }));
214
+ });
215
+ }
216
+ /**
217
+ * Get tracking sessions list
218
+ */
219
+ getSessions(filters_1) {
220
+ return __awaiter(this, arguments, void 0, function* (filters, page = 1, limit = 20) {
221
+ const offset = (page - 1) * limit;
222
+ let query = this.knex("driver_tracking as dt")
223
+ .select("dt.session_id", "dt.user_id", "dt.assignment_id", "dt.route_id")
224
+ .select(this.knex.raw("MIN(dt.recorded_at) as started_at"), this.knex.raw("MAX(dt.recorded_at) as ended_at"), this.knex.raw("COUNT(*) as total_points"))
225
+ .groupBy("dt.session_id", "dt.user_id", "dt.assignment_id", "dt.route_id");
226
+ // Apply filters
227
+ if (filters.user_id) {
228
+ query = query.where("dt.user_id", filters.user_id);
229
+ }
230
+ if (filters.assignment_id) {
231
+ query = query.where("dt.assignment_id", filters.assignment_id);
232
+ }
233
+ if (filters.route_id) {
234
+ query = query.where("dt.route_id", filters.route_id);
235
+ }
236
+ if (filters.from_date) {
237
+ query = query.where("dt.recorded_at", ">=", filters.from_date);
238
+ }
239
+ if (filters.to_date) {
240
+ query = query.where("dt.recorded_at", "<=", filters.to_date);
241
+ }
242
+ // Wrap for counting and joining
243
+ const sessionsQuery = this.knex
244
+ .from(query.as("sessions"))
245
+ .leftJoin("users as u", "sessions.user_id", "u.id")
246
+ .select("sessions.*", this.knex.raw(`jsonb_build_object(
247
+ 'id', u.id,
248
+ 'uuid', u.uuid,
249
+ 'email', u.email,
250
+ 'username', u.username,
251
+ 'first_name', u.first_name,
252
+ 'last_name', u.last_name
253
+ ) as user`));
254
+ // Get count
255
+ const countResult = yield this.knex
256
+ .from(query.clone().as("count_sessions"))
257
+ .count("* as count")
258
+ .first();
259
+ const totalCount = Number((countResult === null || countResult === void 0 ? void 0 : countResult.count) || 0);
260
+ // Get paginated data
261
+ const data = yield sessionsQuery
262
+ .orderBy("sessions.started_at", "desc")
263
+ .limit(limit)
264
+ .offset(offset);
265
+ const totalPages = Math.ceil(totalCount / limit);
266
+ return {
267
+ success: true,
268
+ data: data.map((row) => ({
269
+ session_id: row.session_id,
270
+ user_id: row.user_id,
271
+ user: row.user,
272
+ assignment_id: row.assignment_id,
273
+ route_id: row.route_id,
274
+ started_at: row.started_at,
275
+ ended_at: row.ended_at,
276
+ total_points: parseInt(row.total_points),
277
+ })),
278
+ page,
279
+ limit,
280
+ count: data.length,
281
+ totalCount,
282
+ totalPages,
283
+ };
284
+ });
285
+ }
286
+ /**
287
+ * End a tracking session (mark points as not navigating)
288
+ */
289
+ endSession(sessionId, userId) {
290
+ return __awaiter(this, void 0, void 0, function* () {
291
+ const result = yield this.knex("driver_tracking")
292
+ .where("session_id", sessionId)
293
+ .where("user_id", userId)
294
+ .where("is_navigating", true)
295
+ .update({
296
+ is_navigating: false,
297
+ updated_at: new Date(),
298
+ });
299
+ return result;
300
+ });
301
+ }
302
+ /**
303
+ * Get latest location for a user
304
+ */
305
+ getLatestLocationByUserId(userId) {
306
+ return __awaiter(this, void 0, void 0, function* () {
307
+ const result = yield this.knex("driver_tracking")
308
+ .where("user_id", userId)
309
+ .orderBy("recorded_at", "desc")
310
+ .first();
311
+ return result || null;
312
+ });
313
+ }
314
+ /**
315
+ * Delete old tracking data (cleanup)
316
+ */
317
+ deleteOlderThan(days) {
318
+ return __awaiter(this, void 0, void 0, function* () {
319
+ const cutoffDate = new Date();
320
+ cutoffDate.setDate(cutoffDate.getDate() - days);
321
+ const result = yield this.knex("driver_tracking")
322
+ .where("recorded_at", "<", cutoffDate)
323
+ .delete();
324
+ return result;
325
+ });
326
+ }
327
+ }
328
+ exports.DriverTrackingDAO = DriverTrackingDAO;
329
+ //# sourceMappingURL=driver-tracking.dao.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-tracking.dao.js","sourceRoot":"","sources":["../../../src/dao/driver-tracking/driver-tracking.dao.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { IGPSLocation, IGPSLocationWithDistance, ITripLocationSummary } from "../../interfaces/gps-location/gps-location.interfaces";
2
+ import { IBaseDAO, IDataPaginator } from "../../d.types";
3
+ export declare class GPSLocationDAO implements IBaseDAO<IGPSLocation> {
4
+ private _knex?;
5
+ private get knex();
6
+ /**
7
+ * Parse JSON fields from database
8
+ */
9
+ private parseLocationJson;
10
+ /**
11
+ * Base query with joins
12
+ */
13
+ private baseQuery;
14
+ /**
15
+ * Get all GPS locations with pagination
16
+ */
17
+ getAll(page?: number, limit?: number): Promise<IDataPaginator<IGPSLocation>>;
18
+ /**
19
+ * Get GPS location by ID
20
+ */
21
+ getById(id: number): Promise<IGPSLocation | null>;
22
+ /**
23
+ * Get GPS location by UUID
24
+ */
25
+ getByUuid(uuid: string): Promise<IGPSLocation | null>;
26
+ /**
27
+ * Get current location for a trip
28
+ */
29
+ getCurrentLocationByTripId(tripId: number): Promise<IGPSLocation | null>;
30
+ /**
31
+ * Get location history for a trip
32
+ */
33
+ getLocationHistoryByTripId(tripId: number, page?: number, limit?: number): Promise<IDataPaginator<IGPSLocation>>;
34
+ /**
35
+ * Get recent locations for a trip (last N locations)
36
+ */
37
+ getRecentLocationsByTripId(tripId: number, limit?: number): Promise<IGPSLocation[]>;
38
+ /**
39
+ * Get locations by user ID
40
+ */
41
+ getLocationsByUserId(userId: number, page?: number, limit?: number): Promise<IDataPaginator<IGPSLocation>>;
42
+ /**
43
+ * Get trip location summary
44
+ */
45
+ getTripLocationSummary(tripId: number): Promise<ITripLocationSummary | null>;
46
+ /**
47
+ * Create a new GPS location
48
+ */
49
+ create(data: IGPSLocation): Promise<IGPSLocation>;
50
+ /**
51
+ * Update a GPS location by ID
52
+ */
53
+ update(id: number, data: Partial<IGPSLocation>): Promise<IGPSLocation | null>;
54
+ /**
55
+ * Delete a GPS location by ID
56
+ */
57
+ delete(id: number): Promise<boolean>;
58
+ /**
59
+ * Delete old GPS locations (older than specified hours)
60
+ */
61
+ deleteOldLocations(hoursOld?: number): Promise<number>;
62
+ /**
63
+ * Calculate distance between two GPS coordinates using Haversine formula
64
+ * Returns distance in kilometers
65
+ */
66
+ private calculateDistance;
67
+ private toRad;
68
+ /**
69
+ * Calculate total distance traveled for a trip
70
+ */
71
+ calculateTripDistance(tripId: number): Promise<number>;
72
+ /**
73
+ * Get location history with distances
74
+ */
75
+ getLocationHistoryWithDistances(tripId: number): Promise<IGPSLocationWithDistance[]>;
76
+ }