feat: add typed config validation and logger utility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-03-01 09:18:02 +00:00
parent eb05b40801
commit e5dd5c6257
2 changed files with 80 additions and 0 deletions

49
src/config.ts Normal file
View file

@ -0,0 +1,49 @@
import 'dotenv/config';
interface Config {
telegram: {
botToken: string;
allowedUserIds: number[];
};
payload: {
apiUrl: string;
email: string;
password: string;
};
defaultTenantId: number;
logLevel: string;
nodeEnv: string;
}
function requireEnv(key: string): string {
const value = process.env[key];
if (!value) {
console.error(`Missing required environment variable: ${key}`);
process.exit(1);
}
return value;
}
export const config: Config = {
telegram: {
botToken: requireEnv('TELEGRAM_BOT_TOKEN'),
allowedUserIds: requireEnv('ALLOWED_USER_IDS')
.split(',')
.map((id) => {
const num = Number(id.trim());
if (Number.isNaN(num)) {
console.error(`Invalid user ID in ALLOWED_USER_IDS: "${id}"`);
process.exit(1);
}
return num;
}),
},
payload: {
apiUrl: requireEnv('PAYLOAD_API_URL'),
email: requireEnv('PAYLOAD_ADMIN_EMAIL'),
password: requireEnv('PAYLOAD_ADMIN_PASSWORD'),
},
defaultTenantId: Number(process.env.DEFAULT_TENANT_ID || '4'),
logLevel: process.env.LOG_LEVEL || 'info',
nodeEnv: process.env.NODE_ENV || 'development',
};

31
src/utils/logger.ts Normal file
View file

@ -0,0 +1,31 @@
const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 } as const;
type LogLevel = keyof typeof LEVELS;
let minLevel: number = LEVELS.info;
export function setLogLevel(level: LogLevel): void {
minLevel = LEVELS[level];
}
function formatTimestamp(): string {
return new Date().toISOString().replace('T', ' ').slice(0, 19);
}
function log(level: LogLevel, module: string, message: string, data?: unknown): void {
if (LEVELS[level] < minLevel) return;
const prefix = `[${formatTimestamp()}] [${level.toUpperCase()}] [${module}]`;
if (data !== undefined) {
console[level === 'debug' ? 'log' : level](`${prefix} ${message}`, data);
} else {
console[level === 'debug' ? 'log' : level](`${prefix} ${message}`);
}
}
export function createLogger(module: string) {
return {
debug: (msg: string, data?: unknown) => log('debug', module, msg, data),
info: (msg: string, data?: unknown) => log('info', module, msg, data),
warn: (msg: string, data?: unknown) => log('warn', module, msg, data),
error: (msg: string, data?: unknown) => log('error', module, msg, data),
};
}