import { z } from 'zod'; import dotenv from 'dotenv'; import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); // Load .env from monorepo root (3 levels up from src/config/) dotenv.config({ path: resolve(__dirname, '../../../../.env') }); const envSchema = z.object({ PORT: z.coerce.number().default(3001), DATABASE_URL: z.string().default('sqlite.db'), JWT_SECRET: z.string().default('dev-secret-change-in-production-min32chars'), VITE_GOOGLE_CLIENT_ID: z.string().optional(), GOOGLE_CLIENT_SECRET: z.string().optional(), // AI Provider routing AI_PRIMARY_PROVIDER: z.string().default('groq'), AI_FALLBACK_PROVIDER: z.string().default('mistral'), AI_AUTO_ROTATE: z.coerce.boolean().default(true), AI_TIER: z.enum(['free', 'paid']).default('free'), // Groq (free tier) GROQ_API_KEY: z.string().optional(), GROQ_MODEL: z.string().default('llama-3.3-70b-versatile'), // Mistral (free tier) MISTRAL_API_KEY: z.string().optional(), MISTRAL_MODEL: z.string().default('mistral-small-latest'), // Other AI keys (paid / optional) AI_PROVIDER: z .enum(['groq', 'mistral', 'anthropic', 'openai', 'google', 'openrouter', 'ollama']) .default('groq'), ANTHROPIC_API_KEY: z.string().optional(), OPENAI_API_KEY: z.string().optional(), GOOGLE_AI_API_KEY: z.string().optional(), OPENROUTER_API_KEY: z.string().optional(), OLLAMA_BASE_URL: z.string().default('http://localhost:11434'), APP_URL: z.string().default('http://localhost:5173'), SCAN_INTERVAL_MINUTES: z.coerce.number().default(5), }); export const config = envSchema.parse(process.env); export type Config = z.infer;