From ade5e0b1b3aaad66b78047afc7a414bb9f993d72 Mon Sep 17 00:00:00 2001 From: zmoon460 <42328751+zmoon460@users.noreply.github.com> Date: Fri, 20 Mar 2026 20:08:56 +0800 Subject: [PATCH 1/2] Enhance unique violation check for PostgreSQL --- src/server/routes/api/downstreamApiKeys.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/server/routes/api/downstreamApiKeys.ts b/src/server/routes/api/downstreamApiKeys.ts index 423db26..78afe1e 100644 --- a/src/server/routes/api/downstreamApiKeys.ts +++ b/src/server/routes/api/downstreamApiKeys.ts @@ -22,6 +22,10 @@ function validateKeyShape(key: string): boolean { function looksLikeUniqueViolation(error: unknown): boolean { const message = (error as Error | undefined)?.message || ''; + if (runtimeDbDialect === 'postgres') { + return message.includes('duplicate key value violates unique constraint') && + message.includes('downstream_api_keys_key_unique'); + } return message.includes('UNIQUE constraint failed') && message.includes('downstream_api_keys.key'); } From da76f56721b60d841e6bbd7231156dc37a07291a Mon Sep 17 00:00:00 2001 From: zmoon460 <42328751+zmoon460@users.noreply.github.com> Date: Fri, 20 Mar 2026 20:10:12 +0800 Subject: [PATCH 2/2] Refactor parseJson to handle different value types Refactor parseJson function to handle various input types and improve null checks. --- .../services/downstreamApiKeyService.ts | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/server/services/downstreamApiKeyService.ts b/src/server/services/downstreamApiKeyService.ts index 105f6d0..88068db 100644 --- a/src/server/services/downstreamApiKeyService.ts +++ b/src/server/services/downstreamApiKeyService.ts @@ -90,13 +90,25 @@ function normalizePositiveIntegerOrNull(value: unknown): number | null { return normalized; } -function parseJson(value: string | null | undefined): unknown { - if (!value) return null; - try { - return JSON.parse(value); - } catch { - return null; +function parseJson(value: unknown): unknown { + if (value === null || value === undefined) return null; + + // PostgreSQL JSONB columns are returned as parsed objects/arrays by the pg driver + if (typeof value === 'object') { + return value; } + + // SQLite TEXT columns store JSON as strings that need parsing + if (typeof value === 'string') { + if (value === '') return null; + try { + return JSON.parse(value); + } catch { + return null; + } + } + + return null; } export function normalizeGroupNameInput(input: unknown): string | null {