Add free-type spell checker for students
Build and Push Docker Image / build-and-push (push) Successful in 1m5s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-19 17:01:02 -04:00
1 parent 91fe38c00d
commit a2fb3b056a
5 files changed
+106 -2

No files matched your search

+12
View File
@@ -7,6 +7,8 @@ import { readFile, writeFile, unlink } from 'node:fs/promises';
import { createHash, createHmac, randomUUID } from 'node:crypto';
import mammoth from 'mammoth';
import multer from 'multer';
import nspell from 'nspell';
import dictionaryEn from 'dictionary-en';
import { db, sha256 } from './db.js';
const ROOT = dirname(fileURLToPath(import.meta.url));
@@ -435,6 +437,16 @@ app.get('/api/state/:studentId', (req, res) => {
res.json({ student: { ...student, isBirthdayWeek: isBirthdayWeek(student.birthday) }, assignment, listProgress });
});
// Free-type spell check: any word, checked against a bundled English dictionary
const speller = nspell(dictionaryEn);
app.get('/api/spellcheck', (req, res) => {
const word = String(req.query.word || '').trim();
if (!/^[A-Za-z'’-]{1,60}$/.test(word)) return res.status(400).json({ error: 'Type a single word using letters only.' });
const clean = word.replace(/’/g, "'");
const correct = speller.correct(clean) || speller.correct(clean.toLowerCase());
res.json({ word, correct, suggestions: correct ? [] : speller.suggest(clean).slice(0, 4) });
});
// Build a practice session: the target list's unmastered words only.
// listId overrides the student's pinned weekly assignment (used when launched from a course item).
app.get('/api/session/:studentId', (req, res) => {