/** * Worker Tier + Activation Status * Returns cached DB state. No Stripe polling. * Tier is derived: payoutsEnabled ? 1 : 0 */ response = { "OK": false }; try { requestData = deserializeJSON(toString(getHttpRequestData().content)); userID = val(requestData.UserID ?: 0); // Fallback to auth header if (userID == 0 && structKeyExists(request, "UserID")) { userID = val(request.UserID); } if (userID == 0) { response["ERROR"] = "missing_params"; response["MESSAGE"] = "UserID is required."; writeOutput(serializeJSON(response)); abort; } qUser = queryTimed(" SELECT StripeConnectedAccountID, StripePayoutsEnabled, ActivationBalanceCents, ActivationCapCents FROM Users WHERE ID = :userID ", { userID: userID }, { datasource: "payfrit" }); if (qUser.recordCount == 0) { response["ERROR"] = "user_not_found"; writeOutput(serializeJSON(response)); abort; } payoutsEnabled = qUser.StripePayoutsEnabled == 1; hasAccount = len(trim(qUser.StripeConnectedAccountID ?: "")) > 0; balanceCents = val(qUser.ActivationBalanceCents); capCents = val(qUser.ActivationCapCents); remainingCents = capCents - balanceCents; if (remainingCents < 0) remainingCents = 0; isComplete = (remainingCents == 0); progressPercent = capCents > 0 ? round((balanceCents / capCents) * 100) : 100; if (progressPercent > 100) progressPercent = 100; response["OK"] = true; response["TIER"] = payoutsEnabled ? 1 : 0; response["STRIPE"] = { "HasAccount": hasAccount, "PayoutsEnabled": payoutsEnabled, "SetupIncomplete": hasAccount && !payoutsEnabled }; response["ACTIVATION"] = { "BalanceCents": balanceCents, "CapCents": capCents, "RemainingCents": remainingCents, "IsComplete": isComplete, "ProgressPercent": progressPercent }; } catch (any e) { response["ERROR"] = e.message; } writeOutput(serializeJSON(response));