feat: validate backend runtime configuration
This commit is contained in:
9
backend/libs/configuration/src/configuration.module.ts
Normal file
9
backend/libs/configuration/src/configuration.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { appEnvironmentProvider } from './environment';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [appEnvironmentProvider],
|
||||
exports: [appEnvironmentProvider],
|
||||
})
|
||||
export class ConfigurationModule {}
|
||||
25
backend/libs/configuration/src/environment.spec.ts
Normal file
25
backend/libs/configuration/src/environment.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { loadEnvironment } from './environment';
|
||||
|
||||
describe('loadEnvironment', () => {
|
||||
it('requires database and redis URLs', () => {
|
||||
expect(() => loadEnvironment({})).toThrow('DATABASE_URL');
|
||||
});
|
||||
|
||||
it('returns build metadata without secrets', () => {
|
||||
expect(
|
||||
loadEnvironment({
|
||||
DATABASE_URL: 'postgresql://u:p@postgres:5432/db',
|
||||
REDIS_URL: 'redis://redis:6379',
|
||||
APP_VERSION: '1.2.3',
|
||||
TEAMCITY_BUILD_NUMBER: '42',
|
||||
SOURCE_REVISION: 'abc123',
|
||||
}),
|
||||
).toEqual({
|
||||
databaseUrl: 'postgresql://u:p@postgres:5432/db',
|
||||
redisUrl: 'redis://redis:6379',
|
||||
appVersion: '1.2.3',
|
||||
teamCityBuildNumber: '42',
|
||||
sourceRevision: 'abc123',
|
||||
});
|
||||
});
|
||||
});
|
||||
30
backend/libs/configuration/src/environment.ts
Normal file
30
backend/libs/configuration/src/environment.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export interface AppEnvironment {
|
||||
databaseUrl: string;
|
||||
redisUrl: string;
|
||||
appVersion: string;
|
||||
teamCityBuildNumber: string;
|
||||
sourceRevision: string;
|
||||
}
|
||||
|
||||
function required(env: NodeJS.ProcessEnv, name: string): string {
|
||||
const value = env[name]?.trim();
|
||||
if (!value) throw new Error(`Missing required environment variable: ${name}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function loadEnvironment(env: NodeJS.ProcessEnv): AppEnvironment {
|
||||
return {
|
||||
databaseUrl: required(env, 'DATABASE_URL'),
|
||||
redisUrl: required(env, 'REDIS_URL'),
|
||||
appVersion: env.APP_VERSION?.trim() || 'dev',
|
||||
teamCityBuildNumber: env.TEAMCITY_BUILD_NUMBER?.trim() || 'local',
|
||||
sourceRevision: env.SOURCE_REVISION?.trim() || 'local',
|
||||
};
|
||||
}
|
||||
|
||||
export const APP_ENVIRONMENT = Symbol('APP_ENVIRONMENT');
|
||||
|
||||
export const appEnvironmentProvider = {
|
||||
provide: APP_ENVIRONMENT,
|
||||
useFactory: () => loadEnvironment(process.env),
|
||||
};
|
||||
2
backend/libs/configuration/src/index.ts
Normal file
2
backend/libs/configuration/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './environment';
|
||||
export * from './configuration.module';
|
||||
Reference in New Issue
Block a user