- ابدأ الآن
- البيئة المحلية
- البنية المعمارية
- الهيكل
- الأنماط
- الحزمة التقنية
- قاعدة البيانات
- تعدّد المستأجرين
- الفهرس (Catalog)
- العمل دون اتصال
- المصادقة
- التهيئة (Onboarding)
- تدفق التكامل (Integration Flow)
- التهيئة (Provision)
- القبول
- الحضور
- الامتثال التنظيمي
- الملف الشخصي
- الاجتماعات
- إدارة الرسوم
- الفاتورة
- التدويل
- الترجمة
- دليل الترجمة
- أمان قاعدة البيانات
- المساهمة
- الإلهام
- المالية
- النقل
تتبّع وحدة الحضور حضور الطلاب عبر طرق التقاط متعدّدة، مع وصول مبني على الأدوار، إشعارات للأهل، مستويات خطر وفق US DoE، تتبّع للتدخّلات، وتصدير CSV / Excel / PDF. المعلمون يرون فصولهم المسندة فقط؛ الطلاب وأولياء الأمور يرون سجلاتهم فقط.
متتبّع الإصدار: databayt/hogwarts#1 — متتبّع رئيسي موحّد للحضور والامتثال. راجع كذلك Aldar Epic 01.
الحالة
| الميزة | الحالة | ملاحظات |
|---|---|---|
| التحضير السريع (واجهة المعلم) + ساعة الدوام للمعلمين والموظفين | Production | تحضير موجه للغياب بلمسة واحدة؛ تسجيل الحضور/الانصراف يغذي كشوف الدوام |
| يدوي / حصة / QR / باركود / رفع جماعي | Production | طرق التقاط متعدّدة (راجع جدول طرق الالتقاط) |
| إشعارات الأهل + تقديم الأعذار | Production | داخل التطبيق + SMS + بريد؛ يراجعها الكادر |
| الإنذار المبكّر | Production | مستويات خطر US DoE، تتبّع التدخّلات |
| تصدير التقارير | Production | CSV، Excel (5 أوراق)، PDF (بهوية المدرسة) |
| الحذف الناعم + الاستعادة | Production | deletedAt |
| العذر التلقائي | Production | AbsenceIntention معتمَد → EXCUSED |
| أسماء حسّاسة للّغة | Production | getText() يترجم عند الطلب |
| Geofence / Master gate / محرّك السياسات / تقارير الامتثال | موصول | يعمل، الواجهة لا تزال تنضج |
| الإعدادات | Production | تُحفظ في سجل AttendancePolicy على مستوى المدرسة |
| توقّعات AI / Gamification / Hall pass / Kiosk / خطابات الامتثال | Production | لها صفحات؛ تظهر عبر شبكة الوصول السريع في النظرة العامة |
| نوايا الغياب / واجهة Geofence | موصول | روابط مباشرة فقط حتى تُعرَّب واجهاتها الداخلية |
| إرسال يومي لـ ADEK eSIS | Production | موصّل عام في /compliance، الوضع الافتراضي DRY_RUN |
| كرون تواصل ولي الأمر خلال ساعتين | Production | /api/cron/absence-followup، كل 30 دقيقة، UTC |
على الهاتف
تحت نقطة التحوّل md تتبع النظرة العامة وكل الصفحات الفرعية نمط الهاتف في لوحة المدرسة — المفردات نفسها في لوحة التحكم والمكتبة والبث المباشر على الهاتف: الأرقام في لوحة رمادية واحدة بعمودين، وبطاقات رمادية بلا حدود بأزرار بيضاوية، وأبواب الأقسام أيقونات تطبيقات، وصفوف تنزل تفاصيلها تحت العنوان بدل أن تضغطه. الأجهزة اللوحية وسطح المكتب دون تغيير، ويبقى التحضير اليدوي والكشك والجداول كما هي في كل المقاسات.
المسارات
صفحة الحضور الرئيسية حسب الدور: المعلم يصل إلى التحضير السريع (موجه للجوال والغياب — الجميع حاضر افتراضيًا، واللمسات تتنقل غائب ← متأخر ← حاضر، وحفظ واحد يرسل الكشف كاملًا ويُشعر أولياء أمور الغائبين)، والمشرف/الموظف إلى النظرة العامة، والطالب/ولي الأمر إلى سجله الذاتي. كلها تحت src/app/[lang]/s/[subdomain]/(school-dashboard)/attendance/. التبويبات: /, /manual, /qr-code, /records, /excuses, /early-warning, /interventions, /analytics, /reports, /settings. شبكة الوصول السريع في النظرة العامة تربط /recent, /bulk-upload, /barcode, /hall-pass, /interventions/tiers, /gamification, /ai (+ /kiosk, /letters للمشرفين). روابط مباشرة فقط: /geo, /intentions, /bulk. /analysis يعيد التوجيه نهائيًا إلى /analytics؛ /parent/attendance يعيد التوجيه إلى /attendance/records. راجع جدول طرق الالتقاط أدناه لغرض كل route؛ راجع RBAC للوصول حسب الدور.
RBAC
| الإجراء | DEVELOPER | ADMIN | TEACHER (فصوله) | STAFF | STUDENT | GUARDIAN (أبناؤه) |
|---|---|---|---|---|---|---|
| تسجيل الحضور | Y | Y | Y | Y | — | — |
| قراءة سجلاته | Y | Y | — | — | Y | Y |
| قراءة سجلات الفصل | Y | Y | Y | — | — | — |
| قراءة على مستوى المدرسة | Y | Y | — | Y | — | — |
| حذف | Y | Y | Y | Y | — | — |
| استعادة | Y | Y | — | — | — | — |
| رفع جماعي | Y | Y | Y | — | — | — |
| تصدير | Y | Y | Y | Y | — | — |
| تحليلات | Y | Y | Y | Y | — | — |
| امتثال / إعدادات | Y | Y | — | — | — | — |
| مراجعة الأعذار | Y | Y | Y | Y | — | — |
| تقديم الأعذار | Y | Y | — | — | — | Y |
فصول المعلم هي: فصل الريادة، وكل فصل له معه حصة في الجدول، وكل فصل أُسنِدت إليه فيه مادة — getTeacherSectionIds() (actions/helpers.ts). ويطبّقها sectionScopeWhere() على القراءة: فلتر الفصل يُقاطَع معها ولا يوسّع النطاق أبدًا. وفلتر الصف يمرّ عبر الفصل (section.gradeId).
الحضور اليدوي
شريط أدوات مسطّح inline (PlatformToolbar): محدّد الفصل، منتقي التاريخ، أزرار حالة جماعية، Save. getCurrentPeriod() يختار تلقائياً الفصل المطابق لحصة الجدول الحالية؛ الأسماء تُترجَم عند الطلب عبر getText(). لوحة المفاتيح: P / A / L لحاضر / غائب / متأخر، Cmd/Ctrl+S للحفظ. أولياء الأمور للطلاب الغائبين يُخطَرون تلقائياً عند الحفظ؛ AbsenceIntention معتمَد يحوّل ABSENT → EXCUSED.
طرق الالتقاط
| الطريقة | المسار | ملاحظات |
|---|---|---|
| Manual | /manual | قائمة منسدلة لكل طالب + أزرار جماعية |
| Period | /manual (بحسب الحصة) | getCurrentPeriod()، تحليلات الحصة |
| QR | /qr-code | يُولَّد لفصل — لا يمسحه إلا طلابه؛ صلاحية افتراضية 30 دقيقة، إزالة التكرار |
| Barcode | /barcode | يبحث في StudentIdentifier؛ يُسجَّل الحضور على فصل الطالب نفسه، فلا حاجة لاختيار فصل أولًا |
| Kiosk | /kiosk | يُسجَّل الحضور على فصل الطالب نفسه |
| Bulk upload | /bulk-upload | CSV: studentId, date, status, checkInTime, checkOutTime, notes |
| Geofence | /geo | متتبّع موقع (للطلاب)، مناطق (للمشرفين) |
| Master gate | server actions | recordMasterAttendance(), getPrefillFromMaster() |
تصاريح الخروج (/hall-pass) تُصدَر على فصل الطالب نفسه، فلا يُطلب عند إصدارها إلا الطالب والوجهة.
إشراك الأهل
triggerAbsenceNotification() يُطلَق عند الغياب: داخل التطبيق (أولوية عالية)، SMS عبر Twilio (إن كان مهيّأً)، بريد. يستخدم preferredLanguage للمدرسة.
أسباب العذر: طبّي، طارئ عائلي، ديني، نشاط مدرسي، نقل، طقس، أخرى. معتمَد → EXCUSED؛ مرفوض → غير معذور. العذر المقدَّم — وكذلك نيّة الغياب إذا فُعِّل "إشعار المعلمين" — يصل إلى رائد الفصل والمعلمين المسنَدة إليهم مواده هذا الفصل الدراسي (sectionTeacherUserIds). وقائمة المراجعة لدى المعلم هي أعذار فصوله فقط.
عرض الطالب / ولي الأمر: نسبة + اتجاه، تقويم تاريخي، تفصيل الحالات، تقديم عذر للغيابات غير المعذورة.
الإنذار المبكّر
مستويات خطر US DoE:
| الخطر | معدّل الحضور | معدّل الغياب |
|---|---|---|
| مُرضٍ | ≥95% | <5% |
| في خطر | 90 – 94.9% | 5 – 9.9% |
| مزمن متوسّط | 80 – 89.9% | 10 – 19.9% |
| مزمن حادّ | <80% | ≥20% |
تتبّع التدخّلات في /attendance/interventions — 14 نوع تدخّل (تواصل مع ولي الأمر، زيارة منزلية، إحالة لمرشد / أخصائي اجتماعي / إداري، عقد حضور، إحالة تغيّب، مورد مجتمعي، دعم أكاديمي، إرشاد، تحفيز، أخرى) مع حالات Scheduled → In Progress → Completed / Cancelled / Escalated. محرّك السياسات في actions/policy.ts يقيّم المُحفّزات ويدير الاستثناءات.
التحليلات والتقارير
تحليلات بـ7 تبويبات في /analytics: Summary، Calendar، Trends، Patterns، Methods، Classes (الفصول مرتّبة حسب النسبة)، At Risk. الفلاتر: نطاق التاريخ والفصل.
التقارير في /reports: فلترة بالفصل، الطالب، الحالة، نطاق التاريخ، الحصة. تصدير: CSV، Excel (5 أوراق — summary، detailed، by status، by section، by date)، PDF (بهوية المدرسة). ويتبع التصدير فلتر الفصل.
الرفع الجماعي في /bulk-upload لفصل واحد: كل طالب في الملف يجب أن يكون منه.
الامتثال: getComplianceDashboard(), getComplianceReport(), getScheduledReports().
Server actions
الـactions مقسّمة عبر وحدات حسب المعنى تحت src/components/.../attendance/actions/.
| الوحدة | الملف | السطح |
|---|---|---|
| Core | core.ts | تسجيل، قائمة، تسجيل خروج، حذف + استعادة جماعية |
| Analytics | analytics.ts | إحصاءات، اتجاهات، استخدام الطرق، تقويم، مقارنة فصول، في خطر، نشاط حديث |
| Periods | periods.ts | تسجيل لكل حصة، اكتشاف الحصة الحالية، تحليلات الحصة |
| QR | qr.ts | توليد جلسة، مسح، جلسات نشطة |
| Identifiers | identifiers.ts | CRUD باركود الطالب / معرّف البطاقة + بحث |
| Excuses | excuses.ts | تقديم، مراجعة، قائمة المعلَّق / غير المعذور |
| Interventions | interventions.ts | إنشاء، تحديث، تصعيد، قائمة، إحصاءات، مكلَّفون |
| Bulk | bulk.ts | رفع CSV / Excel، مولِّد التقارير، تصدير CSV، عمليات الرفع الأخيرة |
| Dashboard | dashboard.ts | نظرة اليوم، حسب الخطر، إنذار مبكّر، فصول غير مسجَّلة، ملخّص ولي الأمر |
| Policy | policy.ts | تقييم السياسات، المحفّزات، الاستثناءات، الإلغاءات |
| Master | master.ts | دخول / خروج بوّابة المدرسة، prefill من master |
| Compliance | compliance.ts | لوحة الامتثال + التقارير المجدولة |
| Records | records.ts | الطالب لذاته + أبناء ولي الأمر |
توقيعات نموذجية:
markAttendance(input: {
sectionId: string
date: string
records: Array<{ studentId: string; status: 'present' | 'absent' | 'late' }>
})
markPeriodAttendance(input: {
sectionId: string // فصل المعلم نفسه؛ وكل طالب يجب أن يكون منه
date: string
periodId: string
timetableId?: string // يجب أن تكون حصة هذا الفصل
records: Array<{ studentId: string; status: 'PRESENT' | 'ABSENT' | 'LATE'; notes?: string }>
})
getAttendanceList({ sectionId, date, lang? }) // lang يُطلق الترجمة
deleteAttendance(id: string) // حذف ناعم
restoreAttendance(id: string)Schema
model Attendance {
id String @id @default(cuid())
schoolId String
studentId String
sectionId String? // الفصل الذي يُحفظ عليه الحضور
date DateTime @db.Date
status AttendanceStatus
method AttendanceMethod @default(MANUAL)
checkInTime DateTime?
checkOutTime DateTime?
notes String?
markedBy String?
markedAt DateTime @default(now())
deletedAt DateTime?
periodId String?
timetableId String?
periodName String?
@@unique([schoolId, studentId, sectionId, date, periodId])
@@index([schoolId, date, periodId])
}دلالات الحذف الناعم. الحقل deletedAt علامة حذف (tombstone) وليس حذفًا نهائيًا. يُستبعَد السجل المحذوف من كل قراءات التحليلات ولوحة المعلومات والتصدير والامتثال التنظيمي، ومن عروض الطالب وولي الأمر على الجوال — مع الاحتفاظ بالصف للتدقيق وإمكانية استعادته من قِبل المسؤول (restoreAttendance). وبما أن قيد @@unique لا يزال يحجز مفتاح الصف المحذوف، فإن إعادة تسجيل الطالب لنفس اليوم/الحصة تُحيي السجل الأصلي (تمسح deletedAt) بدلًا من إنشاء نسخة مكررة — وينطبق ذلك على التسجيل اليدوي والحصص ورمز QR والباركود والسياج الجغرافي والكشك.
نماذج داعمة: AttendanceExcuse, AttendanceIntervention, QRCodeSession, StudentIdentifier, AbsenceIntention, PolicyTrigger, PolicyExemption, MasterAttendance, HallPass, KioskLog, AttendanceReward, StudentBadge, AttendanceStreak.
Seed
pnpm db:seed:single attendanceالامتثال للجهات التنظيمية (ADEK eSIS — الإمارات)
يمكن لمدارس الإمارات (School.country === "AE") تفعيل رفع يومي لملف CSV
إلى بوابة ADEK eSIS على esis.adek.gov.ae بالإضافة إلى التواصل مع ولي
الأمر خلال ساعتين من الغياب غير المُبلَّغ (متطلب ADEK). الإطار العام —
إضافة جهة تنظيمية جديدة (هيئة التعليم السعودية، وزارة التعليم القطرية،
وزارة التعليم السودانية) تتطلب فقط إضافة قيمة إلى enum
ComplianceProvider ودليل تحت src/lib/compliance/providers/<authority>/.
| القطعة | المسار | الغرض |
|---|---|---|
| واجهة الإعدادات | /{lang}/compliance | تفعيل، الوضع، المهلة، وقت الإرسال اليومي، قائمة الإرسالات |
| إدارة عبر المستأجرين | /{lang}/(saas-dashboard)/compliance (DEVELOPER) | مجموعات بيانات الاعتماد المشتركة لنمط Aldar |
| كرون يومي | /api/cron/esis-submit (0 10 * * *) | إدخال طوابير + توزيع على المدارس |
| كرون متابعة | /api/cron/absence-followup (*/30 * * * *) | سجل امتثال ساعتين |
| Webhook | /api/webhooks/adek | استلام ACCEPTED/REJECTED غير متزامن |
| Worker (خارج المستودع) | tools/adek-rpa-worker/ (Fly.io) | Playwright عند عدم توفر API |
أوضاع الموصّل — قابلة للضبط لكل مدرسة × مزوّد:
| الوضع | الوظيفة |
|---|---|
DRY_RUN | إنشاء CSV، حفظه للتدقيق، يرفعه المسجّل يدوياً إلى eSIS |
PIGGYBACK | الإرسال عبر بيانات اعتماد مجموعة مشتركة (نمط الدار، صف اعتماد واحد × N مدارس، قاطع دائرة عند التدفقات الفاشلة) |
OFFICIAL_API | واجهة برمجية موثّقة من المزوّد (بانتظار وصول مطوّرين من ADEK) |
RPA | يلتقط عامل Playwright خارجي الصفوف QUEUED ويرفع عبر بوابة eSIS |
DISABLED | تخطّي في الكرون |
مهلة التواصل مع ولي الأمر — ساعتين
عند تفعيل SchoolComplianceConfig.enabled = true، فإن
triggerAbsenceNotification يُرسل عبر قنوات in_app + email + whatsapp
(بدلاً من in_app فقط) لكي تستهلك كرونات البريد و WhatsApp الصف. كل
30 دقيقة، يبحث كرون absence-followup عن صفوف ABSENT التي:
markedAt < now() - parentContactSlaMinutes(افتراضي 120، محسوب بـ UTC)- لا يوجد لها
AttendanceExcuse - لا يوجد لها
AbsenceIntentionمعتمَد يغطّي اليوم - لا يوجد لها
AttendanceInterventionمن نوعPARENT_PHONE_CALL/PARENT_EMAILخلال آخر 24 ساعة
يُرسل إشعار absence_unreported_followup لكل ولي أمر، ثم يكتب صفّ
AttendanceIntervention (PARENT_EMAIL, parentNotified=true,
contactMethod=in_app+email+whatsapp). هذا الصفّ هو سجل التدقيق الموجّه
للجهة التنظيمية — يستعلم getParentContactSlaReport() عنه لتقديم
عدّ "تواصل ضمن المهلة" لتدقيقات ADEK.
النموذج البياني (جانب الامتثال)
خمسة كيانات جديدة في prisma/models/compliance.prisma — ليس أيٌّ منها
خاصّاً بـ ADEK:
ComplianceProviderenum (حالياًADEK_ESIS،CUSTOM)ConnectorModeenumComplianceSubmissionStatusenum +CircuitBreakerStateenumSchoolComplianceConfig— صفّ واحد لكل مدرسة × مزوّد (تفعيل اختياري)SharedComplianceCredentialGroup— بيانات اعتماد مشتركة لمجموعة (نمط الدار)SchoolComplianceCredential— بيانات اعتماد لكل مدرسة (وضع OFFICIAL_API)ComplianceSubmission— صفّ لكل محاولة، مفهرس بـ(schoolId, provider, submissionDate, attemptNumber). تتسلسل المحاولات عبرsupersededBy. يُحفظ CSV داخلcsvArtifactContentويُنزَّل عبر/api/compliance/artifact/[submissionId](S3 URL موقّع قيد التخطيط).
تمّ توسيع AuditLog.userId ليقبل null في نفس الإصدار لكي يُسجَّل كرون /
عامل / webhook كأحداث نظام — تمرير userId: null في المكالمات.
أُضيف نوع NotificationType.absence_unreported_followup لمسار المهلة.
التحضير دون اتصال
التحضير السريع (/attendance للمعلّمين) يعمل بلا اتصال. يُحفظ التحضير في صندوق الصادر على الجهاز (النوع attendance، عنصر واحد معلّق لكل شعبة ويوم) ويُعاد إرساله عبر POST /api/offline/sync ← actions/quick-core.ts، وهو الكود نفسه الذي يشغّله الإجراء المتّصل. التحضير الأحدث الموجود على الخادم يفوز ويُهمل المكرَّر. إشعارات أولياء الأمور بالغياب تُرسَل عند وصول الإعادة. راجع العمل دون اتصال.
انظر أيضاً
- تعدد المستأجرين — RBAC + نطاق المستأجر
- الإشعارات — إرسال الغياب
- الجدول — اكتشاف الحصة تلقائياً
- الامتثال — إطار الإرسال للجهات التنظيمية (ADEK + جهات مستقبلية)
التحضير بلا اتصال
التحضير السريع (/attendance للمعلّمين) يعمل من دون اتصال. تذهب العلامات إلى صندوق الصادر على الجهاز (النوع attendance، عنصر معلّق واحد لكل شعبة ويوم) وتُعاد عبر POST /api/offline/sync ← actions/quick-core.ts، الشيفرة نفسها التي يشغّلها الإجراء المتصل. التحضير الأحدث الموجود على الخادم يفوز وتُسقَط الإعادة كتكرار. تنطلق إشعارات الغياب لأولياء الأمور عند وصول الإعادة. انظر العمل دون اتصال.
جرّبه على هاتف: افتح الحضور ← التحضير السريع، فعّل وضع الطيران، علّم شعبة واحفظ — تؤكد اللوحة أن العلامات حُفظت على الجهاز ويعرض شريط المزامنة عنصرًا واحدًا معلّقًا. أعد الاتصال فيفرغ الشريط وتكون العلامات على الخادم خلال ثوانٍ. تعليم الشعبة نفسها مرة أخرى يُعاد كتكرار ويفوز التحضير الأحدث. تثبيت التطبيق أولًا (زر متابعة في ورقة الترحيب) ليس شرطًا للتحضير بلا اتصال، لكنه شرط على آيفون لإشعارات الدفع.