Skip to content

Commit 24844a9

Browse files
committed
feat(api): add UI config endpoint (Phase 2)
Add GET /api/info/ui-config endpoint that returns runtime configuration for the UI, enabling the frontend to fetch environment-specific values instead of relying on build-time bundling. Returns: - env (staging/production) - segmentWriteKey (analytics) - cloudCapiUrl, aiConvAiApiUrl, aiQuerySocketUrl - features (cloudAds, envDependent) - appFolderName
1 parent 54e6d11 commit 24844a9

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2+
3+
/**
4+
* UI Configuration DTO
5+
*
6+
* Returns runtime configuration values for the UI.
7+
* This enables the UI to adapt to the current environment
8+
* without requiring a rebuild.
9+
*/
10+
export class GetUiConfigResponse {
11+
@ApiProperty({
12+
description: 'Current environment (development, staging, production)',
13+
type: String,
14+
example: 'production',
15+
})
16+
env: string;
17+
18+
@ApiPropertyOptional({
19+
description: 'Segment analytics write key',
20+
type: String,
21+
})
22+
segmentWriteKey?: string;
23+
24+
@ApiPropertyOptional({
25+
description: 'Redis Cloud CAPI URL',
26+
type: String,
27+
example: 'https://api.redislabs.com/v1',
28+
})
29+
cloudCapiUrl?: string;
30+
31+
@ApiPropertyOptional({
32+
description: 'Conversational AI API URL',
33+
type: String,
34+
example: 'https://redis.io/convai/api',
35+
})
36+
aiConvAiApiUrl?: string;
37+
38+
@ApiPropertyOptional({
39+
description: 'AI Query WebSocket URL',
40+
type: String,
41+
})
42+
aiQuerySocketUrl?: string;
43+
44+
@ApiProperty({
45+
description: 'Feature flags',
46+
type: Object,
47+
example: { cloudAds: true, envDependent: true },
48+
})
49+
features: {
50+
cloudAds: boolean;
51+
envDependent: boolean;
52+
};
53+
54+
@ApiPropertyOptional({
55+
description: 'App folder name for data storage',
56+
type: String,
57+
example: '.redis-insight',
58+
})
59+
appFolderName?: string;
60+
}

redisinsight/api/src/modules/server/server.controller.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import { getBlockingCommands } from 'src/utils/cli-helper';
55
import { getUnsupportedCommands } from 'src/modules/cli/utils/getUnsupportedCommands';
66
import { ServerService } from 'src/modules/server/server.service';
77
import { GetServerInfoResponse } from 'src/modules/server/dto/server.dto';
8+
import { GetUiConfigResponse } from 'src/modules/server/dto/ui-config.dto';
89
import { RequestSessionMetadata } from 'src/common/decorators';
910
import { SessionMetadata } from 'src/common/models';
11+
import config, { Config } from 'src/utils/config';
1012

1113
@ApiTags('Info')
1214
@Controller('info')
@@ -65,4 +67,37 @@ export class ServerController {
6567
async getCliBlockingCommands(): Promise<string[]> {
6668
return getBlockingCommands();
6769
}
70+
71+
@Get('/ui-config')
72+
@ApiEndpoint({
73+
description: 'Get UI runtime configuration',
74+
statusCode: 200,
75+
responses: [
76+
{
77+
status: 200,
78+
description: 'UI Configuration',
79+
type: GetUiConfigResponse,
80+
},
81+
],
82+
})
83+
async getUiConfig(): Promise<GetUiConfigResponse> {
84+
const serverConfig = config.get('server') as Config['server'];
85+
const analyticsConfig = config.get('analytics') as Config['analytics'];
86+
const cloudConfig = config.get('cloud') as Config['cloud'];
87+
const aiConfig = config.get('ai') as Config['ai'];
88+
const dirPathConfig = config.get('dir_path') as Config['dir_path'];
89+
90+
return {
91+
env: serverConfig.env,
92+
segmentWriteKey: analyticsConfig.writeKey,
93+
cloudCapiUrl: cloudConfig.capiUrl,
94+
aiConvAiApiUrl: aiConfig.convAiApiUrl,
95+
aiQuerySocketUrl: aiConfig.querySocketUrl,
96+
features: {
97+
cloudAds: true, // Can be extended to read from config
98+
envDependent: serverConfig.env !== 'production',
99+
},
100+
appFolderName: dirPathConfig.homedir?.split('/').pop(),
101+
};
102+
}
68103
}

0 commit comments

Comments
 (0)