# توثيق API — API Specification (OpenAPI Style)

## معلومات عامة

- **Base URL:** `{{BASE_URL}}` (مثلاً `https://api.bilgiagaci.com/api`)
- **Content-Type:** `application/json`
- **Auth Header:** `Authorization: Bearer {sanctum_token}`
- **اللغة:** `Accept-Language: en` أو `tr`

---

## تنسيق الـ Response الموحد

### استجابة ناجحة — عنصر واحد (Single Item)

```json
{
  "code": 200,
  "message": "تمت العملية بنجاح",
  "result": { ... },
  "success": true
}
```

### استجابة ناجحة — قائمة بدون pagination (Array)

```json
{
  "code": 200,
  "message": "تمت العملية بنجاح",
  "result": [ { ... }, { ... } ],
  "success": true
}
```

### استجابة ناجحة — قائمة مع pagination

```json
{
  "code": 200,
  "count": 50,
  "message": "تمت العملية بنجاح",
  "page": 1,
  "pages": 3,
  "result": [ { ... }, { ... } ],
  "success": true,
  "to": 20
}
```

### استجابة فشل — Validation Error

```json
{
  "code": 422,
  "message": "Validation failed",
  "errors": {
    "email": ["The email field is required."],
    "password": ["The password must be at least 8 characters."]
  },
  "success": false
}
```

### استجابة فشل — خطأ عام

```json
{
  "code": 500,
  "message": "Internal server error",
  "errors": {},
  "success": false
}
```

---

## 1. المصادقة (Authentication)

### POST /auth/login

```
Request:
{
  "email": "parent@bilgiagaci.com",
  "password": "password123"
}

Response 200:
{
  "code": 200,
  "message": "Login successful",
  "result": {
    "token": "1|laravel_sanctum_token_string...",
    "user": {
      "id": 1,
      "name": "Ahmet Yılmaz",
      "email": "parent@bilgiagaci.com",
      "phone": "+905551234567",
      "lang": "tr",
      "roles": ["parent"],
      "students": [
        {
          "id": 1,
          "first_name": "Defne",
          "last_name": "Yılmaz",
          "class_id": 1,
          "class_name": "Butterflies",
          "birth_date": "2022-03-15",
          "gender": "female"
        }
      ]
    }
  },
  "success": true
}

Response 401:
{
  "code": 401,
  "message": "Invalid credentials",
  "errors": {
    "email": ["The provided credentials are incorrect."]
  },
  "success": false
}
```

---

### GET /auth/me

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Authenticated user retrieved successfully",
  "result": {
    "id": 1,
    "name": "Ahmet Yılmaz",
    "email": "parent@bilgiagaci.com",
    "phone": "+905551234567",
    "lang": "tr",
    "roles": ["parent"],
    "permissions": [
      "view_child_attendance",
      "view_child_meal_records",
      "view_child_sleep_records",
      "view_class_activities",
      "view_student_media",
      "upload_media",
      "view_announcements",
      "send_pickup_alert",
      "cancel_pickup_alert"
    ],
    "students": [
      {
        "id": 1,
        "first_name": "Defne",
        "last_name": "Yılmaz",
        "class_id": 1,
        "class_name": "Butterflies",
        "birth_date": "2022-03-15",
        "gender": "female",
        "relationship": "father",
        "profile_photo_url": "https://cdn.bilgiagaci.com/students/1/profile/avatar.webp?token=..."
      }
    ]
  },
  "success": true
}
```

---

### POST /auth/logout

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Logged out successfully",
  "result": null,
  "success": true
}
```

---

### PUT /auth/profile

```
Headers: Authorization: Bearer {token}

Request:
{
  "name": "Ahmet Yılmaz",
  "phone": "+905551234567",
  "lang": "tr",
  "expo_push_token": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]"
}

Response 200:
{
  "code": 200,
  "message": "Profile updated successfully",
  "result": {
    "id": 1,
    "name": "Ahmet Yılmaz",
    "email": "parent@bilgiagaci.com",
    "phone": "+905551234567",
    "lang": "tr"
  },
  "success": true
}
```

---

### PUT /auth/password

```
Headers: Authorization: Bearer {token}

Request:
{
  "current_password": "password123",
  "new_password": "newpassword456",
  "new_password_confirmation": "newpassword456"
}

Response 200:
{
  "code": 200,
  "message": "Password changed successfully",
  "result": null,
  "success": true
}

Response 422:
{
  "code": 422,
  "message": "Validation failed",
  "errors": {
    "current_password": ["The current password is incorrect."]
  },
  "success": false
}
```

---

## 2. الطلاب (Students)

**الصلاحية:** Parent (أطفاله فقط)، Teacher (طلاب صفه)، Admin (الجميع)

**ملاحظة:** الحساسيات (allergies) تُخزّن كحقل نصي بسيط `allergies` على الطالب مباشرة (نص مفصول بفواصل مثل `"peanuts, lactose"`)، وليس كجدول منفصل. تظهر بجانب اسم الطالب أثناء توزيع الوجبات.

### GET /students

```
Headers: Authorization: Bearer {token}

Query: ?class_id=1&status=active&page=1&per_page=20

Response 200:
{
  "code": 200,
  "count": 18,
  "message": "Students retrieved successfully",
  "page": 1,
  "pages": 1,
  "result": [
    {
      "id": 1,
      "first_name": "Defne",
      "last_name": "Yılmaz",
      "class_id": 1,
      "class_name": "Butterflies",
      "birth_date": "2022-03-15",
      "gender": "female",
      "status": "active",
      "profile_photo_url": "https://cdn.bilgiagaci.com/students/1/profile/avatar.webp?token=..."
    },
    {
      "id": 2,
      "first_name": "Mehmet",
      "last_name": "Kaya",
      "class_id": 1,
      "class_name": "Butterflies",
      "birth_date": "2022-05-20",
      "gender": "male",
      "status": "active",
      "profile_photo_url": null
    }
  ],
  "success": true,
  "to": 18
}
```

---

### GET /students/{id}

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Student retrieved successfully",
  "result": {
    "id": 1,
    "first_name": "Defne",
    "last_name": "Yılmaz",
    "class_id": 1,
    "class_name": "Butterflies",
    "birth_date": "2022-03-15",
    "gender": "female",
    "status": "active",
    "enrollment_date": "2025-09-01",
    "notes": null,
    "profile_photo_url": "https://cdn.bilgiagaci.com/students/1/profile/avatar.webp?token=...",
    "allergies": "peanuts, lactose",
    "attendance_summary": {
      "present": 20,
      "absent": 2,
      "late": 1,
      "left_early": 1
    }
  },
  "success": true
}
```

---

### POST /admin/students (إنشاء طالب — إدارة فقط)

```
Headers: Authorization: Bearer {token}

Request:
{
  "first_name": "Defne",
  "last_name": "Yılmaz",
  "class_id": 1,
  "birth_date": "2022-03-15",
  "gender": "female",
  "enrollment_date": "2025-09-01",
  "notes": null,
  "allergies": "peanuts, lactose"
}

Response 201:
{
  "code": 201,
  "message": "Student created successfully",
  "result": {
    "id": 1,
    "first_name": "Defne",
    "last_name": "Yılmaz",
    "class_id": 1,
    "class_name": "Butterflies",
    "birth_date": "2022-03-15",
    "gender": "female",
    "status": "active"
  },
  "success": true
}
```

---

### PUT /admin/students/{id} (تعديل طالب — إدارة فقط)

```
Headers: Authorization: Bearer {token}

Request:
{
  "first_name": "Defne",
  "last_name": "Yılmaz",
  "class_id": 2,
  "birth_date": "2022-03-15",
  "gender": "female",
  "status": "active",
  "allergies": "peanuts, lactose"
}

Response 200:
{
  "code": 200,
  "message": "Student updated successfully",
  "result": {
    "id": 1,
    "first_name": "Defne",
    "last_name": "Yılmaz",
    "class_id": 2,
    "class_name": "Daisies",
    "birth_date": "2022-03-15",
    "gender": "female",
    "status": "active"
  },
  "success": true
}
```

---

### DELETE /admin/students/{id} (حذف طالب — إدارة فقط)

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Student deleted successfully",
  "result": null,
  "success": true
}
```

---

## 3. الحضور والغياب (Attendance)

**الصلاحية:** Parent (طفله)، Teacher (صفه)، Admin (الجميع)

### GET /students/{studentId}/attendance

```
Headers: Authorization: Bearer {token}

Query: ?from=2026-06-01&to=2026-06-30&page=1&per_page=31

Response 200:
{
  "code": 200,
  "count": 25,
  "message": "Attendance records retrieved successfully",
  "page": 1,
  "pages": 1,
  "result": [
    {
      "id": 1,
      "date": "2026-06-07",
      "status": "present",
      "arrival_time": "08:15",
      "departure_time": "16:00",
      "recorded_by": "Asya Öğretmen"
    },
    {
      "id": 2,
      "date": "2026-06-06",
      "status": "absent",
      "arrival_time": null,
      "departure_time": null,
      "recorded_by": "Asya Öğretmen"
    }
  ],
  "success": true,
  "to": 25
}
```

---

### POST /attendance (تسجيل حضور طالب — من المعلم)

```
Headers: Authorization: Bearer {token}

Request:
{
  "student_id": 1,
  "date": "2026-06-07",
  "status": "present",
  "arrival_time": "08:15",
  "departure_time": null
}

Response 201:
{
  "code": 201,
  "message": "Attendance recorded successfully",
  "result": {
    "id": 1,
    "student_id": 1,
    "student_name": "Defne Yılmaz",
    "date": "2026-06-07",
    "status": "present",
    "arrival_time": "08:15",
    "departure_time": null
  },
  "success": true
}
```

---

### POST /attendance/bulk (تسجيل الحضور دفعة واحدة للصف)

```
Headers: Authorization: Bearer {token}

Request:
{
  "class_id": 1,
  "date": "2026-06-07",
  "records": [
    { "student_id": 1, "status": "present", "arrival_time": "08:15" },
    { "student_id": 2, "status": "absent", "arrival_time": null },
    { "student_id": 3, "status": "late", "arrival_time": "09:05" }
  ]
}

Response 201:
{
  "code": 201,
  "message": "Bulk attendance recorded successfully",
  "result": {
    "date": "2026-06-07",
    "class_id": 1,
    "total": 3,
    "saved": 3
  },
  "success": true
}
```

---

## 4. الوجبات (Meals)

**الصلاحية:** Parent (طفله)، Teacher (صفه)، Admin (الجميع)

**ملاحظة:** خطط الوجبات خاصة بالحضانة كاملة وليست مرتبطة بصف معين، لذا لا يوجد `class_id` في meal_plans.

### GET /meal-plans

```
Headers: Authorization: Bearer {token}

Query: ?date=2026-06-07

Response 200:
{
  "code": 200,
  "message": "Meal plans retrieved successfully",
  "result": [
    {
      "id": 1,
      "meal_id": 1,
      "meal_name": "Breakfast",
      "meal_type": "breakfast",
      "description": "Cheese sandwich, milk, cucumber",
      "date": "2026-06-07"
    },
    {
      "id": 2,
      "meal_id": 2,
      "meal_name": "Lunch",
      "meal_type": "lunch",
      "description": "Lentil soup, chicken with rice, salad",
      "date": "2026-06-07"
    }
  ],
  "success": true
}
```

---

### GET /students/{studentId}/meal-records

```
Headers: Authorization: Bearer {token}

Query: ?date=2026-06-07

Response 200:
{
  "code": 200,
  "message": "Meal records retrieved successfully",
  "result": [
    {
      "id": 1,
      "meal_id": 1,
      "meal_type": "breakfast",
      "meal_name": "Breakfast",
      "status": "all",
      "notes": null,
      "recorded_by": "Asya Öğretmen",
      "date": "2026-06-07"
    },
    {
      "id": 2,
      "meal_id": 2,
      "meal_type": "lunch",
      "meal_name": "Lunch",
      "status": "little",
      "notes": "Did not like the soup",
      "recorded_by": "Asya Öğretmen",
      "date": "2026-06-07"
    },
    {
      "id": 3,
      "meal_id": 3,
      "meal_type": "snack",
      "meal_name": "Afternoon Snack",
      "status": "good_appetite",
      "notes": null,
      "recorded_by": "Asya Öğretmen",
      "date": "2026-06-07"
    }
  ],
  "success": true
}
```

---

### POST /meal-records (تسجيل وجبة لطالب — من المعلم)

```
Headers: Authorization: Bearer {token}

Request:
{
  "student_id": 1,
  "date": "2026-06-07",
  "meal_id": 1,
  "status": "all",
  "notes": "Finished everything quickly"
}

Response 201:
{
  "code": 201,
  "message": "Meal record saved successfully",
  "result": {
    "id": 1,
    "student_id": 1,
    "student_name": "Defne Yılmaz",
    "meal_id": 1,
    "meal_type": "breakfast",
    "status": "all",
    "notes": "Finished everything quickly",
    "date": "2026-06-07"
  },
  "success": true
}
```

---

### POST /meal-records/bulk (تسجيل وجبات الصف دفعة واحدة)

```
Headers: Authorization: Bearer {token}

Request:
{
  "class_id": 1,
  "date": "2026-06-07",
  "meal_id": 1,
  "records": [
    { "student_id": 1, "status": "all", "notes": null },
    { "student_id": 2, "status": "little", "notes": "Did not eat well" },
    { "student_id": 3, "status": "none", "notes": "Had his own food from home" }
  ]
}

Response 201:
{
  "code": 201,
  "message": "Bulk meal records saved successfully",
  "result": {
    "date": "2026-06-07",
    "meal_id": 1,
    "meal_type": "breakfast",
    "total": 3,
    "saved": 3
  },
  "success": true
}
```

---

## 5. النوم (Sleep)

**الصلاحية:** Parent (طفله)، Teacher (صفه)، Admin (الجميع)
(فقط للصفوف التي has_nap_time = true)

### GET /students/{studentId}/sleep-records

```
Headers: Authorization: Bearer {token}

Query: ?from=2026-06-01&to=2026-06-30

Response 200:
{
  "code": 200,
  "message": "Sleep records retrieved successfully",
  "result": [
    {
      "id": 1,
      "date": "2026-06-07",
      "status": "slept",
      "duration": 90,
      "notes": "Slept peacefully",
      "recorded_by": "Asya Öğretmen"
    },
    {
      "id": 2,
      "date": "2026-06-06",
      "status": "not_slept",
      "duration": null,
      "notes": "Was restless",
      "recorded_by": "Asya Öğretmen"
    }
  ],
  "success": true
}
```

---

### POST /sleep-records (تسجيل نوم طالب — من المعلم)

```
Headers: Authorization: Bearer {token}

Request:
{
  "student_id": 1,
  "date": "2026-06-07",
  "status": "slept",
  "duration": 90,
  "notes": "Slept well"
}

Response 201:
{
  "code": 201,
  "message": "Sleep record saved successfully",
  "result": {
    "id": 1,
    "student_id": 1,
    "student_name": "Defne Yılmaz",
    "date": "2026-06-07",
    "status": "slept",
    "duration": 90,
    "notes": "Slept well"
  },
  "success": true
}
```

---

### POST /sleep-records/bulk

```
Headers: Authorization: Bearer {token}

Request:
{
  "class_id": 1,
  "date": "2026-06-07",
  "records": [
    { "student_id": 1, "status": "slept", "duration": 90 },
    { "student_id": 2, "status": "not_slept", "duration": null },
    { "student_id": 3, "status": "rested_only", "duration": 45 }
  ]
}

Response 201:
{
  "code": 201,
  "message": "Bulk sleep records saved successfully",
  "result": {
    "date": "2026-06-07",
    "class_id": 1,
    "total": 3,
    "saved": 3
  },
  "success": true
}
```

---

## 6. الأنشطة (Activities)

### GET /students/{studentId}/activities

```
Headers: Authorization: Bearer {token}

Query: ?from=2026-06-01&to=2026-06-30&page=1&per_page=20

Response 200:
{
  "code": 200,
  "count": 12,
  "message": "Activities retrieved successfully",
  "page": 1,
  "pages": 1,
  "result": [
    {
      "id": 1,
      "title": "Robotics Activity",
      "description": "Learning directions with Bee-Bot robot. Children guided the robot to reach targets on the mat.",
      "objective": "Spatial awareness and direction concepts",
      "type": "scheduled",
      "class_id": 1,
      "class_name": "Butterflies",
      "date": "2026-06-07",
      "created_by": "Asya Öğretmen",
      "media": [
        {
          "id": 42,
          "url": "https://cdn.bilgiagaci.com/activities/1/images/abc123.webp?token=...",
          "thumbnail_url": "https://cdn.bilgiagaci.com/activities/1/images/abc123_thumb.webp?token=...",
          "mime_type": "image/webp"
        }
      ]
    }
  ],
  "success": true,
  "to": 12
}
```

---

### GET /classes/{classId}/schedules

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Activity schedules retrieved successfully",
  "result": [
    {
      "id": 1,
      "class_id": 1,
      "title": "Robotics",
      "description": "Weekly robotics and coding activity",
      "objective": "Problem solving and logical thinking",
      "day_of_week": 1,
      "day_name": "Monday",
      "start_time": "10:00",
      "end_time": "11:00",
      "is_recurring": true
    },
    {
      "id": 2,
      "class_id": 1,
      "title": "Art & Painting",
      "description": "Creative arts with watercolors",
      "objective": "Creativity and fine motor skills",
      "day_of_week": 3,
      "day_name": "Wednesday",
      "start_time": "10:00",
      "end_time": "11:00",
      "is_recurring": true
    }
  ],
  "success": true
}
```

---

### POST /activities (نشر نشاط — من المعلم)

```
Headers: Authorization: Bearer {token}

Request:
{
  "title": "Robotics Activity",
  "description": "Learning directions with Bee-Bot robot",
  "objective": "Spatial awareness and direction concepts",
  "class_id": 1,
  "date": "2026-06-07",
  "type": "ad_hoc"
}

Response 201:
{
  "code": 201,
  "message": "Activity created successfully",
  "result": {
    "id": 1,
    "title": "Robotics Activity",
    "description": "Learning directions with Bee-Bot robot",
    "objective": "Spatial awareness and direction concepts",
    "class_id": 1,
    "class_name": "Butterflies",
    "date": "2026-06-07",
    "type": "ad_hoc",
    "published": true,
    "media": []
  },
  "success": true
}
```

---

## 7. الصور والفيديو (Media) — رفع مباشر إلى R2

**التصميم:** رفع الملفات مباشرة من التطبيق إلى Cloudflare R2 عبر **Presigned URL** بدون المرور بسيرفر Laravel، ثم تسجيل المرجع في قاعدة البيانات بطلب منفصل.

التدفق الكامل:
```
Mobile App                    Laravel API                         R2
    │                             │                                 │
    │ ① POST /api/media/request-upload                              │
    │   {mime, size, ...}          │                                 │
    │─────────────────────────────>│                                 │
    │                             │─ تعقيم اسم الملف + توليد مسار     │
    │                             │─ إنشاء presigned URL (انتهاء 5 دقائق)
    │  ② 200 {upload_url, file_key, upload_id}                      │
    │<────────────────────────────│                                 │
    │                             │                                 │
    │ ③ PUT upload_url + binary file                                │
    │─────────────────────────────────────────────────────────────>│
    │  200 OK                      │                                 │
    │<─────────────────────────────────────────────────────────────│
    │                             │                                 │
    │ ④ POST /api/media/register  │                                 │
    │   {upload_id, metadata}     │                                 │
    │────────────────────────────>│                                 │
    │                             │─ Job::ProcessMediaFile (queue)   │
    │                             │─ إنشاء سجل Spatie media          │
    │                             │─ إنشاء media_permissions         │
    │  ⑤ 200 {media_id}          │                                 │
    │<────────────────────────────│                                 │
```

---

### POST /media/request-upload — طلب Presigned URL (الخطوة ①)

```
Headers: Authorization: Bearer {token}

Request:
{
  "mime_type": "image/jpeg",
  "size": 5242880,
  "collection": "daily_photos",
  "original_name": "IMG_20260607.jpg"
}

Response 200:
{
  "code": 200,
  "message": "Upload URL generated successfully",
  "result": {
    "upload_id": "550e8400-e29b-41d4-a716-446655440000",
    "upload_url": "https://bilgiagaci.r2.cloudflarestorage.com/uploads/temp/550e8400-e29b-41d4-a716-446655440000.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
    "file_key": "uploads/temp/550e8400-e29b-41d4-a716-446655440000.jpg",
    "expires_in": 300
  },
  "success": true
}

Response 422:
{
  "code": 422,
  "message": "Validation failed",
  "errors": {
    "mime_type": ["Unsupported file type."],
    "size": ["File size exceeds maximum allowed (10 MB)."]
  },
  "success": false
}
```

---

### POST /media/register — تسجيل الملف بعد الرفع (الخطوة ④)

```
Headers: Authorization: Bearer {token}

Request:
{
  "upload_id": "550e8400-e29b-41d4-a716-446655440000",
  "student_ids": [1, 2],
  "class_id": 1,
  "visibility": "parents_tagged",
  "activity_id": null
}

Response 200:
{
  "code": 200,
  "message": "Media registered successfully, processing started",
  "result": {
    "media_id": 42,
    "status": "processing",
    "collection": "daily_photos",
    "original_name": "IMG_20260607.jpg",
    "thumbnail_url": null
  },
  "success": true
}
```

---

### GET /students/{studentId}/media

```
Headers: Authorization: Bearer {token}

Query: ?type=image&status=ready&page=1&per_page=20

Response 200:
{
  "code": 200,
  "count": 25,
  "message": "Media retrieved successfully",
  "page": 1,
  "pages": 2,
  "result": [
    {
      "id": 42,
      "url": "https://cdn.bilgiagaci.com/students/1/photos/2026/06/abc123.webp?token=...",
      "thumbnail_url": "https://cdn.bilgiagaci.com/students/1/photos/2026/06/abc123_thumb.webp?token=...",
      "collection": "daily_photos",
      "mime_type": "image/webp",
      "original_name": "IMG_20260607.jpg",
      "size": 245760,
      "status": "ready",
      "visibility": "parents_tagged",
      "approved": true,
      "created_at": "2026-06-07T10:30:00Z"
    }
  ],
  "success": true,
  "to": 25
}
```

---

### GET /media/{id}/status — متابعة حالة المعالجة

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Media status retrieved successfully",
  "result": {
    "id": 42,
    "status": "processing",
    "progress_percent": 75,
    "original_name": "IMG_20260607.jpg"
  },
  "success": true
}
```

---

### GET /admin/media/pending (للإدارة)

```
Headers: Authorization: Bearer {token}

Query: ?page=1&per_page=20

Response 200:
{
  "code": 200,
  "count": 3,
  "message": "Pending media retrieved successfully",
  "page": 1,
  "pages": 1,
  "result": [
    {
      "id": 42,
      "url": "https://cdn.bilgiagaci.com/uploads/temp/placeholder.jpg?token=...",
      "thumbnail_url": "https://cdn.bilgiagaci.com/uploads/temp/placeholder_thumb.jpg?token=...",
      "collection": "daily_photos",
      "mime_type": "image/webp",
      "visibility": "parents_tagged",
      "requires_approval": true,
      "approved": false,
      "uploaded_by": "Asya Öğretmen",
      "class_id": 1,
      "class_name": "Butterflies",
      "student_ids": [1, 2],
      "created_at": "2026-06-07T10:25:00Z"
    }
  ],
  "success": true,
  "to": 3
}
```

---

### POST /admin/media/{mediaId}/approve

```
Headers: Authorization: Bearer {token}

Request:
{
  "approved": true
}

Response 200:
{
  "code": 200,
  "message": "Media approved successfully",
  "result": {
    "id": 42,
    "approved": true,
    "approved_by": "Admin Name",
    "approved_at": "2026-06-07T11:00:00Z"
  },
  "success": true
}
```

---

### DELETE /media/{id}

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Media deleted successfully",
  "result": null,
  "success": true
}
```

---

## 8. الإعلانات (Announcements)

**تم إلغاء نظام المراسلة، الاعتماد على الإعلانات والإشعارات فقط.**

### GET /announcements

```
Headers: Authorization: Bearer {token}

Query: ?scope=class&class_id=1&page=1&per_page=20

Response 200:
{
  "code": 200,
  "count": 5,
  "message": "Announcements retrieved successfully",
  "page": 1,
  "pages": 1,
  "result": [
    {
      "id": 1,
      "title": "Parent Meeting",
      "body": "There will be a meeting on Friday at 15:00 to discuss upcoming events.",
      "scope": "class",
      "target_class_id": 1,
      "target_class_name": "Butterflies",
      "created_by": "Admin Name",
      "published_at": "2026-06-07T10:00:00Z",
      "expires_at": "2026-06-14T10:00:00Z",
      "read": false
    }
  ],
  "success": true,
  "to": 5
}
```

---

### POST /admin/announcements (نشر إعلان — من الإدارة)

```
Headers: Authorization: Bearer {token}

Request:
{
  "title": "Parent Meeting",
  "body": "There will be a meeting on Friday at 15:00 to discuss upcoming events.",
  "scope": "class",
  "target_class_id": 1,
  "target_user_id": null,
  "expires_at": "2026-06-14T10:00:00"
}

Response 201:
{
  "code": 201,
  "message": "Announcement published successfully",
  "result": {
    "id": 1,
    "title": "Parent Meeting",
    "body": "There will be a meeting on Friday at 15:00 to discuss upcoming events.",
    "scope": "class",
    "published_at": "2026-06-07T10:00:00Z"
  },
  "success": true
}
```

---

### POST /announcements/{id}/read (تمييز كمقروء)

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Announcement marked as read",
  "result": {
    "id": 1,
    "read_at": "2026-06-07T10:05:00Z"
  },
  "success": true
}
```

---

### DELETE /admin/announcements/{id}

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Announcement deleted successfully",
  "result": null,
  "success": true
}
```

---

## 9. الإشعارات (Notifications)

### GET /notifications

```
Headers: Authorization: Bearer {token}

Query: ?page=1&per_page=20

Response 200:
{
  "code": 200,
  "count": 15,
  "message": "Notifications retrieved successfully",
  "page": 1,
  "pages": 1,
  "result": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "type": "App\\Notifications\\AttendanceRecorded",
      "data": {
        "student_name": "Defne Yılmaz",
        "status": "present",
        "date": "2026-06-07"
      },
      "read_at": null,
      "created_at": "2026-06-07T08:00:00Z"
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "type": "App\\Notifications\\MealRecorded",
      "data": {
        "student_name": "Defne Yılmaz",
        "meal_type": "breakfast",
        "status": "all",
        "date": "2026-06-07"
      },
      "read_at": "2026-06-07T09:30:00Z",
      "created_at": "2026-06-07T09:30:00Z"
    }
  ],
  "success": true,
  "to": 15
}
```

---

### POST /notifications/{id}/read

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Notification marked as read",
  "result": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "read_at": "2026-06-07T10:00:00Z"
  },
  "success": true
}
```

---

### GET /notifications/unread-count

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Unread count retrieved successfully",
  "result": {
    "count": 8
  },
  "success": true
}
```

---

## 10. "أنا قادم" (Pickup Alert)

### POST /pickup/notify

```
Headers: Authorization: Bearer {token}

Request:
{
  "student_id": 1,
  "estimated_minutes": "15"
}

Response 200:
{
  "code": 200,
  "message": "Pickup alert sent successfully",
  "result": {
    "id": 1,
    "student_id": 1,
    "student_name": "Defne Yılmaz",
    "class_id": 1,
    "class_name": "Butterflies",
    "estimated_minutes": 15,
    "status": "pending",
    "created_at": "2026-06-07T15:30:00Z"
  },
  "success": true
}
```

---

### POST /pickup/{id}/cancel

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Pickup alert cancelled successfully",
  "result": {
    "id": 1,
    "status": "cancelled",
    "cancelled_at": "2026-06-07T15:35:00Z"
  },
  "success": true
}
```

---

### GET /pickup/alerts (للصف — من لوحة المعلم)

```
Headers: Authorization: Bearer {token}

Query: ?class_id=1&status=pending

Response 200:
{
  "code": 200,
  "message": "Pickup alerts retrieved successfully",
  "result": [
    {
      "id": 1,
      "student_id": 1,
      "student_name": "Defne Yılmaz",
      "parent_id": 1,
      "parent_name": "Ahmet Yılmaz",
      "class_id": 1,
      "class_name": "Butterflies",
      "estimated_minutes": 15,
      "status": "pending",
      "created_at": "2026-06-07T15:30:00Z"
    }
  ],
  "success": true
}
```

---

## 11. الإعدادات (Settings) — صلاحية إدارة فقط

### GET /admin/settings

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Settings retrieved successfully",
  "result": {
    "photos": {
      "require_approval": true
    },
    "school": {
      "name": "Bilgi Ağacı Anaokulu",
      "working_hours": {
        "start": "08:00",
        "end": "17:00"
      },
      "academic_year": "2025-2026"
    }
  },
  "success": true
}
```

---

### PUT /admin/settings

```
Headers: Authorization: Bearer {token}

Request:
{
  "photos.require_approval": false,
  "school.name": "Bilgi Ağacı Anaokulu - Yeni Şube"
}

Response 200:
{
  "code": 200,
  "message": "Settings updated successfully",
  "result": {
    "photos": {
      "require_approval": false
    },
    "school": {
      "name": "Bilgi Ağacı Anaokulu - Yeni Şube",
      "working_hours": {
        "start": "08:00",
        "end": "17:00"
      },
      "academic_year": "2025-2026"
    }
  },
  "success": true
}
```

---

## 12. تقارير الإدارة

### GET /admin/reports/attendance

```
Headers: Authorization: Bearer {token}

Query: ?class_id=1&from=2026-06-01&to=2026-06-30&group=day

Response 200:
{
  "code": 200,
  "message": "Attendance report generated successfully",
  "result": {
    "class_id": 1,
    "class_name": "Butterflies",
    "from": "2026-06-01",
    "to": "2026-06-30",
    "total_students": 18,
    "summary": {
      "present": 340,
      "absent": 40,
      "late": 15,
      "left_early": 10
    },
    "daily": [
      {
        "date": "2026-06-01",
        "present": 16,
        "absent": 2,
        "late": 0,
        "left_early": 0
      },
      {
        "date": "2026-06-02",
        "present": 15,
        "absent": 3,
        "late": 1,
        "left_early": 0
      }
    ]
  },
  "success": true
}
```

---

## 13. الصفوف (Classes) — صلاحية إدارة

### GET /admin/classes

```
Headers: Authorization: Bearer {token}

Response 200:
{
  "code": 200,
  "message": "Classes retrieved successfully",
  "result": [
    {
      "id": 1,
      "name": "Butterflies",
      "grade": "3-4 years",
      "age_min": 36,
      "age_max": 48,
      "has_nap_time": true,
      "nap_start_time": "13:00",
      "nap_end_time": "14:30",
      "academic_year": "2025-2026",
      "is_active": true,
      "student_count": 18,
      "teacher_count": 2
    }
  ],
  "success": true
}
```

---

### POST /admin/classes

```
Headers: Authorization: Bearer {token}

Request:
{
  "name": "Daisies",
  "grade": "4-5 years",
  "age_min": 48,
  "age_max": 60,
  "has_nap_time": true,
  "nap_start_time": "13:00",
  "nap_end_time": "14:00",
  "academic_year": "2025-2026"
}

Response 201:
{
  "code": 201,
  "message": "Class created successfully",
  "result": {
    "id": 2,
    "name": "Daisies",
    "grade": "4-5 years",
    "has_nap_time": true,
    "is_active": true
  },
  "success": true
}
```

---

## 14. المستخدمين (Users) — صلاحية إدارة

### GET /admin/users

```
Headers: Authorization: Bearer {token}

Query: ?role=teacher&is_active=true&page=1&per_page=20

Response 200:
{
  "code": 200,
  "count": 8,
  "message": "Users retrieved successfully",
  "page": 1,
  "pages": 1,
  "result": [
    {
      "id": 2,
      "name": "Asya Korkmaz",
      "email": "asya@bilgiagaci.com",
      "phone": "+905551112233",
      "roles": ["teacher"],
      "is_active": true,
      "classes": [
        { "id": 1, "name": "Butterflies" }
      ]
    }
  ],
  "success": true,
  "to": 8
}
```

---

## ملاحظات API

1. **Bulk endpoints** مصممة خصيصًا للمعلمين — تسجيل حضور/وجبات/نوم الصف كله في طلب واحد.
2. **الصلاحيات** تفحص في كل endpoint عبر Laravel Policies + Spatie Permissions.
3. **Expo Push Token** يحدث في profile لكل جهاز — يستخدم لإرسال push notifications عبر Expo Push Notifications.
4. **اللغة** في الـ API: البيانات المخزنة باللغة الإنجليزية، مع middleware يضبط locale من `Accept-Language` header.
5. **تم إلغاء المراسلة** نهائيًا — لا يوجد endpoints للـ chat.
6. **المدفوعات يدوية** — لا توجد endpoints لبوابات الدفع.
7. **رفع الملفات مباشر إلى R2** — التطبيق يرفع مباشرة إلى Cloudflare R2 عبر Presigned URL ولا تمر الملفات بسيرفر Laravel إطلاقًا.
8. **Presigned URL** صالح لمدة 5 دقائق فقط — كاف لبدء الرفع المباشر.
9. **تنسيق الـ Response الموحد** — جميع الاستجابات تستخدم التنسيق `{ code, message, result, success }` مع إضافة حقول `count, page, pages, to` في حالة الـ pagination.
10. **Queue** — يستخدم database queue driver لكافة الـ jobs (معالجة الوسائط، الإشعارات).
11. **الحساسيات** — تُخزّن كحقل نصي بسيط `allergies` على الطالب (نص مفصول بفواصل مثل `"peanuts, lactose"`)، وليس كجدول منفصل. تظهر بجانب اسم الطالب أثناء توزيع الوجبات.
