Update Saqel Platform: 2026-09-12 13:38:49
This commit is contained in:
@@ -126,7 +126,22 @@ class GuardianController
|
||||
[$studentId]
|
||||
)['cnt'] ?? 0;
|
||||
|
||||
// 4. Forensic Weakness Log (Recent exam attempts with AI diagnostic)
|
||||
// 4. Real Error Notebook metrics from student_error_notebook
|
||||
$errorStats = Database::selectOne(
|
||||
"SELECT
|
||||
COUNT(*) as total_errors,
|
||||
COALESCE(SUM(CASE WHEN status = 'mastered' THEN 1 ELSE 0 END), 0) as mastered_count,
|
||||
COALESCE(SUM(CASE WHEN status != 'mastered' THEN 1 ELSE 0 END), 0) as pending_count
|
||||
FROM student_error_notebook
|
||||
WHERE student_id = ?",
|
||||
[$studentId]
|
||||
);
|
||||
$totalErrors = (int)($errorStats['total_errors'] ?? 0);
|
||||
$masteredErrors = (int)($errorStats['mastered_count'] ?? 0);
|
||||
$pendingErrors = (int)($errorStats['pending_count'] ?? 0);
|
||||
$errorMasteryPercentage = $totalErrors > 0 ? round(($masteredErrors / $totalErrors) * 100, 1) : 100.0;
|
||||
|
||||
// 5. Forensic Weakness Log (Recent exam attempts with AI diagnostic)
|
||||
$diagnosticLogs = Database::select(
|
||||
"SELECT ea.percentage, ea.status, ea.weak_topics_json, ea.ai_diagnostic_report, ea.completed_at, e.title as exam_title, e.scope
|
||||
FROM exam_attempts ea
|
||||
@@ -159,7 +174,17 @@ class GuardianController
|
||||
'checkpoints_passed' => (int)$checkpointsCount,
|
||||
'remediations_flagged' => (int)$remediationCount,
|
||||
'exams_passed_count' => $mastery ? (int)$mastery['exams_passed_count'] : 0,
|
||||
'exams_total_count' => $mastery ? (int)$mastery['exams_total_count'] : 0
|
||||
'exams_total_count' => $mastery ? (int)$mastery['exams_total_count'] : 0,
|
||||
'error_notebook' => [
|
||||
'total_errors' => $totalErrors,
|
||||
'mastered_count' => $masteredErrors,
|
||||
'pending_count' => $pendingErrors,
|
||||
'mastery_percentage' => $errorMasteryPercentage,
|
||||
],
|
||||
'errors_total' => $totalErrors,
|
||||
'errors_mastered' => $masteredErrors,
|
||||
'errors_pending' => $pendingErrors,
|
||||
'errors_mastery_rate' => $errorMasteryPercentage,
|
||||
],
|
||||
'diagnostics' => $diagnosticLogs
|
||||
];
|
||||
@@ -173,6 +198,52 @@ class GuardianController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Child's Error Notebook for Guardian inspection
|
||||
* GET /api/guardian/children/{id}/error-notebook
|
||||
*/
|
||||
public function getChildErrorNotebook(Request $request, Response $response): void
|
||||
{
|
||||
$guardianId = (int)$request->user_id;
|
||||
$studentId = (int)$request->getParam('id');
|
||||
|
||||
// Verify guardian link and analytical authorization
|
||||
$linked = Database::selectOne(
|
||||
"SELECT id FROM guardian_students WHERE guardian_id = ? AND student_id = ? AND can_view_analytics = 1 LIMIT 1",
|
||||
[$guardianId, $studentId]
|
||||
);
|
||||
if (!$linked) {
|
||||
$response->status(403)->json(['status' => 'error', 'message' => 'غير مصرح بالوصول إلى دفتر أخطاء هذا الطالب']);
|
||||
return;
|
||||
}
|
||||
|
||||
$items = Database::select(
|
||||
"SELECT * FROM student_error_notebook WHERE student_id = ? ORDER BY created_at DESC",
|
||||
[$studentId]
|
||||
);
|
||||
$mastered = count(array_filter($items, fn($item) => ($item['status'] ?? '') === 'mastered'));
|
||||
$total = count($items);
|
||||
$bySubject = [];
|
||||
foreach ($items as $item) {
|
||||
$name = (string)($item['subject_name'] ?? '');
|
||||
if ($name !== '') $bySubject[$name] = ($bySubject[$name] ?? 0) + 1;
|
||||
}
|
||||
|
||||
$response->json([
|
||||
'status' => 'success',
|
||||
'data' => [
|
||||
'summary' => [
|
||||
'total_errors' => $total,
|
||||
'mastered_count' => $mastered,
|
||||
'pending_count' => $total - $mastered,
|
||||
'mastery_percentage' => $total > 0 ? round(($mastered / $total) * 100, 1) : 100.0,
|
||||
'by_subject' => $bySubject,
|
||||
],
|
||||
'items' => $items,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function maskNationalId(string $storedValue): string
|
||||
{
|
||||
if ($storedValue === '') {
|
||||
|
||||
Reference in New Issue
Block a user