75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
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,
|
|
};
|
|
}
|
|
}
|