الإعدادات (متغيّرات البيئة)¶
يُضبط كلّ شيء عبر متغيّرات البيئة. والمثال المرجعي هو
backend/.env.example.
لا تُودِع الأسرار في المستودع أبدًا
ملفّات backend/.env و.env في الجذر وbackend.env كلّها مستثناة من
git. وعند إضافة متغيّر، وثّقه في ملفّات README — لا قيمته.
الأساسيات¶
| المتغيّر | مثال | الغرض |
|---|---|---|
PORT |
8080 |
منفذ استماع الواجهة الخلفية |
ENVIRONMENT |
production |
يفعّل ضوابط الإنتاج الصارمة |
DEBUG |
false |
تسجيل مفصّل |
ALLOWED_ORIGINS |
https://open.gerege.mn |
قائمة مصادر CORS المسموح بها (مفصولة بفواصل؛ و* ممنوعة) |
TRUSTED_PROXIES |
— | عناوين الوكلاء العكسيين |
قاعدة البيانات وRedis¶
| المتغيّر | الغرض |
|---|---|
DB_POSTGRE_DSN / DB_POSTGRE_URL |
سلسلة الاتصال |
DB_MAX_OPEN_CONNS، DB_MAX_IDLE_CONNS، DB_CONN_MAX_LIFE_MINS |
ضبط مجمّع الاتصالات |
REDIS_HOST، REDIS_PASS، REDIS_EXPIRED |
اتصال Redis ومدّة البقاء |
يجب أن تستخدم سلاسل الاتصال في الإنتاج sslmode=verify-full
يشترط ذلك حارسُ الإنتاج. وتعمل حزمة Docker Compose عمدًا بـ
ENVIRONMENT=development لأنّ قاعدتها الداخلية بلا TLS.
يجب ألّا تتّصل الواجهة الخلفية كمستخدم خارق الصلاحيات
لا تُطبَّق سياسات RLS إلّا إذا اتّصل التطبيق بدور أدنى صلاحية. أمّا الدور
الخارق أو BYPASSRLS فيُفشل الإقلاع في الإنتاج.
JWT والجلسات¶
| المتغيّر | الغرض |
|---|---|
JWT_SECRET |
32 محرفًا فأكثر. تغييره يُبطل كلّ الجلسات |
JWT_EXPIRED، JWT_REFRESH_EXPIRED |
مدّة رمز الوصول / التحديث |
JWT_ISSUER |
عادةً نطاق التطبيق. وتغييره يُبطل جميع الرموز القائمة |
eID (الطرف المعتمِد)¶
| المتغيّر | الغرض |
|---|---|
EID_BASE_URL |
قاعدة /v3 لـ eID Mongolia (أو مرحِّل التوقيع في SSO) |
EID_RP_UUID، EID_RP_SECRET |
بيانات اعتماد الطرف المعتمِد |
SIGN_RELAY_TOKEN |
الرمز المشترك لمرحِّل التوقيع (فارغ = معطَّل) |
Gerege SSO (جانب الطرف المعتمِد — هذا التطبيق كعميل)¶
| المتغيّر | مثال | الغرض |
|---|---|---|
SSO_ISSUER |
https://sso.gerege.mn |
القيمة الافتراضية عند عدم الضبط |
SSO_CLIENT_ID / SSO_CLIENT_SECRET |
— | تركهما فارغين يُبقي مسار SSO خاملًا |
SSO_REDIRECT_URI |
https://open.gerege.mn/sso/callback |
يجب تسجيله حرفيًّا على عميل SSO |
SSO_SCOPE |
openid profile email nationalid |
يضيف nationalid رقم الهوية المدنية |
SSO_NATIVE_CLIENT_ID |
— | عميل المسار المحمول (PKCE، عام) |
SSO_EID_PROXY_BASE_URL |
— | عند ضبطه تمرّ واجهة PKI الخاصّة بـ eID عبر وكيل SSO |
العميل غير المسجَّل يعيد invalid_client
إذا لم يكن SSO_CLIENT_ID مُدرجًا في سجلّ عملاء المزوّد، تعيد خطوةُ التخويل
{"error":"invalid_client"}. ويجب أن يتطابق عنوان إعادة التوجيه حرفيًّا كذلك.
جانب مزوّد OIDC (هذا التطبيق كمزوّد)¶
| المتغيّر | الغرض |
|---|---|
OAUTH_ISSUER |
مثل https://open.gerege.mn. ولا يُفعَّل المزوّد إلّا عند ضبطه |
SSO_STATE_KEY |
مفتاح HMAC للحالة المؤقّتة للدخول/الموافقة (32 بايت فأكثر) |
SSO_FIRSTPARTY_CLIENTS |
عملاء الطرف الأوّل الذين يتخطّون شاشة الموافقة |
SSO_ADMIN_API_KEYS، SSO_ADMIN_SUBS |
الوصول إلى واجهة الإدارة البرمجية |
واجهة الدخول (AUTH_MODE)¶
كون المنصّة تصادِق المستخدمين بنفسها أم تحوّلهم إلى نظام دخول موحّد أعلى ليس اختلافًا في الشيفرة — بل يحدّده هذا المتغيّر وحده:
| القيمة | في الصفحة الرئيسية و/login |
|---|---|
provider |
تُعرض بطاقة الدخول (رقم السجل/رمز eID · Google) هنا |
client |
تحويل إلى نظام الدخول الموحّد الأعلى (SSO_ISSUER) |
AUTH_MODE=client # النشر المرجعي لهذا القالب — طرف معتمِد لدى SSO
AUTH_MODE=provider # خدمة هوية مثل sso.dgov.mn / sso.gerege.mn
واتركه فارغًا فيُستنتج من وجود SSO_CLIENT_ID — فلا تحتاج عمليات النشر القائمة
إلى أيّ تغيير.
الخطأ المطبعي ليس ارتدادًا صامتًا
القيمة غير المعروفة تجعل الواجهة الخلفية ترفض الإقلاع. وإلّا لأقلعت المنصّة بهدوء بواجهة دخول مغايرة للمقصود.
محور منفصل عن OAUTH_ISSUER
يجيب OAUTH_ISSUER عن سؤال «هل هذه المنصّة مُصدِر لتطبيقات أخرى»، بينما
يجيب AUTH_MODE عن «أين يسجّل مستخدمو هذه المنصّة دخولهم». ويمكن تفعيل
الاثنين معًا — في ترتيب متسلسل.
تقرأ الواجهة الأمامية وضعها من نقطة النهاية العامة GET /api/v1/site/auth (دون
مصادقة ودون أسرار)، فلا توجد متغيّرات بيئة مكرَّرة في الواجهة الأمامية.
لغات الواجهة¶
تُشحن المنصّة بترجمات مدمجة للمنغولية ولغات الأمم المتّحدة الرسمية الستّ (العربية · الصينية · الإنجليزية · الفرنسية · الروسية · الإسبانية). وتعمل السبع فورًا — بقاعدة بيانات فارغة ودون أيّ خطوة ترجمة.
وتحصل العربية تلقائيًّا على <html dir="rtl">.
| المتغيّر | ملاحظات |
|---|---|
| — | لا حاجة إلى إعداد؛ تصل اللغات إلى جدول languages بوصفها is_builtin |
وإذا احتجت لغات إضافية، يضيفها المشرف الأعلى من قسم اللغات ويملأ ترجماتها بـ Gemini — وتُحفظ على هيئة overlay في قاعدة البيانات.
الأطراف الثالثة والتخزين¶
| المتغيّر | الغرض |
|---|---|
GEMINI_API_KEY |
خطّ الذكاء الاصطناعي. وبدونه تعيد /ai/* خطأ 500 حقيقيًّا |
GOOGLE_CLIENT_ID / SECRET |
الربط بحساب Google (يختفي الزرّ عند تركه فارغًا) |
VERIFY_API_BASE، VERIFY_API_KEY، VERIFY_CHANNEL |
التحقّق من المواطنين / المنظمات |
XYP_API_BASE، XYP_CLIENT_ID، XYP_CLIENT_SECRET |
استعلامات السجلّات الحكومية |
GSPACE_* |
تخزين SFTP الخاصّ بالتطبيق (حصّة لكلّ مستخدم) |
INTEGRATION_ENC_KEY |
16 بايت فأكثر. يشفّر رموز OAuth والمصادقة الثنائية للمشرف الأعلى |
المفتاح INTEGRATION_ENC_KEY إلزامي
تتطلّب عمليات النشر هذا المفتاح إلزامًا، وبعد ضبطه يجب ألّا يتغيّر أبدًا — فتدويره يُفسد كلّ القيم المشفَّرة سابقًا.
المراقبة¶
| المتغيّر | الغرض |
|---|---|
OTEL_EXPORTER، OTEL_SAMPLE_RATIO |
تتبّع OpenTelemetry |
OBSERVABILITY_TOKEN |
رمز bearer يحمي /metrics و/swagger في الإنتاج |
الواجهة الأمامية¶
| المتغيّر | الغرض |
|---|---|
BACKEND_URL |
العنوان الداخلي الذي تستدعيه طبقة BFF (مثل http://api:8080) |
قد يتضارب الاسم api على شبكة مشتركة
عندما تتشارك عدّة حزم شبكةَ Docker واحدة، قد يُترجَم http://api:8080 إلى
حاوية أخرى فتتحوّل كلّ نداءات /api/v1/* إلى 404. وحينها ثبِّت
BACKEND_URL على الاسم الكامل لحاوية api الخاصّة بك.