From 83aca9300e5221d7bc88cce5e2f34922623b5e1e Mon Sep 17 00:00:00 2001 From: dal Date: Mon, 22 Sep 2025 08:42:35 -0600 Subject: [PATCH 1/3] percentage instruction fix so llm is better at them --- .../metrics/helpers/metric-tool-description.txt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/ai/src/tools/visualization-tools/metrics/helpers/metric-tool-description.txt b/packages/ai/src/tools/visualization-tools/metrics/helpers/metric-tool-description.txt index 23954e613..9460411f8 100644 --- a/packages/ai/src/tools/visualization-tools/metrics/helpers/metric-tool-description.txt +++ b/packages/ai/src/tools/visualization-tools/metrics/helpers/metric-tool-description.txt @@ -104,7 +104,7 @@ Only utilize the required/default fields unless the user specifically requests t # style: percent # replaceMissingDataWith: 0 # numberSeparatorStyle: ',' -# multiplier: 100 # if calculated and not already multiplied +# multiplier: 100 # Use 100 if SQL returns 0.75 for 75%; use 1 if SQL returns 75 for 75% # minimumFractionDigits: 1 # maximumFractionDigits: 2 # ------------------------------------- @@ -348,15 +348,21 @@ definitions: type: string enum: - currency # Note: The "$" sign is automatically prepended. - - percent # Note: "%" sign is appended. For percentage values: - # - If the value comes directly from a database column, use multiplier: 1 - # - If the value is calculated in your SQL query and not already multiplied by 100, use multiplier: 100 + - percent # Note: "%" sign is automatically appended as a suffix. + # IMPORTANT: You MUST analyze the SQL query to determine the correct multiplier: + # - If SQL returns decimal ratios (e.g., 0.75 for 75%), use multiplier: 100 + # - If SQL returns percentage values (e.g., 75 for 75%), use multiplier: 1 (or omit it) - number - date # Note: For date columns, consider setting xAxisTimeInterval in xAxisConfig to control date grouping (day, week, month, quarter, year) - string multiplier: type: number - description: Value to multiply the number by before display. Default value is 1. For percentages, the multiplier depends on how the data is sourced: if the value comes directly from a database column, use multiplier: 1; if the value is calculated in your SQL query and not already multiplied by 100, use multiplier: 100. + description: | + Value to multiply the number by before display. Default: 1. + For percentages with style: percent, you MUST examine the SQL query and data format: + - If SQL returns decimal ratios (e.g., 0.75), use multiplier: 100 to convert to percentage (75%) + - If SQL returns percentage values (e.g., 75), use multiplier: 1 or omit this field + The agent must analyze the actual SQL query and understand the data format, not make assumptions. displayName: type: string description: Custom display name for the column From e68032ab8d56f5cb9290da664911ebc75080c8e1 Mon Sep 17 00:00:00 2001 From: dal Date: Mon, 22 Sep 2025 08:59:25 -0600 Subject: [PATCH 2/3] lint errors --- packages/database/biome.json | 3 +- packages/database/drizzle.config.ts | 10 ++++--- packages/database/src/connection.ts | 28 +++++++++++++------ ...check-dashboards-containing-metric.test.ts | 2 +- .../check-reports-containing-metric.test.ts | 2 +- .../docs/get-organization-docs.test.ts | 8 +++--- .../src/queries/docs/upsert-doc.test.ts | 8 +++--- .../src/queries/shortcuts/create-shortcut.ts | 5 ++-- .../src/queries/shortcuts/update-shortcut.ts | 2 +- 9 files changed, 41 insertions(+), 27 deletions(-) diff --git a/packages/database/biome.json b/packages/database/biome.json index 726c0c97f..5c3aacb7b 100644 --- a/packages/database/biome.json +++ b/packages/database/biome.json @@ -2,7 +2,8 @@ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "extends": ["../../biome.json"], "files": { - "include": ["src/**/*", "scripts/**/*"] + "include": ["src/**/*"], + "ignore": ["scripts/**/*"] }, "overrides": [ { diff --git a/packages/database/drizzle.config.ts b/packages/database/drizzle.config.ts index f1986929d..851452039 100644 --- a/packages/database/drizzle.config.ts +++ b/packages/database/drizzle.config.ts @@ -11,12 +11,14 @@ if (!connectionString) { } // Disable SSL for local development -const isDevelopment = process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development'; +const isDevelopment = + process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development'; // Append sslmode=disable for local development if not already present -const dbUrl = isDevelopment && !connectionString.includes('sslmode=') - ? `${connectionString}?sslmode=disable` - : connectionString; +const dbUrl = + isDevelopment && !connectionString.includes('sslmode=') + ? `${connectionString}?sslmode=disable` + : connectionString; export default defineConfig({ schema: './src/schema.ts', diff --git a/packages/database/src/connection.ts b/packages/database/src/connection.ts index 880af03d9..c01cae688 100644 --- a/packages/database/src/connection.ts +++ b/packages/database/src/connection.ts @@ -1,6 +1,6 @@ +import * as path from 'node:path'; +import { fileURLToPath } from 'node:url'; import { config } from 'dotenv'; -import * as path from 'path'; -import { fileURLToPath } from 'url'; // Get the directory name for ES modules const __filename = fileURLToPath(import.meta.url); @@ -61,18 +61,28 @@ export function initializePool>( // Create postgres client with pool configuration // Disable SSL for local development - const isDevelopment = process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development'; - - console.log('Database connection - ENVIRONMENT:', process.env.ENVIRONMENT, 'NODE_ENV:', process.env.NODE_ENV, 'isDevelopment:', isDevelopment); - + const isDevelopment = + process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development'; + + console.log( + 'Database connection - ENVIRONMENT:', + process.env.ENVIRONMENT, + 'NODE_ENV:', + process.env.NODE_ENV, + 'isDevelopment:', + isDevelopment + ); + globalPool = postgres(connectionString, { max: poolSize, idle_timeout: 30, connect_timeout: 30, prepare: true, - ssl: isDevelopment ? false : { - rejectUnauthorized: false, // Allow self-signed certificates - }, + ssl: isDevelopment + ? false + : { + rejectUnauthorized: false, // Allow self-signed certificates + }, ...config, }); diff --git a/packages/database/src/queries/cascading-permissions/check-dashboards-containing-metric.test.ts b/packages/database/src/queries/cascading-permissions/check-dashboards-containing-metric.test.ts index addc6ac45..a1c8c10dd 100644 --- a/packages/database/src/queries/cascading-permissions/check-dashboards-containing-metric.test.ts +++ b/packages/database/src/queries/cascading-permissions/check-dashboards-containing-metric.test.ts @@ -10,7 +10,7 @@ vi.mock('../../connection', () => ({ // Mock drizzle-orm vi.mock('drizzle-orm', async (importOriginal) => { - const actual = (await importOriginal()) as any; + const actual = (await importOriginal()) as Record; return { ...actual, sql: actual.sql, diff --git a/packages/database/src/queries/cascading-permissions/check-reports-containing-metric.test.ts b/packages/database/src/queries/cascading-permissions/check-reports-containing-metric.test.ts index 8c3ecbf19..1b83022e4 100644 --- a/packages/database/src/queries/cascading-permissions/check-reports-containing-metric.test.ts +++ b/packages/database/src/queries/cascading-permissions/check-reports-containing-metric.test.ts @@ -10,7 +10,7 @@ vi.mock('../../connection', () => ({ // Mock drizzle-orm vi.mock('drizzle-orm', async (importOriginal) => { - const actual = (await importOriginal()) as any; + const actual = (await importOriginal()) as Record; return { ...actual, sql: actual.sql, diff --git a/packages/database/src/queries/docs/get-organization-docs.test.ts b/packages/database/src/queries/docs/get-organization-docs.test.ts index 8041d9c53..68eda7d01 100644 --- a/packages/database/src/queries/docs/get-organization-docs.test.ts +++ b/packages/database/src/queries/docs/get-organization-docs.test.ts @@ -82,10 +82,10 @@ describe('getOrganizationDocs', () => { organizationId: '123e4567-e89b-12d3-a456-426614174000', }; - let mockSelect: any; - let mockFrom: any; - let mockWhere: any; - let mockOrderBy: any; + let mockSelect: ReturnType; + let mockFrom: ReturnType; + let mockWhere: ReturnType; + let mockOrderBy: ReturnType; beforeEach(() => { vi.clearAllMocks(); diff --git a/packages/database/src/queries/docs/upsert-doc.test.ts b/packages/database/src/queries/docs/upsert-doc.test.ts index e5aa68929..c48bcb326 100644 --- a/packages/database/src/queries/docs/upsert-doc.test.ts +++ b/packages/database/src/queries/docs/upsert-doc.test.ts @@ -124,10 +124,10 @@ describe('upsertDoc', () => { organizationId: '123e4567-e89b-12d3-a456-426614174000', }; - let mockInsert: any; - let mockValues: any; - let mockOnConflictDoUpdate: any; - let mockReturning: any; + let mockInsert: ReturnType; + let mockValues: ReturnType; + let mockOnConflictDoUpdate: ReturnType; + let mockReturning: ReturnType; beforeEach(() => { vi.clearAllMocks(); diff --git a/packages/database/src/queries/shortcuts/create-shortcut.ts b/packages/database/src/queries/shortcuts/create-shortcut.ts index 2d5a4feb6..0be571c4d 100644 --- a/packages/database/src/queries/shortcuts/create-shortcut.ts +++ b/packages/database/src/queries/shortcuts/create-shortcut.ts @@ -87,9 +87,10 @@ export async function createShortcut(input: CreateShortcutInput) { .returning(); return created; - } catch (error: any) { + } catch (error: unknown) { // Handle unique constraint violation - if (error?.code === '23505' && error?.constraint?.includes('unique')) { + const dbError = error as { code?: string; constraint?: string }; + if (dbError?.code === '23505' && dbError?.constraint?.includes('unique')) { throw new Error(`Shortcut with name '${validated.name}' already exists`); } throw error; diff --git a/packages/database/src/queries/shortcuts/update-shortcut.ts b/packages/database/src/queries/shortcuts/update-shortcut.ts index 7f3b209eb..7c54a694a 100644 --- a/packages/database/src/queries/shortcuts/update-shortcut.ts +++ b/packages/database/src/queries/shortcuts/update-shortcut.ts @@ -16,7 +16,7 @@ export type UpdateShortcutInput = z.infer; export async function updateShortcut(input: UpdateShortcutInput) { const validated = UpdateShortcutInputSchema.parse(input); - const updateData: Record = { + const updateData: Record = { updatedBy: validated.updatedBy, updatedAt: new Date().toISOString(), }; From 1adad1b6e9f9a16c220133942505d9929da1b199 Mon Sep 17 00:00:00 2001 From: dal Date: Mon, 22 Sep 2025 09:01:09 -0600 Subject: [PATCH 3/3] ssl through url --- packages/database/src/connection.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/database/src/connection.ts b/packages/database/src/connection.ts index 880af03d9..2ce33104d 100644 --- a/packages/database/src/connection.ts +++ b/packages/database/src/connection.ts @@ -60,19 +60,12 @@ export function initializePool>( } // Create postgres client with pool configuration - // Disable SSL for local development - const isDevelopment = process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development'; - - console.log('Database connection - ENVIRONMENT:', process.env.ENVIRONMENT, 'NODE_ENV:', process.env.NODE_ENV, 'isDevelopment:', isDevelopment); - + // SSL is controlled via the connection string (e.g., ?sslmode=require) globalPool = postgres(connectionString, { max: poolSize, idle_timeout: 30, connect_timeout: 30, prepare: true, - ssl: isDevelopment ? false : { - rejectUnauthorized: false, // Allow self-signed certificates - }, ...config, });