fix(ctmath): чистка банка — год-пачки убраны из пикера пробников
- exam-prep.js: MOCK_VARIANT_RANGE — для ctmath показываем как пробники только чистые 30-задачные варианты [101;1999]; год-пачки (variant=год 2011-2024 и 0, до 114 задач) остаются пулом для тренажёра по темам, но скрыты из пикера/mock-start/просмотра вариантов. math9 (1..80) не затронут (диапазон только для ctmath). - mock.js: пикер «По варианту» — выпадающий список реальных вариантов (через listVariants) вместо number-input 1..N; раньше для ctmath он предлагал 1..18 и не доходил до 101 → пробник по варианту не запускался. - cleanup_ctmath_bank.js: идемпотентный скрипт — ретайр битого id=1419 (mc с противоречивым ответом → long), variants_count → 3 (чистых вариантов). - seed_*: variants_count считается по диапазону [101;1999] (консистентно с роутом). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,21 @@ router.param('examKey', (req, res, next, examKey) => {
|
||||
next();
|
||||
});
|
||||
|
||||
/* ── Mock/variant picker: какие variant считаются «пробниками» ──────
|
||||
ctmath: год-пачки (variant=год 2011–2024 и 0) — это тематический ПУЛ для
|
||||
тренажёра по темам, а НЕ чистые 30-задачные варианты (у части до 114 задач).
|
||||
Чистые варианты-пробники нумеруются 3-значно (101, 102, …), а год-пачки —
|
||||
4-значными годами (≥2011) и 0, поэтому фильтр — ДИАПАЗОН [101;1999], а не
|
||||
просто порог (год 2024 > 101 и иначе бы прошёл!). В пикере пробников,
|
||||
mock/start и просмотре вариантов показываем только чистые. Тренажёр по темам
|
||||
отбирает по subtopic и этот фильтр НЕ использует — пул задач не теряется.
|
||||
Для остальных треков (math9: варианты 1..80) диапазона нет — показываются все. */
|
||||
const MOCK_VARIANT_RANGE = { ctmath: [101, 1999] };
|
||||
const isMockVariant = (examKey, v) => {
|
||||
const r = MOCK_VARIANT_RANGE[examKey];
|
||||
return r ? (v >= r[0] && v <= r[1]) : (v >= 1);
|
||||
};
|
||||
|
||||
/* ── Statements (prepared once) ────────────────────────────────── */
|
||||
const SQL = {
|
||||
listTracks: db.prepare(`
|
||||
@@ -478,7 +493,7 @@ router.get('/:examKey/info', (req, res) => {
|
||||
router.get('/:examKey/variants', (req, res) => {
|
||||
const { examKey } = req.params;
|
||||
if (!SQL.getTrack.get(examKey)) return res.status(404).json({ error: 'Unknown exam track' });
|
||||
const rows = SQL.listVariants.all(req.user.id, examKey);
|
||||
const rows = SQL.listVariants.all(req.user.id, examKey).filter(r => isMockVariant(examKey, r.variant));
|
||||
const variants = rows.map(r => ({
|
||||
n: r.variant,
|
||||
label: `Вариант ${r.variant}`,
|
||||
@@ -498,6 +513,7 @@ router.get('/:examKey/variants/:n/tasks', (req, res) => {
|
||||
const { examKey } = req.params;
|
||||
const n = parseInt(req.params.n, 10);
|
||||
if (!Number.isFinite(n) || n < 1) return res.status(400).json({ error: 'Bad variant number' });
|
||||
if (!isMockVariant(examKey, n)) return res.status(404).json({ error: 'Variant not found or empty' });
|
||||
|
||||
const rows = SQL.getVariantTasks.all(examKey, n);
|
||||
if (!rows.length) return res.status(404).json({ error: 'Variant not found or empty' });
|
||||
@@ -1180,7 +1196,7 @@ router.post('/:examKey/mock/start', (req, res) => {
|
||||
|
||||
if (source === 'variant') {
|
||||
variant = Number(req.body?.variant);
|
||||
if (!Number.isInteger(variant) || variant < 1) {
|
||||
if (!Number.isInteger(variant) || !isMockVariant(examKey, variant)) {
|
||||
return res.status(400).json({ error: 'Variant number required' });
|
||||
}
|
||||
const rows = SQL.getTasksByVariant.all(examKey, variant);
|
||||
|
||||
Reference in New Issue
Block a user