/** * ════════════════════════════════════════════════════════════ * مُصادَق — Environment Validation Schema (Joi) * ════════════════════════════════════════════════════════════ * يتحقق من وجود وصحة جميع متغيرات البيئة عند بدء التطبيق. * أي متغير مفقود أو غير صالح = فشل فوري في التشغيل. * ════════════════════════════════════════════════════════════ */ import * as Joi from 'joi'; export const envValidationSchema = Joi.object({ // ── Application ──────────────────────────────────────── NODE_ENV: Joi.string() .valid('development', 'production', 'test') .required() .description('بيئة التشغيل'), PORT: Joi.number() .port() .default(3300) .description('منفذ الخادم'), APP_URL: Joi.string() .uri() .required() .description('رابط التطبيق الكامل'), ALLOWED_ORIGINS: Joi.string() .required() .description('النطاقات المسموح بها للـ CORS (مفصولة بفاصلة)'), // ── Database ─────────────────────────────────────────── DB_HOST: Joi.string() .required() .description('مضيف قاعدة البيانات'), DB_PORT: Joi.number() .port() .default(5300) .description('منفذ قاعدة البيانات'), DB_USER: Joi.string() .required() .description('مستخدم قاعدة البيانات'), DB_PASS: Joi.string() .min(32) .required() .description('كلمة مرور قاعدة البيانات (32 حرف كحد أدنى)'), DB_NAME: Joi.string() .required() .description('اسم قاعدة البيانات'), // ── Redis ────────────────────────────────────────────── REDIS_HOST: Joi.string() .required() .description('مضيف Redis'), REDIS_PORT: Joi.number() .port() .default(6400) .description('منفذ Redis'), // ── JWT ──────────────────────────────────────────────── JWT_SECRET: Joi.string() .min(64) .required() .description('مفتاح JWT الرئيسي (64 حرف كحد أدنى)'), JWT_EXPIRY: Joi.string() .default('15m') .description('مدة صلاحية Access Token'), JWT_REFRESH_SECRET: Joi.string() .min(64) .required() .description('مفتاح JWT للتجديد (مختلف عن الرئيسي)'), JWT_REFRESH_EXPIRY: Joi.string() .default('7d') .description('مدة صلاحية Refresh Token'), // ── Encryption ───────────────────────────────────────── ENCRYPTION_KEY: Joi.string() .length(64) .hex() .required() .description('مفتاح التشفير AES-256 (32 بايت = 64 حرف hex)'), // ── JoFotara ─────────────────────────────────────────── JOFOTARA_SANDBOX_URL: Joi.string() .uri() .required() .description('رابط بيئة الاختبار لجو فوترة'), JOFOTARA_PROD_URL: Joi.string() .uri() .required() .description('رابط بيئة الإنتاج لجو فوترة'), JOFOTARA_ENV: Joi.string() .valid('sandbox', 'production') .default('sandbox') .description('بيئة جو فوترة المستخدمة'), // ── Gemini AI ────────────────────────────────────────── GEMINI_API_KEY: Joi.string() .required() .description('مفتاح Google Gemini API'), GEMINI_MODEL: Joi.string() .default('gemini-2.0-flash-lite') .description('نموذج Gemini المستخدم'), // ── File Storage ─────────────────────────────────────── STORAGE_PATH: Joi.string() .default('./uploads') .description('مسار تخزين الملفات'), // ── Email ────────────────────────────────────────────── RESEND_API_KEY: Joi.string() .required() .description('مفتاح Resend API للبريد الإلكتروني'), EMAIL_FROM: Joi.string() .email() .required() .description('عنوان المرسل للبريد الإلكتروني'), // ── Domain ───────────────────────────────────────────── DOMAIN: Joi.string() .required() .description('اسم النطاق الرئيسي'), });