🚀 Initialize Musadaq SaaS: Full Backend + AI + React Dashboard + Docker Setup

This commit is contained in:
Hamza-Ayed
2026-04-16 23:26:32 +03:00
commit d66891ba0f
221 changed files with 13079 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
/**
* ════════════════════════════════════════════════════════════
* مُصادَق — 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('اسم النطاق الرئيسي'),
});