feat: 初始化DevOps平台后端
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { EnvConfig } from '../config/env.schema';
|
||||
import {
|
||||
IntegrationConfigKey,
|
||||
IntegrationConfigState,
|
||||
IntegrationConfigStatus,
|
||||
IntegrationConfigStatusResponse,
|
||||
} from './settings.types';
|
||||
|
||||
type EnvStringKey = {
|
||||
[Key in keyof EnvConfig]-?: Extract<EnvConfig[Key], string> extends never
|
||||
? never
|
||||
: Key;
|
||||
}[keyof EnvConfig];
|
||||
type EnvKey = keyof EnvConfig;
|
||||
|
||||
type IntegrationDefinition = {
|
||||
key: IntegrationConfigKey;
|
||||
name: string;
|
||||
required: EnvStringKey[];
|
||||
optional?: EnvKey[];
|
||||
note?: string;
|
||||
};
|
||||
|
||||
const INTEGRATION_DEFINITIONS: IntegrationDefinition[] = [
|
||||
{
|
||||
key: 'jenkins',
|
||||
name: 'Jenkins',
|
||||
required: ['JENKINS_BASE_URL', 'JENKINS_USERNAME', 'JENKINS_API_TOKEN'],
|
||||
},
|
||||
{
|
||||
key: 'gitea',
|
||||
name: 'Gitea',
|
||||
required: ['GITEA_BASE_URL', 'GITEA_TOKEN'],
|
||||
optional: ['GITEA_WEBHOOK_SECRET'],
|
||||
note: 'GITEA_WEBHOOK_SECRET 用于开启 webhook 签名校验。',
|
||||
},
|
||||
{
|
||||
key: 'notification',
|
||||
name: '通知平台',
|
||||
required: ['NOTIFICATION_PROVIDER'],
|
||||
optional: ['WECOM_WEBHOOK_URL', 'FEISHU_WEBHOOK_URL', 'NOTIFICATION_WEBHOOK_URL'],
|
||||
note: '当前不强制配置机器人;后续可按 provider 接入企微、飞书或通用 webhook。',
|
||||
},
|
||||
{
|
||||
key: 'llm',
|
||||
name: 'LLM Agent',
|
||||
required: ['LLM_BASE_URL', 'LLM_API_KEY', 'LLM_MODEL'],
|
||||
},
|
||||
{
|
||||
key: 'database',
|
||||
name: 'MySQL / Prisma',
|
||||
required: ['DATABASE_URL'],
|
||||
optional: ['USE_DATABASE_READS', 'PRISMA_CONNECT_ON_BOOT'],
|
||||
},
|
||||
{
|
||||
key: 'redis',
|
||||
name: 'Redis / BullMQ',
|
||||
required: ['REDIS_URL'],
|
||||
},
|
||||
{
|
||||
key: 'secrets',
|
||||
name: '服务端密钥加密',
|
||||
required: ['SECRET_ENCRYPTION_KEY'],
|
||||
},
|
||||
];
|
||||
|
||||
const PLACEHOLDER_PATTERNS = [
|
||||
/replace-with-/i,
|
||||
/\.example\.internal(?:[/:]|$)/i,
|
||||
];
|
||||
|
||||
@Injectable()
|
||||
export class SettingsService {
|
||||
constructor(private readonly config: ConfigService<EnvConfig, true>) {}
|
||||
|
||||
getIntegrationConfigStatus(): IntegrationConfigStatusResponse {
|
||||
return {
|
||||
checkedAt: new Date().toISOString(),
|
||||
integrations: INTEGRATION_DEFINITIONS.map((definition) =>
|
||||
this.toIntegrationStatus(definition),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
private toIntegrationStatus(
|
||||
definition: IntegrationDefinition,
|
||||
): IntegrationConfigStatus {
|
||||
const configured = definition.required.filter((key) =>
|
||||
this.isConfiguredValue(this.getConfigValue(key)),
|
||||
);
|
||||
const missing = definition.required.filter(
|
||||
(key) => !this.isConfiguredValue(this.getConfigValue(key)),
|
||||
);
|
||||
|
||||
return {
|
||||
key: definition.key,
|
||||
name: definition.name,
|
||||
status: this.resolveStatus(configured.length, missing.length),
|
||||
required: [...definition.required],
|
||||
configured,
|
||||
missing,
|
||||
...(definition.optional ? { optional: [...definition.optional] } : {}),
|
||||
...(definition.note ? { note: definition.note } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
private getConfigValue(key: EnvStringKey): string | undefined {
|
||||
const value = this.config.get(key, { infer: true });
|
||||
|
||||
return typeof value === 'string' ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
private isConfiguredValue(value: string | undefined): boolean {
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !PLACEHOLDER_PATTERNS.some((pattern) => pattern.test(value));
|
||||
}
|
||||
|
||||
private resolveStatus(
|
||||
configuredCount: number,
|
||||
missingCount: number,
|
||||
): IntegrationConfigState {
|
||||
if (missingCount === 0) {
|
||||
return 'configured';
|
||||
}
|
||||
|
||||
return configuredCount > 0 ? 'partial' : 'missing';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user