Files
CC-Switch/src/lib/api/usage.ts
T
Jason eff1e0ccfc feat(db): rebuild Codex usage on upgrade and via maintenance action
Schema v16 wipes codex_session detail rows, _codex_session rollups and
Codex rollout cursors inside the migration savepoint (cursor deletion
uses pure shape matching so CODEX_HOME drift cannot orphan cursors);
the next session sync re-imports history from source JSONL under the
corrected importer. Fresh installs traverse the same branch as a no-op.

Add a manual "Rebuild Codex usage" maintenance action (single-flight,
hard-fail backup before reset, unconditional refresh notification even
when reimport is empty or fails after reset) with a destructive confirm
dialog, result toast and four-locale strings. Historical proxy-side
duplicate rows are intentionally left untouched; history whose source
JSONL was already deleted cannot be reconstructed.
2026-07-21 16:39:34 +08:00

191 lines
4.1 KiB
TypeScript

import { invoke } from "@tauri-apps/api/core";
import type {
UsageSummary,
UsageSummaryByApp,
DailyStats,
ProviderStats,
ModelStats,
RequestLog,
LogFilters,
ModelPricing,
ProviderLimitStatus,
PaginatedLogs,
SessionSyncResult,
DataSourceSummary,
} from "@/types/usage";
import type { UsageResult } from "@/types";
import type { AppId } from "./types";
import type { TemplateType } from "@/config/constants";
export const usageApi = {
// Provider usage script methods
query: async (providerId: string, appId: AppId): Promise<UsageResult> => {
return invoke("queryProviderUsage", { providerId, app: appId });
},
testScript: async (
providerId: string,
appId: AppId,
scriptCode: string,
timeout?: number,
apiKey?: string,
baseUrl?: string,
accessToken?: string,
userId?: string,
templateType?: TemplateType,
): Promise<UsageResult> => {
return invoke("testUsageScript", {
providerId,
app: appId,
scriptCode,
timeout,
apiKey,
baseUrl,
accessToken,
userId,
templateType,
});
},
// Proxy usage statistics methods
getUsageSummary: async (
startDate?: number,
endDate?: number,
appType?: string,
providerName?: string,
model?: string,
): Promise<UsageSummary> => {
return invoke("get_usage_summary", {
startDate,
endDate,
appType,
providerName,
model,
});
},
getUsageSummaryByApp: async (
startDate?: number,
endDate?: number,
providerName?: string,
model?: string,
): Promise<UsageSummaryByApp[]> => {
return invoke("get_usage_summary_by_app", {
startDate,
endDate,
providerName,
model,
});
},
getUsageTrends: async (
startDate?: number,
endDate?: number,
appType?: string,
providerName?: string,
model?: string,
): Promise<DailyStats[]> => {
return invoke("get_usage_trends", {
startDate,
endDate,
appType,
providerName,
model,
});
},
getProviderStats: async (
startDate?: number,
endDate?: number,
appType?: string,
providerName?: string,
model?: string,
): Promise<ProviderStats[]> => {
return invoke("get_provider_stats", {
startDate,
endDate,
appType,
providerName,
model,
});
},
getModelStats: async (
startDate?: number,
endDate?: number,
appType?: string,
providerName?: string,
model?: string,
): Promise<ModelStats[]> => {
return invoke("get_model_stats", {
startDate,
endDate,
appType,
providerName,
model,
});
},
getRequestLogs: async (
filters: LogFilters,
page: number = 0,
pageSize: number = 20,
): Promise<PaginatedLogs> => {
return invoke("get_request_logs", {
filters,
page,
pageSize,
});
},
getRequestDetail: async (requestId: string): Promise<RequestLog | null> => {
return invoke("get_request_detail", { requestId });
},
getModelPricing: async (): Promise<ModelPricing[]> => {
return invoke("get_model_pricing");
},
updateModelPricing: async (
modelId: string,
displayName: string,
inputCost: string,
outputCost: string,
cacheReadCost: string,
cacheCreationCost: string,
): Promise<void> => {
return invoke("update_model_pricing", {
modelId,
displayName,
inputCost,
outputCost,
cacheReadCost,
cacheCreationCost,
});
},
deleteModelPricing: async (modelId: string): Promise<void> => {
return invoke("delete_model_pricing", { modelId });
},
checkProviderLimits: async (
providerId: string,
appType: string,
): Promise<ProviderLimitStatus> => {
return invoke("check_provider_limits", { providerId, appType });
},
// Session usage sync
syncSessionUsage: async (): Promise<SessionSyncResult> => {
return invoke("sync_session_usage");
},
rebuildCodexUsage: async (): Promise<SessionSyncResult> => {
return invoke("rebuild_codex_usage");
},
getDataSourceBreakdown: async (): Promise<DataSourceSummary[]> => {
return invoke("get_usage_data_sources");
},
};