Converts 200+ endpoint files to use queryTimed() wrapper which tracks DB query count and execution time. Restores perf dashboard files that were accidentally moved to _scripts/. Includes portal UI updates.
167 lines
6.2 KiB
Text
167 lines
6.2 KiB
Text
<cfsetting showdebugoutput="false">
|
|
<cfsetting enablecfoutputonly="true">
|
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
|
<cfheader name="Cache-Control" value="no-store">
|
|
|
|
<cfinclude template="_grantUtils.cfm">
|
|
|
|
<cfscript>
|
|
data = {};
|
|
try {
|
|
raw = toString(getHttpRequestData().content);
|
|
if (len(trim(raw))) {
|
|
data = deserializeJSON(raw);
|
|
if (!isStruct(data)) data = {};
|
|
}
|
|
} catch (any e) { data = {}; }
|
|
|
|
ownerBusinessID = val(data.OwnerBusinessID ?: 0);
|
|
guestBusinessID = val(data.GuestBusinessID ?: 0);
|
|
servicePointID = val(data.ServicePointID ?: 0);
|
|
economicsType = trim(data.EconomicsType ?: "none");
|
|
economicsValue = val(data.EconomicsValue ?: 0);
|
|
eligibilityScope = trim(data.EligibilityScope ?: "public");
|
|
timePolicyType = trim(data.TimePolicyType ?: "always");
|
|
timePolicyData = structKeyExists(data, "TimePolicyData") ? data.TimePolicyData : "";
|
|
|
|
// Validate required fields
|
|
if (ownerBusinessID LTE 0 || guestBusinessID LTE 0 || servicePointID LTE 0) {
|
|
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "OwnerBusinessID, GuestBusinessID, and ServicePointID are required." });
|
|
}
|
|
|
|
if (ownerBusinessID == guestBusinessID) {
|
|
apiAbort({ "OK": false, "ERROR": "self_grant", "MESSAGE": "Cannot grant access to your own business." });
|
|
}
|
|
|
|
// Validate caller is the owner of OwnerBusinessID
|
|
callerUserID = val(structKeyExists(request, "UserID") ? request.UserID : 0);
|
|
if (callerUserID LTE 0) {
|
|
apiAbort({ "OK": false, "ERROR": "not_authenticated", "MESSAGE": "Authentication required." });
|
|
}
|
|
|
|
qOwner = queryTimed(
|
|
"SELECT UserID FROM Businesses WHERE ID = ? LIMIT 1",
|
|
[{ value = ownerBusinessID, cfsqltype = "cf_sql_integer" }],
|
|
{ datasource = "payfrit" }
|
|
);
|
|
if (qOwner.recordCount == 0 || qOwner.UserID != callerUserID) {
|
|
apiAbort({ "OK": false, "ERROR": "not_owner", "MESSAGE": "You are not the owner of this business." });
|
|
}
|
|
|
|
// Validate ServicePoint belongs to OwnerBusinessID
|
|
qSP = queryTimed(
|
|
"SELECT ID FROM ServicePoints WHERE ID = ? AND BusinessID = ? LIMIT 1",
|
|
[
|
|
{ value = servicePointID, cfsqltype = "cf_sql_integer" },
|
|
{ value = ownerBusinessID, cfsqltype = "cf_sql_integer" }
|
|
],
|
|
{ datasource = "payfrit" }
|
|
);
|
|
if (qSP.recordCount == 0) {
|
|
apiAbort({ "OK": false, "ERROR": "sp_not_owned", "MESSAGE": "Service point does not belong to your business." });
|
|
}
|
|
|
|
// Validate GuestBusiness exists
|
|
qGuest = queryTimed(
|
|
"SELECT ID FROM Businesses WHERE ID = ? LIMIT 1",
|
|
[{ value = guestBusinessID, cfsqltype = "cf_sql_integer" }],
|
|
{ datasource = "payfrit" }
|
|
);
|
|
if (qGuest.recordCount == 0) {
|
|
apiAbort({ "OK": false, "ERROR": "guest_not_found", "MESSAGE": "Guest business not found." });
|
|
}
|
|
|
|
// Check no active or pending grant exists for this combo
|
|
qExisting = queryTimed(
|
|
"SELECT ID FROM ServicePointGrants
|
|
WHERE OwnerBusinessID = ? AND GuestBusinessID = ? AND ServicePointID = ? AND StatusID IN (0, 1)
|
|
LIMIT 1",
|
|
[
|
|
{ value = ownerBusinessID, cfsqltype = "cf_sql_integer" },
|
|
{ value = guestBusinessID, cfsqltype = "cf_sql_integer" },
|
|
{ value = servicePointID, cfsqltype = "cf_sql_integer" }
|
|
],
|
|
{ datasource = "payfrit" }
|
|
);
|
|
if (qExisting.recordCount > 0) {
|
|
apiAbort({ "OK": false, "ERROR": "grant_exists", "MESSAGE": "An active or pending grant already exists for this service point and guest business." });
|
|
}
|
|
|
|
// Validate enum values
|
|
validEconomics = ["none", "flat_fee", "percent_of_orders"];
|
|
validEligibility = ["public", "employees", "guests", "internal"];
|
|
validTimePolicy = ["always", "schedule", "date_range", "event"];
|
|
|
|
if (!arrayFind(validEconomics, economicsType)) economicsType = "none";
|
|
if (!arrayFind(validEligibility, eligibilityScope)) eligibilityScope = "public";
|
|
if (!arrayFind(validTimePolicy, timePolicyType)) timePolicyType = "always";
|
|
|
|
// Generate UUID and InviteToken
|
|
newUUID = createObject("java", "java.util.UUID").randomUUID().toString();
|
|
inviteToken = lcase(hash(generateSecretKey("AES", 256), "SHA-256"));
|
|
|
|
// Serialize TimePolicyData
|
|
timePolicyJson = javaCast("null", "");
|
|
if (isStruct(timePolicyData) && !structIsEmpty(timePolicyData)) {
|
|
timePolicyJson = serializeJSON(timePolicyData);
|
|
} else if (isSimpleValue(timePolicyData) && len(trim(timePolicyData))) {
|
|
timePolicyJson = timePolicyData;
|
|
}
|
|
|
|
// Insert grant
|
|
queryTimed(
|
|
"INSERT INTO ServicePointGrants
|
|
(UUID, OwnerBusinessID, GuestBusinessID, ServicePointID, StatusID,
|
|
EconomicsType, EconomicsValue, EligibilityScope, TimePolicyType, TimePolicyData,
|
|
InviteToken, CreatedByUserID)
|
|
VALUES (?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?, ?)",
|
|
[
|
|
{ value = newUUID, cfsqltype = "cf_sql_varchar" },
|
|
{ value = ownerBusinessID, cfsqltype = "cf_sql_integer" },
|
|
{ value = guestBusinessID, cfsqltype = "cf_sql_integer" },
|
|
{ value = servicePointID, cfsqltype = "cf_sql_integer" },
|
|
{ value = economicsType, cfsqltype = "cf_sql_varchar" },
|
|
{ value = economicsValue, cfsqltype = "cf_sql_decimal" },
|
|
{ value = eligibilityScope, cfsqltype = "cf_sql_varchar" },
|
|
{ value = timePolicyType, cfsqltype = "cf_sql_varchar" },
|
|
{ value = timePolicyJson, cfsqltype = "cf_sql_varchar", null = isNull(timePolicyJson) },
|
|
{ value = inviteToken, cfsqltype = "cf_sql_varchar" },
|
|
{ value = callerUserID, cfsqltype = "cf_sql_integer" }
|
|
],
|
|
{ datasource = "payfrit" }
|
|
);
|
|
|
|
// Get the inserted grant ID
|
|
qNew = queryTimed(
|
|
"SELECT ID FROM ServicePointGrants WHERE UUID = ? LIMIT 1",
|
|
[{ value = newUUID, cfsqltype = "cf_sql_varchar" }],
|
|
{ datasource = "payfrit" }
|
|
);
|
|
grantID = qNew.ID;
|
|
|
|
// Record history
|
|
recordGrantHistory(
|
|
grantID = grantID,
|
|
action = "created",
|
|
actorUserID = callerUserID,
|
|
actorBusinessID = ownerBusinessID,
|
|
newData = {
|
|
"OwnerBusinessID": ownerBusinessID,
|
|
"GuestBusinessID": guestBusinessID,
|
|
"ServicePointID": servicePointID,
|
|
"EconomicsType": economicsType,
|
|
"EconomicsValue": economicsValue,
|
|
"EligibilityScope": eligibilityScope,
|
|
"TimePolicyType": timePolicyType
|
|
}
|
|
);
|
|
|
|
writeOutput(serializeJSON({
|
|
"OK": true,
|
|
"GrantID": grantID,
|
|
"UUID": newUUID,
|
|
"InviteToken": inviteToken,
|
|
"StatusID": 0,
|
|
"MESSAGE": "Grant created. Awaiting guest acceptance."
|
|
}));
|
|
</cfscript>
|