دورة تطوير نظام إدارة الأعراس والمناسبات ودعوات QR عمليًا

واجهة تسجيل الحضور POST /api/checkin

واجهة تسجيل الحضور POST /api/checkin — نظام إدارة الأعراس والمناسبات ودعوات QR | Next.js وPrisma | أديب الصلوي
وقت الدراسة
14 دقيقة

المسار: تطوير نظام إدارة الأعراس ودعوات QR الوحدة: واجهات API والبنية الخلفية

مدخل إلى الدرس: واجهة تسجيل الحضور POST /api/checkin

واجهة تسجيل الحضور POST /api/checkin — نظام إدارة الأعراس والمناسبات ودعوات QR | Next.js وPrisma | أديب الصلوي

طريقة الدراسة: اقرأ التعريف، تتبّع المثال في الشرح، نفّذه بنفسك، ثم اختبر النتيجة والحالات الاستثنائية قبل الانتقال.

أهداف هذا الدرس

  • تنفيذ قراءة QR → استخراج token وإثبات صحته.
  • تسجيل حضور بمنع التكرار عبر إنشاء CheckIn.
  • تغذية الاستجابة المولّدة للواجهة (اسم، حالات).

مثال

// app/api/checkin/route.ts
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { tokenHashOf, verifySignature } from "@/lib/tsign";

export async function POST(req: Request) {
  const { token, sig, eventId } = await req.json();

  if (!token || !sig || !eventId) {
    return NextResponse.json({ ok: false, error: "معطيات ناقصة" }, { status: 400 });
  }

  // 1) التحقق من التوقيع قبل أي بحث
  if (!verifySignature(token, sig)) {
    return NextResponse.json({ ok: false, error: "توقيع غير صالح" }, { status: 403 });
  }

  // 2) العثور على الضيف بالهاش
  const guest = await prisma.guest.findUnique({
    where: { tokenHash: tokenHashOf(token) },
  });
  if (!guest) {
    return NextResponse.json({ ok: false, error: "ضيف غير موجود" }, { status: 404 });
  }
  if (guest.eventId !== eventId) {
    return NextResponse.json({ ok: false, error: "رمز لمناسبة أخرى" }, { status: 409 });
  }

  // 3) منع الحضور المزدوج
  const existing = await prisma.checkIn.findFirst({
    where: { guestId: guest.id, eventId },
  });
  if (existing) {
    return NextResponse.json(
      { ok: false, error: "سبق تسجيل هذا الضيف", firstSeen: existing.checkedInAt },
      { status: 409 }
    );
  }

  const checkIn = await prisma.checkIn.create({
    data: { guestId: guest.id, eventId },
  });

  return NextResponse.json({ ok: true, data: { guest: guest.name, checkIn } }, { status: 201 });
}

المخطط: مسار قراءة الـ QR في البوابة (فرزة)

flowchart TD
    A["جهاز الفرزة (كاميرا)
مسح → token, sig, eventId"] --> V{"تحقق التوقيع"} V -->|فشل| E403["403 توقيع غير صالح"] V -->|نجح| GH{"جلب بالـ hash"} GH -->|لا ضيف| E404["404"] GH -->|موجود| CH{"CheckIn مسبق؟"} CH -->|نعم| E409["409 أول حضور في: ..."] CH -->|لا| OK["create CheckIn"] --> OK2["201 { guest }"]

الفضائل الأمنية

الترتيب مهم: نرفض التوقيع قبل أي جلب (لا نكشف وجود ضيف)، ونرفض تكرار الحضور قبل الكتابة بنفس الطلب حتى لو ضغط الموظف مرتين متتاليتين.

تمرين تطبيقي: أضف شرطاً يمنع المسح قبل وقت الحفل أو بعده (بالمقارنة مع event.date) وأعد رسالة خطأ مناسبة — سترى الفرق يجعل التجربة واقعية.

أخطاء شائعة يجب تفاديها

  • تسجيل الحضور قبل التحقق من التوقيع — باب مفتوح للتزوير.
  • السماح للمسح المزدوج بالكتابة twice مع كسر UNIQUE.
  • كشف تفاصيل قدرة الضيف (كم عدد ضيوفه) في ردّ الخطأ.

معجم مصطلحات الدرس

CheckIn
سطر حضور: ضيف + مناسبة + لحظة دخول.
تحقق توقيع
إثبات أن محتوى الرمز لم يُعدَّل من طرف غير الخادم.
منع مزدوج
رفض كتابة حضور ثاني لنفس الضيف/المناسبة.

مراجعة وتمرين تثبيت المهارة

اختبار سريع: اشرح بعبارتك معنى «واجهة تسجيل الحضور POST /api/checkin»، ثم بيّن أين ستستخدمه داخل نظام تسجيل حضور دعوات مناسبة عبر رمز QR، وما الخطأ الذي يجب اختباره قبل الاعتماد على الحل.

تحدٍّ إضافي: غيّر شرطًا واحدًا في التطبيق، وتوقع النتيجة، ثم نفّذ الاختبار وفسّر الاختلاف.

الدرس التالي: التحقق من المدخلات ومعالجة الأخطاء. من الأفضل إنهاء التجربة الحالية قبل متابعة الدرس التالي.

دروس نصية

#1

نظرة عامة على الدورة والمخرجات

#2

مقدمة إلى Next.js وأسباب اختياره

#3

أساسيات schema.prisma والنماذج

#4

مقدمة Route Handlers وبنية الاستجابة

#5

فهم Server Components والجلب الآمن

#6

تصميم الرمز Secured والتوقيع HMAC

#7

بناء الإنتاج وتجنّب أخطاء الحالة المربكة

#8

تحليل المتطلبات وتحديد الكيانات

#9

إنشاء مشروع Next.js وتجربته

#10

نموذج المناسبة Event بالعلاقات

#11

واجهة إنشاء المناسبة POST /api/events

#12

تصميم صفحة الدعوة الإلكترونية

#13

توليد صورة QR من قاعدة الدعوة

#14

نشر المشروع على Vercel

#15

تصميم قاعدة البيانات والعلاقات

#16

تجريب PostgreSQL محلياً وإنشاء قاعدة الداتا

#17

نموذج المدعو Guest مع الرمز الموقّع

#18

واجهات الضيوف الإضافة والقائمة

#19

نموذج الرد RSVP التفاعلي

#20

تجربة المسح في بوابة الحفل

#21

قاعدة بيانات إنتاج مُدارة وأمانها

#22

تدفق الدعوة وقراءة QR من التوليد إلى الحضور

#23

تثبيت Prisma والاتصال بالقاعدة

#24

نموذج الرد Rsvp ومنع التكرار

#25

واجهة تسجيل الحضور POST /api/checkin

#26

صفحة قائمة الضيوف والفرز

#27

واجهة تتفهم حالة الحضور والحصر

#28

إدارة المتغيرات السرية بيئة وواجهة

#29

سيناريو المشروع وقواعد العمل

#30

بنية مجلدات المشروع ومسارات الصفحات

#31

الاستعلام والجلب مع العلاقات

#32

التحقق من المدخلات ومعالجة الأخطاء

#33

لوحة الإحصائيات الحية

#34

تأمين الروابط والهجمات الشائعة

#35

قائمة الفحص النهائي قبل الإطلاق

#36

الترحيلات migrations والبذور seed

عرض الدروس كاملة تحقق من صفحة تعلم الدورة
درس نصي 4/36
أنت تشاهد
واجهة تسجيل الحضور POST /api/checkin