import { Tags } from '../tags'; import type { CostDateBasis } from './prices'; import type { CostComposition } from './costComposition.js'; export type BillingChargeSource = 'marketplace' | 'azure' | 'mixed' | 'unknown'; export type BillingCadence = 'daily' | 'monthly' | 'unknown'; /** Billing-source facts attached by the backend. This is not lifecycle evidence. */ export interface BillingChargeContext { source: BillingChargeSource; publisher?: string; product?: string; cadence?: BillingCadence; } /** Azure inventory lifecycle facts. An absent createdInPeriod means unknown. */ export interface ResourceLifecycleContext { createdAt?: string; createdInPeriod?: boolean; } export interface DecompositionTreeNode { [key: string]: unknown; id?: string; /** e.g., "Resource Group A", "Storage", "Standard Page Blob v2", "Storage Account", "mystorageaccount" */ name: string; cost: number; costAmortized?: number; costPrevious?: number; costAmortizedPrevious?: number; /** e.g., 80.5 (for 80.5%) */ percentageOfTotal: number; /** Absolute change from previous period */ costChange?: number; /** Percentage change from previous period */ costChangePercent?: number; children?: DecompositionTreeNode[]; /** Total spend at this level (for percentage calculation) */ totalSpend?: number; totalSpendAmortized?: number; totalSpendPrevious?: number; totalSpendAmortizedPrevious?: number; displayName?: string; nodePath?: string; expanded?: boolean; collapsed?: boolean; hasChildren?: boolean; forceCollapsedView?: boolean; subscriptionId?: string; dataSource?: string; actualShare?: number; estimatedShare?: number; estimationMethod?: string; pricingSource?: string; metricsInput?: Record; unitRates?: Record; metadata?: Record; blendedComponents?: unknown; /** Analysis of why costs changed (only present on leaf nodes) */ changeAnalysis?: CostChangeAnalysis; /** Only present on leaf nodes (individual resources) */ meterDetails?: MeterDetail[]; tags?: Record; spottoTags?: Tags; resourceId?: string; chargeContext?: BillingChargeContext; resourceLifecycle?: ResourceLifecycleContext; composition?: CostComposition; } export interface MeterDetail { /** "P1 v3 App" */ meter: string; /** "Azure App Service" */ meterCategory: string; /** "Premium Plan" */ meterSubCategory: string; /** 24 (hours, GB, etc.) */ quantity: number; /** 12.721536 */ cost: number; /** 12.721536 */ costAmortized: number; /** cost / quantity = rate per unit */ unitCost?: number; } export interface DecompositionTree { root: DecompositionTreeNode; period: { startDate: string; endDate: string; type: 'billing_period' | 'calendar_month' | 'calendar_day' | 'rolling_30_days'; basis?: CostDateBasis; timeZone?: string; }; lastUpdated: string; totalSpend: number; totalSpendAmortized?: number; totalSpendPrevious?: number; totalSpendAmortizedPrevious?: number; currency: string; currencySymbol: string; version?: string; composition?: CostComposition; } export interface EstimationTree extends DecompositionTree { dataSource: 'estimated' | 'blended' | 'actual' | 'metrics_pricing'; coveragePercent?: number; confidence?: number; actualShare?: number; estimatedShare?: number; billingReconciliationStatus?: 'pending' | 'matched' | 'mismatch'; actualArrivedAt?: string; lastActualCoverageAt?: string; reconciledAt?: string; root: EstimationTreeNode; } export interface EstimationDetailComponent { method?: string; dataSource?: 'estimated' | 'actual' | 'blended' | 'metrics_pricing'; pricingSource?: 'billing' | 'retail' | 'manual' | string; formula?: string; inputs?: { coverageDays?: number; missingDays?: number; missingFactor?: number; metricsInput?: Record; [key: string]: unknown; }; rates?: Record; output?: { actualCost?: number; estimatedCost?: number; estimatedCostByMetrics?: number; estimatedCostByMA?: number; totalCost?: number; [key: string]: unknown; }; [key: string]: unknown; } export interface EstimationNodeDetails { version?: number; dataSource?: 'estimated' | 'actual' | 'blended' | 'metrics_pricing'; actualShare?: number; estimatedShare?: number; componentCount?: number; components?: EstimationDetailComponent[]; [key: string]: unknown; } export interface EstimationTreeNode extends DecompositionTreeNode { dataSource?: 'estimated' | 'actual' | 'blended' | 'metrics_pricing'; coveragePercent?: number; coverageDays?: number; actualShare?: number; estimatedShare?: number; confidence?: number; serviceCategory?: 'A' | 'B' | 'C' | 'D'; componentCategory?: 'A' | 'B' | 'C' | 'D'; metricsInput?: Record; unitRates?: Record; pricingSource?: 'billing' | 'retail' | 'manual'; estimationMethod?: string; estimatedDays?: string[]; estimatedDaysSource?: 'metrics' | 'ma7' | 'ma14' | 'ma'; estimatedDaysBySource?: { metrics?: string[]; ma7?: string[]; ma14?: string[]; ma?: string[]; }; /** Last day with actual billed cost in the current estimation window */ billingActualThroughDate?: number; /** First estimated day in the current estimation window */ estimationStartDate?: number; /** Last estimated day in the current estimation window */ estimationEndDate?: number; /** Resource lifecycle end date (if known) used to cap estimation */ resourceLifecycleEndDate?: number; /** Detected billing cadence for this node */ billingCadence?: BillingCadence; /** Confidence of billing cadence detection */ billingCadenceConfidence?: 'high' | 'medium' | 'low'; /** * Type of this node: 'subscription' | 'resourceGroup' | 'provider' | 'service' | 'resource' | 'deployment' | 'component' * Helps frontend understand the hierarchy and render appropriately */ nodeType?: 'subscription' | 'resourceGroup' | 'provider' | 'service' | 'resource' | 'deployment' | 'component'; /** * Azure resource type (e.g., "microsoft.cognitiveservices/accounts") * Only present on resource nodes and their children * Helps frontend determine how to display child nodes */ resourceType?: string; /** * For deployment/component nodes: identifies the parent resource * For resource nodes: same as resourceId */ parentResourceId?: string; /** * Deployment-specific metadata (only for cognitive services) * Frontend can use this to display deployment-level details */ deployment?: string; model?: string; /** * Generic metadata for other resource types * Allows extensibility for future resource types with sub-components */ metadata?: { estimationDetails?: EstimationNodeDetails; [key: string]: unknown; }; blendedComponents?: EstimationTreeNodeBlendedComponent[] | EstimationTreeNodeBlendedComponent; children?: EstimationTreeNode[]; } export interface EstimationTreeNodeBlendedComponent { componentCategory?: 'A' | 'B' | 'C' | 'D'; dataSource?: 'estimated' | 'actual' | 'blended' | 'metrics_pricing'; actualCost: number; estimatedCost: number; estimatedCostByMetrics?: number; estimatedCostByMA?: number; coverageDays: number; coveragePercent?: number; missingDays: number; method: string; estimationMethod?: string; estimatedDays?: string[]; estimatedDaysSource?: 'metrics' | 'ma7' | 'ma14' | 'ma'; estimatedDaysBySource?: { metrics?: string[]; ma7?: string[]; ma14?: string[]; ma?: string[]; }; metricsInput?: Record; unitRates?: Record; pricingSource?: 'billing' | 'retail' | 'manual'; actualShare?: number; estimatedShare?: number; estimationDetails?: EstimationDetailComponent; } export interface DecompositionTreeEntry { /** e.g., "2025-01" for calendar month, "2025-01-01_2025-01-31" for billing period */ period: string; startDate: string; endDate: string; tree: DecompositionTree; } export interface DecompositionTreeSummary { id?: string; root?: DecompositionTreeNode; currency?: string; currencySymbol?: string; totalSpend?: number; totalSpendAmortized?: number; totalSpendPrevious?: number; totalSpendAmortizedPrevious?: number; version?: string; entries: DecompositionTreeEntry[]; lastUpdated: string; } /** Type of change detected in cost analysis */ export type ChangeType = 'increase' | 'decrease' | 'no_change' | 'new_resource' | 'removed_resource'; /** Specific reason types for cost changes */ export declare enum ChangeReasonType { NEW_RESOURCE = "new_resource", REMOVED_RESOURCE = "removed_resource", QUANTITY_INCREASE = "quantity_increase", QUANTITY_DECREASE = "quantity_decrease", RATE_CHANGE = "rate_change", SKU_CHANGE = "sku_change", NEW_METER = "new_meter", REMOVED_METER = "removed_meter" } export type BillingModifierType = 'reservation' | 'savings_plan' | 'spot' | 'promotion' | 'other'; export interface BillingModifierDetail { type: BillingModifierType; name?: string; coverageHours?: number; coveragePercent?: number; previousCoveragePercent?: number; coveragePercentDelta?: number; notes?: string; } export interface RateChangeContext { previousEffectiveRate?: number; currentEffectiveRate?: number; previousPaidRate?: number; currentPaidRate?: number; totalHours?: number; paidHours?: number; coveredHours?: number; previousCoveredHours?: number; previousCoveredPercent?: number; currentCoveredPercent?: number; coverageDeltaPercent?: number; modifier?: BillingModifierDetail; } /** Details about a specific change reason */ export interface ChangeReasonDetails { /** The meter name (e.g., "P1 v3 App") */ meter?: string; /** The meter category (e.g., "Azure App Service") */ meterCategory?: string; /** The meter sub-category */ meterSubCategory?: string; /** Previous value (could be cost, quantity, rate, or SKU name) */ oldValue?: string | number; /** New value (could be cost, quantity, rate, or SKU name) */ newValue?: string | number; /** Human-readable description of the change */ description: string; /** Additional rate-change context (coverage shifts, modifier attribution, etc.) */ rateContext?: RateChangeContext; /** Optional narrative fragments to help surface a story in the UI */ storyFragments?: string[]; } /** A single reason explaining a cost change */ export interface ChangeReason { /** Type of change */ type: ChangeReasonType; /** Dollar impact of this change (can be positive or negative) */ impact: number; /** Percentage of total change this reason represents */ impactPercent: number; /** Detailed information about the change */ details: ChangeReasonDetails; /** Optional narrative fragments tied to this reason */ storyFragments?: string[]; } /** Complete analysis of cost changes for a resource */ export interface CostChangeAnalysis { /** Overall type of change */ changeType: ChangeType; /** List of specific reasons for the change, ordered by impact */ changeReasons: ChangeReason[]; /** Human-readable summary of the changes */ summary: string; /** Optional narrative fragments surfaced for display */ storyFragments?: string[]; } //# sourceMappingURL=reports.d.ts.map