mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
docs(dealix): production readiness — go-live gate CLI, LAUNCH_CHECKLIST, internal token note
- Add scripts/check_go_live_gate.py for in-process go-live-gate summary - LAUNCH_CHECKLIST: go-live-gate section, CORS/FRONTEND_URL/NEXT_PUBLIC details, internal token review - internal_api: pointer to checklist section 6 for strict production review Made-with: Cursor
This commit is contained in:
parent
a07829d485
commit
c114ac34ae
@ -1,4 +1,8 @@
|
|||||||
"""Optional bearer token for /api/v1 when DEALIX_INTERNAL_API_TOKEN is set (production hardening)."""
|
"""Optional bearer token for /api/v1 when DEALIX_INTERNAL_API_TOKEN is set (production hardening).
|
||||||
|
|
||||||
|
Exemption list is broad (public marketing, demo widgets). Before strict production, see
|
||||||
|
docs/LAUNCH_CHECKLIST.md section 6.
|
||||||
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|||||||
@ -21,10 +21,22 @@
|
|||||||
`.\scripts\grand_launch_verify.ps1 -HttpCheck -SoftReady`
|
`.\scripts\grand_launch_verify.ps1 -HttpCheck -SoftReady`
|
||||||
مع `DEALIX_BASE_URL` إذا لم يكن الـ API على `http://127.0.0.1:8000`.
|
مع `DEALIX_BASE_URL` إذا لم يكن الـ API على `http://127.0.0.1:8000`.
|
||||||
|
|
||||||
|
### 2.1 بوابة الجاهزية التجارية (`go-live-gate`)
|
||||||
|
|
||||||
|
- [ ] مع تشغيل الـ API وبعد ضبط `.env` الحقيقي (staging أو إنتاج): استدعِ
|
||||||
|
`GET /api/v1/autonomous-foundation/integrations/go-live-gate`
|
||||||
|
- [ ] **200** + `launch_allowed: true` يعني اجتياز الفحوص الحاسمة حسب [`go_live_matrix.py`](../backend/app/services/go_live_matrix.py). **403** مع نفس شكل JSON يعني وجود فحوص معطّلة — راجع `blocked_reasons` و`blocking`.
|
||||||
|
- [ ] من الطرفية (خادم على 8000):
|
||||||
|
`curl -sS http://127.0.0.1:8000/api/v1/autonomous-foundation/integrations/go-live-gate`
|
||||||
|
- [ ] ملخص سريع بدون uvicorn (يحمّل التطبيق داخل العملية، مثل الاختبارات): من جذر `salesflow-saas`:
|
||||||
|
`py -3 scripts/check_go_live_gate.py`
|
||||||
|
(للطباعة الكاملة: `py -3 scripts/check_go_live_gate.py --json`)
|
||||||
|
|
||||||
## 3. الواجهة (Next.js)
|
## 3. الواجهة (Next.js)
|
||||||
|
|
||||||
- [ ] ضبط `NEXT_PUBLIC_API_URL` لنقطة نهاية الـ API العامة (انظر `frontend/.env.example`).
|
- [ ] ضبط **`NEXT_PUBLIC_API_URL`** لعنوان الـ API الذي يصل إليه المتصفح فعليًا (HTTPS في الإنتاج). مرجع: [`frontend/.env.example`](../frontend/.env.example).
|
||||||
- [ ] التأكد من أن الـ backend يضمّن نطاق الواجهة في CORS (`FRONTEND_URL` / `main.py`).
|
- [ ] **CORS:** في الباكند عرّف **`FRONTEND_URL`** (أصل الواجهة الافتراضي، مثل `https://app.dealix.sa`) في `backend/.env` — يُستخدم في [`main.py`](../backend/app/main.py) مع أصول ثابتة إضافية. لأصول إضافية (معاينة، دومين قديم): **`CORS_EXTRA_ORIGINS`** قائمة مفصولة بفواصل — انظر [`app/config.py`](../backend/app/config.py).
|
||||||
|
- [ ] تحقق من أن قيمة `NEXT_PUBLIC_API_URL` على الواجهة **تطابق** المخطط والشهادة (لا خلط `http`/`https` أو دومين خاطئ) حتى لا تفشل طلبات `fetch` / `apiFetch`.
|
||||||
|
|
||||||
## 4. الأسرار والبيئة
|
## 4. الأسرار والبيئة
|
||||||
|
|
||||||
@ -34,7 +46,15 @@
|
|||||||
## 5. ما بعد الإطلاق
|
## 5. ما بعد الإطلاق
|
||||||
|
|
||||||
- [ ] مراقبة `/api/v1/health` و `/api/v1/ready`.
|
- [ ] مراقبة `/api/v1/health` و `/api/v1/ready`.
|
||||||
- [ ] مراجعة `go-live-gate` عند التكاملات الحقيقية (قد يعيد 403 حتى اكتمال التهيئة — متوقع).
|
- [ ] إعادة فحص **`go-live-gate`** بعد أي تغيير على أسرار الطرف الثالث (Stripe، البريد، CRM، إلخ).
|
||||||
|
|
||||||
|
## 6. أمان `DEALIX_INTERNAL_API_TOKEN` (إنتاج)
|
||||||
|
|
||||||
|
عند تعيين **`DEALIX_INTERNAL_API_TOKEN`** في الباكند، يُطلب `Authorization: Bearer <التوكن>` على معظم مسارات `/api/v1`، مع **قائمة إعفاءات** واسعة للمسارات العامة والتسويق والديمو — التنفيذ في [`app/middleware/internal_api.py`](../backend/app/middleware/internal_api.py).
|
||||||
|
|
||||||
|
- [ ] **Staging / ديمو:** الإعفاءات الحالية تسمح للواجهة بجلب محتوى عام ولوحات ديمو دون التوكن الداخلي؛ هذا متعمد لتجربة المطوّر.
|
||||||
|
- [ ] **إنتاج صارم:** راجع ما إذا كانت مسارات الإعفاء (مثل أجزاء من التسويق أو `dealix/generate-leads`) مقبولة لسياسة المنتج؛ يمكن لاحقًا تقييد الإعفاءات حسب `ENVIRONMENT` أو إلزام **`apiFetch` + JWT** لمسارات حساسة بدل الإعفاء.
|
||||||
|
- [ ] إن لم تُضبط المتغير (فارغ)، الميدلوير لا يفرض التوكن — مناسب للتطوير المحلي فقط.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
58
salesflow-saas/scripts/check_go_live_gate.py
Normal file
58
salesflow-saas/scripts/check_go_live_gate.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Print a short summary of GET /api/v1/autonomous-foundation/integrations/go-live-gate.
|
||||||
|
|
||||||
|
Uses the in-process FastAPI app (same deps as pytest). Does not start uvicorn.
|
||||||
|
|
||||||
|
Run from repo:
|
||||||
|
cd salesflow-saas && py -3 scripts/check_go_live_gate.py
|
||||||
|
|
||||||
|
Against a running API instead:
|
||||||
|
curl -sS http://127.0.0.1:8000/api/v1/autonomous-foundation/integrations/go-live-gate | py -3 -m json.tool
|
||||||
|
|
||||||
|
Exit code: 0 always (informational). Use HTTP status / launch_allowed in the JSON when calling from CI.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
saas = Path(__file__).resolve().parent.parent
|
||||||
|
backend = saas / "backend"
|
||||||
|
os.environ.setdefault("DATABASE_URL", "sqlite+aiosqlite:///./go_live_gate_cli.db")
|
||||||
|
os.environ.setdefault("DEALIX_INTERNAL_API_TOKEN", "")
|
||||||
|
sys.path.insert(0, str(backend))
|
||||||
|
os.chdir(backend)
|
||||||
|
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
from app.main import app
|
||||||
|
|
||||||
|
c = TestClient(app)
|
||||||
|
r = c.get("/api/v1/autonomous-foundation/integrations/go-live-gate")
|
||||||
|
try:
|
||||||
|
body = r.json()
|
||||||
|
except Exception:
|
||||||
|
print("HTTP", r.status_code, "non-JSON body", r.text[:500])
|
||||||
|
return 0
|
||||||
|
|
||||||
|
la = body.get("launch_allowed")
|
||||||
|
print(f"HTTP {r.status_code} launch_allowed={la}")
|
||||||
|
print(f"readiness_percent_total={body.get('readiness_percent_total')}")
|
||||||
|
br = body.get("blocked_reasons") or []
|
||||||
|
if br:
|
||||||
|
print("blocked_reasons (up to 8):")
|
||||||
|
for line in br[:8]:
|
||||||
|
print(f" - {line}")
|
||||||
|
blocking = body.get("blocking") or []
|
||||||
|
print(f"blocking_checks={len(blocking)}")
|
||||||
|
if "--json" in sys.argv:
|
||||||
|
print(json.dumps(body, indent=2, ensure_ascii=False))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Loading…
Reference in New Issue
Block a user