- Store headerImageUrl from discovery response
- Show preview of discovered header in header image step
- Download header via server-side downloadImages.php when no file uploaded
- Remove outdated Lucee comment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use getElementById for progressDiv/spinnerDiv inside an addMessage bubble
so completed lines persist as each menu finishes extracting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
PHP returns prices as strings (e.g. "0.000000000"). Wrap in parseFloat()
before calling .toFixed(2) to prevent render crash.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The unified schema query used INNER JOIN to children, which excluded
categories with no items. Changed to direct query with NOT EXISTS
template filter so empty categories persist after save+reload.
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>
Playwright now follows menu sub-page links (brunch, lunch, dinner, etc.)
AND detects ordering platform links (order.online, toasttab, grubhub, etc.)
on restaurant websites. Visits ordering pages to scrape item-image pairs,
then fuzzy-matches them to menu items extracted from the main site.
This gives us complete menus from the restaurant's own website plus
food photos from their ordering platform — best of both worlds.
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>
Feature cancelled — modifier wording handles the use case instead.
Removes IsInvertedGroup from SELECTs, JSON responses, RemovedDefaults
computation, and KDS/portal display logic. DB column left in place.
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>
Modifiers and remarks are now collapsed by default with a count badge.
Tap to expand/collapse. Matches the Works Android behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Removed IsInvertedGroup toggle and badge from menu builder UI
- Fixed saveFromBuilder.cfm not updating Name for template modifiers
(only selection rules were saved, name changes were silently lost)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
attachDefaultChildren now detects IsInvertedGroup=1 on parent items
and skips auto-adding defaults. The Android client explicitly sends
only the modifiers the user kept checked, so auto-adding was
re-inserting items the user had unchecked (e.g., Mustard).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The inverted group header item isn't always an order line item itself,
so RemovedDefaults was never computed. Now detects inverted groups
via children's ParentIsInvertedGroup flag and attaches RemovedDefaults
to the first child as a proxy. KDS JS handles both patterns.
Also skips showing default modifiers from inverted groups since those
are represented by "NO removed-item" instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Was filtering out IsCheckedByDefault modifiers, which hid all
toppings/options on orders where the customer kept the defaults
(e.g. Bay Cities sandwiches). Inverted groups still handled
separately with "NO" prefix for removed defaults.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
23 businesses were being cut to 20 when sorted alphabetically (no location),
hiding Win~Dow Venice and other names near end of alphabet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pickup and Delivery had colored badges but Dine-In did not. Added
blue DINE-IN badge matching the existing badge style.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Items with NULL StationID now appear in all station views instead of
being hidden when a specific station is selected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
KDS was keeping the station filter from a previous business in
localStorage, causing orders to be hidden when switching businesses.
Now tracks businessId and resets station selection on change.
New businesses also get a default "Kitchen" station so the KDS works
out of the box.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Grand total now always shows the actual order amount. Balance and
payment method shown as informational lines underneath instead of
subtracting balance from the total.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Receipt was treating balance-only orders as card payments, adding
Stripe processing fees that inflated the total. Now checks
PaymentFromCreditCard to determine if card fees apply. Also adds
tip line and includes TipAmount in total calculation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JS new Date() was parsing dates without Z as local time, showing UTC
values as-is. Adding Z suffix tells JS the dates are UTC so it converts
to the user's local timezone automatically.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Application.cfm requires request.BusinessID from session or header.
The fetch was only sending it in the POST body which the auth layer
doesn't read.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- showToast → toast (correct method name) across all settings methods
- Clear onchange before setting .checked to prevent save during load
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>