@optima-chat/dev-skills 0.7.8 → 0.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/helpers/query-db.ts +35 -15
- package/dist/bin/helpers/query-db.js +32 -15
- package/package.json +1 -1
package/bin/helpers/query-db.ts
CHANGED
|
@@ -20,31 +20,40 @@ interface DatabaseConfig {
|
|
|
20
20
|
const SERVICE_DB_MAP = {
|
|
21
21
|
'commerce-backend': {
|
|
22
22
|
ci: { container: 'commerce-postgres', user: 'commerce', password: 'commerce123', database: 'commerce' },
|
|
23
|
-
stage: { userKey: 'COMMERCE_DB_USER', passwordKey: 'COMMERCE_DB_PASSWORD', database: '
|
|
23
|
+
stage: { userKey: 'COMMERCE_DB_USER', passwordKey: 'COMMERCE_DB_PASSWORD', database: 'optima_commerce' },
|
|
24
24
|
prod: { userKey: 'COMMERCE_DB_USER', passwordKey: 'COMMERCE_DB_PASSWORD', database: 'optima_commerce' }
|
|
25
25
|
},
|
|
26
26
|
'user-auth': {
|
|
27
27
|
ci: { container: 'user-auth-postgres-1', user: 'userauth', password: 'password123', database: 'userauth' },
|
|
28
|
-
stage: { userKey: 'AUTH_DB_USER', passwordKey: 'AUTH_DB_PASSWORD', database: '
|
|
28
|
+
stage: { userKey: 'AUTH_DB_USER', passwordKey: 'AUTH_DB_PASSWORD', database: 'optima_auth' },
|
|
29
29
|
prod: { userKey: 'AUTH_DB_USER', passwordKey: 'AUTH_DB_PASSWORD', database: 'optima_auth' }
|
|
30
30
|
},
|
|
31
|
-
'mcp-host': {
|
|
32
|
-
ci: { container: 'mcp-host-db-1', user: 'mcp_user', password: 'mcp_password', database: 'mcp_host' },
|
|
33
|
-
stage: { userKey: 'MCP_DB_USER', passwordKey: 'MCP_DB_PASSWORD', database: 'optima_stage_mcp' },
|
|
34
|
-
prod: { userKey: 'MCP_DB_USER', passwordKey: 'MCP_DB_PASSWORD', database: 'optima_mcp' }
|
|
35
|
-
},
|
|
36
31
|
'agentic-chat': {
|
|
37
32
|
ci: { container: 'optima-postgres', user: 'postgres', password: 'postgres123', database: 'optima_chat' },
|
|
38
|
-
stage: { userKey: 'CHAT_DB_USER', passwordKey: 'CHAT_DB_PASSWORD', database: '
|
|
33
|
+
stage: { userKey: 'CHAT_DB_USER', passwordKey: 'CHAT_DB_PASSWORD', database: 'optima_chat' },
|
|
39
34
|
prod: { userKey: 'CHAT_DB_USER', passwordKey: 'CHAT_DB_PASSWORD', database: 'optima_chat' }
|
|
35
|
+
},
|
|
36
|
+
'bi-backend': {
|
|
37
|
+
ci: null, // CI 环境暂无 BI 数据库
|
|
38
|
+
stage: { userKey: 'BI_DB_USER', passwordKey: 'BI_DB_PASSWORD', database: 'optima_bi' },
|
|
39
|
+
prod: { userKey: 'BI_DB_USER', passwordKey: 'BI_DB_PASSWORD', database: 'optima_bi' }
|
|
40
|
+
},
|
|
41
|
+
'session-gateway': {
|
|
42
|
+
ci: null, // CI 环境暂无 session-gateway 数据库
|
|
43
|
+
stage: { userKey: 'SHELL_DB_USER', passwordKey: 'SHELL_DB_PASSWORD', database: 'optima_shell' },
|
|
44
|
+
prod: { userKey: 'AI_SHELL_DB_USER', passwordKey: 'AI_SHELL_DB_PASSWORD', database: 'optima_ai_shell' }
|
|
40
45
|
}
|
|
41
46
|
};
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
// Stage 和 Prod 独立的 RDS 实例
|
|
49
|
+
const RDS_HOSTS = {
|
|
50
|
+
stage: 'optima-stage-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com',
|
|
51
|
+
prod: 'optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com'
|
|
46
52
|
};
|
|
47
53
|
|
|
54
|
+
// 统一使用 Shared EC2 作为跳板机
|
|
55
|
+
const EC2_HOST = '13.251.46.219';
|
|
56
|
+
|
|
48
57
|
function getGitHubVariable(name: string): string {
|
|
49
58
|
return execSync(`gh variable get ${name} -R Optima-Chat/optima-dev-skills`, { encoding: 'utf-8' }).trim();
|
|
50
59
|
}
|
|
@@ -165,7 +174,7 @@ async function main() {
|
|
|
165
174
|
if (args.length < 2) {
|
|
166
175
|
console.error('Usage: query-db.ts <service> <sql> [environment]');
|
|
167
176
|
console.error('');
|
|
168
|
-
console.error('Services: commerce-backend, user-auth,
|
|
177
|
+
console.error('Services: commerce-backend, user-auth, agentic-chat, bi-backend, session-gateway');
|
|
169
178
|
console.error('Environments: ci (default), stage, prod');
|
|
170
179
|
console.error('');
|
|
171
180
|
console.error('Example: query-db.ts user-auth "SELECT COUNT(*) FROM users" prod');
|
|
@@ -182,6 +191,14 @@ async function main() {
|
|
|
182
191
|
|
|
183
192
|
const serviceConfig = SERVICE_DB_MAP[service as keyof typeof SERVICE_DB_MAP][environment as 'ci' | 'stage' | 'prod'];
|
|
184
193
|
|
|
194
|
+
if (!serviceConfig) {
|
|
195
|
+
console.error(`Service ${service} is not available in ${environment.toUpperCase()} environment.`);
|
|
196
|
+
if (environment === 'ci') {
|
|
197
|
+
console.error('Try using stage or prod environment instead.');
|
|
198
|
+
}
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
|
|
185
202
|
console.log(`\n🔍 Querying ${service} (${environment.toUpperCase()})...`);
|
|
186
203
|
|
|
187
204
|
if (environment === 'ci') {
|
|
@@ -210,14 +227,17 @@ async function main() {
|
|
|
210
227
|
console.log('✓ Retrieved database credentials from Infisical');
|
|
211
228
|
|
|
212
229
|
const { userKey, passwordKey, database } = serviceConfig as any;
|
|
213
|
-
const dbHost =
|
|
230
|
+
const dbHost = RDS_HOSTS[environment as 'stage' | 'prod'];
|
|
214
231
|
const dbUser = secrets[userKey];
|
|
215
232
|
const dbPassword = secrets[passwordKey];
|
|
216
233
|
|
|
234
|
+
if (!dbUser || !dbPassword) {
|
|
235
|
+
throw new Error(`Database credentials not found in Infisical for ${service}. Keys: ${userKey}, ${passwordKey}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
217
238
|
const localPort = environment === 'stage' ? 15432 : 15433;
|
|
218
|
-
const ec2Host = EC2_HOSTS[environment as 'stage' | 'prod'];
|
|
219
239
|
|
|
220
|
-
setupSSHTunnel(
|
|
240
|
+
setupSSHTunnel(EC2_HOST, dbHost, localPort);
|
|
221
241
|
|
|
222
242
|
// 等待隧道建立
|
|
223
243
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
@@ -39,29 +39,37 @@ const fs = __importStar(require("fs"));
|
|
|
39
39
|
const SERVICE_DB_MAP = {
|
|
40
40
|
'commerce-backend': {
|
|
41
41
|
ci: { container: 'commerce-postgres', user: 'commerce', password: 'commerce123', database: 'commerce' },
|
|
42
|
-
stage: { userKey: 'COMMERCE_DB_USER', passwordKey: 'COMMERCE_DB_PASSWORD', database: '
|
|
42
|
+
stage: { userKey: 'COMMERCE_DB_USER', passwordKey: 'COMMERCE_DB_PASSWORD', database: 'optima_commerce' },
|
|
43
43
|
prod: { userKey: 'COMMERCE_DB_USER', passwordKey: 'COMMERCE_DB_PASSWORD', database: 'optima_commerce' }
|
|
44
44
|
},
|
|
45
45
|
'user-auth': {
|
|
46
46
|
ci: { container: 'user-auth-postgres-1', user: 'userauth', password: 'password123', database: 'userauth' },
|
|
47
|
-
stage: { userKey: 'AUTH_DB_USER', passwordKey: 'AUTH_DB_PASSWORD', database: '
|
|
47
|
+
stage: { userKey: 'AUTH_DB_USER', passwordKey: 'AUTH_DB_PASSWORD', database: 'optima_auth' },
|
|
48
48
|
prod: { userKey: 'AUTH_DB_USER', passwordKey: 'AUTH_DB_PASSWORD', database: 'optima_auth' }
|
|
49
49
|
},
|
|
50
|
-
'mcp-host': {
|
|
51
|
-
ci: { container: 'mcp-host-db-1', user: 'mcp_user', password: 'mcp_password', database: 'mcp_host' },
|
|
52
|
-
stage: { userKey: 'MCP_DB_USER', passwordKey: 'MCP_DB_PASSWORD', database: 'optima_stage_mcp' },
|
|
53
|
-
prod: { userKey: 'MCP_DB_USER', passwordKey: 'MCP_DB_PASSWORD', database: 'optima_mcp' }
|
|
54
|
-
},
|
|
55
50
|
'agentic-chat': {
|
|
56
51
|
ci: { container: 'optima-postgres', user: 'postgres', password: 'postgres123', database: 'optima_chat' },
|
|
57
|
-
stage: { userKey: 'CHAT_DB_USER', passwordKey: 'CHAT_DB_PASSWORD', database: '
|
|
52
|
+
stage: { userKey: 'CHAT_DB_USER', passwordKey: 'CHAT_DB_PASSWORD', database: 'optima_chat' },
|
|
58
53
|
prod: { userKey: 'CHAT_DB_USER', passwordKey: 'CHAT_DB_PASSWORD', database: 'optima_chat' }
|
|
54
|
+
},
|
|
55
|
+
'bi-backend': {
|
|
56
|
+
ci: null, // CI 环境暂无 BI 数据库
|
|
57
|
+
stage: { userKey: 'BI_DB_USER', passwordKey: 'BI_DB_PASSWORD', database: 'optima_bi' },
|
|
58
|
+
prod: { userKey: 'BI_DB_USER', passwordKey: 'BI_DB_PASSWORD', database: 'optima_bi' }
|
|
59
|
+
},
|
|
60
|
+
'session-gateway': {
|
|
61
|
+
ci: null, // CI 环境暂无 session-gateway 数据库
|
|
62
|
+
stage: { userKey: 'SHELL_DB_USER', passwordKey: 'SHELL_DB_PASSWORD', database: 'optima_shell' },
|
|
63
|
+
prod: { userKey: 'AI_SHELL_DB_USER', passwordKey: 'AI_SHELL_DB_PASSWORD', database: 'optima_ai_shell' }
|
|
59
64
|
}
|
|
60
65
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
// Stage 和 Prod 独立的 RDS 实例
|
|
67
|
+
const RDS_HOSTS = {
|
|
68
|
+
stage: 'optima-stage-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com',
|
|
69
|
+
prod: 'optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com'
|
|
64
70
|
};
|
|
71
|
+
// 统一使用 Shared EC2 作为跳板机
|
|
72
|
+
const EC2_HOST = '13.251.46.219';
|
|
65
73
|
function getGitHubVariable(name) {
|
|
66
74
|
return (0, child_process_1.execSync)(`gh variable get ${name} -R Optima-Chat/optima-dev-skills`, { encoding: 'utf-8' }).trim();
|
|
67
75
|
}
|
|
@@ -157,7 +165,7 @@ async function main() {
|
|
|
157
165
|
if (args.length < 2) {
|
|
158
166
|
console.error('Usage: query-db.ts <service> <sql> [environment]');
|
|
159
167
|
console.error('');
|
|
160
|
-
console.error('Services: commerce-backend, user-auth,
|
|
168
|
+
console.error('Services: commerce-backend, user-auth, agentic-chat, bi-backend, session-gateway');
|
|
161
169
|
console.error('Environments: ci (default), stage, prod');
|
|
162
170
|
console.error('');
|
|
163
171
|
console.error('Example: query-db.ts user-auth "SELECT COUNT(*) FROM users" prod');
|
|
@@ -170,6 +178,13 @@ async function main() {
|
|
|
170
178
|
process.exit(1);
|
|
171
179
|
}
|
|
172
180
|
const serviceConfig = SERVICE_DB_MAP[service][environment];
|
|
181
|
+
if (!serviceConfig) {
|
|
182
|
+
console.error(`Service ${service} is not available in ${environment.toUpperCase()} environment.`);
|
|
183
|
+
if (environment === 'ci') {
|
|
184
|
+
console.error('Try using stage or prod environment instead.');
|
|
185
|
+
}
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
173
188
|
console.log(`\n🔍 Querying ${service} (${environment.toUpperCase()})...`);
|
|
174
189
|
if (environment === 'ci') {
|
|
175
190
|
// CI 环境:通过 SSH + Docker Exec
|
|
@@ -189,12 +204,14 @@ async function main() {
|
|
|
189
204
|
const secrets = getInfisicalSecrets(infisicalConfig, token, environment === 'stage' ? 'staging' : 'prod');
|
|
190
205
|
console.log('✓ Retrieved database credentials from Infisical');
|
|
191
206
|
const { userKey, passwordKey, database } = serviceConfig;
|
|
192
|
-
const dbHost =
|
|
207
|
+
const dbHost = RDS_HOSTS[environment];
|
|
193
208
|
const dbUser = secrets[userKey];
|
|
194
209
|
const dbPassword = secrets[passwordKey];
|
|
210
|
+
if (!dbUser || !dbPassword) {
|
|
211
|
+
throw new Error(`Database credentials not found in Infisical for ${service}. Keys: ${userKey}, ${passwordKey}`);
|
|
212
|
+
}
|
|
195
213
|
const localPort = environment === 'stage' ? 15432 : 15433;
|
|
196
|
-
|
|
197
|
-
setupSSHTunnel(ec2Host, dbHost, localPort);
|
|
214
|
+
setupSSHTunnel(EC2_HOST, dbHost, localPort);
|
|
198
215
|
// 等待隧道建立
|
|
199
216
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
200
217
|
const result = queryDatabase('localhost', localPort, dbUser, dbPassword, database, sql);
|