feat: Implement Zero-Touch Autonomous Forensic AI Video & Curriculum Analyzer (Gemini timeline chaptering, strictly chronological Socratic checkpoints, and curriculum grounding)

This commit is contained in:
Hamza-Ayed
2026-08-28 01:42:59 +03:00
parent 54ceab1aae
commit 4d01962cf8
5 changed files with 450 additions and 88 deletions
+50 -2
View File
@@ -642,13 +642,31 @@ class StudentPortal
<div class="player-bar">
<div style="display: flex; align-items: center; gap: 12px;">
<span class="time-badge" id="video_time_display">00:00 / 09:56</span>
<span style="font-size: 12px; color: var(--text-muted);">نقطة التثبيت المعرفي التالية عند: 00:15</span>
<span style="font-size: 12px; color: var(--accent-cyan); font-weight: 700;" id="checkpoint_status_badge">نقاط الفحص السقراطي الذكي نشطة 🧠</span>
</div>
<button type="button" onclick="triggerCheckpointDemo()" style="background: rgba(245,158,11,0.15); border: 1px solid rgba(245,158,11,0.3); color: var(--accent-gold); border-radius: 980px; padding: 5px 14px; font-size: 11.5px; cursor: pointer; font-weight: 700;">
محاكاة نقطة الكويز اللحظي (00:15) ⏱️
محاكاة نقطة الكويز اللحظي ⏱️
</button>
</div>
</div>
<!-- AI Timeline Chapters Roadmap -->
<div style="margin-top: 20px; background: rgba(15, 23, 42, 0.6); border: 1px solid var(--border); border-radius: 16px; padding: 18px;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px;">
<span style="font-size: 13.5px; font-weight: 800; color: var(--accent-cyan);">🗺️ فهرس الأفكار والمحطات الزمنية (التحليل الجنائي للمنهاج)</span>
<span style="font-size: 11px; color: var(--text-muted);">انقر على أي محطة للانتقال المباشر</span>
</div>
<div id="ai_timeline_chapters_list" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px;">
<!-- Dynamically loaded via loadStudentLessonPlayback -->
<div style="background: rgba(255,255,255,0.03); border: 1px solid var(--border); border-radius: 12px; padding: 12px; cursor: pointer;" onclick="seekToSeconds(0)">
<div style="display: flex; justify-content: space-between; font-size: 11.5px; color: var(--accent-gold); font-weight: 700; margin-bottom: 4px;">
<span>المحطة 1: التمهيد وتوضيح المفهوم</span>
<span>00:00</span>
</div>
<div style="font-size: 12px; color: var(--text-secondary);">المعنى الفيزيائي والهندسي للمشتقة الأولى.</div>
</div>
</div>
</div>
</div>
<!-- TAB 2: Real-time Chat with Teacher (Workerman WebSocket) -->
@@ -956,6 +974,15 @@ class StudentPortal
}
}
function seekToSeconds(sec) {
const video = document.getElementById('lesson_video_player');
if (video) {
video.currentTime = sec;
video.play();
showLuxuryToast('تم الانتقال للمحطة ⏱️', formatTime(sec));
}
}
async function loadStudentLessonPlayback(lessonId = 1) {
const token = localStorage.getItem('saqel_student_jwt');
if (!token) return;
@@ -967,8 +994,29 @@ class StudentPortal
if (res.ok && data.status === 'success') {
const pb = data.data.playback;
const checkpoints = data.data.checkpoints || [];
const chapters = data.data.chapters || [];
activeLessonCheckpoints = checkpoints;
// Update Checkpoint Status badge
const badge = document.getElementById('checkpoint_status_badge');
if (badge) {
badge.textContent = `الفحص السقراطي الذكي نشط (${checkpoints.length} نقاط فحص) 🧠`;
}
// Render AI Timeline Chapters
const chaptersList = document.getElementById('ai_timeline_chapters_list');
if (chaptersList && chapters.length > 0) {
chaptersList.innerHTML = chapters.map((ch, idx) => `
<div style="background: rgba(255,255,255,0.03); border: 1px solid var(--border); border-radius: 12px; padding: 12px; cursor: pointer; transition: all 0.2s ease;" onclick="seekToSeconds(${ch.start_seconds})" onmouseover="this.style.borderColor='var(--accent-cyan)'" onmouseout="this.style.borderColor='var(--border)'">
<div style="display: flex; justify-content: space-between; font-size: 11.5px; color: var(--accent-gold); font-weight: 700; margin-bottom: 4px;">
<span>المحطة ${idx + 1}: ${escapeHtml(ch.title)}</span>
<span style="font-family: monospace; color: var(--accent-cyan);">${formatTime(ch.start_seconds)}</span>
</div>
<div style="font-size: 12px; color: var(--text-secondary); line-height: 1.4;">${escapeHtml(ch.summary || '')}</div>
</div>
`).join('');
}
const video = document.getElementById('lesson_video_player');
if (video && pb) {
if (pb.hls_url && window.Hls && Hls.isSupported()) {
+19 -75
View File
@@ -446,12 +446,12 @@ class TeacherPortal
</div>
</div>
<!-- TAB 2: Courses & Dual Video Upload (API & Bunny Stream) -->
<!-- TAB 2: Zero-Touch Autonomous Video & AI Studio -->
<div id="tab_courses_content" class="studio-card" style="display: none;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 12px;">
<div>
<h3 style="font-size: 18px; font-weight: 900;">إدارة الحصص والفيديوهات التعليمية (Direct API & Bunny Stream) 🎬</h3>
<p style="font-size: 12px; color: var(--text-muted); margin-top: 4px;">رفع وبث الفيديوهات بالطريقتين مع التشفير وتثبيت نقاط الفحص السقراطي داخل الفيديو.</p>
<h3 style="font-size: 18px; font-weight: 900;">استوديو رفع الحصص والتحليل الجنائي للذكاء الاصطناعي 🎬</h3>
<p style="font-size: 12px; color: var(--text-muted); margin-top: 4px;">ارفع الفيديو واترك الباقي لمحرك صَقِل: تقطيع HLS، مطابقة المنهاج، وتوليد الأسئلة السقراطية آلياً.</p>
</div>
<div style="display: flex; gap: 10px;">
<button type="button" onclick="switchVideoUploadMode('api')" id="btn_mode_api" class="btn-primary" style="width: auto; padding: 8px 18px; font-size: 12px; background: linear-gradient(135deg, #0284C7, #0369A1);">1. الرفع المباشر عبر السيرفر ⚡</button>
@@ -462,8 +462,8 @@ class TeacherPortal
<!-- UPLOADER BOX 1: Direct API Upload -->
<div id="uploader_box_api" style="background: rgba(11, 19, 43, 0.85); border: 1px solid rgba(56, 189, 248, 0.3); border-radius: 18px; padding: 24px; margin-bottom: 24px; box-shadow: 0 10px 30px rgba(0,0,0,0.4);">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px;">
<h4 style="font-size: 15px; font-weight: 800; color: var(--accent-cyan);">⚡ الرفع المباشر والتلقائي عبر السيرفر (Direct API Stream)</h4>
<span style="font-size: 11px; background: rgba(56,189,248,0.1); color: var(--accent-cyan); padding: 3px 10px; border-radius: 6px; font-weight: 700;">HTTP 206 Partial Content</span>
<h4 style="font-size: 15px; font-weight: 800; color: var(--accent-cyan);">⚡ رفع مباشر ومعالجة ذكية فورية (HLS + Gemini Socratic Engine)</h4>
<span style="font-size: 11px; background: rgba(56,189,248,0.1); color: var(--accent-cyan); padding: 3px 10px; border-radius: 6px; font-weight: 700;">معالجة آلية 100% 🧠</span>
</div>
<form id="form_direct_upload" onsubmit="handleDirectVideoUpload(event)">
@@ -486,10 +486,10 @@ class TeacherPortal
<div class="form-group" style="margin-top: 12px;">
<label class="form-label">ملف الفيديو (MP4, WebM, MOV - حتى 2GB)</label>
<div style="border: 2px dashed rgba(56, 189, 248, 0.4); border-radius: 14px; padding: 24px; text-align: center; background: rgba(0,0,0,0.2); cursor: pointer;" onclick="document.getElementById('direct_video_file').click()">
<div style="font-size: 28px; margin-bottom: 8px;">🎬</div>
<div style="font-size: 13px; font-weight: 700; color: #FFFFFF;" id="file_selected_label">اضغط لاختيار ملف الفيديو أو اسحبه وأفلته هنا</div>
<div style="font-size: 11px; color: var(--text-muted); margin-top: 4px;">يتم حفظه تلقائياً في مسار السيرفر الآمن وبثه تدفقياً عبر الـ API</div>
<div style="border: 2px dashed rgba(56, 189, 248, 0.4); border-radius: 14px; padding: 28px; text-align: center; background: rgba(0,0,0,0.2); cursor: pointer;" onclick="document.getElementById('direct_video_file').click()">
<div style="font-size: 32px; margin-bottom: 8px;">🎬</div>
<div style="font-size: 14px; font-weight: 700; color: #FFFFFF;" id="file_selected_label">اضغط لاختيار ملف الفيديو أو اسحبه وأفلته هنا</div>
<div style="font-size: 11.5px; color: var(--text-muted); margin-top: 6px;">يتولى السيرفر التقطيع إلى HLS والتحليل الجنائي وتوليد نقاط الفحص السقراطي فوراً في الخلفية</div>
<input type="file" id="direct_video_file" accept="video/mp4,video/webm,video/quicktime,video/x-matroska" style="display: none;" onchange="onVideoFileSelected(this)">
</div>
</div>
@@ -505,7 +505,7 @@ class TeacherPortal
</div>
</div>
<button type="submit" id="btn_submit_direct_upload" class="btn-primary" style="margin-top: 18px; width: auto; padding: 12px 32px; font-size: 13px;">بدء رفع وحفظ الفيديو الآن 🚀</button>
<button type="submit" id="btn_submit_direct_upload" class="btn-primary" style="margin-top: 18px; width: auto; padding: 12px 36px; font-size: 13.5px; font-weight: 800;">رفع وحفظ الحصة والتحليل الذكي الآن 🚀</button>
</form>
</div>
@@ -540,74 +540,18 @@ class TeacherPortal
<input type="number" id="bunny_duration_input" value="1800" class="input-text">
</div>
</div>
<button type="submit" id="btn_submit_bunny_link" class="btn-primary" style="margin-top: 18px; width: auto; padding: 12px 32px; font-size: 13px; background: linear-gradient(135deg, #F59E0B, #D97706);">حفظ وربط درس Bunny Stream ✓</button>
<button type="submit" id="btn_submit_bunny_link" class="btn-primary" style="margin-top: 18px; width: auto; padding: 12px 36px; font-size: 13.5px; font-weight: 800; background: linear-gradient(135deg, #F59E0B, #D97706);">حفظ وربط درس Bunny Stream ✓</button>
</form>
</div>
<!-- IN-VIDEO SOCRATIC CHECKPOINTS -->
<div style="background: rgba(15, 23, 42, 0.8); border: 1px solid var(--border); border-radius: 18px; padding: 24px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; flex-wrap: wrap; gap: 8px;">
<h4 style="font-size: 15px; font-weight: 800; color: var(--accent-cyan);">+ تثبيت نقطة فحص معرفي سقراطي (Socratic Checkpoint) في الفيديو</h4>
<span style="font-size: 11px; background: rgba(56,189,248,0.1); color: var(--accent-cyan); padding: 3px 10px; border-radius: 6px;">محرك التثبيت الصدمي والعلاجي 🧠</span>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px;">
<div class="form-group">
<label class="form-label">الدرس المستهدف</label>
<select id="checkpoint_lesson_select" class="input-text">
<option value="1">الدرس 1: قواعد الاشتقاق الأساسية</option>
<option value="2">الدرس 2: مشتقات الاقترانات المثلثية</option>
</select>
</div>
<div class="form-group">
<label class="form-label">توقيت ظهور السؤال (دقيقة:ثانية)</label>
<input type="text" id="checkpoint_timestamp" value="00:15" placeholder="00:15" class="input-text" style="color: var(--accent-cyan); font-family: monospace;">
</div>
<div class="form-group">
<label class="form-label">عقوبة الإرجاع عند الخطأ</label>
<select id="checkpoint_rewind_select" class="input-text">
<option value="45">إرجاع الطالب 45 ثانية للخلف (موصى به)</option>
<option value="60">إرجاع الطالب 60 ثانية</option>
<option value="30">إرجاع الطالب 30 ثانية</option>
</select>
</div>
</div>
<div class="form-group" style="margin-top: 8px;">
<label class="form-label">نص السؤال السقراطي الفوري</label>
<input type="text" id="checkpoint_question_input" value="إذا كان f(x) = sin(3x)، فما هي قيمة المشتقة f'(x)؟" placeholder="اكتب نص السؤال لفحص فهم الفكرة..." class="input-text">
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 12px;">
<div class="form-group">
<label class="form-label">الخيار (أ)</label>
<input type="text" id="cp_opt_0" value="3 cos(3x)" class="input-text">
</div>
<div class="form-group">
<label class="form-label">الخيار (ب)</label>
<input type="text" id="cp_opt_1" value="cos(3x)" class="input-text">
</div>
<div class="form-group">
<label class="form-label">الخيار (ج)</label>
<input type="text" id="cp_opt_2" value="-3 cos(3x)" class="input-text">
</div>
<div class="form-group">
<label class="form-label">الخيار (د)</label>
<input type="text" id="cp_opt_3" value="3 sin(3x)" class="input-text">
</div>
</div>
<div style="display: flex; align-items: center; justify-content: space-between; margin-top: 14px; flex-wrap: wrap; gap: 12px;">
<div class="form-group" style="margin: 0; min-width: 220px;">
<label class="form-label">الإجابة الصحيحة المعتمدة</label>
<select id="cp_correct_idx" class="input-text" style="color: var(--accent-gold); font-weight: 700;">
<option value="0">الخيار (أ) هو الصحيح ✓</option>
<option value="1">الخيار (ب) هو الصحيح ✓</option>
<option value="2">الخيار (ج) هو الصحيح ✓</option>
<option value="3">الخيار (د) هو الصحيح ✓</option>
</select>
</div>
<button type="button" id="btn_save_checkpoint" onclick="handleSaveCheckpoint()" class="btn-primary" style="width: auto; padding: 12px 32px; font-size: 13px;">تثبيت النقطة في محرك التثبيت المعرفي ✓</button>
<!-- AUTONOMOUS AI BANNER -->
<div style="background: rgba(0, 245, 212, 0.05); border: 1px solid rgba(0, 245, 212, 0.2); border-radius: 18px; padding: 20px; display: flex; align-items: center; gap: 16px;">
<div style="font-size: 32px;">🧠</div>
<div>
<h4 style="font-size: 14px; font-weight: 800; color: var(--accent-cyan); margin-bottom: 2px;">المعالجة السقراطية الذكية تعمل تلقائياً 100%</h4>
<p style="font-size: 12px; color: var(--text-muted); line-height: 1.6; margin: 0;">
لا داعي لأي جهد يدوي من المعلم. فور رفعك للملف، يطابق النظام نصوص المنهاج الوزاري، ويولد الفهرس الزمني للأفكار ونقاط الفحص السقراطي اللحظي، وتظهر فوراً للطالب في المشغل التفاعلي.
</p>
</div>
</div>
</div>