fix(billTeam): update cached ACUC after billing

This commit is contained in:
Gergő Móricz 2024-09-25 21:37:01 +02:00
parent f22ab5ffaf
commit 84bff8add8
3 changed files with 24 additions and 5 deletions

View File

@ -37,7 +37,7 @@ function normalizedApiIsUuid(potentialUuid: string): boolean {
return validate(potentialUuid);
}
async function setCachedACUC(api_key: string, acuc: AuthCreditUsageChunk) {
export async function setCachedACUC(api_key: string, acuc: AuthCreditUsageChunk) {
const cacheKeyACUC = `acuc_${api_key}`;
const redLockKey = `lock_${cacheKeyACUC}`;
const lockTTL = 10000; // 10 seconds
@ -58,14 +58,14 @@ async function setCachedACUC(api_key: string, acuc: AuthCreditUsageChunk) {
}
}
async function getACUC(api_key: string): Promise<AuthCreditUsageChunk | null> {
export async function getACUC(api_key: string, cacheOnly = false): Promise<AuthCreditUsageChunk | null> {
const cacheKeyACUC = `acuc_${api_key}`;
const cachedACUC = await getValue(cacheKeyACUC);
if (cachedACUC !== null) {
return JSON.parse(cachedACUC);
} else {
} else if (!cacheOnly) {
const { data, error } =
await supabase_service.rpc("auth_credit_usage_chunk", { input_key: api_key });
@ -85,6 +85,8 @@ async function getACUC(api_key: string): Promise<AuthCreditUsageChunk | null> {
}
return chunk;
} else {
return null;
}
}

View File

@ -324,7 +324,7 @@ export type AuthCreditUsageChunk = {
price_id: string | null;
price_credits: number; // credit limit with assoicated price, or free_credits (500) if free plan
credits_used: number;
coupon_credits: number;
coupon_credits: number; // do not rely on this number to be up to date after calling a billTeam
coupons: any[];
adjusted_credits_used: number; // credits this period minus coupons used
remaining_credits: number;

View File

@ -5,6 +5,7 @@ import { supabase_service } from "../supabase";
import { Logger } from "../../lib/logger";
import * as Sentry from "@sentry/node";
import { AuthCreditUsageChunk } from "../../controllers/v1/types";
import { getACUC, setCachedACUC } from "../../controllers/auth";
const FREE_CREDITS = 500;
@ -20,13 +21,29 @@ export async function supaBillTeam(team_id: string, subscription_id: string, cre
}
Logger.info(`Billing team ${team_id} for ${credits} credits`);
const { error } =
const { data, error } =
await supabase_service.rpc("bill_team", { _team_id: team_id, sub_id: subscription_id ?? null, fetch_subscription: subscription_id === undefined, credits });
if (error) {
Sentry.captureException(error);
Logger.error("Failed to bill team: " + JSON.stringify(error));
return;
}
(async () => {
for (const apiKey of (data ?? []).map(x => x.api_key)) {
const acuc = await getACUC(apiKey, true);
if (acuc !== null) {
await setCachedACUC(apiKey, {
...acuc,
credits_used: acuc.credits_used + credits,
adjusted_credits_used: acuc.adjusted_credits_used + credits,
remaining_credits: acuc.remaining_credits - credits,
});
}
}
})();
}
export async function checkTeamCredits(chunk: AuthCreditUsageChunk, team_id: string, credits: number) {