diff --git a/packages/core/src/services/documentLogs/computeDocumentLogsWithMetadata.ts b/packages/core/src/services/documentLogs/computeDocumentLogsWithMetadata.ts index 29410d5bd..356750a86 100644 --- a/packages/core/src/services/documentLogs/computeDocumentLogsWithMetadata.ts +++ b/packages/core/src/services/documentLogs/computeDocumentLogsWithMetadata.ts @@ -1,11 +1,29 @@ -import { and, desc, eq } from 'drizzle-orm' +import { and, desc, eq, sum } from 'drizzle-orm' import { Commit } from '../../browser' import { database } from '../../client' import { - createDocumentLogQuery, - getCommitFilter, -} from './_createDocumentLogQuery' + DocumentLogsWithErrorsRepository, + DocumentLogWithErrorScope, +} from '../../repositories' +import { commits, providerLogs } from '../../schema' +import { getCommitFilter } from './_createDocumentLogQuery' + +function getRepositoryScopes(workspaceId: number, db = database) { + const documentLogsScope = new DocumentLogsWithErrorsRepository( + workspaceId, + db, + ).scope + return { documentLogsScope } +} + +function getCommonQueryConditions( + scope: DocumentLogWithErrorScope, + documentUuid: string, + draft?: Commit, +) { + return and(eq(scope.documentUuid, documentUuid), getCommitFilter(draft)) +} // TODO: Add test document log without provider should appear here export function computeDocumentLogsWithMetadataQuery( @@ -13,15 +31,69 @@ export function computeDocumentLogsWithMetadataQuery( workspaceId, documentUuid, draft, + page = '1', + pageSize = '25', }: { workspaceId: number documentUuid: string draft?: Commit + page?: string + pageSize?: string }, db = database, ) { - const { scope, baseQuery } = createDocumentLogQuery(workspaceId, db) - return baseQuery - .where(and(eq(scope.documentUuid, documentUuid), getCommitFilter(draft))) - .orderBy(desc(scope.createdAt)) + const { documentLogsScope } = getRepositoryScopes(workspaceId, db) + const offset = (parseInt(page) - 1) * parseInt(pageSize) + const filteredSubQuery = db + .select({ + id: documentLogsScope.id, + tokens: sum(providerLogs.tokens).mapWith(Number).as('tokens'), + duration: sum(providerLogs.duration).mapWith(Number).as('duration_in_ms'), + costInMillicents: sum(providerLogs.costInMillicents) + .mapWith(Number) + .as('cost_in_millicents'), + }) + .from(documentLogsScope) + .leftJoin( + providerLogs, + eq(providerLogs.documentLogUuid, documentLogsScope.uuid), + ) + .where(getCommonQueryConditions(documentLogsScope, documentUuid, draft)) + .orderBy(desc(documentLogsScope.createdAt)) + .limit(parseInt(pageSize)) + .offset(offset) + .as('filteredDocumentLogsSubQuery') + + const aggregatedFieldsSubQuery = db + .select({ + id: documentLogsScope.id, + tokens: sum(providerLogs.tokens).mapWith(Number).as('tokens'), + duration: sum(providerLogs.duration).mapWith(Number).as('duration_in_ms'), + costInMillicents: sum(providerLogs.costInMillicents) + .mapWith(Number) + .as('cost_in_millicents'), + }) + .from(documentLogsScope) + .innerJoin(filteredSubQuery, eq(filteredSubQuery.id, documentLogsScope.id)) + .leftJoin( + providerLogs, + eq(providerLogs.documentLogUuid, documentLogsScope.uuid), + ) + .groupBy(documentLogsScope.id) + .as('aggregatedFieldsSubQuery') + + return db + .select({ + ...documentLogsScope._.selectedFields, + commit: commits, + tokens: aggregatedFieldsSubQuery.tokens, + duration: aggregatedFieldsSubQuery.duration, + costInMillicents: aggregatedFieldsSubQuery.costInMillicents, + }) + .from(documentLogsScope) + .innerJoin(commits, eq(commits.id, documentLogsScope.commitId)) + .innerJoin( + aggregatedFieldsSubQuery, + eq(aggregatedFieldsSubQuery.id, documentLogsScope.id), + ) }