From eb77ea8e7e2190bb2db05350d9a0ad8b3784e8b7 Mon Sep 17 00:00:00 2001 From: hided62 Date: Sat, 22 Aug 2026 10:51:29 +0000 Subject: [PATCH] =?UTF-8?q?fix(gateway):=20=EC=A0=84=EC=9A=A9=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4=20URL=EC=9D=84=20?= =?UTF-8?q?=EC=9A=B0=EC=84=A0=20=EC=82=AC=EC=9A=A9=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 릴리스 프로세스가 전달한 GATEWAY_DATABASE_URL을 API와 orchestrator가 직접 사용하도록 고친다. 원시 POSTGRES_* 재조합으로 특수문자 비밀번호가 깨지는 회귀를 테스트한다. --- app/gateway-api/src/gatewayPostgresConfig.ts | 17 ++++++++++ app/gateway-api/src/index.ts | 1 + .../src/orchestrator/orchestratorServer.ts | 4 +-- app/gateway-api/src/server.ts | 4 +-- .../test/gatewayPostgresConfig.test.ts | 33 +++++++++++++++++++ 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 app/gateway-api/src/gatewayPostgresConfig.ts create mode 100644 app/gateway-api/test/gatewayPostgresConfig.test.ts diff --git a/app/gateway-api/src/gatewayPostgresConfig.ts b/app/gateway-api/src/gatewayPostgresConfig.ts new file mode 100644 index 00000000..dd14107e --- /dev/null +++ b/app/gateway-api/src/gatewayPostgresConfig.ts @@ -0,0 +1,17 @@ +import { resolvePostgresConfigFromEnv, type PostgresConfig } from '@sammo-ts/infra'; + +export const resolveGatewayPostgresConfigFromEnv = ( + env: NodeJS.ProcessEnv = process.env, + schema?: string +): PostgresConfig => { + const gatewayDatabaseUrl = env.GATEWAY_DATABASE_URL?.trim(); + return resolvePostgresConfigFromEnv({ + env: gatewayDatabaseUrl + ? { + ...env, + DATABASE_URL: gatewayDatabaseUrl, + } + : env, + schema, + }); +}; diff --git a/app/gateway-api/src/index.ts b/app/gateway-api/src/index.ts index 11e97eee..3c3f81d5 100644 --- a/app/gateway-api/src/index.ts +++ b/app/gateway-api/src/index.ts @@ -3,6 +3,7 @@ import { runGatewayOrchestrator } from './orchestrator/orchestratorServer.js'; import { runProfileSeedCli } from './orchestrator/profileSeedCli.js'; export * from './config.js'; +export * from './gatewayPostgresConfig.js'; export * from './context.js'; export * from './router.js'; export * from './server.js'; diff --git a/app/gateway-api/src/orchestrator/orchestratorServer.ts b/app/gateway-api/src/orchestrator/orchestratorServer.ts index 6485e593..16fdad9d 100644 --- a/app/gateway-api/src/orchestrator/orchestratorServer.ts +++ b/app/gateway-api/src/orchestrator/orchestratorServer.ts @@ -1,16 +1,16 @@ import { createGatewayPostgresConnector, type GatewayPrismaClient, - resolvePostgresConfigFromEnv, } from '@sammo-ts/infra'; import { resolveGatewayOrchestratorConfigFromEnv } from '../config.js'; +import { resolveGatewayPostgresConfigFromEnv } from '../gatewayPostgresConfig.js'; import { createGatewayOrchestrator } from './orchestratorFactory.js'; import { installGatewayShutdownController } from '../lifecycle/shutdownController.js'; export const runGatewayOrchestrator = async (): Promise => { const config = resolveGatewayOrchestratorConfigFromEnv(); - const postgres = createGatewayPostgresConnector(resolvePostgresConfigFromEnv({ schema: config.dbSchema })); + const postgres = createGatewayPostgresConnector(resolveGatewayPostgresConfigFromEnv(process.env, config.dbSchema)); await postgres.connect(); const { orchestrator } = createGatewayOrchestrator(postgres.prisma as GatewayPrismaClient, config, process.env); diff --git a/app/gateway-api/src/server.ts b/app/gateway-api/src/server.ts index e4319692..b9e26339 100644 --- a/app/gateway-api/src/server.ts +++ b/app/gateway-api/src/server.ts @@ -9,11 +9,11 @@ import { createGatewayPostgresConnector, createRedisConnector, type GatewayPrismaClient, - resolvePostgresConfigFromEnv, resolveRedisConfigFromEnv, } from '@sammo-ts/infra'; import { resolveGatewayApiConfigFromEnv } from './config.js'; +import { resolveGatewayPostgresConfigFromEnv } from './gatewayPostgresConfig.js'; import { createGatewayApiContext } from './context.js'; import { RedisGatewayFlushPublisher } from './auth/flushPublisher.js'; import { KakaoOAuthClient } from './auth/kakaoClient.js'; @@ -36,7 +36,7 @@ import { registerRuntimeNavigationRoute } from './navigation/runtimeNavigationRo export const createGatewayApiServer = async () => { const config = resolveGatewayApiConfigFromEnv(); - const postgres = createGatewayPostgresConnector(resolvePostgresConfigFromEnv({ schema: config.dbSchema })); + const postgres = createGatewayPostgresConnector(resolveGatewayPostgresConfigFromEnv(process.env, config.dbSchema)); const redis = createRedisConnector(resolveRedisConfigFromEnv()); await postgres.connect(); await redis.connect(); diff --git a/app/gateway-api/test/gatewayPostgresConfig.test.ts b/app/gateway-api/test/gatewayPostgresConfig.test.ts new file mode 100644 index 00000000..1612b378 --- /dev/null +++ b/app/gateway-api/test/gatewayPostgresConfig.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, it } from 'vitest'; + +import { resolveGatewayPostgresConfigFromEnv } from '../src/gatewayPostgresConfig.js'; + +describe('resolveGatewayPostgresConfigFromEnv', () => { + it('uses the encoded Gateway URL instead of rebuilding one from raw PostgreSQL credentials', () => { + const config = resolveGatewayPostgresConfigFromEnv( + { + GATEWAY_DATABASE_URL: 'postgresql://sammo:encoded%23password@postgres:5432/sammo?schema=legacy', + POSTGRES_USER: 'sammo', + POSTGRES_PASSWORD: 'raw#password', + POSTGRES_HOST: 'postgres', + POSTGRES_PORT: '5432', + POSTGRES_DB: 'sammo', + POSTGRES_POOL_MAX: '4', + }, + 'public' + ); + + const parsed = new URL(config.url); + expect(parsed.password).toBe('encoded%23password'); + expect(parsed.searchParams.get('schema')).toBe('public'); + expect(config.maxConnections).toBe(4); + }); + + it('keeps DATABASE_URL as the fallback for existing launchers', () => { + const config = resolveGatewayPostgresConfigFromEnv({ + DATABASE_URL: 'postgresql://sammo:password@postgres:5432/sammo?schema=public', + }); + + expect(config.url).toBe('postgresql://sammo:password@postgres:5432/sammo?schema=public'); + }); +});