import type { OpenCodeUsageDailyAggregate, OpenCodeUsagePersistedState } from './types' import { OPENCODE_USAGE_SCHEMA_VERSION } from './opencode-usage-provider' const SCHEMA_VERSION = OPENCODE_USAGE_SCHEMA_VERSION export function getDefaultState(): OpenCodeUsagePersistedState { return { schemaVersion: SCHEMA_VERSION, worktreeFingerprint: null, processedDatabases: [], sessions: [], dailyAggregates: [], scanState: { enabled: false, lastScanStartedAt: null, lastScanCompletedAt: null, lastScanError: null } } } export function normalizePersistedState( state: OpenCodeUsagePersistedState ): OpenCodeUsagePersistedState { if (state.schemaVersion !== SCHEMA_VERSION) { const defaults = getDefaultState() return { ...defaults, scanState: { ...defaults.scanState, enabled: state.scanState?.enabled ?? false } } } return { ...state, processedDatabases: (state.processedDatabases ?? []).map((database) => ({ ...database, sessions: (database.sessions ?? []).map(normalizeSessionCost), dailyAggregates: (database.dailyAggregates ?? []).map(normalizeDailyAggregateCost) })), sessions: state.sessions.map(normalizeSessionCost), dailyAggregates: state.dailyAggregates.map(normalizeDailyAggregateCost) } } function normalizeDailyAggregateCost( entry: OpenCodeUsageDailyAggregate ): OpenCodeUsageDailyAggregate { return { ...entry, estimatedCostUsd: entry.estimatedCostUsd ?? null } } function normalizeSessionCost( session: OpenCodeUsagePersistedState['sessions'][number] ): OpenCodeUsagePersistedState['sessions'][number] { return { ...session, estimatedCostUsd: session.estimatedCostUsd ?? null, locationBreakdown: (session.locationBreakdown ?? []).map((entry) => ({ ...entry, estimatedCostUsd: entry.estimatedCostUsd ?? null })), modelBreakdown: (session.modelBreakdown ?? []).map((entry) => ({ ...entry, estimatedCostUsd: entry.estimatedCostUsd ?? null })), locationModelBreakdown: (session.locationModelBreakdown ?? []).map((entry) => ({ ...entry, estimatedCostUsd: entry.estimatedCostUsd ?? null })) } }