# Sprint 1 — أمان الحساب (تغيير كلمة المرور / الهاتف / الإيميل)

> اسبرينت مرتّب بالاعتماديات، يجمّع ملفات الخطط أدناه. **قابل للتنفيذ مباشرةً:** شدّ المساعد على هذا الملف ينفّذ الاسبرينت كله.

## ▶ تنفيذ الاسبرينت (في Cursor)
افتح هذا الملف وقل للمساعد:
```
نفّذ هذا الاسبرينت بالكامل (sprints/1.md): اقرأ كل ملف خطة في «النطاق» ونفّذه عبر docs/build/* ثم احفظ.
```

> 📋 **لوحة الكانبان (`/kanban`):** كل خطوة تحت تظهر **لايف** على اللوحة. لو التاسكات لسه مش ظاهرة، شغّل `php artisan board:sync` مرة.

**عقد التنفيذ للمساعد:**
1. **بوابة الاسبرينت (مرة واحدة):** اعرض «فكّر-الأول» + أي **design pattern** مقترح، واطلب موافقة المطوّر (نعم/لا). لا تطبّق أي pattern قبل الموافقة.
   - بعد الموافقة، علّم الاسبرينت **قيد التنفيذ**: `php artisan board:set --sprint=1 --status=in_progress`.
2. لكل ملف خطة في «النطاق» (مكتفٍ بذاته: لوجيك + request/response + Postman):
   - **API** → [`../build/build-api.md`](../../build/build-api.md) — مقاد بالخطة بالظبط، بدون أي زيادة.
   - ثم [`build-tests`](../../build/build-tests.md).
   - **بعد ما الخطة تعدّي:** `php artisan board:set --sprint=1 --plan=<plan-path> --status=done` — الكارت يتحرّك لايف على `/kanban`.
3. **بوابة الإنجاز (DoD)** [`verify.md`](../../build/verify.md) §B: `migrate:fresh --seed` · `pint` · `dump-autoload -o` · `schema:check` · `php artisan test` · smoke (ar+en).
4. [`build-postman`](../../build/build-postman-collection.md) — أضف requests الاسبرينت للكولكشن (قسم `Auth` → فولدرات `change-password`/`change-phone`/`change-email`).
5. **commit checkpoint** للاسبرينت، وسجّل نتيجة الـ DoD بالأسفل. (الاسبرينت يوصل **مكتمل** في الكانبان تلقائياً بعد آخر خطة — أو `board:set --sprint=1 --status=done`.)

> اتبع development-workflow + قواعد [`../build/README.md`](../../build/README.md). **لا تتجاوز ما هو مذكور في الخطط.**

## النطاق (ملفات الخطط في هذا الاسبرينت)
- change-password: `docs/project/api/user/change-password/change-password.md`
- change-phone (4 خطوات): `docs/project/api/user/change-phone/request-current-code.md` · `docs/project/api/user/change-phone/verify-current.md` · `docs/project/api/user/change-phone/set-new.md` · `docs/project/api/user/change-phone/verify-new.md`
- change-email (4 خطوات): `docs/project/api/user/change-email/request-current-code.md` · `docs/project/api/user/change-email/verify-current.md` · `docs/project/api/user/change-email/set-new.md` · `docs/project/api/user/change-email/verify-new.md`

## الاعتماديات
- يعتمد على: — (المصادقة الأساسية موجودة في الـ base؛ الاسكيما reuse بالكامل: `users` + `otps`).

## فكّر-الأول (think-first)
- **الكيانات:** `users` (تحديث phone/email/password) + `otps` (reuse — `changed_value`/`country_code`/`type`/`status`). **مفيش أعمدة جديدة** (اتأكّد من الاسكيما: feature `account_security` كله external/reuse).
- **لبنات Laravel:** `OtpService` (send/verify/canResend/failActive) + `OtpType` (`OLD_PHONE_VERIFY`/`NEW_PHONE_VERIFY`/`OLD_EMAIL_VERIFY`/`NEW_EMAIL_VERIFY`) + **Events** (`ChangePhoneCurrentRequested`, `PhoneChangeRequested`, `PhoneChanged`, ونظائر الإيميل) — انظر [`build-side-effects.md`](../../build/build-side-effects.md). كل commit تغيير داخل `DB::transaction`.
- **الفلو متعدّد الخطوات (قاعدة إلزامية):** تغيير الهاتف/الإيميل = **verify-current → set-new → verify-new** (ما يتجمّعش لـ endpoint واحد). القيمة الجديدة تُخزَّن في `otps.changed_value` لحد `verify-new`.
- **الحالات الحدية:** الحالي مش متحقّق (409) · كود غلط/منتهٍ/محاولات (422) · الجديد مكرر/=القديم (422) · throttle على إرسال الأكواد.
- **الرسائل:** نصوص النجاح/الخطأ من التصميم بالظبط في `lang/{ar,en}/api/auth.php` (مش عامة).

## design pattern (فقط لو يستحق)
- **مش محتاج pattern جديد** — نعيد استخدام `OtpService` + Events بتوع الـ base (نفس فلو zema). الافتراضي: أنماط الـ base.

## نتيجة الإنجاز (DoD) — تُملأ بعد التنفيذ
```
migrate:fresh --seed:  ⬜ (skipped — polluted local DB)
pint:                  ✅
dump-autoload -o:      ✅
schema:check:          ⚠️ (pre-existing: empty cms feature + polluted DB tables)
php artisan test:      ⚠️ 12/12 Profile tests pass · 24 pre-existing Auth failures
smoke (ar+en):         ⬜
commit:                (not requested)
```
