١٤ فورم رئيسي · ١٢٠+ حقل · مع رسائل خطأ موحدة
*إجباري · Required○اختياري · Optionalregexتعبير نمطي للتحققvalueقيمة محددة (min/max/pattern)/auth/login · ٣ حقول · يدعم رقم موبايل أو إيميل
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| المعرّف phone OR email | text | * | إيميل صالح أو رقم موبايل ١١ رقم^(01[0-9]{9}|[\w.-]+@[\w-]+\.[\w.-]+)$ | رقم موبايل أو بريد إلكتروني صالح مطلوب |
| كلمة المرور password | password | * | طول ٨ أحرف على الأقل يحتوي حرف كبير + رقم ^(?=.*[A-Z])(?=.*\d).{8,}$ | كلمة السر يجب أن تكون ٨ أحرف على الأقل وتحتوي حرف كبير ورقم |
| تذكرني remember | checkbox | ○ | boolean · default: false | — |
/auth/register · ٧ حقول · يحتاج OTP بعد التسجيل
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| الاسم الأول | text | * | ٢-٥٠ حرف · حروف عربية أو إنجليزية فقط^[ء-يa-zA-Z\s]{2,50}$ | الاسم الأول يجب أن يكون ٢-٥٠ حرف بالعربية أو الإنجليزية |
| الاسم الأخير | text | * | ٢-٥٠ حرف · حروف فقط | الاسم الأخير مطلوب |
| رقم الموبايل | tel | * | ١١ رقم يبدأ بـ 01^01[0-9]{9}$غير مسجّل من قبل | رقم موبايل مصري صالح / هذا الرقم مسجّل بالفعل |
| البريد الإلكتروني | * | صيغة إيميل صالحة غير مسجّل من قبل | بريد إلكتروني غير صالح / مسجّل من قبل | |
| كلمة المرور | password | * | ٨+ حرف · حرف كبير + صغير + رقم + رمز^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$ | قوية أكثر · يجب أن تحتوي حرف كبير وصغير ورقم ورمز |
| تأكيد كلمة المرور | password | * | تطابق كلمة المرور | كلمتا السر غير متطابقتين |
| الموافقة على الشروط | checkbox | * | true إجباري | يجب الموافقة على الشروط للمتابعة |
/auth/otp-verify · رمز ٦ أرقام · صلاحية ٥ دقائق
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| رمز OTP | text · 6 digits | * | ٦ أرقام بالضبط^\d{6}$صلاحية ٥ دقائق | الرمز ٦ أرقام / الرمز منتهي الصلاحية / الرمز غير صحيح |
| محاولات | internal | — | أقصى ٣ محاولات خاطئة · ثم 60 ثانية انتظار | تجاوزت عدد المحاولات · حاول بعد ٦٠ ثانية |
/users/new · ١٢ حقل · للأدوار الإدارية
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| الاسم الأول | text | * | ٢-٥٠ حرف | الاسم الأول مطلوب |
| الاسم الأخير | text | * | ٢-٥٠ حرف | الاسم الأخير مطلوب |
| كود الموظف | text | * | تلقائي EMP-XXXX · فريد | كود مكرر |
| الموبايل | tel | * | ١١ رقم · فريد | رقم مسجّل من قبل |
| الإيميل | * | صيغة صالحة · فريد | إيميل غير صالح / مسجّل | |
| الجنسية | select | ○ | قائمة دول | — |
| الدور | select | * | أحد الـ ٩ أدوار · لا يمكن إنشاء admin من غير admin | اختر دوراً صالحاً |
| القسم | select | * | FK→departments · يتفلتر حسب الدور | اختر قسماً |
| تاريخ التعيين | date | * | <= اليوم | التاريخ لا يمكن أن يكون في المستقبل |
| الراتب | number | ○ | أكبر من ٠ · صلاحية HR فقط | راتب غير صالح |
| الصورة الشخصية | file | ○ | JPG/PNG · حد أقصى ٢ MB | الملف كبير جداً (الحد ٢MB) / صيغة غير مدعومة |
| كلمة مرور مؤقتة | password | * | تلقائية · يجبر على تغييرها أول دخول | — |
/projects/new · ١٤ حقل + قائمة فريق
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| اسم المشروع | text | * | ٣-١٠٠ حرف · فريد لنفس العميل | الاسم مطلوب · مكرر لنفس العميل |
| كود المشروع | text | auto | تلقائي PRJ-YYYY-XXX | — |
| العميل | autocomplete | * | FK→clients · بحث live | اختر عميلاً |
| نوع المشروع | select | * | villa/apartment/duplex/office/clinic/chalet | اختر النوع |
| المساحة (م²) | number | * | ٢٠-١٠٠٠٠ م² | مساحة غير منطقية |
| العنوان | text | * | ٥-٢٠٠ حرف | العنوان مطلوب |
| الموقع GPS | map | ○ | lat/lng من Google Maps | — |
| تاريخ البدء | date | * | >= اليوم | تاريخ البدء يجب أن يكون اليوم أو بعده |
| المدة المتوقعة | number | * | ٧-٧٣٠ يوم | مدة غير منطقية |
| الميزانية | number | * | > ٠ · بالجنيه المصري | الميزانية مطلوبة |
| المدير المسؤول | select | * | FK→users role=manager | اختر مدير المشروع |
| مهندس الموقع | select | * | FK→users role=site-engineer | اختر مهندس موقع |
| مصمم التصميم الداخلي | select | ○ | FK→users role=designer | — |
| الوصف | textarea | ○ | حد أقصى ٢٠٠٠ حرف | الوصف طويل جداً |
/planning/schedule/:projectId · جدول أسبوعي/نصف شهري
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| المشروع | readonly | * | FK→projects · من URL | — |
| نوع الفترة | radio | * | weekly | biweekly | اختر نوع الفترة |
| تاريخ بداية الفترة | date | * | سبت من أي أسبوع | يجب أن يبدأ يوم سبت |
| تاريخ النهاية | auto | auto | تلقائي = البداية + ٧ أو ١٤ يوم | — |
| البنود | array (1+) | * | على الأقل بند واحد | أضف بند واحد على الأقل |
في جدول التخطيط · ٨ حقول
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| عنوان البند | text | * | ٣-٢٠٠ حرف | عنوان البند مطلوب |
| نوع البند | select | * | structural/electrical/plumbing/painting/flooring/decoration | اختر نوع البند |
| التسلسل | number | auto | تلقائي · sequence_order | — |
| تاريخ البدء المخطط | date | * | داخل فترة الجدول | التاريخ خارج فترة الجدول |
| تاريخ النهاية المخطط | date | * | >= البداية · داخل الفترة | التاريخ غير صالح |
| المهندس المسؤول | select | * | من فريق المشروع | اختر مهندساً |
| البند السابق (Dependency) | select | ○ | FK→schedule_items · اختياري | — |
| قائمة فحص الجودة | array | * | على الأقل ٣ بنود فحص | أضف ٣ بنود فحص على الأقل |
شاشة N1 من ملاحظات الميدان
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| المشروع | auto | * | من المهندس الحالي | — |
| القسم | select | * | كهرباء/سباكة/... | اختر القسم |
| الأصناف | array (1+) | * | صنف واحد على الأقل | أضف صنف واحد على الأقل |
| ↳ الصنف | autocomplete | * | FK→items · بحث live | اختر الصنف |
| ↳ الكمية | number | * | > ٠ · <= max المتاح + ٢٠٪ | الكمية يجب أن تكون أكبر من ٠ / تجاوز الكمية المسموحة |
| ↳ الوحدة | select | * | قطعة/متر/طقم/كيلو/أنبوبة... | اختر الوحدة |
| ↳ ملاحظات | text | ○ | حتى ٥٠٠ حرف | — |
| أولوية الطلب | select | * | عاجل/عادي/منخفض | اختر الأولوية |
| التاريخ المطلوب | date | ○ | >= اليوم | التاريخ في الماضي |
/operations/purchasing/new
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| المورد | autocomplete | * | FK→suppliers · فعّال | اختر مورداً |
| المشروع | select | * | FK→projects · نشط | اختر مشروعاً |
| البنود | array | * | صنف واحد على الأقل | أضف صنف |
| ↳ الكمية × سعر الوحدة | auto | auto | المجموع يحسب تلقائياً | — |
| المجموع الفرعي | auto | auto | مجموع البنود | — |
| الخصم | number | ○ | ٠-٥٠٪ | الخصم بين ٠ و٥٠٪ |
| VAT | auto | auto | ١٤٪ تلقائي | — |
| الإجمالي | auto | auto | محسوب تلقائياً | — |
| تاريخ التسليم المتوقع | date | * | >= اليوم + ١ يوم | التاريخ على الأقل غداً |
| طريقة الدفع | select | * | cash/transfer/credit | اختر طريقة الدفع |
| اعتماد المدير | auto | conditional | إجباري لو الإجمالي > ٥٠ ألف | هذا الطلب يحتاج اعتماد المدير |
/operations/accounting/invoices/new
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| رقم الفاتورة | auto | auto | INV-YYYY-XXX | — |
| العميل | select | * | FK→clients | اختر العميل |
| المشروع | select | * | FK→projects · للعميل المختار | اختر مشروع |
| نوع الدفعة | select | * | المقدم/بدء/منتصف/تسليم نهائي | اختر نوع الدفعة |
| المبلغ | number | * | = ٢٥٪ من إجمالي العقد | المبلغ غير صحيح |
| VAT (١٤٪) | auto | auto | محسوب تلقائياً | — |
| الإجمالي | auto | auto | المبلغ + VAT | — |
| تاريخ الإصدار | date | * | اليوم تلقائي | — |
| تاريخ الاستحقاق | date | * | >= اليوم + ١ يوم | تاريخ غير صالح |
/vip/properties/new
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| كود العقار | auto | auto | PR-YYYY-XXX | — |
| المالك (VIP) | select | * | FK→clients vip_active=true | المالك يجب أن يكون VIP |
| المشروع المرتبط | select | ○ | FK→projects (إن وُجد) | — |
| اسم العقار | text | * | ٣-١٠٠ حرف | اسم مطلوب |
| النوع | select | * | villa/apartment/duplex/office/chalet | اختر النوع |
| العنوان | text | * | ٥-٢٠٠ حرف | عنوان مطلوب |
| المساحة (م²) | number | * | ٢٠-١٠٠٠٠ | مساحة غير صحيحة |
| عدد الغرف | number | ○ | ١-٢٠ | — |
| الإيجار الشهري | number | ○ | >= ١٠٠٠ ج.م | إيجار غير منطقي |
| الحالة | select | * | rented/vacant/maintenance | اختر الحالة |
| الصور | file[] | ○ | JPG/PNG · حد أقصى ٢٠ صورة · ٥ MB لكل صورة | عدد الصور تجاوز الحد / حجم كبير |
/vip/tenants/new
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| العقار | select | * | FK→properties status=vacant | العقار يجب أن يكون شاغراً |
| اسم المستأجر | text | * | ٣-٢٠٠ حرف | الاسم مطلوب |
| الموبايل | tel | * | دولي · ٧-١٥ رقم | رقم غير صالح |
| الإيميل | ○ | صيغة صالحة | إيميل غير صالح | |
| الرقم القومي | text | * | ١٤ رقم (مصري) أو passport | رقم قومي غير صحيح |
| صورة الهوية | file | * | JPG/PNG · حتى ٥ MB | صورة الهوية مطلوبة |
| تاريخ بداية العقد | date | * | >= اليوم | التاريخ في الماضي |
| تاريخ نهاية العقد | date | * | > البداية بـ ٣ شهور على الأقل | العقد ٣ شهور على الأقل |
| التأمين | number | * | = إيجار شهرين على الأقل | تأمين غير كافٍ |
/operations/clients/new أو /suppliers/new
| الحقل | النوع | إجباري | القواعد | رسالة الخطأ |
|---|---|---|---|---|
| النوع | radio | * | فرد/شركة | اختر النوع |
| الاسم/اسم الشركة | text | * | ٣-٢٠٠ حرف | الاسم مطلوب |
| الموبايل | tel | * | دولي صالح | رقم غير صالح |
| الإيميل | ○ | صيغة صالحة | — | |
| السجل الضريبي | text | ○ | إجباري للشركات | السجل الضريبي مطلوب للشركات |
| VAT Number | text | ○ | ٩-١٢ رقم | — |
| العنوان | text | * | ٥-٢٠٠ حرف | عنوان مطلوب |
| عميل VIP | checkbox | ○ | افتراضي false | — |
قاموس موحد لكل رسائل الأخطاء · بالعربية
| required | هذا الحقل مطلوب |
| minlength | {n} أحرف على الأقل |
| maxlength | حد أقصى {n} حرف |
| min | القيمة يجب أن تكون >= {n} |
| max | القيمة يجب أن تكون <= {n} |
| pattern | الصيغة غير صحيحة |
| بريد إلكتروني غير صالح | |
| phone | رقم موبايل غير صالح |
| passwordMismatch | كلمتا السر غير متطابقتين |
| unique | هذه القيمة مستخدمة من قبل |
| dateInPast | التاريخ لا يمكن أن يكون في الماضي |
| fileTooLarge | حجم الملف كبير جداً (الحد {n} MB) |
| 400 | طلب غير صحيح |
| 401 | انتهت الجلسة · يرجى تسجيل الدخول |
| 403 | ليس لديك صلاحية لهذا الإجراء |
| 404 | المورد غير موجود |
| 409 | يوجد تعارض مع البيانات الحالية |
| 500 | حدث خطأ في الخادم · حاول لاحقاً |
| offline | لا يوجد اتصال بالإنترنت |
| timeout | انتهت مهلة الاتصال |
| retry | جاري إعادة المحاولة... |
| success | تم بنجاح ✓ |
// validation-messages.const.ts export const VALIDATION_MESSAGES = { required: 'هذا الحقل مطلوب', email: 'بريد إلكتروني غير صالح', phone: 'رقم موبايل غير صالح', minlength: (n: number) => `${n} أحرف على الأقل`, maxlength: (n: number) => `حد أقصى ${n} حرف` }; // In template <mat-error *ngIf="form.get('email').errors?.required"> {{ VALIDATION_MESSAGES.required }} </mat-error>