enforce windowed usage cap in V2 deduction lua
This commit is contained in:
@@ -18,29 +18,61 @@ local function read_subject_balances(params)
|
||||
local balances_by_id = {}
|
||||
local missing_customer_entitlement_ids = {}
|
||||
local entries_by_balance_key = {}
|
||||
local seen_ids_by_balance_key = {}
|
||||
-- Anchor-only cus_ents (usage-window owners not in the deduction set) must
|
||||
-- not abort the deduction when absent; a missing anchor fails closed later.
|
||||
local anchor_only_ids = {}
|
||||
local balance_keys_by_feature_id = safe_table(params.balance_keys_by_feature_id)
|
||||
|
||||
local function queue_balance_read(customer_entitlement_id, feature_id)
|
||||
if not (customer_entitlement_id and feature_id) then
|
||||
return false
|
||||
end
|
||||
|
||||
local balance_key = balance_keys_by_feature_id[feature_id]
|
||||
if not balance_key then
|
||||
return false
|
||||
end
|
||||
|
||||
if entries_by_balance_key[balance_key] == nil then
|
||||
entries_by_balance_key[balance_key] = {
|
||||
feature_id = feature_id,
|
||||
customer_entitlement_ids = {},
|
||||
}
|
||||
seen_ids_by_balance_key[balance_key] = {}
|
||||
end
|
||||
|
||||
if seen_ids_by_balance_key[balance_key][customer_entitlement_id] then
|
||||
return true
|
||||
end
|
||||
seen_ids_by_balance_key[balance_key][customer_entitlement_id] = true
|
||||
|
||||
table.insert(
|
||||
entries_by_balance_key[balance_key].customer_entitlement_ids,
|
||||
customer_entitlement_id
|
||||
)
|
||||
return true
|
||||
end
|
||||
|
||||
local deduction_ids = {}
|
||||
for _, ent_obj in ipairs(params.customer_entitlement_deductions or {}) do
|
||||
local customer_entitlement_id = ent_obj.customer_entitlement_id
|
||||
local feature_id = ent_obj.feature_id
|
||||
|
||||
if customer_entitlement_id and feature_id then
|
||||
local balance_key = balance_keys_by_feature_id[feature_id]
|
||||
if not balance_key then
|
||||
if customer_entitlement_id then
|
||||
local queued = queue_balance_read(customer_entitlement_id, ent_obj.feature_id)
|
||||
if not queued then
|
||||
table.insert(missing_customer_entitlement_ids, customer_entitlement_id)
|
||||
else
|
||||
if entries_by_balance_key[balance_key] == nil then
|
||||
entries_by_balance_key[balance_key] = {
|
||||
feature_id = feature_id,
|
||||
customer_entitlement_ids = {},
|
||||
}
|
||||
end
|
||||
|
||||
table.insert(
|
||||
entries_by_balance_key[balance_key].customer_entitlement_ids,
|
||||
customer_entitlement_id
|
||||
)
|
||||
end
|
||||
deduction_ids[customer_entitlement_id] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- A deduction target must never be marked anchor_only, or a cache miss on it is
|
||||
-- swallowed instead of surfacing as missing + triggering the Postgres fallback.
|
||||
for _, anchor in ipairs(params.anchor_entitlements or {}) do
|
||||
local customer_entitlement_id = anchor.customer_entitlement_id
|
||||
if customer_entitlement_id and not deduction_ids[customer_entitlement_id] then
|
||||
anchor_only_ids[customer_entitlement_id] = true
|
||||
queue_balance_read(customer_entitlement_id, anchor.feature_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,16 +89,19 @@ local function read_subject_balances(params)
|
||||
local subject_balance = decode_subject_balance(raw_value)
|
||||
|
||||
if subject_balance == nil then
|
||||
table.insert(
|
||||
missing_customer_entitlement_ids,
|
||||
customer_entitlement_id
|
||||
)
|
||||
if not anchor_only_ids[customer_entitlement_id] then
|
||||
table.insert(
|
||||
missing_customer_entitlement_ids,
|
||||
customer_entitlement_id
|
||||
)
|
||||
end
|
||||
else
|
||||
balances_by_id[customer_entitlement_id] = {
|
||||
balance_key = balance_key,
|
||||
customer_entitlement_id = customer_entitlement_id,
|
||||
feature_id = entry.feature_id,
|
||||
subject_balance = subject_balance,
|
||||
anchor_only = anchor_only_ids[customer_entitlement_id] or nil,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user