function apiAbort(required struct payload) { writeOutput(serializeJSON(payload)); abort; } function readJsonBody() { var raw = getHttpRequestData().content; if (isNull(raw)) raw = ""; if (!len(trim(raw))) return {}; try { var data = deserializeJSON(raw); if (isStruct(data)) return data; } catch (any e) {} return {}; } // Normalize phone to digits only function normalizePhone(phone) { return reReplace(phone, "[^0-9]", "", "all"); } data = readJsonBody(); query = structKeyExists(data, "Query") ? trim(data.Query) : ""; businessId = structKeyExists(data, "BusinessID") ? val(data.BusinessID) : 0; if (len(query) < 3) { apiAbort({ "OK": false, "ERROR": "query_too_short", "MESSAGE": "Enter at least 3 characters" }); } try { // Detect if it's a phone number or email isPhone = reFind("^[\d\s\-\(\)\+]+$", query) && len(normalizePhone(query)) >= 7; isEmail = find("@", query) > 0; if (isPhone) { // Search by phone - normalize both sides phoneDigits = normalizePhone(query); qUser = queryExecute(" SELECT UserID, UserFirstName, UserLastName, UserContactNumber, UserEmailAddress FROM Users WHERE REPLACE(REPLACE(REPLACE(REPLACE(UserContactNumber, '-', ''), ' ', ''), '(', ''), ')', '') LIKE :phone LIMIT 1 ", { phone: { value: "%" & phoneDigits & "%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" }); } else if (isEmail) { // Search by email (partial match) qUser = queryExecute(" SELECT UserID, UserFirstName, UserLastName, UserContactNumber, UserEmailAddress FROM Users WHERE UserEmailAddress LIKE :email LIMIT 1 ", { email: { value: "%" & query & "%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" }); } else { // Search by name qUser = queryExecute(" SELECT UserID, UserFirstName, UserLastName, UserContactNumber, UserEmailAddress FROM Users WHERE UserFirstName LIKE :name OR UserLastName LIKE :name OR CONCAT(UserFirstName, ' ', UserLastName) LIKE :name LIMIT 1 ", { name: { value: "%" & query & "%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" }); } if (qUser.recordCount > 0) { // Check if already on team qTeam = queryExecute(" SELECT EmployeeID FROM lt_Users_Businesses_Employees WHERE BusinessID = :bizId AND UserID = :userId ", { bizId: { value: businessId, cfsqltype: "cf_sql_integer" }, userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); apiAbort({ "OK": true, "USER": { "UserID": qUser.UserID, "Name": trim(qUser.UserFirstName & " " & qUser.UserLastName), "Phone": qUser.UserContactNumber, "Email": qUser.UserEmailAddress, "AlreadyOnTeam": qTeam.recordCount > 0 } }); } else { apiAbort({ "OK": true, "USER": javaCast("null", "") }); } } catch (any e) { apiAbort({ "OK": false, "ERROR": "server_error", "MESSAGE": e.message }); }