mirror of
https://git.mirrors.martin98.com/https://github.com/mendableai/firecrawl
synced 2025-08-05 15:00:39 +08:00
fix(billTeam): update cached ACUC after billing
This commit is contained in:
parent
f22ab5ffaf
commit
84bff8add8
@ -37,7 +37,7 @@ function normalizedApiIsUuid(potentialUuid: string): boolean {
|
|||||||
return validate(potentialUuid);
|
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 cacheKeyACUC = `acuc_${api_key}`;
|
||||||
const redLockKey = `lock_${cacheKeyACUC}`;
|
const redLockKey = `lock_${cacheKeyACUC}`;
|
||||||
const lockTTL = 10000; // 10 seconds
|
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 cacheKeyACUC = `acuc_${api_key}`;
|
||||||
|
|
||||||
const cachedACUC = await getValue(cacheKeyACUC);
|
const cachedACUC = await getValue(cacheKeyACUC);
|
||||||
|
|
||||||
if (cachedACUC !== null) {
|
if (cachedACUC !== null) {
|
||||||
return JSON.parse(cachedACUC);
|
return JSON.parse(cachedACUC);
|
||||||
} else {
|
} else if (!cacheOnly) {
|
||||||
const { data, error } =
|
const { data, error } =
|
||||||
await supabase_service.rpc("auth_credit_usage_chunk", { input_key: api_key });
|
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;
|
return chunk;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ export type AuthCreditUsageChunk = {
|
|||||||
price_id: string | null;
|
price_id: string | null;
|
||||||
price_credits: number; // credit limit with assoicated price, or free_credits (500) if free plan
|
price_credits: number; // credit limit with assoicated price, or free_credits (500) if free plan
|
||||||
credits_used: number;
|
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[];
|
coupons: any[];
|
||||||
adjusted_credits_used: number; // credits this period minus coupons used
|
adjusted_credits_used: number; // credits this period minus coupons used
|
||||||
remaining_credits: number;
|
remaining_credits: number;
|
||||||
|
@ -5,6 +5,7 @@ import { supabase_service } from "../supabase";
|
|||||||
import { Logger } from "../../lib/logger";
|
import { Logger } from "../../lib/logger";
|
||||||
import * as Sentry from "@sentry/node";
|
import * as Sentry from "@sentry/node";
|
||||||
import { AuthCreditUsageChunk } from "../../controllers/v1/types";
|
import { AuthCreditUsageChunk } from "../../controllers/v1/types";
|
||||||
|
import { getACUC, setCachedACUC } from "../../controllers/auth";
|
||||||
|
|
||||||
const FREE_CREDITS = 500;
|
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`);
|
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 });
|
await supabase_service.rpc("bill_team", { _team_id: team_id, sub_id: subscription_id ?? null, fetch_subscription: subscription_id === undefined, credits });
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
Logger.error("Failed to bill team: " + JSON.stringify(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) {
|
export async function checkTeamCredits(chunk: AuthCreditUsageChunk, team_id: string, credits: number) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user