/** * إعداد مركزي يقرأ متغيرات البيئة مع افتراضات العزل (راجع docs/14). */ export default () => ({ env: process.env.NODE_ENV ?? 'development', apiPort: parseInt(process.env.API_PORT ?? '4010', 10), db: { host: process.env.DB_HOST ?? 'postgres', port: parseInt(process.env.DB_PORT ?? '5432', 10), name: process.env.DB_NAME ?? 'tripz', user: process.env.DB_USER ?? 'tripz', password: process.env.DB_PASSWORD ?? 'change_me_strong', // بادئة الجداول لعزل Tripz عن باقي البرامج على نفس السيرفر tablePrefix: process.env.DB_TABLE_PREFIX ?? 'tripz_', synchronize: process.env.DB_SYNC === 'true', }, redis: { host: process.env.REDIS_HOST ?? 'redis', port: parseInt(process.env.REDIS_PORT ?? '6379', 10), // DB رقم غير الافتراضي 0 لعزل Tripz عن باقي البرامج db: parseInt(process.env.REDIS_DB ?? '3', 10), keyPrefix: process.env.REDIS_KEY_PREFIX ?? 'tripz:', }, queue: { prefix: process.env.QUEUE_PREFIX ?? 'tripz_', }, jwt: { secret: process.env.JWT_SECRET ?? 'change_me_jwt_secret', expires: process.env.JWT_EXPIRES ?? '15m', refreshExpires: process.env.JWT_REFRESH_EXPIRES ?? '30d', }, auth: { // وضع تطوير: رمز OTP ثابت 0000 يُطبع باللوغ بلا مزوّد SMS (راجع docs/07). // للإنتاج: OTP_DEV_MODE=false + ربط محوّل SMS في P2. otpDevMode: process.env.OTP_DEV_MODE !== 'false', otpTtl: parseInt(process.env.OTP_TTL ?? '300', 10), otpLength: parseInt(process.env.OTP_LENGTH ?? '4', 10), // ربط الجلسة بالجهاز (docs/17 — D2). مطفأ حتى يرسل فلاتر x-device-id؛ // تفعيله قبل ذلك يقطع كل طلب مصادَق (نفس نمط PAYMENTS_REQUIRE_SIGNATURE). requireDeviceBinding: process.env.AUTH_REQUIRE_DEVICE_BINDING === 'true', }, maps: { tilesUrl: process.env.MAPS_TILES_URL ?? 'http://martin:3000', provider: process.env.MAPS_PROVIDER ?? 'antlaq', // خرائط انطلق (map-saas). مفتاح افتراضي + مفاتيح لكل دولة. baseUrl: process.env.MAPS_BASE_URL ?? 'https://map-saas.intaleqapp.com', apiKey: process.env.MAPS_API_KEY ?? '', apiKeyByCountry: { jo: process.env.MAPS_API_KEY_JO ?? process.env.MAPS_API_KEY ?? '', sy: process.env.MAPS_API_KEY_SY ?? process.env.MAPS_API_KEY ?? '', } as Record, placesApiKey: process.env.MAPS_PLACES_API_KEY ?? process.env.MAPS_API_KEY ?? '', }, // Nabeh — إرسال OTP عبر واتساب. nabeh: { baseUrl: process.env.NABEH_BASE_URL ?? 'https://nabeh.intaleqapp.com', email: process.env.NABEH_EMAIL ?? '', password: process.env.NABEH_PASSWORD ?? '', otpType: process.env.NABEH_OTP_TYPE ?? 'text', }, // ملاحظة: خرائط الاتصال الدولية صارت في common/phone/phone.service.ts // (docs/17 — D1) — مصدر واحد للحقيقة بدل نسختين قد تتباعدان. // Gemini (رؤية) — قراءة الوثائق ومطابقة الوجه. gemini: { apiKey: process.env.GEMINI_API_KEY ?? '', model: process.env.GEMINI_MODEL ?? 'gemini-2.0-flash', }, // سرّ المنصة (super-admin) — لتعيين أول أدمن قبل وجود أدمن. platform: { secret: process.env.PLATFORM_SECRET ?? '', }, // تخزين ملفات الوثائق. baseUrl فارغ = محلي؛ يُضبط لسيرفر التوطين لاحقاً (docs/06). storage: { dir: process.env.STORAGE_DIR ?? '/app/storage', baseUrl: process.env.STORAGE_BASE_URL ?? '', }, // المدفوعات: توقيع HMAC على العمليات المالية (docs/17 — I6). // مطفأ حتى يوقّع تطبيق فلاتر؛ تفعيله قبل ذلك يقطع كل سحب. payments: { requireSignature: process.env.PAYMENTS_REQUIRE_SIGNATURE === 'true', }, // إشعارات FCM (اتركه فارغاً لتعطيل الإرسال — يُسجَّل فقط). fcm: { serverKey: process.env.FCM_SERVER_KEY ?? '', endpoint: process.env.FCM_ENDPOINT ?? 'https://fcm.googleapis.com/fcm/send', }, });