متغيرات البيئة
ما يفعله كل إعداد في ملفات .env الخاصة بواجهة API والواجهتين الأماميتين، وأيها تحتاج إليه.
لحزمة الحزمة الكاملة
أين توجد الإعدادات
| الملف | يقرؤه | يحتوي على أسرار |
|---|---|---|
back-end/.env | واجهة API، مع yarn dev وداخل Docker Compose | نعم. لا تضفه إلى المستودع أبدًا. |
storefront/.env | المتجر، أثناء البناء | لا. كل القيم عامة. |
admin-dashboard/.env | لوحة الإدارة، أثناء البناء | لا. كل القيم عامة. |
.env بجوار docker-compose.yml | Docker Compose، للحزمة الكاملة | لا |
أنشئ كل ملف من .env.example المجاور له، والذي يوثّق كل متغير: cp .env.example .env. تعمل الأمثلة كما هي للتشغيل المحلي.
أين توجد الإعدادات
ملف واحد، storefront/.env، يُقرأ عند بناء المتجر. كل القيم فيه عامة، لذا لا يحتوي على أي سر أبدًا. اتركه لتشغيل المتجر النموذجي؛ وأنشئه من .env.example عندما تربط واجهة API: cp .env.example .env.
أين توجد الإعدادات
ملف واحد، admin-dashboard/.env، يُقرأ عند بناء لوحة الإدارة. كل القيم فيه عامة، لذا لا يحتوي على أي سر أبدًا. اتركه لتشغيل المتجر النموذجي؛ وأنشئه من .env.example عندما تربط واجهة API: cp .env.example .env.
أين توجد الإعدادات
ملف واحد، back-end/.env، تقرؤه واجهة API مع yarn dev، وتقرؤه الحاوية عندما تمرّره بـ --env-file .env. يحتوي على أسرار: لا تضفه إلى المستودع أبدًا. أنشئه من .env.example، الذي يوثّق كل متغير ويعمل كما هو للتشغيل المحلي: cp .env.example .env.
أساسيات واجهة API
تتحقق واجهة API من JWT_SECRET وCORS_ORIGIN قبل أن تبدأ. إذا كان أحدهما مفقودًا أو غير صالح، تتوقف وتطبع سطرًا واحدًا يوضح ما يجب إصلاحه.
| المتغير | وظيفته |
|---|---|
NODE_ENV | development محليًا، وهو ينشئ الجداول ويحدّثها عند بدء التشغيل. وproduction على خادم مباشر، وهو لا يلمس الجداول أبدًا. |
PORT | منفذ واجهة API، وهو 8000. تشير إليه الواجهتان الأماميتان. |
DB_TYPE | sqlite (الافتراضي) أو mysql. |
SQLITE_DATABASE | مسار ملف SQLite، وهو ./database.sqlite افتراضيًا. |
JWT_SECRET | يوقّع كل جلسة تسجيل دخول. مطلوب. القيمة المثال مقبولة في بيئة التطوير فقط. |
JWT_EXPIRATION | مدة صلاحية تسجيل الدخول، وهي 7d افتراضيًا. |
CORS_ORIGIN | عنوانا المتجر ولوحة الإدارة، مفصولين بفاصلة. إذا لم يُضبط، يُستخدم المنفذان المحليان؛ وهو مطلوب في الإنتاج. |
FRONTEND_URL | عنوان لوحة الإدارة، الذي تتصل منه إشعاراتها المباشرة. مطلوب في الإنتاج لتعمل تلك الإشعارات. |
TRUST_PROXY | اختياري. إلى أي مدى تثق واجهة API بـ X-Forwarded-For عند حساب محاولات تسجيل الدخول لكل زائر. إذا لم يُضبط، لا تقرؤه إلا من خادم وكيل على عنوان خاص؛ ومع false لا تقرؤه أبدًا؛ ومع رقم تثق بذلك العدد من الخوادم الوكيلة تمامًا. |
RESEED_REVIEWS | اختياري. القيمة 1 تجعل yarn seed يعيد كتابة التقييمات التجريبية. |
ولّد JWT_SECRET خاصًا بك بالأمر:
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"أي بيانات اعتماد أدناه ما زالت تحمل قيمتها في .env.example تمامًا تُعامَل كأنها غير مضبوطة، فتُظهر الميزة التابعة لها أنها متوقفة بدلًا من أن تفشل عند أول استدعاء.
استخدم MySQL بدلًا من SQLite
أنشئ قاعدة بيانات فارغة، ثم اضبط برنامج التشغيل والاتصال في back-end/.env:
DB_TYPE=mysql
DB_HOST=your-mysql-host
DB_PORT=3306
DB_USERNAME=your-mysql-username
DB_PASSWORD=your-mysql-password
DB_DATABASE=your-database-nameثم شغّل yarn seed للمتجر التجريبي، أو yarn db:sync للجداول من دون بيانات. لا تنشئ واجهة API العاملة الجداول ولا تحدّثها بنفسها إلا عندما يكون NODE_ENV=development، لذا مع NODE_ENV=production يجب تشغيل أحد هذين الأمرين قبل أول تشغيل (yarn db:sync:prod أو yarn seed:prod بعد yarn build).
المتجر ولوحة الإدارة
كل قيمة NEXT_PUBLIC_* تُضمَّن في كود JavaScript الذي يحمّله المتصفح، ويستطيع أي شخص يفتح الصفحة قراءتها. لا تضع أي سر في هذه الملفات أبدًا، وأعد البناء بعد تغيير أي قيمة.
| المتغير | التطبيق | وظيفته |
|---|---|---|
NEXT_PUBLIC_API_BASE_URL | كلاهما | عنوان واجهة API متضمنًا /api، مثل http://localhost:8000/api. ضبطه هو ما يوقف المتجر النموذجي؛ وإذا كان فارغًا أو غير موجود، يعمل التطبيق على متجره النموذجي. |
NEXT_PUBLIC_MEDIA_HOSTNAME | كلاهما | المضيف العام لمخزن الوسائط الخاص بك، أي مضيف R2_PUBLIC_URL، من دون https:// ومن دون شرطة مائلة في النهاية. اتركه فارغًا حتى يصبح لديك مخزن. |
NEXT_PUBLIC_SITE_URL | المتجر | العنوان العام للمتجر، ويُستخدم لروابط canonical و hreflang، وبطاقات المشاركة، والبيانات المنظمة، وrobots.txt وsitemap.xml. اضبطه على نطاقك الحقيقي قبل الإطلاق. |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | المتجر | مفتاح حقيقي pk_test_… أو pk_live_…. إذا كان فارغًا، أو أي شيء ليس مفتاحًا حقيقيًا، يتوقف خيار البطاقة في صفحة إتمام الشراء، ويُطلب من المتسوّقين اختيار الدفع عند الاستلام. |
NEXT_PUBLIC_DEMO_CHECKOUT | المتجر | القيمة true تملأ صفحة إتمام الشراء مسبقًا ببيانات مشترٍ مولَّد، للعروض التجريبية. اتركها false لمتجر حقيقي. |
API_INTERNAL_URL | كلاهما | اختياري، للخادم فقط. العنوان الذي يصل منه خادم التطبيق نفسه إلى واجهة API عندما يختلف عن عنوان المتصفح، كما داخل Docker Compose. اتركه فارغًا في غير ذلك. |
NEXT_PUBLIC_WEBSOCKET_BASE_URL | لوحة الإدارة | عنوان واجهة API من دون /api، للإشعارات المباشرة وتحديثات الصلاحيات. اختياري: إذا كان فارغًا يُؤخذ من NEXT_PUBLIC_API_BASE_URL. |
NEXT_PUBLIC_STOREFRONT_URL | لوحة الإدارة | الوجهة التي يذهب إليها رابط «الذهاب إلى المتجر» في الشريط العلوي للوحة الإدارة. |
BUILD_STANDALONE | كلاهما | القيمة true تجعل yarn build يُخرج خادمًا مستقلًا بذاته، وهي القيمة التي تضبطها ملفات Dockerfile. اتركه غير مضبوط في غير ذلك. |
وسوم التسويق في المتجر هي أيضًا قيم NEXT_PUBLIC_*.
خيارات Docker Compose
لا حاجة إلى ضبط أي شيء للتشغيل المحلي. لتغيير شيء ما، ضعه في ملف .env بجوار docker-compose.yml وشغّل docker compose up --build مجددًا: تضمّن الواجهتان الأماميتان هذه القيم أثناء البناء.
| المتغير | وظيفته |
|---|---|
SITE_PORT, ADMIN_PORT, API_PORT | المنافذ على جهازك: 3030 و3031 و8000 افتراضيًا. اضبط أحدها حين يستخدم برنامج آخر ذلك المنفذ، مثل ADMIN_PORT=3041. وتتبعها العناوين أدناه وCORS_ORIGIN وFRONTEND_URL. |
SITE_URL, ADMIN_URL, API_URL | العناوين التي يصل منها المتصفح إلى كل تطبيق. اضبط الثلاثة كلها عند تشغيل الحزمة على نطاقاتك الخاصة؛ إذ يُبنى منها CORS_ORIGIN وFRONTEND_URL الخاصان بواجهة API. |
MEDIA_HOSTNAME | المضيف العام لمخزنك، مع متغيرات R2_* في back-end/.env. |
SEED_DEMO_DATA | القيمة false تبدأ بجداول فارغة بدلًا من المتجر التجريبي. |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | نموذج البطاقة في المتجر. |
NEXT_PUBLIC_GTM_ID, NEXT_PUBLIC_GA4_MEASUREMENT_ID, NEXT_PUBLIC_META_PIXEL_ID, NEXT_PUBLIC_TIKTOK_PIXEL_ID, NEXT_PUBLIC_SNAPCHAT_PIXEL_ID, NEXT_PUBLIC_PINTEREST_TAG_ID, NEXT_PUBLIC_ANALYTICS_CURRENCY | وسوم التسويق في المتجر، وكلها اختيارية. |
تقرأ حاوية واجهة API أيضًا ملف back-end/.env عند وجوده، فتُضبط مفاتيح الدفع والوسائط والذكاء الاصطناعي في مكان واحد لكل من yarn dev و Docker. وتكون الأولوية لملف compose في القيم القليلة التي تختلف داخل الحاوية: مسار قاعدة البيانات، والمنفذ، وNODE_ENV=production، وCORS_ORIGIN، وFRONTEND_URL. تُحفظ البيانات في وحدة التخزين ecommerce-data.
تخزين الوسائط
تُرفع صور المنتجات، وصور الفئات، والصور الرمزية، ومرفقات المحادثة، ونتائج استوديو الذكاء الاصطناعي، وصور غرفة القياس إلى مخزن Cloudflare R2، أو أي مخزن متوافق مع S3. اضبط المتغيرات الخمسة في back-end/.env وأعطِ الواجهتين الأماميتين المضيف العام للمخزن عبر NEXT_PUBLIC_MEDIA_HOSTNAME (ومع Docker Compose عبر MEDIA_HOSTNAME).
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
R2_BUCKET_NAME=
R2_PUBLIC_URL=https://your-public-url.r2.devمن دون مخزن، يحفظ yarn seed صورة كل منتج وفئة كمسار /mock-media/…، وترفق الواجهتان الأماميتان هذه الملفات الخمسة والثلاثين في public/mock-media/، فيظهر الكتالوج دون رفع أي شيء. يتوقف فقط رفع الصور الجديدة: يُجاب بـ 503 إلى أن يُضبط المخزن.
مع وجود مخزن، ترفع عملية تعبئة البيانات صور الكتالوج إليه. أبقِ public/mock-media/ في الواجهتين الأماميتين ما دام أي منتج يشير إليه.
الدفع بالبطاقة
يعمل الدفع بالبطاقة عبر Stripe: STRIPE_SECRET_KEY وSTRIPE_WEBHOOK_SECRET في back-end/.env، وNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY للمتجر. من دونها لا يُقبل أي دفع بالبطاقة، ويعمل الدفع عند الاستلام كالمعتاد.
STRIPE_SECRET_KEY=sk_test_your-stripe-secret-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secretالبريد الإلكتروني
لا يأتي القالب مع وسيلة لإرسال البريد، لذا لا تُرسل أي رسالة بالبريد الإلكتروني أبدًا. خارج بيئة الإنتاج، يُكتب رمز إعادة تعيين كلمة مرور العميل في سجل واجهة API بدلًا من ذلك؛ ومع NODE_ENV=production لا يذهب إلى أي مكان. اربط مزوّد البريد الخاص بك قبل الإطلاق: نقطة الربط هي forgotPassword في back-end/src/modules/customer-auth/customer-auth.controller.ts.
ميزات الذكاء الاصطناعي
مُضمَّن مع مشترياتك. سجّل الدخول لقراءته، أو افتحه في ملف التنزيل.
تفعيل ميزات الذكاء الاصطناعي: مفاتيح المزوّدين، والنماذج التي تستخدمها كل ميزة، وتكلفة كل منها.
المتجر النموذجي في الواجهتين الأماميتين
تعمل الواجهتان الأماميتان من دون واجهة API. عند تشغيل أي منهما أو بنائها من دون NEXT_PUBLIC_API_BASE_URL، تُجيب عن كل طلب من متجر نموذجي داخل المتصفح وتعرض تنبيه «بيانات تجريبية». ضبط العنوان هو ما يوقفه.
- في المتجر، أي بريد إلكتروني وكلمة مرور يسجّلان دخولك كمتسوّق نموذجي. وفي لوحة الإدارة، يسجّل دخولك كمدير عام أي بريد إلكتروني صالح مع كلمة مرور من 6 أحرف على الأقل.
- عمليات الكتابة حقيقية وتُحفظ في تخزين المتصفح، فتبقى بعد إعادة تحميل الصفحة. للبدء من جديد، شغّل
localStorage.removeItem("mock_db_v1"); location.reload();في وحدة تحكم المتصفح. - تكتمل عملية إتمام الشراء في المتجر دون الاتصال بـ Stripe.
- في لوحة الإدارة، يبقى المساعد الذكي واستوديو الذكاء الاصطناعي غير متاحين، لأن كليهما يحتاج إلى مفاتيح واجهة API.
- بعد أن تصبح واجهة API الخاصة بك قيد العمل، يحذف
yarn remove:mockفي أي من التطبيقين المتجر النموذجي وتنبيهه. ويُبقيpublic/mock-media/في مكانه، لأن الخادم الخلفي المملوء بالبيانات من دون مخزن يوجّه صوره إليه.
كيف يعمل المتجر النموذجي
مُضمَّن مع مشترياتك. سجّل الدخول لقراءته، أو افتحه في ملف التنزيل.
كيف تُوجَّه الطلبات إلى المتجر النموذجي، وكيف تغيّره أو توسّعه.
وضع العرض التجريبي
مُضمَّن مع مشترياتك. سجّل الدخول لقراءته، أو افتحه في ملف التنزيل.
تشغيل عرض تجريبي عام: مفتاح العرض التجريبي، والحسابات المنفصلة لكل زائر، وما يستطيع الزوار تغييره.
الإطلاق
قبل النشر على أي مكان عام:
- اضبط
NODE_ENV=productionوJWT_SECRETعشوائيًا وطويلًا خاصًا بك فيback-end/.env. - اضبط
CORS_ORIGINعلى عنوانَي المتجر ولوحة الإدارة، مفصولين بفاصلة، وFRONTEND_URLعلى عنوان لوحة الإدارة. - على قاعدة بيانات فارغة، شغّل
yarn build، ثمyarn db:sync:prodمرة واحدة (أوyarn seed:prodللمتجر التجريبي)، ثمyarn start:prod. - وجّه فحص السلامة لدى الاستضافة إلى
/api/health. - ابنِ كل واجهة أمامية مع ضبط
NEXT_PUBLIC_API_BASE_URLعلى واجهة API المنشورة، وضبطNEXT_PUBLIC_SITE_URLللمتجر على عنوانه الخاص. - غيّر كلمة مرور المدير العام، أو ابدأ من جداول فارغة.
لا يصلح لمتجر فيه طلبات حقيقية
يبني yarn railway:setup التطبيق، ويجلب نموذج إزالة الخلفية، ويحذف كل الجداول ويملأ البيانات من جديد، في كل مرة يُشغَّل فيها. يناسب نشر عرض تجريبي، ولا يصلح أبدًا كأمر بناء لمتجر حقيقي.