- Brand color: add # prefix when loading from DB (stored without #,
CSS needs it for backgroundColor)
- Header upload: delete destination file before rename to prevent
collision when re-uploading same extension
- Header preview: prepend BASE_PATH to image URL for local dev
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace default password login with email-based OTP flow. User enters
email, receives 6-digit code, enters it to log in. Password login
retained as fallback via link. On dev, magic OTP code is shown directly
for easy testing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- tasks/accept.cfm: WHERE TaskID → WHERE ID
- tasks/completeChat.cfm: WHERE TaskID → WHERE ID
- tasks/expireStaleChats.cfm: WHERE TaskID → WHERE ID
- cron/expireStaleChats.cfm: WHERE TaskID → WHERE ID
- chat/closeChat.cfm: WHERE TaskID → WHERE ID
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- uploadHeader.cfm: WHERE BusinessID → WHERE ID (Businesses table PK)
- onboard.cfm: WHERE BusinessID → WHERE ID, BusinessStripeOnboardingStarted → StripeOnboardingStarted
- createPaymentIntent.cfm: WHERE BusinessID → WHERE ID, OrderDeliveryFee → DeliveryFee, WHERE OrderID → WHERE ID
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Only quickTasks/ and scheduledTasks/ subdirectories remain tracked
since those are actively used by the portal.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Hours query was still using HoursDayID, HoursOpenTime etc. which
don't exist in payfrit_dev. Now uses DayID, OpenTime, ClosingTime.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated 70 files to match the payfrit_dev schema where columns like
BusinessName→Name, UserFirstName→FirstName, AddressCity→City, etc.
PKs renamed to ID, FKs keep referenced table name (e.g. BusinessID).
SQL aliases preserve original JSON response keys for API compatibility.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated all remaining SQL queries to use correct prefixed column names for
ServicePoints, Users, Businesses, Addresses, tt_States, tt_Days, and Hours
tables across 23 admin/infrastructure API files.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated Users (UserID, UserFirstName, UserLastName, UserEmailAddress, UserContactNumber),
ServicePoints (ServicePointID, ServicePointName, ServicePointTypeID), and Businesses
(BusinessID, BusinessName, BusinessTaxRate, BusinessPhone) column references with proper
prefixed names and AS aliases for API compatibility.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All lookup/reference tables use prefixed column names (tt_StateID, tt_StateAbbreviation,
tt_DayID, tt_DayAbbrev, tt_OrderTypeID, tt_OrderTypeName, ServicePointID, ServicePointName,
UserID, UserFirstName, UserLastName, AddressID, AddressLine1, etc). Updated all affected
queries to use correct column names with aliases to maintain API compatibility.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sweep of 26 API files to use prefixed column names matching the
database schema (e.g. BusinessID not ID, BusinessName not Name,
BusinessDeliveryFlatFee not DeliveryFlatFee, ServicePointName not Name).
Files fixed: auth, beacons, businesses, menu, orders, setup, stripe,
tasks, and workers endpoints.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- saveBrandColor.cfm: BrandColor -> BusinessBrandColor (normalized column name)
- portal.js: Accept hex colors with or without # prefix in validation
- portal.js: Auto-prepend # when typing bare hex in color input
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- loginOTP.cfm/sendOTP.cfm: Use magic OTP code (123456) on dev instead of random
- portal/login.html: Hide login card until auth check completes to prevent flash of login form when redirecting to business selection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- myBusinesses.cfm: Use BusinessID/BusinessName/BusinessUserID instead of
ID/Name/UserID (post-normalization column names)
- login.html: Fix biz.BusinessName -> biz.Name to match API response key
- login.html: Add friendly error messages for bad_credentials
- portal.js: Fix b.ID -> b.BusinessID in access check
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- setLineItem.cfm: WHERE ID→WHERE OrderID on 3 OrderLineItems queries
that filter by order (FK), not by line item PK
- setLineItem.cfm: qKids.ItemID→qKids.ID, qTemplateKids.ItemID→
qTemplateKids.ID (query only selects ID column from Items)
- abandonOrder.cfm: DELETE FROM OrderLineItems WHERE ID→WHERE OrderID
(was deleting one line item by PK instead of all items for the order)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users table primary key was renamed from UserID to ID but these
endpoints still referenced the old column name, causing server_error
on login/signup OTP flow.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add queryTimed(), logPerf(), flushPerfBuffer() to environment.cfm
- Auto-create ApiPerfLogs table on first flush
- Hook logPerf into Application.cfm apiAbort for automatic tracking
- Initialize request perf counters in Application.cfm
- Remove local apiAbort() overrides from 7 endpoints
- Instrument 12 high-traffic endpoints with logPerf calls
- Buffer metrics in application scope, batch INSERT every 100 requests
- 30-day auto-cleanup with probabilistic trigger
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all SQL queries, query result references, and ColdFusion code to match
the renamed database schema. Tables use plural CamelCase, PKs are all `ID`,
column prefixes stripped (e.g. BusinessName→Name, UserFirstName→FirstName).
Key changes:
- Strip table-name prefixes from all column references (Businesses, Users,
Addresses, Hours, Menus, Categories, Items, Stations, Orders,
OrderLineItems, Tasks, TaskCategories, TaskRatings, QuickTaskTemplates,
ScheduledTaskDefinitions, ChatMessages, Beacons, ServicePoints, Employees,
VisitorTrackings, ApiPerfLogs, tt_States, tt_Days, tt_AddressTypes,
tt_OrderTypes, tt_TaskTypes)
- Rename PK references from {TableName}ID to ID in all queries
- Rewrite 7 admin beacon files to use ServicePoints.BeaconID instead of
dropped lt_Beacon_Businesses_ServicePoints link table
- Rewrite beacon assignment files (list, save, delete) for new schema
- Fix FK references incorrectly changed to ID (OrderLineItems.OrderID,
Categories.MenuID, Tasks.CategoryID, ServicePoints.BeaconID)
- Update Addresses: AddressLat→Latitude, AddressLng→Longitude
- Update Users: UserPassword→Password, UserIsEmailVerified→IsEmailVerified,
UserIsActive→IsActive, UserBalance→Balance, etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Only include category headers that actually have items assigned
to them, preventing empty categories from showing up in the app.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Always return all active menus in the response so chip selector
always appears. Show all items from all menus by default instead
of filtering by current time, which caused empty results outside
menu hours.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Returns active menus in response so mobile apps can show menu
selector chips. Accepts optional MenuID param to filter items
to a specific menu.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When multiple menus exist, checks current time and day against menu
schedules. If exactly one menu matches, auto-selects it. If times
overlap or none match, shows all categories. User can still manually
select any menu or 'All Menus' from the dropdown.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The menuName variable was only defined in the else branch (new menu
creation) but referenced later in category logging. Now looks up the
menu name from DB when using a provided menuId.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
javaCast('null','') makes the variable truly undefined, causing
'variable doesn't exist' errors when referenced in query params.
Use empty string + len() check instead.
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>
The endpoint was missing from the public paths whitelist in
Application.cfm, causing all requests to fail with not_logged_in.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes save failure when MenuStartTime/MenuEndTime are null -
Lucee couldn't determine the SQL type without explicit hints.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
saveBrandColor.cfm no longer prepends # before storing. API responses
(get.cfm, items.cfm, getForBuilder.cfm) prepend # if missing so
consumers always get a CSS-ready value.
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>
- Remove TypeID/Label from list response
- Hardcode TypeID=2 (delivery) in add endpoint
- Filter to personal addresses only (BusinessID=0 or NULL)
- Just IsDefault flag, no home/work labels
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /addresses/types.cfm - returns address types list
- Update /addresses/list.cfm - include TypeID in response
- Update /addresses/add.cfm - accept TypeID instead of hardcoded '2'
- Fix loginOTP.cfm and sendOTP.cfm to skip Twilio SMS on dev server
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update create.cfm to handle TaskTypeID for service bell tasks
- Update hud.js to prefer TaskTypeColor/TaskTypeName for task display
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>