From 9e195b79e0e53a9f1ef2365fd56a75de1b5b1f75 Mon Sep 17 00:00:00 2001 From: John Mizerek Date: Thu, 15 Jan 2026 15:29:15 -0800 Subject: [PATCH] Add conversational modifier assignment for uncertain modifiers Backend (analyzeMenuImages.cfm): - Updated AI prompts to classify modifiers by confidence level - Added appliesTo field: 'category', 'item', or 'uncertain' - Added categoryName field for category-level modifiers - Auto-assign category-level modifiers to items in that category - Only assign item-level modifiers when clearly in item description - Mark uncertain modifiers for user confirmation Frontend (setup-wizard.html): - Added showUncertainModifiersStep() between modifier and item steps - Shows conversational prompts for each uncertain modifier - Users can select which categories each modifier applies to - Users can skip modifiers that don't apply automatically - Applies user selections to items before proceeding - Added CSS styling for category selection checkboxes Flow: 1. AI extracts modifiers with confidence classification 2. Category-level modifiers auto-assigned to items 3. Uncertain modifiers presented one-by-one for user decision 4. User confirms or skips each uncertain modifier 5. Assignments applied to items before save Co-Authored-By: Claude Sonnet 4.5 --- api/setup/analyzeMenuImages.cfm | 42 ++++++++++- portal/setup-wizard.html | 130 +++++++++++++++++++++++++++++++- 2 files changed, 169 insertions(+), 3 deletions(-) diff --git a/api/setup/analyzeMenuImages.cfm b/api/setup/analyzeMenuImages.cfm index 7a0525c..66782d0 100644 --- a/api/setup/analyzeMenuImages.cfm +++ b/api/setup/analyzeMenuImages.cfm @@ -94,7 +94,7 @@ - + @@ -108,7 +108,7 @@ - + @@ -233,6 +233,10 @@ + + + + @@ -302,6 +306,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/portal/setup-wizard.html b/portal/setup-wizard.html index 3d8286e..a56bc13 100644 --- a/portal/setup-wizard.html +++ b/portal/setup-wizard.html @@ -335,6 +335,33 @@ margin-left: 4px; } + /* Category Selection */ + .category-option { + display: flex; + align-items: center; + gap: 8px; + padding: 12px; + background: #fff; + border: 1px solid var(--gray-200); + border-radius: 6px; + cursor: pointer; + transition: all 0.2s; + } + + .category-option:hover { + border-color: var(--primary); + background: rgba(99, 102, 241, 0.05); + } + + .category-option input[type="checkbox"] { + cursor: pointer; + } + + .category-option span { + font-size: 14px; + color: var(--gray-700); + } + /* Action Buttons */ .action-buttons { display: flex; @@ -1453,7 +1480,108 @@ }); config.extractedData.modifiers = updatedModifiers; - showItemsStep(); + + // Check if there are uncertain modifiers that need category assignment + showUncertainModifiersStep(); + } + + // New step: Handle uncertain modifier assignments + function showUncertainModifiersStep() { + const modifiers = config.extractedData.modifiers || []; + const categories = config.extractedData.categories || []; + + // Find modifiers marked as "uncertain" + const uncertainModifiers = modifiers.filter(mod => + mod.appliesTo === 'uncertain' + ); + + if (uncertainModifiers.length === 0 || categories.length === 0) { + // No uncertain modifiers or no categories, skip to items + showItemsStep(); + return; + } + + // Initialize uncertain modifier assignment tracking + if (!config.uncertainModifierAssignments) { + config.uncertainModifierAssignments = {}; + config.currentUncertainModIndex = 0; + } + + const currentIndex = config.currentUncertainModIndex; + + if (currentIndex >= uncertainModifiers.length) { + // All uncertain modifiers have been processed, apply assignments and continue + applyUncertainModifierAssignments(); + showItemsStep(); + return; + } + + const modifier = uncertainModifiers[currentIndex]; + + // Ask user about this modifier + const categoryOptions = categories.map((cat, i) => ` + + `).join(''); + + addMessage('ai', ` +

I found the modifier template "${modifier.name}" but I'm not sure which items it applies to.

+

Select the categories where this modifier should be applied, or skip if it doesn't apply automatically:

+
+ ${categoryOptions} +
+
+ + +
+ `); + } + + function skipUncertainModifier() { + config.currentUncertainModIndex++; + showUncertainModifiersStep(); + } + + function assignUncertainModifier(modifierName) { + const checkboxes = document.querySelectorAll('input[name="category-assign"]:checked'); + const selectedCategories = Array.from(checkboxes).map(cb => cb.value); + + if (selectedCategories.length > 0) { + config.uncertainModifierAssignments[modifierName] = selectedCategories; + } + + config.currentUncertainModIndex++; + showUncertainModifiersStep(); + } + + function applyUncertainModifierAssignments() { + // Apply the user's category selections to items + const items = config.extractedData.items || []; + const modifiers = config.extractedData.modifiers || []; + + for (const [modifierName, categories] of Object.entries(config.uncertainModifierAssignments)) { + items.forEach(item => { + if (!item.modifiers) { + item.modifiers = []; + } + + // If this item is in one of the selected categories, add the modifier + if (categories.includes(item.category)) { + if (!item.modifiers.includes(modifierName)) { + item.modifiers.push(modifierName); + } + } + }); + + // Update the modifier's appliesTo field to reflect the assignment + const modifier = modifiers.find(m => m.name === modifierName); + if (modifier) { + modifier.appliesTo = 'category'; + modifier.categoryNames = categories; // Store all assigned categories + } + } } // Step 4: Items