Commit graph

159 commits

Author SHA1 Message Date
John Mizerek
2f35eb69eb Add beacon sharding support to lookup API
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>
2026-02-08 12:21:30 -08:00
John Mizerek
9ea3ec87f7 Fix modifiers not showing in app - CategoryID filter excluded them
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>
2026-02-08 11:57:05 -08:00
John Mizerek
fc27e2b87f Remove uploads and logs from git tracking
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>
2026-02-07 16:26:43 -08:00
John Mizerek
2023e1b5d9 Setup wizard and tasks updates
- Setup wizard save improvements
- Call server task updates
- Task creation changes
- Portal JS updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 15:18:01 -08:00
John Mizerek
30c175bafe Add TaxRate to cart and menu API responses
- 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>
2026-02-07 14:31:26 -08:00
John Mizerek
e40e87efe0 Allow child businesses to use parent service points without grant
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 11:58:44 -08:00
John Mizerek
5786f69ba4 Add AvatarUrl to profile API and update ImageExtension on upload
- 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>
2026-02-06 18:49:38 -08:00
John Mizerek
7f6c8253d0 Fix customer lookup: use NULLIF on both Order and Task UserID
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>
2026-02-06 18:46:00 -08:00
John Mizerek
624264ad2e Fix customer lookup: treat Order.UserID=0 as NULL
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>
2026-02-06 18:36:13 -08:00
John Mizerek
e1000dbe19 Fix customer lookup: prioritize Order.UserID over Task.UserID
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>
2026-02-06 18:28:36 -08:00
John Mizerek
c1edb20e53 Fix customer lookup - treat UserID 0 as NULL 2026-02-06 18:24:52 -08:00
John Mizerek
14c9336025 Fix getDetails customer info 2026-02-06 18:22:45 -08:00
John Mizerek
407f68655e Add UserID and customer info to service bell tasks
- 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>
2026-02-06 17:57:22 -08:00
John Mizerek
d8565deda1 Fix customer data query - remove invalid t.UserID join
Tasks table doesn't have UserID column. Customer data comes from Order.UserID only.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 17:52:40 -08:00
John Mizerek
b1a263bb36 Fix task APIs to get ServicePointName from Task.ServicePointID
- 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>
2026-02-06 17:46:04 -08:00
John Mizerek
8c247eb000 KDS: Dark minimal theme matching HUD, fix updateStatus column names
- 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>
2026-02-06 17:45:11 -08:00
John Mizerek
17d17071d1 Fix service bell task to include ServicePointID
- 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>
2026-02-06 17:42:56 -08:00
John Mizerek
d8333b3747 Add ServicePointName to task list endpoints
Returns service point name in listMine and listPending responses.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 17:34:12 -08:00
John Mizerek
5e9be8c2ca Fix min() function call in complete.cfm
Lucee's min() only takes 2 args, not 3. Use nested min() calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 17:30:12 -08:00
John Mizerek
f2a186c727 Fix tt_TaskTypes column name in callServer.cfm
Column is ID, not tt_TaskTypeID (per new naming convention).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 17:27:24 -08:00
John Mizerek
8696e3002f Fix callServer.cfm TaskTypeID null constraint error
TaskTypeID column is NOT NULL, so insert 0 instead of NULL when
no TaskTypeID is provided.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 17:25:15 -08:00
John Mizerek
3089f84873 Add beacon UUID sharding system and fix task customer info
- 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>
2026-02-06 17:16:08 -08:00
John Mizerek
31a89018f5 Launch prep: fix menu builder, payment flow, comment out pre-launch features
- 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>
2026-02-05 10:18:33 -08:00
John Mizerek
d7632c5d35 Menu builder and portal updates
- 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>
2026-02-03 17:08:54 -08:00
John Mizerek
e21a7f7266 Remove DeliveryMultiplier from Businesses query (column no longer exists)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 11:11:34 -08:00
John Mizerek
152ac572c7 Add detailed error message to getOrCreateCart for debugging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 11:07:03 -08:00
John
16a3b7c9a3 Replace queryExecute with queryTimed across all endpoints for perf tracking
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.
2026-02-02 00:28:37 -08:00
John Mizerek
f52d14bb7e Add Service Point Sharing infrastructure
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>
2026-02-01 21:34:03 -08:00
John Mizerek
89f339a9fd Fix order history and active cart API response keys
- 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>
2026-02-01 10:12:03 -08:00
John Mizerek
d6478da03f Fix brand color display and header upload collision
- 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>
2026-02-01 09:10:45 -08:00
John Mizerek
db90d9911a Add OTP email login to business portal
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>
2026-02-01 09:03:40 -08:00
John Mizerek
3f15b0c8b6 Fix SQL injection, wrong PK, and hardcoded production URLs
Security:
- orders/submit.cfm: parameterize IN clause (was string-interpolated)
- auth/completeProfile.cfm: fix UserID → ID on Users table PK

Environment-aware URLs:
- Add application.baseUrl to config/environment.cfm
- Replace all hardcoded https://biz.payfrit.com with application.baseUrl in:
  orders/getDetail, tasks/getDetails, auth/completeProfile, auth/avatar,
  stripe/onboard, users/search, workers/onboardingLink, workers/earlyUnlock

Also fix submit.cfm qMeta.ItemID → qMeta.ID (column not in SELECT)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:14:19 -08:00
John Mizerek
e30a757c39 Fix missing datasource in addresses/list.cfm and LIKE on INT column in setDefault.cfm
- list.cfm: add missing datasource: "payfrit" parameter to queryExecute
- setDefault.cfm: change AddressTypeID LIKE '%2%' to AddressTypeID = 2 (INT column)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:05:06 -08:00
John Mizerek
3dc15f8c13 Fix TaskID → ID in WHERE clauses on Tasks table (4 files + cron copy)
- 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>
2026-01-31 21:00:46 -08:00
John Mizerek
a7b7717ccd Fix prefixed column names in uploadHeader, stripe/onboard, stripe/createPaymentIntent
- 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>
2026-01-31 20:56:35 -08:00
John Mizerek
09172ace40 Fix header image URL to use relative path instead of hardcoded production domain
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:52:19 -08:00
John Mizerek
89ec86c9d2 Move 70 one-off admin scripts to api/admin/_scripts/ (gitignored)
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>
2026-01-31 20:38:49 -08:00
John Mizerek
78035e9cf6 Fix remaining prefixed DB column names across 17 API files
Hours: HoursBusinessID/HoursDayID/HoursOpenTime/HoursClosingTime -> BusinessID/DayID/OpenTime/ClosingTime
ServicePoints: ServicePointID/ServicePointName/ServicePointBusinessID -> ID/Name/BusinessID
Users: UserFirstName/UserLastName/UserEmailAddress/UserContactNumber -> FirstName/LastName/EmailAddress/ContactNumber
Orders: BusinessDeliveryMultiplier -> DeliveryMultiplier (column renamed in dev DB)
Businesses: BusinessParentBusinessID -> ParentBusinessID
tt_Days: tt_DayID/tt_DayName -> ID/Name

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:35:24 -08:00
John Mizerek
4f5ba7f549 Fix businesses/get.cfm: use un-prefixed dev DB column names
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>
2026-01-31 20:06:52 -08:00
John Mizerek
8acf2f3249 Complete DB column normalization: strip redundant table-name prefixes from all SQL queries
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>
2026-01-31 20:03:40 -08:00
John Mizerek
c62895e464 Fix prefixed column names in admin, beacon, task, assignment, chat, rating APIs
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>
2026-01-31 17:55:16 -08:00
John Mizerek
39448c5d91 Fix prefixed column names in auth, orders, portal team, users search, workers APIs
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>
2026-01-31 17:43:33 -08:00
John Mizerek
e92362f773 Fix prefixed column names for tt_States, tt_Days, tt_OrderTypes, ServicePoints, Users, Addresses, Hours tables
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>
2026-01-31 17:38:33 -08:00
John Mizerek
6b66d2cef8 Fix normalized DB column names across all API files
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>
2026-01-31 16:56:41 -08:00
John Mizerek
62c61c13cd Fix header upload: use normalized column names
- HeaderImageExtension -> BusinessHeaderImageExtension
- ID -> BusinessID in SELECT query

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:28:23 -08:00
John Mizerek
469cc06a29 Fix brand color save: use BusinessBrandColor column, allow # to be optional
- 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>
2026-01-31 14:27:44 -08:00
John Mizerek
498ebb6c0e Fix magic OTP on dev, fix portal login flash of login form
- 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>
2026-01-31 14:19:36 -08:00
John Mizerek
c5a332b04e Fix portal login: use normalized DB column names, fix business dropdown
- 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>
2026-01-31 14:15:37 -08:00
John Mizerek
94ee89d1f3 Fix FK references on OrderLineItems incorrectly changed to ID
- 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>
2026-01-30 23:30:10 -08:00
John Mizerek
8dff081407 Fix remaining old column names missed by initial batch rename
Second pass fixing 70+ references across 32 files:
- Orders: DeliveryMultiplier→BusinessDeliveryMultiplier, OrderTipAmount→TipAmount,
  OrderPaymentCompletedOn→PaymentCompletedOn, OrderPaymentError→PaymentError
- Orders PK: WHERE OrderID=? → WHERE ID=? on Orders table
- OrderLineItems PK: OrderLineItemID→ID in INSERT, WHERE, and query results
- Items: parent.ItemID→parent.ID in JOIN conditions
- Tasks: t.TaskID→t.ID in JOIN conditions
- Users PK: WHERE UserID=X → WHERE ID=X on Users table
- Addresses PK: A.AddressID→A.ID in JOIN conditions
- tt_States: tt_StateID→ID, remove nonexistent tt_StateCountryID/tt_StateSortOrder
- tt_OrderTypes: tt_OrderTypeID→ID, tt_OrderTypeName→Name
- tt_Days: D.tt_DayID→D.ID
- confirm_email.cfm: Add missing SELECT/FROM to queries
- setLineItem.cfm: Fix 13 old column references
- Stripe webhook/payment: Fix column names and PK references

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:58:46 -08:00