diff --git a/api/Application.cfm b/api/Application.cfm index 8a5723d..a354ace 100644 --- a/api/Application.cfm +++ b/api/Application.cfm @@ -103,6 +103,8 @@ if (len(request._api_path)) { if (findNoCase("/api/auth/verifyOTP.cfm", request._api_path)) request._api_isPublic = true; if (findNoCase("/api/auth/loginOTP.cfm", request._api_path)) request._api_isPublic = true; if (findNoCase("/api/auth/verifyLoginOTP.cfm", request._api_path)) request._api_isPublic = true; + if (findNoCase("/api/auth/sendLoginOTP.cfm", request._api_path)) request._api_isPublic = true; + if (findNoCase("/api/auth/verifyEmailOTP.cfm", request._api_path)) request._api_isPublic = true; if (findNoCase("/api/auth/completeProfile.cfm", request._api_path)) request._api_isPublic = true; if (findNoCase("/api/businesses/list.cfm", request._api_path)) request._api_isPublic = true; diff --git a/api/addresses/add.cfm b/api/addresses/add.cfm index 247daf7..09e5ff7 100644 --- a/api/addresses/add.cfm +++ b/api/addresses/add.cfm @@ -55,7 +55,7 @@ try { // If setting as default, clear other defaults first (for same type) if (setAsDefault) { - queryExecute(" + queryTimed(" UPDATE Addresses SET IsDefaultDelivery = 0 WHERE UserID = :userId @@ -68,11 +68,11 @@ try { } // Get next AddressID - qNext = queryExecute("SELECT IFNULL(MAX(ID), 0) + 1 AS NextID FROM Addresses", {}, { datasource: "payfrit" }); + qNext = queryTimed("SELECT IFNULL(MAX(ID), 0) + 1 AS NextID FROM Addresses", {}, { datasource: "payfrit" }); newAddressId = qNext.NextID; // Insert new address - queryExecute(" + queryTimed(" INSERT INTO Addresses ( ID, UserID, @@ -117,7 +117,7 @@ try { }, { datasource: "payfrit" }); // Get state info for response - qState = queryExecute("SELECT Abbreviation as StateAbbreviation, Name as StateName FROM tt_States WHERE ID = :stateId", { + qState = queryTimed("SELECT Abbreviation as StateAbbreviation, Name as StateName FROM tt_States WHERE ID = :stateId", { stateId: { value: stateId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); diff --git a/api/addresses/delete.cfm b/api/addresses/delete.cfm index ba37e22..4dcb977 100644 --- a/api/addresses/delete.cfm +++ b/api/addresses/delete.cfm @@ -40,7 +40,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U userToken = getHeader("X-User-Token"); if (len(userToken)) { try { - qTok = queryExecute( + qTok = queryTimed( "SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1", [{ value = userToken, cfsqltype = "cf_sql_varchar" }], { datasource = "payfrit" } @@ -75,7 +75,7 @@ if (addressId <= 0) { try { // First, get the address details so we can find all matching duplicates - qAddr = queryExecute(" + qAddr = queryTimed(" SELECT Line1, Line2, City, StateID, ZIPCode FROM Addresses WHERE ID = :addressId @@ -91,7 +91,7 @@ try { } // Soft-delete ALL addresses that match the same Line1, Line2, City, StateID, ZIPCode - qDelete = queryExecute(" + qDelete = queryTimed(" UPDATE Addresses SET IsDeleted = 1 WHERE UserID = :userId diff --git a/api/addresses/list.cfm b/api/addresses/list.cfm index b5c8f2a..1e9a363 100644 --- a/api/addresses/list.cfm +++ b/api/addresses/list.cfm @@ -29,7 +29,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U userToken = getHeader("X-User-Token"); if (len(userToken)) { try { - qTok = queryExecute( + qTok = queryTimed( "SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1", [{ value = userToken, cfsqltype = "cf_sql_varchar" }], { datasource = "payfrit" } @@ -47,7 +47,7 @@ if (userId <= 0) { try { // Get user's delivery addresses - qAddresses = queryExecute(" + qAddresses = queryTimed(" SELECT a.ID, a.IsDefaultDelivery, diff --git a/api/addresses/setDefault.cfm b/api/addresses/setDefault.cfm index 1fd2835..a2628c8 100644 --- a/api/addresses/setDefault.cfm +++ b/api/addresses/setDefault.cfm @@ -40,7 +40,7 @@ try { } // Verify address belongs to user - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM Addresses WHERE ID = :addressId @@ -61,7 +61,7 @@ try { } // Clear all defaults for this user - queryExecute(" + queryTimed(" UPDATE Addresses SET IsDefaultDelivery = 0 WHERE UserID = :userId @@ -72,7 +72,7 @@ try { }, { datasource: "payfrit" }); // Set this one as default - queryExecute(" + queryTimed(" UPDATE Addresses SET IsDefaultDelivery = 1 WHERE ID = :addressId diff --git a/api/addresses/states.cfm b/api/addresses/states.cfm index ed81780..b96b7b6 100644 --- a/api/addresses/states.cfm +++ b/api/addresses/states.cfm @@ -5,7 +5,7 @@ try { - qStates = queryExecute(" + qStates = queryTimed(" SELECT ID as StateID, Abbreviation as StateAbbreviation, Name as StateName FROM tt_States ORDER BY Name diff --git a/api/addresses/types.cfm b/api/addresses/types.cfm index 72b39eb..8000aa2 100644 --- a/api/addresses/types.cfm +++ b/api/addresses/types.cfm @@ -11,7 +11,7 @@ */ try { - qTypes = queryExecute(" + qTypes = queryTimed(" SELECT tt_AddressTypeID as ID, tt_AddressType as Label FROM tt_AddressTypes ORDER BY tt_AddressTypeID diff --git a/api/admin/_scripts/addCategoryIsActiveColumn.cfm b/api/admin/_scripts/addCategoryIsActiveColumn.cfm index 046935d..9c4b5c4 100644 --- a/api/admin/_scripts/addCategoryIsActiveColumn.cfm +++ b/api/admin/_scripts/addCategoryIsActiveColumn.cfm @@ -5,7 +5,7 @@ // Add IsActive column to TaskCategories table try { // Check if column exists - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' AND TABLE_NAME = 'TaskCategories' @@ -13,7 +13,7 @@ try { ", [], { datasource: "payfrit" }); if (qCheck.recordCount == 0) { - queryExecute(" + queryTimed(" ALTER TABLE TaskCategories ADD COLUMN IsActive TINYINT(1) NOT NULL DEFAULT 1 ", [], { datasource: "payfrit" }); diff --git a/api/admin/_scripts/addCategoryScheduleFields.cfm b/api/admin/_scripts/addCategoryScheduleFields.cfm index 963e600..62f905f 100644 --- a/api/admin/_scripts/addCategoryScheduleFields.cfm +++ b/api/admin/_scripts/addCategoryScheduleFields.cfm @@ -19,7 +19,7 @@ response = { "OK": false }; try { // Check if columns already exist - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' @@ -33,7 +33,7 @@ try { // Add ScheduleStart if not exists if (!listFindNoCase(existingCols, "ScheduleStart")) { - queryExecute(" + queryTimed(" ALTER TABLE Categories ADD COLUMN ScheduleStart TIME NULL ", {}, { datasource: "payfrit" }); @@ -42,7 +42,7 @@ try { // Add ScheduleEnd if not exists if (!listFindNoCase(existingCols, "ScheduleEnd")) { - queryExecute(" + queryTimed(" ALTER TABLE Categories ADD COLUMN ScheduleEnd TIME NULL ", {}, { datasource: "payfrit" }); @@ -51,7 +51,7 @@ try { // Add ScheduleDays if not exists if (!listFindNoCase(existingCols, "ScheduleDays")) { - queryExecute(" + queryTimed(" ALTER TABLE Categories ADD COLUMN ScheduleDays VARCHAR(20) NULL ", {}, { datasource: "payfrit" }); diff --git a/api/admin/_scripts/addDrinkModifiers.cfm b/api/admin/_scripts/addDrinkModifiers.cfm index 7d62e40..3617c75 100644 --- a/api/admin/_scripts/addDrinkModifiers.cfm +++ b/api/admin/_scripts/addDrinkModifiers.cfm @@ -14,7 +14,7 @@ try { bigDeansBusinessId = 27; // Find the Fountain Soda item we created - qFountain = queryExecute(" + qFountain = queryTimed(" SELECT ID, Name FROM Items WHERE BusinessID = :bizId AND Name = 'Fountain Soda' ", { bizId: bigDeansBusinessId }, { datasource: "payfrit" }); @@ -29,14 +29,14 @@ try { response["FountainSodaID"] = fountainId; // Update Fountain Soda to require child selection and be collapsible - queryExecute(" + queryTimed(" UPDATE Items SET RequiresChildSelection = 1, IsCollapsible = 1 WHERE ID = :itemId ", { itemId: fountainId }, { datasource: "payfrit" }); // Check if modifiers already exist - qExisting = queryExecute(" + qExisting = queryTimed(" SELECT COUNT(*) as cnt FROM Items WHERE ParentItemID = :parentId ", { parentId: fountainId }, { datasource: "payfrit" }); @@ -48,10 +48,10 @@ try { } // Add Size group - qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); + qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); sizeGroupId = qMaxItem.nextId; - queryExecute(" + queryTimed(" INSERT INTO Items ( ID, BusinessID, CategoryID, ParentItemID, Name, Description, Price, IsActive, @@ -77,8 +77,8 @@ try { sizesAdded = 0; for (size in sizes) { - qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); - queryExecute(" + qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); + queryTimed(" INSERT INTO Items ( ItemID, BusinessID, CategoryID, ParentItemID, Name, Description, Price, IsActive, @@ -103,10 +103,10 @@ try { } // Add Type/Flavor group - qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); + qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); typeGroupId = qMaxItem.nextId; - queryExecute(" + queryTimed(" INSERT INTO Items ( ID, BusinessID, CategoryID, ParentItemID, Name, Description, Price, IsActive, @@ -136,8 +136,8 @@ try { typesAdded = 0; for (type in types) { - qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); - queryExecute(" + qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); + queryTimed(" INSERT INTO Items ( ItemID, BusinessID, CategoryID, ParentItemID, Name, Description, Price, IsActive, diff --git a/api/admin/_scripts/addItemCategoryColumn.cfm b/api/admin/_scripts/addItemCategoryColumn.cfm index c04b791..da1b56f 100644 --- a/api/admin/_scripts/addItemCategoryColumn.cfm +++ b/api/admin/_scripts/addItemCategoryColumn.cfm @@ -12,7 +12,7 @@ response = { "OK": false }; try { // Check if column already exists - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' @@ -25,14 +25,14 @@ try { response["MESSAGE"] = "CategoryID column already exists"; } else { // Add the column - queryExecute(" + queryTimed(" ALTER TABLE Items ADD COLUMN CategoryID INT NULL DEFAULT 0 AFTER ParentItemID ", {}, { datasource: "payfrit" }); // Add index for performance try { - queryExecute(" + queryTimed(" CREATE INDEX idx_items_categoryid ON Items(CategoryID) ", {}, { datasource: "payfrit" }); } catch (any indexErr) { diff --git a/api/admin/_scripts/addLatLng.cfm b/api/admin/_scripts/addLatLng.cfm index 5c89c1d..8afb03f 100644 --- a/api/admin/_scripts/addLatLng.cfm +++ b/api/admin/_scripts/addLatLng.cfm @@ -5,7 +5,7 @@ try { // Check if columns already exist - checkCols = queryExecute( + checkCols = queryTimed( "SHOW COLUMNS FROM Addresses LIKE 'Latitude'", [], { datasource = "payfrit" } @@ -13,7 +13,7 @@ try { if (checkCols.recordCount EQ 0) { // Add the columns - queryExecute( + queryTimed( "ALTER TABLE Addresses ADD COLUMN Latitude DECIMAL(10,7) NULL, ADD COLUMN Longitude DECIMAL(10,7) NULL", diff --git a/api/admin/_scripts/addServiceCategoryColumn.cfm b/api/admin/_scripts/addServiceCategoryColumn.cfm index bdbccbc..3f2d2a6 100644 --- a/api/admin/_scripts/addServiceCategoryColumn.cfm +++ b/api/admin/_scripts/addServiceCategoryColumn.cfm @@ -5,7 +5,7 @@ // Add CategoryID column to tt_TaskTypes (Services) table try { // Check if column exists - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' AND TABLE_NAME = 'tt_TaskTypes' @@ -13,7 +13,7 @@ try { ", [], { datasource: "payfrit" }); if (qCheck.recordCount == 0) { - queryExecute(" + queryTimed(" ALTER TABLE tt_TaskTypes ADD COLUMN TaskCategoryID INT NULL ", [], { datasource: "payfrit" }); diff --git a/api/admin/_scripts/addTaskSourceColumns.cfm b/api/admin/_scripts/addTaskSourceColumns.cfm index df621f0..99dc2f0 100644 --- a/api/admin/_scripts/addTaskSourceColumns.cfm +++ b/api/admin/_scripts/addTaskSourceColumns.cfm @@ -10,7 +10,7 @@ result = { "OK": true, "STEPS": [] }; try { // Check if columns already exist - cols = queryExecute(" + cols = queryTimed(" SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' @@ -23,7 +23,7 @@ try { // Add SourceType if missing if (!listFindNoCase(existingCols, "SourceType")) { - queryExecute(" + queryTimed(" ALTER TABLE Tasks ADD COLUMN SourceType VARCHAR(50) NULL ", [], { datasource: "payfrit" }); arrayAppend(result.STEPS, "Added SourceType column"); @@ -33,7 +33,7 @@ try { // Add SourceID if missing if (!listFindNoCase(existingCols, "SourceID")) { - queryExecute(" + queryTimed(" ALTER TABLE Tasks ADD COLUMN SourceID INT NULL ", [], { datasource: "payfrit" }); arrayAppend(result.STEPS, "Added SourceID column"); @@ -42,7 +42,7 @@ try { } // Verify columns now exist - verifyQuery = queryExecute(" + verifyQuery = queryTimed(" SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' diff --git a/api/admin/_scripts/beaconStatus.cfm b/api/admin/_scripts/beaconStatus.cfm index a34a137..6793ad2 100644 --- a/api/admin/_scripts/beaconStatus.cfm +++ b/api/admin/_scripts/beaconStatus.cfm @@ -4,7 +4,7 @@ // Show all beacons with their current business/service point assignments -q = queryExecute(" +q = queryTimed(" SELECT b.ID, b.UUID, @@ -35,7 +35,7 @@ for (row in q) { } // Also get service points for reference -spQuery = queryExecute(" +spQuery = queryTimed(" SELECT sp.ID, sp.Name AS Name, sp.BusinessID AS BusinessID, b.Name AS Name FROM ServicePoints sp JOIN Businesses b ON b.ID = sp.BusinessID diff --git a/api/admin/_scripts/checkBigDeans.cfm b/api/admin/_scripts/checkBigDeans.cfm index ef674a7..c8289b9 100644 --- a/api/admin/_scripts/checkBigDeans.cfm +++ b/api/admin/_scripts/checkBigDeans.cfm @@ -4,14 +4,14 @@ // Check Big Dean's owner -q = queryExecute(" +q = queryTimed(" SELECT b.ID, b.Name, b.UserID FROM Businesses b WHERE b.ID = 27 ", {}, { datasource: "payfrit" }); // Get users -users = queryExecute(" +users = queryTimed(" SELECT * FROM Users ORDER BY ID diff --git a/api/admin/_scripts/checkUser.cfm b/api/admin/_scripts/checkUser.cfm index 6994ce8..b07fad5 100644 --- a/api/admin/_scripts/checkUser.cfm +++ b/api/admin/_scripts/checkUser.cfm @@ -11,7 +11,7 @@ if (!len(phone)) { abort; } -q = queryExecute(" +q = queryTimed(" SELECT ID, FirstName, LastName, EmailAddress, ContactNumber, IsContactVerified FROM Users WHERE ContactNumber = :phone OR EmailAddress = :phone diff --git a/api/admin/_scripts/cleanupBeacons.cfm b/api/admin/_scripts/cleanupBeacons.cfm index ddb1319..b526d85 100644 --- a/api/admin/_scripts/cleanupBeacons.cfm +++ b/api/admin/_scripts/cleanupBeacons.cfm @@ -15,7 +15,7 @@ try { lazyDaisyID = 37; // Unassign beacons 7, 8, 9 from any service points - queryExecute(" + queryTimed(" UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL WHERE BeaconID IN (7, 8, 9) AND BusinessID = :bizId @@ -23,33 +23,33 @@ try { response.steps.append("Unassigned beacons 7, 8, 9 from service points"); // Delete duplicate beacons 7, 8, 9 - queryExecute(" + queryTimed(" DELETE FROM Beacons WHERE ID IN (7, 8, 9) AND BusinessID = :bizId ", { bizId: lazyDaisyID }, { datasource: "payfrit" }); response.steps.append("Deleted duplicate beacons 7, 8, 9"); // Update original beacons with names based on their service point assignments - queryExecute(" + queryTimed(" UPDATE Beacons SET Name = 'Beacon - Table 1' WHERE ID = 4 AND BusinessID = :bizId ", { bizId: lazyDaisyID }, { datasource: "payfrit" }); response.steps.append("Updated Beacon 4 name to 'Beacon - Table 1'"); - queryExecute(" + queryTimed(" UPDATE Beacons SET Name = 'Beacon - Table 2' WHERE ID = 5 AND BusinessID = :bizId ", { bizId: lazyDaisyID }, { datasource: "payfrit" }); response.steps.append("Updated Beacon 5 name to 'Beacon - Table 2'"); - queryExecute(" + queryTimed(" UPDATE Beacons SET Name = 'Beacon - Table 3' WHERE ID = 6 AND BusinessID = :bizId ", { bizId: lazyDaisyID }, { datasource: "payfrit" }); response.steps.append("Updated Beacon 6 name to 'Beacon - Table 3'"); // Get final status - qFinal = queryExecute(" + qFinal = queryTimed(" SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID, b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName, biz.Name AS BusinessName diff --git a/api/admin/_scripts/cleanupCategories.cfm b/api/admin/_scripts/cleanupCategories.cfm index b842664..0b2ce7e 100644 --- a/api/admin/_scripts/cleanupCategories.cfm +++ b/api/admin/_scripts/cleanupCategories.cfm @@ -28,7 +28,7 @@ try { confirm = structKeyExists(url, "confirm") && url.confirm == "YES"; // Verification Step 1: Check for items without BusinessID - qNoBusinessID = queryExecute(" + qNoBusinessID = queryTimed(" SELECT COUNT(*) as cnt FROM Items WHERE BusinessID IS NULL OR BusinessID = 0 ", {}, { datasource: "payfrit" }); @@ -36,14 +36,14 @@ try { response.verification["itemsWithoutBusinessID"] = qNoBusinessID.cnt; // Verification Step 2: Check that all categories were converted - qCategories = queryExecute(" + qCategories = queryTimed(" SELECT COUNT(*) as cnt FROM Categories ", {}, { datasource: "payfrit" }); response.verification["categoriesRemaining"] = qCategories.cnt; // Verification Step 3: Check category Items exist (ParentID=0 with children) - qCategoryItems = queryExecute(" + qCategoryItems = queryTimed(" SELECT COUNT(DISTINCT p.ItemID) as cnt FROM Items p INNER JOIN Items c ON c.ParentItemID = p.ItemID @@ -57,7 +57,7 @@ try { response.verification["categoryItemsCreated"] = qCategoryItems.cnt; // Verification Step 4: Check templates exist (in lt_ItemID_TemplateItemID) - qTemplates = queryExecute(" + qTemplates = queryTimed(" SELECT COUNT(DISTINCT tl.TemplateItemID) as cnt FROM lt_ItemID_TemplateItemID tl INNER JOIN Items t ON t.ItemID = tl.TemplateItemID @@ -67,7 +67,7 @@ try { // Verification Step 5: Find orphans at ParentID=0 // Orphan = ParentID=0, no children pointing to it, not in lt_ItemID_TemplateItemID - qOrphans = queryExecute(" + qOrphans = queryTimed(" SELECT i.ID, i.Name, i.BusinessID FROM Items i WHERE i.ParentItemID = 0 @@ -121,7 +121,7 @@ try { // Step 1: Drop CategoryID column try { - queryExecute(" + queryTimed(" ALTER TABLE Items DROP COLUMN CategoryID ", {}, { datasource: "payfrit" }); arrayAppend(response.steps, "Dropped CategoryID column from Items"); @@ -135,7 +135,7 @@ try { // Step 2: Drop IsModifierTemplate column (now derived from lt_ItemID_TemplateItemID) try { - queryExecute(" + queryTimed(" ALTER TABLE Items DROP COLUMN IsModifierTemplate ", {}, { datasource: "payfrit" }); arrayAppend(response.steps, "Dropped IsModifierTemplate column from Items"); @@ -149,7 +149,7 @@ try { // Step 3: Drop Categories table try { - queryExecute(" + queryTimed(" DROP TABLE Categories ", {}, { datasource: "payfrit" }); arrayAppend(response.steps, "Dropped Categories table"); diff --git a/api/admin/_scripts/cleanupDuplicateEmployees.cfm b/api/admin/_scripts/cleanupDuplicateEmployees.cfm index 40e76d8..d5634ff 100644 --- a/api/admin/_scripts/cleanupDuplicateEmployees.cfm +++ b/api/admin/_scripts/cleanupDuplicateEmployees.cfm @@ -33,7 +33,7 @@ if (businessId <= 0) { try { // Find duplicate UserIDs for this business (keep the one with highest status or oldest) - qDupes = queryExecute(" + qDupes = queryTimed(" SELECT ID, COUNT(*) as cnt, MIN(ID) as keepId FROM Employees WHERE BusinessID = ? @@ -44,7 +44,7 @@ try { deleted = 0; for (row in qDupes) { // Delete all but the one we want to keep (the one with lowest EmployeeID) - qDel = queryExecute(" + qDel = queryTimed(" DELETE FROM Employees WHERE BusinessID = ? AND UserID = ? AND ID != ? ", [ @@ -56,7 +56,7 @@ try { } // Get remaining employees - qRemaining = queryExecute(" + qRemaining = queryTimed(" SELECT e.ID, e.UserID, u.FirstName, u.LastName FROM Employees e JOIN Users u ON e.UserID = u.ID diff --git a/api/admin/_scripts/cleanupForLazyDaisy.cfm b/api/admin/_scripts/cleanupForLazyDaisy.cfm index 196a6f1..7600ff9 100644 --- a/api/admin/_scripts/cleanupForLazyDaisy.cfm +++ b/api/admin/_scripts/cleanupForLazyDaisy.cfm @@ -10,7 +10,7 @@ try { keepBusinessID = 37; // Unassign all beacons from service points of other businesses - queryExecute(" + queryTimed(" UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL WHERE BusinessID != :keepID AND BeaconID IS NOT NULL @@ -18,7 +18,7 @@ try { response.steps.append("Unassigned beacons from other businesses' service points"); // Get list of businesses to delete - qBiz = queryExecute(" + qBiz = queryTimed(" SELECT ID, Name FROM Businesses WHERE ID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); @@ -30,7 +30,7 @@ try { // Delete related data first (foreign key constraints) // Delete lt_ItemID_TemplateItemID for items from other businesses - queryExecute(" + queryTimed(" DELETE itl FROM lt_ItemID_TemplateItemID itl JOIN Items i ON i.ID = itl.ItemID WHERE i.BusinessID != :keepID @@ -38,29 +38,29 @@ try { response.steps.append("Deleted lt_ItemID_TemplateItemID for other businesses"); // Delete Items for other businesses - qItems = queryExecute(" + qItems = queryTimed(" SELECT COUNT(*) as cnt FROM Items WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); - queryExecute(" + queryTimed(" DELETE FROM Items WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted " & qItems.cnt & " items from other businesses"); // Delete Categories for other businesses - queryExecute(" + queryTimed(" DELETE FROM Categories WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted categories from other businesses"); // Delete Hours for other businesses - queryExecute(" + queryTimed(" DELETE FROM Hours WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted hours from other businesses"); // Delete Employees for other businesses try { - queryExecute(" + queryTimed(" DELETE FROM Employees WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted employees from other businesses"); @@ -70,7 +70,7 @@ try { // Delete ServicePoints for other businesses try { - queryExecute(" + queryTimed(" DELETE FROM ServicePoints WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted service points from other businesses"); @@ -80,7 +80,7 @@ try { // Delete Stations for other businesses try { - queryExecute(" + queryTimed(" DELETE FROM Stations WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted stations from other businesses"); @@ -90,7 +90,7 @@ try { // Delete beacon-business mappings for other businesses try { - queryExecute(" + queryTimed(" DELETE FROM lt_BeaconsID_BusinessesID WHERE BusinessID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted beacon mappings for other businesses"); @@ -99,13 +99,13 @@ try { } // Finally delete the businesses themselves - queryExecute(" + queryTimed(" DELETE FROM Businesses WHERE ID != :keepID ", { keepID: keepBusinessID }, { datasource: "payfrit" }); response.steps.append("Deleted " & arrayLen(deletedBusinesses) & " businesses"); // Get beacon status - qBeacons = queryExecute(" + qBeacons = queryTimed(" SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID, b.UUID, biz.Name AS BusinessName, sp.Name AS ServicePointName FROM ServicePoints sp diff --git a/api/admin/_scripts/cleanupOrphanItem.cfm b/api/admin/_scripts/cleanupOrphanItem.cfm index 4637990..665aefb 100644 --- a/api/admin/_scripts/cleanupOrphanItem.cfm +++ b/api/admin/_scripts/cleanupOrphanItem.cfm @@ -6,7 +6,7 @@ param name="url.itemId" default="11543"; param name="url.action" default="check"; // "check" or "deactivate" // Check the item first -qItem = queryExecute(" +qItem = queryTimed(" SELECT ID, Name, ParentItemID, IsActive, IsCollapsible FROM Items WHERE ID = :itemId @@ -18,7 +18,7 @@ if (qItem.recordCount == 0) { } // Get all children (direct only for display) -qChildren = queryExecute(" +qChildren = queryTimed(" SELECT ID, Name FROM Items WHERE ParentItemID = :itemId @@ -46,14 +46,14 @@ result = { if (url.action == "deactivate") { // Deactivate children first - queryExecute(" + queryTimed(" UPDATE Items SET IsActive = 0 WHERE ParentItemID = :itemId ", { itemId: url.itemId }); // Then deactivate the parent - queryExecute(" + queryTimed(" UPDATE Items SET IsActive = 0 WHERE ItemID = :itemId diff --git a/api/admin/_scripts/clearCarts.cfm b/api/admin/_scripts/clearCarts.cfm index ba7cd14..37e0d9f 100644 --- a/api/admin/_scripts/clearCarts.cfm +++ b/api/admin/_scripts/clearCarts.cfm @@ -3,14 +3,14 @@ // Delete cart orders (status 0) to reset for testing -result = queryExecute(" +result = queryTimed(" DELETE FROM OrderLineItems WHERE OrderID IN ( SELECT ID FROM Orders WHERE StatusID = 0 ) ", {}, { datasource = "payfrit" }); -result2 = queryExecute(" +result2 = queryTimed(" DELETE FROM Orders WHERE StatusID = 0 ", {}, { datasource = "payfrit" }); diff --git a/api/admin/_scripts/clearLocalCoffee.cfm b/api/admin/_scripts/clearLocalCoffee.cfm index da77556..060241c 100644 --- a/api/admin/_scripts/clearLocalCoffee.cfm +++ b/api/admin/_scripts/clearLocalCoffee.cfm @@ -11,26 +11,26 @@ try { for (bizID in businessIDs) { // Delete lt_ItemID_TemplateItemID for items belonging to this business - queryExecute(" + queryTimed(" DELETE itl FROM lt_ItemID_TemplateItemID itl INNER JOIN Items i ON i.ID = itl.ItemID WHERE i.BusinessID = :bizID ", { bizID: bizID }, { datasource: "payfrit" }); // Delete Items - queryExecute("DELETE FROM Items WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); + queryTimed("DELETE FROM Items WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); // Delete Categories - queryExecute("DELETE FROM Categories WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); + queryTimed("DELETE FROM Categories WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); // Delete Hours - queryExecute("DELETE FROM Hours WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); + queryTimed("DELETE FROM Hours WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); // Delete Addresses linked to this business - queryExecute("DELETE FROM Addresses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); + queryTimed("DELETE FROM Addresses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); // Delete the Business itself - queryExecute("DELETE FROM Businesses WHERE ID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); + queryTimed("DELETE FROM Businesses WHERE ID = :bizID", { bizID: bizID }, { datasource: "payfrit" }); response.steps.append("Deleted business " & bizID & " and all related data"); } diff --git a/api/admin/_scripts/closeAllChats.cfm b/api/admin/_scripts/closeAllChats.cfm index 237f710..ff7fb58 100644 --- a/api/admin/_scripts/closeAllChats.cfm +++ b/api/admin/_scripts/closeAllChats.cfm @@ -3,7 +3,7 @@ // Close all open chat tasks try { - result = queryExecute(" + result = queryTimed(" UPDATE Tasks SET CompletedOn = NOW() WHERE TaskTypeID = 2 diff --git a/api/admin/_scripts/copyDrinksToBigDeans.cfm b/api/admin/_scripts/copyDrinksToBigDeans.cfm index 0e4c9ba..50a2446 100644 --- a/api/admin/_scripts/copyDrinksToBigDeans.cfm +++ b/api/admin/_scripts/copyDrinksToBigDeans.cfm @@ -14,7 +14,7 @@ try { bigDeansBusinessId = 27; // First, check if Big Dean's has a Beverages/Drinks category - qExistingCat = queryExecute(" + qExistingCat = queryTimed(" SELECT ID, Name FROM Categories WHERE BusinessID = :bizId AND (Name LIKE '%Drink%' OR Name LIKE '%Beverage%') ", { bizId: bigDeansBusinessId }, { datasource: "payfrit" }); @@ -24,14 +24,14 @@ try { response["CategoryNote"] = "Using existing category: " & qExistingCat.Name; } else { // Create a new Beverages category for Big Dean's - qMaxCat = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Categories", {}, { datasource: "payfrit" }); + qMaxCat = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Categories", {}, { datasource: "payfrit" }); drinksCategoryId = qMaxCat.nextId; - qMaxSort = queryExecute(" + qMaxSort = queryTimed(" SELECT COALESCE(MAX(SortOrder), 0) + 1 as nextSort FROM Categories WHERE BusinessID = :bizId ", { bizId: bigDeansBusinessId }, { datasource: "payfrit" }); - queryExecute(" + queryTimed(" INSERT INTO Categories (ID, BusinessID, ParentCategoryID, Name, SortOrder, AddedOn) VALUES (:catId, :bizId, 0, 'Beverages', :sortOrder, NOW()) ", { @@ -60,17 +60,17 @@ try { for (drink in drinks) { // Check if item already exists - qExists = queryExecute(" + qExists = queryTimed(" SELECT ID FROM Items WHERE BusinessID = :bizId AND Name = :name AND CategoryID = :catId ", { bizId: bigDeansBusinessId, name: drink.name, catId: drinksCategoryId }, { datasource: "payfrit" }); if (qExists.recordCount == 0) { // Get next ItemID - qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); + qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); newItemId = qMaxItem.nextId; - queryExecute(" + queryTimed(" INSERT INTO Items ( ID, BusinessID, CategoryID, ParentItemID, Name, Description, Price, IsActive, @@ -100,8 +100,8 @@ try { flavors = ["Chocolate", "Vanilla", "Strawberry"]; flavorSort = 0; for (flavor in flavors) { - qMaxOpt = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); - queryExecute(" + qMaxOpt = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" }); + queryTimed(" INSERT INTO Items ( ID, BusinessID, CategoryID, ParentItemID, Name, Description, Price, IsActive, diff --git a/api/admin/_scripts/createBeacons.cfm b/api/admin/_scripts/createBeacons.cfm index d7cca75..a6e8979 100644 --- a/api/admin/_scripts/createBeacons.cfm +++ b/api/admin/_scripts/createBeacons.cfm @@ -20,11 +20,11 @@ try { uuid = beaconUUIDs[i]; // Check if beacon exists - qB = queryExecute("SELECT ID FROM Beacons WHERE UUID = :uuid", { uuid: uuid }, { datasource: "payfrit" }); + qB = queryTimed("SELECT ID FROM Beacons WHERE UUID = :uuid", { uuid: uuid }, { datasource: "payfrit" }); if (qB.recordCount == 0) { - queryExecute("INSERT INTO Beacons (UUID, BusinessID) VALUES (:uuid, :bizID)", { uuid: uuid, bizID: lazyDaisyID }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + queryTimed("INSERT INTO Beacons (UUID, BusinessID) VALUES (:uuid, :bizID)", { uuid: uuid, bizID: lazyDaisyID }, { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); beaconID = qNew.id; response.steps.append("Created beacon " & beaconID & " with UUID: " & uuid); } else { @@ -34,17 +34,17 @@ try { } // Get service point Table 1 - qSP = queryExecute(" + qSP = queryTimed(" SELECT ID FROM ServicePoints WHERE BusinessID = :bizID AND Name = 'Table 1' ", { bizID: lazyDaisyID }, { datasource: "payfrit" }); if (qSP.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO ServicePoints (BusinessID, Name) VALUES (:bizID, 'Table 1') ", { bizID: lazyDaisyID }, { datasource: "payfrit" }); - qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qSP = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); servicePointID = qSP.id; response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")"); } else { @@ -53,20 +53,20 @@ try { } // Assign all beacons to the Table 1 service point - qBeacons = queryExecute("SELECT ID, UUID FROM Beacons WHERE BusinessID = :bizID", { bizID: lazyDaisyID }, { datasource: "payfrit" }); + qBeacons = queryTimed("SELECT ID, UUID FROM Beacons WHERE BusinessID = :bizID", { bizID: lazyDaisyID }, { datasource: "payfrit" }); for (i = 1; i <= qBeacons.recordCount; i++) { beaconID = qBeacons.ID[i]; // Unassign this beacon from any existing service point - queryExecute(" + queryTimed(" UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL WHERE BeaconID = :beaconID ", { beaconID: beaconID }, { datasource: "payfrit" }); // Assign beacon to Table 1 service point - queryExecute(" + queryTimed(" UPDATE ServicePoints SET BeaconID = :beaconID, AssignedByUserID = 1 WHERE ID = :spID AND BusinessID = :bizID ", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" }); @@ -74,7 +74,7 @@ try { } // Get final status - qFinal = queryExecute(" + qFinal = queryTimed(" SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID, b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName, biz.Name AS BusinessName diff --git a/api/admin/_scripts/createChatMessagesTable.cfm b/api/admin/_scripts/createChatMessagesTable.cfm index a641e6b..be0685c 100644 --- a/api/admin/_scripts/createChatMessagesTable.cfm +++ b/api/admin/_scripts/createChatMessagesTable.cfm @@ -3,7 +3,7 @@ try { // Create ChatMessages table - queryExecute(" + queryTimed(" CREATE TABLE IF NOT EXISTS ChatMessages ( ID INT AUTO_INCREMENT PRIMARY KEY, TaskID INT NOT NULL, @@ -20,20 +20,20 @@ try { ", {}, { datasource: "payfrit" }); // Also add a "Chat" category if it doesn't exist for business 17 - existing = queryExecute(" + existing = queryTimed(" SELECT ID FROM TaskCategories WHERE BusinessID = 17 AND Name = 'Chat' ", {}, { datasource: "payfrit" }); if (existing.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO TaskCategories (BusinessID, Name, Color) VALUES (17, 'Chat', '##2196F3') ", {}, { datasource: "payfrit" }); } // Verify table was created - cols = queryExecute("DESCRIBE ChatMessages", {}, { datasource: "payfrit" }); + cols = queryTimed("DESCRIBE ChatMessages", {}, { datasource: "payfrit" }); colNames = []; for (c in cols) { arrayAppend(colNames, c.Field); diff --git a/api/admin/_scripts/createMenusTable.cfm b/api/admin/_scripts/createMenusTable.cfm index 38f22be..639d411 100644 --- a/api/admin/_scripts/createMenusTable.cfm +++ b/api/admin/_scripts/createMenusTable.cfm @@ -18,7 +18,7 @@ response = { "OK": false }; try { // Check if Menus table exists - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'payfrit' AND TABLE_NAME = 'Menus' @@ -29,7 +29,7 @@ try { response["MESSAGE"] = "Menus table already exists"; } else { // Create Menus table - queryExecute(" + queryTimed(" CREATE TABLE Menus ( ID INT AUTO_INCREMENT PRIMARY KEY, BusinessID INT NOT NULL, @@ -54,7 +54,7 @@ try { } // Check if MenuID column exists in Categories table - qCatCol = queryExecute(" + qCatCol = queryTimed(" SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' AND TABLE_NAME = 'Categories' @@ -63,7 +63,7 @@ try { if (qCatCol.recordCount == 0) { // Add MenuID column to Categories table - queryExecute(" + queryTimed(" ALTER TABLE Categories ADD COLUMN MenuID INT NULL DEFAULT NULL AFTER BusinessID, ADD INDEX idx_categories_menu (MenuID) diff --git a/api/admin/_scripts/createParentBusiness.cfm b/api/admin/_scripts/createParentBusiness.cfm index a60325d..9603851 100644 --- a/api/admin/_scripts/createParentBusiness.cfm +++ b/api/admin/_scripts/createParentBusiness.cfm @@ -55,18 +55,18 @@ try { } // Create minimal address record (just a placeholder) - queryExecute(" + queryTimed(" INSERT INTO Addresses (Line1, UserID, AddressTypeID, AddedOn) VALUES ('Parent Business - No Physical Location', :userID, 2, NOW()) ", { userID: UserID }, { datasource = "payfrit" }); - qAddr = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" }); + qAddr = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" }); addressId = qAddr.id; // Create parent business (no menu, no hours, just a shell) - queryExecute(" + queryTimed(" INSERT INTO Businesses (Name, UserID, AddressID, ParentBusinessID, BusinessDeliveryZipCodes, AddedOn) VALUES (:name, :userId, :addressId, NULL, '', NOW()) ", { @@ -75,11 +75,11 @@ try { addressId: addressId }, { datasource = "payfrit" }); - qBiz = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" }); + qBiz = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" }); newBusinessID = qBiz.id; // Link address back to business - queryExecute(" + queryTimed(" UPDATE Addresses SET BusinessID = :bizId WHERE ID = :addrId ", { bizId: newBusinessID, @@ -91,7 +91,7 @@ try { for (childID in ChildBusinessIDs) { childID = val(childID); if (childID > 0) { - queryExecute(" + queryTimed(" UPDATE Businesses SET ParentBusinessID = :parentId WHERE ID = :childId ", { parentId: newBusinessID, diff --git a/api/admin/_scripts/debugBigDeansDeactivated.cfm b/api/admin/_scripts/debugBigDeansDeactivated.cfm index f77a444..a52459e 100644 --- a/api/admin/_scripts/debugBigDeansDeactivated.cfm +++ b/api/admin/_scripts/debugBigDeansDeactivated.cfm @@ -8,7 +8,7 @@ bizId = 27; // These are the items that were deactivated by fixBigDeansCategories.cfm deactivatedIds = [11177, 11180, 11183, 11186, 11190, 11193, 11196, 11199, 11204, 11212, 11220, 11259]; -qDeactivated = queryExecute(" +qDeactivated = queryTimed(" SELECT i.ID, i.Name, i.ParentItemID, i.IsActive, i.IsCollapsible, (SELECT COUNT(*) FROM Items c WHERE c.ParentItemID = i.ID) as ChildCount, (SELECT GROUP_CONCAT(c.Name) FROM Items c WHERE c.ParentItemID = i.ID) as Children diff --git a/api/admin/_scripts/debugBigDeansLinks.cfm b/api/admin/_scripts/debugBigDeansLinks.cfm index 708d78e..d0ed727 100644 --- a/api/admin/_scripts/debugBigDeansLinks.cfm +++ b/api/admin/_scripts/debugBigDeansLinks.cfm @@ -6,7 +6,7 @@ bizId = 27; // Get all template links for Big Dean's with item names -qLinks = queryExecute(" +qLinks = queryTimed(" SELECT tl.ItemID as MenuItemID, mi.Name as MenuName, @@ -33,7 +33,7 @@ for (row in qLinks) { } // Get burgers specifically (parent = 11271) -qBurgers = queryExecute(" +qBurgers = queryTimed(" SELECT ID, Name FROM Items WHERE BusinessID = :bizId AND ParentItemID = 11271 AND IsActive = 1 ORDER BY SortOrder @@ -42,7 +42,7 @@ qBurgers = queryExecute(" burgers = []; for (row in qBurgers) { // Get templates for this burger - qBurgerTemplates = queryExecute(" + qBurgerTemplates = queryTimed(" SELECT tl.TemplateItemID, t.Name as TemplateName FROM lt_ItemID_TemplateItemID tl JOIN Items t ON t.ItemID = tl.TemplateItemID diff --git a/api/admin/_scripts/debugBigDeansMenu.cfm b/api/admin/_scripts/debugBigDeansMenu.cfm index 884353e..b06638c 100644 --- a/api/admin/_scripts/debugBigDeansMenu.cfm +++ b/api/admin/_scripts/debugBigDeansMenu.cfm @@ -6,7 +6,7 @@ businessID = 27; // Run the EXACT query from getForBuilder.cfm -qCategories = queryExecute(" +qCategories = queryTimed(" SELECT DISTINCT p.ItemID as CategoryID, p.Name as Name, @@ -31,12 +31,12 @@ for (c in qCategories) { } // Also check raw counts -rawCount = queryExecute(" +rawCount = queryTimed(" SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bizId AND ParentItemID = 0 AND IsActive = 1 ", { bizId: businessID }); -childrenCount = queryExecute(" +childrenCount = queryTimed(" SELECT COUNT(DISTINCT c.ParentItemID) as cnt FROM Items c INNER JOIN Items p ON p.ItemID = c.ParentItemID diff --git a/api/admin/_scripts/debugBigDeansTemplates.cfm b/api/admin/_scripts/debugBigDeansTemplates.cfm index 35c2603..72506b0 100644 --- a/api/admin/_scripts/debugBigDeansTemplates.cfm +++ b/api/admin/_scripts/debugBigDeansTemplates.cfm @@ -6,7 +6,7 @@ bizId = 27; // Get all template links for Big Dean's -qLinks = queryExecute(" +qLinks = queryTimed(" SELECT tl.ItemID as MenuItemID, mi.Name as MenuName, @@ -36,7 +36,7 @@ for (row in qLinks) { } // Get all templates that exist for this business -qTemplates = queryExecute(" +qTemplates = queryTimed(" SELECT ID, Name, IsActive, ParentItemID FROM Items WHERE BusinessID = :bizId diff --git a/api/admin/_scripts/debugBigDeansTemplates2.cfm b/api/admin/_scripts/debugBigDeansTemplates2.cfm index b61e913..c2a1025 100644 --- a/api/admin/_scripts/debugBigDeansTemplates2.cfm +++ b/api/admin/_scripts/debugBigDeansTemplates2.cfm @@ -8,7 +8,7 @@ bizId = 27; // Check the template items themselves (IDs from lt_ItemID_TemplateItemID) templateIds = "11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227"; -qTemplates = queryExecute(" +qTemplates = queryTimed(" SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID FROM Items WHERE ID IN (#templateIds#) @@ -29,7 +29,7 @@ for (row in qTemplates) { // Also check what other templates might exist for burgers // Look for items that are in lt_ItemID_TemplateItemID but NOT linked to burgers -qMissingTemplates = queryExecute(" +qMissingTemplates = queryTimed(" SELECT DISTINCT t.ItemID, t.Name, t.IsCollapsible, t.IsActive FROM Items t WHERE t.BusinessID = :bizId @@ -52,7 +52,7 @@ for (row in qMissingTemplates) { } // What templates SHOULD burgers have? Let's see all templates used by ANY item -qAllTemplateUsage = queryExecute(" +qAllTemplateUsage = queryTimed(" SELECT t.ItemID, t.Name, COUNT(tl.ItemID) as UsageCount FROM lt_ItemID_TemplateItemID tl JOIN Items t ON t.ItemID = tl.TemplateItemID diff --git a/api/admin/_scripts/debugBigDeansTemplates3.cfm b/api/admin/_scripts/debugBigDeansTemplates3.cfm index 66b34ca..1f33840 100644 --- a/api/admin/_scripts/debugBigDeansTemplates3.cfm +++ b/api/admin/_scripts/debugBigDeansTemplates3.cfm @@ -6,7 +6,7 @@ bizId = 27; // Get the template items themselves -qTemplates = queryExecute(" +qTemplates = queryTimed(" SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID FROM Items WHERE ID IN (11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227) @@ -26,7 +26,7 @@ for (row in qTemplates) { } // What templates are used by burgers vs all items? -qBurgerLinks = queryExecute(" +qBurgerLinks = queryTimed(" SELECT mi.ID, mi.Name, GROUP_CONCAT(t.Name ORDER BY tl.SortOrder) as Templates FROM Items mi JOIN lt_ItemID_TemplateItemID tl ON tl.ItemID = mi.ID @@ -48,7 +48,7 @@ for (row in qBurgerLinks) { // Also check: are there templates that SHOULD be linked to burgers? // (e.g., Add Cheese, etc.) -qCheeseTemplate = queryExecute(" +qCheeseTemplate = queryTimed(" SELECT ID, Name, ParentItemID, IsActive FROM Items WHERE BusinessID = :bizId diff --git a/api/admin/_scripts/debugBusinesses.cfm b/api/admin/_scripts/debugBusinesses.cfm index 51dd741..13a8564 100644 --- a/api/admin/_scripts/debugBusinesses.cfm +++ b/api/admin/_scripts/debugBusinesses.cfm @@ -25,7 +25,7 @@ - + - + - + - + - + - + - + - - - + + + 0 ? qState.ID : 5; // Default to 5 if not found // Check if Big Dean's already has an address - existingAddr = queryExecute(" + existingAddr = queryTimed(" SELECT ID FROM Addresses WHERE BusinessID = :bizId AND UserID = 0 ", { bizId: businessId }); if (existingAddr.recordCount == 0) { // Insert new address - queryExecute(" + queryTimed(" INSERT INTO Addresses (UserID, BusinessID, AddressTypeID, Line1, City, StateID, ZIPCode, IsDeleted, AddedOn) VALUES (0, :bizId, '2', :line1, :city, :stateId, :zip, 0, NOW()) ", { @@ -37,7 +37,7 @@ try { response["ADDRESS_ACTION"] = "inserted"; } else { // Update existing address - queryExecute(" + queryTimed(" UPDATE Addresses SET Line1 = :line1, City = :city, StateID = :stateId, ZIPCode = :zip WHERE BusinessID = :bizId AND UserID = 0 @@ -52,7 +52,7 @@ try { } // Check existing hours for this business - existingHours = queryExecute(" + existingHours = queryTimed(" SELECT COUNT(*) as cnt FROM Hours WHERE BusinessID = :bizId ", { bizId: businessId }); @@ -64,39 +64,39 @@ try { // Sun: 11am-10pm (day 1) // Sunday (1): 11am-10pm - queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 1, '11:00:00', '22:00:00')", { bizId: businessId }); + queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 1, '11:00:00', '22:00:00')", { bizId: businessId }); // Monday (2): 11am-10pm - queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 2, '11:00:00', '22:00:00')", { bizId: businessId }); + queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 2, '11:00:00', '22:00:00')", { bizId: businessId }); // Tuesday (3): 11am-10pm - queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 3, '11:00:00', '22:00:00')", { bizId: businessId }); + queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 3, '11:00:00', '22:00:00')", { bizId: businessId }); // Wednesday (4): 11am-10pm - queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 4, '11:00:00', '22:00:00')", { bizId: businessId }); + queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 4, '11:00:00', '22:00:00')", { bizId: businessId }); // Thursday (5): 11am-10pm - queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 5, '11:00:00', '22:00:00')", { bizId: businessId }); + queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 5, '11:00:00', '22:00:00')", { bizId: businessId }); // Friday (6): 11am-11pm - queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 6, '11:00:00', '23:00:00')", { bizId: businessId }); + queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 6, '11:00:00', '23:00:00')", { bizId: businessId }); // Saturday (7): 11am-11pm - queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 7, '11:00:00', '23:00:00')", { bizId: businessId }); + queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 7, '11:00:00', '23:00:00')", { bizId: businessId }); response["HOURS_ACTION"] = "inserted 7 days"; } else { // Update existing hours // Mon-Thu: 11am-10pm - queryExecute("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '22:00:00' WHERE BusinessID = :bizId AND DayID IN (1, 2, 3, 4, 5)", { bizId: businessId }); + queryTimed("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '22:00:00' WHERE BusinessID = :bizId AND DayID IN (1, 2, 3, 4, 5)", { bizId: businessId }); // Fri-Sat: 11am-11pm - queryExecute("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '23:00:00' WHERE BusinessID = :bizId AND DayID IN (6, 7)", { bizId: businessId }); + queryTimed("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '23:00:00' WHERE BusinessID = :bizId AND DayID IN (6, 7)", { bizId: businessId }); response["HOURS_ACTION"] = "updated"; } // Update phone on Businesses table (if column exists) try { - queryExecute("UPDATE Businesses SET Phone = :phone WHERE ID = :bizId", { + queryTimed("UPDATE Businesses SET Phone = :phone WHERE ID = :bizId", { phone: "(310) 393-2666", bizId: businessId }); @@ -106,14 +106,14 @@ try { } // Verify the data - address = queryExecute(" + address = queryTimed(" SELECT a.*, s.Abbreviation FROM Addresses a LEFT JOIN tt_States s ON s.ID = a.StateID WHERE a.BusinessID = :bizId AND a.UserID = 0 ", { bizId: businessId }); - hours = queryExecute(" + hours = queryTimed(" SELECT h.*, d.Name AS DayName FROM Hours h JOIN tt_Days d ON d.ID = h.DayID diff --git a/api/admin/_scripts/setupBigDeansStations.cfm b/api/admin/_scripts/setupBigDeansStations.cfm index b85c9fa..bcbea0d 100644 --- a/api/admin/_scripts/setupBigDeansStations.cfm +++ b/api/admin/_scripts/setupBigDeansStations.cfm @@ -8,19 +8,19 @@ response = { "OK": false }; try { // Check if Big Dean's already has stations - existing = queryExecute(" + existing = queryTimed(" SELECT COUNT(*) as cnt FROM Stations WHERE BusinessID = :bizId ", { bizId: businessId }); if (existing.cnt == 0) { // Insert Kitchen station - queryExecute(" + queryTimed(" INSERT INTO Stations (BusinessID, Name, Color, SortOrder, IsActive) VALUES (:bizId, 'Kitchen', :color1, 1, 1) ", { bizId: businessId, color1: "##FF5722" }); // Insert Bar station - queryExecute(" + queryTimed(" INSERT INTO Stations (BusinessID, Name, Color, SortOrder, IsActive) VALUES (:bizId, 'Bar', :color2, 2, 1) ", { bizId: businessId, color2: "##2196F3" }); @@ -31,7 +31,7 @@ try { } // Get current stations - stations = queryExecute(" + stations = queryTimed(" SELECT ID, Name, Color, SortOrder FROM Stations WHERE BusinessID = :bizId AND IsActive = 1 diff --git a/api/admin/_scripts/setupLazyDaisyBeacons.cfm b/api/admin/_scripts/setupLazyDaisyBeacons.cfm index 578d08d..278b583 100644 --- a/api/admin/_scripts/setupLazyDaisyBeacons.cfm +++ b/api/admin/_scripts/setupLazyDaisyBeacons.cfm @@ -9,21 +9,21 @@ try { lazyDaisyID = 37; // Get all beacons - qBeacons = queryExecute("SELECT ID, UUID FROM Beacons", {}, { datasource: "payfrit" }); + qBeacons = queryTimed("SELECT ID, UUID FROM Beacons", {}, { datasource: "payfrit" }); response.steps.append("Found " & qBeacons.recordCount & " beacons"); // Create service point for Table 1 if it doesn't exist - qSP = queryExecute(" + qSP = queryTimed(" SELECT ID FROM ServicePoints WHERE BusinessID = :bizID AND Name = 'Table 1' ", { bizID: lazyDaisyID }, { datasource: "payfrit" }); if (qSP.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO ServicePoints (BusinessID, Name) VALUES (:bizID, 'Table 1') ", { bizID: lazyDaisyID }, { datasource: "payfrit" }); - qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qSP = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); servicePointID = qSP.id; response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")"); } else { @@ -36,13 +36,13 @@ try { beaconID = qBeacons.ID[i]; // Unassign this beacon from any other service point first - queryExecute(" + queryTimed(" UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL WHERE BeaconID = :beaconID ", { beaconID: beaconID }, { datasource: "payfrit" }); // Assign beacon to Table 1 service point - queryExecute(" + queryTimed(" UPDATE ServicePoints SET BeaconID = :beaconID, AssignedByUserID = 1 WHERE ID = :spID AND BusinessID = :bizID ", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" }); @@ -50,7 +50,7 @@ try { } // Get final status - qFinal = queryExecute(" + qFinal = queryTimed(" SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID, b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName, biz.Name AS BusinessName diff --git a/api/admin/_scripts/setupModifierTemplates.cfm b/api/admin/_scripts/setupModifierTemplates.cfm index 340b872..d15748c 100644 --- a/api/admin/_scripts/setupModifierTemplates.cfm +++ b/api/admin/_scripts/setupModifierTemplates.cfm @@ -20,7 +20,7 @@ response = { "OK": false, "steps": [] }; try { // Step 1: Add IsModifierTemplate column if it doesn't exist try { - queryExecute(" + queryTimed(" ALTER TABLE Items ADD COLUMN IsModifierTemplate TINYINT(1) DEFAULT 0 ", {}, { datasource: "payfrit" }); arrayAppend(response.steps, "Added IsModifierTemplate column"); @@ -34,7 +34,7 @@ try { // Step 2: Create lt_ItemID_TemplateItemID table if it doesn't exist try { - queryExecute(" + queryTimed(" CREATE TABLE IF NOT EXISTS lt_ItemID_TemplateItemID ( ID INT AUTO_INCREMENT PRIMARY KEY, ItemID INT NOT NULL, diff --git a/api/admin/_scripts/setupStations.cfm b/api/admin/_scripts/setupStations.cfm index 1d9af68..31f2b37 100644 --- a/api/admin/_scripts/setupStations.cfm +++ b/api/admin/_scripts/setupStations.cfm @@ -10,7 +10,7 @@ - - @@ -38,7 +38,7 @@ - @@ -46,12 +46,12 @@ - - - - + -qTask = queryExecute(" +qTask = queryTimed(" SELECT ID, TaskTypeID, ClaimedByUserID, CompletedOn FROM Tasks WHERE ID = 57 diff --git a/api/admin/_scripts/updateBeaconMapping.cfm b/api/admin/_scripts/updateBeaconMapping.cfm index 5c5221a..b989646 100644 --- a/api/admin/_scripts/updateBeaconMapping.cfm +++ b/api/admin/_scripts/updateBeaconMapping.cfm @@ -9,27 +9,27 @@ oldBusinessId = 37; // previous mapping newBusinessId = 17; // Remove old mapping -queryExecute(" +queryTimed(" DELETE FROM lt_BeaconsID_BusinessesID WHERE BeaconID = :beaconId AND BusinessID = :oldBizId ", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" }); // Add new mapping -queryExecute(" +queryTimed(" INSERT INTO lt_BeaconsID_BusinessesID (BeaconID, BusinessID) VALUES (:beaconId, :newBizId) ON DUPLICATE KEY UPDATE ID = ID ", { beaconId: beaconId, newBizId: newBusinessId }, { datasource: "payfrit" }); // Clear ServicePoints.BeaconID for old business where this beacon was assigned -queryExecute(" +queryTimed(" UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL WHERE BeaconID = :beaconId AND BusinessID = :oldBizId ", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" }); // Get current state -q = queryExecute(" +q = queryTimed(" SELECT b.ID AS BeaconID, b.UUID, diff --git a/api/admin/_scripts/updateBigDeans.cfm b/api/admin/_scripts/updateBigDeans.cfm index 94558bb..f14641c 100644 --- a/api/admin/_scripts/updateBigDeans.cfm +++ b/api/admin/_scripts/updateBigDeans.cfm @@ -12,7 +12,7 @@ hours = "Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm"; try { // Update phone and hours on Businesses table - queryExecute(" + queryTimed(" UPDATE Businesses SET Phone = :phone, Hours = :hours @@ -24,14 +24,14 @@ try { }, { datasource: "payfrit" }); // Update or insert address in Addresses table - qAddr = queryExecute(" + qAddr = queryTimed(" SELECT ID FROM Addresses WHERE BusinessID = :bizId AND IsDeleted = 0 LIMIT 1 ", { bizId: businessId }, { datasource: "payfrit" }); if (qAddr.recordCount > 0) { - queryExecute(" + queryTimed(" UPDATE Addresses SET Line1 = :line1, City = :city, ZIPCode = :zip WHERE ID = :addrId @@ -42,7 +42,7 @@ try { addrId: qAddr.ID }, { datasource: "payfrit" }); } else { - queryExecute(" + queryTimed(" INSERT INTO Addresses (BusinessID, UserID, AddressTypeID, Line1, City, ZIPCode, AddedOn) VALUES (:bizId, 0, 'business', :line1, :city, :zip, NOW()) ", { @@ -54,7 +54,7 @@ try { } // Get updated record - updated = queryExecute(" + updated = queryTimed(" SELECT ID, Name, Phone, Hours FROM Businesses WHERE ID = :bizId diff --git a/api/admin/perf-dashboard.cfm b/api/admin/perf-dashboard.cfm new file mode 100644 index 0000000..61469fc --- /dev/null +++ b/api/admin/perf-dashboard.cfm @@ -0,0 +1,313 @@ + + + +// Localhost-only protection +remoteAddr = cgi.REMOTE_ADDR; +if (remoteAddr != "127.0.0.1" && remoteAddr != "::1" && remoteAddr != "0:0:0:0:0:0:0:1" && remoteAddr != "10.10.0.2") { + writeOutput("Forbidden"); abort; +} + + + + + + +API Performance Dashboard + + + + +

API Performance Dashboard

+ +
+ + + +
+ + +
+ +
+ +
Loading...
+ + + +
+ DB time + App time +
+ + + + + + + + + + diff --git a/api/admin/perf.cfm b/api/admin/perf.cfm new file mode 100644 index 0000000..5c094fd --- /dev/null +++ b/api/admin/perf.cfm @@ -0,0 +1,179 @@ + + + + + + +function apiAbort(payload) { + writeOutput(serializeJSON(payload)); + abort; +} + +// Localhost-only protection +remoteAddr = cgi.REMOTE_ADDR; +if (remoteAddr != "127.0.0.1" && remoteAddr != "::1" && remoteAddr != "0:0:0:0:0:0:0:1" && remoteAddr != "10.10.0.2") { + apiAbort({ "OK": false, "ERROR": "forbidden" }); +} + +try { + // Parse parameters + view = structKeyExists(url, "view") ? lcase(url.view) : "count"; + hours = structKeyExists(url, "hours") ? val(url.hours) : 24; + if (hours <= 0 || hours > 720) hours = 24; + limitRows = structKeyExists(url, "limit") ? val(url.limit) : 20; + if (limitRows <= 0 || limitRows > 100) limitRows = 20; + + // Flush any buffered metrics first + flushPerfBuffer(); + + response = { "OK": true, "VIEW": view, "HOURS": hours }; + + if (view == "count") { + // Top endpoints by call count + q = queryExecute(" + SELECT + Endpoint, + COUNT(*) as Calls, + ROUND(AVG(TotalMs)) as AvgMs, + ROUND(AVG(DbMs)) as AvgDbMs, + ROUND(AVG(AppMs)) as AvgAppMs, + MAX(TotalMs) as MaxMs, + ROUND(AVG(QueryCount), 1) as AvgQueries, + ROUND(AVG(ResponseBytes)) as AvgBytes + FROM ApiPerfLogs + WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR) + GROUP BY Endpoint + ORDER BY Calls DESC + LIMIT :lim + ", { + hours: { value: hours, cfsqltype: "cf_sql_integer" }, + lim: { value: limitRows, cfsqltype: "cf_sql_integer" } + }, { datasource: "payfrit" }); + + rows = []; + for (row in q) { + arrayAppend(rows, { + "Endpoint": row.Endpoint, + "Calls": row.Calls, + "AvgMs": row.AvgMs, + "AvgDbMs": row.AvgDbMs, + "AvgAppMs": row.AvgAppMs, + "MaxMs": row.MaxMs, + "AvgQueries": row.AvgQueries, + "AvgBytes": row.AvgBytes + }); + } + response["DATA"] = rows; + + } else if (view == "latency") { + // Top endpoints by average latency + q = queryExecute(" + SELECT + Endpoint, + COUNT(*) as Calls, + ROUND(AVG(TotalMs)) as AvgMs, + ROUND(AVG(DbMs)) as AvgDbMs, + ROUND(AVG(AppMs)) as AvgAppMs, + MAX(TotalMs) as MaxMs, + ROUND(AVG(QueryCount), 1) as AvgQueries + FROM ApiPerfLogs + WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR) + GROUP BY Endpoint + HAVING Calls >= 3 + ORDER BY AvgMs DESC + LIMIT :lim + ", { + hours: { value: hours, cfsqltype: "cf_sql_integer" }, + lim: { value: limitRows, cfsqltype: "cf_sql_integer" } + }, { datasource: "payfrit" }); + + rows = []; + for (row in q) { + arrayAppend(rows, { + "Endpoint": row.Endpoint, + "Calls": row.Calls, + "AvgMs": row.AvgMs, + "AvgDbMs": row.AvgDbMs, + "AvgAppMs": row.AvgAppMs, + "MaxMs": row.MaxMs, + "AvgQueries": row.AvgQueries + }); + } + response["DATA"] = rows; + + } else if (view == "slow") { + // Slowest individual requests + q = queryExecute(" + SELECT Endpoint, TotalMs, DbMs, AppMs, QueryCount, ResponseBytes, + BusinessID, UserID, LoggedAt + FROM ApiPerfLogs + WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR) + ORDER BY TotalMs DESC + LIMIT :lim + ", { + hours: { value: hours, cfsqltype: "cf_sql_integer" }, + lim: { value: limitRows, cfsqltype: "cf_sql_integer" } + }, { datasource: "payfrit" }); + + rows = []; + for (row in q) { + arrayAppend(rows, { + "Endpoint": row.Endpoint, + "TotalMs": row.TotalMs, + "DbMs": row.DbMs, + "AppMs": row.AppMs, + "QueryCount": row.QueryCount, + "ResponseBytes": row.ResponseBytes, + "BusinessID": row.BusinessID, + "UserID": row.UserID, + "LoggedAt": dateTimeFormat(row.LoggedAt, "yyyy-mm-dd HH:nn:ss") + }); + } + response["DATA"] = rows; + + } else if (view == "summary") { + // Overall summary stats + q = queryExecute(" + SELECT + COUNT(*) as TotalRequests, + COUNT(DISTINCT Endpoint) as UniqueEndpoints, + ROUND(AVG(TotalMs)) as OverallAvgMs, + MAX(TotalMs) as OverallMaxMs, + ROUND(AVG(DbMs)) as OverallAvgDbMs, + ROUND(AVG(AppMs)) as OverallAvgAppMs, + ROUND(AVG(QueryCount), 1) as OverallAvgQueries, + MIN(LoggedAt) as FirstLog, + MAX(LoggedAt) as LastLog + FROM ApiPerfLogs + WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR) + ", { + hours: { value: hours, cfsqltype: "cf_sql_integer" } + }, { datasource: "payfrit" }); + + response["DATA"] = { + "TotalRequests": q.TotalRequests, + "UniqueEndpoints": q.UniqueEndpoints, + "OverallAvgMs": q.OverallAvgMs, + "OverallMaxMs": q.OverallMaxMs, + "OverallAvgDbMs": q.OverallAvgDbMs, + "OverallAvgAppMs": q.OverallAvgAppMs, + "OverallAvgQueries": q.OverallAvgQueries, + "FirstLog": isDate(q.FirstLog) ? dateTimeFormat(q.FirstLog, "yyyy-mm-dd HH:nn:ss") : "", + "LastLog": isDate(q.LastLog) ? dateTimeFormat(q.LastLog, "yyyy-mm-dd HH:nn:ss") : "" + }; + + } else { + apiAbort({ "OK": false, "ERROR": "invalid_view", "MESSAGE": "Use ?view=count|latency|slow|summary" }); + } + + apiAbort(response); + +} catch (any e) { + apiAbort({ + "OK": false, + "ERROR": "server_error", + "MESSAGE": e.message, + "DETAIL": e.detail + }); +} + diff --git a/api/admin/quickTasks/addTypeIdColumn.cfm b/api/admin/quickTasks/addTypeIdColumn.cfm index fdb72fb..6e299d3 100644 --- a/api/admin/quickTasks/addTypeIdColumn.cfm +++ b/api/admin/quickTasks/addTypeIdColumn.cfm @@ -5,7 +5,7 @@ // Add TaskTypeID column to QuickTaskTemplates table if it doesn't exist try { // Check if column exists - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'payfrit' AND TABLE_NAME = 'QuickTaskTemplates' @@ -13,7 +13,7 @@ try { ", [], { datasource: "payfrit" }); if (qCheck.recordCount == 0) { - queryExecute(" + queryTimed(" ALTER TABLE QuickTaskTemplates ADD COLUMN TaskTypeID INT NULL AFTER TaskCategoryID ", [], { datasource: "payfrit" }); diff --git a/api/admin/quickTasks/cleanup.cfm b/api/admin/quickTasks/cleanup.cfm index fb2add7..5867378 100644 --- a/api/admin/quickTasks/cleanup.cfm +++ b/api/admin/quickTasks/cleanup.cfm @@ -6,7 +6,7 @@ // One-time cleanup: delete test tasks and reset try { // Delete tasks 30, 31, 32 (test tasks with bad data) - queryExecute("DELETE FROM Tasks WHERE ID IN (30, 31, 32)", [], { datasource: "payfrit" }); + queryTimed("DELETE FROM Tasks WHERE ID IN (30, 31, 32)", [], { datasource: "payfrit" }); writeOutput(serializeJSON({ "OK": true, diff --git a/api/admin/quickTasks/create.cfm b/api/admin/quickTasks/create.cfm index 82ce682..7ad3c81 100644 --- a/api/admin/quickTasks/create.cfm +++ b/api/admin/quickTasks/create.cfm @@ -48,7 +48,7 @@ try { } // Get template details - qTemplate = queryExecute(" + qTemplate = queryTimed(" SELECT Title as Title, Details as Details, @@ -67,7 +67,7 @@ try { } // Create the task (ClaimedByUserID=0 means unclaimed/pending) - queryExecute(" + queryTimed(" INSERT INTO Tasks ( BusinessID, CategoryID, TaskTypeID, Title, Details, CreatedOn, ClaimedByUserID @@ -83,7 +83,7 @@ try { details: { value: qTemplate.Details, cfsqltype: "cf_sql_longvarchar", null: isNull(qTemplate.Details) } }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); apiAbort({ "OK": true, diff --git a/api/admin/quickTasks/debug.cfm b/api/admin/quickTasks/debug.cfm index d4a936f..fc1ebf4 100644 --- a/api/admin/quickTasks/debug.cfm +++ b/api/admin/quickTasks/debug.cfm @@ -4,7 +4,7 @@ try { - q = queryExecute(" + q = queryTimed(" SELECT ID, Title, Details, TaskCategoryID, ClaimedByUserID, CompletedOn, CreatedOn FROM Tasks WHERE BusinessID = 47 diff --git a/api/admin/quickTasks/delete.cfm b/api/admin/quickTasks/delete.cfm index 883f3a4..236aa21 100644 --- a/api/admin/quickTasks/delete.cfm +++ b/api/admin/quickTasks/delete.cfm @@ -48,7 +48,7 @@ try { } // Verify template exists and belongs to this business - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM QuickTaskTemplates WHERE ID = :id AND BusinessID = :businessID ", { @@ -61,7 +61,7 @@ try { } // Soft delete by setting IsActive to 0 - queryExecute(" + queryTimed(" UPDATE QuickTaskTemplates SET IsActive = 0 WHERE ID = :id ", { diff --git a/api/admin/quickTasks/list.cfm b/api/admin/quickTasks/list.cfm index ce4254e..9e0f36b 100644 --- a/api/admin/quickTasks/list.cfm +++ b/api/admin/quickTasks/list.cfm @@ -43,7 +43,7 @@ try { } // Get quick task templates for this business - q = queryExecute(" + q = queryTimed(" SELECT qt.ID, qt.Name as Name, diff --git a/api/admin/quickTasks/purge.cfm b/api/admin/quickTasks/purge.cfm index 1240ae2..073e71f 100644 --- a/api/admin/quickTasks/purge.cfm +++ b/api/admin/quickTasks/purge.cfm @@ -5,7 +5,7 @@ try { // Delete all Quick Task templates for business 1 - queryExecute("DELETE FROM QuickTaskTemplates WHERE BusinessID = 1", [], { datasource: "payfrit" }); + queryTimed("DELETE FROM QuickTaskTemplates WHERE BusinessID = 1", [], { datasource: "payfrit" }); writeOutput(serializeJSON({ "OK": true, diff --git a/api/admin/quickTasks/save.cfm b/api/admin/quickTasks/save.cfm index 864c6c2..002f3c3 100644 --- a/api/admin/quickTasks/save.cfm +++ b/api/admin/quickTasks/save.cfm @@ -68,7 +68,7 @@ try { if (templateID > 0) { // UPDATE existing template - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM QuickTaskTemplates WHERE ID = :id AND BusinessID = :businessID ", { @@ -80,7 +80,7 @@ try { apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Template not found" }); } - queryExecute(" + queryTimed(" UPDATE QuickTaskTemplates SET Name = :name, Title = :title, @@ -108,7 +108,7 @@ try { } else { // INSERT new template // Get next sort order - qSort = queryExecute(" + qSort = queryTimed(" SELECT COALESCE(MAX(SortOrder), 0) + 1 as nextSort FROM QuickTaskTemplates WHERE BusinessID = :businessID ", { @@ -117,7 +117,7 @@ try { nextSort = qSort.nextSort; - queryExecute(" + queryTimed(" INSERT INTO QuickTaskTemplates ( BusinessID, Name, Title, Details, TaskCategoryID, @@ -136,7 +136,7 @@ try { sortOrder: { value: nextSort, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); apiAbort({ "OK": true, diff --git a/api/admin/quickTasks/setup.cfm b/api/admin/quickTasks/setup.cfm index 9a41840..9ae1d53 100644 --- a/api/admin/quickTasks/setup.cfm +++ b/api/admin/quickTasks/setup.cfm @@ -13,7 +13,7 @@ function apiAbort(required struct payload) { try { // Create QuickTaskTemplates table - queryExecute(" + queryTimed(" CREATE TABLE IF NOT EXISTS QuickTaskTemplates ( ID INT AUTO_INCREMENT PRIMARY KEY, BusinessID INT NOT NULL, diff --git a/api/admin/scheduledTasks/delete.cfm b/api/admin/scheduledTasks/delete.cfm index c58e212..cccb08e 100644 --- a/api/admin/scheduledTasks/delete.cfm +++ b/api/admin/scheduledTasks/delete.cfm @@ -48,7 +48,7 @@ try { } // Verify exists and belongs to business - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM ScheduledTaskDefinitions WHERE ID = :id AND BusinessID = :businessID ", { @@ -61,7 +61,7 @@ try { } // Hard delete the definition - queryExecute(" + queryTimed(" DELETE FROM ScheduledTaskDefinitions WHERE ID = :id ", { id: { value: taskID, cfsqltype: "cf_sql_integer" } diff --git a/api/admin/scheduledTasks/list.cfm b/api/admin/scheduledTasks/list.cfm index 9c2115b..15448d4 100644 --- a/api/admin/scheduledTasks/list.cfm +++ b/api/admin/scheduledTasks/list.cfm @@ -43,7 +43,7 @@ try { } // Get scheduled task definitions for this business - q = queryExecute(" + q = queryTimed(" SELECT st.ID, st.Name as Name, diff --git a/api/admin/scheduledTasks/run.cfm b/api/admin/scheduledTasks/run.cfm index f6ba38c..8a42f0f 100644 --- a/api/admin/scheduledTasks/run.cfm +++ b/api/admin/scheduledTasks/run.cfm @@ -49,7 +49,7 @@ try { } // Get scheduled task definition - qDef = queryExecute(" + qDef = queryTimed(" SELECT Title as Title, Details as Details, @@ -66,7 +66,7 @@ try { } // Create the task (ClaimedByUserID=0 means unclaimed/pending) - queryExecute(" + queryTimed(" INSERT INTO Tasks ( BusinessID, CategoryID, TaskTypeID, Title, Details, CreatedOn, ClaimedByUserID @@ -82,7 +82,7 @@ try { details: { value: qDef.Details, cfsqltype: "cf_sql_longvarchar", null: isNull(qDef.Details) } }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); apiAbort({ "OK": true, diff --git a/api/admin/scheduledTasks/runDue.cfm b/api/admin/scheduledTasks/runDue.cfm index 3e9c074..0bd2d19 100644 --- a/api/admin/scheduledTasks/runDue.cfm +++ b/api/admin/scheduledTasks/runDue.cfm @@ -65,7 +65,7 @@ function calculateNextRun(required string cronExpression) { try { // Find all active scheduled tasks that are due - dueTasks = queryExecute(" + dueTasks = queryTimed(" SELECT ID AS ScheduledTaskID, BusinessID as BusinessID, @@ -84,7 +84,7 @@ try { for (task in dueTasks) { // Create the actual task (ClaimedByUserID=0 means unclaimed/pending) - queryExecute(" + queryTimed(" INSERT INTO Tasks ( BusinessID, CategoryID, TaskTypeID, Title, Details, CreatedOn, ClaimedByUserID @@ -100,7 +100,7 @@ try { details: { value: task.Details, cfsqltype: "cf_sql_longvarchar", null: isNull(task.Details) } }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); // Calculate next run based on schedule type if (task.ScheduleType == "interval_after_completion" && !isNull(task.IntervalMinutes) && task.IntervalMinutes > 0) { @@ -115,7 +115,7 @@ try { nextRun = calculateNextRun(task.CronExpression); } - queryExecute(" + queryTimed(" UPDATE ScheduledTaskDefinitions SET LastRunOn = NOW(), NextRunOn = :nextRun diff --git a/api/admin/scheduledTasks/save.cfm b/api/admin/scheduledTasks/save.cfm index 8db00e1..f390088 100644 --- a/api/admin/scheduledTasks/save.cfm +++ b/api/admin/scheduledTasks/save.cfm @@ -156,7 +156,7 @@ try { if (taskID > 0) { // UPDATE existing - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM ScheduledTaskDefinitions WHERE ID = :id AND BusinessID = :businessID ", { @@ -168,7 +168,7 @@ try { apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Scheduled task not found" }); } - queryExecute(" + queryTimed(" UPDATE ScheduledTaskDefinitions SET Name = :name, Title = :title, @@ -202,7 +202,7 @@ try { } else { // INSERT new - queryExecute(" + queryTimed(" INSERT INTO ScheduledTaskDefinitions ( BusinessID, Name, Title, Details, TaskCategoryID, @@ -224,11 +224,11 @@ try { nextRun: { value: nextRunOn, cfsqltype: "cf_sql_timestamp" } }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); newScheduledTaskID = qNew.newID; // Create the first task immediately - queryExecute(" + queryTimed(" INSERT INTO Tasks ( BusinessID, CategoryID, TaskTypeID, Title, Details, CreatedOn, ClaimedByUserID @@ -244,7 +244,7 @@ try { details: { value: taskDetails, cfsqltype: "cf_sql_longvarchar", null: !len(taskDetails) } }, { datasource: "payfrit" }); - qTask = queryExecute("SELECT LAST_INSERT_ID() as taskID", [], { datasource: "payfrit" }); + qTask = queryTimed("SELECT LAST_INSERT_ID() as taskID", [], { datasource: "payfrit" }); // Now set the NEXT run time (not the immediate one we just created) if (scheduleType == "interval" || scheduleType == "interval_after_completion") { @@ -260,7 +260,7 @@ try { actualNextRun = calculateNextRun(cronExpression); } - queryExecute(" + queryTimed(" UPDATE ScheduledTaskDefinitions SET LastRunOn = NOW(), NextRunOn = :nextRun diff --git a/api/admin/scheduledTasks/setup.cfm b/api/admin/scheduledTasks/setup.cfm index 5408a41..a25d0e2 100644 --- a/api/admin/scheduledTasks/setup.cfm +++ b/api/admin/scheduledTasks/setup.cfm @@ -13,7 +13,7 @@ function apiAbort(required struct payload) { try { // Create ScheduledTaskDefinitions table - queryExecute(" + queryTimed(" CREATE TABLE IF NOT EXISTS ScheduledTaskDefinitions ( ID INT AUTO_INCREMENT PRIMARY KEY, BusinessID INT NOT NULL, @@ -37,7 +37,7 @@ try { // Add new columns if they don't exist (for existing tables) try { - queryExecute(" + queryTimed(" ALTER TABLE ScheduledTaskDefinitions ADD COLUMN ScheduleType VARCHAR(20) DEFAULT 'cron' AFTER CronExpression ", [], { datasource: "payfrit" }); @@ -46,7 +46,7 @@ try { } try { - queryExecute(" + queryTimed(" ALTER TABLE ScheduledTaskDefinitions ADD COLUMN IntervalMinutes INT NULL AFTER ScheduleType ", [], { datasource: "payfrit" }); diff --git a/api/admin/scheduledTasks/toggle.cfm b/api/admin/scheduledTasks/toggle.cfm index e28df84..f72ce7a 100644 --- a/api/admin/scheduledTasks/toggle.cfm +++ b/api/admin/scheduledTasks/toggle.cfm @@ -98,7 +98,7 @@ try { } // Verify exists and get cron expression and schedule type - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID, CronExpression as CronExpression, COALESCE(ScheduleType, 'cron') as ScheduleType, IntervalMinutes as IntervalMinutes @@ -128,7 +128,7 @@ try { // Update status if (isActive) { - queryExecute(" + queryTimed(" UPDATE ScheduledTaskDefinitions SET IsActive = :isActive, NextRunOn = :nextRun @@ -139,7 +139,7 @@ try { id: { value: taskID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); } else { - queryExecute(" + queryTimed(" UPDATE ScheduledTaskDefinitions SET IsActive = :isActive WHERE ID = :id ", { diff --git a/api/auth/avatar.cfm b/api/auth/avatar.cfm index 932d954..4b15e31 100644 --- a/api/auth/avatar.cfm +++ b/api/auth/avatar.cfm @@ -50,7 +50,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U if (len(userToken)) { try { - qTok = queryExecute( + qTok = queryTimed( "SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1", [ { value = userToken, cfsqltype = "cf_sql_varchar" } ], { datasource = "payfrit" } diff --git a/api/auth/completeProfile.cfm b/api/auth/completeProfile.cfm index b398a99..537bda3 100644 --- a/api/auth/completeProfile.cfm +++ b/api/auth/completeProfile.cfm @@ -70,7 +70,7 @@ try { } // Check if email is already used by another verified account - qEmailCheck = queryExecute(" + qEmailCheck = queryTimed(" SELECT ID FROM Users WHERE EmailAddress = :email AND IsEmailVerified = 1 @@ -86,13 +86,13 @@ try { } // Get current user UUID for email confirmation link - qUser = queryExecute(" + qUser = queryTimed(" SELECT UUID FROM Users WHERE ID = :userId ", { userId: { value: userId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); // Update user profile AND mark account as verified/active // This completes the signup process - queryExecute(" + queryTimed(" UPDATE Users SET FirstName = :firstName, LastName = :lastName, diff --git a/api/auth/login.cfm b/api/auth/login.cfm index 82bf4a3..3997635 100644 --- a/api/auth/login.cfm +++ b/api/auth/login.cfm @@ -53,7 +53,7 @@ if (!len(username) || !len(password)) { } try { - q = queryExecute( + q = queryTimed( " SELECT ID, FirstName FROM Users @@ -81,7 +81,7 @@ try { token = replace(createUUID(), "-", "", "all"); - queryExecute( + queryTimed( "INSERT INTO UserTokens (UserID, Token) VALUES (?, ?)", [ { value = q.ID, cfsqltype = "cf_sql_integer" }, diff --git a/api/auth/loginOTP.cfm b/api/auth/loginOTP.cfm index 38b59d7..35cc2fc 100644 --- a/api/auth/loginOTP.cfm +++ b/api/auth/loginOTP.cfm @@ -52,7 +52,7 @@ try { } // Find verified account with this phone - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, UUID FROM Users WHERE ContactNumber = :phone @@ -68,7 +68,7 @@ try { userUUID = qUser.UUID; if (!len(trim(userUUID))) { userUUID = replace(createUUID(), "-", "", "all"); - queryExecute(" + queryTimed(" UPDATE Users SET UUID = :uuid WHERE ID = :userId ", { uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" }, @@ -82,7 +82,7 @@ try { && structKeyExists(application, "MAGIC_OTP_CODE") && len(application.MAGIC_OTP_CODE)) { otp = application.MAGIC_OTP_CODE; } - queryExecute(" + queryTimed(" UPDATE Users SET MobileVerifyCode = :otp WHERE ID = :userId diff --git a/api/auth/profile.cfm b/api/auth/profile.cfm index 6ee50cc..29f1d41 100644 --- a/api/auth/profile.cfm +++ b/api/auth/profile.cfm @@ -38,7 +38,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U userToken = getHeader("X-User-Token"); if (len(userToken)) { try { - qTok = queryExecute( + qTok = queryTimed( "SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1", [ { value = userToken, cfsqltype = "cf_sql_varchar" } ], { datasource = "payfrit" } @@ -57,7 +57,7 @@ if (userId <= 0) { // Handle GET - return profile if (cgi.REQUEST_METHOD == "GET") { try { - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName, @@ -124,14 +124,14 @@ if (cgi.REQUEST_METHOD == "POST") { } // Execute update - queryExecute(" + queryTimed(" UPDATE Users SET #arrayToList(updates, ', ')# WHERE ID = :userId ", params); // Return updated profile - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName, diff --git a/api/auth/sendLoginOTP.cfm b/api/auth/sendLoginOTP.cfm index d34d0cc..ae2595a 100644 --- a/api/auth/sendLoginOTP.cfm +++ b/api/auth/sendLoginOTP.cfm @@ -37,7 +37,7 @@ genericResponse = { "OK": true, "MESSAGE": "If an account exists, a code has bee try { // Look up user by email - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName FROM Users WHERE EmailAddress = :email @@ -56,7 +56,7 @@ try { userId = qUser.ID; // Rate limit: max 3 codes per user in last 10 minutes - qRateCheck = queryExecute(" + qRateCheck = queryTimed(" SELECT COUNT(*) AS cnt FROM OTPCodes WHERE UserID = :userId @@ -81,7 +81,7 @@ try { } // Store in DB with 10-minute expiry - queryExecute(" + queryTimed(" INSERT INTO OTPCodes (UserID, Code, ExpiresAt) VALUES (:userId, :code, DATE_ADD(NOW(), INTERVAL 10 MINUTE)) ", { diff --git a/api/auth/sendOTP.cfm b/api/auth/sendOTP.cfm index a4b46c9..d4a97a7 100644 --- a/api/auth/sendOTP.cfm +++ b/api/auth/sendOTP.cfm @@ -56,7 +56,7 @@ try { // Check if phone already has a COMPLETE account (verified AND has profile info) // An account is only "complete" if they have a first name (meaning they finished signup) - qExisting = queryExecute(" + qExisting = queryTimed(" SELECT ID, UUID, FirstName FROM Users WHERE ContactNumber = :phone @@ -72,7 +72,7 @@ try { // Check for incomplete account with this phone (verified but no profile, OR unverified) // These accounts can be reused for signup - qIncomplete = queryExecute(" + qIncomplete = queryTimed(" SELECT ID, UUID FROM Users WHERE ContactNumber = :phone @@ -90,7 +90,7 @@ try { if (qIncomplete.recordCount > 0) { // Update existing incomplete record with new OTP and reset for re-registration userUUID = qIncomplete.UUID; - queryExecute(" + queryTimed(" UPDATE Users SET MobileVerifyCode = :otp, IsContactVerified = 0, @@ -103,7 +103,7 @@ try { } else { // Create new user record userUUID = replace(createUUID(), "-", "", "all"); - queryExecute(" + queryTimed(" INSERT INTO Users ( ContactNumber, UUID, diff --git a/api/auth/validateToken.cfm b/api/auth/validateToken.cfm index ca668a7..a1b5572 100644 --- a/api/auth/validateToken.cfm +++ b/api/auth/validateToken.cfm @@ -32,7 +32,7 @@ try { } // Look up the token - qToken = queryExecute(" + qToken = queryTimed(" SELECT ut.UserID, u.FirstName, u.LastName FROM UserTokens ut JOIN Users u ON u.ID = ut.UserID @@ -47,7 +47,7 @@ try { userID = qToken.UserID; // Determine if user is a worker (has any active employment) - qWorker = queryExecute(" + qWorker = queryTimed(" SELECT COUNT(*) as cnt FROM Employees WHERE UserID = :userID AND IsActive = 1 diff --git a/api/auth/verifyEmailOTP.cfm b/api/auth/verifyEmailOTP.cfm index b1b7f1f..f7ac373 100644 --- a/api/auth/verifyEmailOTP.cfm +++ b/api/auth/verifyEmailOTP.cfm @@ -36,7 +36,7 @@ if (!len(email) || !len(code)) { try { // Look up user by email - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName FROM Users WHERE EmailAddress = :email @@ -53,7 +53,7 @@ try { userId = qUser.ID; // Check for valid OTP in OTPCodes table - qOTP = queryExecute(" + qOTP = queryTimed(" SELECT ID FROM OTPCodes WHERE UserID = :userId @@ -72,7 +72,7 @@ try { } // Mark OTP as used - queryExecute(" + queryTimed(" UPDATE OTPCodes SET UsedAt = NOW() WHERE ID = :otpId @@ -83,7 +83,7 @@ try { // Create auth token (same as login.cfm) token = replace(createUUID(), "-", "", "all"); - queryExecute( + queryTimed( "INSERT INTO UserTokens (UserID, Token) VALUES (?, ?)", [ { value: userId, cfsqltype: "cf_sql_integer" }, diff --git a/api/auth/verifyLoginOTP.cfm b/api/auth/verifyLoginOTP.cfm index 128a1f8..0d2da84 100644 --- a/api/auth/verifyLoginOTP.cfm +++ b/api/auth/verifyLoginOTP.cfm @@ -39,7 +39,7 @@ try { // Find verified user with matching UUID and OTP // Magic OTP only bypasses Twilio SMS (in loginOTP.cfm), not OTP verification - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName, LastName FROM Users WHERE UUID = :uuid @@ -53,7 +53,7 @@ try { if (qUser.recordCount == 0) { // Check if UUID exists but OTP is wrong - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM Users WHERE UUID = :uuid AND IsContactVerified = 1 ", { uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" }); @@ -65,7 +65,7 @@ try { } // Clear the OTP (one-time use) - queryExecute(" + queryTimed(" UPDATE Users SET MobileVerifyCode = '' WHERE ID = :userId @@ -73,7 +73,7 @@ try { // Create auth token token = replace(createUUID(), "-", "", "all"); - queryExecute(" + queryTimed(" INSERT INTO UserTokens (UserID, Token) VALUES (:userId, :token) ", { userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" }, diff --git a/api/auth/verifyOTP.cfm b/api/auth/verifyOTP.cfm index 35a6af4..5704783 100644 --- a/api/auth/verifyOTP.cfm +++ b/api/auth/verifyOTP.cfm @@ -42,7 +42,7 @@ try { // Find unverified user with matching UUID and OTP // Magic OTP only bypasses Twilio SMS (in sendOTP.cfm), not OTP verification - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName, LastName, EmailAddress, IsEmailVerified FROM Users WHERE UUID = :uuid @@ -56,7 +56,7 @@ try { if (qUser.recordCount == 0) { // Check if UUID exists but OTP is wrong - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM Users WHERE UUID = :uuid AND IsContactVerified = 0 ", { uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" }); @@ -69,7 +69,7 @@ try { // Clear the OTP code (one-time use) but DON'T mark as verified yet // Account will be marked verified after profile completion - queryExecute(" + queryTimed(" UPDATE Users SET MobileVerifyCode = '' WHERE ID = :userId @@ -77,7 +77,7 @@ try { // Create auth token (needed for completeProfile call) token = replace(createUUID(), "-", "", "all"); - queryExecute(" + queryTimed(" INSERT INTO UserTokens (UserID, Token) VALUES (:userId, :token) ", { userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" }, diff --git a/api/beacons/save.cfm b/api/beacons/save.cfm index 6083941..cfc0de2 100644 --- a/api/beacons/save.cfm +++ b/api/beacons/save.cfm @@ -35,7 +35,7 @@ if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) || } // Verify the business exists -qBiz = queryExecute( +qBiz = queryTimed( "SELECT ID FROM Businesses WHERE ID = ? LIMIT 1", [ { value=request.BusinessID, cfsqltype="cf_sql_integer" } ], { datasource="payfrit" } @@ -65,7 +65,7 @@ if (structKeyExists(data, "IsActive")) { // App is authoritative: if UUID exists, treat as update (overwrite) if (beaconId EQ 0 && len(uuid) GT 0) { - qExisting = queryExecute( + qExisting = queryTimed( "SELECT ID FROM Beacons WHERE UUID = ? LIMIT 1", [ { value=uuid, cfsqltype="cf_sql_varchar" } ], { datasource="payfrit" } diff --git a/api/businesses/get.cfm b/api/businesses/get.cfm index b576664..f0c002f 100644 --- a/api/businesses/get.cfm +++ b/api/businesses/get.cfm @@ -33,7 +33,7 @@ try { } // Get business details - q = queryExecute(" + q = queryTimed(" SELECT ID, Name, @@ -55,7 +55,7 @@ try { } // Get address from Addresses table (either linked via AddressBusinessID or via Businesses.BusinessAddressID) - qAddr = queryExecute(" + qAddr = queryTimed(" SELECT a.Line1 AS AddressLine1, a.Line2 AS AddressLine2, a.City AS AddressCity, a.ZIPCode AS AddressZIPCode, s.Abbreviation FROM Addresses a LEFT JOIN tt_States s ON s.ID = a.StateID @@ -87,7 +87,7 @@ try { } // Get hours from Hours table - qHours = queryExecute(" + qHours = queryTimed(" SELECT h.DayID, h.OpenTime, h.ClosingTime, d.Abbrev FROM Hours h JOIN tt_Days d ON d.ID = h.DayID diff --git a/api/businesses/getChildren.cfm b/api/businesses/getChildren.cfm index 39d8541..a0a22be 100644 --- a/api/businesses/getChildren.cfm +++ b/api/businesses/getChildren.cfm @@ -33,7 +33,7 @@ if (parentBusinessId LTE 0) { } try { - q = queryExecute( + q = queryTimed( " SELECT ID, diff --git a/api/businesses/list.cfm b/api/businesses/list.cfm index 9f91962..580846b 100644 --- a/api/businesses/list.cfm +++ b/api/businesses/list.cfm @@ -40,7 +40,7 @@ try { hasUserLocation = (userLat != 0 AND userLng != 0); // Get businesses with their address coordinates (exclude demo and private) - q = queryExecute( + q = queryTimed( " SELECT b.ID, diff --git a/api/businesses/saveBrandColor.cfm b/api/businesses/saveBrandColor.cfm index 0e8ec84..2e9d6d0 100644 --- a/api/businesses/saveBrandColor.cfm +++ b/api/businesses/saveBrandColor.cfm @@ -47,7 +47,7 @@ if (len(brandColor) GT 0) { } // Update the database -queryExecute(" +queryTimed(" UPDATE Businesses SET BrandColor = :color WHERE ID = :bizId diff --git a/api/businesses/setHiring.cfm b/api/businesses/setHiring.cfm index bc32636..49bb7f3 100644 --- a/api/businesses/setHiring.cfm +++ b/api/businesses/setHiring.cfm @@ -43,7 +43,7 @@ if (isHiring == -1) { } try { - queryExecute(" + queryTimed(" UPDATE Businesses SET IsHiring = ? WHERE ID = ? diff --git a/api/businesses/update.cfm b/api/businesses/update.cfm index 669efa9..ffa4b63 100644 --- a/api/businesses/update.cfm +++ b/api/businesses/update.cfm @@ -47,7 +47,7 @@ try { if (len(bizName)) { if (isNumeric(taxRate)) { - queryExecute(" + queryTimed(" UPDATE Businesses SET Name = :name, Phone = :phone, TaxRate = :taxRate WHERE ID = :id ", { @@ -57,7 +57,7 @@ try { id: businessId }, { datasource: "payfrit" }); } else { - queryExecute(" + queryTimed(" UPDATE Businesses SET Name = :name, Phone = :phone WHERE ID = :id ", { @@ -80,7 +80,7 @@ try { // Get state ID stateID = 0; if (len(state)) { - qState = queryExecute(" + qState = queryTimed(" SELECT ID FROM tt_States WHERE Abbreviation = :abbr ", { abbr: uCase(state) }, { datasource: "payfrit" }); if (qState.recordCount > 0) { @@ -89,7 +89,7 @@ try { } // Check if business has an address - qAddr = queryExecute(" + qAddr = queryTimed(" SELECT ID FROM Addresses WHERE BusinessID = :bizID AND UserID = 0 AND IsDeleted = 0 LIMIT 1 @@ -97,7 +97,7 @@ try { if (qAddr.recordCount > 0) { // Update existing address - queryExecute(" + queryTimed(" UPDATE Addresses SET Line1 = :line1, City = :city, @@ -113,7 +113,7 @@ try { }, { datasource: "payfrit" }); } else { // Create new address - queryExecute(" + queryTimed(" INSERT INTO Addresses (Line1, City, StateID, ZIPCode, BusinessID, UserID, AddressTypeID, AddedOn) VALUES (:line1, :city, :stateID, :zip, :bizID, 0, 2, NOW()) ", { diff --git a/api/businesses/updateHours.cfm b/api/businesses/updateHours.cfm index ffb6fcc..0a561b8 100644 --- a/api/businesses/updateHours.cfm +++ b/api/businesses/updateHours.cfm @@ -37,7 +37,7 @@ try { hours = structKeyExists(data, "Hours") && isArray(data.Hours) ? data.Hours : []; // Delete all existing hours for this business - queryExecute(" + queryTimed(" DELETE FROM Hours WHERE BusinessID = :bizID ", { bizID: businessId }, { datasource: "payfrit" }); @@ -54,7 +54,7 @@ try { if (len(openTime) == 5) openTime = openTime & ":00"; if (len(closeTime) == 5) closeTime = closeTime & ":00"; - queryExecute(" + queryTimed(" INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizID, :dayID, :openTime, :closeTime) ", { diff --git a/api/chat/closeChat.cfm b/api/chat/closeChat.cfm index fe15e8a..2612a0d 100644 --- a/api/chat/closeChat.cfm +++ b/api/chat/closeChat.cfm @@ -32,7 +32,7 @@ try { } // Mark the task as completed - queryExecute(" + queryTimed(" UPDATE Tasks SET CompletedOn = NOW() WHERE ID = :taskID diff --git a/api/chat/getActiveChat.cfm b/api/chat/getActiveChat.cfm index 0e00ee1..2c8c6c6 100644 --- a/api/chat/getActiveChat.cfm +++ b/api/chat/getActiveChat.cfm @@ -44,7 +44,7 @@ try { // Look for any active chat task at this service point // TaskTypeID = 2 (Chat), not completed, at this service point - qChat = queryExecute(" + qChat = queryTimed(" SELECT t.ID, t.Title, (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.ID) as LastMessageTime FROM Tasks t diff --git a/api/chat/getMessages.cfm b/api/chat/getMessages.cfm index 10f6ce4..28b9c3b 100644 --- a/api/chat/getMessages.cfm +++ b/api/chat/getMessages.cfm @@ -34,7 +34,7 @@ try { // Get messages if (afterMessageID > 0) { - qMessages = queryExecute(" + qMessages = queryTimed(" SELECT m.ID, m.TaskID, @@ -53,7 +53,7 @@ try { afterID: { value: afterMessageID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); } else { - qMessages = queryExecute(" + qMessages = queryTimed(" SELECT m.ID, m.TaskID, @@ -87,7 +87,7 @@ try { } // Check if chat/task is closed (completed) - qTask = queryExecute(" + qTask = queryTimed(" SELECT CompletedOn FROM Tasks WHERE ID = :taskID ", { taskID: { value: taskID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); diff --git a/api/chat/markRead.cfm b/api/chat/markRead.cfm index a3e1818..4839267 100644 --- a/api/chat/markRead.cfm +++ b/api/chat/markRead.cfm @@ -41,7 +41,7 @@ try { // If reader is worker, mark customer messages as read otherType = readerType == "customer" ? "worker" : "customer"; - queryExecute(" + queryTimed(" UPDATE ChatMessages SET IsRead = 1 WHERE TaskID = :taskID AND SenderType = :otherType AND IsRead = 0 diff --git a/api/chat/sendMessage.cfm b/api/chat/sendMessage.cfm index c4cf327..de0bc91 100644 --- a/api/chat/sendMessage.cfm +++ b/api/chat/sendMessage.cfm @@ -53,7 +53,7 @@ try { } // Verify task exists and is still open - taskQuery = queryExecute(" + taskQuery = queryTimed(" SELECT ID, ClaimedByUserID, CompletedOn FROM Tasks WHERE ID = :taskID ", { taskID: { value: taskID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); @@ -67,7 +67,7 @@ try { } // Insert message - queryExecute(" + queryTimed(" INSERT INTO ChatMessages (TaskID, SenderUserID, SenderType, MessageBody) VALUES (:taskID, :userID, :senderType, :message) ", { @@ -78,7 +78,7 @@ try { }, { datasource: "payfrit" }); // Get the new message ID - result = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + result = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); messageID = result.newID; apiAbort({ diff --git a/api/debug/checkTask.cfm b/api/debug/checkTask.cfm index bea65ab..fff417a 100644 --- a/api/debug/checkTask.cfm +++ b/api/debug/checkTask.cfm @@ -15,7 +15,7 @@
- try { - qTables = queryExecute("SHOW TABLES LIKE '%tate%'", {}, { datasource: "payfrit" }); + qTables = queryTimed("SHOW TABLES LIKE '%tate%'", {}, { datasource: "payfrit" }); tables = []; for (row in qTables) { diff --git a/api/dev/seedData.cfm b/api/dev/seedData.cfm index 47125d7..7868766 100644 --- a/api/dev/seedData.cfm +++ b/api/dev/seedData.cfm @@ -42,7 +42,7 @@ function readJsonBody() { function createTestUser(phone, firstName, lastName, isVerified = true) { var userUUID = replace(createUUID(), "-", "", "all"); - queryExecute(" + queryTimed(" INSERT INTO Users ( ContactNumber, UUID, @@ -125,7 +125,7 @@ function seedTestData() { function resetTestData() { // Delete test users (by phone prefix 555) - queryExecute(" + queryTimed(" DELETE FROM Users WHERE ContactNumber LIKE '555%' ", {}, { datasource: "payfrit" }); @@ -134,7 +134,7 @@ function resetTestData() { } function getTestDataInfo() { - var qUsers = queryExecute(" + var qUsers = queryTimed(" SELECT ID, ContactNumber, FirstName, LastName, IsContactVerified, UUID FROM Users diff --git a/api/dev/timeTravel.cfm b/api/dev/timeTravel.cfm index b41652c..4383cf2 100644 --- a/api/dev/timeTravel.cfm +++ b/api/dev/timeTravel.cfm @@ -57,7 +57,7 @@ try { apiAbort({ "OK": false, "ERROR": "missing_userId" }); } - queryExecute(" + queryTimed(" UPDATE UserTokens SET CreatedAt = DATE_SUB(NOW(), INTERVAL 30 DAY) WHERE UserID = :userId @@ -77,7 +77,7 @@ try { apiAbort({ "OK": false, "ERROR": "missing_userId_or_daysAgo" }); } - queryExecute(" + queryTimed(" UPDATE Users SET AddedOn = DATE_SUB(NOW(), INTERVAL :days DAY) WHERE UserID = :userId @@ -94,7 +94,7 @@ try { case "clearotps": // Clear all OTPs (force re-request) - queryExecute(" + queryTimed(" UPDATE Users SET MobileVerifyCode = '' ", {}, { datasource: "payfrit" }); @@ -110,7 +110,7 @@ try { apiAbort({ "OK": false, "ERROR": "missing_phone" }); } - queryExecute(" + queryTimed(" UPDATE Users SET IsContactVerified = 0, IsActive = 0, diff --git a/api/grants/_grantUtils.cfm b/api/grants/_grantUtils.cfm index 84ee891..a67df3d 100644 --- a/api/grants/_grantUtils.cfm +++ b/api/grants/_grantUtils.cfm @@ -71,7 +71,7 @@ function checkGrantEligibility( if (arguments.eligibilityScope == "public") return true; // Check if user is employee of a given business - var isGuestEmployee = queryExecute( + var isGuestEmployee = queryTimed( "SELECT 1 FROM Employees WHERE BusinessID = ? AND UserID = ? AND IsActive = 1 LIMIT 1", [ { value = arguments.guestBusinessID, cfsqltype = "cf_sql_integer" }, @@ -80,7 +80,7 @@ function checkGrantEligibility( { datasource = "payfrit" } ).recordCount > 0; - var isOwnerEmployee = queryExecute( + var isOwnerEmployee = queryTimed( "SELECT 1 FROM Employees WHERE BusinessID = ? AND UserID = ? AND IsActive = 1 LIMIT 1", [ { value = arguments.ownerBusinessID, cfsqltype = "cf_sql_integer" }, @@ -118,7 +118,7 @@ function recordGrantHistory( var ip = ""; try { ip = cgi.REMOTE_ADDR; } catch (any e) {} - queryExecute( + queryTimed( "INSERT INTO ServicePointGrantHistory (GrantID, Action, ActorUserID, ActorBusinessID, PreviousData, NewData, IPAddress) VALUES (?, ?, ?, ?, ?, ?, ?)", [ diff --git a/api/grants/accept.cfm b/api/grants/accept.cfm index 422bc6b..e4d86a8 100644 --- a/api/grants/accept.cfm +++ b/api/grants/accept.cfm @@ -29,7 +29,7 @@ if (callerUserID LTE 0) { // Load grant by ID or token if (grantID GT 0) { - qGrant = queryExecute( + qGrant = queryTimed( "SELECT g.*, b.UserID AS GuestOwnerUserID FROM ServicePointGrants g JOIN Businesses b ON b.ID = g.GuestBusinessID @@ -39,7 +39,7 @@ if (grantID GT 0) { { datasource = "payfrit" } ); } else { - qGrant = queryExecute( + qGrant = queryTimed( "SELECT g.*, b.UserID AS GuestOwnerUserID FROM ServicePointGrants g JOIN Businesses b ON b.ID = g.GuestBusinessID @@ -65,7 +65,7 @@ if (qGrant.StatusID != 0) { } // Accept: activate grant -queryExecute( +queryTimed( "UPDATE ServicePointGrants SET StatusID = 1, AcceptedOn = NOW(), AcceptedByUserID = ?, InviteToken = NULL WHERE ID = ?", diff --git a/api/grants/create.cfm b/api/grants/create.cfm index 464fbca..97db805 100644 --- a/api/grants/create.cfm +++ b/api/grants/create.cfm @@ -39,7 +39,7 @@ if (callerUserID LTE 0) { apiAbort({ "OK": false, "ERROR": "not_authenticated", "MESSAGE": "Authentication required." }); } -qOwner = queryExecute( +qOwner = queryTimed( "SELECT UserID FROM Businesses WHERE ID = ? LIMIT 1", [{ value = ownerBusinessID, cfsqltype = "cf_sql_integer" }], { datasource = "payfrit" } @@ -49,7 +49,7 @@ if (qOwner.recordCount == 0 || qOwner.UserID != callerUserID) { } // Validate ServicePoint belongs to OwnerBusinessID -qSP = queryExecute( +qSP = queryTimed( "SELECT ID FROM ServicePoints WHERE ID = ? AND BusinessID = ? LIMIT 1", [ { value = servicePointID, cfsqltype = "cf_sql_integer" }, @@ -62,7 +62,7 @@ if (qSP.recordCount == 0) { } // Validate GuestBusiness exists -qGuest = queryExecute( +qGuest = queryTimed( "SELECT ID FROM Businesses WHERE ID = ? LIMIT 1", [{ value = guestBusinessID, cfsqltype = "cf_sql_integer" }], { datasource = "payfrit" } @@ -72,7 +72,7 @@ if (qGuest.recordCount == 0) { } // Check no active or pending grant exists for this combo -qExisting = queryExecute( +qExisting = queryTimed( "SELECT ID FROM ServicePointGrants WHERE OwnerBusinessID = ? AND GuestBusinessID = ? AND ServicePointID = ? AND StatusID IN (0, 1) LIMIT 1", @@ -109,7 +109,7 @@ if (isStruct(timePolicyData) && !structIsEmpty(timePolicyData)) { } // Insert grant -queryExecute( +queryTimed( "INSERT INTO ServicePointGrants (UUID, OwnerBusinessID, GuestBusinessID, ServicePointID, StatusID, EconomicsType, EconomicsValue, EligibilityScope, TimePolicyType, TimePolicyData, @@ -132,7 +132,7 @@ queryExecute( ); // Get the inserted grant ID -qNew = queryExecute( +qNew = queryTimed( "SELECT ID FROM ServicePointGrants WHERE UUID = ? LIMIT 1", [{ value = newUUID, cfsqltype = "cf_sql_varchar" }], { datasource = "payfrit" } diff --git a/api/grants/decline.cfm b/api/grants/decline.cfm index de4e1b9..b0b9790 100644 --- a/api/grants/decline.cfm +++ b/api/grants/decline.cfm @@ -25,7 +25,7 @@ if (callerUserID LTE 0) { apiAbort({ "OK": false, "ERROR": "not_authenticated" }); } -qGrant = queryExecute( +qGrant = queryTimed( "SELECT g.*, b.UserID AS GuestOwnerUserID FROM ServicePointGrants g JOIN Businesses b ON b.ID = g.GuestBusinessID @@ -47,7 +47,7 @@ if (qGrant.StatusID != 0) { apiAbort({ "OK": false, "ERROR": "bad_state", "MESSAGE": "Only pending grants can be declined." }); } -queryExecute( +queryTimed( "UPDATE ServicePointGrants SET StatusID = 2 WHERE ID = ?", [{ value = grantID, cfsqltype = "cf_sql_integer" }], { datasource = "payfrit" } diff --git a/api/grants/get.cfm b/api/grants/get.cfm index ae08851..3824a04 100644 --- a/api/grants/get.cfm +++ b/api/grants/get.cfm @@ -24,7 +24,7 @@ if (callerUserID LTE 0) { } // Load grant with business/SP names -qGrant = queryExecute( +qGrant = queryTimed( "SELECT g.*, ob.Name AS OwnerBusinessName, @@ -52,7 +52,7 @@ if (qGrant.recordCount == 0) { } // Load history -qHistory = queryExecute( +qHistory = queryTimed( "SELECT h.*, u.FirstName, u.LastName FROM ServicePointGrantHistory h LEFT JOIN Users u ON u.ID = h.ActorUserID diff --git a/api/grants/list.cfm b/api/grants/list.cfm index bf3605b..574239c 100644 --- a/api/grants/list.cfm +++ b/api/grants/list.cfm @@ -76,7 +76,7 @@ if (statusFilter >= 0) { params.statusFilter = { value = statusFilter, cfsqltype = "cf_sql_integer" }; } -qGrants = queryExecute(sql, params, { datasource = "payfrit" }); +qGrants = queryTimed(sql, params, { datasource = "payfrit" }); grants = []; for (row in qGrants) { diff --git a/api/grants/revoke.cfm b/api/grants/revoke.cfm index 18e83fd..9f5a509 100644 --- a/api/grants/revoke.cfm +++ b/api/grants/revoke.cfm @@ -26,7 +26,7 @@ if (callerUserID LTE 0) { } // Load grant + verify ownership -qGrant = queryExecute( +qGrant = queryTimed( "SELECT g.ID, g.OwnerBusinessID, g.GuestBusinessID, g.StatusID, b.UserID AS OwnerUserID FROM ServicePointGrants g JOIN Businesses b ON b.ID = g.OwnerBusinessID @@ -53,7 +53,7 @@ if (qGrant.StatusID != 0 && qGrant.StatusID != 1) { } // Revoke immediately -queryExecute( +queryTimed( "UPDATE ServicePointGrants SET StatusID = 3, RevokedOn = NOW() WHERE ID = ?", [{ value = grantID, cfsqltype = "cf_sql_integer" }], { datasource = "payfrit" } diff --git a/api/grants/searchBusiness.cfm b/api/grants/searchBusiness.cfm index 970b57c..8187d62 100644 --- a/api/grants/searchBusiness.cfm +++ b/api/grants/searchBusiness.cfm @@ -39,7 +39,7 @@ if (excludeBusinessID GT 0) { sql &= " ORDER BY Name LIMIT 20"; -qResults = queryExecute(sql, params, { datasource = "payfrit" }); +qResults = queryTimed(sql, params, { datasource = "payfrit" }); businesses = []; for (row in qResults) { diff --git a/api/grants/update.cfm b/api/grants/update.cfm index 342827e..74fd4ef 100644 --- a/api/grants/update.cfm +++ b/api/grants/update.cfm @@ -26,7 +26,7 @@ if (callerUserID LTE 0) { } // Load current grant -qGrant = queryExecute( +qGrant = queryTimed( "SELECT g.*, b.UserID AS OwnerUserID FROM ServicePointGrants g JOIN Businesses b ON b.ID = g.OwnerBusinessID @@ -124,7 +124,7 @@ if (arrayLen(setClauses) == 0) { // Execute update arrayAppend(setParams, { value = grantID, cfsqltype = "cf_sql_integer" }); -queryExecute( +queryTimed( "UPDATE ServicePointGrants SET #arrayToList(setClauses, ', ')# WHERE ID = ?", setParams, { datasource = "payfrit" } diff --git a/api/import/crimson_menu.cfm b/api/import/crimson_menu.cfm index ef08c60..38a284f 100644 --- a/api/import/crimson_menu.cfm +++ b/api/import/crimson_menu.cfm @@ -13,7 +13,7 @@ try { response.steps.append("Creating business record..."); // Check if business already exists by name - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM Businesses WHERE Name = :name ", { name: "Crimson Mediterranean Cookhouse" }, { datasource: "payfrit" }); @@ -21,7 +21,7 @@ try { BusinessID = qCheck.BusinessID; response.steps.append("Business already exists with ID: " & BusinessID); } else { - queryExecute(" + queryTimed(" INSERT INTO Businesses (Name, BusinessOwnerUserID) VALUES (:name, :ownerID) ", { @@ -29,7 +29,7 @@ try { ownerID: 2 // UserID 2 (John) }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); BusinessID = qNew.id; response.steps.append("Created business with ID: " & BusinessID); } @@ -53,7 +53,7 @@ try { for (cat in categories) { // Check if exists - qCat = queryExecute(" + qCat = queryTimed(" SELECT ID FROM Categories WHERE BusinessID = :bizID AND Name = :name ", { bizID: BusinessID, name: cat.name }, { datasource: "payfrit" }); @@ -61,7 +61,7 @@ try { if (qCat.recordCount > 0) { categoryMap[cat.id] = qCat.CategoryID; } else { - queryExecute(" + queryTimed(" INSERT INTO Categories (BusinessID, Name, SortOrder) VALUES (:bizID, :name, :sortOrder) ", { @@ -70,7 +70,7 @@ try { sortOrder: cat.order }, { datasource: "payfrit" }); - qNewCat = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewCat = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); categoryMap[cat.id] = qNewCat.id; } } @@ -86,7 +86,7 @@ try { // Helper function to create a modifier group function createModifierGroup(categoryID, parentItemID, groupName, groupID, options, required, maxSelect) { // Check if group exists - var qMod = queryExecute(" + var qMod = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = :parentID ", { catID: categoryID, name: groupName, parentID: parentItemID }, { datasource: "payfrit" }); @@ -95,7 +95,7 @@ try { if (qMod.recordCount > 0) { groupItemID = qMod.ItemID; } else { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, ParentItemID, Price, IsActive, RequiresChildSelection, MaxNumSelectionReq, IsCollapsible, SortOrder) VALUES (:catID, :name, :parentID, 0, 1, :required, :maxSelect, 1, :sortOrder) @@ -108,21 +108,21 @@ try { sortOrder: 100 }, { datasource: "payfrit" }); - var qNewMod = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + var qNewMod = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); groupItemID = qNewMod.id; } // Create options var optionOrder = 1; for (var opt in options) { - var qOpt = queryExecute(" + var qOpt = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = :parentID ", { catID: categoryID, name: opt.name, parentID: groupItemID }, { datasource: "payfrit" }); if (qOpt.recordCount == 0) { var isDefault = (optionOrder == 1 && required) ? 1 : 0; - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, ParentItemID, Price, IsActive, IsCheckedByDefault, SortOrder) VALUES (:catID, :name, :parentID, :price, 1, :isDefault, :sortOrder) @@ -158,13 +158,13 @@ try { itemOrder = 1; for (item in grillItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: grillCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, RequiresChildSelection, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :reqChild, :sortOrder) @@ -198,13 +198,13 @@ try { itemOrder = 1; for (item in wrapItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: wrapsCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -234,13 +234,13 @@ try { itemOrder = 1; for (item in saladItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: saladsCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -276,13 +276,13 @@ try { itemOrder = 1; for (item in sideItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: sidesCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -317,13 +317,13 @@ try { itemOrder = 1; for (item in hotCoffeeItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: hotCoffeeCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -355,13 +355,13 @@ try { itemOrder = 1; for (item in icedCoffeeItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: icedCoffeeCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -391,13 +391,13 @@ try { itemOrder = 1; for (item in hotTeaItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: hotTeaCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -428,13 +428,13 @@ try { itemOrder = 1; for (item in icedTeaItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: icedTeaCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -466,13 +466,13 @@ try { itemOrder = 1; for (item in bevItems) { - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0 ", { catID: bevCatID, name: item.name }, { datasource: "payfrit" }); if (qItem.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price, IsActive, SortOrder) VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder) @@ -488,7 +488,7 @@ try { } // Count total items - qCount = queryExecute(" + qCount = queryTimed(" SELECT COUNT(*) as cnt FROM Items i INNER JOIN Categories c ON c.ID = i.CategoryID WHERE c.BusinessID = :bizID diff --git a/api/menu/clearAllData.cfm b/api/menu/clearAllData.cfm index 654593e..6ce1f3c 100644 --- a/api/menu/clearAllData.cfm +++ b/api/menu/clearAllData.cfm @@ -20,14 +20,14 @@ try { } // Get counts before deletion - qItemCount = queryExecute("SELECT COUNT(*) as cnt FROM Items", {}, { datasource: "payfrit" }); - qCatCount = queryExecute("SELECT COUNT(*) as cnt FROM Categories", {}, { datasource: "payfrit" }); - qLinkCount = queryExecute("SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" }); + qItemCount = queryTimed("SELECT COUNT(*) as cnt FROM Items", {}, { datasource: "payfrit" }); + qCatCount = queryTimed("SELECT COUNT(*) as cnt FROM Categories", {}, { datasource: "payfrit" }); + qLinkCount = queryTimed("SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" }); // Delete in correct order (foreign key constraints) - queryExecute("DELETE FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" }); - queryExecute("DELETE FROM Items", {}, { datasource: "payfrit" }); - queryExecute("DELETE FROM Categories", {}, { datasource: "payfrit" }); + queryTimed("DELETE FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" }); + queryTimed("DELETE FROM Items", {}, { datasource: "payfrit" }); + queryTimed("DELETE FROM Categories", {}, { datasource: "payfrit" }); response = { "OK": true, diff --git a/api/menu/clearBusinessData.cfm b/api/menu/clearBusinessData.cfm index 8e1bc98..dec2a6d 100644 --- a/api/menu/clearBusinessData.cfm +++ b/api/menu/clearBusinessData.cfm @@ -24,11 +24,11 @@ try { } // Get counts before deletion - qItemCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); - qCatCount = queryExecute("SELECT COUNT(*) as cnt FROM Categories WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); + qItemCount = queryTimed("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); + qCatCount = queryTimed("SELECT COUNT(*) as cnt FROM Categories WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); // Get item IDs for this business to delete template links - qItemIds = queryExecute("SELECT ID FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); + qItemIds = queryTimed("SELECT ID FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); itemIds = []; for (row in qItemIds) { arrayAppend(itemIds, row.ID); @@ -37,17 +37,17 @@ try { deletedLinks = 0; if (arrayLen(itemIds) > 0) { // Delete template links for these items - queryExecute("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID IN (:ids) OR TemplateItemID IN (:ids)", + queryTimed("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID IN (:ids) OR TemplateItemID IN (:ids)", { ids: { value: arrayToList(itemIds), cfsqltype: "cf_sql_varchar", list: true } }, { datasource: "payfrit" }); deletedLinks = arrayLen(itemIds); } // Delete all items for this business - queryExecute("DELETE FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); + queryTimed("DELETE FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); // Delete all categories for this business - queryExecute("DELETE FROM Categories WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); + queryTimed("DELETE FROM Categories WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" }); response = { "OK": true, diff --git a/api/menu/clearOrders.cfm b/api/menu/clearOrders.cfm index 53bcdf0..56c2adb 100644 --- a/api/menu/clearOrders.cfm +++ b/api/menu/clearOrders.cfm @@ -20,16 +20,16 @@ try { } // Get counts before deletion - qOrderLineItems = queryExecute("SELECT COUNT(*) as cnt FROM OrderLineItems", {}, { datasource: "payfrit" }); - qOrders = queryExecute("SELECT COUNT(*) as cnt FROM Orders", {}, { datasource: "payfrit" }); - qAddresses = queryExecute("SELECT COUNT(*) as cnt FROM Addresses WHERE AddressTypeID != 2", {}, { datasource: "payfrit" }); - qTasks = queryExecute("SELECT COUNT(*) as cnt FROM Tasks", {}, { datasource: "payfrit" }); + qOrderLineItems = queryTimed("SELECT COUNT(*) as cnt FROM OrderLineItems", {}, { datasource: "payfrit" }); + qOrders = queryTimed("SELECT COUNT(*) as cnt FROM Orders", {}, { datasource: "payfrit" }); + qAddresses = queryTimed("SELECT COUNT(*) as cnt FROM Addresses WHERE AddressTypeID != 2", {}, { datasource: "payfrit" }); + qTasks = queryTimed("SELECT COUNT(*) as cnt FROM Tasks", {}, { datasource: "payfrit" }); // Delete in correct order (foreign key constraints) - queryExecute("DELETE FROM Tasks", {}, { datasource: "payfrit" }); - queryExecute("DELETE FROM OrderLineItems", {}, { datasource: "payfrit" }); - queryExecute("DELETE FROM Orders", {}, { datasource: "payfrit" }); - queryExecute("DELETE FROM Addresses WHERE AddressTypeID != 2", {}, { datasource: "payfrit" }); + queryTimed("DELETE FROM Tasks", {}, { datasource: "payfrit" }); + queryTimed("DELETE FROM OrderLineItems", {}, { datasource: "payfrit" }); + queryTimed("DELETE FROM Orders", {}, { datasource: "payfrit" }); + queryTimed("DELETE FROM Addresses WHERE AddressTypeID != 2", {}, { datasource: "payfrit" }); response = { "OK": true, diff --git a/api/menu/debug.cfm b/api/menu/debug.cfm index 0eb535a..63a672e 100644 --- a/api/menu/debug.cfm +++ b/api/menu/debug.cfm @@ -7,7 +7,7 @@ response = {}; try { // Get all businesses with items - qBusinesses = queryExecute(" + qBusinesses = queryTimed(" SELECT DISTINCT i.BusinessID, COUNT(*) as ItemCount FROM Items i WHERE i.BusinessID > 0 @@ -23,7 +23,7 @@ try { } // Get categories - qCategories = queryExecute(" + qCategories = queryTimed(" SELECT ID, COUNT(*) as cnt FROM Categories GROUP BY BusinessID @@ -38,7 +38,7 @@ try { } // Get sample items - qItems = queryExecute(" + qItems = queryTimed(" SELECT ID, BusinessID, CategoryID, ParentItemID, Name, IsActive FROM Items WHERE IsActive = 1 @@ -58,7 +58,7 @@ try { } // Get template links - qLinks = queryExecute(" + qLinks = queryTimed(" SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID ", {}, { datasource: "payfrit" }); response["template_link_count"] = qLinks.cnt; diff --git a/api/menu/getForBuilder.cfm b/api/menu/getForBuilder.cfm index 2712883..2c6a3a8 100644 --- a/api/menu/getForBuilder.cfm +++ b/api/menu/getForBuilder.cfm @@ -63,7 +63,7 @@ try { // Get all menus for this business allMenus = []; try { - qMenus = queryExecute(" + qMenus = queryTimed(" SELECT ID, Name, Description, DaysActive, StartTime, EndTime, SortOrder FROM Menus @@ -123,7 +123,7 @@ try { // Check if Categories table has data for this business hasCategoriesData = false; try { - qCatCheck = queryExecute(" + qCatCheck = queryTimed(" SELECT 1 FROM Categories WHERE BusinessID = :businessID LIMIT 1 ", { businessID: businessID }, { datasource: "payfrit" }); hasCategoriesData = (qCatCheck.recordCount > 0); @@ -141,7 +141,7 @@ try { menuParams["menuID"] = menuID; } - qCategories = queryExecute(" + qCategories = queryTimed(" SELECT ID, Name, @@ -153,7 +153,7 @@ try { ", menuParams, { datasource: "payfrit" }); // Get menu items - items that belong to categories (not modifiers) - qItems = queryExecute(" + qItems = queryTimed(" SELECT i.ID, i.CategoryID as CategoryItemID, @@ -170,7 +170,7 @@ try { ", { businessID: businessID }, { datasource: "payfrit" }); // Get direct modifiers (items with ParentItemID pointing to menu items, not categories) - qDirectModifiers = queryExecute(" + qDirectModifiers = queryTimed(" SELECT m.ItemID, m.ParentItemID as ParentItemID, @@ -190,7 +190,7 @@ try { } else { // NEW UNIFIED SCHEMA: Categories are Items at ParentID=0 with children - qCategories = queryExecute(" + qCategories = queryTimed(" SELECT DISTINCT p.ItemID as CategoryID, p.Name as Name, @@ -206,7 +206,7 @@ try { ORDER BY p.SortOrder, p.Name ", { businessID: businessID }, { datasource: "payfrit" }); - qItems = queryExecute(" + qItems = queryTimed(" SELECT i.ID, i.ParentItemID as CategoryItemID, @@ -226,7 +226,7 @@ try { ORDER BY i.SortOrder, i.Name ", { businessID: businessID }, { datasource: "payfrit" }); - qDirectModifiers = queryExecute(" + qDirectModifiers = queryTimed(" SELECT m.ItemID, m.ParentItemID as ParentItemID, @@ -253,7 +253,7 @@ try { // Get template links ONLY for this business's menu items qTemplateLinks = queryNew("ParentItemID,TemplateItemID,SortOrder"); if (arrayLen(menuItemIds) > 0) { - qTemplateLinks = queryExecute(" + qTemplateLinks = queryTimed(" SELECT tl.ItemID as ParentItemID, tl.TemplateItemID, @@ -265,7 +265,7 @@ try { } // Get templates for this business only - qTemplates = queryExecute(" + qTemplates = queryTimed(" SELECT DISTINCT t.ItemID, t.Name, @@ -290,7 +290,7 @@ try { qTemplateChildren = queryNew("ItemID,ParentItemID,Name,Price,IsDefault,SortOrder,RequiresSelection,MaxSelections"); if (arrayLen(templateIds) > 0) { - qTemplateChildren = queryExecute(" + qTemplateChildren = queryTimed(" SELECT c.ItemID, c.ParentItemID as ParentItemID, @@ -441,7 +441,7 @@ try { // Get business brand color brandColor = ""; try { - qBrand = queryExecute(" + qBrand = queryTimed(" SELECT BrandColor AS BusinessBrandColor FROM Businesses WHERE ID = :bizId ", { bizId: businessID }, { datasource: "payfrit" }); if (qBrand.recordCount > 0 && len(trim(qBrand.BusinessBrandColor))) { diff --git a/api/menu/items.cfm b/api/menu/items.cfm index 69b4ecf..6c3496d 100644 --- a/api/menu/items.cfm +++ b/api/menu/items.cfm @@ -57,7 +57,7 @@ - 0", [ { value = BusinessID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" } @@ -74,7 +74,7 @@ - - - - - - - - - 0) { // Update existing menu - queryExecute(" + queryTimed(" UPDATE Menus SET Name = :menuName, Description = :menuDescription, @@ -153,7 +153,7 @@ try { response = { "OK": true, "MenuID": menuID, "ACTION": "updated" }; } else { // Create new menu - queryExecute(" + queryTimed(" INSERT INTO Menus ( BusinessID, Name, Description, DaysActive, StartTime, EndTime, @@ -173,7 +173,7 @@ try { menuSortOrder: { value: menuSortOrder, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); - result = queryExecute("SELECT LAST_INSERT_ID() as newID", {}, { datasource: "payfrit" }); + result = queryTimed("SELECT LAST_INSERT_ID() as newID", {}, { datasource: "payfrit" }); response = { "OK": true, "MenuID": result.newID, "ACTION": "created" }; } break; @@ -186,21 +186,21 @@ try { } // Check if menu has categories/items for warning - qCatCheck = queryExecute(" + qCatCheck = queryTimed(" SELECT COUNT(*) as cnt FROM Categories WHERE MenuID = :menuID AND BusinessID = :businessID ", { menuID: menuID, businessID: businessID }, { datasource: "payfrit" }); // Unassign categories from this menu if (qCatCheck.cnt > 0) { - queryExecute(" + queryTimed(" UPDATE Categories SET MenuID = 0 WHERE MenuID = :menuID AND BusinessID = :businessID ", { menuID: menuID, businessID: businessID }, { datasource: "payfrit" }); } // Soft-delete the menu - queryExecute(" + queryTimed(" UPDATE Menus SET IsActive = 0 WHERE ID = :menuID AND BusinessID = :businessID ", { menuID: menuID, businessID: businessID }, { datasource: "payfrit" }); @@ -221,7 +221,7 @@ try { } for (i = 1; i <= arrayLen(menuOrder); i++) { - queryExecute(" + queryTimed(" UPDATE Menus SET SortOrder = :sortOrder WHERE ID = :menuID AND BusinessID = :businessID ", { diff --git a/api/menu/saveCategory.cfm b/api/menu/saveCategory.cfm index 3bc66c1..03e4ed5 100644 --- a/api/menu/saveCategory.cfm +++ b/api/menu/saveCategory.cfm @@ -50,7 +50,7 @@ try { if (CategoryID > 0) { // Update existing category - queryExecute(" + queryTimed(" UPDATE Categories SET Name = :name, SortOrder = :sortOrder, @@ -75,7 +75,7 @@ try { } else if (BusinessID > 0 && len(Name)) { // Insert new category - queryExecute(" + queryTimed(" INSERT INTO Categories (BusinessID, Name, SortOrder, OrderTypes, ScheduleStart, ScheduleEnd, ScheduleDays, AddedOn) @@ -91,7 +91,7 @@ try { schedDays: { value = ScheduleDays, cfsqltype = "cf_sql_varchar", null = isNull(ScheduleDays) } }, { datasource = "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newId", {}, { datasource = "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newId", {}, { datasource = "payfrit" }); response["OK"] = true; response["CategoryID"] = qNew.newId; response["MESSAGE"] = "Category created"; diff --git a/api/menu/saveFromBuilder.cfm b/api/menu/saveFromBuilder.cfm index dcbd92b..0833d02 100644 --- a/api/menu/saveFromBuilder.cfm +++ b/api/menu/saveFromBuilder.cfm @@ -22,7 +22,7 @@ function saveOptionsRecursive(options, parentID, businessID) { if (optDbId > 0) { optionID = optDbId; - queryExecute(" + queryTimed(" UPDATE Items SET Name = :name, Price = :price, @@ -43,7 +43,7 @@ function saveOptionsRecursive(options, parentID, businessID) { maxSelections: maxSelections }); } else { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, ParentItemID, Name, Price, IsCheckedByDefault, SortOrder, IsActive, AddedOn, @@ -64,7 +64,7 @@ function saveOptionsRecursive(options, parentID, businessID) { maxSelections: maxSelections }); - var result = queryExecute("SELECT LAST_INSERT_ID() as newID"); + var result = queryTimed("SELECT LAST_INSERT_ID() as newID"); optionID = result.newID; } @@ -98,7 +98,7 @@ try { // Check if new schema is active newSchemaActive = false; try { - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT 1 FROM Items WHERE BusinessID = :businessID AND BusinessID > 0 LIMIT 1 @@ -118,7 +118,7 @@ try { if (newSchemaActive) { if (categoryDbId > 0) { categoryID = categoryDbId; - queryExecute(" + queryTimed(" UPDATE Items SET Name = :name, SortOrder = :sortOrder @@ -131,7 +131,7 @@ try { sortOrder: catSortOrder }); } else { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, Description, ParentItemID, Price, IsActive, @@ -147,7 +147,7 @@ try { sortOrder: catSortOrder }); - result = queryExecute("SELECT LAST_INSERT_ID() as newID"); + result = queryTimed("SELECT LAST_INSERT_ID() as newID"); categoryID = result.newID; } } else { @@ -157,7 +157,7 @@ try { if (categoryDbId > 0) { categoryID = categoryDbId; - queryExecute(" + queryTimed(" UPDATE Categories SET Name = :name, SortOrder = :sortOrder, @@ -170,7 +170,7 @@ try { menuId: categoryMenuIdParam }); } else { - queryExecute(" + queryTimed(" INSERT INTO Categories (BusinessID, MenuID, Name, SortOrder, AddedOn) VALUES (:businessID, :menuId, :name, :sortOrder, NOW()) ", { @@ -180,7 +180,7 @@ try { sortOrder: catSortOrder }); - result = queryExecute("SELECT LAST_INSERT_ID() as newID"); + result = queryTimed("SELECT LAST_INSERT_ID() as newID"); categoryID = result.newID; } } @@ -196,7 +196,7 @@ try { itemID = itemDbId; if (newSchemaActive) { - queryExecute(" + queryTimed(" UPDATE Items SET Name = :name, Description = :description, @@ -213,7 +213,7 @@ try { sortOrder: itemSortOrder }); } else { - queryExecute(" + queryTimed(" UPDATE Items SET Name = :name, Description = :description, @@ -232,7 +232,7 @@ try { } } else { if (newSchemaActive) { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, ParentItemID, Name, Description, Price, SortOrder, IsActive, AddedOn, CategoryID @@ -249,7 +249,7 @@ try { sortOrder: itemSortOrder }); } else { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, CategoryID, Name, Description, Price, SortOrder, IsActive, ParentItemID, AddedOn @@ -267,14 +267,14 @@ try { }); } - result = queryExecute("SELECT LAST_INSERT_ID() as newID"); + result = queryTimed("SELECT LAST_INSERT_ID() as newID"); itemID = result.newID; } // Handle modifiers if (structKeyExists(item, "modifiers") && isArray(item.modifiers) && arrayLen(item.modifiers) > 0) { // Clear existing template links for this item - queryExecute("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID = :itemID", { itemID: itemID }); + queryTimed("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID = :itemID", { itemID: itemID }); modSortOrder = 0; for (mod in item.modifiers) { @@ -284,7 +284,7 @@ try { if (structKeyExists(mod, "isTemplate") && mod.isTemplate && modDbId > 0) { // This is a template reference - create link - queryExecute(" + queryTimed(" INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder) VALUES (:itemID, :templateID, :sortOrder) ON DUPLICATE KEY UPDATE SortOrder = :sortOrder @@ -295,7 +295,7 @@ try { }); // Update template's selection rules - queryExecute(" + queryTimed(" UPDATE Items SET RequiresChildSelection = :requiresSelection, MaxNumSelectionReq = :maxSelections @@ -315,7 +315,7 @@ try { } } else if (modDbId > 0) { // Direct modifier (not a template) - update it - queryExecute(" + queryTimed(" UPDATE Items SET Name = :name, Price = :price, @@ -341,7 +341,7 @@ try { } } else { // New direct modifier - insert it - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, ParentItemID, Name, Price, IsCheckedByDefault, SortOrder, IsActive, AddedOn, @@ -362,7 +362,7 @@ try { maxSelections: maxSelections }); - modResult = queryExecute("SELECT LAST_INSERT_ID() as newModID"); + modResult = queryTimed("SELECT LAST_INSERT_ID() as newModID"); newModID = modResult.newModID; if (structKeyExists(mod, "options") && isArray(mod.options)) { saveOptionsRecursive(mod.options, newModID, businessID); diff --git a/api/menu/updateStations.cfm b/api/menu/updateStations.cfm index a3d1b68..9fa8fff 100644 --- a/api/menu/updateStations.cfm +++ b/api/menu/updateStations.cfm @@ -39,7 +39,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0) { // Update to active - queryExecute(" + queryTimed(" UPDATE Employees SET IsActive = 1, StatusID = 2 WHERE BusinessID = ? AND UserID = ? @@ -57,7 +57,7 @@ try { // NOTE: BusinessID in Employees is technically redundant since // the business relationship is established via ServicePoint -> Beacon chain. // Kept for legacy/convenience but could be derived from context. - queryExecute(" + queryTimed(" INSERT INTO Employees (BusinessID, UserID, StatusID, IsActive) VALUES (?, ?, 2, 1) ", [ @@ -65,7 +65,7 @@ try { { value: userId, cfsqltype: "cf_sql_integer" } ], { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() AS EmployeeID", {}, { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() AS EmployeeID", {}, { datasource: "payfrit" }); apiAbort({ "OK": true, "MESSAGE": "Team member added", "EmployeeID": qNew.ID }); diff --git a/api/portal/getSettings.cfm b/api/portal/getSettings.cfm index b128375..55c859d 100644 --- a/api/portal/getSettings.cfm +++ b/api/portal/getSettings.cfm @@ -22,7 +22,7 @@ if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) || } try { - q = queryExecute(" + q = queryTimed(" SELECT b.ID, b.Name, @@ -38,7 +38,7 @@ try { } // Get address from Addresses table - qAddr = queryExecute(" + qAddr = queryTimed(" SELECT a.Line1, a.Line2, a.City, a.ZIPCode, s.Abbreviation AS State FROM Addresses a LEFT JOIN tt_States s ON s.ID = a.StateID @@ -59,7 +59,7 @@ try { } // Get owner email from Users table - qUser = queryExecute(" + qUser = queryTimed(" SELECT ContactNumber, EmailAddress FROM Users WHERE ID = (SELECT UserID FROM Businesses WHERE ID = :businessId) diff --git a/api/portal/myBusinesses.cfm b/api/portal/myBusinesses.cfm index b4ca131..58f90dd 100644 --- a/api/portal/myBusinesses.cfm +++ b/api/portal/myBusinesses.cfm @@ -44,7 +44,7 @@ try { // Get businesses for this user (owner only) - q = queryExecute(" + q = queryTimed(" SELECT b.ID, b.Name FROM Businesses b WHERE b.UserID = :userID diff --git a/api/portal/searchUser.cfm b/api/portal/searchUser.cfm index a4634c2..3857fb3 100644 --- a/api/portal/searchUser.cfm +++ b/api/portal/searchUser.cfm @@ -40,7 +40,7 @@ try { if (isPhone) { // Search by phone - normalize both sides phoneDigits = normalizePhone(query); - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName, LastName, ContactNumber, EmailAddress FROM Users WHERE REPLACE(REPLACE(REPLACE(REPLACE(ContactNumber, '-', ''), ' ', ''), '(', ''), ')', '') LIKE :phone @@ -50,7 +50,7 @@ try { }, { datasource: "payfrit" }); } else if (isEmail) { // Search by email (partial match) - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName, LastName, ContactNumber, EmailAddress FROM Users WHERE EmailAddress LIKE :email @@ -60,7 +60,7 @@ try { }, { datasource: "payfrit" }); } else { // Search by name - qUser = queryExecute(" + qUser = queryTimed(" SELECT ID, FirstName, LastName, ContactNumber, EmailAddress FROM Users WHERE FirstName LIKE :name OR LastName LIKE :name @@ -73,7 +73,7 @@ try { if (qUser.recordCount > 0) { // Check if already on team - qTeam = queryExecute(" + qTeam = queryTimed(" SELECT ID FROM Employees WHERE BusinessID = :bizId AND UserID = :userId ", { diff --git a/api/portal/stats.cfm b/api/portal/stats.cfm index 479bf66..24e3301 100644 --- a/api/portal/stats.cfm +++ b/api/portal/stats.cfm @@ -37,7 +37,7 @@ try { todayEnd = dateFormat(now(), "yyyy-mm-dd") & " 23:59:59"; // Orders today count - qOrdersToday = queryExecute(" + qOrdersToday = queryTimed(" SELECT COUNT(*) as cnt FROM Orders WHERE BusinessID = :businessID @@ -50,7 +50,7 @@ try { }); // Revenue today (sum of line items) - qRevenueToday = queryExecute(" + qRevenueToday = queryTimed(" SELECT COALESCE(SUM(li.Quantity * li.Price), 0) as total FROM Orders o JOIN OrderLineItems li ON li.OrderID = o.ID @@ -65,7 +65,7 @@ try { }); // Pending orders (status 1 = submitted, 2 = preparing) - qPendingOrders = queryExecute(" + qPendingOrders = queryTimed(" SELECT COUNT(*) as cnt FROM Orders WHERE BusinessID = :businessID @@ -74,7 +74,7 @@ try { // Menu items count (active items that have a parent category, excluding categories themselves) // Categories are items with ParentItemID = 0 and IsCollapsible = 0 - qMenuItems = queryExecute(" + qMenuItems = queryTimed(" SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :businessID diff --git a/api/portal/team.cfm b/api/portal/team.cfm index 64e55e1..f1c8e4a 100644 --- a/api/portal/team.cfm +++ b/api/portal/team.cfm @@ -40,7 +40,7 @@ if (businessId <= 0) { try { // Get employees for this business with user details // Cast BIT to INT to avoid binary comparison issues - qTeam = queryExecute(" + qTeam = queryTimed(" SELECT e.ID, e.UserID, diff --git a/api/portal/updateSettings.cfm b/api/portal/updateSettings.cfm index ff01f74..a314481 100644 --- a/api/portal/updateSettings.cfm +++ b/api/portal/updateSettings.cfm @@ -99,12 +99,12 @@ try { // Build and execute Businesses update if (arrayLen(updates) > 0) { sql = "UPDATE Businesses SET " & arrayToList(updates, ", ") & " WHERE ID = :businessId"; - queryExecute(sql, params, { datasource: "payfrit" }); + queryTimed(sql, params, { datasource: "payfrit" }); } // Update address in Addresses table if needed if (hasAddressUpdate) { - qExistingAddr = queryExecute(" + qExistingAddr = queryTimed(" SELECT ID FROM Addresses WHERE (BusinessID = :businessId OR ID = (SELECT AddressID FROM Businesses WHERE ID = :businessId)) AND IsDeleted = 0 @@ -127,21 +127,21 @@ try { addrParams.zip = { value: addrFields.ZIPCode, cfsqltype: "cf_sql_varchar" }; } if (arrayLen(addrUpdates) > 0) { - queryExecute("UPDATE Addresses SET " & arrayToList(addrUpdates, ", ") & " WHERE ID = :addrId", + queryTimed("UPDATE Addresses SET " & arrayToList(addrUpdates, ", ") & " WHERE ID = :addrId", addrParams, { datasource: "payfrit" }); } } } // Return updated settings - q = queryExecute(" + q = queryTimed(" SELECT b.ID, b.Name, b.TaxRate, b.Phone FROM Businesses b WHERE b.ID = :businessId LIMIT 1 ", { businessId: request.BusinessID }, { datasource: "payfrit" }); - qAddr = queryExecute(" + qAddr = queryTimed(" SELECT a.Line1, a.City, a.ZIPCode, s.Abbreviation AS State FROM Addresses a LEFT JOIN tt_States s ON s.ID = a.StateID diff --git a/api/ratings/createAdminRating.cfm b/api/ratings/createAdminRating.cfm index cfb1a8f..eb90f05 100644 --- a/api/ratings/createAdminRating.cfm +++ b/api/ratings/createAdminRating.cfm @@ -45,7 +45,7 @@ try { } // Verify task exists and is completed - qTask = queryExecute(" + qTask = queryTimed(" SELECT t.ID, t.ClaimedByUserID, t.CompletedOn, t.BusinessID FROM Tasks t WHERE t.ID = :taskID @@ -68,7 +68,7 @@ try { } // Check if admin rating already exists for this task - qExisting = queryExecute(" + qExisting = queryTimed(" SELECT ID FROM TaskRatings WHERE TaskID = :taskID AND Direction = 'admin_rates_worker' @@ -82,7 +82,7 @@ try { // Insert the admin rating (completed immediately since admin submits directly) token = generateToken(); - queryExecute(" + queryTimed(" INSERT INTO TaskRatings ( TaskID, ByUserID, ForUserID, Direction, OnTime, CompletedScope, RequiredFollowup, ContinueAllow, @@ -103,7 +103,7 @@ try { token: token }); - ratingID = queryExecute("SELECT LAST_INSERT_ID() AS id", {}).id; + ratingID = queryTimed("SELECT LAST_INSERT_ID() AS id", {}).id; writeOutput(serializeJSON({ "OK": true, diff --git a/api/ratings/listForAdmin.cfm b/api/ratings/listForAdmin.cfm index 56a42d6..a73d9da 100644 --- a/api/ratings/listForAdmin.cfm +++ b/api/ratings/listForAdmin.cfm @@ -30,7 +30,7 @@ try { // Get completed tasks from last 7 days where a worker was assigned // and no admin rating exists yet - qTasks = queryExecute(" + qTasks = queryTimed(" SELECT t.ID, t.Title, t.CompletedOn, t.ClaimedByUserID, t.OrderID, u.FirstName AS WorkerFirstName, u.LastName AS WorkerLastName, o.ID, o.UserID, diff --git a/api/ratings/setup.cfm b/api/ratings/setup.cfm index 018b46c..d21a85b 100644 --- a/api/ratings/setup.cfm +++ b/api/ratings/setup.cfm @@ -3,7 +3,7 @@ try { // Create TaskRatings table - queryExecute(" + queryTimed(" CREATE TABLE IF NOT EXISTS TaskRatings ( ID INT AUTO_INCREMENT PRIMARY KEY, TaskID INT NOT NULL, @@ -39,7 +39,7 @@ try { ", {}, { datasource: "payfrit" }); // Verify table was created - cols = queryExecute("DESCRIBE TaskRatings", {}, { datasource: "payfrit" }); + cols = queryTimed("DESCRIBE TaskRatings", {}, { datasource: "payfrit" }); colNames = []; for (c in cols) { arrayAppend(colNames, c.Field); diff --git a/api/ratings/submit.cfm b/api/ratings/submit.cfm index 54b6a81..1058d20 100644 --- a/api/ratings/submit.cfm +++ b/api/ratings/submit.cfm @@ -26,7 +26,7 @@ try { } // Look up the rating by token - qRating = queryExecute(" + qRating = queryTimed(" SELECT r.*, t.Title, u_for.FirstName AS ForFirstName, u_for.LastName AS ForLastName, u_by.FirstName AS ByFirstName, u_by.LastName AS ByLastName @@ -95,7 +95,7 @@ try { // Process submission based on direction if (qRating.Direction == "customer_rates_worker" || qRating.Direction == "admin_rates_worker") { - queryExecute(" + queryTimed(" UPDATE TaskRatings SET OnTime = ?, CompletedScope = ?, @@ -111,7 +111,7 @@ try { { value = qRating.ID, cfsqltype = "cf_sql_integer" } ]); } else if (qRating.Direction == "worker_rates_customer") { - queryExecute(" + queryTimed(" UPDATE TaskRatings SET Prepared = ?, CompletedScope = ?, diff --git a/api/setup/checkDuplicate.cfm b/api/setup/checkDuplicate.cfm index a8ebfc5..eecb043 100644 --- a/api/setup/checkDuplicate.cfm +++ b/api/setup/checkDuplicate.cfm @@ -43,7 +43,7 @@ try { // Build query to find potential duplicates // Match by name (case-insensitive) OR by address components - qDuplicates = queryExecute(" + qDuplicates = queryTimed(" SELECT DISTINCT b.ID AS BusinessID, b.Name AS Name, diff --git a/api/setup/importBusiness.cfm b/api/setup/importBusiness.cfm index 460933d..681415e 100644 --- a/api/setup/importBusiness.cfm +++ b/api/setup/importBusiness.cfm @@ -92,7 +92,7 @@ try { // Step 1: Create or find business response.steps.append("Step 1: Creating business record..."); - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM Businesses WHERE Name = :name ", { name: biz.name }, { datasource: "payfrit" }); @@ -101,13 +101,13 @@ try { response.steps.append("Business already exists with ID: " & BusinessID); response.warnings.append("Existing business found - will add to existing menu"); } else if (!dryRun) { - queryExecute(" + queryTimed(" INSERT INTO Businesses (Name, UserID, AddressID, BusinessDeliveryZipCodes, AddedOn) VALUES (:name, :ownerID, 0, '', NOW()) ", { name: biz.name, ownerID: ownerUserID }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); BusinessID = qNew.id; response.steps.append("Created business with ID: " & BusinessID); } else { @@ -129,7 +129,7 @@ try { if (!dryRun) { // Check if template already exists for this business - qTmpl = queryExecute(" + qTmpl = queryTimed(" SELECT ID FROM Items WHERE BusinessID = :bizID AND Name = :name @@ -143,7 +143,7 @@ try { } else { // Create template as Item at ParentID=0, with IsCollapsible=1 to mark it as a template // This ensures the API filter excludes it from categories - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, ParentItemID, Price, IsActive, RequiresChildSelection, MaxNumSelectionReq, SortOrder, IsCollapsible @@ -157,7 +157,7 @@ try { maxSelect: maxSelections }, { datasource: "payfrit" }); - qNewTmpl = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewTmpl = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); templateItemID = qNewTmpl.id; response.steps.append("Created template: " & templateName & " (ID: " & templateItemID & ")"); } @@ -172,13 +172,13 @@ try { optPrice = structKeyExists(opt, "price") ? val(opt.price) : 0; optDefault = structKeyExists(opt, "isDefault") && opt.isDefault == true; - qOpt = queryExecute(" + qOpt = queryTimed(" SELECT ID FROM Items WHERE BusinessID = :bizID AND Name = :name AND ParentItemID = :parentID ", { bizID: BusinessID, name: optName, parentID: templateItemID }, { datasource: "payfrit" }); if (qOpt.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, ParentItemID, Price, IsActive, IsCheckedByDefault, SortOrder @@ -214,7 +214,7 @@ try { if (!dryRun) { // Check if category exists (Item at ParentID=0, not a template) - qCat = queryExecute(" + qCat = queryTimed(" SELECT ID FROM Items WHERE BusinessID = :bizID AND Name = :name @@ -226,7 +226,7 @@ try { categoryItemID = qCat.ItemID; response.steps.append("Category exists: " & catName); } else { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, ParentItemID, Price, IsActive, SortOrder @@ -239,7 +239,7 @@ try { sortOrder: catOrder }, { datasource: "payfrit" }); - qNewCat = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewCat = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); categoryItemID = qNewCat.id; response.steps.append("Created category: " & catName & " (ID: " & categoryItemID & ")"); } @@ -271,7 +271,7 @@ try { if (!dryRun) { // Check if item exists - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE BusinessID = :bizID AND Name = :name AND ParentItemID = :parentID ", { bizID: BusinessID, name: itemName, parentID: categoryItemID }, { datasource: "payfrit" }); @@ -279,7 +279,7 @@ try { if (qItem.recordCount > 0) { menuItemID = qItem.ID; } else { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, Description, ParentItemID, Price, IsActive, SortOrder @@ -295,7 +295,7 @@ try { sortOrder: itemOrder }, { datasource: "payfrit" }); - qNewItem = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewItem = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); menuItemID = qNewItem.id; } @@ -307,13 +307,13 @@ try { templateItemID = templateMap[modRef]; // Check if link exists - qLink = queryExecute(" + qLink = queryTimed(" SELECT 1 FROM lt_ItemID_TemplateItemID WHERE ItemID = :itemID AND TemplateItemID = :templateID ", { itemID: menuItemID, templateID: templateItemID }, { datasource: "payfrit" }); if (qLink.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder) VALUES (:itemID, :templateID, :sortOrder) ", { diff --git a/api/setup/reimportBigDeans.cfm b/api/setup/reimportBigDeans.cfm index 6dfe0e8..0f6de7c 100644 --- a/api/setup/reimportBigDeans.cfm +++ b/api/setup/reimportBigDeans.cfm @@ -16,9 +16,9 @@ actions = []; // ============================================================ if (!dryRun) { // Delete template links first - queryExecute("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID IN (SELECT ID FROM Items WHERE BusinessID = :bizId)", { bizId: bizId }); + queryTimed("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID IN (SELECT ID FROM Items WHERE BusinessID = :bizId)", { bizId: bizId }); // Delete all items - queryExecute("DELETE FROM Items WHERE BusinessID = :bizId", { bizId: bizId }); + queryTimed("DELETE FROM Items WHERE BusinessID = :bizId", { bizId: bizId }); } arrayAppend(actions, { step: "CLEAR", message: dryRun ? "Would clear existing data" : "Cleared existing data" }); @@ -30,7 +30,7 @@ arrayAppend(actions, { step: "CLEAR", message: dryRun ? "Would clear existing da function insertItem(name, description, parentId, price, isActive, isCheckedByDefault, requiresChild, maxSelections, isCollapsible, sortOrder) { if (dryRun) return 0; // Note: IsActive is BIT(1) type, use b'1' or b'0' syntax - queryExecute(" + queryTimed(" INSERT INTO Items (BusinessID, Name, Description, ParentItemID, Price, IsActive, IsCheckedByDefault, RequiresChildSelection, MaxNumSelectionReq, IsCollapsible, SortOrder, AddedOn) @@ -41,14 +41,14 @@ function insertItem(name, description, parentId, price, isActive, isCheckedByDef maxSel: maxSelections, isCollapse: isCollapsible, sort: sortOrder }); - qId = queryExecute("SELECT LAST_INSERT_ID() as id"); + qId = queryTimed("SELECT LAST_INSERT_ID() as id"); return qId.id; } // Helper to link template to item function linkTemplate(menuItemId, templateId, sortOrder) { if (dryRun) return; - queryExecute(" + queryTimed(" INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder) VALUES (:itemId, :templateId, :sort) ", { itemId: menuItemId, templateId: templateId, sort: sortOrder }); @@ -316,13 +316,13 @@ arrayAppend(actions, { step: "ITEMS", category: "Hot Dogs & Such", count: 3 }); // Count totals if (!dryRun) { - qCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bizId", { bizId: bizId }); + qCount = queryTimed("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bizId", { bizId: bizId }); totalItems = qCount.cnt; - qTemplateCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bizId AND ParentItemID = 0 AND IsCollapsible = 1", { bizId: bizId }); + qTemplateCount = queryTimed("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bizId AND ParentItemID = 0 AND IsCollapsible = 1", { bizId: bizId }); templateCount = qTemplateCount.cnt; - qLinkCount = queryExecute(" + qLinkCount = queryTimed(" SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID tl JOIN Items i ON i.ID = tl.ItemID WHERE i.BusinessID = :bizId diff --git a/api/setup/saveWizard.cfm b/api/setup/saveWizard.cfm index e40f8a9..ad6589f 100644 --- a/api/setup/saveWizard.cfm +++ b/api/setup/saveWizard.cfm @@ -70,7 +70,7 @@ try { stateID = 0; response.steps.append("State value received: '" & state & "' (len: " & len(state) & ")"); if (len(state)) { - qState = queryExecute(" + qState = queryTimed(" SELECT ID FROM tt_States WHERE Abbreviation = :abbr ", { abbr: uCase(state) }, { datasource: "payfrit" }); @@ -81,7 +81,7 @@ try { } } - queryExecute(" + queryTimed(" INSERT INTO Addresses (Line1, City, StateID, ZIPCode, UserID, AddressTypeID, AddedOn) VALUES (:line1, :city, :stateID, :zip, :userID, :typeID, NOW()) ", { @@ -93,7 +93,7 @@ try { typeID: 2 }, { datasource: "payfrit" }); - qNewAddr = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewAddr = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); addressId = qNewAddr.id; response.steps.append("Created address record (ID: " & addressId & ")"); @@ -102,7 +102,7 @@ try { if (communityMealType < 1 || communityMealType > 2) communityMealType = 1; // Create new business with address link and phone - queryExecute(" + queryTimed(" INSERT INTO Businesses (Name, Phone, UserID, AddressID, DeliveryZIPCodes, BusinessCommunityMealType, TaxRate, BusinessAddedOn) VALUES (:name, :phone, :userId, :addressId, :deliveryZips, :communityMealType, :taxRate, NOW()) ", { @@ -115,12 +115,12 @@ try { taxRate: { value: bizTaxRate, cfsqltype: "cf_sql_decimal" } }, { datasource: "payfrit" }); - qNewBiz = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewBiz = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); businessId = qNewBiz.id; response.steps.append("Created new business: " & bizName & " (ID: " & businessId & ")"); // Update address with business ID link - queryExecute(" + queryTimed(" UPDATE Addresses SET BusinessID = :businessID WHERE ID = :addressID ", { businessID: businessId, @@ -140,7 +140,7 @@ try { for (tt = 1; tt <= arrayLen(defaultTaskTypes); tt++) { taskType = defaultTaskTypes[tt]; - queryExecute(" + queryTimed(" INSERT INTO tt_TaskTypes (Name, Description, Icon, Color, BusinessID, SortOrder) VALUES (:name, :description, :icon, :color, :businessID, :sortOrder) ", { @@ -172,7 +172,7 @@ try { if (len(closeTime) == 5) closeTime = closeTime & ":00"; // Insert hours record for this day - queryExecute(" + queryTimed(" INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizID, :dayID, :openTime, :closeTime) ", { @@ -187,7 +187,7 @@ try { } } else { // Verify existing business exists - qBiz = queryExecute(" + qBiz = queryTimed(" SELECT ID, Name AS BusinessName FROM Businesses WHERE ID = :id ", { id: businessId }, { datasource: "payfrit" }); @@ -219,7 +219,7 @@ try { response.steps.append("Template '" & tmplName & "' has " & arrayLen(options) & " options (type: " & (isArray(options) ? "array" : "other") & ")"); // Check if template already exists for this business - qTmpl = queryExecute(" + qTmpl = queryTimed(" SELECT i.ID FROM Items i WHERE i.BusinessID = :bizID AND i.Name = :name @@ -232,7 +232,7 @@ try { response.steps.append("Template exists: " & tmplName & " (ID: " & templateItemID & ")"); } else { // Create template as Item with CategoryID=0 to mark as template - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, ParentItemID, CategoryID, Price, IsActive, RequiresChildSelection, MaxNumSelectionReq, @@ -246,7 +246,7 @@ try { required: required ? 1 : 0 }, { datasource: "payfrit" }); - qNewTmpl = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewTmpl = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); templateItemID = qNewTmpl.id; response.steps.append("Created template: " & tmplName & " (ID: " & templateItemID & ")"); } @@ -266,13 +266,13 @@ try { optName = opt.name; optPrice = structKeyExists(opt, "price") && isSimpleValue(opt.price) ? val(opt.price) : 0; - qOpt = queryExecute(" + qOpt = queryTimed(" SELECT ID FROM Items WHERE BusinessID = :bizID AND Name = :name AND ParentItemID = :parentID ", { bizID: businessId, name: optName, parentID: templateItemID }, { datasource: "payfrit" }); if (qOpt.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, ParentItemID, CategoryID, Price, IsActive, SortOrder @@ -295,7 +295,7 @@ try { if (providedMenuId > 0) { menuID = providedMenuId; // Look up the menu name for logging - qName = queryExecute("SELECT Name FROM Menus WHERE ID = :id", { id: menuID }, { datasource: "payfrit" }); + qName = queryTimed("SELECT Name FROM Menus WHERE ID = :id", { id: menuID }, { datasource: "payfrit" }); menuName = qName.recordCount > 0 ? qName.Name : "Menu " & menuID; response.steps.append("Using provided menu: " & menuName & " (ID: " & menuID & ")"); } else { @@ -318,7 +318,7 @@ try { // Validate menu hours fall within business operating hours if (len(menuStartTime) && len(menuEndTime)) { - qHours = queryExecute(" + qHours = queryTimed(" SELECT MIN(OpenTime) as earliestOpen, MAX(ClosingTime) as latestClose FROM Hours WHERE BusinessID = :bizID @@ -335,7 +335,7 @@ try { } } - qMenu = queryExecute(" + qMenu = queryTimed(" SELECT ID FROM Menus WHERE BusinessID = :bizID AND Name = :name AND IsActive = 1 ", { bizID: businessId, name: menuName }, { datasource: "payfrit" }); @@ -344,7 +344,7 @@ try { menuID = qMenu.ID; // Update existing menu with new time range if provided if (len(menuStartTime) && len(menuEndTime)) { - queryExecute(" + queryTimed(" UPDATE Menus SET StartTime = :startTime, EndTime = :endTime WHERE ID = :menuID ", { @@ -357,7 +357,7 @@ try { response.steps.append("Using existing menu: " & menuName & " (ID: " & menuID & ")"); } } else { - queryExecute(" + queryTimed(" INSERT INTO Menus ( BusinessID, Name, DaysActive, StartTime, EndTime, SortOrder, IsActive, AddedOn ) VALUES ( @@ -370,7 +370,7 @@ try { endTime: len(menuEndTime) ? menuEndTime : javaCast("null", "") }, { datasource: "payfrit" }); - qNewMenu = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewMenu = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); menuID = qNewMenu.id; timeInfo = len(menuStartTime) && len(menuEndTime) ? " (" & menuStartTime & " - " & menuEndTime & ")" : " (all day)"; response.steps.append("Created menu: " & menuName & timeInfo & " (ID: " & menuID & ")"); @@ -393,7 +393,7 @@ try { } // Check if category exists in Categories table for this menu - qCat = queryExecute(" + qCat = queryTimed(" SELECT ID FROM Categories WHERE BusinessID = :bizID AND Name = :name AND MenuID = :menuID ", { bizID: businessId, name: catName, menuID: menuID }, { datasource: "payfrit" }); @@ -403,7 +403,7 @@ try { response.steps.append("Category exists: " & catName & " (ID: " & categoryID & ")"); } else { // Create category in Categories table with MenuID - queryExecute(" + queryTimed(" INSERT INTO Categories ( BusinessID, MenuID, Name, SortOrder ) VALUES ( @@ -416,7 +416,7 @@ try { sortOrder: catOrder }, { datasource: "payfrit" }); - qNewCat = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewCat = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); categoryID = qNewCat.id; response.steps.append("Created category: " & catName & " in menu " & menuName & " (ID: " & categoryID & ")"); } @@ -482,7 +482,7 @@ try { categoryItemOrder[itemCategory]++; // Check if item exists - qItem = queryExecute(" + qItem = queryTimed(" SELECT ID FROM Items WHERE BusinessID = :bizID AND Name = :name @@ -492,7 +492,7 @@ try { if (qItem.recordCount > 0) { menuItemID = qItem.ID; // Update existing item - queryExecute(" + queryTimed(" UPDATE Items SET Description = :desc, Price = :price, @@ -505,7 +505,7 @@ try { id: menuItemID }, { datasource: "payfrit" }); } else { - queryExecute(" + queryTimed(" INSERT INTO Items ( BusinessID, Name, Description, ParentItemID, CategoryID, Price, IsActive, SortOrder @@ -521,7 +521,7 @@ try { sortOrder: itemOrder }, { datasource: "payfrit" }); - qNewItem = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + qNewItem = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); menuItemID = qNewItem.id; } @@ -543,13 +543,13 @@ try { templateItemID = templateMap[modName]; // Check if link exists - qLink = queryExecute(" + qLink = queryTimed(" SELECT 1 FROM lt_ItemID_TemplateItemID WHERE ItemID = :itemID AND TemplateItemID = :templateID ", { itemID: menuItemID, templateID: templateItemID }, { datasource: "payfrit" }); if (qLink.recordCount == 0) { - queryExecute(" + queryTimed(" INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder) VALUES (:itemID, :templateID, :sortOrder) ", { diff --git a/api/stations/list.cfm b/api/stations/list.cfm index b47750a..abb64a1 100644 --- a/api/stations/list.cfm +++ b/api/stations/list.cfm @@ -34,7 +34,7 @@ - 0) { // Update order status to paid/submitted (status 1) // Note: Task is created later when order status changes to Ready (3) in updateStatus.cfm - queryExecute(" + queryTimed(" UPDATE Orders SET PaymentStatus = 'paid', PaymentCompletedOn = NOW(), @@ -92,7 +92,7 @@ try { // === WORKER PAYOUT TRANSFER === // Find ledger row for this PaymentIntent try { - qLedger = queryExecute(" + qLedger = queryTimed(" SELECT wpl.ID, wpl.UserID, wpl.TaskID, wpl.NetTransferCents, wpl.StripeTransferID, wpl.Status FROM WorkPayoutLedgers wpl @@ -102,13 +102,13 @@ try { if (qLedger.recordCount > 0 && isNull(qLedger.StripeTransferID) && qLedger.Status == "pending_charge") { // Mark as charged - queryExecute(" + queryTimed(" UPDATE WorkPayoutLedgers SET Status = 'charged', UpdatedAt = NOW() WHERE ID = :ledgerID ", { ledgerID: qLedger.ID }); // Look up worker's Stripe Connected Account - qWorker = queryExecute(" + qWorker = queryTimed(" SELECT StripeConnectedAccountID FROM Users WHERE ID = :userID ", { userID: qLedger.UserID }); @@ -135,7 +135,7 @@ try { transferData = deserializeJSON(transferResult.fileContent); if (structKeyExists(transferData, "id")) { - queryExecute(" + queryTimed(" UPDATE WorkPayoutLedgers SET StripeTransferID = :transferID, Status = 'transferred', UpdatedAt = NOW() WHERE ID = :ledgerID @@ -147,7 +147,7 @@ try { } } else if (qLedger.NetTransferCents == 0) { // Nothing to transfer (entire amount withheld for activation) - queryExecute(" + queryTimed(" UPDATE WorkPayoutLedgers SET Status = 'transferred', UpdatedAt = NOW() WHERE ID = :ledgerID ", { ledgerID: qLedger.ID }); @@ -166,7 +166,7 @@ try { if (grantOwnerFeeCents > 0 && grantOwnerBizID > 0) { // Look up owner business Stripe account - qOwnerBiz = queryExecute(" + qOwnerBiz = queryTimed(" SELECT StripeAccountID FROM Businesses WHERE ID = :bizID ", { bizID: grantOwnerBizID }); @@ -212,7 +212,7 @@ try { failureMessage = eventData.last_payment_error.message ?: "Payment failed"; if (orderID > 0) { - queryExecute(" + queryTimed(" UPDATE Orders SET PaymentStatus = 'failed', PaymentError = :failureMessage @@ -233,13 +233,13 @@ try { refundAmount = eventData.amount_refunded / 100; if (paymentIntentID != "") { - qOrder = queryExecute(" + qOrder = queryTimed(" SELECT ID FROM Orders WHERE OrderStripePaymentIntentID = :paymentIntentID ", { paymentIntentID: paymentIntentID }); if (qOrder.recordCount > 0) { - queryExecute(" + queryTimed(" UPDATE Orders SET PaymentStatus = 'refunded', OrderRefundAmount = :refundAmount, @@ -261,20 +261,20 @@ try { paymentIntentID = eventData.payment_intent ?: ""; if (paymentIntentID != "") { - qOrder = queryExecute(" + qOrder = queryTimed(" SELECT ID, BusinessID FROM Orders WHERE OrderStripePaymentIntentID = :paymentIntentID ", { paymentIntentID: paymentIntentID }); if (qOrder.recordCount > 0) { - queryExecute(" + queryTimed(" UPDATE Orders SET PaymentStatus = 'disputed' WHERE OrderStripePaymentIntentID = :paymentIntentID ", { paymentIntentID: paymentIntentID }); // Create a task for the dispute - queryExecute(" + queryTimed(" INSERT INTO Tasks (BusinessID, CategoryID, Title, Details, CreatedOn, StatusID, SourceType, SourceID) VALUES (:businessID, 4, 'Payment Dispute', 'Order ###qOrder.ID# has been disputed. Review immediately.', NOW(), 0, 'dispute', :orderID) ", { @@ -295,7 +295,7 @@ try { // Business accounts if (chargesEnabled && payoutsEnabled) { - queryExecute(" + queryTimed(" UPDATE Businesses SET StripeOnboardingComplete = 1 WHERE StripeAccountID = :accountID @@ -306,14 +306,14 @@ try { // Worker accounts โ€” update StripePayoutsEnabled for tier derivation try { - qWorkerAcct = queryExecute(" + qWorkerAcct = queryTimed(" SELECT ID FROM Users WHERE StripeConnectedAccountID = :accountID LIMIT 1 ", { accountID: accountID }); if (qWorkerAcct.recordCount > 0) { - queryExecute(" + queryTimed(" UPDATE Users SET StripePayoutsEnabled = :payoutsEnabled WHERE StripeConnectedAccountID = :accountID @@ -338,7 +338,7 @@ try { metaUserID = val(sessionMetadata.user_id ?: 0); if (metaType == "activation_unlock" && metaUserID > 0) { - queryExecute(" + queryTimed(" UPDATE Users SET ActivationBalanceCents = ActivationCapCents WHERE ID = :userID @@ -355,7 +355,7 @@ try { if (metaTipID > 0) { // Mark tip as paid - queryExecute(" + queryTimed(" UPDATE Tips SET Status = 'paid', PaidOn = NOW(), @@ -370,14 +370,14 @@ try { // Transfer tip to worker's Stripe Connect account if (metaWorkerID > 0) { - qTipWorker = queryExecute(" + qTipWorker = queryTimed(" SELECT StripeConnectedAccountID FROM Users WHERE ID = :userID ", { userID: metaWorkerID }, { datasource: "payfrit" }); tipWorkerAcct = qTipWorker.recordCount > 0 ? (qTipWorker.StripeConnectedAccountID ?: "") : ""; if (len(trim(tipWorkerAcct)) > 0) { - qTipAmt = queryExecute(" + qTipAmt = queryTimed(" SELECT AmountCents FROM Tips WHERE ID = :tipID ", { tipID: metaTipID }, { datasource: "payfrit" }); @@ -400,7 +400,7 @@ try { tipTransferData = deserializeJSON(tipTransferResult.fileContent); if (structKeyExists(tipTransferData, "id")) { - queryExecute(" + queryTimed(" UPDATE Tips SET Status = 'transferred', StripeTransferID = :transferID WHERE ID = :tipID diff --git a/api/tasks/accept.cfm b/api/tasks/accept.cfm index ea6f9b0..92abf03 100644 --- a/api/tasks/accept.cfm +++ b/api/tasks/accept.cfm @@ -36,7 +36,7 @@ - - 0) { - userQuery = queryExecute(" + userQuery = queryTimed(" SELECT FirstName FROM Users WHERE ID = :userID ", { userID: { value: userID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); if (userQuery.recordCount && len(trim(userQuery.FirstName))) { @@ -62,7 +62,7 @@ try { taskTypeName = ""; taskTypeCategoryID = 0; if (taskTypeID > 0) { - typeQuery = queryExecute(" + typeQuery = queryTimed(" SELECT Name, TaskCategoryID FROM tt_TaskTypes WHERE tt_TaskTypeID = :typeID ", { typeID: { value: taskTypeID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); if (typeQuery.recordCount) { @@ -104,7 +104,7 @@ try { categoryID = taskTypeCategoryID; } else { // Fallback: look up or create a "Service" category for this business - catQuery = queryExecute(" + catQuery = queryTimed(" SELECT ID FROM TaskCategories WHERE BusinessID = :businessID AND Name = 'Service' LIMIT 1 @@ -112,12 +112,12 @@ try { if (catQuery.recordCount == 0) { // Create the category - queryExecute(" + queryTimed(" INSERT INTO TaskCategories (BusinessID, Name, Color) VALUES (:businessID, 'Service', '##FF9800') ", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); - catResult = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + catResult = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); categoryID = catResult.newID; } else { categoryID = catQuery.ID; @@ -125,7 +125,7 @@ try { } // Insert task - queryExecute(" + queryTimed(" INSERT INTO Tasks ( BusinessID, CategoryID, @@ -155,7 +155,7 @@ try { }, { datasource: "payfrit" }); // Get the new task ID - result = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + result = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); taskID = result.newID; apiAbort({ diff --git a/api/tasks/complete.cfm b/api/tasks/complete.cfm index 64d59e1..0a8f62c 100644 --- a/api/tasks/complete.cfm +++ b/api/tasks/complete.cfm @@ -44,7 +44,7 @@ - - - - - @@ -149,7 +149,7 @@ - - - - - - 0) { - itemQuery = queryExecute(" + itemQuery = queryTimed(" SELECT Name FROM Items WHERE ID = :itemID ", { itemID: itemID }); if (itemQuery.recordCount) { @@ -105,7 +105,7 @@ try { } // Insert legacy task - queryExecute(" + queryTimed(" INSERT INTO Tasks ( BusinessID, TaskItemID, @@ -136,7 +136,7 @@ try { } // Get the new task ID - result = queryExecute("SELECT LAST_INSERT_ID() as newID", {}, { datasource: "payfrit" }); + result = queryTimed("SELECT LAST_INSERT_ID() as newID", {}, { datasource: "payfrit" }); taskID = result.newID; response = { diff --git a/api/tasks/createChat.cfm b/api/tasks/createChat.cfm index af02596..9bf7020 100644 --- a/api/tasks/createChat.cfm +++ b/api/tasks/createChat.cfm @@ -45,7 +45,7 @@ try { if (!forceNew) { // Look for any active chat for this business // Check by: order match, service point match, OR user match (for remote chats) - existingChat = queryExecute(" + existingChat = queryTimed(" SELECT t.ID, t.CreatedOn, (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.ID) as LastMessageTime FROM Tasks t @@ -78,7 +78,7 @@ try { if (chatAge > 30) { // Auto-close stale chat - queryExecute(" + queryTimed(" UPDATE Tasks SET CompletedOn = NOW() WHERE TaskID = :taskID ", { taskID: { value: existingChat.ID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); @@ -97,7 +97,7 @@ try { // Get service point info (table name) - only if dine-in tableName = ""; if (servicePointID > 0) { - spQuery = queryExecute(" + spQuery = queryTimed(" SELECT Name FROM ServicePoints WHERE ID = :spID ", { spID: { value: servicePointID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); tableName = spQuery.recordCount ? spQuery.Name : "Table ##" & servicePointID; @@ -106,7 +106,7 @@ try { // Get user name if available userName = ""; if (userID > 0) { - userQuery = queryExecute(" + userQuery = queryTimed(" SELECT FirstName FROM Users WHERE ID = :userID ", { userID: { value: userID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); if (userQuery.recordCount && len(trim(userQuery.FirstName))) { @@ -136,7 +136,7 @@ try { } // Look up or create a "Chat" category for this business - catQuery = queryExecute(" + catQuery = queryTimed(" SELECT ID FROM TaskCategories WHERE BusinessID = :businessID AND Name = 'Chat' LIMIT 1 @@ -144,12 +144,12 @@ try { if (catQuery.recordCount == 0) { // Create the category (blue color for chat) - queryExecute(" + queryTimed(" INSERT INTO TaskCategories (BusinessID, Name, Color) VALUES (:businessID, 'Chat', '##2196F3') ", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); - catResult = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + catResult = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); categoryID = catResult.newID; } else { categoryID = catQuery.ID; @@ -165,7 +165,7 @@ try { } // Insert task with TaskTypeID = 2 (Chat) - queryExecute(" + queryTimed(" INSERT INTO Tasks ( BusinessID, CategoryID, @@ -200,12 +200,12 @@ try { }, { datasource: "payfrit" }); // Get the new task ID - result = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + result = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); taskID = result.newID; // If there's an initial message, save it if (len(initialMessage) && userID > 0) { - queryExecute(" + queryTimed(" INSERT INTO ChatMessages (TaskID, SenderUserID, SenderType, MessageBody) VALUES (:taskID, :userID, 'customer', :message) ", { diff --git a/api/tasks/deleteCategory.cfm b/api/tasks/deleteCategory.cfm index 5e8c311..5575607 100644 --- a/api/tasks/deleteCategory.cfm +++ b/api/tasks/deleteCategory.cfm @@ -50,7 +50,7 @@ try { } // Verify ownership - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM TaskCategories WHERE ID = :id AND BusinessID = :businessID ", { @@ -63,7 +63,7 @@ try { } // Check if any tasks use this category - qTasks = queryExecute(" + qTasks = queryTimed(" SELECT COUNT(*) as cnt FROM Tasks WHERE CategoryID = :id ", { @@ -72,7 +72,7 @@ try { if (qTasks.cnt > 0) { // Soft delete - just deactivate - queryExecute(" + queryTimed(" UPDATE TaskCategories SET IsActive = 0 WHERE ID = :id ", { @@ -85,7 +85,7 @@ try { }); } else { // Hard delete - no tasks use it - queryExecute(" + queryTimed(" DELETE FROM TaskCategories WHERE ID = :id ", { id: { value: categoryID, cfsqltype: "cf_sql_integer" } diff --git a/api/tasks/deleteType.cfm b/api/tasks/deleteType.cfm index 2ba1bbe..cd6f63d 100644 --- a/api/tasks/deleteType.cfm +++ b/api/tasks/deleteType.cfm @@ -45,7 +45,7 @@ try { } // Verify task type exists and belongs to this business - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT tt_TaskTypeID, BusinessID FROM tt_TaskTypes WHERE tt_TaskTypeID = :taskTypeID @@ -62,7 +62,7 @@ try { } // Delete the task type - queryExecute(" + queryTimed(" DELETE FROM tt_TaskTypes WHERE tt_TaskTypeID = :taskTypeID AND BusinessID = :businessID diff --git a/api/tasks/expireStaleChats.cfm b/api/tasks/expireStaleChats.cfm index bf6fc3e..e1bc7be 100644 --- a/api/tasks/expireStaleChats.cfm +++ b/api/tasks/expireStaleChats.cfm @@ -19,7 +19,7 @@ try { // 2. CompletedOn IS NULL (not closed) // 3. No messages in the last 20 minutes AND task is older than 20 minutes - staleChats = queryExecute(" + staleChats = queryTimed(" SELECT t.ID, t.CreatedOn, (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.ID) as LastMessageOn FROM Tasks t @@ -47,7 +47,7 @@ try { } if (shouldExpire) { - queryExecute(" + queryTimed(" UPDATE Tasks SET CompletedOn = NOW() WHERE ID = :taskID ", { taskID: { value: chat.ID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); diff --git a/api/tasks/getDetails.cfm b/api/tasks/getDetails.cfm index d45741e..71c4693 100644 --- a/api/tasks/getDetails.cfm +++ b/api/tasks/getDetails.cfm @@ -35,7 +35,7 @@ - - - - - @@ -54,7 +54,7 @@ - 0) { // UPDATE existing category - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT ID FROM TaskCategories WHERE ID = :id AND BusinessID = :businessID ", { @@ -77,7 +77,7 @@ try { apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Category not found" }); } - queryExecute(" + queryTimed(" UPDATE TaskCategories SET Name = :name, Color = :color @@ -96,7 +96,7 @@ try { } else { // INSERT new category - queryExecute(" + queryTimed(" INSERT INTO TaskCategories (BusinessID, Name, Color) VALUES (:businessID, :name, :color) ", { @@ -105,7 +105,7 @@ try { color: { value: categoryColor, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); apiAbort({ "OK": true, diff --git a/api/tasks/saveType.cfm b/api/tasks/saveType.cfm index 75e9aa2..0c59742 100644 --- a/api/tasks/saveType.cfm +++ b/api/tasks/saveType.cfm @@ -94,7 +94,7 @@ try { if (taskTypeID > 0) { // UPDATE - verify it belongs to this business - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT tt_TaskTypeID FROM tt_TaskTypes WHERE tt_TaskTypeID = :taskTypeID AND BusinessID = :businessID @@ -107,7 +107,7 @@ try { apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Task type not found or does not belong to this business" }); } - queryExecute(" + queryTimed(" UPDATE tt_TaskTypes SET Name = :taskTypeName, Description = :taskTypeDescription, @@ -131,7 +131,7 @@ try { }); } else { // INSERT new task type - queryExecute(" + queryTimed(" INSERT INTO tt_TaskTypes (Name, Description, Icon, Color, BusinessID, TaskCategoryID) VALUES (:taskTypeName, :taskTypeDescription, :taskTypeIcon, :taskTypeColor, :businessID, :categoryID) ", { @@ -143,7 +143,7 @@ try { categoryID: { value: taskTypeCategoryID, cfsqltype: "cf_sql_integer", null: isNull(taskTypeCategoryID) } }, { datasource: "payfrit" }); - qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); + qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" }); newID = qNew.newID; apiAbort({ diff --git a/api/tasks/seedCategories.cfm b/api/tasks/seedCategories.cfm index b48f60b..7687f5b 100644 --- a/api/tasks/seedCategories.cfm +++ b/api/tasks/seedCategories.cfm @@ -45,7 +45,7 @@ try { } // Check if categories already exist - qCheck = queryExecute(" + qCheck = queryTimed(" SELECT COUNT(*) AS cnt FROM TaskCategories WHERE BusinessID = :businessID ", { @@ -54,7 +54,7 @@ try { if (qCheck.cnt > 0) { // Categories already exist, just return them - qCategories = queryExecute(" + qCategories = queryTimed(" SELECT ID, Name, Color FROM TaskCategories WHERE BusinessID = :businessID AND IsActive = 1 @@ -92,7 +92,7 @@ try { // Insert defaults for (cat in defaults) { - queryExecute(" + queryTimed(" INSERT INTO TaskCategories (BusinessID, Name, Color) VALUES (:businessID, :name, :color) ", { @@ -103,7 +103,7 @@ try { } // Return the created categories - qCategories = queryExecute(" + qCategories = queryTimed(" SELECT ID, Name, Color FROM TaskCategories WHERE BusinessID = :businessID AND IsActive = 1 diff --git a/api/tasks/setup.cfm b/api/tasks/setup.cfm index e623fb6..5aca0e1 100644 --- a/api/tasks/setup.cfm +++ b/api/tasks/setup.cfm @@ -2,7 +2,7 @@ - - + - - + - - + +
+
B
+
+
Loading...
+
Online
+
+
+ - + @@ -145,10 +128,29 @@ - @@ -748,5 +750,30 @@
+ + + diff --git a/portal/login.html b/portal/login.html index 94af0a2..68d3a84 100644 --- a/portal/login.html +++ b/portal/login.html @@ -1,775 +1,775 @@ - - - - - - Login - Payfrit Business Portal - - - - - - - - - + + + + + + Login - Payfrit Business Portal + + + + + + + + + diff --git a/portal/menu-builder.html b/portal/menu-builder.html index 716c456..636968a 100644 --- a/portal/menu-builder.html +++ b/portal/menu-builder.html @@ -1,4140 +1,4140 @@ - - - - - - Menu Builder - Payfrit - - - - - -
- - - - -
-
- -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
- -
-

Components

-
-
-
๐Ÿ“
-
-
Category
-
Group of menu items
-
-
-
-
๐Ÿฝ๏ธ
-
-
Menu Item
-
Orderable product
-
-
-
-
โš™๏ธ
-
-
Modifier
-
Add-on or option
-
-
-
-
๐Ÿ“‹
-
-
Modifier Group
-
Group of options
-
-
-
- -

Modifier Templates

-
-
Loading templates...
-
- -

Quick Stats

-
-
- Categories: - 0 -
-
- Items: - 0 -
-
- Templates: - 0 -
-
- Photos Missing: - 0 -
-
- -

Branding

-
- - -

- Header: 1200x400px recommended
- Color: Used for category bars in the app -

-
-
- - -
-
-

- Menu Builder - -

-
- -
-
- - -
- - -
-
-

Properties

-
- -
-

- Select an item to edit its properties -

-
-
-
-
-
-
- - -
-
- - - - - Edit - Enter -
-
- - - - - Clone - Ctrl+D -
-
- - - - - - Create Photo Task -
-
-
- - - - Move Up - Alt+Up -
-
- - - - Move Down - Alt+Down -
-
-
- - - - Delete - Del -
-
- - - - - -
- - - - + + + + + + Menu Builder - Payfrit + + + + + +
+ + + + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+ +
+

Components

+
+
+
๐Ÿ“
+
+
Category
+
Group of menu items
+
+
+
+
๐Ÿฝ๏ธ
+
+
Menu Item
+
Orderable product
+
+
+
+
โš™๏ธ
+
+
Modifier
+
Add-on or option
+
+
+
+
๐Ÿ“‹
+
+
Modifier Group
+
Group of options
+
+
+
+ +

Modifier Templates

+
+
Loading templates...
+
+ +

Quick Stats

+
+
+ Categories: + 0 +
+
+ Items: + 0 +
+
+ Templates: + 0 +
+
+ Photos Missing: + 0 +
+
+ +

Branding

+
+ + +

+ Header: 1200x400px recommended
+ Color: Used for category bars in the app +

+
+
+ + +
+
+

+ Menu Builder + +

+
+ +
+
+ + +
+ + +
+
+

Properties

+
+ +
+

+ Select an item to edit its properties +

+
+
+
+
+
+
+ + +
+
+ + + + + Edit + Enter +
+
+ + + + + Clone + Ctrl+D +
+
+ + + + + + Create Photo Task +
+
+
+ + + + Move Up + Alt+Up +
+
+ + + + Move Down + Alt+Down +
+
+
+ + + + Delete + Del +
+
+ + + + + +
+ + + + diff --git a/portal/portal.js b/portal/portal.js index c8a1667..5ca5159 100644 --- a/portal/portal.js +++ b/portal/portal.js @@ -113,18 +113,18 @@ const Portal = { this.businessData = biz; // Store for later use document.getElementById('businessName').textContent = biz.Name || 'Business'; document.getElementById('businessAvatar').textContent = (biz.Name || 'B').charAt(0).toUpperCase(); - document.getElementById('userAvatar').textContent = 'U'; + document.getElementById('userAvatar').textContent = (document.getElementById('businessAvatar').textContent || 'B'); } else { this.businessData = null; document.getElementById('businessName').textContent = 'Business #' + this.config.businessId; document.getElementById('businessAvatar').textContent = 'B'; - document.getElementById('userAvatar').textContent = 'U'; + document.getElementById('userAvatar').textContent = (document.getElementById('businessAvatar').textContent || 'B'); } } catch (err) { console.error('[Portal] Business info error:', err); document.getElementById('businessName').textContent = 'Business #' + this.config.businessId; document.getElementById('businessAvatar').textContent = 'B'; - document.getElementById('userAvatar').textContent = 'U'; + document.getElementById('userAvatar').textContent = (document.getElementById('businessAvatar').textContent || 'B'); } },