137 lines
5.3 KiB
TypeScript
137 lines
5.3 KiB
TypeScript
/**
|
|
* ════════════════════════════════════════════════════════════
|
|
* مُصادَق — 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('اسم النطاق الرئيسي'),
|
|
});
|