Previously each extraction step cleared the conversation and only showed
the latest result. Now completed menus accumulate as checkmarked lines
while the spinner updates in place for the current extraction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New users without an existing menu to import can now click "Start from Scratch"
to enter their business info and get redirected to the Menu Builder.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pass platform URLs from discovery to extraction phase
- Call platform_images mode with stealth Playwright
- Fuzzy match platform images to extracted items by name
- Show progress during image fetching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- showItemsStep rendered per-category index as data-item-id
- confirmItems filtered by global index, causing massive mismatch
- Now assigns unique 'item_N' IDs to all items before rendering
- Also preserves menuName in category confirmation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add console.log to showFinalStep for menus debugging
- Preserve menuName property when rebuilding categories in confirmCategories
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Store schedule per menu from Claude extraction
- Show schedule in progress messages
- Compute combined business hours from all menu schedules
- Display schedule summary in final result
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Store businessInfo from discovery phase
- Pre-populate from JSON-LD/meta before sub-page extraction
- Only fill gaps from sub-page Claude responses
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Phase 1: Quick scan shows detected menu pages with checkboxes
- User confirms which pages are actual menus
- Phase 2: Each page extracted individually through Claude
- Shows progress for each page being processed
- Falls back to single-page extract if no sub-pages found
- Optional extra URL field for manual addition
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Handles "United States/USA" at end of address string that
was blocking ZIP and state regex extraction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the import detects multiple menus (Brunch, Lunch, Dinner, etc.),
shows checkboxes for each menu instead of a single menu name input.
Passes selectedMenus array to saveWizard for separate menu creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PHP API is now deployed on both dev and biz servers with PHP-FPM.
Admin endpoints (quickTasks, scheduledTasks) remain .cfm as they
haven't been ported yet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Another tab doing the PHP migration renamed all API endpoint references
from .cfm to .php, but the PHP endpoints aren't deployed yet. Reverted
all references back to .cfm so the wizard and portal work again.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Combined HTML from multiple sub-pages was too large. Now strips all HTML
tags and keeps only text content for Claude extraction. Also strips
nav/header/footer from sub-pages to remove duplication. Bumped Claude
API timeout from 120s to 300s. Updated wizard message to say 1-3 minutes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
parseHoursString expected a string but Claude AI sometimes returns
structured hours data as an object. Now normalizes to string first.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip common suffixes like "Order pickup and delivery" and embedded
street addresses from business names. Clean city field when it contains
state/zip/country (e.g. "Santa Monica, CA 90405, USA" → "Santa Monica").
Fixes applied in both CFML parser and JS frontend as safety net.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The JSON-LD fast path only got items/categories/prices but no modifiers.
Removing it lets Uber Eats pages fall through to Claude AI extraction
which handles modifiers like every other platform.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Warning to disable ad blockers before saving pages for import
- Listed supported platforms with what each extracts (Toast, Grubhub,
DoorDash, Uber Eats, and fallback AI extraction)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Parse JSON-LD structured menu data from saved Uber Eats pages
(categories, items, prices, descriptions, business info)
- Show save-and-upload instructions when user pastes Uber Eats URL
- Always show header image upload step (was skipped for URL imports)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- items.cfm: return BrandColorLight in menu response
- saveWizard.cfm: save BrandColorLight during business creation
- setup-wizard.html: second color picker for light brand color
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the conditional out of the nested template literal to avoid
parsing issues with arrow functions inside backtick strings. Also
skip empty mod-groups divs on items without modifiers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Outline button reveals modifier groups under each item with a +
expand button to drill into individual options and prices. Helps
debug imported menus before saving.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
For URL imports (Toast, Grubhub, etc.) there's no header image
to show, so skip straight from business info to categories
instead of showing an empty "Choose Image / Skip" prompt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows subcategory count as a separate indented row beneath categories
when subcategories are present.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changed from fixed 120px height to aspect-ratio 3:1 to match the
recommended 1200x400 dimensions, preventing heavy cropping.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- analyzeMenuUrl.cfm: Detect subcategories from Toast subgroups and
Claude API responses, preserve hierarchy with parentCategoryName
- setup-wizard.html: Display subcategories indented under parents
throughout wizard flow (categories step, items review, summary, preview)
- menu-builder.html: Show subcategories nested in outline modal view
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The escaped backticks (\`) were causing "invalid escape sequence" error,
breaking the entire script and making the Upload Files button non-functional.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When business info step loads with a ZIP code, automatically looks up
the combined sales tax rate and pre-fills the field. User can still
edit if needed. Field gets light green background to indicate auto-fill.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Items were being grouped only by known categories. If the category
array was empty or didn't include an item's category, those items
never got checkboxes rendered, causing confirmItems() to filter
them all out.
Now collects unassigned items and groups them by their category
name (or 'Menu' as fallback).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Log sample imageUrls to console to debug why upload step is shown.
Also handle protocol-relative URLs (//domain.com/...).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Items from Toast menus have CDN URLs (https://img.cdn4dd.com/...) which
saveWizard.cfm will download automatically. No need to prompt user
to upload images when remote URLs are already present.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- uploadSavedPage.cfm: sanitize extracted files (whitelist safe extensions,
delete symlinks) to protect against malicious content from infected sites
- analyzeMenuUrl.cfm: detect local temp URLs and read directly from disk,
bypassing Playwright for faster processing of saved pages
- saveWizard.cfm: delete temp folder immediately after wizard completes
instead of waiting for 1-hour auto-cleanup
- setup-wizard.html: track temp folder ID and pass to saveWizard for cleanup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For Cloudflare-protected sites, users can now:
1. Save the page from their browser (Webpage, Complete)
2. ZIP the HTML and assets folder
3. Upload the ZIP in the wizard
4. Server extracts to temp folder, Playwright scans local copy
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Backend now accepts either url or html content in request body
- Frontend adds HTML file upload option below URL input
- Useful when websites block the crawler (403 errors)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pass menuName in redirect URL from menu-builder
- Show menu name in wizard header and final review
- Skip hours validation in both JS and backend for add-menu mode
- Hide menu name, hours, and community meal fields in final step
- Add id to community meal card for toggling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a new menu is created in Manage Menus, the user is now redirected
to the setup wizard with businessId and menuId params. The wizard skips
business info/header steps and goes straight to photo upload + category
extraction. Backend uses the provided menuId instead of creating a new
menu. Also removes temp debug from menus.cfm.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move menu manager button to toolbar next to Save Menu for visibility
- Implement server-side photo upload for menu items
- Strip base64 data URLs from save payload to reduce size
- Add scheduled tasks, quick tasks, ratings, and task categories APIs
- Add vertical support and brand color features
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>