@tmlmobilidade/go-interfaces-labdb 20260717.1316.58
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/databases/operation.d.ts +8 -0
- package/dist/databases/operation.js +21 -0
- package/dist/databases/performance.d.ts +8 -0
- package/dist/databases/performance.js +21 -0
- package/dist/databases/simplified-apex.d.ts +14 -0
- package/dist/databases/simplified-apex.js +35 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +73 -0
- package/dist/interface.template.d.ts +125 -0
- package/dist/interface.template.js +252 -0
- package/dist/types/operation.d.ts +3 -0
- package/dist/types/operation.js +24 -0
- package/dist/types/performance.d.ts +3 -0
- package/dist/types/performance.js +8 -0
- package/dist/types/simplified-apex.d.ts +9 -0
- package/dist/types/simplified-apex.js +170 -0
- package/package.json +56 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ClickHouseInterfaceTemplate } from '../interface.template.js';
|
|
2
|
+
import { ClickHouseClient } from '@tmlmobilidade/go-clients-clickhouse';
|
|
3
|
+
import { type SimplifiedVehicleEvent } from '@tmlmobilidade/types';
|
|
4
|
+
export declare class OperationDatabase {
|
|
5
|
+
readonly vehicleEvents: ClickHouseInterfaceTemplate<SimplifiedVehicleEvent>;
|
|
6
|
+
private readonly databaseName;
|
|
7
|
+
constructor(instance: ClickHouseClient);
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { ClickHouseInterfaceTemplate } from '../interface.template.js';
|
|
3
|
+
import { simplifiedVehicleEventSchema } from '../types/operation.js';
|
|
4
|
+
/* * */
|
|
5
|
+
export class OperationDatabase {
|
|
6
|
+
//
|
|
7
|
+
//
|
|
8
|
+
// Collections
|
|
9
|
+
vehicleEvents;
|
|
10
|
+
//
|
|
11
|
+
databaseName = 'operation';
|
|
12
|
+
constructor(instance) {
|
|
13
|
+
// Create collection interfaces
|
|
14
|
+
this.vehicleEvents = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'simplified_vehicle_events', simplifiedVehicleEventSchema, {
|
|
15
|
+
engine: 'ReplacingMergeTree(created_at)',
|
|
16
|
+
orderBy: ['operational_date', 'trip_id', 'vehicle_id', 'agency_id', 'created_at'],
|
|
17
|
+
partitionBy: 'toYYYYMM(fromUnixTimestamp64Milli(created_at))',
|
|
18
|
+
primaryKey: ['operational_date', 'trip_id', 'vehicle_id'],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ClickHouseInterfaceTemplate } from '../interface.template.js';
|
|
2
|
+
import { ClickHouseClient } from '@tmlmobilidade/go-clients-clickhouse';
|
|
3
|
+
import { type DemandByAgencyByOperationalDate } from '@tmlmobilidade/go-types-performance';
|
|
4
|
+
export declare class PerformanceDatabase {
|
|
5
|
+
readonly demandByAgencyByOperationalDate: ClickHouseInterfaceTemplate<DemandByAgencyByOperationalDate>;
|
|
6
|
+
private readonly databaseName;
|
|
7
|
+
constructor(instance: ClickHouseClient);
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { ClickHouseInterfaceTemplate } from '../interface.template.js';
|
|
3
|
+
import { demandByAgencyByOperationalDateSchema } from '../types/performance.js';
|
|
4
|
+
/* * */
|
|
5
|
+
export class PerformanceDatabase {
|
|
6
|
+
//
|
|
7
|
+
//
|
|
8
|
+
// Tables
|
|
9
|
+
demandByAgencyByOperationalDate;
|
|
10
|
+
//
|
|
11
|
+
databaseName = 'performance';
|
|
12
|
+
constructor(instance) {
|
|
13
|
+
//
|
|
14
|
+
// Create the table interfaces
|
|
15
|
+
this.demandByAgencyByOperationalDate = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'demand_by_agency_by_operational_date', demandByAgencyByOperationalDateSchema, {
|
|
16
|
+
engine: 'ReplacingMergeTree(updated_at)',
|
|
17
|
+
orderBy: ['operational_date', 'agency_id'],
|
|
18
|
+
partitionBy: 'intDiv(operational_date, 100)',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ClickHouseInterfaceTemplate } from '../interface.template.js';
|
|
2
|
+
import { ClickHouseClient } from '@tmlmobilidade/go-clients-clickhouse';
|
|
3
|
+
import { type SimplifiedApexBankingTap, SimplifiedApexInspection, SimplifiedApexInspectionDecision, SimplifiedApexLocation, SimplifiedApexOnBoardRefund, SimplifiedApexOnBoardSale, SimplifiedApexValidation } from '@tmlmobilidade/go-types-apex';
|
|
4
|
+
export declare class SimplifiedApexDatabase {
|
|
5
|
+
readonly bankingTaps: ClickHouseInterfaceTemplate<SimplifiedApexBankingTap>;
|
|
6
|
+
readonly inspectionDecisions: ClickHouseInterfaceTemplate<SimplifiedApexInspectionDecision>;
|
|
7
|
+
readonly inspections: ClickHouseInterfaceTemplate<SimplifiedApexInspection>;
|
|
8
|
+
readonly locations: ClickHouseInterfaceTemplate<SimplifiedApexLocation>;
|
|
9
|
+
readonly refunds: ClickHouseInterfaceTemplate<SimplifiedApexOnBoardRefund>;
|
|
10
|
+
readonly sales: ClickHouseInterfaceTemplate<SimplifiedApexOnBoardSale>;
|
|
11
|
+
readonly validations: ClickHouseInterfaceTemplate<SimplifiedApexValidation>;
|
|
12
|
+
private readonly databaseName;
|
|
13
|
+
constructor(instance: ClickHouseClient);
|
|
14
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { ClickHouseInterfaceTemplate } from '../interface.template.js';
|
|
3
|
+
import { simplifiedApexBankingTapSchema, simplifiedApexInspectionDecisionSchema, simplifiedApexInspectionSchema, simplifiedApexLocationSchema, simplifiedApexOnBoardRefundSchema, simplifiedApexOnBoardSaleSchema, simplifiedApexValidationSchema } from '../types/simplified-apex.js';
|
|
4
|
+
/* * */
|
|
5
|
+
export class SimplifiedApexDatabase {
|
|
6
|
+
//
|
|
7
|
+
//
|
|
8
|
+
// Tables
|
|
9
|
+
bankingTaps;
|
|
10
|
+
inspectionDecisions;
|
|
11
|
+
inspections;
|
|
12
|
+
locations;
|
|
13
|
+
refunds;
|
|
14
|
+
sales;
|
|
15
|
+
validations;
|
|
16
|
+
//
|
|
17
|
+
databaseName = 'simplified_apex';
|
|
18
|
+
constructor(instance) {
|
|
19
|
+
//
|
|
20
|
+
// Setup the table options, as they are the same for all simplified APEX tables
|
|
21
|
+
const simplifiedTableOptions = {
|
|
22
|
+
engine: 'ReplacingMergeTree(updated_at)',
|
|
23
|
+
orderBy: ['agency_id', 'operational_date', 'created_at', '_id'],
|
|
24
|
+
partitionBy: 'intDiv(operational_date, 100)',
|
|
25
|
+
};
|
|
26
|
+
// Create the table interfaces
|
|
27
|
+
this.bankingTaps = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'banking_taps', simplifiedApexBankingTapSchema, simplifiedTableOptions);
|
|
28
|
+
this.inspectionDecisions = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'inspection_decisions', simplifiedApexInspectionDecisionSchema, simplifiedTableOptions);
|
|
29
|
+
this.inspections = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'inspections', simplifiedApexInspectionSchema, simplifiedTableOptions);
|
|
30
|
+
this.locations = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'locations', simplifiedApexLocationSchema, simplifiedTableOptions);
|
|
31
|
+
this.refunds = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'refunds', simplifiedApexOnBoardRefundSchema, simplifiedTableOptions);
|
|
32
|
+
this.sales = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'sales', simplifiedApexOnBoardSaleSchema, simplifiedTableOptions);
|
|
33
|
+
this.validations = new ClickHouseInterfaceTemplate(instance, this.databaseName, 'validations', simplifiedApexValidationSchema, simplifiedTableOptions);
|
|
34
|
+
}
|
|
35
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { queryFromFile, queryFromString } from '@tmlmobilidade/go-clients-clickhouse';
|
|
2
|
+
import { OperationDatabase } from './databases/operation.js';
|
|
3
|
+
import { PerformanceDatabase } from './databases/performance.js';
|
|
4
|
+
import { SimplifiedApexDatabase } from './databases/simplified-apex.js';
|
|
5
|
+
declare class LabDbClass {
|
|
6
|
+
private static _instance;
|
|
7
|
+
private readonly clickhouseClient;
|
|
8
|
+
readonly operation: OperationDatabase;
|
|
9
|
+
readonly performance: PerformanceDatabase;
|
|
10
|
+
readonly simplifiedApex: SimplifiedApexDatabase;
|
|
11
|
+
/**
|
|
12
|
+
* Establishes a connection to the Mongo database and initializes the collection.
|
|
13
|
+
* @param options Optional Mongo client connection options.
|
|
14
|
+
* @throws Error if the environment variable for the database URI is missing or if the connection fails.
|
|
15
|
+
*/
|
|
16
|
+
static getInstance(): Promise<LabDbClass>;
|
|
17
|
+
private constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Executes a query from a .sql file with optional parameter substitutions.
|
|
20
|
+
* @param filePath Absolute or relative path to the .sql file.
|
|
21
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
22
|
+
* @returns Query result rows typed as `T`.
|
|
23
|
+
* @example
|
|
24
|
+
* // Given a SQL file "get_users.sql" with the content:
|
|
25
|
+
* // SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}
|
|
26
|
+
* const users = await clickhouseService.queryFromFile<User>('get_users.sql', {
|
|
27
|
+
* start_date: '2024-01-01',
|
|
28
|
+
* end_date: '2024-12-31',
|
|
29
|
+
* });
|
|
30
|
+
*/
|
|
31
|
+
queryFromFile<T>(filePath: string, params?: Record<string, number | string>): ReturnType<typeof queryFromFile<T>>;
|
|
32
|
+
/**
|
|
33
|
+
* Executes a query from a string.
|
|
34
|
+
* @param client The ClickHouse client to use for executing the query.
|
|
35
|
+
* @param query The SQL query to execute, with optional {key} placeholders for parameters.
|
|
36
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
37
|
+
* @returns Query result rows typed as `T`.
|
|
38
|
+
* @example
|
|
39
|
+
* const users = await queryFromString<User>(clickhouseClient,
|
|
40
|
+
* 'SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}',
|
|
41
|
+
* { start_date: '2024-01-01', end_date: '2024-12-31' }
|
|
42
|
+
* );
|
|
43
|
+
*/
|
|
44
|
+
queryFromString<T>(query: string, params?: Record<string, number | string>): ReturnType<typeof queryFromString<T>>;
|
|
45
|
+
}
|
|
46
|
+
export declare const labDb: LabDbClass;
|
|
47
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { ClickHouseDatabaseClient, queryFromFile, queryFromString } from '@tmlmobilidade/go-clients-clickhouse';
|
|
3
|
+
import { asyncSingletonProxy } from '@tmlmobilidade/utils';
|
|
4
|
+
import { OperationDatabase } from './databases/operation.js';
|
|
5
|
+
import { PerformanceDatabase } from './databases/performance.js';
|
|
6
|
+
import { SimplifiedApexDatabase } from './databases/simplified-apex.js';
|
|
7
|
+
/* * */
|
|
8
|
+
class LabDbClass {
|
|
9
|
+
//
|
|
10
|
+
//
|
|
11
|
+
//
|
|
12
|
+
static _instance;
|
|
13
|
+
clickhouseClient;
|
|
14
|
+
//
|
|
15
|
+
// Databases
|
|
16
|
+
operation;
|
|
17
|
+
performance;
|
|
18
|
+
simplifiedApex;
|
|
19
|
+
/**
|
|
20
|
+
* Establishes a connection to the Mongo database and initializes the collection.
|
|
21
|
+
* @param options Optional Mongo client connection options.
|
|
22
|
+
* @throws Error if the environment variable for the database URI is missing or if the connection fails.
|
|
23
|
+
*/
|
|
24
|
+
static async getInstance() {
|
|
25
|
+
if (!LabDbClass._instance) {
|
|
26
|
+
const clickhouseClient = await ClickHouseDatabaseClient.getClient({ prefix: 'LABDB' });
|
|
27
|
+
LabDbClass._instance = new LabDbClass(clickhouseClient);
|
|
28
|
+
}
|
|
29
|
+
return LabDbClass._instance;
|
|
30
|
+
}
|
|
31
|
+
//
|
|
32
|
+
// Constructor
|
|
33
|
+
constructor(clickhouseClient) {
|
|
34
|
+
this.clickhouseClient = clickhouseClient;
|
|
35
|
+
this.operation = new OperationDatabase(this.clickhouseClient);
|
|
36
|
+
this.performance = new PerformanceDatabase(this.clickhouseClient);
|
|
37
|
+
this.simplifiedApex = new SimplifiedApexDatabase(this.clickhouseClient);
|
|
38
|
+
}
|
|
39
|
+
//
|
|
40
|
+
// Queries
|
|
41
|
+
/**
|
|
42
|
+
* Executes a query from a .sql file with optional parameter substitutions.
|
|
43
|
+
* @param filePath Absolute or relative path to the .sql file.
|
|
44
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
45
|
+
* @returns Query result rows typed as `T`.
|
|
46
|
+
* @example
|
|
47
|
+
* // Given a SQL file "get_users.sql" with the content:
|
|
48
|
+
* // SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}
|
|
49
|
+
* const users = await clickhouseService.queryFromFile<User>('get_users.sql', {
|
|
50
|
+
* start_date: '2024-01-01',
|
|
51
|
+
* end_date: '2024-12-31',
|
|
52
|
+
* });
|
|
53
|
+
*/
|
|
54
|
+
async queryFromFile(filePath, params) {
|
|
55
|
+
return await queryFromFile(this.clickhouseClient, filePath, params);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Executes a query from a string.
|
|
59
|
+
* @param client The ClickHouse client to use for executing the query.
|
|
60
|
+
* @param query The SQL query to execute, with optional {key} placeholders for parameters.
|
|
61
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
62
|
+
* @returns Query result rows typed as `T`.
|
|
63
|
+
* @example
|
|
64
|
+
* const users = await queryFromString<User>(clickhouseClient,
|
|
65
|
+
* 'SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}',
|
|
66
|
+
* { start_date: '2024-01-01', end_date: '2024-12-31' }
|
|
67
|
+
* );
|
|
68
|
+
*/
|
|
69
|
+
async queryFromString(query, params) {
|
|
70
|
+
return await queryFromString(this.clickhouseClient, query, params);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export const labDb = asyncSingletonProxy(LabDbClass);
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { ClickHouseClient, ClickhouseField, ClickHouseTableEngine, ClickHouseTableSchema, DataFormat } from '@tmlmobilidade/go-clients-clickhouse';
|
|
2
|
+
import { queryFromFile, queryFromString } from '@tmlmobilidade/go-clients-clickhouse';
|
|
3
|
+
export interface ClickhouseInterfaceTableOptions<T extends object> {
|
|
4
|
+
engine?: ClickHouseTableEngine<T>;
|
|
5
|
+
manageSchema?: boolean;
|
|
6
|
+
orderBy?: Array<ClickhouseField<T>> | ClickhouseField<T>;
|
|
7
|
+
partitionBy?: string;
|
|
8
|
+
primaryKey?: Array<ClickhouseField<T>> | ClickhouseField<T>;
|
|
9
|
+
}
|
|
10
|
+
export declare class ClickHouseInterfaceTemplate<T extends object> {
|
|
11
|
+
private readonly databaseName;
|
|
12
|
+
private readonly schema;
|
|
13
|
+
private readonly tableName;
|
|
14
|
+
private readonly tableOptions;
|
|
15
|
+
private client;
|
|
16
|
+
/**
|
|
17
|
+
* @param databaseName - The name of the database to create the interface for.
|
|
18
|
+
* @param engine - The engine of the table to create the interface for.
|
|
19
|
+
* @param schema - The schema of the table to create the interface for.
|
|
20
|
+
* @param tableName - The name of the table to create the interface for.
|
|
21
|
+
*/
|
|
22
|
+
constructor(client: ClickHouseClient, databaseName: string, tableName: string, schema: ClickHouseTableSchema<T>, options?: ClickhouseInterfaceTableOptions<T>);
|
|
23
|
+
/**
|
|
24
|
+
* Executes a COUNT query on the ClickHouse table using the service's client.
|
|
25
|
+
* @param select The columns to select in the query (e.g., `"*"`, `"column1, column2"`).
|
|
26
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
27
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
28
|
+
* @returns A promise that resolves to an array of results matching the query.
|
|
29
|
+
*/
|
|
30
|
+
count(select: string, where: string, params?: Record<string, number | string>): Promise<number>;
|
|
31
|
+
/**
|
|
32
|
+
* Executes a DELETE query on the ClickHouse table using the service's client.
|
|
33
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
34
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
35
|
+
* @returns A promise that resolves when the delete operation is complete.
|
|
36
|
+
*/
|
|
37
|
+
delete(where: string, params?: Record<string, number | string | string[]>): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Executes a DISTINCT query on the ClickHouse table using the service's client.
|
|
40
|
+
* @param select The columns to select in the query (e.g., `"*"`, `"column1, column2"`).
|
|
41
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
42
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
43
|
+
* @returns A promise that resolves to an array of distinct values matching the query.
|
|
44
|
+
*/
|
|
45
|
+
distinct<T>(field: keyof T, where: string, params?: Record<string, number | string>): Promise<T[keyof T][]>;
|
|
46
|
+
/**
|
|
47
|
+
* Provides access to the ClickHouse client instance,
|
|
48
|
+
* initializing it if it has not already been created.
|
|
49
|
+
* @returns A promise that resolves to the ClickHouse client instance.
|
|
50
|
+
* @warning Use with caution: direct access to the client allows for executing arbitrary queries.
|
|
51
|
+
*/
|
|
52
|
+
getClient(): Promise<ClickHouseClient>;
|
|
53
|
+
/**
|
|
54
|
+
* Returns the name of the database used by this service.
|
|
55
|
+
*/
|
|
56
|
+
getDatabaseName(): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Returns the name of the table used by this service.
|
|
59
|
+
*/
|
|
60
|
+
getTableName(): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* Inserts data into a specified ClickHouse table using the service's client.
|
|
63
|
+
* @param format The format of the data being inserted (default is 'JSONEachRow').
|
|
64
|
+
* @param values An array of data objects to insert into the table.
|
|
65
|
+
* @returns A promise that resolves when the data is inserted successfully.
|
|
66
|
+
*/
|
|
67
|
+
insert<T>(format: DataFormat | undefined, values: T[]): Promise<import("@clickhouse/client").InsertResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Executes a simple SELECT query on the ClickHouse table using the service's client.
|
|
70
|
+
* @param select The columns to select in the query (e.g., `"*"`, `"column1, column2"`).
|
|
71
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
72
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
73
|
+
* @returns A promise that resolves to an array of results matching the query.
|
|
74
|
+
*/
|
|
75
|
+
select(select: string, where: string, params?: Record<string, number | string>): Promise<T[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Initializes the ClickHouse client and ensures that the specified database and table exist.
|
|
78
|
+
* This method should be called before performing any operations on the database or table.
|
|
79
|
+
* It handles the asynchronous setup process and logs any errors that occur during initialization.
|
|
80
|
+
* @throws Will throw an error if the client initialization or database/table setup fails.
|
|
81
|
+
* @returns A promise that resolves when the initialization process is complete.
|
|
82
|
+
*/
|
|
83
|
+
protected init(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Optional override for custom setup logic:
|
|
86
|
+
* indexes, materialized views, constraints, etc.
|
|
87
|
+
*/
|
|
88
|
+
protected postInit(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Executes a query from a .sql file with optional parameter substitutions.
|
|
91
|
+
* @param filePath Absolute or relative path to the .sql file.
|
|
92
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
93
|
+
* @returns Query result rows typed as `T`.
|
|
94
|
+
* @example
|
|
95
|
+
* // Given a SQL file "get_users.sql" with the content:
|
|
96
|
+
* // SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}
|
|
97
|
+
* const users = await clickhouseService.queryFromFile<User>('get_users.sql', {
|
|
98
|
+
* start_date: '2024-01-01',
|
|
99
|
+
* end_date: '2024-12-31',
|
|
100
|
+
* });
|
|
101
|
+
*/
|
|
102
|
+
queryFromFile<T>(filePath: string, params?: Record<string, number | string>): ReturnType<typeof queryFromFile<T>>;
|
|
103
|
+
/**
|
|
104
|
+
* Executes a query from a string.
|
|
105
|
+
* @param client The ClickHouse client to use for executing the query.
|
|
106
|
+
* @param query The SQL query to execute, with optional {key} placeholders for parameters.
|
|
107
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
108
|
+
* @returns Query result rows typed as `T`.
|
|
109
|
+
* @example
|
|
110
|
+
* const users = await queryFromString<User>(clickhouseClient,
|
|
111
|
+
* 'SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}',
|
|
112
|
+
* { start_date: '2024-01-01', end_date: '2024-12-31' }
|
|
113
|
+
* );
|
|
114
|
+
*/
|
|
115
|
+
queryFromString<T>(query: string, params?: Record<string, number | string>): ReturnType<typeof queryFromString<T>>;
|
|
116
|
+
private ensureDatabase;
|
|
117
|
+
/**
|
|
118
|
+
* Ensures that the specified table exists in ClickHouse, creating it if it does not already exist.
|
|
119
|
+
* This method performs input validation to prevent SQL injection and logs the outcome of the operation.
|
|
120
|
+
* It constructs a CREATE TABLE query based on the provided schema and engine type, and executes it using the client.
|
|
121
|
+
* @throws Will throw an error if any of the inputs are unsafe or if the table creation query fails.
|
|
122
|
+
* @returns A promise that resolves when the table is ensured to exist.
|
|
123
|
+
*/
|
|
124
|
+
private ensureTable;
|
|
125
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { ClickHouseError, preparePositionalQueryParams, queryFromFile, queryFromString, validateSqlParam } from '@tmlmobilidade/go-clients-clickhouse';
|
|
3
|
+
import { Logger } from '@tmlmobilidade/logger';
|
|
4
|
+
export class ClickHouseInterfaceTemplate {
|
|
5
|
+
//
|
|
6
|
+
databaseName;
|
|
7
|
+
schema;
|
|
8
|
+
tableName;
|
|
9
|
+
tableOptions = {};
|
|
10
|
+
client;
|
|
11
|
+
/**
|
|
12
|
+
* @param databaseName - The name of the database to create the interface for.
|
|
13
|
+
* @param engine - The engine of the table to create the interface for.
|
|
14
|
+
* @param schema - The schema of the table to create the interface for.
|
|
15
|
+
* @param tableName - The name of the table to create the interface for.
|
|
16
|
+
*/
|
|
17
|
+
constructor(client, databaseName, tableName, schema, options = {}) {
|
|
18
|
+
this.client = client;
|
|
19
|
+
this.databaseName = databaseName;
|
|
20
|
+
this.schema = schema;
|
|
21
|
+
this.tableName = tableName;
|
|
22
|
+
this.tableOptions = {
|
|
23
|
+
engine: options.engine ?? 'MergeTree()',
|
|
24
|
+
manageSchema: options.manageSchema ?? true,
|
|
25
|
+
orderBy: options.orderBy ?? '_id',
|
|
26
|
+
partitionBy: options.partitionBy ?? undefined,
|
|
27
|
+
primaryKey: options.primaryKey ?? undefined,
|
|
28
|
+
};
|
|
29
|
+
this.init().catch((error) => {
|
|
30
|
+
Logger.error({ error, message: `CLICKHOUSE [${this.databaseName}."${this.tableName}"]: Error @ constructor(): ${error.message}` });
|
|
31
|
+
throw error;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Executes a COUNT query on the ClickHouse table using the service's client.
|
|
36
|
+
* @param select The columns to select in the query (e.g., `"*"`, `"column1, column2"`).
|
|
37
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
38
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
39
|
+
* @returns A promise that resolves to an array of results matching the query.
|
|
40
|
+
*/
|
|
41
|
+
async count(select, where, params) {
|
|
42
|
+
const result = await queryFromString(this.client, `SELECT COUNT(${select}) AS count FROM "${this.databaseName}"."${this.tableName}" WHERE ${where}`, params);
|
|
43
|
+
return result.length > 0 ? result[0].count : 0;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Executes a DELETE query on the ClickHouse table using the service's client.
|
|
47
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
48
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
49
|
+
* @returns A promise that resolves when the delete operation is complete.
|
|
50
|
+
*/
|
|
51
|
+
async delete(where, params) {
|
|
52
|
+
const preparedQuery = preparePositionalQueryParams(`DELETE FROM "${this.databaseName}"."${this.tableName}" WHERE ${where}`, params);
|
|
53
|
+
await this.client.command({
|
|
54
|
+
query: preparedQuery.query,
|
|
55
|
+
query_params: preparedQuery.query_params,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Executes a DISTINCT query on the ClickHouse table using the service's client.
|
|
60
|
+
* @param select The columns to select in the query (e.g., `"*"`, `"column1, column2"`).
|
|
61
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
62
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
63
|
+
* @returns A promise that resolves to an array of distinct values matching the query.
|
|
64
|
+
*/
|
|
65
|
+
async distinct(field, where, params) {
|
|
66
|
+
const result = await queryFromString(this.client, `SELECT DISTINCT ${String(field)} FROM "${this.databaseName}"."${this.tableName}" WHERE ${where}`, params);
|
|
67
|
+
return result.map(doc => doc[field]);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Provides access to the ClickHouse client instance,
|
|
71
|
+
* initializing it if it has not already been created.
|
|
72
|
+
* @returns A promise that resolves to the ClickHouse client instance.
|
|
73
|
+
* @warning Use with caution: direct access to the client allows for executing arbitrary queries.
|
|
74
|
+
*/
|
|
75
|
+
async getClient() {
|
|
76
|
+
if (!this.client)
|
|
77
|
+
await this.init();
|
|
78
|
+
return this.client;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Returns the name of the database used by this service.
|
|
82
|
+
*/
|
|
83
|
+
async getDatabaseName() {
|
|
84
|
+
return this.databaseName;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns the name of the table used by this service.
|
|
88
|
+
*/
|
|
89
|
+
async getTableName() {
|
|
90
|
+
return this.tableName;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Inserts data into a specified ClickHouse table using the service's client.
|
|
94
|
+
* @param format The format of the data being inserted (default is 'JSONEachRow').
|
|
95
|
+
* @param values An array of data objects to insert into the table.
|
|
96
|
+
* @returns A promise that resolves when the data is inserted successfully.
|
|
97
|
+
*/
|
|
98
|
+
async insert(format = 'JSONEachRow', values) {
|
|
99
|
+
return this.client.insert({
|
|
100
|
+
format: format,
|
|
101
|
+
table: `"${this.databaseName}"."${this.tableName}"`,
|
|
102
|
+
values: values,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Executes a simple SELECT query on the ClickHouse table using the service's client.
|
|
107
|
+
* @param select The columns to select in the query (e.g., `"*"`, `"column1, column2"`).
|
|
108
|
+
* @param where The WHERE clause to filter the results (e.g., `"id = 1"`).
|
|
109
|
+
* @param params Optional key-value substitutions applied to the WHERE clause (replaces $1, $2, etc.).
|
|
110
|
+
* @returns A promise that resolves to an array of results matching the query.
|
|
111
|
+
*/
|
|
112
|
+
async select(select, where, params) {
|
|
113
|
+
return await queryFromString(this.client, `SELECT ${select} FROM "${this.databaseName}"."${this.tableName}" WHERE ${where}`, params);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Initializes the ClickHouse client and ensures that the specified database and table exist.
|
|
117
|
+
* This method should be called before performing any operations on the database or table.
|
|
118
|
+
* It handles the asynchronous setup process and logs any errors that occur during initialization.
|
|
119
|
+
* @throws Will throw an error if the client initialization or database/table setup fails.
|
|
120
|
+
* @returns A promise that resolves when the initialization process is complete.
|
|
121
|
+
*/
|
|
122
|
+
async init() {
|
|
123
|
+
// Skip if already initialized
|
|
124
|
+
if (this.client)
|
|
125
|
+
return;
|
|
126
|
+
// Validate required properties before attempting to connect
|
|
127
|
+
if (!this.databaseName)
|
|
128
|
+
throw new Error('CLICKHOUSE: databaseName is required.');
|
|
129
|
+
if (!this.tableName)
|
|
130
|
+
throw new Error('CLICKHOUSE: tableName is required.');
|
|
131
|
+
if (this.tableOptions.manageSchema && (!this.schema || Object.entries(this.schema).length === 0)) {
|
|
132
|
+
throw new Error('CLICKHOUSE: schema is required and cannot be empty.');
|
|
133
|
+
}
|
|
134
|
+
// Only own the schema when this interface is the source of truth.
|
|
135
|
+
// External DDL owners (see `manageSchema`) skip this entirely.
|
|
136
|
+
if (this.tableOptions.manageSchema) {
|
|
137
|
+
await this.ensureDatabase();
|
|
138
|
+
await this.ensureTable();
|
|
139
|
+
}
|
|
140
|
+
await this.postInit();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Optional override for custom setup logic:
|
|
144
|
+
* indexes, materialized views, constraints, etc.
|
|
145
|
+
*/
|
|
146
|
+
async postInit() {
|
|
147
|
+
// no-op by default
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Executes a query from a .sql file with optional parameter substitutions.
|
|
151
|
+
* @param filePath Absolute or relative path to the .sql file.
|
|
152
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
153
|
+
* @returns Query result rows typed as `T`.
|
|
154
|
+
* @example
|
|
155
|
+
* // Given a SQL file "get_users.sql" with the content:
|
|
156
|
+
* // SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}
|
|
157
|
+
* const users = await clickhouseService.queryFromFile<User>('get_users.sql', {
|
|
158
|
+
* start_date: '2024-01-01',
|
|
159
|
+
* end_date: '2024-12-31',
|
|
160
|
+
* });
|
|
161
|
+
*/
|
|
162
|
+
async queryFromFile(filePath, params) {
|
|
163
|
+
return await queryFromFile(this.client, filePath, params);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Executes a query from a string.
|
|
167
|
+
* @param client The ClickHouse client to use for executing the query.
|
|
168
|
+
* @param query The SQL query to execute, with optional {key} placeholders for parameters.
|
|
169
|
+
* @param params Optional key-value substitutions applied to the query (replaces {key} placeholders).
|
|
170
|
+
* @returns Query result rows typed as `T`.
|
|
171
|
+
* @example
|
|
172
|
+
* const users = await queryFromString<User>(clickhouseClient,
|
|
173
|
+
* 'SELECT * FROM users WHERE created_at >= {start_date} AND created_at <= {end_date}',
|
|
174
|
+
* { start_date: '2024-01-01', end_date: '2024-12-31' }
|
|
175
|
+
* );
|
|
176
|
+
*/
|
|
177
|
+
async queryFromString(query, params) {
|
|
178
|
+
return await queryFromString(this.client, query, params);
|
|
179
|
+
}
|
|
180
|
+
async ensureDatabase() {
|
|
181
|
+
// Validate the inputs are safe identifiers to prevent SQL injection
|
|
182
|
+
if (!validateSqlParam(this.databaseName, false))
|
|
183
|
+
throw new Error(`CLICKHOUSE [${this.databaseName}]: Unsafe database name provided.`);
|
|
184
|
+
// Perform the query to create the database if it does not exist
|
|
185
|
+
try {
|
|
186
|
+
await this.client.command({ query: `CREATE DATABASE IF NOT EXISTS "${this.databaseName}"` });
|
|
187
|
+
Logger.info({ message: `CLICKHOUSE [${this.databaseName}]: Database created.` });
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
Logger.error({ error, message: `CLICKHOUSE [${this.databaseName}]: Error @ createDatabase(): ${error.message}` });
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Ensures that the specified table exists in ClickHouse, creating it if it does not already exist.
|
|
196
|
+
* This method performs input validation to prevent SQL injection and logs the outcome of the operation.
|
|
197
|
+
* It constructs a CREATE TABLE query based on the provided schema and engine type, and executes it using the client.
|
|
198
|
+
* @throws Will throw an error if any of the inputs are unsafe or if the table creation query fails.
|
|
199
|
+
* @returns A promise that resolves when the table is ensured to exist.
|
|
200
|
+
*/
|
|
201
|
+
async ensureTable() {
|
|
202
|
+
// Validate the inputs are safe identifiers to prevent SQL injection
|
|
203
|
+
if (!validateSqlParam(this.databaseName, false))
|
|
204
|
+
throw new Error(`CLICKHOUSE [${this.databaseName}]: Unsafe database name provided.`);
|
|
205
|
+
if (!validateSqlParam(this.tableName, false))
|
|
206
|
+
throw new Error(`CLICKHOUSE [${this.tableName}]: Unsafe table name provided.`);
|
|
207
|
+
// Validate the schema columns are safe identifiers
|
|
208
|
+
const unsafeColumns = Object.keys(this.schema).filter(key => !validateSqlParam(key, false));
|
|
209
|
+
if (unsafeColumns.length > 0)
|
|
210
|
+
throw new Error(`CLICKHOUSE [${this.tableName}]: Unsafe column names provided: ${unsafeColumns.join(', ')}.`);
|
|
211
|
+
// Ensure the database exists before creating the table
|
|
212
|
+
await this.ensureDatabase();
|
|
213
|
+
// Setup the full CREATE TABLE query
|
|
214
|
+
const createTableQuery = `
|
|
215
|
+
CREATE TABLE IF NOT EXISTS "${this.databaseName}"."${this.tableName}" (
|
|
216
|
+
${Object.entries(this.schema).map(([key, column]) => `${key} ${column.type}`).join(', ')}
|
|
217
|
+
) ENGINE = ${this.tableOptions.engine}
|
|
218
|
+
${this.tableOptions.primaryKey ? `PRIMARY KEY (${Array.isArray(this.tableOptions.primaryKey) ? this.tableOptions.primaryKey.join(', ') : this.tableOptions.primaryKey})` : ''}
|
|
219
|
+
${this.tableOptions.orderBy ? `ORDER BY (${Array.isArray(this.tableOptions.orderBy) ? this.tableOptions.orderBy.join(', ') : this.tableOptions.orderBy})` : ''}
|
|
220
|
+
${this.tableOptions.partitionBy ? `PARTITION BY (${this.tableOptions.partitionBy})` : ''}
|
|
221
|
+
`;
|
|
222
|
+
// Perform the query to create the table
|
|
223
|
+
try {
|
|
224
|
+
await this.client.command({ query: createTableQuery });
|
|
225
|
+
Logger.info({ message: `CLICKHOUSE [${this.tableName}]: Table created.` });
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
// If the error is not an ACCESS_DENIED, throw it right away
|
|
229
|
+
if (!(error instanceof ClickHouseError) || error.code !== '497') {
|
|
230
|
+
Logger.error({ error, message: `CLICKHOUSE [${this.tableName}]: Error @ createTable(): ${error.message}` });
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
// If the error is an ACCESS_DENIED, check if the table exists
|
|
234
|
+
try {
|
|
235
|
+
const resultSet = await this.client.query({
|
|
236
|
+
format: 'JSONEachRow',
|
|
237
|
+
query: `SHOW TABLES FROM "${this.databaseName}" LIKE '${this.tableName}'`,
|
|
238
|
+
});
|
|
239
|
+
const tables = await resultSet.json();
|
|
240
|
+
if (Array.isArray(tables) && tables.length > 0)
|
|
241
|
+
return;
|
|
242
|
+
Logger.error({ error, message: `CLICKHOUSE [${this.tableName}]: ACCESS_DENIED and table does not exist. ${error.message}` });
|
|
243
|
+
throw error;
|
|
244
|
+
}
|
|
245
|
+
catch (verifyError) {
|
|
246
|
+
//
|
|
247
|
+
Logger.error({ error: verifyError, message: `CLICKHOUSE [${this.tableName}]: Failed to verify table existence after ACCESS_DENIED: ${verifyError.message}` });
|
|
248
|
+
throw verifyError;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
/* * */
|
|
3
|
+
export const simplifiedVehicleEventSchema = {
|
|
4
|
+
_id: { type: 'String' },
|
|
5
|
+
agency_id: { type: 'String' },
|
|
6
|
+
created_at: { type: 'Int64' },
|
|
7
|
+
geohash: { default: 'geohashEncode(longitude, latitude, 7)', type: 'String' },
|
|
8
|
+
latitude: { type: 'Float64' },
|
|
9
|
+
longitude: { type: 'Float64' },
|
|
10
|
+
operational_date: { type: 'Date' },
|
|
11
|
+
received_at: { type: 'Int64' },
|
|
12
|
+
trip_id: { type: 'String' },
|
|
13
|
+
vehicle_id: { type: 'String' },
|
|
14
|
+
// Optional Fields
|
|
15
|
+
bearing: { type: 'Nullable(Int64)' },
|
|
16
|
+
current_status: { type: 'Nullable(String)' },
|
|
17
|
+
door: { type: 'Nullable(String)' },
|
|
18
|
+
driver_id: { type: 'Nullable(String)' },
|
|
19
|
+
extra_trip_id: { type: 'Nullable(String)' },
|
|
20
|
+
odometer: { type: 'Nullable(Int64)' },
|
|
21
|
+
pattern_id: { type: 'Nullable(String)' },
|
|
22
|
+
speed: { type: 'Nullable(Int64)' },
|
|
23
|
+
stop_id: { type: 'Nullable(String)' },
|
|
24
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type ClickHouseTableSchema } from '@tmlmobilidade/go-clients-clickhouse';
|
|
2
|
+
import { type DemandByAgencyByOperationalDate } from '@tmlmobilidade/go-types-performance';
|
|
3
|
+
export declare const demandByAgencyByOperationalDateSchema: ClickHouseTableSchema<DemandByAgencyByOperationalDate>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ClickHouseTableSchema } from '@tmlmobilidade/go-clients-clickhouse';
|
|
2
|
+
import { type SimplifiedApexBankingTap, SimplifiedApexInspection, SimplifiedApexInspectionDecision, SimplifiedApexLocation, SimplifiedApexOnBoardRefund, SimplifiedApexOnBoardSale, SimplifiedApexValidation } from '@tmlmobilidade/go-types-apex';
|
|
3
|
+
export declare const simplifiedApexBankingTapSchema: ClickHouseTableSchema<SimplifiedApexBankingTap>;
|
|
4
|
+
export declare const simplifiedApexInspectionDecisionSchema: ClickHouseTableSchema<SimplifiedApexInspectionDecision>;
|
|
5
|
+
export declare const simplifiedApexInspectionSchema: ClickHouseTableSchema<SimplifiedApexInspection>;
|
|
6
|
+
export declare const simplifiedApexLocationSchema: ClickHouseTableSchema<SimplifiedApexLocation>;
|
|
7
|
+
export declare const simplifiedApexOnBoardRefundSchema: ClickHouseTableSchema<SimplifiedApexOnBoardRefund>;
|
|
8
|
+
export declare const simplifiedApexOnBoardSaleSchema: ClickHouseTableSchema<SimplifiedApexOnBoardSale>;
|
|
9
|
+
export declare const simplifiedApexValidationSchema: ClickHouseTableSchema<SimplifiedApexValidation>;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
/* * */
|
|
3
|
+
export const simplifiedApexBankingTapSchema = {
|
|
4
|
+
_id: { type: 'UUID' },
|
|
5
|
+
agency_id: { type: 'LowCardinality(String)' },
|
|
6
|
+
apex_version: { type: 'LowCardinality(String)' },
|
|
7
|
+
banking_token: { type: 'String' },
|
|
8
|
+
card_brand: { type: 'UInt8' },
|
|
9
|
+
card_pan: { type: 'String' },
|
|
10
|
+
created_at: { type: 'Int64' },
|
|
11
|
+
device_id: { type: 'LowCardinality(String)' },
|
|
12
|
+
event_type: { type: 'UInt8' },
|
|
13
|
+
group_dimension: { type: 'Int32' },
|
|
14
|
+
is_ok: { type: 'Bool' },
|
|
15
|
+
is_ok_pcgi: { type: 'Bool' },
|
|
16
|
+
line_id: { type: 'LowCardinality(String)' },
|
|
17
|
+
mac_ase_counter_value: { type: 'UInt64' },
|
|
18
|
+
mac_sam_serial_number: { type: 'UInt64' },
|
|
19
|
+
operational_date: { type: 'UInt32' },
|
|
20
|
+
pattern_id: { type: 'LowCardinality(String)' },
|
|
21
|
+
product_id: { type: 'LowCardinality(String)' },
|
|
22
|
+
received_at: { type: 'Int64' },
|
|
23
|
+
stop_id: { type: 'LowCardinality(String)' },
|
|
24
|
+
trip_id: { type: 'Nullable(String)' },
|
|
25
|
+
updated_at: { type: 'Int64' },
|
|
26
|
+
vehicle_id: { type: 'LowCardinality(Nullable(String))' },
|
|
27
|
+
};
|
|
28
|
+
export const simplifiedApexInspectionDecisionSchema = {
|
|
29
|
+
_id: { type: 'UUID' },
|
|
30
|
+
agency_id: { type: 'LowCardinality(String)' },
|
|
31
|
+
apex_version: { type: 'LowCardinality(String)' },
|
|
32
|
+
created_at: { type: 'Int64' },
|
|
33
|
+
device_id: { type: 'LowCardinality(String)' },
|
|
34
|
+
final_control_status: { type: 'UInt8' },
|
|
35
|
+
inspection_id: { type: 'Nullable(UUID)' },
|
|
36
|
+
is_ok: { type: 'Bool' },
|
|
37
|
+
is_ok_pcgi: { type: 'Bool' },
|
|
38
|
+
mac_ase_counter_value: { type: 'UInt64' },
|
|
39
|
+
mac_sam_serial_number: { type: 'UInt64' },
|
|
40
|
+
operational_date: { type: 'UInt32' },
|
|
41
|
+
received_at: { type: 'Int64' },
|
|
42
|
+
updated_at: { type: 'Int64' },
|
|
43
|
+
};
|
|
44
|
+
export const simplifiedApexInspectionSchema = {
|
|
45
|
+
_id: { type: 'UUID' },
|
|
46
|
+
agency_id: { type: 'LowCardinality(String)' },
|
|
47
|
+
apex_version: { type: 'LowCardinality(String)' },
|
|
48
|
+
card_serial_number: { type: 'Nullable(UInt64)' },
|
|
49
|
+
control_destination_stop_id: { type: 'LowCardinality(Nullable(String))' },
|
|
50
|
+
control_origin_stop_id: { type: 'LowCardinality(Nullable(String))' },
|
|
51
|
+
control_status: { type: 'UInt8' },
|
|
52
|
+
created_at: { type: 'Int64' },
|
|
53
|
+
device_id: { type: 'LowCardinality(String)' },
|
|
54
|
+
environment_status: { type: 'UInt8' },
|
|
55
|
+
inspection_id: { type: 'Nullable(UUID)' },
|
|
56
|
+
is_ok: { type: 'Bool' },
|
|
57
|
+
is_ok_pcgi: { type: 'Bool' },
|
|
58
|
+
line_id: { type: 'LowCardinality(Nullable(String))' },
|
|
59
|
+
mac_ase_counter_value: { type: 'UInt64' },
|
|
60
|
+
mac_sam_serial_number: { type: 'UInt64' },
|
|
61
|
+
operational_date: { type: 'UInt32' },
|
|
62
|
+
pattern_id: { type: 'LowCardinality(Nullable(String))' },
|
|
63
|
+
product_id: { type: 'LowCardinality(Nullable(String))' },
|
|
64
|
+
received_at: { type: 'Int64' },
|
|
65
|
+
trip_id: { type: 'Nullable(String)' },
|
|
66
|
+
updated_at: { type: 'Int64' },
|
|
67
|
+
vehicle_id: { type: 'LowCardinality(Nullable(String))' },
|
|
68
|
+
};
|
|
69
|
+
export const simplifiedApexLocationSchema = {
|
|
70
|
+
_id: { type: 'UUID' },
|
|
71
|
+
agency_id: { type: 'LowCardinality(String)' },
|
|
72
|
+
apex_version: { type: 'LowCardinality(String)' },
|
|
73
|
+
created_at: { type: 'Int64' },
|
|
74
|
+
device_id: { type: 'LowCardinality(String)' },
|
|
75
|
+
is_ok: { type: 'Bool' },
|
|
76
|
+
is_ok_pcgi: { type: 'Bool' },
|
|
77
|
+
line_id: { type: 'LowCardinality(Nullable(String))' },
|
|
78
|
+
mac_ase_counter_value: { type: 'UInt64' },
|
|
79
|
+
mac_sam_serial_number: { type: 'UInt64' },
|
|
80
|
+
operational_date: { type: 'UInt32' },
|
|
81
|
+
pattern_id: { type: 'LowCardinality(Nullable(String))' },
|
|
82
|
+
received_at: { type: 'Int64' },
|
|
83
|
+
stop_id: { type: 'LowCardinality(Nullable(String))' },
|
|
84
|
+
trip_id: { type: 'Nullable(String)' },
|
|
85
|
+
updated_at: { type: 'Int64' },
|
|
86
|
+
vehicle_id: { type: 'LowCardinality(Nullable(String))' },
|
|
87
|
+
};
|
|
88
|
+
export const simplifiedApexOnBoardRefundSchema = {
|
|
89
|
+
_id: { type: 'UUID' },
|
|
90
|
+
agency_id: { type: 'LowCardinality(String)' },
|
|
91
|
+
apex_version: { type: 'LowCardinality(String)' },
|
|
92
|
+
card_physical_type: { type: 'UInt8' },
|
|
93
|
+
card_serial_number: { type: 'Nullable(UInt64)' },
|
|
94
|
+
created_at: { type: 'Int64' },
|
|
95
|
+
device_id: { type: 'LowCardinality(String)' },
|
|
96
|
+
is_ok: { type: 'Bool' },
|
|
97
|
+
is_ok_pcgi: { type: 'Bool' },
|
|
98
|
+
line_id: { type: 'LowCardinality(Nullable(String))' },
|
|
99
|
+
mac_ase_counter_value: { type: 'UInt64' },
|
|
100
|
+
mac_sam_serial_number: { type: 'UInt64' },
|
|
101
|
+
on_board_sale_id: { type: 'Nullable(UUID)' },
|
|
102
|
+
operational_date: { type: 'UInt32' },
|
|
103
|
+
pattern_id: { type: 'LowCardinality(Nullable(String))' },
|
|
104
|
+
payment_method: { type: 'UInt8' },
|
|
105
|
+
price: { type: 'Int32' },
|
|
106
|
+
product_id: { type: 'LowCardinality(Nullable(String))' },
|
|
107
|
+
product_quantity: { type: 'Int32' },
|
|
108
|
+
received_at: { type: 'Int64' },
|
|
109
|
+
stop_id: { type: 'LowCardinality(Nullable(String))' },
|
|
110
|
+
trip_id: { type: 'Nullable(String)' },
|
|
111
|
+
updated_at: { type: 'Int64' },
|
|
112
|
+
validation_id: { type: 'Nullable(UUID)' },
|
|
113
|
+
vehicle_id: { type: 'LowCardinality(Nullable(String))' },
|
|
114
|
+
};
|
|
115
|
+
export const simplifiedApexOnBoardSaleSchema = {
|
|
116
|
+
_id: { type: 'UUID' },
|
|
117
|
+
agency_id: { type: 'LowCardinality(String)' },
|
|
118
|
+
apex_version: { type: 'LowCardinality(String)' },
|
|
119
|
+
card_physical_type: { type: 'UInt8' },
|
|
120
|
+
card_serial_number: { type: 'Nullable(UInt64)' },
|
|
121
|
+
created_at: { type: 'Int64' },
|
|
122
|
+
device_id: { type: 'LowCardinality(String)' },
|
|
123
|
+
is_ok: { type: 'Bool' },
|
|
124
|
+
is_ok_pcgi: { type: 'Bool' },
|
|
125
|
+
is_passenger: { type: 'Bool' },
|
|
126
|
+
line_id: { type: 'LowCardinality(Nullable(String))' },
|
|
127
|
+
mac_ase_counter_value: { type: 'UInt64' },
|
|
128
|
+
mac_sam_serial_number: { type: 'UInt64' },
|
|
129
|
+
on_board_refund_id: { type: 'Nullable(UUID)' },
|
|
130
|
+
operational_date: { type: 'UInt32' },
|
|
131
|
+
pattern_id: { type: 'LowCardinality(Nullable(String))' },
|
|
132
|
+
payment_method: { type: 'UInt8' },
|
|
133
|
+
price: { type: 'Int32' },
|
|
134
|
+
product_id: { type: 'LowCardinality(Nullable(String))' },
|
|
135
|
+
product_quantity: { type: 'Int32' },
|
|
136
|
+
received_at: { type: 'Int64' },
|
|
137
|
+
stop_id: { type: 'LowCardinality(Nullable(String))' },
|
|
138
|
+
trip_id: { type: 'Nullable(String)' },
|
|
139
|
+
updated_at: { type: 'Int64' },
|
|
140
|
+
validation_id: { type: 'Nullable(UUID)' },
|
|
141
|
+
vehicle_id: { type: 'LowCardinality(Nullable(String))' },
|
|
142
|
+
};
|
|
143
|
+
export const simplifiedApexValidationSchema = {
|
|
144
|
+
_id: { type: 'UUID' },
|
|
145
|
+
agency_id: { type: 'LowCardinality(String)' },
|
|
146
|
+
apex_version: { type: 'LowCardinality(String)' },
|
|
147
|
+
card_serial_number: { type: 'Nullable(UInt64)' },
|
|
148
|
+
category: { type: 'LowCardinality(String)' },
|
|
149
|
+
created_at: { type: 'Int64' },
|
|
150
|
+
device_id: { type: 'LowCardinality(String)' },
|
|
151
|
+
event_type: { type: 'UInt8' },
|
|
152
|
+
is_ok: { type: 'Bool' },
|
|
153
|
+
is_ok_pcgi: { type: 'Bool' },
|
|
154
|
+
is_passenger: { type: 'Bool' },
|
|
155
|
+
line_id: { type: 'LowCardinality(Nullable(String))' },
|
|
156
|
+
mac_ase_counter_value: { type: 'UInt64' },
|
|
157
|
+
mac_sam_serial_number: { type: 'UInt64' },
|
|
158
|
+
on_board_refund_id: { type: 'Nullable(UUID)' },
|
|
159
|
+
on_board_sale_id: { type: 'Nullable(UUID)' },
|
|
160
|
+
operational_date: { type: 'UInt32' },
|
|
161
|
+
pattern_id: { type: 'LowCardinality(Nullable(String))' },
|
|
162
|
+
product_id: { type: 'LowCardinality(Nullable(String))' },
|
|
163
|
+
received_at: { type: 'Int64' },
|
|
164
|
+
stop_id: { type: 'LowCardinality(Nullable(String))' },
|
|
165
|
+
trip_id: { type: 'Nullable(String)' },
|
|
166
|
+
units_qty: { type: 'Nullable(Int32)' },
|
|
167
|
+
updated_at: { type: 'Int64' },
|
|
168
|
+
validation_status: { type: 'LowCardinality(String)' },
|
|
169
|
+
vehicle_id: { type: 'LowCardinality(Nullable(String))' },
|
|
170
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tmlmobilidade/go-interfaces-labdb",
|
|
3
|
+
"version": "20260717.1316.58",
|
|
4
|
+
"author": {
|
|
5
|
+
"email": "iso@tmlmobilidade.pt",
|
|
6
|
+
"name": "TML-ISO"
|
|
7
|
+
},
|
|
8
|
+
"license": "AGPL-3.0-or-later",
|
|
9
|
+
"homepage": "https://go.tmlmobilidade.pt",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/tmlmobilidade/go/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/tmlmobilidade/go.git"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"public transit",
|
|
19
|
+
"tml",
|
|
20
|
+
"transportes metropolitanos de lisboa",
|
|
21
|
+
"go"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc && resolve-tspaths",
|
|
34
|
+
"lint": "eslint ./src/ && tsc --noEmit",
|
|
35
|
+
"lint:fix": "eslint ./src/ --fix",
|
|
36
|
+
"watch": "tsc-watch --onSuccess 'resolve-tspaths'"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@tmlmobilidade/go-clients-clickhouse": "*",
|
|
40
|
+
"@tmlmobilidade/go-types-apex": "*",
|
|
41
|
+
"@tmlmobilidade/go-types-performance": "*",
|
|
42
|
+
"@tmlmobilidade/logger": "*",
|
|
43
|
+
"@tmlmobilidade/types": "*",
|
|
44
|
+
"@tmlmobilidade/utils": "*",
|
|
45
|
+
"luxon": "3.7.2",
|
|
46
|
+
"zod": "3.25.76"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@tmlmobilidade/tsconfig": "*",
|
|
50
|
+
"@types/luxon": "3.7.2",
|
|
51
|
+
"@types/node": "26.1.1",
|
|
52
|
+
"resolve-tspaths": "0.8.23",
|
|
53
|
+
"tsc-watch": "7.2.1",
|
|
54
|
+
"typescript": "6.0.3"
|
|
55
|
+
}
|
|
56
|
+
}
|