پیشفرضهای دیروز روی یک سرورِ تازه کار میکردند ولی روی سرورِ واقعی نه، و تستِ با .env واقعی نشانش داد: هر دو حالتِ شایع خنثیشان میکرد. مقدارِ موجود ولی ناقص: .env سرور از قبل DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1 دارد. چون مقدار خالی نبود، کاملاً جایگزینِ پیشفرض میشد و دامنهی api.math.tadrisino2.ir باز هم غایب میماند — یعنی همان «Disallowed Host» قبلی، و باز هم ویرایشِ دستیِ فایل. حالا دامنههای خودمان به مقدارِ محیطی اضافه میشوند نه جایگزینش؛ همین برای CSRF_TRUSTED_ORIGINS و CORS_ALLOWED_ORIGINS هم اعمال شد. مقدارِ موجود ولی خالی: PUBLIC_BASE_URL در .env هست و خالی است، و os.environ.get فقط وقتی کلید *نباشد* پیشفرض میدهد. نتیجهاش paymentUrl نسبی و callbackِ خالیِ زرینپال بود — خرابیای که فقط موقعِ اولین پرداختِ واقعی معلوم میشود. حالا مقدارِ خالی هم به پیشفرض میافتد. این سهتا همانهاییاند که تا امروز مسئولِ سرور باید دستی به .env اضافه میکرد و چون در .env.example هم نبودند، هر بار از نو کشف میشدند. حالا در همان فایل مستند شدهاند و تست نگهبانشان است. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
115 lines
7.2 KiB
Plaintext
115 lines
7.2 KiB
Plaintext
# نمونهی فایلِ تنظیمات — هم برای ماشینِ خودتان، هم برای سرور.
|
||
#
|
||
# cp .env.example .env
|
||
#
|
||
# تقریباً هیچکدام اجباری نیستند. هر چیزی که از قبل قابلِ تصمیم بود در خودِ
|
||
# کد پیشفرض شده: دامنهها، origin های مجاز، و کلیدِ امضا (اولین اجرا خودش
|
||
# یک کلیدِ تصادفی میسازد و در .django_secret_key نگه میدارد). حتی با یک
|
||
# فایلِ خالی هم سرویس بالا میآید.
|
||
#
|
||
# روی سرور، بعد از یکبار ساختنِ این فایل، هر آپدیت فقط:
|
||
# git pull && ./deploy.sh
|
||
|
||
# -----------------------------------------------------------------------
|
||
# پایه
|
||
# -----------------------------------------------------------------------
|
||
# DEBUG=1 حالتِ توسعه است: خطاها کامل دیده میشوند و اپ راحتتر بالا میآید.
|
||
#
|
||
# ⚠️ روی سرورِ عمومی دو ریسک دارد:
|
||
# • صفحههای خطا کلِ تنظیمات و traceback را نشان میدهند
|
||
# • کدِ ورودِ آزمایشیِ 0000 برای هر شمارهای پذیرفته میشود، یعنی هر
|
||
# کسی میتواند بهجای هر کاربری وارد شود
|
||
# تا وقتی کاربرِ واقعی ندارید اشکالی ندارد؛ قبل از اولین کاربرِ واقعی 0 کنید.
|
||
DJANGO_DEBUG=1
|
||
|
||
# خالی بگذارید تا خودش ساخته و در .django_secret_key ذخیره شود.
|
||
DJANGO_SECRET_KEY=
|
||
|
||
# بدونِ Redis سرویس بالا میآید ولی محدودیتِ نرخ بینِ workerها مشترک نیست؛
|
||
# /api/health همین را هشدار میدهد. برای پروداکشنِ واقعی پرش کنید.
|
||
CACHE_URL=
|
||
|
||
# نامِ سرویسِ systemd تا deploy.sh خودش ریاستارت کند (فقط روی سرور).
|
||
# TADRISINO_SERVICE=
|
||
|
||
# -----------------------------------------------------------------------
|
||
# آدرسِ سرویس — این چهار تا پیشفرضِ درست دارند
|
||
# -----------------------------------------------------------------------
|
||
# تا پیش از این هر چهارتا باید دستی روی سرور اضافه میشدند، و چون در همین
|
||
# فایل نبودند هر بار از نو کشف میشدند: نبودِ اولی یعنی «Disallowed Host»،
|
||
# دومی یعنی ردِ ورود به پنلِ ادمین، سومی یعنی بلاک شدنِ فرانت در مرورگر، و
|
||
# چهارمی یعنی شکستنِ بیسروصدای مسیرِ پرداخت.
|
||
#
|
||
# حالا هر چهارتا مقدارِ پیشفرضِ دامنهی خودمان را دارند و لازم نیست ست شوند.
|
||
# فقط اگر دامنه عوض شد، اینها را باز کنید:
|
||
#
|
||
# DJANGO_ALLOWED_HOSTS=api.math.tadrisino2.ir,math.tadrisino2.ir,localhost,127.0.0.1
|
||
# CSRF_TRUSTED_ORIGINS=https://api.math.tadrisino2.ir
|
||
# CORS_ALLOWED_ORIGINS=https://math.tadrisino2.ir
|
||
# PUBLIC_BASE_URL=https://api.math.tadrisino2.ir
|
||
|
||
# اختیاری — بدونش OTP واقعی ارسال نمیشه (فقط خطای صریح ۵۰۳ برمیگرده،
|
||
# طبق رفتارِ موجودِ accounts/services.py)
|
||
KAVENEGAR_API_KEY=
|
||
|
||
# رمزِ ادمینِ Grafana (کاربرِ admin) — فقط برای دسترسیِ محلی
|
||
GRAFANA_ADMIN_PASSWORD=admin
|
||
|
||
# -----------------------------------------------------------------------
|
||
# RAG / AI tutor (اپ rag) — موقعِ تست پر کنید
|
||
# -----------------------------------------------------------------------
|
||
# بدونِ OPENAI_API_KEY و QDRANT_API_KEY، مسیرِ RAG غیرفعاله و
|
||
# POST /api/ai/ask همون پاسخِ stubِ قبلی رو میده (سازگاریِ عقبرو).
|
||
# فعلاً از GapGPT (پروکسیِ OpenAI برای ایران) استفاده میکنیم.
|
||
OPENAI_API_KEY=
|
||
OPENAI_BASE_URL=https://api.gapgpt.app/v1
|
||
# اگه بعداً خواستی مستقیم OpenAI واقعی رو تست کنی: کلیدِ واقعی رو این پایین
|
||
# پارک کن، بعد فقط دو خطِ بالا رو باهاش عوض کن. هیچ منطقِ سوییچی در کد نیست
|
||
# تا ساده و بیاشتباه بمونه.
|
||
# OPENAI_BASE_URL=https://api.openai.com/v1
|
||
OPENAI_API_KEY_OPENAI_DIRECT=
|
||
OPENAI_CHAT_MODEL=gpt-4o-mini
|
||
OPENAI_VISION_MODEL=gpt-4o
|
||
# این رو تغییر نده؛ باید با مدلی که تیمِ دیگه باهاش collectionها رو ساخته یکی باشه.
|
||
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
|
||
|
||
QDRANT_URL=https://qdrant.tadrisino2.ir:443
|
||
QDRANT_API_KEY=
|
||
|
||
# نامِ collection = f"{subject} {grade}".lower() . collectionهای موجود روی
|
||
# سرورِ تیمِ دیگه (بررسیشده): «علوم تجربی سوم» ، «مطالعات اجتماعی چهارم» ،
|
||
# «مطالعات اجتماعی ششم» ، «ریاضی سوم» ، «ریاضی ششم» ، «ریاضی هفتم».
|
||
# یعنی جزءِ گرید فقط «سوم/چهارم/ششم/هفتم» است (بدونِ «دبستان»).
|
||
#
|
||
# کلیدِ فیلترِ درس دستی تنظیم نمیشه — rag/services/known_collections.py خودش
|
||
# تشخیص میده: ریاضی → `chapter` (و شمارهی فصل رو به رشتهی دقیق تبدیل میکنه)،
|
||
# بقیه → `lesson_number`.
|
||
RAG_COLLECTION_NAME_TEMPLATE={subject} {grade}
|
||
RAG_RETRIEVAL_TOP_K=4
|
||
# RAG_FORCE_MOCK=1 یعنی حتی با وجودِ کلیدها هم مسیرِ RAG خاموش بمونه.
|
||
RAG_FORCE_MOCK=
|
||
|
||
# -----------------------------------------------------------------------
|
||
# زرینپال (اپ payment) — درگاهِ اصلیِ پرداختِ ما
|
||
# -----------------------------------------------------------------------
|
||
# بدونِ ZARINPAL_MERCHANT_ID، مسیرِ پرداخت fail-closed میمونه (خطای صریحِ
|
||
# ۵۰۳ بهجایِ پرداختِ ساختگیِ موفق).
|
||
# PUBLIC_BASE_URL بالاتر توضیح داده شده؛ پیشفرض دارد.
|
||
ZARINPAL_MERCHANT_ID=
|
||
# 1 = محیطِ sandbox زرینپال (برای تست بدونِ پرداختِ واقعی)
|
||
ZARINPAL_SANDBOX=1
|
||
# اختیاری — بعدِ تاییدِ پرداخت، کاربر به این URL (مثلاً یک deep link اپ) با
|
||
# ?orderId=...&status=... ریدایرکت میشه. خالی = پاسخِ JSON ساده.
|
||
ZARINPAL_REDIRECT_URL=
|
||
|
||
# -----------------------------------------------------------------------
|
||
# تنظیماتِ مقیاسپذیری (همه دیفالتِ امن دارن)
|
||
# -----------------------------------------------------------------------
|
||
# persistent DB connection (ثانیه). با SQLite بیاثر؛ بعد از Postgres مهم.
|
||
DB_CONN_MAX_AGE=60
|
||
# کشِ کوتاهِ ردیفِ کاربر در auth تا هر request یک SELECT نزنه. 0 = خاموش
|
||
# (پیشفرض). توصیهی پروداکشن با Redis: 30. با هر save/delete روی User باطل میشه.
|
||
AUTH_USER_CACHE_TTL=0
|
||
# سقفِ ارزانِ خواندن روی endpointهای پرترافیکِ GET (home/leaderboard/summary/...).
|
||
READ_THROTTLE_RATE=120/min
|