| import { useQuery } from '@tanstack/react-query';
|
| import { useTranslation } from 'react-i18next';
|
| import { graphqlRequest } from '@/gql/graphql';
|
| import { useSelectedProjectId } from '@/stores/projectStore';
|
| import { useErrorHandler } from '@/hooks/use-error-handler';
|
| import { useUsageLogPermissions } from '../../../gql/useUsageLogPermissions';
|
| import { UsageLog, UsageLogConnection, usageLogConnectionSchema, usageLogSchema } from './schema';
|
|
|
|
|
| function buildUsageLogsQuery(permissions: { canViewChannels: boolean }) {
|
| const channelFields = permissions.canViewChannels
|
| ? `
|
| channel {
|
| id
|
| name
|
| type
|
| }`
|
| : '';
|
|
|
| return `
|
| query GetUsageLogs($first: Int, $after: Cursor, $orderBy: UsageLogOrder, $where: UsageLogWhereInput) {
|
| usageLogs(first: $first, after: $after, orderBy: $orderBy, where: $where) {
|
| edges {
|
| node {
|
| id
|
| createdAt
|
| updatedAt
|
| requestID${channelFields}
|
| modelID
|
| promptTokens
|
| completionTokens
|
| totalTokens
|
| promptAudioTokens
|
| promptCachedTokens
|
| promptWriteCachedTokens
|
| completionAudioTokens
|
| completionReasoningTokens
|
| completionAcceptedPredictionTokens
|
| completionRejectedPredictionTokens
|
| source
|
| format
|
| totalCost
|
| costItems {
|
| itemCode
|
| quantity
|
| subtotal
|
| }
|
| }
|
| cursor
|
| }
|
| pageInfo {
|
| hasNextPage
|
| hasPreviousPage
|
| startCursor
|
| endCursor
|
| }
|
| totalCount
|
| }
|
| }
|
| `;
|
| }
|
|
|
| function buildUsageLogDetailQuery(permissions: { canViewChannels: boolean }) {
|
| const channelFields = permissions.canViewChannels
|
| ? `
|
| channel {
|
| id
|
| name
|
| type
|
| }`
|
| : '';
|
|
|
| return `
|
| query GetUsageLog($id: ID!) {
|
| node(id: $id) {
|
| ... on UsageLog {
|
| id
|
| createdAt
|
| updatedAt
|
| requestID${channelFields}
|
| modelID
|
| promptTokens
|
| completionTokens
|
| totalTokens
|
| promptAudioTokens
|
| promptCachedTokens
|
| promptWriteCachedTokens
|
| completionAudioTokens
|
| completionReasoningTokens
|
| completionAcceptedPredictionTokens
|
| completionRejectedPredictionTokens
|
| source
|
| format
|
| totalCost
|
| costItems {
|
| itemCode
|
| quantity
|
| subtotal
|
| }
|
| }
|
| }
|
| }
|
| `;
|
| }
|
|
|
|
|
| export function useUsageLogs(variables?: {
|
| first?: number;
|
| after?: string;
|
| orderBy?: { field: 'CREATED_AT'; direction: 'ASC' | 'DESC' };
|
| where?: {
|
| source?: string;
|
| modelID?: string;
|
| channelID?: string;
|
| projectID?: string;
|
| [key: string]: any;
|
| };
|
| }) {
|
| const { handleError } = useErrorHandler();
|
| const { t } = useTranslation();
|
| const permissions = useUsageLogPermissions();
|
| const selectedProjectId = useSelectedProjectId();
|
|
|
| return useQuery({
|
| queryKey: ['usageLogs', variables, permissions, selectedProjectId],
|
| queryFn: async () => {
|
| try {
|
| const query = buildUsageLogsQuery(permissions);
|
| const headers = selectedProjectId ? { 'X-Project-ID': selectedProjectId } : undefined;
|
| const data = await graphqlRequest<{ usageLogs: UsageLogConnection }>(query, variables, headers);
|
| return usageLogConnectionSchema.parse(data?.usageLogs);
|
| } catch (error) {
|
| handleError(error, t('usageLogs.errors.loadUsageLogsFailed'));
|
| throw error;
|
| }
|
| },
|
| enabled: !!selectedProjectId,
|
| });
|
| }
|
|
|
| export function useUsageLog(id: string) {
|
| const { handleError } = useErrorHandler();
|
| const { t } = useTranslation();
|
| const permissions = useUsageLogPermissions();
|
| const selectedProjectId = useSelectedProjectId();
|
|
|
| return useQuery({
|
| queryKey: ['usageLog', id, permissions, selectedProjectId],
|
| queryFn: async () => {
|
| try {
|
| const query = buildUsageLogDetailQuery(permissions);
|
| const headers = selectedProjectId ? { 'X-Project-ID': selectedProjectId } : undefined;
|
| const data = await graphqlRequest<{ node: UsageLog }>(query, { id }, headers);
|
| if (!data.node) {
|
| throw new Error('Usage log not found');
|
| }
|
| return usageLogSchema.parse(data.node);
|
| } catch (error) {
|
| handleError(error, t('usageLogs.errors.loadUsageLogDetailFailed'));
|
| throw error;
|
| }
|
| },
|
| enabled: !!id,
|
| });
|
| }
|
|
|