@tmlmobilidade/databases 20260330.1756.23 → 20260331.1620.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/dist/clients/go-clickhouse.js +7 -2
- package/dist/clients/go-mongo.js +3 -1
- package/dist/clients/pcgi-file-manager.js +3 -1
- package/dist/clients/pcgi-raw.js +3 -1
- package/dist/clients/pcgi-ticketing.js +3 -1
- package/dist/clients/pcgi-validations.js +3 -1
- package/dist/interfaces/apex/pcgi-transaction-entity.d.ts +383 -27
- package/dist/interfaces/simplified-apex/simplified-apex-locations.d.ts +3 -3
- package/dist/interfaces/simplified-apex/simplified-apex-on-board-refunds.d.ts +5 -5
- package/dist/interfaces/simplified-apex/simplified-apex-on-board-sales.d.ts +5 -5
- package/dist/interfaces/simplified-apex/simplified-apex-validations.d.ts +9 -10
- package/dist/interfaces/simplified-apex/simplified-apex-validations.js +2 -1
- package/dist/interfaces/vehicle-events/raw-vehicle-events-ledger.d.ts +1 -0
- package/dist/interfaces/vehicle-events/raw-vehicle-events-ledger.js +50 -0
- package/dist/interfaces/vehicle-events/raw-vehicle-events.d.ts +383 -27
- package/dist/interfaces/vehicle-events/raw-vehicle-events.js +2 -0
- package/dist/interfaces/vehicle-events/simplified-vehicle-events.d.ts +18 -1
- package/dist/interfaces/vehicle-events/simplified-vehicle-events.js +38 -0
- package/dist/templates/clickhouse.d.ts +29 -5
- package/dist/templates/clickhouse.js +34 -8
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ declare class SimplifiedVehicleEventsNewClass extends ClickHouseInterfaceTemplat
|
|
|
5
5
|
private static _instance;
|
|
6
6
|
readonly databaseName = "operation";
|
|
7
7
|
readonly orderBy = "(created_at, trip_id)";
|
|
8
|
+
readonly partitionBy = "toYYYYMMDD(fromUnixTimestamp64Milli(created_at))";
|
|
8
9
|
readonly schema: ClickHouseSchema<{
|
|
9
10
|
_id: string;
|
|
10
11
|
created_at: number & {
|
|
@@ -13,10 +14,10 @@ declare class SimplifiedVehicleEventsNewClass extends ClickHouseInterfaceTemplat
|
|
|
13
14
|
latitude: number;
|
|
14
15
|
longitude: number;
|
|
15
16
|
agency_id: string;
|
|
16
|
-
pattern_id: string | null;
|
|
17
17
|
received_at: number & {
|
|
18
18
|
__brand: "UnixTimestamp";
|
|
19
19
|
};
|
|
20
|
+
pattern_id: string | null;
|
|
20
21
|
stop_id: string | null;
|
|
21
22
|
trip_id: string;
|
|
22
23
|
vehicle_id: string;
|
|
@@ -29,6 +30,22 @@ declare class SimplifiedVehicleEventsNewClass extends ClickHouseInterfaceTemplat
|
|
|
29
30
|
extra_trip_id: string | null;
|
|
30
31
|
}>;
|
|
31
32
|
readonly tableName = "simplified_vehicle_events";
|
|
33
|
+
/**
|
|
34
|
+
* Returns the last event for a given vehicle.
|
|
35
|
+
* @param vehicleId - The ID of the vehicle.
|
|
36
|
+
* @returns The last event for the vehicle.
|
|
37
|
+
*/
|
|
38
|
+
getLastEvent(vehicleId: string, agencyId: string): Promise<null | SimplifiedVehicleEvent>;
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves the most recent event per vehicle within the given time window.
|
|
41
|
+
*
|
|
42
|
+
* @param secondsAgo - The number of seconds in the past to consider for retrieving recent positions. Defaults to 90 seconds.
|
|
43
|
+
* @returns A promise resolving to an array of SimplifiedVehicleEvent objects, each representing the latest event for a vehicle within the specified period.
|
|
44
|
+
*
|
|
45
|
+
* The method filters out events where any of vehicle_id, agency_id, or trip_id are empty or null,
|
|
46
|
+
* and also ensures latitude and longitude are not zero. Only the most recent event per vehicle is returned.
|
|
47
|
+
*/
|
|
48
|
+
getPositions(secondsAgo?: number): Promise<SimplifiedVehicleEvent[]>;
|
|
32
49
|
/**
|
|
33
50
|
* Returns the singleton instance of the subclass.
|
|
34
51
|
*/
|
|
@@ -29,8 +29,46 @@ class SimplifiedVehicleEventsNewClass extends ClickHouseInterfaceTemplate {
|
|
|
29
29
|
static _instance = null;
|
|
30
30
|
databaseName = 'operation';
|
|
31
31
|
orderBy = '(created_at, trip_id)';
|
|
32
|
+
partitionBy = 'toYYYYMMDD(fromUnixTimestamp64Milli(created_at))';
|
|
32
33
|
schema = tableSchema;
|
|
33
34
|
tableName = 'simplified_vehicle_events';
|
|
35
|
+
/**
|
|
36
|
+
* Returns the last event for a given vehicle.
|
|
37
|
+
* @param vehicleId - The ID of the vehicle.
|
|
38
|
+
* @returns The last event for the vehicle.
|
|
39
|
+
*/
|
|
40
|
+
async getLastEvent(vehicleId, agencyId) {
|
|
41
|
+
const query = `
|
|
42
|
+
SELECT *
|
|
43
|
+
FROM "${this.databaseName}"."${this.tableName}"
|
|
44
|
+
WHERE vehicle_id = '${vehicleId}'
|
|
45
|
+
AND agency_id = '${agencyId}'
|
|
46
|
+
ORDER BY created_at DESC
|
|
47
|
+
LIMIT 1
|
|
48
|
+
`;
|
|
49
|
+
const result = await this.queryFromString(query);
|
|
50
|
+
return result.length > 0 ? result[0] : null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves the most recent event per vehicle within the given time window.
|
|
54
|
+
*
|
|
55
|
+
* @param secondsAgo - The number of seconds in the past to consider for retrieving recent positions. Defaults to 90 seconds.
|
|
56
|
+
* @returns A promise resolving to an array of SimplifiedVehicleEvent objects, each representing the latest event for a vehicle within the specified period.
|
|
57
|
+
*
|
|
58
|
+
* The method filters out events where any of vehicle_id, agency_id, or trip_id are empty or null,
|
|
59
|
+
* and also ensures latitude and longitude are not zero. Only the most recent event per vehicle is returned.
|
|
60
|
+
*/
|
|
61
|
+
async getPositions(secondsAgo = 90) {
|
|
62
|
+
const query = `
|
|
63
|
+
SELECT *
|
|
64
|
+
FROM "${this.databaseName}"."${this.tableName}"
|
|
65
|
+
WHERE created_at > toUnixTimestamp64Milli(now64(3) - INTERVAL ${secondsAgo} SECOND)
|
|
66
|
+
ORDER BY created_at DESC
|
|
67
|
+
LIMIT 1 BY vehicle_id, agency_id
|
|
68
|
+
`;
|
|
69
|
+
const result = await this.queryFromString(query);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
34
72
|
/**
|
|
35
73
|
* Returns the singleton instance of the subclass.
|
|
36
74
|
*/
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ClickHouseSchema, type ClickHouseTableEngine } from '../types/index.js';
|
|
2
|
+
import { queryFromFile } from '../utils/clickhouse/query-from-file.js';
|
|
3
|
+
import { queryFromString } from '../utils/clickhouse/query-from-string.js';
|
|
2
4
|
import { type ClickHouseClient, type DataFormat } from '@clickhouse/client';
|
|
3
5
|
export declare abstract class ClickHouseInterfaceTemplate<T> {
|
|
4
6
|
protected readonly abstract databaseName: string;
|
|
@@ -6,6 +8,7 @@ export declare abstract class ClickHouseInterfaceTemplate<T> {
|
|
|
6
8
|
protected readonly abstract tableName: string;
|
|
7
9
|
protected readonly engine: ClickHouseTableEngine;
|
|
8
10
|
protected readonly orderBy: string;
|
|
11
|
+
protected readonly partitionBy: null | string;
|
|
9
12
|
private client;
|
|
10
13
|
/**
|
|
11
14
|
* Disallow direct instantiation of the service.
|
|
@@ -85,11 +88,32 @@ export declare abstract class ClickHouseInterfaceTemplate<T> {
|
|
|
85
88
|
*/
|
|
86
89
|
protected postInit(): Promise<void>;
|
|
87
90
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* @
|
|
91
|
-
* @returns
|
|
92
|
-
|
|
91
|
+
* Executes a query from a .sql file with optional parameter substitutions.
|
|
92
|
+
* @param filePath Absolute or relative path to the .sql file.
|
|
93
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
94
|
+
* @returns Query result rows typed as `T`.
|
|
95
|
+
* @example
|
|
96
|
+
* // Given a SQL file "get_users.sql" with the content:
|
|
97
|
+
* // SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}
|
|
98
|
+
* const users = await clickhouseService.queryFromFile<User>('get_users.sql', {
|
|
99
|
+
* start_date: '2024-01-01',
|
|
100
|
+
* end_date: '2024-12-31',
|
|
101
|
+
* });
|
|
102
|
+
*/
|
|
103
|
+
queryFromFile<T>(filePath: string, params?: Record<string, number | string>): ReturnType<typeof queryFromFile<T>>;
|
|
104
|
+
/**
|
|
105
|
+
* Executes a query from a string.
|
|
106
|
+
* @param client The ClickHouse client to use for executing the query.
|
|
107
|
+
* @param query The SQL query to execute, with optional {key} placeholders for parameters.
|
|
108
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
109
|
+
* @returns Query result rows typed as `T`.
|
|
110
|
+
* @example
|
|
111
|
+
* const users = await queryFromString<User>(clickhouseClient,
|
|
112
|
+
* 'SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}',
|
|
113
|
+
* { start_date: '2024-01-01', end_date: '2024-12-31' }
|
|
114
|
+
* );
|
|
115
|
+
*/
|
|
116
|
+
queryFromString<T>(query: string, params?: Record<string, number | string>): ReturnType<typeof queryFromString<T>>;
|
|
93
117
|
private ensureDatabase;
|
|
94
118
|
/**
|
|
95
119
|
* Ensures that the specified table exists in ClickHouse, creating it if it does not already exist.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* * */
|
|
2
2
|
import { preparePositionalQueryParams } from '../utils/clickhouse/prepare-positional-query-params.js';
|
|
3
|
+
import { queryFromFile } from '../utils/clickhouse/query-from-file.js';
|
|
3
4
|
import { queryFromString } from '../utils/clickhouse/query-from-string.js';
|
|
4
5
|
import { validateSqlParam } from '../utils/clickhouse/validate-sql-param.js';
|
|
5
6
|
import { Logger } from '@tmlmobilidade/logger';
|
|
@@ -7,6 +8,7 @@ import { Logger } from '@tmlmobilidade/logger';
|
|
|
7
8
|
export class ClickHouseInterfaceTemplate {
|
|
8
9
|
engine = 'ReplicatedMergeTree';
|
|
9
10
|
orderBy = '_id';
|
|
11
|
+
partitionBy = null;
|
|
10
12
|
client;
|
|
11
13
|
/**
|
|
12
14
|
* Disallow direct instantiation of the service.
|
|
@@ -127,11 +129,36 @@ export class ClickHouseInterfaceTemplate {
|
|
|
127
129
|
// no-op by default
|
|
128
130
|
}
|
|
129
131
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* @
|
|
133
|
-
* @returns
|
|
134
|
-
|
|
132
|
+
* Executes a query from a .sql file with optional parameter substitutions.
|
|
133
|
+
* @param filePath Absolute or relative path to the .sql file.
|
|
134
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
135
|
+
* @returns Query result rows typed as `T`.
|
|
136
|
+
* @example
|
|
137
|
+
* // Given a SQL file "get_users.sql" with the content:
|
|
138
|
+
* // SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}
|
|
139
|
+
* const users = await clickhouseService.queryFromFile<User>('get_users.sql', {
|
|
140
|
+
* start_date: '2024-01-01',
|
|
141
|
+
* end_date: '2024-12-31',
|
|
142
|
+
* });
|
|
143
|
+
*/
|
|
144
|
+
async queryFromFile(filePath, params) {
|
|
145
|
+
return await queryFromFile(this.client, filePath, params);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Executes a query from a string.
|
|
149
|
+
* @param client The ClickHouse client to use for executing the query.
|
|
150
|
+
* @param query The SQL query to execute, with optional {key} placeholders for parameters.
|
|
151
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
152
|
+
* @returns Query result rows typed as `T`.
|
|
153
|
+
* @example
|
|
154
|
+
* const users = await queryFromString<User>(clickhouseClient,
|
|
155
|
+
* 'SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}',
|
|
156
|
+
* { start_date: '2024-01-01', end_date: '2024-12-31' }
|
|
157
|
+
* );
|
|
158
|
+
*/
|
|
159
|
+
async queryFromString(query, params) {
|
|
160
|
+
return await queryFromString(this.client, query, params);
|
|
161
|
+
}
|
|
135
162
|
async ensureDatabase() {
|
|
136
163
|
// Validate the inputs are safe identifiers to prevent SQL injection
|
|
137
164
|
if (!validateSqlParam(this.databaseName, false))
|
|
@@ -159,8 +186,6 @@ export class ClickHouseInterfaceTemplate {
|
|
|
159
186
|
throw new Error(`CLICKHOUSE [${this.databaseName}]: Unsafe database name provided.`);
|
|
160
187
|
if (!validateSqlParam(this.tableName, false))
|
|
161
188
|
throw new Error(`CLICKHOUSE [${this.tableName}]: Unsafe table name provided.`);
|
|
162
|
-
if (!validateSqlParam(this.engine, false))
|
|
163
|
-
throw new Error(`CLICKHOUSE [${this.engine}]: Unsafe engine type provided.`);
|
|
164
189
|
// Validate the schema columns are safe identifiers
|
|
165
190
|
const unsafeColumns = Object.keys(this.schema).filter(key => !validateSqlParam(key, false));
|
|
166
191
|
if (unsafeColumns.length > 0)
|
|
@@ -172,7 +197,8 @@ export class ClickHouseInterfaceTemplate {
|
|
|
172
197
|
CREATE TABLE IF NOT EXISTS "${this.databaseName}"."${this.tableName}" ON CLUSTER default_cluster (
|
|
173
198
|
${Object.entries(this.schema).map(([key, column]) => `${key} ${column.type}`).join(', ')}
|
|
174
199
|
) ENGINE = ${this.getEngineString()}
|
|
175
|
-
ORDER BY ${this.orderBy}
|
|
200
|
+
${this.orderBy ? `ORDER BY ${this.orderBy}` : ''}
|
|
201
|
+
${this.partitionBy ? `PARTITION BY ${this.partitionBy}` : ''}
|
|
176
202
|
`;
|
|
177
203
|
// Perform the query to create the table
|
|
178
204
|
try {
|