- sendLoginOTP.cfm: Accept Email, Phone, or Identifier field
Sends OTP via SMS for phone, email for email addresses
- verifyEmailOTP.cfm: Accept phone numbers for verification
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For businesses using beacon sharding:
- beacons/list.cfm now returns ServicePoints with BeaconMinor as beacons
- assignments/list.cfm now shows sharding assignments (SP + Minor)
- Both APIs include USES_SHARDING flag and sharding info
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The lookup API now handles two formats:
1. Sharding: { "Beacons": [{ "UUID", "Major", "Minor" }] }
Resolves via BeaconShards -> Businesses.BeaconMajor -> ServicePoints.BeaconMinor
2. Legacy: { "UUIDs": ["..."] }
Resolves via old Beacons table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Modifiers are saved with CategoryID=0 and ParentItemID pointing to their
parent item. The query was filtering by CategoryID IN (visible categories)
which excluded all modifiers.
Changed to: (CategoryID IN (visible) OR (CategoryID=0 AND ParentItemID>0))
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
User-uploaded content and log files should not be version controlled:
- Added uploads/ and *.log to .gitignore
- Removed uploads/ directory from tracking (files remain on disk)
- Removed api/menu/saveFromBuilder.log from tracking
This prevents git reset --hard from overwriting user content during deploys.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- getCart.cfm: Include TaxRate from Businesses table
- getOrCreateCart.cfm: Include TaxRate from Businesses table
- items.cfm: Include TaxRate in menu response for cart calculation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- profile.cfm now returns AvatarUrl in USER object
- avatar.cfm now updates Users.ImageExtension after successful upload
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When both OrderID and UserID are 0, dont join to User 0 (Payfrit Network).
Instead return no customer info, letting the app show Guest.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
COALESCE treats 0 as valid, so Order.UserID=0 was matching User 0
(Payfrit Network) instead of falling back to Task.UserID.
Use NULLIF to convert 0 to NULL before the fallback.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For order-based tasks, the customer comes from Order.UserID.
For standalone tasks without an order, fall back to Task.UserID.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Store UserID when creating service bell tasks
- Return CustomerID and CustomerName in listPending and listMine
- Join Users table to fetch customer first/last name
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use COALESCE(t.ServicePointID, o.ServicePointID) in JOIN
- Add ServicePointID to JSON response
- Fixes service bell tasks showing table name
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Redesign KDS with HUD-matching dark theme (pure black background)
- Header styling identical to HUD: position, font, clock format
- Status indicator moved to bottom-right corner like HUD
- Remove business ID config - now uses portal localStorage only
- Keep station toggle functionality
- Fix updateStatus.cfm: use correct column names for dev DB
(sp.Name instead of sp.ServicePointName, sp.ID instead of sp.ServicePointID)
- Use relative API URL instead of hardcoded production URL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ServicePointID to INSERT statement for service bell tasks
- Fix tt_TaskTypes query to use ID instead of tt_TaskTypeID
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add beacon-sharding API endpoints for scalable iBeacon addressing
(64 shard UUIDs × 65k businesses = ~4.2M capacity)
- Fix callServer.cfm to save UserID when creating Call Server tasks
- Fix getDetails.cfm to return customer info from Task.UserID when
Order.UserID is null (for tasks without orders)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix menu builder dropdown showing empty names (return MenuName instead of Name)
- Add default menu selection (setDefault action, DefaultMenuID in getForBuilder)
- Fix createPaymentIntent column names for dev schema (ID, StripeAccountID, etc.)
- Fix menu-builder favicon and remove redundant business label
- Comment out Tabs/Running Checks feature for launch (HTML + JS)
- Comment out Service Point Marketing/Grants feature for launch (HTML + JS)
- Add testMarkPaid.cfm for testing orders without Stripe webhooks
- Task API updates for worker payout ledger integration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Menu builder UI improvements
- Portal CSS and JS updates
- Station assignment updates
- Add business tabs update endpoint
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Converts 200+ endpoint files to use queryTimed() wrapper which tracks
DB query count and execution time. Restores perf dashboard files that
were accidentally moved to _scripts/. Includes portal UI updates.
Grant-based system allowing businesses to share service points with
other businesses. Includes grant CRUD API, time/eligibility/economics
policies, enforcement at cart creation and order submit, Stripe payment
routing for owner fees, and portal UI for managing grants.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace tt_OrderTypes JOIN with CASE statement (table casing on Linux)
- Fix key mismatches: Name->BusinessName, UUID->OrderUUID, StatusID->OrderStatusID
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>