OpenYsd/ysd-ai

1

stars

195

commits

TypeScript

primary language

Sep 11, 2026

updated

README

YSD AI — منصة الذكاء العربي

منصة ذكاء اصطناعي احترافية من YSD AI Studio. عربية أولًا (RTL) مع دعم الإنجليزية، مبنية على بنية Modular قابلة للتوسع.

التقنيات

الطبقةالتقنية
الواجهةNext.js App Router · TypeScript Strict · Tailwind CSS
قاعدة البيانات والمصادقةSupabase (PostgreSQL · Auth · Storage · RLS)
الذكاء الاصطناعيطبقة AIProviderAdapter موحدة — Anthropic أولًا، جاهزة لأي موفر
التحققZod · React Hook Form
الاختباراتVitest · Playwright

التشغيل المحلي

# 1. تثبيت الاعتماديات
npm install

# 2. إعداد البيئة
cp .env.example .env
# املأ مفاتيح Supabase وANTHROPIC_API_KEY

# 3. إعداد Supabase
#    - أنشئ مشروعًا على supabase.com
#    - ثبّت Supabase CLI ثم:
supabase link --project-ref YOUR_PROJECT_REF
supabase db push          # يشغّل migrations من supabase/migrations/

# 4. التشغيل
npm run dev

الفحص قبل أي Commit

npm run typecheck && npm run lint && npm run build && npm test

⚠️ لا تشغّل npm run build أثناء عمل npm run dev — كلاهما يكتب في .next نفسه، وسيؤدي ذلك إلى صفحات بلا CSS (روابط أصول قديمة ترجع 404). إن حدث ذلك: أوقف الخادم، احذف .next، ثم شغّل npm run dev من جديد. اختبار tests/styling-e2e.test.ts (مع YSD_E2E=1) يكتشف هذه الحالة آليًا.

بنية المشروع

app/
  api/chat/route.ts        مسار المحادثة الآمن (Streaming · Rate limit · Usage)
  (auth)/login/            صفحات المصادقة
  (app)/chat/              واجهة المحادثة (قيد البناء — انظر النموذج الأولي)
lib/
  ai/                      AIProviderAdapter + الموفرون + السجل
  supabase/                عملاء الخادم والمتصفح
  validation/              مخططات Zod
supabase/migrations/       مخطط قاعدة البيانات + RLS
docs/                      خارطة الطريق والتوثيق
middleware.ts              حماية الجلسات والصفحات ولوحة الإدارة

إضافة موفر ذكاء اصطناعي جديد

انظر docs/ADDING_A_PROVIDER.md — باختصار: نفّذ واجهة AIProviderAdapter وسجّله في lib/ai/registry.ts. لا حاجة لتعديل أي شيء آخر.

الميزات — v0.6.6

استقرار وتجربة (إصدار تثبيت): لا ردود مقطوعة ولا مُعلّم قائمة منفرد، ولا تكرار للرسالة عند النقر المزدوج أو إعادة الاتصال (client_request_id محمي في قاعدة البيانات — يعمل عبر أكثر من نسخة خادم)، ولا خروج مفاجئ عند انتهاء access token مع بقاء المسودة، وتصنيف صريح لأخطاء auth_expired/network_error/timeout/rate_limit/provider_unavailable. الأسماء الملتبسة تُسأل بدل التخمين (JoJo ≠ Jujutsu Kaisen)، والمهلة تشمل جسم البثّ لا الترويسات فقط.

مراقبة آمنة: /admin/health بمقاييس دائمة تنجو من إعادة التشغيل. الجدول لا يخزّن نص المستخدم ولا نص المساعد ولا البريد ولا IP ولا user_id — أرقام ورموز مغلقة فقط، والقراءة للإدارة وحدها. مفتاح الخدمة خادمي بحت محروس بـserver-only ولا يصل المتصفح.

يتطلب تطبيق migrations 0017 و0018 — انظر docs/V0.6.6_DATABASE_GATE.md.

الميزات — v0.6.5

جودة الإجابة: فهم سياق الألعاب والقصص بدل الرفض بالكلمات المفتاحية (ضرر/نزف لم تعد تُسقط سؤالًا آمنًا)، ورفض الأذى الحقيقي باختصار. أسماء الألعاب بالنقحرة العربية تُفهَم («الدن رينق» = Elden Ring). الأسئلة التي تطلب مواقع أو خطوات أو أرقامًا دقيقة تدخل وضعًا محميًا: لا تُعرض تفاصيل متخصصة غير مُسنَدة إلى مصدر، وبلا مصدر يصل اعتراف فوري بعدم التأكد (~1.4 ثانية، بلا استدعاء مزوّد). الأسئلة العامة والإبداعية تبقى على البثّ الفوري كما هي.

متانة: حارس لغة أدقّ يمنع التسريبات (يابانية/سيريلية/يونانية وكلمات دخيلة) مع السماح بأسماء العلم والاختصارات، وإصلاح انقطاع البثّ المتأخر بمتابعة صامتة بلا تكرار، ومنع الردود الفارغة (تفكير داخلي بلا إجابة).

حدّ معروف: سؤال متخصص بلا ملف مرفق يحصل على اعتراف بعدم التأكد لا على إجابة تفصيلية. للحصول على تفاصيل موثقة: أرفق ملفًا واسأل عنه (RAG). هذا الإصدار لا يضمن صحة كل المعلومات العامة.

الميزات — v0.6.4

أداء (مقيس): تحقّق هوية محلي بـgetClaims (ES256/JWKS) بلا رحلة شبكة، إسقاط تكرار auth/profile عبر سياق الوسيط المُتحقَّق (x-ysd-*، محمي ضد الانتحال)، كاش platform_settings 30ث مع إبطال، وموازاة استعلامات /api/chat (Promise.allSettled بعد ضمان حفظ رسالة المستخدم). زمن التطبيق قبل المزوّد ~3410ms → 1030ms، إنشاء المحادثة 2422ms → 1030ms. ما تبقّى من زمن أول token خارجي (المزوّد المجاني). سجلات أداء آمنة بـrequest_id بلا محتوى أو أسرار.

الميزات — v0.6.3

حالات المرفقات صريحة وصادقة:

  • أربع حالات في المحادثة: استخراج النص · تجهيز الذكاء الاصطناعي (مع النسبة) · جاهز للسؤال · فشل مع زر إعادة محاولة.
  • الصور: «صورة — بلا سياق AI». الصور تُحفظ وتُعرض فقط ولا تدخل RAG (بلا OCR) — والواجهة تقول ذلك صراحةً بدل أن تَعِد بتجهيز لا يأتي.
  • إعادة المحاولة آمنة: idempotency عبر rag_content_hash + فهرس فريد جزئي للوظائف + حذف chunks الملف قبل أي إدراج ⇒ لا chunks مكررة.

الميزات — v0.6.2

صلابة النماذج المجانية:

  • تهدئة النماذج: النموذج الفاشل يُتخطّى قبل إرسال أي طلب إليه — لا يُدفع ثمن الفشل في كل طلب. 429Retry-After وإلا 15 دقيقة · 404 no_free_model → 6 ساعات (غياب بنيوي) · 5xx/timeout → دقيقتان. انتهاء المدة يسمح بمحاولة واحدة جديدة تلقائيًا.
  • ثلاثة مزوّدين في سلسلة ysd/free: Google AI Studio · Nvidia · Darkbloom — حجب مزوّد واحد لا يُسقط الخدمة (الدرس: التنوّع في المزوّد لا في اسم النموذج).
  • كل نموذج مُختبَر عربيًا فعليًا قبل الإنتاج (بث حقيقي + نقاء أحرف + رفض الاختلاق). openrouter/free مستبعد دائمًا.
  • عند تهدئة الجميع: رسالة عربية بمدة صادقة، بلا انتظار وبلا محاولات مكررة.

الميزات — v0.6.0

Private Beta — بالدعوات فقط:

  • التسجيل مغلق إلا بدعوة. البوابة في مُحفّز handle_new_user على auth.usersغير قابلة للتجاوز من أي عميل. إعداد Supabase Allow new users to sign up يبقى مفعّلًا عمدًا؛ الإغلاق من platform_settings والتطبيق فقط.
  • دعوات hash-only: كود ≈80 بت، تُخزَّن sha256 وcode_hint فقط. الكود الخام يُعاد مرة واحدة ولا يدخل القاعدة ولا السجلات ولا التدقيق.
  • رموز تسجيل مؤقتة أحادية الاستخدام: كود الدعوة لا يصل GoTrue إطلاقًا؛ يُستبدل عبر /api/invite/claim بتذكرة 32 بايت تعيش 10 دقائق (hash فقط). تُستهلك ذريًا عند التسجيل ثم تُستهلك الدعوة ذريًا — فتسريبها بلا قيمة. لماذا: أي مفتاح في signUp.data ينتهي في استجابة GoTrue وفي الـJWT.
  • مكافحة الإغراق في القاعدة: قفل صف الدعوة (FOR UPDATE) قبل العدّ والإدراج، ثم 3 تذاكر نشطة و20 تذكرة/ساعة لكل دعوة. الرفض عام لا يكشف السبب. الـRate Limit في المسار طبقة إضافية فقط (الدالة مُصرَّحة لـanon عبر PostgREST).
  • تأكيد البريد مفعّل + موافقة إلزامية على الشروط والخصوصية: رقم النسخة يُختم من platform_settings داخل المُحفّز — لا يُوثق بنسخة العميل.
  • حالات الدعوات بساعة القاعدة: revoked → exhausted → expired → active تُحسب في PostgreSQL بـnow()، والانتهاء يُحسب بـnow() + make_interval(days => …). لا Date.now() في مسار الدعوات — الإنشاء والإنفاذ والعرض على ساعة واحدة.
  • وضع صيانة حقيقي: يحجب المستخدم العادي من الصفحات والـAPIs الخاصة (503) ويسمح للطاقم. الحظر شامل: banned → كل الصفحات الخاصة (/suspended) وكل الـAPIs (403)؛ ai_suspended يمنع /api/chat فقط.
  • صفحات: /beta · /invite/[code] · /terms · /privacy · /usage (حدود يومية/شهرية
    • تنبيهات 80% و100%) · /admin/invites + تقرير Beta أسبوعي.
  • migrations 00110016. لا Stripe ولا بوابة دفع ولا خدمة بريد مدفوعة ولا Mock Data.

الاختبارات الحية: beta-check 70/70 · scrub-check 24/24 · claim-concurrency 13/13 · hourly-cap 10/10 — 117/117.

node scripts/beta-check.mjs             # البوابة، التزامن، الصيانة، banned، العزل
node scripts/scrub-check.mjs            # لا كود خام في signUp/JWT/auth.users/identities
node scripts/claim-concurrency-check.mjs  # 20 طلبًا متوازيًا → ≤ 3 تذاكر
node scripts/hourly-cap-check.mjs       # حد 20/ساعة (~8 دقائق)

تتطلب scripts/.qa-owner.json (حساب QA بصلاحية owner) وكود دعوة في scripts/.qa-invite.txt — كلاهما مُستثنى من git ولا يُنشأ إلا عند الاختبار ويُحذف بعده. أقسام التسجيل تتطلب تعطيل Confirm email مؤقتًا (وإلا لا تُنشأ جلسة لمستخدم عادي).

لوحة الإدارة والمراقبة (/admin):

  • حماية متعددة الطبقات (middleware + حارس خادمي + RLS + دوال security definer owner-only)
  • 7 صفحات ببيانات حقيقية: نظرة عامة، مستخدمون، نماذج، RAG، استهلاك، تدقيق، إعدادات
  • إدارة المستخدمين (دور/باقة/حظر/تعليق AI/إعادة تعيين استهلاك)، حدود الباقات، وظائف RAG
  • سجل تدقيق آمن (before/after، correlation، ip) بلا أسرار — وإصلاح ثغرة تصعيد صلاحيات

Deployment Ready:

  • فحص صحي آمن GET /api/health (تطبيق · Supabase · DB · pgvector · Storage · OpenRouter · Embeddings) بلا طلب AI مدفوع ولا كشف أسرار، مع correlation_id
  • فحص متغيرات البيئة عند الإقلاع دون طباعة قيم؛ سجلات JSON منظّمة؛ وضع ذاكرة منخفضة
  • مهلات صريحة، حارس نسخة نموذج واحدة، graceful shutdown، docs/DEPLOYMENT.md + PRODUCTION_CHECKLIST.md

Production-Hardened RAG (طابور دائم في قاعدة البيانات):

  • PostgreSQL مصدر الحقيقة للوظائف والأقفال والمحاولات (جدول rag_jobs) — الذاكرة للأداء فقط
  • التقاط ذري عبر FOR UPDATE SKIP LOCKED، فهرس فريد جزئي (وظيفة نشطة واحدة لكل ملف)
  • استئناف بعد التوقف (chunking يُتخطّى عبر hash، embedding للمقاطع الفارغة فقط)
  • Retry بـ backoff أُسّي وتصنيف أخطاء، إلغاء، تنظيف دوري (احتفاظ 7 أيام)
  • المعالجة request-driven حاليًا — العامل المستقل عبر المستخدمين غير مُفعّل (يحتاج service role بموافقة)
  • تزامن Embeddings داخل العملية = 1؛ أعلى استهلاك مقاس ≈ 1.9GB RSS عند 5 ملفات متزامنة
  • اختبار ضغط حي 20/20 + rag-check 22/22 + مراجعة أمنية لـ migration 0008

RAG محلي مجاني (مكتمل ومُختبر E2E من المتصفح — PDF متعدد الصفحات + DOCX):

  • إرفاق ملف بالمحادثة ← تقسيم ← embeddings محلية (multilingual-e5-small، 384 بُعد، بلا API خارجي) ← بحث دلالي
  • استرجاع آمن عبر RPC يتحقق من auth.uid()، عتبة مُعايَرة (أرضية 0.78 + ثقة 0.80)، تصريح «لم أجد هذه المعلومة في الملفات المرفقة» عند عدم التطابق
  • أرقام صفحات PDF في المصادر، معاملة محتوى الملفات كمصدر غير موثوق (حماية Prompt Injection)، ومصادر قابلة للنقر تحت الرد
  • التجهيز التلقائي عند الإرفاق، شارات الحالة، وبقاء المرفقات والمصادر بعد التحديث

نظام الملفات الكامل (36/36 اختبار Runtime):

  • رفع PDF/DOCX/TXT/MD/PNG/JPG/WEBP بسحب وإفلات وتقدم حقيقي وإلغاء
  • تحقق مزدوج (امتداد + MIME) وتعقيم أسماء ومنع path traversal وحدود لكل باقة
  • تخزين خاص (Bucket غير عام) بمسارات userId/… وSigned URLs وسياسات Storage
  • استخراج نص حقيقي: PDF (unpdf) · DOCX (mammoth) · TXT/MD (مع ترميز عربي احتياطي)
  • الحد الفعلي للملف = min(حد الباقة، سقف مزود التخزين 50MB)
  • تكامل المشاريع والمحادثات (إرفاق دون دخول سياق الذكاء — بانتظار RAG)

v0.1.1:

  • موفر OpenRouter مجاني افتراضي (Allowlist نماذج مُتحقق منها بالعربية — لا موجّه عشوائي)
  • Language Guard: منع الردود مختلطة اللغات مع إعادة محاولة بنموذج احتياطي
  • تسجيل النموذج الفعلي لكل رد (messages/usage_events) وعرضه في وضع التطوير
  • حد يومي للرسائل حسب الباقة (free: 50/يوم) — migrations 0003 و0004
  • نظام المشاريع الكامل: تعليمات خاصة تدخل موجه النظام، ربط المحادثات، بحث وفرز

مكتمل ومُختبر (38/38 اختبار Runtime + E2E تنسيق):

  • المصادقة الكاملة: تسجيل، دخول/خروج، استعادة كلمة المرور، جلسات مستمرة، حماية صفحات
  • واجهة المحادثة: بث SSE، إيقاف التوليد، إعادة توليد، تعديل رسالة المستخدم، Markdown + كتل كود مع نسخ، اختيار النموذج
  • المحادثات محفوظة في قاعدة البيانات: إنشاء، عنوان تلقائي، إعادة تسمية، حذف ناعم، بحث
  • الهيكل: شريط جانبي قابل للطي، متجاوب للجوال، داكن/فاتح، عربي RTL / إنجليزي LTR
  • الحساب والاستهلاك: عدادات شهرية حقيقية (رسائل + Tokens) مقابل حدود الباقة
  • الإعدادات: المظهر، اللغة، النموذج الافتراضي
  • الأمان: RLS مُختبر بين مستخدمين، منع IDOR على مستوى الخادم، Rate limiting، أخطاء الموفر برسائل عربية دون تسريب أسرار

التالي (انظر docs/YSD_AI_ROADMAP.md):

  • المشاريع (قيد التنفيذ) · رفع الملفات · لوحة الإدارة · صفحة الباقات

Contributors

OpenYsd

195 commits

OpenYsd/ysd-ai

1

stars

195

commits

TypeScript

primary language

Sep 11, 2026

updated

README

YSD AI — منصة الذكاء العربي

منصة ذكاء اصطناعي احترافية من YSD AI Studio. عربية أولًا (RTL) مع دعم الإنجليزية، مبنية على بنية Modular قابلة للتوسع.

التقنيات

الطبقةالتقنية
الواجهةNext.js App Router · TypeScript Strict · Tailwind CSS
قاعدة البيانات والمصادقةSupabase (PostgreSQL · Auth · Storage · RLS)
الذكاء الاصطناعيطبقة AIProviderAdapter موحدة — Anthropic أولًا، جاهزة لأي موفر
التحققZod · React Hook Form
الاختباراتVitest · Playwright

التشغيل المحلي

# 1. تثبيت الاعتماديات
npm install

# 2. إعداد البيئة
cp .env.example .env
# املأ مفاتيح Supabase وANTHROPIC_API_KEY

# 3. إعداد Supabase
#    - أنشئ مشروعًا على supabase.com
#    - ثبّت Supabase CLI ثم:
supabase link --project-ref YOUR_PROJECT_REF
supabase db push          # يشغّل migrations من supabase/migrations/

# 4. التشغيل
npm run dev

الفحص قبل أي Commit

npm run typecheck && npm run lint && npm run build && npm test

⚠️ لا تشغّل npm run build أثناء عمل npm run dev — كلاهما يكتب في .next نفسه، وسيؤدي ذلك إلى صفحات بلا CSS (روابط أصول قديمة ترجع 404). إن حدث ذلك: أوقف الخادم، احذف .next، ثم شغّل npm run dev من جديد. اختبار tests/styling-e2e.test.ts (مع YSD_E2E=1) يكتشف هذه الحالة آليًا.

بنية المشروع

app/
  api/chat/route.ts        مسار المحادثة الآمن (Streaming · Rate limit · Usage)
  (auth)/login/            صفحات المصادقة
  (app)/chat/              واجهة المحادثة (قيد البناء — انظر النموذج الأولي)
lib/
  ai/                      AIProviderAdapter + الموفرون + السجل
  supabase/                عملاء الخادم والمتصفح
  validation/              مخططات Zod
supabase/migrations/       مخطط قاعدة البيانات + RLS
docs/                      خارطة الطريق والتوثيق
middleware.ts              حماية الجلسات والصفحات ولوحة الإدارة

إضافة موفر ذكاء اصطناعي جديد

انظر docs/ADDING_A_PROVIDER.md — باختصار: نفّذ واجهة AIProviderAdapter وسجّله في lib/ai/registry.ts. لا حاجة لتعديل أي شيء آخر.

الميزات — v0.6.6

استقرار وتجربة (إصدار تثبيت): لا ردود مقطوعة ولا مُعلّم قائمة منفرد، ولا تكرار للرسالة عند النقر المزدوج أو إعادة الاتصال (client_request_id محمي في قاعدة البيانات — يعمل عبر أكثر من نسخة خادم)، ولا خروج مفاجئ عند انتهاء access token مع بقاء المسودة، وتصنيف صريح لأخطاء auth_expired/network_error/timeout/rate_limit/provider_unavailable. الأسماء الملتبسة تُسأل بدل التخمين (JoJo ≠ Jujutsu Kaisen)، والمهلة تشمل جسم البثّ لا الترويسات فقط.

مراقبة آمنة: /admin/health بمقاييس دائمة تنجو من إعادة التشغيل. الجدول لا يخزّن نص المستخدم ولا نص المساعد ولا البريد ولا IP ولا user_id — أرقام ورموز مغلقة فقط، والقراءة للإدارة وحدها. مفتاح الخدمة خادمي بحت محروس بـserver-only ولا يصل المتصفح.

يتطلب تطبيق migrations 0017 و0018 — انظر docs/V0.6.6_DATABASE_GATE.md.

الميزات — v0.6.5

جودة الإجابة: فهم سياق الألعاب والقصص بدل الرفض بالكلمات المفتاحية (ضرر/نزف لم تعد تُسقط سؤالًا آمنًا)، ورفض الأذى الحقيقي باختصار. أسماء الألعاب بالنقحرة العربية تُفهَم («الدن رينق» = Elden Ring). الأسئلة التي تطلب مواقع أو خطوات أو أرقامًا دقيقة تدخل وضعًا محميًا: لا تُعرض تفاصيل متخصصة غير مُسنَدة إلى مصدر، وبلا مصدر يصل اعتراف فوري بعدم التأكد (~1.4 ثانية، بلا استدعاء مزوّد). الأسئلة العامة والإبداعية تبقى على البثّ الفوري كما هي.

متانة: حارس لغة أدقّ يمنع التسريبات (يابانية/سيريلية/يونانية وكلمات دخيلة) مع السماح بأسماء العلم والاختصارات، وإصلاح انقطاع البثّ المتأخر بمتابعة صامتة بلا تكرار، ومنع الردود الفارغة (تفكير داخلي بلا إجابة).

حدّ معروف: سؤال متخصص بلا ملف مرفق يحصل على اعتراف بعدم التأكد لا على إجابة تفصيلية. للحصول على تفاصيل موثقة: أرفق ملفًا واسأل عنه (RAG). هذا الإصدار لا يضمن صحة كل المعلومات العامة.

الميزات — v0.6.4

أداء (مقيس): تحقّق هوية محلي بـgetClaims (ES256/JWKS) بلا رحلة شبكة، إسقاط تكرار auth/profile عبر سياق الوسيط المُتحقَّق (x-ysd-*، محمي ضد الانتحال)، كاش platform_settings 30ث مع إبطال، وموازاة استعلامات /api/chat (Promise.allSettled بعد ضمان حفظ رسالة المستخدم). زمن التطبيق قبل المزوّد ~3410ms → 1030ms، إنشاء المحادثة 2422ms → 1030ms. ما تبقّى من زمن أول token خارجي (المزوّد المجاني). سجلات أداء آمنة بـrequest_id بلا محتوى أو أسرار.

الميزات — v0.6.3

حالات المرفقات صريحة وصادقة:

  • أربع حالات في المحادثة: استخراج النص · تجهيز الذكاء الاصطناعي (مع النسبة) · جاهز للسؤال · فشل مع زر إعادة محاولة.
  • الصور: «صورة — بلا سياق AI». الصور تُحفظ وتُعرض فقط ولا تدخل RAG (بلا OCR) — والواجهة تقول ذلك صراحةً بدل أن تَعِد بتجهيز لا يأتي.
  • إعادة المحاولة آمنة: idempotency عبر rag_content_hash + فهرس فريد جزئي للوظائف + حذف chunks الملف قبل أي إدراج ⇒ لا chunks مكررة.

الميزات — v0.6.2

صلابة النماذج المجانية:

  • تهدئة النماذج: النموذج الفاشل يُتخطّى قبل إرسال أي طلب إليه — لا يُدفع ثمن الفشل في كل طلب. 429Retry-After وإلا 15 دقيقة · 404 no_free_model → 6 ساعات (غياب بنيوي) · 5xx/timeout → دقيقتان. انتهاء المدة يسمح بمحاولة واحدة جديدة تلقائيًا.
  • ثلاثة مزوّدين في سلسلة ysd/free: Google AI Studio · Nvidia · Darkbloom — حجب مزوّد واحد لا يُسقط الخدمة (الدرس: التنوّع في المزوّد لا في اسم النموذج).
  • كل نموذج مُختبَر عربيًا فعليًا قبل الإنتاج (بث حقيقي + نقاء أحرف + رفض الاختلاق). openrouter/free مستبعد دائمًا.
  • عند تهدئة الجميع: رسالة عربية بمدة صادقة، بلا انتظار وبلا محاولات مكررة.

الميزات — v0.6.0

Private Beta — بالدعوات فقط:

  • التسجيل مغلق إلا بدعوة. البوابة في مُحفّز handle_new_user على auth.usersغير قابلة للتجاوز من أي عميل. إعداد Supabase Allow new users to sign up يبقى مفعّلًا عمدًا؛ الإغلاق من platform_settings والتطبيق فقط.
  • دعوات hash-only: كود ≈80 بت، تُخزَّن sha256 وcode_hint فقط. الكود الخام يُعاد مرة واحدة ولا يدخل القاعدة ولا السجلات ولا التدقيق.
  • رموز تسجيل مؤقتة أحادية الاستخدام: كود الدعوة لا يصل GoTrue إطلاقًا؛ يُستبدل عبر /api/invite/claim بتذكرة 32 بايت تعيش 10 دقائق (hash فقط). تُستهلك ذريًا عند التسجيل ثم تُستهلك الدعوة ذريًا — فتسريبها بلا قيمة. لماذا: أي مفتاح في signUp.data ينتهي في استجابة GoTrue وفي الـJWT.
  • مكافحة الإغراق في القاعدة: قفل صف الدعوة (FOR UPDATE) قبل العدّ والإدراج، ثم 3 تذاكر نشطة و20 تذكرة/ساعة لكل دعوة. الرفض عام لا يكشف السبب. الـRate Limit في المسار طبقة إضافية فقط (الدالة مُصرَّحة لـanon عبر PostgREST).
  • تأكيد البريد مفعّل + موافقة إلزامية على الشروط والخصوصية: رقم النسخة يُختم من platform_settings داخل المُحفّز — لا يُوثق بنسخة العميل.
  • حالات الدعوات بساعة القاعدة: revoked → exhausted → expired → active تُحسب في PostgreSQL بـnow()، والانتهاء يُحسب بـnow() + make_interval(days => …). لا Date.now() في مسار الدعوات — الإنشاء والإنفاذ والعرض على ساعة واحدة.
  • وضع صيانة حقيقي: يحجب المستخدم العادي من الصفحات والـAPIs الخاصة (503) ويسمح للطاقم. الحظر شامل: banned → كل الصفحات الخاصة (/suspended) وكل الـAPIs (403)؛ ai_suspended يمنع /api/chat فقط.
  • صفحات: /beta · /invite/[code] · /terms · /privacy · /usage (حدود يومية/شهرية
    • تنبيهات 80% و100%) · /admin/invites + تقرير Beta أسبوعي.
  • migrations 00110016. لا Stripe ولا بوابة دفع ولا خدمة بريد مدفوعة ولا Mock Data.

الاختبارات الحية: beta-check 70/70 · scrub-check 24/24 · claim-concurrency 13/13 · hourly-cap 10/10 — 117/117.

node scripts/beta-check.mjs             # البوابة، التزامن، الصيانة، banned، العزل
node scripts/scrub-check.mjs            # لا كود خام في signUp/JWT/auth.users/identities
node scripts/claim-concurrency-check.mjs  # 20 طلبًا متوازيًا → ≤ 3 تذاكر
node scripts/hourly-cap-check.mjs       # حد 20/ساعة (~8 دقائق)

تتطلب scripts/.qa-owner.json (حساب QA بصلاحية owner) وكود دعوة في scripts/.qa-invite.txt — كلاهما مُستثنى من git ولا يُنشأ إلا عند الاختبار ويُحذف بعده. أقسام التسجيل تتطلب تعطيل Confirm email مؤقتًا (وإلا لا تُنشأ جلسة لمستخدم عادي).

لوحة الإدارة والمراقبة (/admin):

  • حماية متعددة الطبقات (middleware + حارس خادمي + RLS + دوال security definer owner-only)
  • 7 صفحات ببيانات حقيقية: نظرة عامة، مستخدمون، نماذج، RAG، استهلاك، تدقيق، إعدادات
  • إدارة المستخدمين (دور/باقة/حظر/تعليق AI/إعادة تعيين استهلاك)، حدود الباقات، وظائف RAG
  • سجل تدقيق آمن (before/after، correlation، ip) بلا أسرار — وإصلاح ثغرة تصعيد صلاحيات

Deployment Ready:

  • فحص صحي آمن GET /api/health (تطبيق · Supabase · DB · pgvector · Storage · OpenRouter · Embeddings) بلا طلب AI مدفوع ولا كشف أسرار، مع correlation_id
  • فحص متغيرات البيئة عند الإقلاع دون طباعة قيم؛ سجلات JSON منظّمة؛ وضع ذاكرة منخفضة
  • مهلات صريحة، حارس نسخة نموذج واحدة، graceful shutdown، docs/DEPLOYMENT.md + PRODUCTION_CHECKLIST.md

Production-Hardened RAG (طابور دائم في قاعدة البيانات):

  • PostgreSQL مصدر الحقيقة للوظائف والأقفال والمحاولات (جدول rag_jobs) — الذاكرة للأداء فقط
  • التقاط ذري عبر FOR UPDATE SKIP LOCKED، فهرس فريد جزئي (وظيفة نشطة واحدة لكل ملف)
  • استئناف بعد التوقف (chunking يُتخطّى عبر hash، embedding للمقاطع الفارغة فقط)
  • Retry بـ backoff أُسّي وتصنيف أخطاء، إلغاء، تنظيف دوري (احتفاظ 7 أيام)
  • المعالجة request-driven حاليًا — العامل المستقل عبر المستخدمين غير مُفعّل (يحتاج service role بموافقة)
  • تزامن Embeddings داخل العملية = 1؛ أعلى استهلاك مقاس ≈ 1.9GB RSS عند 5 ملفات متزامنة
  • اختبار ضغط حي 20/20 + rag-check 22/22 + مراجعة أمنية لـ migration 0008

RAG محلي مجاني (مكتمل ومُختبر E2E من المتصفح — PDF متعدد الصفحات + DOCX):

  • إرفاق ملف بالمحادثة ← تقسيم ← embeddings محلية (multilingual-e5-small، 384 بُعد، بلا API خارجي) ← بحث دلالي
  • استرجاع آمن عبر RPC يتحقق من auth.uid()، عتبة مُعايَرة (أرضية 0.78 + ثقة 0.80)، تصريح «لم أجد هذه المعلومة في الملفات المرفقة» عند عدم التطابق
  • أرقام صفحات PDF في المصادر، معاملة محتوى الملفات كمصدر غير موثوق (حماية Prompt Injection)، ومصادر قابلة للنقر تحت الرد
  • التجهيز التلقائي عند الإرفاق، شارات الحالة، وبقاء المرفقات والمصادر بعد التحديث

نظام الملفات الكامل (36/36 اختبار Runtime):

  • رفع PDF/DOCX/TXT/MD/PNG/JPG/WEBP بسحب وإفلات وتقدم حقيقي وإلغاء
  • تحقق مزدوج (امتداد + MIME) وتعقيم أسماء ومنع path traversal وحدود لكل باقة
  • تخزين خاص (Bucket غير عام) بمسارات userId/… وSigned URLs وسياسات Storage
  • استخراج نص حقيقي: PDF (unpdf) · DOCX (mammoth) · TXT/MD (مع ترميز عربي احتياطي)
  • الحد الفعلي للملف = min(حد الباقة، سقف مزود التخزين 50MB)
  • تكامل المشاريع والمحادثات (إرفاق دون دخول سياق الذكاء — بانتظار RAG)

v0.1.1:

  • موفر OpenRouter مجاني افتراضي (Allowlist نماذج مُتحقق منها بالعربية — لا موجّه عشوائي)
  • Language Guard: منع الردود مختلطة اللغات مع إعادة محاولة بنموذج احتياطي
  • تسجيل النموذج الفعلي لكل رد (messages/usage_events) وعرضه في وضع التطوير
  • حد يومي للرسائل حسب الباقة (free: 50/يوم) — migrations 0003 و0004
  • نظام المشاريع الكامل: تعليمات خاصة تدخل موجه النظام، ربط المحادثات، بحث وفرز

مكتمل ومُختبر (38/38 اختبار Runtime + E2E تنسيق):

  • المصادقة الكاملة: تسجيل، دخول/خروج، استعادة كلمة المرور، جلسات مستمرة، حماية صفحات
  • واجهة المحادثة: بث SSE، إيقاف التوليد، إعادة توليد، تعديل رسالة المستخدم، Markdown + كتل كود مع نسخ، اختيار النموذج
  • المحادثات محفوظة في قاعدة البيانات: إنشاء، عنوان تلقائي، إعادة تسمية، حذف ناعم، بحث
  • الهيكل: شريط جانبي قابل للطي، متجاوب للجوال، داكن/فاتح، عربي RTL / إنجليزي LTR
  • الحساب والاستهلاك: عدادات شهرية حقيقية (رسائل + Tokens) مقابل حدود الباقة
  • الإعدادات: المظهر، اللغة، النموذج الافتراضي
  • الأمان: RLS مُختبر بين مستخدمين، منع IDOR على مستوى الخادم، Rate limiting، أخطاء الموفر برسائل عربية دون تسريب أسرار

التالي (انظر docs/YSD_AI_ROADMAP.md):

  • المشاريع (قيد التنفيذ) · رفع الملفات · لوحة الإدارة · صفحة الباقات

Contributors

OpenYsd

195 commits

Languages

TypeScript

81.9%

JavaScript

11.6%

PLpgSQL

6.3%