feat(cc-050): add AiRequests controller (list + costs)
This commit is contained in:
parent
dccd0bbffa
commit
ddb39df95f
1 changed files with 75 additions and 0 deletions
75
src/ai-requests/ai-requests.controller.ts
Normal file
75
src/ai-requests/ai-requests.controller.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { Controller, Get, Query } from '@nestjs/common';
|
||||
import { desc, eq, sum, count } from 'drizzle-orm';
|
||||
import { CurrentSession } from '../auth/session.decorator';
|
||||
import type { AuthenticatedSession } from '../auth/tenant.guard';
|
||||
import { db } from '../db/client';
|
||||
import { aiRequests } from '../db/schema';
|
||||
|
||||
@Controller('ai-requests')
|
||||
export class AiRequestsController {
|
||||
@Get()
|
||||
async list(
|
||||
@CurrentSession() session: AuthenticatedSession,
|
||||
@Query('limit') limitStr?: string,
|
||||
) {
|
||||
const limit = Math.min(Math.max(1, parseInt(limitStr ?? '200', 10) || 200), 500);
|
||||
return db.query.aiRequests.findMany({
|
||||
where: eq(aiRequests.tenantId, session.tenantId),
|
||||
orderBy: desc(aiRequests.createdAt),
|
||||
limit,
|
||||
columns: {
|
||||
contextManifest: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@Get('costs')
|
||||
async costs(@CurrentSession() session: AuthenticatedSession) {
|
||||
const [totals] = await db
|
||||
.select({
|
||||
totalCostUsd: sum(aiRequests.costUsd),
|
||||
totalRequests: count(),
|
||||
})
|
||||
.from(aiRequests)
|
||||
.where(eq(aiRequests.tenantId, session.tenantId));
|
||||
|
||||
const byModel = await db
|
||||
.select({
|
||||
model: aiRequests.model,
|
||||
requests: count(),
|
||||
costUsd: sum(aiRequests.costUsd),
|
||||
})
|
||||
.from(aiRequests)
|
||||
.where(eq(aiRequests.tenantId, session.tenantId))
|
||||
.groupBy(aiRequests.model);
|
||||
|
||||
const byPurpose = await db
|
||||
.select({
|
||||
purpose: aiRequests.purpose,
|
||||
requests: count(),
|
||||
costUsd: sum(aiRequests.costUsd),
|
||||
})
|
||||
.from(aiRequests)
|
||||
.where(eq(aiRequests.tenantId, session.tenantId))
|
||||
.groupBy(aiRequests.purpose);
|
||||
|
||||
const byStatus = await db
|
||||
.select({
|
||||
resultStatus: aiRequests.resultStatus,
|
||||
requests: count(),
|
||||
})
|
||||
.from(aiRequests)
|
||||
.where(eq(aiRequests.tenantId, session.tenantId))
|
||||
.groupBy(aiRequests.resultStatus);
|
||||
|
||||
return {
|
||||
totals: {
|
||||
totalCostUsd: totals?.totalCostUsd ?? '0',
|
||||
totalRequests: totals?.totalRequests ?? 0,
|
||||
},
|
||||
byModel,
|
||||
byPurpose,
|
||||
byStatus,
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue