mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
263 lines
12 KiB
MySQL
263 lines
12 KiB
MySQL
|
|
ALTER TABLE IF EXISTS public.usage_settlement_snapshots
|
||
|
|
ADD COLUMN IF NOT EXISTS settlement_snapshot_schema_version character varying(20),
|
||
|
|
ADD COLUMN IF NOT EXISTS settlement_snapshot jsonb,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_dimensions jsonb,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_input_tokens bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_effective_input_tokens bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_output_tokens bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_cache_creation_tokens bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_cache_creation_5m_tokens bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_cache_creation_1h_tokens bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_cache_read_tokens bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_total_input_context bigint,
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_cache_creation_cost_usd numeric(20,8),
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_cache_read_cost_usd numeric(20,8),
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_total_cost_usd numeric(20,8),
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_actual_total_cost_usd numeric(20,8),
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_pricing_source character varying(50),
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_rule_id character varying(100),
|
||
|
|
ADD COLUMN IF NOT EXISTS billing_rule_version character varying(50);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_usage_settlement_snapshots_schema_version
|
||
|
|
ON public.usage_settlement_snapshots USING btree (settlement_snapshot_schema_version);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS ix_usage_settlement_snapshots_pricing_source
|
||
|
|
ON public.usage_settlement_snapshots USING btree (billing_pricing_source);
|
||
|
|
|
||
|
|
CREATE OR REPLACE VIEW public.usage_billing_facts AS
|
||
|
|
SELECT
|
||
|
|
usage_rows.id,
|
||
|
|
usage_rows.request_id,
|
||
|
|
usage_rows.user_id,
|
||
|
|
usage_rows.api_key_id,
|
||
|
|
usage_rows.username,
|
||
|
|
usage_rows.api_key_name,
|
||
|
|
usage_rows.provider_name,
|
||
|
|
usage_rows.model,
|
||
|
|
usage_rows.target_model,
|
||
|
|
usage_rows.provider_id,
|
||
|
|
usage_rows.provider_endpoint_id,
|
||
|
|
usage_rows.provider_api_key_id,
|
||
|
|
usage_rows.request_type,
|
||
|
|
usage_rows.api_format,
|
||
|
|
usage_rows.api_family,
|
||
|
|
usage_rows.endpoint_kind,
|
||
|
|
usage_rows.endpoint_api_format,
|
||
|
|
usage_rows.provider_api_family,
|
||
|
|
usage_rows.provider_endpoint_kind,
|
||
|
|
COALESCE(usage_rows.has_format_conversion, FALSE) AS has_format_conversion,
|
||
|
|
COALESCE(usage_rows.is_stream, FALSE) AS is_stream,
|
||
|
|
usage_rows.status_code,
|
||
|
|
usage_rows.error_message,
|
||
|
|
usage_rows.error_category,
|
||
|
|
usage_rows.response_time_ms,
|
||
|
|
usage_rows.first_byte_time_ms,
|
||
|
|
usage_rows.status,
|
||
|
|
COALESCE(settlement.billing_status, usage_rows.billing_status) AS billing_status,
|
||
|
|
usage_rows.created_at,
|
||
|
|
COALESCE(settlement.finalized_at, usage_rows.finalized_at) AS finalized_at,
|
||
|
|
GREATEST(COALESCE(settlement.billing_input_tokens, usage_rows.input_tokens, 0), 0)::bigint
|
||
|
|
AS input_tokens,
|
||
|
|
GREATEST(
|
||
|
|
COALESCE(
|
||
|
|
settlement.billing_effective_input_tokens,
|
||
|
|
CASE
|
||
|
|
WHEN GREATEST(COALESCE(usage_rows.input_tokens, 0), 0) <= 0 THEN 0
|
||
|
|
WHEN GREATEST(COALESCE(usage_rows.cache_read_input_tokens, 0), 0) <= 0
|
||
|
|
THEN GREATEST(COALESCE(usage_rows.input_tokens, 0), 0)
|
||
|
|
WHEN split_part(lower(COALESCE(COALESCE(usage_rows.endpoint_api_format, usage_rows.api_format), '')), ':', 1)
|
||
|
|
IN ('openai', 'gemini', 'google')
|
||
|
|
THEN GREATEST(
|
||
|
|
GREATEST(COALESCE(usage_rows.input_tokens, 0), 0)
|
||
|
|
- GREATEST(COALESCE(usage_rows.cache_read_input_tokens, 0), 0),
|
||
|
|
0
|
||
|
|
)
|
||
|
|
ELSE GREATEST(COALESCE(usage_rows.input_tokens, 0), 0)
|
||
|
|
END
|
||
|
|
),
|
||
|
|
0
|
||
|
|
)::bigint AS effective_input_tokens,
|
||
|
|
GREATEST(COALESCE(settlement.billing_output_tokens, usage_rows.output_tokens, 0), 0)::bigint
|
||
|
|
AS output_tokens,
|
||
|
|
GREATEST(
|
||
|
|
COALESCE(
|
||
|
|
settlement.billing_cache_creation_tokens,
|
||
|
|
CASE
|
||
|
|
WHEN COALESCE(usage_rows.cache_creation_input_tokens, 0) = 0
|
||
|
|
AND (
|
||
|
|
COALESCE(usage_rows.cache_creation_input_tokens_5m, 0)
|
||
|
|
+ COALESCE(usage_rows.cache_creation_input_tokens_1h, 0)
|
||
|
|
) > 0
|
||
|
|
THEN COALESCE(usage_rows.cache_creation_input_tokens_5m, 0)
|
||
|
|
+ COALESCE(usage_rows.cache_creation_input_tokens_1h, 0)
|
||
|
|
ELSE COALESCE(usage_rows.cache_creation_input_tokens, 0)
|
||
|
|
END,
|
||
|
|
0
|
||
|
|
),
|
||
|
|
0
|
||
|
|
)::bigint AS cache_creation_input_tokens,
|
||
|
|
GREATEST(
|
||
|
|
COALESCE(
|
||
|
|
settlement.billing_cache_creation_5m_tokens,
|
||
|
|
usage_rows.cache_creation_input_tokens_5m,
|
||
|
|
0
|
||
|
|
),
|
||
|
|
0
|
||
|
|
)::bigint AS cache_creation_input_tokens_5m,
|
||
|
|
GREATEST(
|
||
|
|
COALESCE(
|
||
|
|
settlement.billing_cache_creation_1h_tokens,
|
||
|
|
usage_rows.cache_creation_input_tokens_1h,
|
||
|
|
0
|
||
|
|
),
|
||
|
|
0
|
||
|
|
)::bigint AS cache_creation_input_tokens_1h,
|
||
|
|
GREATEST(COALESCE(settlement.billing_cache_read_tokens, usage_rows.cache_read_input_tokens, 0), 0)::bigint
|
||
|
|
AS cache_read_input_tokens,
|
||
|
|
GREATEST(
|
||
|
|
COALESCE(
|
||
|
|
CASE
|
||
|
|
WHEN settlement.billing_input_tokens IS NOT NULL
|
||
|
|
OR settlement.billing_output_tokens IS NOT NULL
|
||
|
|
OR settlement.billing_cache_creation_tokens IS NOT NULL
|
||
|
|
OR settlement.billing_cache_creation_5m_tokens IS NOT NULL
|
||
|
|
OR settlement.billing_cache_creation_1h_tokens IS NOT NULL
|
||
|
|
OR settlement.billing_cache_read_tokens IS NOT NULL
|
||
|
|
THEN COALESCE(settlement.billing_input_tokens, 0)
|
||
|
|
+ COALESCE(settlement.billing_output_tokens, 0)
|
||
|
|
+ COALESCE(
|
||
|
|
settlement.billing_cache_creation_tokens,
|
||
|
|
COALESCE(settlement.billing_cache_creation_5m_tokens, 0)
|
||
|
|
+ COALESCE(settlement.billing_cache_creation_1h_tokens, 0),
|
||
|
|
0
|
||
|
|
)
|
||
|
|
+ COALESCE(settlement.billing_cache_read_tokens, 0)
|
||
|
|
END,
|
||
|
|
usage_rows.total_tokens,
|
||
|
|
0
|
||
|
|
),
|
||
|
|
0
|
||
|
|
)::bigint AS total_tokens,
|
||
|
|
GREATEST(
|
||
|
|
COALESCE(
|
||
|
|
settlement.billing_total_input_context,
|
||
|
|
CASE
|
||
|
|
WHEN split_part(lower(COALESCE(COALESCE(usage_rows.endpoint_api_format, usage_rows.api_format), '')), ':', 1)
|
||
|
|
IN ('claude', 'anthropic')
|
||
|
|
THEN GREATEST(COALESCE(usage_rows.input_tokens, 0), 0)
|
||
|
|
+ CASE
|
||
|
|
WHEN COALESCE(usage_rows.cache_creation_input_tokens, 0) = 0
|
||
|
|
AND (
|
||
|
|
COALESCE(usage_rows.cache_creation_input_tokens_5m, 0)
|
||
|
|
+ COALESCE(usage_rows.cache_creation_input_tokens_1h, 0)
|
||
|
|
) > 0
|
||
|
|
THEN COALESCE(usage_rows.cache_creation_input_tokens_5m, 0)
|
||
|
|
+ COALESCE(usage_rows.cache_creation_input_tokens_1h, 0)
|
||
|
|
ELSE COALESCE(usage_rows.cache_creation_input_tokens, 0)
|
||
|
|
END
|
||
|
|
+ GREATEST(COALESCE(usage_rows.cache_read_input_tokens, 0), 0)
|
||
|
|
WHEN split_part(lower(COALESCE(COALESCE(usage_rows.endpoint_api_format, usage_rows.api_format), '')), ':', 1)
|
||
|
|
IN ('openai', 'gemini', 'google')
|
||
|
|
THEN CASE
|
||
|
|
WHEN GREATEST(COALESCE(usage_rows.input_tokens, 0), 0) <= 0 THEN 0
|
||
|
|
WHEN GREATEST(COALESCE(usage_rows.cache_read_input_tokens, 0), 0) <= 0
|
||
|
|
THEN GREATEST(COALESCE(usage_rows.input_tokens, 0), 0)
|
||
|
|
ELSE GREATEST(
|
||
|
|
GREATEST(COALESCE(usage_rows.input_tokens, 0), 0)
|
||
|
|
- GREATEST(COALESCE(usage_rows.cache_read_input_tokens, 0), 0),
|
||
|
|
0
|
||
|
|
)
|
||
|
|
END
|
||
|
|
+ GREATEST(COALESCE(usage_rows.cache_read_input_tokens, 0), 0)
|
||
|
|
ELSE GREATEST(COALESCE(usage_rows.input_tokens, 0), 0)
|
||
|
|
+ CASE
|
||
|
|
WHEN COALESCE(usage_rows.cache_creation_input_tokens, 0) = 0
|
||
|
|
AND (
|
||
|
|
COALESCE(usage_rows.cache_creation_input_tokens_5m, 0)
|
||
|
|
+ COALESCE(usage_rows.cache_creation_input_tokens_1h, 0)
|
||
|
|
) > 0
|
||
|
|
THEN COALESCE(usage_rows.cache_creation_input_tokens_5m, 0)
|
||
|
|
+ COALESCE(usage_rows.cache_creation_input_tokens_1h, 0)
|
||
|
|
ELSE COALESCE(usage_rows.cache_creation_input_tokens, 0)
|
||
|
|
END
|
||
|
|
+ GREATEST(COALESCE(usage_rows.cache_read_input_tokens, 0), 0)
|
||
|
|
END,
|
||
|
|
0
|
||
|
|
),
|
||
|
|
0
|
||
|
|
)::bigint AS total_input_context,
|
||
|
|
COALESCE(CAST(usage_rows.input_cost_usd AS DOUBLE PRECISION), 0) AS input_cost_usd,
|
||
|
|
COALESCE(CAST(usage_rows.output_cost_usd AS DOUBLE PRECISION), 0) AS output_cost_usd,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.billing_cache_creation_cost_usd AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.cache_creation_cost_usd AS DOUBLE PRECISION),
|
||
|
|
0
|
||
|
|
) AS cache_creation_cost_usd,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.billing_cache_read_cost_usd AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.cache_read_cost_usd AS DOUBLE PRECISION),
|
||
|
|
0
|
||
|
|
) AS cache_read_cost_usd,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.billing_total_cost_usd AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.total_cost_usd AS DOUBLE PRECISION),
|
||
|
|
0
|
||
|
|
) AS total_cost_usd,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.billing_actual_total_cost_usd AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.actual_total_cost_usd AS DOUBLE PRECISION),
|
||
|
|
0
|
||
|
|
) AS actual_total_cost_usd,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.output_price_per_1m AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.output_price_per_1m AS DOUBLE PRECISION)
|
||
|
|
) AS output_price_per_1m,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.input_price_per_1m AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.input_price_per_1m AS DOUBLE PRECISION)
|
||
|
|
) AS input_price_per_1m,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.cache_creation_price_per_1m AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.cache_creation_price_per_1m AS DOUBLE PRECISION)
|
||
|
|
) AS cache_creation_price_per_1m,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.cache_read_price_per_1m AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.cache_read_price_per_1m AS DOUBLE PRECISION)
|
||
|
|
) AS cache_read_price_per_1m,
|
||
|
|
COALESCE(
|
||
|
|
CAST(settlement.price_per_request AS DOUBLE PRECISION),
|
||
|
|
CAST(usage_rows.price_per_request AS DOUBLE PRECISION)
|
||
|
|
) AS price_per_request,
|
||
|
|
settlement.billing_pricing_source,
|
||
|
|
settlement.billing_rule_id,
|
||
|
|
settlement.billing_rule_version
|
||
|
|
FROM public."usage" AS usage_rows
|
||
|
|
LEFT JOIN public.usage_settlement_snapshots AS settlement
|
||
|
|
ON settlement.request_id = usage_rows.request_id;
|
||
|
|
|
||
|
|
COMMENT ON VIEW public.usage_billing_facts IS
|
||
|
|
'Canonical billing read model. Token/cost fields prefer usage_settlement_snapshots.billing_* and fall back to deprecated usage mirrors for legacy rows.';
|
||
|
|
|
||
|
|
COMMENT ON COLUMN public.usage.input_tokens IS
|
||
|
|
'DEPRECATED: billing dimension mirror. Use public.usage_settlement_snapshots.billing_input_tokens or public.usage_billing_facts.input_tokens.';
|
||
|
|
COMMENT ON COLUMN public.usage.output_tokens IS
|
||
|
|
'DEPRECATED: billing dimension mirror. Use public.usage_settlement_snapshots.billing_output_tokens or public.usage_billing_facts.output_tokens.';
|
||
|
|
COMMENT ON COLUMN public.usage.total_tokens IS
|
||
|
|
'DEPRECATED: billing dimension mirror. Use public.usage_billing_facts.total_tokens.';
|
||
|
|
COMMENT ON COLUMN public.usage.cache_creation_input_tokens IS
|
||
|
|
'DEPRECATED: billing dimension mirror. Use public.usage_settlement_snapshots.billing_cache_creation_tokens or public.usage_billing_facts.cache_creation_input_tokens.';
|
||
|
|
COMMENT ON COLUMN public.usage.cache_creation_input_tokens_5m IS
|
||
|
|
'DEPRECATED: billing dimension mirror. Use public.usage_settlement_snapshots.billing_cache_creation_5m_tokens or public.usage_billing_facts.cache_creation_input_tokens_5m.';
|
||
|
|
COMMENT ON COLUMN public.usage.cache_creation_input_tokens_1h IS
|
||
|
|
'DEPRECATED: billing dimension mirror. Use public.usage_settlement_snapshots.billing_cache_creation_1h_tokens or public.usage_billing_facts.cache_creation_input_tokens_1h.';
|
||
|
|
COMMENT ON COLUMN public.usage.cache_read_input_tokens IS
|
||
|
|
'DEPRECATED: billing dimension mirror. Use public.usage_settlement_snapshots.billing_cache_read_tokens or public.usage_billing_facts.cache_read_input_tokens.';
|
||
|
|
COMMENT ON COLUMN public.usage.cache_creation_cost_usd IS
|
||
|
|
'DEPRECATED: billing cost mirror. Use public.usage_settlement_snapshots.billing_cache_creation_cost_usd or public.usage_billing_facts.cache_creation_cost_usd.';
|
||
|
|
COMMENT ON COLUMN public.usage.cache_read_cost_usd IS
|
||
|
|
'DEPRECATED: billing cost mirror. Use public.usage_settlement_snapshots.billing_cache_read_cost_usd or public.usage_billing_facts.cache_read_cost_usd.';
|
||
|
|
COMMENT ON COLUMN public.usage.total_cost_usd IS
|
||
|
|
'DEPRECATED: billing cost mirror. Use public.usage_settlement_snapshots.billing_total_cost_usd or public.usage_billing_facts.total_cost_usd.';
|
||
|
|
COMMENT ON COLUMN public.usage.actual_total_cost_usd IS
|
||
|
|
'DEPRECATED: billing cost mirror. Use public.usage_settlement_snapshots.billing_actual_total_cost_usd or public.usage_billing_facts.actual_total_cost_usd.';
|