From fe1ccb303a98f93928e3a79b5f2d8e1672cc7c55 Mon Sep 17 00:00:00 2001 From: dal Date: Thu, 21 Aug 2025 21:31:31 -0600 Subject: [PATCH] Refactor metric data retrieval to enhance type handling and metadata generation - Updated getMetricDataHandler to convert query results into a consistent type format (string | number | null). - Improved metadata construction for query results, including detailed type mapping for database fields. - Changed API call in the web client to use mainApiV2 for metric data requests. --- .../api/v2/metric_files/get-metric-data.ts | 103 ++++++++++++++++-- .../src/api/buster_rest/metrics/requests.ts | 2 +- 2 files changed, 97 insertions(+), 8 deletions(-) diff --git a/apps/server/src/api/v2/metric_files/get-metric-data.ts b/apps/server/src/api/v2/metric_files/get-metric-data.ts index 32f04afb0..6559592e4 100644 --- a/apps/server/src/api/v2/metric_files/get-metric-data.ts +++ b/apps/server/src/api/v2/metric_files/get-metric-data.ts @@ -122,16 +122,105 @@ export async function getMetricDataHandler( const hasMoreRecords = queryResult.rows.length > queryLimit; // Trim results to requested limit if we have more - const data = hasMoreRecords ? queryResult.rows.slice(0, queryLimit) : queryResult.rows; + const rawData = hasMoreRecords ? queryResult.rows.slice(0, queryLimit) : queryResult.rows; + + // Convert data to match expected type (string | number | null) + const data = rawData.map((row) => { + const typedRow: Record = {}; + for (const [key, value] of Object.entries(row)) { + if (value === null || typeof value === 'string' || typeof value === 'number') { + typedRow[key] = value; + } else if (typeof value === 'boolean') { + typedRow[key] = value.toString(); + } else if (value instanceof Date) { + typedRow[key] = value.toISOString(); + } else { + // Convert other types to string (JSON objects, arrays, etc) + typedRow[key] = JSON.stringify(value); + } + } + return typedRow; + }); + + // Build metadata from query result with required fields + const columnMetadata = queryResult.fields.map((field) => { + // Determine simple type based on field type + const simpleType = + field.type.includes('int') || + field.type.includes('float') || + field.type.includes('decimal') || + field.type.includes('numeric') || + field.type === 'number' + ? 'number' + : field.type.includes('date') || field.type.includes('time') + ? 'date' + : 'text'; + + return { + name: field.name, + // Map common database types to supported types + type: (field.type.toLowerCase().includes('varchar') + ? 'varchar' + : field.type.toLowerCase().includes('char') + ? 'char' + : field.type.toLowerCase().includes('text') + ? 'text' + : field.type.toLowerCase().includes('int') + ? 'integer' + : field.type.toLowerCase().includes('float') + ? 'float' + : field.type.toLowerCase().includes('decimal') + ? 'decimal' + : field.type.toLowerCase().includes('numeric') + ? 'numeric' + : field.type.toLowerCase().includes('bool') + ? 'bool' + : field.type.toLowerCase().includes('date') + ? 'date' + : field.type.toLowerCase().includes('time') + ? 'timestamp' + : field.type.toLowerCase().includes('json') + ? 'json' + : 'text') as + | 'text' + | 'float' + | 'integer' + | 'date' + | 'float8' + | 'timestamp' + | 'timestamptz' + | 'bool' + | 'time' + | 'boolean' + | 'json' + | 'jsonb' + | 'int8' + | 'int4' + | 'int2' + | 'decimal' + | 'char' + | 'character varying' + | 'character' + | 'varchar' + | 'number' + | 'numeric' + | 'tinytext' + | 'mediumtext' + | 'longtext' + | 'nchar' + | 'nvarchat' + | 'ntext' + | 'float4', + min_value: '', // These would need to be calculated from actual data + max_value: '', + unique_values: 0, + simple_type: simpleType as 'text' | 'number' | 'date', + }; + }); - // Build metadata from query result const dataMetadata = { column_count: queryResult.fields.length, - column_metadata: queryResult.fields.map((field) => ({ - name: field.name, - type: field.type, - nullable: field.nullable, - })), + column_metadata: columnMetadata, row_count: data.length, }; diff --git a/apps/web/src/api/buster_rest/metrics/requests.ts b/apps/web/src/api/buster_rest/metrics/requests.ts index 171041fd1..dffefa996 100644 --- a/apps/web/src/api/buster_rest/metrics/requests.ts +++ b/apps/web/src/api/buster_rest/metrics/requests.ts @@ -41,7 +41,7 @@ export const getMetricData = async ({ version_number, password }: GetMetricDataRequest): Promise => { - return mainApi + return mainApiV2 .get(`/metric_files/${id}/data`, { params: { password, version_number } }) .then((res) => res.data); };