Розробка системи перевірки домашніх завдань (ручна/автоматична) для LMS

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка системи перевірки домашніх завдань (ручна/автоматична) для LMS
Середня
~5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розроблення системи рецензування домашніх завдань у LMS

Система рецензування домашніх завдань розширює оцінювання з peer-review, багатокроковим робочим потоком (відправлення учня → рецензія однолітків → рецензія викладача), детальним зворотним зв'язком на основі рубрики та історією розробок. Підтримує як синхронні рецензії викладача, так і асинхронні відгуки однолітків.

Робочий процес відправлення та рецензування

interface Submission {
  id: string;
  assignmentId: string;
  userId: string;
  content: string;
  files: Array<{ url: string }>;
  submittedAt: Date;
  status: 'draft' | 'submitted' | 'in_review' | 'approved' | 'needs_revision';
  revisionCount: number;
}

interface Review {
  id: string;
  submissionId: string;
  reviewerId: string;
  type: 'peer' | 'instructor';
  rubricScores: Record<string, number>;
  overallFeedback: string;
  comments: Array<{ line: number; text: string }>;
  createdAt: Date;
  approved: boolean;
}

Призначення peer-review

app.post('/api/assignments/:assignmentId/assign-peer-reviews', authenticate, async (req, res) => {
  const assignment = await db.assignments.findById(req.params.assignmentId);
  const submissions = await db.submissions.findByAssignment(req.params.assignmentId);

  const reviewsPerSubmission = 2;  // Кожен учень отримує 2 peer-review

  for (const submission of submissions) {
    const otherSubmissions = submissions.filter(s => s.userId !== submission.userId);
    const randomReviewers = otherSubmissions
      .sort(() => Math.random() - 0.5)
      .slice(0, reviewsPerSubmission);

    for (const reviewer of randomReviewers) {
      await db.peerReviews.create({
        submissionId: submission.id,
        reviewerId: reviewer.userId,
        assignmentId: req.params.assignmentId,
        status: 'pending',
      });
    }
  }

  res.json({ ok: true });
});

// Отримати призначені peer-reviews
app.get('/api/my-peer-reviews', authenticate, async (req, res) => {
  const reviews = await db.peerReviews.findByReviewer(req.user.id);
  const populated = await Promise.all(
    reviews.map(async (r) => ({
      ...r,
      submission: await db.submissions.findById(r.submissionId),
      assignment: await db.assignments.findById(r.assignmentId),
    }))
  );
  res.json(populated);
});

Вбудовані коментарі та зворотний зв'язок

function SubmissionReview({ submission, reviewRubric, onSave }) {
  const [lineComments, setLineComments] = useState<Map<number, string>>(new Map());
  const [rubricScores, setRubricScores] = useState<Record<string, number>>({});
  const [overallFeedback, setOverallFeedback] = useState('');
  const lines = submission.content.split('\n');

  const handleAddComment = (lineNum: number, text: string) => {
    setLineComments(new Map(lineComments).set(lineNum, text));
  };

  const handleSave = async () => {
    await fetch(`/api/submissions/${submission.id}/review`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        rubricScores,
        lineComments: Array.from(lineComments.entries()).map(([line, text]) => ({
          line, text,
        })),
        overallFeedback,
      }),
    });
    onSave?.();
  };

  return (
    <div className="max-w-4xl mx-auto p-6 space-y-6">
      <div className="bg-gray-100 p-4 rounded-lg space-y-2 font-mono text-sm">
        {lines.map((line, i) => (
          <div key={i} className="relative group flex gap-2">
            <span className="text-gray-500 w-8 text-right">{i + 1}</span>
            <span className="flex-1">{line}</span>
            <button
              onClick={() => {
                const comment = prompt('Додати коментар');
                if (comment) handleAddComment(i, comment);
              }}
              className="opacity-0 group-hover:opacity-100 text-xs text-blue-600 hover:underline"
            >
              Коментар
            </button>
            {lineComments.has(i) && (
              <div className="absolute left-0 top-full mt-1 bg-yellow-100 p-2 rounded text-xs">
                {lineComments.get(i)}
              </div>
            )}
          </div>
        ))}
      </div>

      <div>
        <h3 className="font-semibold mb-4">Оцінка за рубрикою</h3>
        {reviewRubric.map((criterion) => (
          <div key={criterion.id} className="mb-3">
            <label className="text-sm">{criterion.name}</label>
            <select
              value={rubricScores[criterion.id] || 0}
              onChange={(e) => setRubricScores({
                ...rubricScores,
                [criterion.id]: Number(e.target.value),
              })}
              className="border rounded px-2 py-1"
            >
              {[...Array(criterion.points + 1)].map((_, i) => (
                <option key={i} value={i}>{i}/{criterion.points}</option>
              ))}
            </select>
          </div>
        ))}
      </div>

      <div>
        <label className="block text-sm font-medium mb-2">Загальний зворотний зв'язок</label>
        <textarea
          value={overallFeedback}
          onChange={(e) => setOverallFeedback(e.target.value)}
          rows={6}
          className="w-full border rounded px-3 py-2"
          placeholder="Надайте конструктивний зворотний зв'язок..."
        />
      </div>

      <button
        onClick={handleSave}
        className="w-full bg-green-600 text-white rounded-lg py-2 font-medium"
      >
        Відправити рецензію
      </button>
    </div>
  );
}

Строки виконання

Базова система peer-review з оцінками рубрики — 1.5 тижня. З вбудованими коментарями, отслідюванням розробок та багатокроковим робочим потоком — 2.5–3 тижні.