Files
HoruxDespachos/apps/api/src/config/env.ts
Horux Dev e7dbae1ab7 feat: conceptos tab, filters, backfill, facturapi live keys, fixes
- Add Conceptos tab in CFDI page with column filters, sorting, pagination
- Add GET /cfdi/conceptos endpoint with filters and orderBy
- Backfill cfdi_conceptos from legacy XMLs (824k concepts inserted)
- Fix CFDI delete button (bypass subscription check, add alerts)
- Fix export to Excel (fetch all filtered results, limit 10k)
- Fix facturacion page concepto delete bug (immutable updates, unique ids)
- Add Facturapi live key auto-generation and caching
- Fix SAT fechaPagoP parsing
- Add metrics cache support for current year
- Increase DB pool max to 15
2026-04-29 21:03:41 +00:00

65 lines
2.1 KiB
TypeScript

import { z } from 'zod';
import { config } from 'dotenv';
import { resolve } from 'path';
// Load .env file from the api package root
config({ path: resolve(process.cwd(), '.env') });
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
PORT: z.string().default('4000'),
DATABASE_URL: z.string(),
JWT_SECRET: z.string().min(32),
JWT_EXPIRES_IN: z.string().default('15m'),
JWT_REFRESH_EXPIRES_IN: z.string().default('7d'),
CORS_ORIGIN: z.string().default('http://localhost:3000'),
// Frontend URL (for MercadoPago back_url, emails, etc.)
FRONTEND_URL: z.string().default('https://horuxfin.com'),
// FIEL encryption (separate from JWT to allow independent rotation)
FIEL_ENCRYPTION_KEY: z.string().min(32),
FIEL_STORAGE_PATH: z.string().default('/var/horux/fiel'),
// MercadoPago
MP_ACCESS_TOKEN: z.string().optional(),
MP_WEBHOOK_SECRET: z.string().optional(),
MP_NOTIFICATION_URL: z.string().optional(),
// SMTP (Gmail Workspace)
SMTP_HOST: z.string().default('smtp.gmail.com'),
SMTP_PORT: z.string().default('587'),
SMTP_USER: z.string().optional(),
SMTP_PASS: z.string().optional(),
SMTP_FROM: z.string().default('Horux360 <noreply@horuxfin.com>'),
// Admin notification email
ADMIN_EMAIL: z.string().default('carlos@horuxfin.com'),
// Facturapi
FACTURAPI_USER_KEY: z.string().optional(),
FACTURAPI_MODE: z.enum(['test', 'live']).optional(),
// Cloudflare Tunnel (connector BYO-DB)
CLOUDFLARE_API_TOKEN: z.string().optional(),
CLOUDFLARE_ACCOUNT_ID: z.string().optional(),
CLOUDFLARE_TUNNEL_DOMAIN: z.string().default('tunnel.horux.mx'),
// KMS for encrypting DB connection strings and connector tokens
CONNECTOR_ENCRYPTION_KEY: z.string().optional(),
});
const parsed = envSchema.safeParse(process.env);
if (!parsed.success) {
console.error('❌ Invalid environment variables:', parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const env = parsed.data;
// Parse CORS origins (comma-separated) into array
export function getCorsOrigins(): string[] {
return env.CORS_ORIGIN.split(',').map(origin => origin.trim());
}