حيث تجد الشركةُ موظّفَها المناسب.
منصّة توظيف قطرية تعرض ملفّات مهنية مجهولة الهوية؛ تتصفّحها الشركات وتطّلع على المؤهّلات، ولا تُكشَف هويّة المرشّح وبيانات التواصل معه إلّا مقابل رسمٍ يُدفَع للمنصّة.
الحجب حالةُ بيانات، لا حالةُ عرض.
إن لم يوجد سجلّ كشفٍ صالح، فالحقل الحسّاس غائب تماماً من استجابة الـ API — لا null، ولا منجَّم أ***د، ولا مشوّش بـ CSS. اقرأ Brain/06-masking-and-reveal.md قبل لمس أي كود يمسّ الملفّات.
| المجلد | المحتوى |
|---|---|
Brain/ |
عقل المشروع. المعمارية، المنطق، المراحل، سجلّ القرارات (ADR). |
progress/ |
حالة الإنجاز، محدَّثة باستمرار. |
UI/ |
نماذج التصميم المرجعية (لا تُنشر). |
api/ |
Laravel 13 — REST API خالص. |
web/ |
React 19 + TypeScript + Vite — SPA. |
PHP 8.3 · Composer 2 · Node 22 · MySQL 8
cd api
composer install
cp .env.example .env
php artisan key:generate
mysql -u root -e "CREATE DATABASE kafaat CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
mysql -u root -e "CREATE DATABASE kafaat_testing CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
php artisan migrate --seed
php artisan serve --port=8010المنفذ 8010 لا 8000 — تفادياً للتصادم مع مشاريع أخرى على الجهاز نفسه.
cd web
npm install
cp .env.example .env
npm run dev # http://localhost:5173| الحساب | البريد | كلمة المرور |
|---|---|---|
| المشرف العام | admin@kafaat.qa |
password |
| شركة | gulf@kafaat.qa |
password |
| شركة أخرى | doha-bank@kafaat.qa |
password |
| موظّف | a.alkuwari@mail.qa |
password |
أحمد الكواريموظّفٌ حاليّ لدى «شركة الخليج للتقنية». سجّل دخولك بها، ولن تجده في التصفّح إطلاقاً — عمى صاحب العمل.
- سجّل دخولك كشركة (
gulf@kafaat.qa) وافتح/candidates. - لاحظ أن الأسماء غائبة، لا مشوّشة. افتح أدوات المطوّر ← Network ← ستجد أن الـ JSON نفسه لا يحوي
name. - اضغط «كشف الهوية · 75 ر.ق» ← تُنقَل إلى صفحة محاكاة الدفع.
- انسخ الأمر المعروض وشغّله في طرفية
api/:
php artisan kafaat:simulate-payment {provider_ref}هذا يرسل webhook موقّعاً بـ HMAC إلى المسار الحقيقي، فيمرّ بتحقّق التوقيع ومنع إعادة التشغيل والمعاملة كاملةً — لا يكتب في قاعدة البيانات مباشرةً، وإلّا كنّا نختبر طريقاً لا يسلكه الإنتاج.
- عُد إلى
/candidates← ظهر الاسم وبيانات التواصل، لهذا المرشّح وحده.
النشر رغبةُ الموظّف، والاعتماد قرارُ المنصّة. الملفّ لا يظهر لأي شركة قبل اجتماعهما.
- سجّل دخولك بـ
admin@kafaat.qaوافتح طلبات الكفاءات — ستجد طلبين معلّقين. - لاحظ أن الجدول لا يعرض اسماً ولا بريداً ولا هاتفاً. من يعتمد يراجع جودة الملفّ لا هويّة صاحبه — وإلّا منحنا كل مراجعٍ المنتجَ مجّاناً.
- اعتمد أحدهما ← يظهر فوراً في تصفّح الشركات، وهويّته ما زالت محجوبة حتى الدفع.
- من يحتاج رؤية الهوية فعلاً (للتحقّق من مستند) يفتح صفحة المرشّح بصلاحية
profile.moderate— ويُسجَّل عليه ذلك فيaudit_logs.
cd api
php vendor/bin/pest # 87 اختباراً
php vendor/bin/pint --test # تنسيق
php vendor/bin/phpstan analyse --memory-limit=1G # Larastan level 7
cd ../web
npm run build # tsc + viteملاحظة: حزمة
laravel/paoتعترض مخرجات الأدوات وتُحوّلها JSON عند التشغيل تحت وكيل. لرؤية المخرجات الخام:PAO_DISABLE=1 php vendor/bin/phpstan …
عمداً (ADR-015): lockForUpdate() لا أثر له في SQLite. لو انزلقت الاختبارات إليها، لمرّ اختبارُ منع الخصم المزدوج كذباً.
اقرأ Brain/README.md — المبادئ الحاكمة الخمسة غير قابلة للتفاوض:
- الحجب يقع في الـ API، لا في الواجهة.
- كل قاعدة عمل تعيش في الإعدادات، لا في الكود.
- لا أدوار مثبّتة في الكود — الفحص بالصلاحية دائماً.
- كل فعل حسّاس يُسجَّل في
audit_logs. - الخصوصية بالتصميم، لا بالإضافة.
ثمّ progress/STATUS.md لتعرف أين نحن.