blackmistcode's picture
Add files using upload-large-folder tool
71b8eb2 verified
Raw
History Blame Contribute Delete
2.02 kB
/**
* Configuracion centralizada de variables de entorno.
*
* Carga los valores de process.env mediante dotenv, los valida con Zod
* y expone constantes tipadas como: PORT, DATABASE_URL, JWT_SECRET,
* HF_TOKEN, HF_SPACE_MODERNFINBERT_URL, HF_SPACE_QWEN_URL, etc.
*
* Variables clave:
* - PORT: 7860 (requerido por HuggingFace Spaces).
* - DATABASE_URL: SQLite local para desarrollo, PostgreSQL para produccion.
* - JWT_SECRET: minimo 32 caracteres, usado para firmar tokens de autenticacion.
* - HF_TOKEN / HF_SPACE_*: credenciales para los Spaces de HuggingFace (IA).
* - OPENROUTER_API_KEY: fallback LLM si los Spaces estan saturados.
* - FINNHUB_API_KEY: noticias financieras para el pipeline de senales.
* - TELEGRAM_BOT_TOKEN: bot de alertas (@BotFather).
*
* Si falla la validacion, el proceso termina con error antes de levantar el servidor.
*/
import 'dotenv/config';
import { z } from 'zod';
const schema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
PORT: z.coerce.number().int().positive().default(7860),
DATABASE_URL: z.string().min(1, 'DATABASE_URL is required'),
JWT_SECRET: z.string().min(32, 'JWT_SECRET must be at least 32 chars'),
JWT_EXPIRES_IN: z.string().default('1h'),
BCRYPT_ROUNDS: z.coerce.number().int().min(4).max(15).default(10),
CORS_ORIGIN: z.string().default('http://localhost:5173'),
LOG_LEVEL: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'),
HF_TOKEN: z.string().optional(),
HF_SPACE_MODERNFINBERT_URL: z.string().optional(),
HF_SPACE_QWEN_URL: z.string().optional(),
OPENROUTER_API_KEY: z.string().optional(),
FINNHUB_API_KEY: z.string().optional(),
TELEGRAM_BOT_TOKEN: z.string().optional(),
});
const parsed = schema.safeParse(process.env);
if (!parsed.success) {
console.error('Invalid environment variables:');
console.error(parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const config = Object.freeze(parsed.data);