/home/techb158/workloadmatch.com/api/routes
NameSizeModeActions
ai_generate.php116420644editdlrm
assignments.php99310644editdlrm
auth.php66970644editdlrm
chat.php99340644editdlrm
courses.php72250644editdlrm
coursesessions.php67050644editdlrm
dashboard.php62320644editdlrm
groups.php110990644editdlrm
logs.php35870644editdlrm
managers.php96120644editdlrm
masters.php66850644editdlrm
notifications.php59750644editdlrm
preferences.php64870644editdlrm
programs.php48820644editdlrm
reports.php136960644editdlrm
roles.php85160644editdlrm
schedules.php110420644editdlrm
settings.php42950644editdlrm
teachers.php160130644editdlrm
timeslots.php48070644editdlrm
Edit: /home/techb158/workloadmatch.com/api/routes/ai_generate.php (11642B)
$p, 'display' => ProviderFactory::getProviderDisplayName($p), 'configured' => $configured, ]; } Response::success($providers); } function getProgramGroups(int $programId, mysqli $mysqli): void { require_once __DIR__ . '/../../Manager/Inc/BatchScheduler.php'; $batch = new BatchScheduler($mysqli); $groups = $batch->getGroupsForProgram($programId); Response::success($groups); } function getCalendarEvents(int $groupId, mysqli $mysqli): void { $events = []; $stmt = $mysqli->prepare(" SELECT scfg.Schedule_ID, scfg.Course_ID, c.Course_Name, scfg.Start_Date, scfg.End_Date, scfg.Time_Slot, scfg.Start_Time, scfg.End_Time, g.Group_Name FROM schedule_course_for_group scfg JOIN Courses c ON scfg.Course_ID = c.Course_ID JOIN manager_group_name g ON scfg.Group_ID = g.Group_ID WHERE scfg.Group_ID = ? ORDER BY scfg.Start_Date "); $stmt->bind_param('i', $groupId); $stmt->execute(); $rows = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); $stmt->close(); $lastSessionPerCourse = []; foreach ($rows as $r) { $lastSessionPerCourse[$r['Course_ID']] = $r['Schedule_ID']; } foreach ($rows as $r) { $isExam = $lastSessionPerCourse[$r['Course_ID']] === $r['Schedule_ID']; $events[] = [ 'id' => $r['Schedule_ID'], 'schedule_id' => $r['Schedule_ID'], 'title' => $r['Course_Name'] . ($isExam ? ' (Exam)' : '') . ' - ' . $r['Group_Name'], 'start' => $r['Start_Date'], 'end' => $r['End_Date'], 'allDay' => true, 'type' => $isExam ? 'exam' : 'class', 'color' => $isExam ? '#f56954' : '#00a65a', 'course_id' => $r['Course_ID'], 'course_name' => $r['Course_Name'], 'time_slot' => $r['Time_Slot'], 'group_name' => $r['Group_Name'], ]; } $res = $mysqli->query("SELECT Event_Start, Event_End, Event_Title FROM Events WHERE Calendar_Year = YEAR(CURDATE())"); while ($r = $res->fetch_assoc()) { $events[] = [ 'id' => 'holiday-' . $r['Event_Start'], 'title' => 'Holiday: ' . ($r['Event_Title'] ?? $r['Event_Name'] ?? ''), 'start' => $r['Event_Start'], 'end' => $r['Event_End'], 'allDay' => true, 'type' => 'holiday', 'color' => '#f39c12', 'editable' => false, ]; } Response::success($events); } function saveCalendarChanges(?array $body, mysqli $mysqli): void { Auth::requireAnyRole(['master_profile', 'manager_profile']); $changes = $body['changes'] ?? []; if (empty($changes)) { Response::error('No changes provided'); return; } $updated = 0; foreach ($changes as $c) { $scheduleId = (int)($c['schedule_id'] ?? 0); $newDate = $c['new_date'] ?? ''; if (!$scheduleId || !$newDate) continue; $stmt = $mysqli->prepare("UPDATE schedule_course_for_group SET Start_Date = ?, End_Date = ? WHERE Schedule_ID = ?"); $stmt->bind_param('ssi', $newDate, $newDate, $scheduleId); if ($stmt->execute() && $stmt->affected_rows > 0) { $updated++; } $stmt->close(); $stmt2 = $mysqli->prepare("UPDATE course_group_schedule_main SET Start_Date = ?, End_Date = ? WHERE Schedule_ID = ?"); $stmt2->bind_param('ssi', $newDate, $newDate, $scheduleId); $stmt2->execute(); $stmt2->close(); } Response::success(['updated' => $updated], "Updated $updated schedule entries"); } function getAnalytics(int $programId, mysqli $mysqli): void { require_once __DIR__ . '/../../Manager/Inc/ScheduleAnalytics.php'; $analytics = new ScheduleAnalytics($mysqli); $summary = $programId ? $analytics->getProgramSummary($programId) : []; $workload = $analytics->getTeacherWorkload($programId); $monthly = $programId ? $analytics->getMonthlyDistribution($programId, date('Y')) : []; $gaps = $analytics->getScheduleGaps($programId); Response::success([ 'summary' => $summary, 'workload' => $workload, 'monthly' => $monthly, 'gaps' => $gaps, ]); } function generateAiSchedule(?array $body, mysqli $mysqli): void { Auth::requireAnyRole(['master_profile', 'manager_profile', 'admin_profile']); $programId = (int)($body['program_id'] ?? 0); $groupId = (int)($body['group_id'] ?? 0); $startDate = $body['start_date'] ?? ''; $endDate = $body['end_date'] ?? null; $selectedCourses = $body['selected_courses'] ?? []; $priorityCourses = $body['priority_courses'] ?? []; $provider = $body['provider'] ?? null; $useAi = $body['use_ai'] ?? true; $saveToDb = $body['save'] ?? false; if (!$programId || !$groupId || !$startDate || empty($selectedCourses)) { Response::validationError(['program_id', 'group_id', 'start_date', 'selected_courses' => 'Required']); return; } require_once __DIR__ . '/../../Manager/Inc/CombinedScheduler.php'; require_once __DIR__ . '/../../Manager/Inc/LLMProviders/ProviderFactory.php'; $scheduler = new CombinedScheduler($mysqli); if ($useAi && $provider) { switch ($provider) { case 'openai': $apiKey = getenv('OPENAI_API_KEY'); break; case 'gemini': $apiKey = getenv('GEMINI_API_KEY'); break; case 'claude': $apiKey = getenv('CLAUDE_API_KEY'); break; default: $apiKey = null; } if ($apiKey) { $llmProvider = ProviderFactory::create($provider, $apiKey); $scheduler->setProvider($llmProvider); } } elseif ($useAi) { try { $llmProvider = ProviderFactory::createFromEnv(); $scheduler->setProvider($llmProvider); } catch (Throwable $e) { error_log("AI provider not configured, using deterministic: " . $e->getMessage()); } } try { $result = $scheduler->generateAndAssign( $programId, $groupId, $startDate, $endDate, $selectedCourses, $priorityCourses, $saveToDb, $useAi ); $scheduleResult = $result['schedule_result']; $responseData = [ 'ai_generated' => $scheduleResult['ai_generated'] ?? false, 'provider_used' => $provider ?? 'auto', 'schedule_entries' => count($scheduleResult['schedule'] ?? []), 'schedule' => $scheduleResult['schedule'] ?? [], 'saved_entries' => $result['saved_entries'] ?? [], 'assignment_results' => $result['assignment_results'] ?? [], ]; if (isset($scheduleResult['ai_reasoning'])) { $responseData['ai_reasoning'] = $scheduleResult['ai_reasoning']; } Response::success($responseData, $saveToDb ? 'Schedule generated, saved, and teachers assigned' : 'Schedule generated (not saved)'); } catch (Throwable $e) { Response::error('Generation failed: ' . $e->getMessage(), 500); } } function generateBatchSchedule(?array $body, mysqli $mysqli): void { Auth::requireAnyRole(['master_profile', 'manager_profile', 'admin_profile']); $programId = (int)($body['program_id'] ?? 0); $groupIds = $body['group_ids'] ?? []; $startDate = $body['start_date'] ?? ''; $endDate = $body['end_date'] ?? null; $saveToDb = $body['save'] ?? false; $useAi = $body['use_ai'] ?? true; $provider = $body['provider'] ?? null; if (!$programId || empty($groupIds) || !$startDate) { Response::validationError(['program_id', 'group_ids', 'start_date' => 'Required']); return; } require_once __DIR__ . '/../../Manager/Inc/BatchScheduler.php'; require_once __DIR__ . '/../../Manager/Inc/LLMProviders/ProviderFactory.php'; $batch = new BatchScheduler($mysqli); if ($useAi && $provider) { switch ($provider) { case 'openai': $apiKey = getenv('OPENAI_API_KEY'); break; case 'gemini': $apiKey = getenv('GEMINI_API_KEY'); break; case 'claude': $apiKey = getenv('CLAUDE_API_KEY'); break; default: $apiKey = null; } if ($apiKey) { $llmProvider = ProviderFactory::create($provider, $apiKey); $batch->setProvider($llmProvider); } } elseif ($useAi) { try { $batch->setProvider(ProviderFactory::createFromEnv()); } catch (Throwable $e) { error_log("Batch: AI provider not configured: " . $e->getMessage()); } } try { $result = $batch->generateAll($programId, $groupIds, $startDate, $endDate, $saveToDb, $useAi); Response::success($result, "Batch generation completed"); } catch (Throwable $e) { Response::error('Batch generation failed: ' . $e->getMessage(), 500); } }