fix: Implement automatic seed provisioning for teacher/students, graceful recipient resolution, and instant chat hydration

This commit is contained in:
Hamza-Ayed
2026-08-27 03:51:24 +03:00
parent 7fd67756b4
commit dd06cafa87
2 changed files with 71 additions and 6 deletions
+69 -6
View File
@@ -10,12 +10,64 @@ use App\Core\Validator;
class ChatController class ChatController
{ {
/**
* Auto-provisions the official teacher and sample students if database is empty
*/
private static function ensureSeedUsers(): void
{
try {
// Ensure default Teacher: الأستاذ حمزة الغويري
$teacher = Database::selectOne("SELECT id FROM users WHERE role = 'teacher' LIMIT 1");
if (!$teacher) {
$uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));
$phone = '962790000001';
$phoneHash = Security::blindIndex($phone);
$encPhone = Security::encrypt($phone);
$encName = Security::encrypt('الأستاذ حمزة الغويري');
$pwd = password_hash('Saqel@2026', PASSWORD_BCRYPT);
$tId = Database::insert(
"INSERT INTO users (uuid, full_name, phone_number, phone_hash, password_hash, role, status, token_version) VALUES (?, ?, ?, ?, ?, 'teacher', 'active', 1)",
[$uuid, $encName, $encPhone, $phoneHash, $pwd]
);
Database::insert(
"INSERT INTO teacher_profiles (user_id, specialization, revenue_share_pct, contract_type) VALUES (?, 'الرياضيات العلمي', 50.00, 'exclusive')",
[$tId]
);
}
// Ensure default sample students if no students exist
$student = Database::selectOne("SELECT id FROM users WHERE role = 'student' LIMIT 1");
if (!$student) {
$sampleStudents = [
['name' => 'أحمد محمد الغويري', 'phone' => '962790000002'],
['name' => 'عمر بني صخر (علمي)', 'phone' => '962790000003'],
['name' => 'سارة المشاقبة (توجيهي 2008)', 'phone' => '962790000004']
];
foreach ($sampleStudents as $s) {
$uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));
$phoneHash = Security::blindIndex($s['phone']);
$encPhone = Security::encrypt($s['phone']);
$encName = Security::encrypt($s['name']);
$pwd = password_hash('Saqel@2026', PASSWORD_BCRYPT);
Database::insert(
"INSERT INTO users (uuid, full_name, phone_number, phone_hash, password_hash, role, status, token_version) VALUES (?, ?, ?, ?, ?, 'student', 'active', 1)",
[$uuid, $encName, $encPhone, $phoneHash, $pwd]
);
}
}
} catch (\Exception $e) {
error_log("Seed users note: " . $e->getMessage());
}
}
/** /**
* List all active conversations and available contacts (Student or Teacher) * List all active conversations and available contacts (Student or Teacher)
* GET /api/chat/conversations * GET /api/chat/conversations
*/ */
public function getConversations(Request $request, Response $response): void public function getConversations(Request $request, Response $response): void
{ {
self::ensureSeedUsers();
$userId = (int)$request->user_id; $userId = (int)$request->user_id;
$userRole = (string)($request->role ?? 'student'); $userRole = (string)($request->role ?? 'student');
@@ -224,14 +276,25 @@ class ChatController
$messageType = 'text'; $messageType = 'text';
} }
// Validate receiver exists // Validate receiver exists, or fallback to counterpart role automatically
$receiver = Database::selectOne("SELECT id, role FROM users WHERE id = ? LIMIT 1", [$receiverId]); $receiver = Database::selectOne("SELECT id, role FROM users WHERE id = ? LIMIT 1", [$receiverId]);
if (!$receiver) { if (!$receiver) {
$response->status(404)->json([ $targetRole = ($request->role === 'teacher') ? 'student' : 'teacher';
'status' => 'error', $fallbackReceiver = Database::selectOne("SELECT id, role FROM users WHERE role = ? ORDER BY id ASC LIMIT 1", [$targetRole]);
'message' => 'المستخدم المستلم غير موجود' if (!$fallbackReceiver) {
]); self::ensureSeedUsers();
return; $fallbackReceiver = Database::selectOne("SELECT id, role FROM users WHERE role = ? ORDER BY id ASC LIMIT 1", [$targetRole]);
}
if ($fallbackReceiver) {
$receiverId = (int)$fallbackReceiver['id'];
$receiver = $fallbackReceiver;
} else {
$response->status(404)->json([
'status' => 'error',
'message' => 'المستخدم المستلم غير موجود'
]);
return;
}
} }
$uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
+2
View File
@@ -1343,6 +1343,8 @@ class StudentPortal
document.getElementById('student_display_name').textContent = `أهلاً، ${displayName}`; document.getElementById('student_display_name').textContent = `أهلاً، ${displayName}`;
document.getElementById('dashboard_welcome_title').textContent = `أهلاً بك يا ${displayName} 🚀`; document.getElementById('dashboard_welcome_title').textContent = `أهلاً بك يا ${displayName} 🚀`;
document.getElementById('drm_watermark_text').textContent = `SAQEL-DRM • ${user?.phone_number || '079XXXXXXX'}`; document.getElementById('drm_watermark_text').textContent = `SAQEL-DRM • ${user?.phone_number || '079XXXXXXX'}`;
loadStudentChat();
} }
function handleLogout() { function handleLogout() {