Skip to content

Commit 724b706

Browse files
authored
feat: remove all credit usage logging (#5428)
* chore: remove `unneeded` fields from `checkAndDeductOrganizationCredits` call * feat: remove all credit `usage` logging * chore: delete unnecessary `transactions` and drop `credit_transactions`
1 parent c342790 commit 724b706

File tree

9 files changed

+10
-166
lines changed

9 files changed

+10
-166
lines changed

apps/frontend/app/api/v1/chat/completions/route.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ export const POST = withPostHogTracking(async (req: NextRequest) => {
4646
orgId,
4747
TransactionType.AGENT_QUERY,
4848
tracker,
49-
"/api/v1/chat/completions",
50-
{ message: getLatestMessage(body.messages) },
5149
);
5250
} catch (error) {
5351
if (error instanceof InsufficientCreditsError) {

apps/frontend/app/api/v1/chat/route.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ export const POST = withPostHogTracking(async (req: NextRequest) => {
6262
org.id,
6363
TransactionType.CHAT_QUERY,
6464
tracker,
65-
"/api/v1/chat",
66-
{ message: getLatestMessage(prompt.messages) },
6765
);
6866
} catch (error) {
6967
if (error instanceof InsufficientCreditsError) {

apps/frontend/app/api/v1/graphql/route.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -140,21 +140,11 @@ const customHandler = async (req: NextRequest) => {
140140
const requestClone = req.clone();
141141
const tracker = trackServerEvent(user);
142142

143-
let operation = "unknown";
144143
let query = "";
145144

146145
try {
147146
const body = await requestClone.json();
148147
query = body.query || "";
149-
150-
// TODO(jabolo): Use a real parser to extract operation type and name
151-
if (query.includes("query")) {
152-
operation = "query";
153-
} else if (query.includes("mutation")) {
154-
operation = "mutation";
155-
} else if (query.includes("subscription")) {
156-
operation = "subscription";
157-
}
158148
} catch (error) {
159149
logger.error("Error parsing GraphQL request body:", error);
160150
}
@@ -179,8 +169,6 @@ const customHandler = async (req: NextRequest) => {
179169
user.orgId,
180170
TransactionType.GRAPHQL_QUERY,
181171
tracker,
182-
"/api/v1/graphql",
183-
{ operation, query },
184172
);
185173
} catch (error) {
186174
if (error instanceof InsufficientCreditsError) {

apps/frontend/app/api/v1/responses/route.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ export const POST = withPostHogTracking(async (req: NextRequest) => {
4646
orgId,
4747
TransactionType.AGENT_QUERY,
4848
tracker,
49-
"/api/v1/chat/responses",
50-
{ message: getLatestMessage(body.messages) },
5149
);
5250
} catch (error) {
5351
if (error instanceof InsufficientCreditsError) {

apps/frontend/app/api/v1/sql/route.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ export const POST = withPostHogTracking(async (request: NextRequest) => {
114114
user.orgId,
115115
TransactionType.SQL_QUERY,
116116
tracker,
117-
"/api/v1/sql",
118-
{ query },
119117
);
120118
} catch (error) {
121119
if (error instanceof InsufficientCreditsError) {

apps/frontend/app/api/v1/text2sql/route.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ export const POST = withPostHogTracking(async (req: NextRequest) => {
4646
orgId,
4747
TransactionType.TEXT2SQL,
4848
tracker,
49-
"/api/v1/text2sql",
50-
{ message: getLatestMessage(prompt.messages) },
5149
);
5250
} catch (error) {
5351
if (error instanceof InsufficientCreditsError) {

apps/frontend/lib/services/credits.test.ts

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ describe("CreditsService", () => {
165165
TEST_ORG_ID,
166166
TransactionType.AGENT_QUERY,
167167
mockTracker,
168-
"/api/test",
169168
);
170169

171170
expect(result).toBeDefined();
@@ -178,18 +177,6 @@ describe("CreditsService", () => {
178177
.single();
179178

180179
expect(credits?.credits_balance).toBe(100 - FREE_PLAN_COST);
181-
182-
const { data: transactions } = await adminSupabase
183-
.from("organization_credit_transactions")
184-
.select("*")
185-
.eq("org_id", TEST_ORG_ID)
186-
.order("created_at", { ascending: false })
187-
.limit(1);
188-
189-
expect(transactions?.[0]?.amount).toBe(-FREE_PLAN_COST);
190-
expect(transactions?.[0]?.transaction_type).toBe(
191-
TransactionType.AGENT_QUERY,
192-
);
193180
});
194181

195182
it("should throw InsufficientCreditsError when balance too low", async () => {
@@ -215,56 +202,12 @@ describe("CreditsService", () => {
215202
TEST_ORG_ID,
216203
TransactionType.AGENT_QUERY,
217204
mockTracker,
218-
"/api/test",
219205
),
220206
).rejects.toThrow(InsufficientCreditsError);
221207

222208
expect(mockTracker.track).toHaveBeenCalled();
223209
});
224210

225-
it("should log failed transaction when insufficient credits", async () => {
226-
await adminSupabase
227-
.from("organization_credits")
228-
.update({ credits_balance: 0 })
229-
.eq("org_id", TEST_ORG_ID);
230-
231-
const user: OrgUser = {
232-
userId: TEST_USER_ID,
233-
role: "user",
234-
orgId: TEST_ORG_ID,
235-
orgName: "test",
236-
orgRole: "admin",
237-
name: "Test User",
238-
keyName: "test-key",
239-
host: null,
240-
};
241-
242-
try {
243-
await CreditsService.checkAndDeductOrganizationCredits(
244-
user,
245-
TEST_ORG_ID,
246-
TransactionType.AGENT_QUERY,
247-
mockTracker,
248-
"/api/test",
249-
);
250-
} catch (err) {
251-
void err;
252-
}
253-
254-
const { data: transactions } = await adminSupabase
255-
.from("organization_credit_transactions")
256-
.select("*")
257-
.eq("org_id", TEST_ORG_ID)
258-
.order("created_at", { ascending: false })
259-
.limit(1);
260-
261-
expect(transactions).toHaveLength(1);
262-
expect(transactions?.[0]?.amount).toBeLessThan(0);
263-
expect(transactions?.[0]?.transaction_type).toBe(
264-
TransactionType.AGENT_QUERY,
265-
);
266-
});
267-
268211
it("should return null for anonymous users", async () => {
269212
const anonUser: OrgUser = { role: "anonymous" as const, host: null };
270213

@@ -273,7 +216,6 @@ describe("CreditsService", () => {
273216
TEST_ORG_ID,
274217
TransactionType.AGENT_QUERY,
275218
mockTracker,
276-
"/api/test",
277219
);
278220

279221
expect(result).toBeNull();
@@ -309,7 +251,6 @@ describe("CreditsService", () => {
309251
TEST_ORG_ID,
310252
TransactionType.AGENT_QUERY,
311253
mockTracker,
312-
"/api/test",
313254
);
314255

315256
const { data: credits } = await adminSupabase
@@ -367,7 +308,6 @@ describe("CreditsService", () => {
367308
TEST_ORG_ID,
368309
TransactionType.AGENT_QUERY,
369310
mockTracker,
370-
"/api/test",
371311
);
372312

373313
const { data: credits } = await adminSupabase

apps/frontend/lib/services/credits.ts

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -88,53 +88,11 @@ export class InsufficientCreditsError extends Error {
8888
}
8989
}
9090

91-
interface TransactionLogParams {
92-
orgId: string;
93-
userId: string;
94-
amount: number;
95-
transactionType: TransactionType;
96-
apiEndpoint?: string;
97-
metadata?: Record<string, any>;
98-
error?: {
99-
type: "insufficient_credits" | "transaction_failed";
100-
details?: Record<string, any>;
101-
};
102-
}
103-
10491
export class CreditsService {
10592
static isAnonymousUser(user: OrgUser | User): user is AnonUser {
10693
return user.role === "anonymous";
10794
}
10895

109-
private static async logTransaction(
110-
client: SupabaseClient,
111-
params: TransactionLogParams,
112-
): Promise<void> {
113-
const {
114-
orgId,
115-
userId,
116-
amount,
117-
transactionType,
118-
apiEndpoint,
119-
metadata,
120-
error,
121-
} = params;
122-
123-
const finalMetadata = error
124-
? { error: error.type, ...error.details, ...metadata }
125-
: metadata;
126-
127-
await client.from("organization_credit_transactions").insert({
128-
org_id: orgId,
129-
user_id: userId,
130-
amount,
131-
transaction_type: transactionType,
132-
api_endpoint: apiEndpoint,
133-
metadata: finalMetadata,
134-
created_at: new Date().toISOString(),
135-
});
136-
}
137-
13896
private static async validateUserAccess(
13997
client: SupabaseClient,
14098
actingUserId: string,
@@ -454,8 +412,6 @@ export class CreditsService {
454412
orgId: string,
455413
transactionType: TransactionType,
456414
tracker: PostHogTracker,
457-
apiEndpoint?: string,
458-
metadata?: Record<string, any>,
459415
): Promise<OrganizationPlan | null> {
460416
if (CreditsService.isAnonymousUser(user)) {
461417
return null;
@@ -482,22 +438,6 @@ export class CreditsService {
482438
);
483439

484440
if (!deductionResult.success) {
485-
await CreditsService.logTransaction(client, {
486-
orgId,
487-
userId: user.userId,
488-
amount: -costPerCall,
489-
transactionType,
490-
apiEndpoint,
491-
metadata,
492-
error: {
493-
type: "insufficient_credits",
494-
details: {
495-
attempted_amount: costPerCall,
496-
current_balance: deductionResult.currentBalance,
497-
},
498-
},
499-
});
500-
501441
await CreditsService.handleInsufficientCredits(
502442
client,
503443
orgId,
@@ -506,32 +446,8 @@ export class CreditsService {
506446
);
507447
}
508448

509-
await CreditsService.logTransaction(client, {
510-
orgId,
511-
userId: user.userId,
512-
amount: -costPerCall,
513-
transactionType,
514-
apiEndpoint,
515-
metadata,
516-
});
517-
518449
return orgPlan;
519450
} catch (error) {
520-
await CreditsService.logTransaction(client, {
521-
orgId,
522-
userId: user.userId,
523-
amount: -costPerCall,
524-
transactionType,
525-
apiEndpoint,
526-
metadata,
527-
error: {
528-
type: "transaction_failed",
529-
details: {
530-
sql_error: error instanceof Error ? error.message : String(error),
531-
},
532-
},
533-
});
534-
535451
logger.error("Exception in checkAndDeductOrganizationCredits:", error);
536452
throw error;
537453
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
DROP TABLE IF EXISTS public.credit_transactions CASCADE;
2+
3+
DELETE FROM public.organization_credit_transactions
4+
WHERE transaction_type IN (
5+
'sql_query',
6+
'graphql_query',
7+
'chat_query',
8+
'text2sql',
9+
'agent_query'
10+
);

0 commit comments

Comments
 (0)