import { z } from "zod"; const supportedLocales = ["de", "en"] as const; const configSchema = z.object({ port: z.coerce.number().min(1).max(65535).default(8000), logLevel: z.enum(["debug", "info", "warn", "error"]).default("info"), databasePath: z.string().default("./data/contracts.db"), paperlessBaseUrl: z.string().url().optional(), paperlessToken: z.string().min(1).optional(), paperlessExternalUrl: z.string().url().optional(), paperlessWebhookUrl: z.string().url().optional(), appExternalUrl: z.string().url().optional(), appLocale: z.enum(supportedLocales).default("de"), schedulerIntervalMinutes: z.coerce.number().min(5).default(60), alertDaysBefore: z.coerce.number().min(1).default(30), mailServer: z.string().optional(), mailPort: z.coerce.number().min(1).max(65535).default(587), mailUsername: z.string().optional(), mailPassword: z.string().optional(), mailUseTls: z.coerce.boolean().default(true), mailFrom: z.string().email().optional(), mailTo: z.string().email().optional(), authUsername: z.string().optional(), authPassword: z.string().optional(), authJwtSecret: z.string().optional(), authTokenExpiresInHours: z.coerce.number().min(1).max(168).default(12), ntfyServerUrl: z.string().url().optional(), ntfyTopic: z.string().min(1).optional(), ntfyToken: z.string().optional(), ntfyPriority: z.string().optional(), icalSecret: z.string().optional(), aiEnabled: z.coerce.boolean().default(false), aiProvider: z.enum(["openai", "openai-compatible", "gemini"]).optional(), aiBaseUrl: z.string().url().optional(), aiModel: z.string().min(1).optional(), aiApiKey: z.string().min(1).optional(), aiSystemPrompt: z.string().optional(), aiTimeoutSeconds: z.coerce.number().min(5).max(300).default(60), aiMaxTokens: z.coerce.number().min(256).max(16000).default(2000), paperlessWebhookSecret: z.string().min(10).optional() }); function parseBoolean(value: string | undefined, fallback: boolean): boolean { if (value === undefined) { return fallback; } return ["1", "true", "yes", "on"].includes(value.toLowerCase()); } function readEnv(name: string): string | undefined { const value = process.env[name]; if (value === undefined) { return undefined; } return value.trim().length > 0 ? value : undefined; } const rawConfig = { port: readEnv("PORT"), logLevel: readEnv("LOG_LEVEL"), databasePath: readEnv("DATABASE_PATH"), paperlessBaseUrl: readEnv("PAPERLESS_BASE_URL"), paperlessToken: readEnv("PAPERLESS_TOKEN"), paperlessExternalUrl: readEnv("PAPERLESS_EXTERNAL_URL"), paperlessWebhookUrl: readEnv("PAPERLESS_WEBHOOK_URL"), appExternalUrl: readEnv("APP_EXTERNAL_URL"), appLocale: readEnv("APP_LOCALE"), schedulerIntervalMinutes: readEnv("SCHEDULER_INTERVAL_MINUTES"), alertDaysBefore: readEnv("ALERT_DAYS_BEFORE"), mailServer: readEnv("MAIL_SERVER"), mailPort: readEnv("MAIL_PORT"), mailUsername: readEnv("MAIL_USERNAME"), mailPassword: readEnv("MAIL_PASSWORD"), mailUseTls: parseBoolean(readEnv("MAIL_USE_TLS"), true), mailFrom: readEnv("MAIL_FROM"), mailTo: readEnv("MAIL_TO"), authUsername: readEnv("AUTH_USERNAME"), authPassword: readEnv("AUTH_PASSWORD"), authJwtSecret: readEnv("AUTH_JWT_SECRET"), authTokenExpiresInHours: readEnv("AUTH_TOKEN_EXPIRES_IN_HOURS"), ntfyServerUrl: readEnv("NTFY_SERVER_URL"), ntfyTopic: readEnv("NTFY_TOPIC"), ntfyToken: readEnv("NTFY_TOKEN"), ntfyPriority: readEnv("NTFY_PRIORITY"), icalSecret: readEnv("ICAL_SECRET"), aiEnabled: parseBoolean(readEnv("AI_ENABLED"), false), aiProvider: readEnv("AI_PROVIDER"), aiBaseUrl: readEnv("AI_BASE_URL"), aiModel: readEnv("AI_MODEL"), aiApiKey: readEnv("AI_API_KEY"), aiSystemPrompt: readEnv("AI_SYSTEM_PROMPT"), aiTimeoutSeconds: readEnv("AI_TIMEOUT_SECONDS"), aiMaxTokens: readEnv("AI_MAX_TOKENS"), paperlessWebhookSecret: readEnv("PAPERLESS_WEBHOOK_SECRET") }; export type AppConfig = z.infer; export const config: AppConfig = configSchema.parse(rawConfig);