تحديات الواجهة الخلفية

جرّب هذه التحديات بعد إتمام خطوات الواجهة الخلفية الست كلها.


اختبار المعرفة

  1. ماذا تفعل jsonify() في Flask؟ ولماذا لا يمكنك أن تُرجع قاموسًا عاديًا؟

  2. ما الغرض من البيئة الافتراضية؟

  3. ماذا تفعل db.session.commit()؟ وماذا يحدث إذا نسيت استدعاءها؟

  4. ماذا يعني المعامل nullable=False في عمود قاعدة بيانات؟

  5. لماذا يجب ألا تضيف ملفات .env إلى git أبدًا؟


تحديات برمجية

التحدي 1: أضف نقطة نهاية DELETE

يوجد في الواجهة الخلفية بالفعل مسار DELETE بالعنوان /api/messages/<id> داخل routes.py. أضف نقطة نهاية DELETE ALL تحذف جميع الرسائل:

DELETE /api/messages

ينبغي أن تحذف كل رسالة من قاعدة البيانات وتُرجع {"deleted": count}.

التحدي 2: أضف مسار موجه النظام

أنشئ نقطة نهاية جديدة تتيح لك تغيير شخصية الذكاء الاصطناعي دون إعادة تشغيل الخادم:

POST /api/system-prompt
Body: {"prompt": "You are a pirate who speaks in riddles."}
GET /api/system-prompt
Returns: {"current_prompt": "..."}

خزّن موجه النظام الحالي في الذاكرة (في متغير) أو في جدول جديد في قاعدة البيانات.

التحدي 3: اختبر نقطة نهاية DELETE

اكتب ملف اختبار tests/test_delete.py يقوم بما يلي: 1. يختبر حذف رسالة موجودة 2. يختبر حذف رسالة غير موجودة (404) 3. يتحقق من أن قائمة الرسائل تصبح أقصر بعد الحذف

def test_delete_reduces_message_count(client):
    client.post("/api/chat", json={"message": "A"})
    client.post("/api/chat", json={"message": "B"})
    msgs = client.get("/api/messages").get_json()
    assert len(msgs) == 2

    client.delete(f"/api/messages/{msgs[0]['id']}")
    remaining = client.get("/api/messages").get_json()
    assert len(remaining) == 1

التحدي 4: سياق سجل المحادثة

حاليًا، لا ترسل الواجهة الخلفية إلى OpenAI سوى آخر رسالة من المستخدم. عدّل نقطة نهاية المحادثة لتُرسل آخر 10 رسائل كسجل للمحادثة. يتيح ذلك للذكاء الاصطناعي تذكّر السياق.

تلميح: استعلم عن آخر 10 رسائل من قاعدة البيانات وصغّها على شكل مصفوفة رسائل.


التحدي 5: أضف مقياسًا مخصصًا

أضف مقياسًا يتتبع متوسط زمن الاستجابة لنقطة النهاية /api/chat. تلميح: استخدم time.time() قبل استدعاء OpenAI وبعده، وخزّن المدد الزمنية في قائمة.

التحدي 6: افحص اختباراتك

شغّل ruff check backend/tests/. أصلح أي مشكلات يجدها ruff. يضمن ذلك أن يكون كود اختبارك نظيفًا مثل كود الإنتاج.


مشروع مفتوح: API لقائمة المهام

ابنِ API كاملًا لقائمة المهام من الصفر:

المتطلبات:

POST   /api/todos       — إنشاء مهمة (body: {"title": "..."})
GET    /api/todos       — عرض جميع المهام
PUT    /api/todos/<id>  — تحديد المهمة كمكتملة (body: {"completed": true})
DELETE /api/todos/<id>  — حذف مهمة

نموذج قاعدة البيانات:

class Todo(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    completed = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

أهداف إضافية: - أضف نقطة نهاية POST /api/todos/bulk تُنشئ عدة مهام دفعة واحدة - أضف إمكانية التصفية: GET /api/todos?completed=true - أضف إمكانية الفرز: GET /api/todos?sort=created_at&order=desc

اختبر باستخدام curl:

curl -X POST http://localhost:5000/api/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "Learn Flask"}'