From 4ad687df73365b084115477774e0aada9d102c28 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Mon, 10 Nov 2025 10:25:43 -0600 Subject: [PATCH] fix(worksheets): validation function was converting mastery mode to manual MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRITICAL FIX: The validateWorksheetConfig() function only checked for mode === 'smart', causing mastery mode configs to fall through to the manual mode path. This meant: - Frontend sent mode: 'mastery' with displayRules - Validation function created a manual mode config instead - displayRules were lost, replaced with boolean flags - Ten-frames didn't render because flags defaulted to false Changes: - validation.ts: Check for both 'smart' OR 'mastery' when using displayRules - validation.ts: Preserve mode as 'smart' | 'mastery' instead of forcing 'smart' - validation.ts: Include currentStepId for mastery progression tracking - types.ts: Import and include AdditionConfigV4Mastery in WorksheetFormState type This was the third place mastery mode needed to be handled: 1. ✅ config-schemas.ts - Zod schema (added in previous commit) 2. ✅ typstGenerator.ts - Problem enrichment (added in previous commit) 3. ✅ validation.ts - Config validation (this commit) Tests: All 14 ten-frames tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- apps/web/.claude/settings.local.json | 4 +++- apps/web/src/app/create/worksheets/addition/types.ts | 12 ++++++------ .../src/app/create/worksheets/addition/validation.ts | 7 ++++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/web/.claude/settings.local.json b/apps/web/.claude/settings.local.json index 3713de7a..50f47a2a 100644 --- a/apps/web/.claude/settings.local.json +++ b/apps/web/.claude/settings.local.json @@ -36,7 +36,9 @@ "Bash(done)", "mcp__sqlite__list_tables", "mcp__sqlite__describe_table", - "Bash(npm test:*)" + "Bash(npm test:*)", + "mcp__sqlite__read_query", + "Bash(cat:*)" ], "deny": [], "ask": [] diff --git a/apps/web/src/app/create/worksheets/addition/types.ts b/apps/web/src/app/create/worksheets/addition/types.ts index 43831a63..c72a5bbb 100644 --- a/apps/web/src/app/create/worksheets/addition/types.ts +++ b/apps/web/src/app/create/worksheets/addition/types.ts @@ -4,6 +4,7 @@ import type { AdditionConfigV4, AdditionConfigV4Smart, AdditionConfigV4Manual, + AdditionConfigV4Mastery, } from '../config-schemas' /** @@ -42,26 +43,25 @@ export type WorksheetConfig = AdditionConfigV4 & { * Partial form state - user may be editing, fields optional * Based on V4 config with additional derived state * - * V4 supports two modes via discriminated union: + * V4 supports three modes via discriminated union: * - Smart mode: Has displayRules and optional difficultyProfile + * - Mastery mode: Has displayRules and optional currentStepId * - Manual mode: Has boolean display flags and optional manualPreset * * During editing, mode field may be present to indicate which mode is active. * If mode is absent, defaults to 'smart' mode. * * This type is intentionally permissive during form editing to allow fields from - * both modes to exist temporarily. Validation will enforce mode consistency. + * all modes to exist temporarily. Validation will enforce mode consistency. */ export type WorksheetFormState = Partial> & - Partial> & { + Partial> & + Partial> & { // DERIVED state (calculated from primary state) rows?: number total?: number date?: string seed?: number - - // Mastery progression mode - currentStepId?: string // Current step in progression path } /** diff --git a/apps/web/src/app/create/worksheets/addition/validation.ts b/apps/web/src/app/create/worksheets/addition/validation.ts index 8177865b..4152f156 100644 --- a/apps/web/src/app/create/worksheets/addition/validation.ts +++ b/apps/web/src/app/create/worksheets/addition/validation.ts @@ -138,8 +138,8 @@ export function validateWorksheetConfig(formState: WorksheetFormState): Validati // Build mode-specific config let config: WorksheetConfig - if (mode === 'smart') { - // Smart mode: Use displayRules for conditional scaffolding + if (mode === 'smart' || mode === 'mastery') { + // Smart & Mastery modes: Use displayRules for conditional scaffolding const displayRules: DisplayRules = { carryBoxes: 'whenRegrouping', answerBoxes: 'always', @@ -154,9 +154,10 @@ export function validateWorksheetConfig(formState: WorksheetFormState): Validati config = { version: 4, - mode: 'smart', + mode: mode as 'smart' | 'mastery', // Preserve the actual mode displayRules, difficultyProfile: formState.difficultyProfile, + currentStepId: formState.currentStepId, // Mastery progression tracking ...sharedFields, } } else {