feat: Phase 1 – Plattform-Grundgerüst (Docker, NestJS, React, Auth)
This commit is contained in:
83
apps/platform-backend/src/config/configuration.ts
Normal file
83
apps/platform-backend/src/config/configuration.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Zentrale, typsichere Konfiguration der Management-Plattform.
|
||||
* Alle Werte stammen aus Umgebungsvariablen und werden beim Start
|
||||
* einmalig validiert (fail-fast bei fehlerhafter Konfiguration).
|
||||
*/
|
||||
|
||||
export type NodeEnvironment = 'development' | 'test' | 'production';
|
||||
|
||||
export interface DatabaseConfig {
|
||||
readonly url: string;
|
||||
}
|
||||
|
||||
export interface SecurityConfig {
|
||||
readonly sessionTtlMinutes: number;
|
||||
readonly cookieSecure: boolean;
|
||||
readonly behindProxy: boolean;
|
||||
readonly loginMaxAttempts: number;
|
||||
readonly loginLockoutMinutes: number;
|
||||
readonly loginRateLimitAttempts: number;
|
||||
readonly loginRateLimitWindowMinutes: number;
|
||||
}
|
||||
|
||||
export interface AdminSeedConfig {
|
||||
readonly username: string;
|
||||
readonly email: string;
|
||||
readonly password: string;
|
||||
}
|
||||
|
||||
export interface AppConfig {
|
||||
readonly nodeEnv: NodeEnvironment;
|
||||
readonly port: number;
|
||||
readonly database: DatabaseConfig;
|
||||
readonly security: SecurityConfig;
|
||||
readonly adminSeed: AdminSeedConfig;
|
||||
}
|
||||
|
||||
const booleanFromString = z
|
||||
.enum(['true', 'false'])
|
||||
.default('false')
|
||||
.transform((value) => value === 'true');
|
||||
|
||||
const environmentSchema = z.object({
|
||||
NODE_ENV: z.enum(['development', 'test', 'production']).default('production'),
|
||||
PORT: z.coerce.number().int().positive().default(3000),
|
||||
DATABASE_URL: z.string().min(1, 'DATABASE_URL ist erforderlich'),
|
||||
SESSION_TTL_MINUTES: z.coerce.number().int().positive().default(120),
|
||||
COOKIE_SECURE: booleanFromString,
|
||||
BEHIND_PROXY: booleanFromString,
|
||||
LOGIN_MAX_ATTEMPTS: z.coerce.number().int().positive().default(5),
|
||||
LOGIN_LOCKOUT_MINUTES: z.coerce.number().int().positive().default(15),
|
||||
LOGIN_RATE_LIMIT_ATTEMPTS: z.coerce.number().int().positive().default(10),
|
||||
LOGIN_RATE_LIMIT_WINDOW_MINUTES: z.coerce.number().int().positive().default(5),
|
||||
ADMIN_USERNAME: z.string().trim().min(3).max(100),
|
||||
ADMIN_EMAIL: z.string().trim().email(),
|
||||
ADMIN_PASSWORD: z.string().min(10, 'ADMIN_PASSWORD muss mindestens 10 Zeichen lang sein').max(200),
|
||||
});
|
||||
|
||||
/** Lädt und validiert die Konfiguration aus den Umgebungsvariablen. */
|
||||
export function loadConfiguration(): AppConfig {
|
||||
const environment = environmentSchema.parse(process.env);
|
||||
|
||||
return {
|
||||
nodeEnv: environment.NODE_ENV,
|
||||
port: environment.PORT,
|
||||
database: { url: environment.DATABASE_URL },
|
||||
security: {
|
||||
sessionTtlMinutes: environment.SESSION_TTL_MINUTES,
|
||||
cookieSecure: environment.COOKIE_SECURE,
|
||||
behindProxy: environment.BEHIND_PROXY,
|
||||
loginMaxAttempts: environment.LOGIN_MAX_ATTEMPTS,
|
||||
loginLockoutMinutes: environment.LOGIN_LOCKOUT_MINUTES,
|
||||
loginRateLimitAttempts: environment.LOGIN_RATE_LIMIT_ATTEMPTS,
|
||||
loginRateLimitWindowMinutes: environment.LOGIN_RATE_LIMIT_WINDOW_MINUTES,
|
||||
},
|
||||
adminSeed: {
|
||||
username: environment.ADMIN_USERNAME,
|
||||
email: environment.ADMIN_EMAIL,
|
||||
password: environment.ADMIN_PASSWORD,
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user