Огляд бекенду
Ця документація описує поточну логіку бекенду, реалізовану для TechTutor.
Стек
- Laravel 13
- PHP 8.3
- PostgreSQL 16
- Laravel Sanctum
Реалізована доменна модель
- User
- Course
- Module
- Lesson
- Enrollment
- Progress
- Quiz
- QuizAttempt
- Review
- Payment
- CourseCertificate
- PublishRequest
Поточні можливості
Ролі та доступ
- Поле ролі в користувача (
student,instructor,admin) - Перевірки з урахуванням ролей у бізнес-логіці та policy
- Sanctum middleware для захищених маршрутів
- Публічна реєстрація та логін видають Sanctum bearer token
- Доступні endpoint-и current-user, logout, resend verification, email verification, forgot-password і reset-password
- Заблоковані користувачі не можуть увійти та не мають доступу до захищених маршрутів
- Auth endpoint-и мають rate limit для зменшення brute-force атак
CAPTCHA_ENABLEDу backend.envє джерелом правди для того, чи вмикати CAPTCHA- Frontend читає
/api/app-config, щоб визначити, чи показувати CAPTCHA UI - Реєстрація, логін і запит email-коду для signup вимагають CAPTCHA лише коли
CAPTCHA_ENABLED=true - Нормалізація запитів видаляє HTML-теги та зайві пробіли в основних текстових полях перед валідацією
Нотатки з безпеки авторизації
- У production краще використовувати невидиму CAPTCHA або score-based CAPTCHA, щоб зберегти зручний логін/реєстрацію
- Для локальної розробки можна використовувати demo token лише тоді, коли CAPTCHA увімкнена, але site key ще не налаштований
localhostпідходить для локального тестування і пізніше може бути замінений у dashboard CAPTCHA-провайдера- Якщо CAPTCHA вимкнена, frontend повністю ховає CAPTCHA helper і не надсилає токен
Runtime app config
GET /api/app-configповертає runtime-параметри, які потрібні auth UI- Поточний payload містить
captcha_enabledіcaptcha_site_key - Це тримає frontend синхронізованим із backend
.envбез захардкожування security-поведінки у браузерному білді
Google OAuth автентифікація
TechTutor підтримує безшовний Google OAuth логін для студентів та існуючих користувачів.
Потік:
- Фронтенд ініціює OAuth, відкриваючи
/auth/google/redirect?return_to=<frontend_origin>у popup-вікні - Користувач проходить автентифікацію в Google і надає згоду на дані
- Бекенд обробляє callback через
/auth/google/callbackіз return URL, збереженим у сесії - У разі успіху: користувач створюється або оновлюється, верифікується та отримує Sanctum token
- Бекенд повертає auth payload через
window.postMessage()назад у popup фронтенду - Фронтенд дістає token і дані користувача, закриває popup і автентифікує сесію
Логіка створення/оновлення користувача:
- Нові користувачі: створюються з email від Google, випадковим непередбачуваним паролем (не показується користувачу), роллю
studentта автоматичною верифікацією- Якщо Google OAuth стане недоступним, можна використати "Forgot Password" для встановлення нового пароля
- Випадковий пароль підвищує безпеку: знаючи email, неможливо зайти без Google або reset password
- Існуючі користувачі: ім'я оновлюється, якщо воно порожнє; email автоматично верифікується через OAuth
- Заблоковані користувачі: відхиляються на етапі callback з повідомленням про помилку
- Email є унікальним ідентифікатором; той самий Google email завжди оновлює того ж користувача TechTutor
Керування сесією:
- OAuth return URL зберігається в
session['google_oauth_return_to']під час redirect-кроку - URL перевіряється через
resolveFrontendOrigin()для запобігання open redirect - Дані сесії очищуються після обробки callback
Структура курсів
- CRUD для Course
- CRUD для Module, вкладений у курс
- CRUD для Lesson, вкладений у модуль
- Прапори publish/draft і метадані на курсі та квізі
- Метадані каталогу курсів: subtitle, category, level, language, thumbnail path, duration
- Пошук, фільтрація, сортування, середній рейтинг, кількість відгуків і зарахувань з БД
- Індексація та full-text пошук каталогу курсів через MeiliSearch
Дашборд викладача
- Живий зведений дашборд для викладачів та адміністраторів
- Огляд керування курсами з кількістю опублікованих/чернеток
- Прогрес студентів по курсах на основі завершення уроків
- Агрегації за зарахуваннями, завершеннями, сертифікатами, балами квізів і доходом
- Окремі таблиці статистики дашборду не зберігаються
- Дохід наразі рахується за внутрішніми оплаченими платежами; можна уточнити після впровадження webhooks платіжного провайдера
Моніторинг адміністратора
- Живий монітор активності платформи для адміністраторів
- Підсумки по користувачах, курсах, зарахуваннях, сертифікатах, спробах квізів і модерації
- Розподіл статусів платежів і дохід по курсах для оплачених платежів
- Стрічка нещодавньої активності з наявних користувачів, курсів, зарахувань, платежів і сертифікатів
- Окремі таблиці статистики моніторингу не зберігаються
Навчальний потік студента
- Запис на курс
- Збереження прогресу уроку (0-100)
- Фіксація часу завершення при досягненні 100
- Ідемпотентна видача сертифіката курсу після завершення всіх уроків
- Видимість сертифікатів залежить від ролі: студенти бачать свої, викладачі - для своїх курсів, адміністратори - усі
- Email-сповіщення студенту при створенні зарахування та видачі сертифіката
Потік квізів
- CRUD для Quiz у межах курсу
- Питання single-choice і multiple-choice
- Спроби квізів у межах Quiz
- Розрахунок score на бекенді з надісланих відповідей
- Автоматичне визначення
passedза score і порогом проходження - Жива аналітика квізів для викладачів/адмінів з поточних attempts/questions
- Окремі таблиці статистики для аналітики квізів не зберігаються
- Email-сповіщення студенту після кожної завершеної спроби з балом/статусом
Сповіщення
- Email-сповіщення Laravel використовують mailer із
.env - Поточні тригери: верифікація реєстрації, reset password, нове зарахування, завершена спроба квізу, виданий сертифікат, оброблений адміністратором publish request
- У тестах канал сповіщень фейкується, тому SMTP-облікові дані не використовуються
Аудит валідації та санітизації вводу
- Auth-запити нормалізують email, token name і поля профілю до валідації
- Payload-и course, module, lesson, review, comment, quiz і payment нормалізують текстові поля перед збереженням
- Текст запитань та опцій квізу очищується від HTML і стискається до plain text
- URL-поля в checkout-запитах обрізаються перед використанням
- Мета: рано відхиляти некоректні дані та зменшувати ризик HTML-ін'єкцій
Комерція та спільнота
- Створення/оновлення/видалення відгуків
- Створення/перегляд платежів із provider, amount, currency, status
- Внутрішній purchase flow видає квитанції, ставить payment у paid, надає доступ до курсу і створює active enrollment
- Для paid-курсів зарахування вимагає наявного оплаченого платежу
- Створення Stripe Checkout сесії підключено для paid-курсів і зберігає pending Stripe payments
- Верифікація Stripe webhook перетворює оплачені Checkout Session у квитанції та активні зарахування
- Publish requests надсилають сповіщення викладачам при схваленні або відхиленні адміністратором
Тестові дані
Сідинг БД включає користувачів із ролями (пароль: password):
admin@techtutor.testbackend@techtutor.testfrontend@techtutor.testml@techtutor.testdevops@techtutor.teststudent@techtutor.teststudent2@techtutor.testbanned@techtutor.test
Покриття тестами
Поточні feature-тести покривають:
- Створення курсу, зарахування та прогрес уроків
- Реєстрацію, логін/логаут, верифікацію email і reset password
- Пошук/фільтрацію каталогу курсів і метадані
- Створення квізів та надсилання студентських спроб
- Перевірки тригерів email-сповіщень
- Потоки відгуків і purchase/payment
Запуск тестів:
bash
php artisan test