import { join, resolve } from 'path'; // Carga compatible del entorno: en SvelteKit usa $env/dynamic/private; // en tests/ejecución fuera de SvelteKit cae a process.env. let env: any; try { const mod = await import('$env/dynamic/private'); env = (mod as any).env; } catch { env = process.env as any; } /** * Resuelve la ruta absoluta al archivo de la base de datos SQLite compartida. * Prioridad: * 1) DB_PATH (ruta completa al archivo) * 2) DATA_DIR + filename (en prod por defecto /app/data; en dev por defecto ./tmp) */ export function resolveDbAbsolutePath(filename: string = 'tasks.db'): string { const dbPathEnv = (env.DB_PATH || '').trim(); if (dbPathEnv) { return resolve(dbPathEnv); } const isProdEnv = String(env.NODE_ENV || 'development').trim().toLowerCase() === 'production'; const dataDir = env.DATA_DIR ? String(env.DATA_DIR) : (isProdEnv ? '/app/data' : 'tmp'); return resolve(join(dataDir, filename)); } export const WEB_BASE_URL = (env.WEB_BASE_URL || '').trim(); export const COOKIE_SECRET = (env.COOKIE_SECRET || '').trim(); const SESSION_IDLE_TTL_MIN = Number(env.SESSION_IDLE_TTL_MIN || 120); export const sessionIdleTtlMs = Math.max(1, Math.floor(SESSION_IDLE_TTL_MIN)) * 60 * 1000; export const NODE_ENV = (env.NODE_ENV || 'development').trim().toLowerCase(); export const isProd = () => NODE_ENV === 'production'; export const isDev = () => NODE_ENV === 'development'; // Flags de desarrollo (solo en entornos no productivos) const toBool = (v: string) => ['1', 'true', 'yes', 'on'].includes(String(v || '').trim().toLowerCase()); export const DEV_BYPASS_AUTH = toBool(env.DEV_BYPASS_AUTH || ''); export const DEV_DEFAULT_USER = (env.DEV_DEFAULT_USER || 'demo').trim(); export const DEV_AUTOSEED_DB = toBool(env.DEV_AUTOSEED_DB || ''); // ICS: horizonte en meses y rate limit (por minuto, 0 = desactivado) const ICS_HORIZON_MONTHS = Number(env.ICS_HORIZON_MONTHS || 12); export const icsHorizonMonths = Math.max(1, Math.floor(ICS_HORIZON_MONTHS)); const ICS_RATE_LIMIT_PER_MIN = Number(env.ICS_RATE_LIMIT_PER_MIN || 0); export const icsRateLimitPerMin = Math.max(0, Math.floor(ICS_RATE_LIMIT_PER_MIN)); // Uncomplete window (minutos; por defecto 1440 = 24h) const UNCOMPLETE_WINDOW_MIN_RAW = Number(env.UNCOMPLETE_WINDOW_MIN || 1440); export const UNCOMPLETE_WINDOW_MIN = Math.max(1, Math.floor(UNCOMPLETE_WINDOW_MIN_RAW)); export const uncompleteWindowMs = UNCOMPLETE_WINDOW_MIN * 60 * 1000; // Reacciones (flags de característica para la web) const REACTIONS_TTL_DAYS_RAW = Number(env.REACTIONS_TTL_DAYS || 14); export const REACTIONS_TTL_DAYS = Math.max(1, Math.floor(REACTIONS_TTL_DAYS_RAW)); export const REACTIONS_ENABLED = toBool(env.REACTIONS_ENABLED || ''); export const REACTIONS_SCOPE = ((env.REACTIONS_SCOPE || 'groups').trim().toLowerCase() === 'all' ? 'all' : 'groups'); export const GROUP_GATING_MODE = (env.GROUP_GATING_MODE || 'off').trim().toLowerCase();