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()) {