INSIGHT-MVP/packages/core-service/src/config/env.validation.ts
Thomas Reitz 5412ae137a feat: adapt codebase for IP-based HTTP deployment on 172.20.10.59
Switch from hostname+HTTPS (insight-dev.xinion.lan) to IP+HTTP
(172.20.10.59) for alpha/dev deployment without DNS.

Key changes:
- Cookie secure/sameSite flags environment-conditional (fixes HTTP auth)
- docker-compose.yml: remove HTTPS, update host rules, reduce PG memory
- Traefik: disable TLS, update CORS/CSP for HTTP
- Add Prisma init migration (7 tables) and admin seed script
- Generate package-lock.json for npm ci in Docker builds
- Update all documentation for IP-based access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:21:45 +01:00

98 lines
1.7 KiB
TypeScript

import { plainToInstance } from 'class-transformer';
import {
IsEnum,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
Min,
Max,
validateSync,
} from 'class-validator';
enum Environment {
Development = 'development',
Production = 'production',
Test = 'test',
}
class EnvironmentVariables {
@IsEnum(Environment)
NODE_ENV: Environment = Environment.Development;
@IsNumber()
@Min(1)
@Max(65535)
APP_PORT = 3000;
@IsString()
@IsNotEmpty()
APP_URL = 'http://172.20.10.59';
// Datenbank
@IsString()
@IsNotEmpty()
DATABASE_URL!: string;
@IsString()
@IsOptional()
DATABASE_URL_DIRECT?: string;
// Redis
@IsString()
REDIS_HOST = 'redis';
@IsNumber()
REDIS_PORT = 6379;
@IsString()
@IsOptional()
REDIS_PASSWORD?: string;
// JWT
@IsString()
@IsNotEmpty()
JWT_PRIVATE_KEY_PATH = '/app/keys/jwt-private.pem';
@IsString()
@IsNotEmpty()
JWT_PUBLIC_KEY_PATH = '/app/keys/jwt-public.pem';
@IsString()
JWT_ACCESS_TOKEN_EXPIRY = '15m';
@IsString()
JWT_REFRESH_TOKEN_EXPIRY = '7d';
@IsString()
JWT_ISSUER = 'insight-platform';
// Bcrypt
@IsNumber()
@Min(10)
@Max(14)
BCRYPT_COST = 12;
// Rate Limiting
@IsNumber()
THROTTLE_TTL = 60000;
@IsNumber()
THROTTLE_LIMIT = 200;
}
export function validateConfig(
config: Record<string, unknown>,
): EnvironmentVariables {
const validatedConfig = plainToInstance(EnvironmentVariables, config, {
enableImplicitConversion: true,
});
const errors = validateSync(validatedConfig, {
skipMissingProperties: false,
});
if (errors.length > 0) {
throw new Error(`Config validation error: ${errors.toString()}`);
}
return validatedConfig;
}