feat(data): complete portable SQL backend parity

Align MySQL and SQLite schemas, migrations, usage, stats, export, and backfill behavior with the shared data contracts. Extend gateway startup and maintenance support across all SQL drivers.
This commit is contained in:
elky
2026-07-25 21:28:21 +08:00
parent 764e9fd131
commit 778cfb1a5c
85 changed files with 32096 additions and 2328 deletions
@@ -0,0 +1,784 @@
-- PostgreSQL and legacy SQLite exports encode timestamps as ISO/SQL datetime text.
-- Normalize imported and repository-facing timestamps back to the INTEGER Unix-second contract.
-- Numeric strings already receive INTEGER affinity on insert; unparseable text is preserved.
UPDATE "users"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "users"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "users"
SET "last_login_at" = CAST(strftime('%s', trim("last_login_at")) AS INTEGER)
WHERE typeof("last_login_at") = 'text'
AND strftime('%s', trim("last_login_at")) IS NOT NULL;
UPDATE "users"
SET "privacy_policy_accepted_at" = CAST(strftime('%s', trim("privacy_policy_accepted_at")) AS INTEGER)
WHERE typeof("privacy_policy_accepted_at") = 'text'
AND strftime('%s', trim("privacy_policy_accepted_at")) IS NOT NULL;
UPDATE "api_keys"
SET "expires_at" = CAST(strftime('%s', trim("expires_at")) AS INTEGER)
WHERE typeof("expires_at") = 'text'
AND strftime('%s', trim("expires_at")) IS NOT NULL;
UPDATE "api_keys"
SET "last_used_at" = CAST(strftime('%s', trim("last_used_at")) AS INTEGER)
WHERE typeof("last_used_at") = 'text'
AND strftime('%s', trim("last_used_at")) IS NOT NULL;
UPDATE "api_keys"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "api_keys"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "providers"
SET "quota_last_reset_at" = CAST(strftime('%s', trim("quota_last_reset_at")) AS INTEGER)
WHERE typeof("quota_last_reset_at") = 'text'
AND strftime('%s', trim("quota_last_reset_at")) IS NOT NULL;
UPDATE "providers"
SET "quota_expires_at" = CAST(strftime('%s', trim("quota_expires_at")) AS INTEGER)
WHERE typeof("quota_expires_at") = 'text'
AND strftime('%s', trim("quota_expires_at")) IS NOT NULL;
UPDATE "providers"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "providers"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "expires_at" = CAST(strftime('%s', trim("expires_at")) AS INTEGER)
WHERE typeof("expires_at") = 'text'
AND strftime('%s', trim("expires_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "last_429_at" = CAST(strftime('%s', trim("last_429_at")) AS INTEGER)
WHERE typeof("last_429_at") = 'text'
AND strftime('%s', trim("last_429_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "last_probe_increase_at" = CAST(strftime('%s', trim("last_probe_increase_at")) AS INTEGER)
WHERE typeof("last_probe_increase_at") = 'text'
AND strftime('%s', trim("last_probe_increase_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "last_used_at" = CAST(strftime('%s', trim("last_used_at")) AS INTEGER)
WHERE typeof("last_used_at") = 'text'
AND strftime('%s', trim("last_used_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "last_models_fetch_at" = CAST(strftime('%s', trim("last_models_fetch_at")) AS INTEGER)
WHERE typeof("last_models_fetch_at") = 'text'
AND strftime('%s', trim("last_models_fetch_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "oauth_invalid_at" = CAST(strftime('%s', trim("oauth_invalid_at")) AS INTEGER)
WHERE typeof("oauth_invalid_at") = 'text'
AND strftime('%s', trim("oauth_invalid_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "provider_api_keys"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "provider_endpoints"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "provider_endpoints"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "global_models"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "global_models"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "models"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "models"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "auth_modules"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "auth_modules"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "oauth_providers"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "oauth_providers"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "user_oauth_links"
SET "linked_at" = CAST(strftime('%s', trim("linked_at")) AS INTEGER)
WHERE typeof("linked_at") = 'text'
AND strftime('%s', trim("linked_at")) IS NOT NULL;
UPDATE "user_oauth_links"
SET "last_login_at" = CAST(strftime('%s', trim("last_login_at")) AS INTEGER)
WHERE typeof("last_login_at") = 'text'
AND strftime('%s', trim("last_login_at")) IS NOT NULL;
UPDATE "user_groups"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "user_groups"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "user_group_members"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "proxy_nodes"
SET "last_heartbeat_at" = CAST(strftime('%s', trim("last_heartbeat_at")) AS INTEGER)
WHERE typeof("last_heartbeat_at") = 'text'
AND strftime('%s', trim("last_heartbeat_at")) IS NOT NULL;
UPDATE "proxy_nodes"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "proxy_nodes"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "proxy_nodes"
SET "tunnel_connected_at" = CAST(strftime('%s', trim("tunnel_connected_at")) AS INTEGER)
WHERE typeof("tunnel_connected_at") = 'text'
AND strftime('%s', trim("tunnel_connected_at")) IS NOT NULL;
UPDATE "system_configs"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "system_configs"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "wallets"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "wallets"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "wallet_transactions"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "wallet_daily_usage_ledgers"
SET "first_finalized_at" = CAST(strftime('%s', trim("first_finalized_at")) AS INTEGER)
WHERE typeof("first_finalized_at") = 'text'
AND strftime('%s', trim("first_finalized_at")) IS NOT NULL;
UPDATE "wallet_daily_usage_ledgers"
SET "last_finalized_at" = CAST(strftime('%s', trim("last_finalized_at")) AS INTEGER)
WHERE typeof("last_finalized_at") = 'text'
AND strftime('%s', trim("last_finalized_at")) IS NOT NULL;
UPDATE "wallet_daily_usage_ledgers"
SET "aggregated_at" = CAST(strftime('%s', trim("aggregated_at")) AS INTEGER)
WHERE typeof("aggregated_at") = 'text'
AND strftime('%s', trim("aggregated_at")) IS NOT NULL;
UPDATE "wallet_daily_usage_ledgers"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "wallet_daily_usage_ledgers"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "payment_orders"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "payment_orders"
SET "paid_at" = CAST(strftime('%s', trim("paid_at")) AS INTEGER)
WHERE typeof("paid_at") = 'text'
AND strftime('%s', trim("paid_at")) IS NOT NULL;
UPDATE "payment_orders"
SET "credited_at" = CAST(strftime('%s', trim("credited_at")) AS INTEGER)
WHERE typeof("credited_at") = 'text'
AND strftime('%s', trim("credited_at")) IS NOT NULL;
UPDATE "payment_orders"
SET "expires_at" = CAST(strftime('%s', trim("expires_at")) AS INTEGER)
WHERE typeof("expires_at") = 'text'
AND strftime('%s', trim("expires_at")) IS NOT NULL;
UPDATE "payment_callbacks"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "payment_callbacks"
SET "processed_at" = CAST(strftime('%s', trim("processed_at")) AS INTEGER)
WHERE typeof("processed_at") = 'text'
AND strftime('%s', trim("processed_at")) IS NOT NULL;
UPDATE "refund_requests"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "refund_requests"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "refund_requests"
SET "processed_at" = CAST(strftime('%s', trim("processed_at")) AS INTEGER)
WHERE typeof("processed_at") = 'text'
AND strftime('%s', trim("processed_at")) IS NOT NULL;
UPDATE "refund_requests"
SET "completed_at" = CAST(strftime('%s', trim("completed_at")) AS INTEGER)
WHERE typeof("completed_at") = 'text'
AND strftime('%s', trim("completed_at")) IS NOT NULL;
UPDATE "redeem_code_batches"
SET "expires_at" = CAST(strftime('%s', trim("expires_at")) AS INTEGER)
WHERE typeof("expires_at") = 'text'
AND strftime('%s', trim("expires_at")) IS NOT NULL;
UPDATE "redeem_code_batches"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "redeem_code_batches"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "redeem_codes"
SET "redeemed_at" = CAST(strftime('%s', trim("redeemed_at")) AS INTEGER)
WHERE typeof("redeemed_at") = 'text'
AND strftime('%s', trim("redeemed_at")) IS NOT NULL;
UPDATE "redeem_codes"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "redeem_codes"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "usage"
SET "created_at_unix_ms" = CAST(strftime('%s', trim("created_at_unix_ms")) AS INTEGER)
WHERE typeof("created_at_unix_ms") = 'text'
AND strftime('%s', trim("created_at_unix_ms")) IS NOT NULL;
UPDATE "usage"
SET "updated_at_unix_secs" = CAST(strftime('%s', trim("updated_at_unix_secs")) AS INTEGER)
WHERE typeof("updated_at_unix_secs") = 'text'
AND strftime('%s', trim("updated_at_unix_secs")) IS NOT NULL;
UPDATE "usage"
SET "finalized_at" = CAST(strftime('%s', trim("finalized_at")) AS INTEGER)
WHERE typeof("finalized_at") = 'text'
AND strftime('%s', trim("finalized_at")) IS NOT NULL;
UPDATE "billing_rules"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "billing_rules"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "dimension_collectors"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "dimension_collectors"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "usage_settlement_snapshots"
SET "finalized_at" = CAST(strftime('%s', trim("finalized_at")) AS INTEGER)
WHERE typeof("finalized_at") = 'text'
AND strftime('%s', trim("finalized_at")) IS NOT NULL;
UPDATE "usage_settlement_snapshots"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "usage_settlement_snapshots"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "announcements"
SET "start_time" = CAST(strftime('%s', trim("start_time")) AS INTEGER)
WHERE typeof("start_time") = 'text'
AND strftime('%s', trim("start_time")) IS NOT NULL;
UPDATE "announcements"
SET "end_time" = CAST(strftime('%s', trim("end_time")) AS INTEGER)
WHERE typeof("end_time") = 'text'
AND strftime('%s', trim("end_time")) IS NOT NULL;
UPDATE "announcements"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "announcements"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "management_tokens"
SET "expires_at" = CAST(strftime('%s', trim("expires_at")) AS INTEGER)
WHERE typeof("expires_at") = 'text'
AND strftime('%s', trim("expires_at")) IS NOT NULL;
UPDATE "management_tokens"
SET "last_used_at" = CAST(strftime('%s', trim("last_used_at")) AS INTEGER)
WHERE typeof("last_used_at") = 'text'
AND strftime('%s', trim("last_used_at")) IS NOT NULL;
UPDATE "management_tokens"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "management_tokens"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "video_tasks"
SET "next_poll_at" = CAST(strftime('%s', trim("next_poll_at")) AS INTEGER)
WHERE typeof("next_poll_at") = 'text'
AND strftime('%s', trim("next_poll_at")) IS NOT NULL;
UPDATE "video_tasks"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "video_tasks"
SET "submitted_at" = CAST(strftime('%s', trim("submitted_at")) AS INTEGER)
WHERE typeof("submitted_at") = 'text'
AND strftime('%s', trim("submitted_at")) IS NOT NULL;
UPDATE "video_tasks"
SET "completed_at" = CAST(strftime('%s', trim("completed_at")) AS INTEGER)
WHERE typeof("completed_at") = 'text'
AND strftime('%s', trim("completed_at")) IS NOT NULL;
UPDATE "video_tasks"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "payment_gateway_configs"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "payment_gateway_configs"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "billing_plans"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "billing_plans"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
UPDATE "user_plan_entitlements"
SET "starts_at" = CAST(strftime('%s', trim("starts_at")) AS INTEGER)
WHERE typeof("starts_at") = 'text'
AND strftime('%s', trim("starts_at")) IS NOT NULL;
UPDATE "user_plan_entitlements"
SET "expires_at" = CAST(strftime('%s', trim("expires_at")) AS INTEGER)
WHERE typeof("expires_at") = 'text'
AND strftime('%s', trim("expires_at")) IS NOT NULL;
UPDATE "user_plan_entitlements"
SET "created_at" = CAST(strftime('%s', trim("created_at")) AS INTEGER)
WHERE typeof("created_at") = 'text'
AND strftime('%s', trim("created_at")) IS NOT NULL;
UPDATE "user_plan_entitlements"
SET "updated_at" = CAST(strftime('%s', trim("updated_at")) AS INTEGER)
WHERE typeof("updated_at") = 'text'
AND strftime('%s', trim("updated_at")) IS NOT NULL;
-- Do not mark the migration successful while an incompatible timestamp can still reach SQLx.
DROP TABLE IF EXISTS temp._aether_timestamp_storage_guard;
CREATE TEMP TABLE _aether_timestamp_storage_guard (
invalid_count INTEGER NOT NULL,
CONSTRAINT imported_timestamp_storage_must_be_integer CHECK (invalid_count = 0)
);
INSERT INTO _aether_timestamp_storage_guard (invalid_count)
SELECT COUNT(*)
FROM (
SELECT 1 FROM "users"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "users"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "users"
WHERE "last_login_at" IS NOT NULL AND typeof("last_login_at") <> 'integer'
UNION ALL
SELECT 1 FROM "users"
WHERE "privacy_policy_accepted_at" IS NOT NULL AND typeof("privacy_policy_accepted_at") <> 'integer'
UNION ALL
SELECT 1 FROM "api_keys"
WHERE "expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer'
UNION ALL
SELECT 1 FROM "api_keys"
WHERE "last_used_at" IS NOT NULL AND typeof("last_used_at") <> 'integer'
UNION ALL
SELECT 1 FROM "api_keys"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "api_keys"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "providers"
WHERE "quota_last_reset_at" IS NOT NULL AND typeof("quota_last_reset_at") <> 'integer'
UNION ALL
SELECT 1 FROM "providers"
WHERE "quota_expires_at" IS NOT NULL AND typeof("quota_expires_at") <> 'integer'
UNION ALL
SELECT 1 FROM "providers"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "providers"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "last_429_at" IS NOT NULL AND typeof("last_429_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "last_probe_increase_at" IS NOT NULL AND typeof("last_probe_increase_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "last_used_at" IS NOT NULL AND typeof("last_used_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "last_models_fetch_at" IS NOT NULL AND typeof("last_models_fetch_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "oauth_invalid_at" IS NOT NULL AND typeof("oauth_invalid_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_api_keys"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_endpoints"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "provider_endpoints"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "global_models"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "global_models"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "models"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "models"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "auth_modules"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "auth_modules"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "oauth_providers"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "oauth_providers"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_oauth_links"
WHERE "linked_at" IS NOT NULL AND typeof("linked_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_oauth_links"
WHERE "last_login_at" IS NOT NULL AND typeof("last_login_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_groups"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_groups"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_group_members"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "proxy_nodes"
WHERE "last_heartbeat_at" IS NOT NULL AND typeof("last_heartbeat_at") <> 'integer'
UNION ALL
SELECT 1 FROM "proxy_nodes"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "proxy_nodes"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "proxy_nodes"
WHERE "tunnel_connected_at" IS NOT NULL AND typeof("tunnel_connected_at") <> 'integer'
UNION ALL
SELECT 1 FROM "system_configs"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "system_configs"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallets"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallets"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallet_transactions"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallet_daily_usage_ledgers"
WHERE "first_finalized_at" IS NOT NULL AND typeof("first_finalized_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallet_daily_usage_ledgers"
WHERE "last_finalized_at" IS NOT NULL AND typeof("last_finalized_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallet_daily_usage_ledgers"
WHERE "aggregated_at" IS NOT NULL AND typeof("aggregated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallet_daily_usage_ledgers"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "wallet_daily_usage_ledgers"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_orders"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_orders"
WHERE "paid_at" IS NOT NULL AND typeof("paid_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_orders"
WHERE "credited_at" IS NOT NULL AND typeof("credited_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_orders"
WHERE "expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_callbacks"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_callbacks"
WHERE "processed_at" IS NOT NULL AND typeof("processed_at") <> 'integer'
UNION ALL
SELECT 1 FROM "refund_requests"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "refund_requests"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "refund_requests"
WHERE "processed_at" IS NOT NULL AND typeof("processed_at") <> 'integer'
UNION ALL
SELECT 1 FROM "refund_requests"
WHERE "completed_at" IS NOT NULL AND typeof("completed_at") <> 'integer'
UNION ALL
SELECT 1 FROM "redeem_code_batches"
WHERE "expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer'
UNION ALL
SELECT 1 FROM "redeem_code_batches"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "redeem_code_batches"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "redeem_codes"
WHERE "redeemed_at" IS NOT NULL AND typeof("redeemed_at") <> 'integer'
UNION ALL
SELECT 1 FROM "redeem_codes"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "redeem_codes"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "usage"
WHERE "created_at_unix_ms" IS NOT NULL AND typeof("created_at_unix_ms") <> 'integer'
UNION ALL
SELECT 1 FROM "usage"
WHERE "updated_at_unix_secs" IS NOT NULL AND typeof("updated_at_unix_secs") <> 'integer'
UNION ALL
SELECT 1 FROM "usage"
WHERE "finalized_at" IS NOT NULL AND typeof("finalized_at") <> 'integer'
UNION ALL
SELECT 1 FROM "billing_rules"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "billing_rules"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "dimension_collectors"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "dimension_collectors"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "usage_settlement_snapshots"
WHERE "finalized_at" IS NOT NULL AND typeof("finalized_at") <> 'integer'
UNION ALL
SELECT 1 FROM "usage_settlement_snapshots"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "usage_settlement_snapshots"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "announcements"
WHERE "start_time" IS NOT NULL AND typeof("start_time") <> 'integer'
UNION ALL
SELECT 1 FROM "announcements"
WHERE "end_time" IS NOT NULL AND typeof("end_time") <> 'integer'
UNION ALL
SELECT 1 FROM "announcements"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "announcements"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "management_tokens"
WHERE "expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer'
UNION ALL
SELECT 1 FROM "management_tokens"
WHERE "last_used_at" IS NOT NULL AND typeof("last_used_at") <> 'integer'
UNION ALL
SELECT 1 FROM "management_tokens"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "management_tokens"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "video_tasks"
WHERE "next_poll_at" IS NOT NULL AND typeof("next_poll_at") <> 'integer'
UNION ALL
SELECT 1 FROM "video_tasks"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "video_tasks"
WHERE "submitted_at" IS NOT NULL AND typeof("submitted_at") <> 'integer'
UNION ALL
SELECT 1 FROM "video_tasks"
WHERE "completed_at" IS NOT NULL AND typeof("completed_at") <> 'integer'
UNION ALL
SELECT 1 FROM "video_tasks"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_gateway_configs"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "payment_gateway_configs"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "billing_plans"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "billing_plans"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_plan_entitlements"
WHERE "starts_at" IS NOT NULL AND typeof("starts_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_plan_entitlements"
WHERE "expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_plan_entitlements"
WHERE "created_at" IS NOT NULL AND typeof("created_at") <> 'integer'
UNION ALL
SELECT 1 FROM "user_plan_entitlements"
WHERE "updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer'
) AS invalid_timestamp_values;
DROP TABLE temp._aether_timestamp_storage_guard;
@@ -0,0 +1,270 @@
-- Complete the portable schema contract that is already represented by the
-- logical/generated schema and PostgreSQL usage capture tables.
ALTER TABLE provider_api_keys ADD COLUMN last_error_at INTEGER;
ALTER TABLE provider_api_keys ADD COLUMN last_error_msg TEXT;
CREATE TABLE IF NOT EXISTS api_key_provider_mappings (
id TEXT PRIMARY KEY NOT NULL,
api_key_id TEXT NOT NULL,
provider_id TEXT NOT NULL,
priority_adjustment INTEGER NOT NULL DEFAULT 0,
weight_multiplier REAL NOT NULL DEFAULT 1,
is_enabled INTEGER NOT NULL DEFAULT 1,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (api_key_id, provider_id)
);
CREATE INDEX IF NOT EXISTS api_key_provider_mappings_api_key_id_idx
ON api_key_provider_mappings (api_key_id);
CREATE INDEX IF NOT EXISTS api_key_provider_mappings_provider_id_idx
ON api_key_provider_mappings (provider_id);
CREATE INDEX IF NOT EXISTS idx_apikey_provider_enabled
ON api_key_provider_mappings (api_key_id, is_enabled);
CREATE TABLE IF NOT EXISTS provider_usage_tracking (
id TEXT PRIMARY KEY NOT NULL,
provider_id TEXT NOT NULL,
window_start INTEGER NOT NULL,
window_end INTEGER NOT NULL,
total_requests INTEGER NOT NULL DEFAULT 0,
successful_requests INTEGER NOT NULL DEFAULT 0,
failed_requests INTEGER NOT NULL DEFAULT 0,
avg_response_time_ms REAL NOT NULL DEFAULT 0,
total_response_time_ms REAL NOT NULL DEFAULT 0,
total_cost_usd REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS provider_usage_tracking_provider_id_idx
ON provider_usage_tracking (provider_id);
CREATE INDEX IF NOT EXISTS provider_usage_tracking_window_start_idx
ON provider_usage_tracking (window_start);
CREATE INDEX IF NOT EXISTS idx_provider_window
ON provider_usage_tracking (provider_id, window_start);
CREATE INDEX IF NOT EXISTS idx_window_time
ON provider_usage_tracking (window_start, window_end);
-- The baseline already has partial uniqueness guards for enabled billing
-- configuration. These full indexes cover reads that also inspect disabled rows.
CREATE INDEX IF NOT EXISTS billing_rules_global_model_task_idx
ON billing_rules (global_model_id, task_type, is_enabled);
CREATE INDEX IF NOT EXISTS billing_rules_model_task_idx
ON billing_rules (model_id, task_type, is_enabled);
CREATE INDEX IF NOT EXISTS dimension_collectors_enabled_idx
ON dimension_collectors (api_format, task_type, dimension_name, priority, is_enabled);
ALTER TABLE video_tasks ADD COLUMN converted_request_body TEXT;
ALTER TABLE video_tasks ADD COLUMN max_retries INTEGER NOT NULL DEFAULT 3;
ALTER TABLE video_tasks ADD COLUMN video_urls TEXT;
ALTER TABLE video_tasks ADD COLUMN thumbnail_url TEXT;
ALTER TABLE video_tasks ADD COLUMN video_size_bytes INTEGER;
ALTER TABLE video_tasks ADD COLUMN video_expires_at INTEGER;
ALTER TABLE video_tasks ADD COLUMN stored_video_path TEXT;
ALTER TABLE video_tasks ADD COLUMN storage_provider TEXT;
ALTER TABLE video_tasks ADD COLUMN remixed_from_task_id TEXT;
ALTER TABLE video_tasks ADD COLUMN webhook_url TEXT;
ALTER TABLE video_tasks ADD COLUMN webhook_sent INTEGER NOT NULL DEFAULT 0;
ALTER TABLE video_tasks ADD COLUMN webhook_sent_at INTEGER;
ALTER TABLE video_tasks ADD COLUMN video_duration_seconds REAL;
-- Portable compatibility columns. New canonical HTTP payload writes use the
-- normalized usage_http_audits and usage_body_blobs tables below.
ALTER TABLE "usage" ADD COLUMN input_output_total_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN cache_creation_input_tokens_5m INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN cache_creation_input_tokens_1h INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN input_context_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN input_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN output_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN cache_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN cache_creation_cost_usd_5m REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN cache_creation_cost_usd_1h REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN request_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_input_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_output_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_cache_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_cache_creation_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_cache_creation_cost_usd_5m REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_cache_creation_cost_usd_1h REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_cache_read_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN actual_request_cost_usd REAL NOT NULL DEFAULT 0;
ALTER TABLE "usage" ADD COLUMN rate_multiplier REAL NOT NULL DEFAULT 1;
ALTER TABLE "usage" ADD COLUMN input_price_per_1m REAL;
ALTER TABLE "usage" ADD COLUMN cache_creation_price_per_1m REAL;
ALTER TABLE "usage" ADD COLUMN cache_creation_price_per_1m_5m REAL;
ALTER TABLE "usage" ADD COLUMN cache_creation_price_per_1m_1h REAL;
ALTER TABLE "usage" ADD COLUMN cache_read_price_per_1m REAL;
ALTER TABLE "usage" ADD COLUMN price_per_request REAL;
ALTER TABLE "usage" ADD COLUMN request_headers TEXT;
ALTER TABLE "usage" ADD COLUMN request_body TEXT;
ALTER TABLE "usage" ADD COLUMN provider_request_headers TEXT;
ALTER TABLE "usage" ADD COLUMN provider_request_body TEXT;
ALTER TABLE "usage" ADD COLUMN response_headers TEXT;
ALTER TABLE "usage" ADD COLUMN response_body TEXT;
ALTER TABLE "usage" ADD COLUMN client_response_headers TEXT;
ALTER TABLE "usage" ADD COLUMN client_response_body TEXT;
ALTER TABLE "usage" ADD COLUMN request_body_compressed BLOB;
ALTER TABLE "usage" ADD COLUMN provider_request_body_compressed BLOB;
ALTER TABLE "usage" ADD COLUMN response_body_compressed BLOB;
ALTER TABLE "usage" ADD COLUMN client_response_body_compressed BLOB;
ALTER TABLE "usage" ADD COLUMN created_at INTEGER;
ALTER TABLE "usage" ADD COLUMN username TEXT;
ALTER TABLE "usage" ADD COLUMN api_key_name TEXT;
CREATE TABLE IF NOT EXISTS usage_body_blobs (
body_ref TEXT PRIMARY KEY NOT NULL,
request_id TEXT NOT NULL,
body_field TEXT NOT NULL,
payload_gzip BLOB NOT NULL,
created_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s', 'now') AS INTEGER)),
updated_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s', 'now') AS INTEGER)),
UNIQUE (request_id, body_field),
FOREIGN KEY (request_id) REFERENCES "usage" (request_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_usage_body_blobs_request_id
ON usage_body_blobs (request_id);
CREATE TABLE IF NOT EXISTS usage_http_audits (
request_id TEXT PRIMARY KEY NOT NULL,
request_headers TEXT,
provider_request_headers TEXT,
response_headers TEXT,
client_response_headers TEXT,
request_body_ref TEXT,
provider_request_body_ref TEXT,
response_body_ref TEXT,
client_response_body_ref TEXT,
request_body_state TEXT,
provider_request_body_state TEXT,
response_body_state TEXT,
client_response_body_state TEXT,
body_capture_mode TEXT NOT NULL DEFAULT 'none',
created_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s', 'now') AS INTEGER)),
updated_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s', 'now') AS INTEGER)),
FOREIGN KEY (request_id) REFERENCES "usage" (request_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_usage_http_audits_updated_at
ON usage_http_audits (updated_at);
-- Billing V3 keeps the immutable pricing/token snapshot separate from the
-- mutable compatibility columns on usage.
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_snapshot_schema_version TEXT;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_snapshot_status TEXT;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN rate_multiplier REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN is_free_tier INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN input_price_per_1m REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN output_price_per_1m REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN cache_creation_price_per_1m REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN cache_read_price_per_1m REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN price_per_request REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN settlement_snapshot_schema_version TEXT;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN settlement_snapshot TEXT;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_dimensions TEXT;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_input_tokens INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_effective_input_tokens INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_output_tokens INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_cache_creation_tokens INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_cache_creation_5m_tokens INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_cache_creation_1h_tokens INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_cache_read_tokens INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_total_input_context INTEGER;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_cache_creation_cost_usd REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_cache_read_cost_usd REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_total_cost_usd REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_actual_total_cost_usd REAL;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_pricing_source TEXT;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_rule_id TEXT;
ALTER TABLE usage_settlement_snapshots
ADD COLUMN billing_rule_version TEXT;
CREATE INDEX IF NOT EXISTS ix_usage_settlement_snapshots_schema_version
ON usage_settlement_snapshots (settlement_snapshot_schema_version);
CREATE INDEX IF NOT EXISTS ix_usage_settlement_snapshots_pricing_source
ON usage_settlement_snapshots (billing_pricing_source);
CREATE TABLE IF NOT EXISTS stats_summary (
id TEXT PRIMARY KEY NOT NULL,
cutoff_date INTEGER NOT NULL,
all_time_requests INTEGER NOT NULL DEFAULT 0,
all_time_success_requests INTEGER NOT NULL DEFAULT 0,
all_time_error_requests INTEGER NOT NULL DEFAULT 0,
all_time_input_tokens INTEGER NOT NULL DEFAULT 0,
all_time_output_tokens INTEGER NOT NULL DEFAULT 0,
all_time_cache_creation_tokens INTEGER NOT NULL DEFAULT 0,
all_time_cache_read_tokens INTEGER NOT NULL DEFAULT 0,
all_time_cost REAL NOT NULL DEFAULT 0,
all_time_actual_cost REAL NOT NULL DEFAULT 0,
total_users INTEGER NOT NULL DEFAULT 0,
active_users INTEGER NOT NULL DEFAULT 0,
total_api_keys INTEGER NOT NULL DEFAULT 0,
active_api_keys INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS user_model_usage_counts (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
model TEXT NOT NULL,
usage_count INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, model)
);
CREATE INDEX IF NOT EXISTS idx_user_model_usage_user
ON user_model_usage_counts (user_id);
CREATE INDEX IF NOT EXISTS idx_user_model_usage_model
ON user_model_usage_counts (model);
ALTER TABLE stats_daily ADD COLUMN input_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily ADD COLUMN output_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily ADD COLUMN cache_creation_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily ADD COLUMN cache_read_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily ADD COLUMN p50_response_time_ms INTEGER;
ALTER TABLE stats_daily ADD COLUMN p90_response_time_ms INTEGER;
ALTER TABLE stats_daily ADD COLUMN p99_response_time_ms INTEGER;
ALTER TABLE stats_daily ADD COLUMN p50_first_byte_time_ms INTEGER;
ALTER TABLE stats_daily ADD COLUMN p90_first_byte_time_ms INTEGER;
ALTER TABLE stats_daily ADD COLUMN p99_first_byte_time_ms INTEGER;
-- PostgreSQL uses a partial index for this active-row cleanup path. SQLite can
-- preserve the same selectivity and ordering.
CREATE INDEX IF NOT EXISTS idx_usage_stale_pending_created_request
ON "usage" (created_at_unix_ms, request_id)
WHERE status IN ('pending', 'streaming');
CREATE INDEX IF NOT EXISTS idx_provider_api_keys_provider_created_at_desc
ON provider_api_keys (provider_id, created_at DESC, name, id);
CREATE INDEX IF NOT EXISTS idx_provider_api_keys_provider_last_used_at_desc
ON provider_api_keys (provider_id, last_used_at DESC, name, id);
@@ -0,0 +1,447 @@
ALTER TABLE stats_user_daily
ADD COLUMN actual_total_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN response_time_sum_ms REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN response_time_samples INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN effective_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN total_input_context INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN cache_creation_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN cache_read_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN cache_creation_ephemeral_5m_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN cache_creation_ephemeral_1h_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN settled_total_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN settled_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN settled_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN settled_output_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN settled_cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN settled_cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_user_daily
ADD COLUMN settled_first_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_user_daily
ADD COLUMN settled_last_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_hourly_user
ADD COLUMN cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN actual_total_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN response_time_sum_ms REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN response_time_samples INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_total_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_output_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_first_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_hourly_user
ADD COLUMN settled_last_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_daily
ADD COLUMN effective_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN total_input_context INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN response_time_sum_ms REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN response_time_samples INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN cache_creation_ephemeral_5m_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN cache_creation_ephemeral_1h_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN cache_hit_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN cache_hit_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_cache_hit_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_total_input_context INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_cache_creation_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN completed_cache_read_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN settled_total_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN settled_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN settled_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN settled_output_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN settled_cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN settled_cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily
ADD COLUMN settled_first_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_daily
ADD COLUMN settled_last_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_hourly
ADD COLUMN response_time_sum_ms REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN response_time_samples INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN cache_hit_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN cache_hit_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_cache_hit_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_total_input_context INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_cache_creation_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN completed_cache_read_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN settled_total_cost REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN settled_total_requests INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN settled_input_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN settled_output_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN settled_cache_creation_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN settled_cache_read_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly
ADD COLUMN settled_first_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_hourly
ADD COLUMN settled_last_finalized_at_unix_secs INTEGER;
ALTER TABLE stats_daily_model
ADD COLUMN response_time_sum_ms REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_daily_model
ADD COLUMN response_time_samples INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily_model
ADD COLUMN cache_creation_ephemeral_5m_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_daily_model
ADD COLUMN cache_creation_ephemeral_1h_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_model
ADD COLUMN response_time_sum_ms REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_model
ADD COLUMN response_time_samples INTEGER NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user_model
ADD COLUMN response_time_sum_ms REAL NOT NULL DEFAULT 0;
ALTER TABLE stats_hourly_user_model
ADD COLUMN response_time_samples INTEGER NOT NULL DEFAULT 0;
CREATE TABLE IF NOT EXISTS stats_user_summary (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL UNIQUE,
username TEXT,
cutoff_date INTEGER NOT NULL,
all_time_requests INTEGER NOT NULL DEFAULT 0,
all_time_success_requests INTEGER NOT NULL DEFAULT 0,
all_time_error_requests INTEGER NOT NULL DEFAULT 0,
all_time_input_tokens INTEGER NOT NULL DEFAULT 0,
all_time_output_tokens INTEGER NOT NULL DEFAULT 0,
all_time_cache_creation_tokens INTEGER NOT NULL DEFAULT 0,
all_time_cache_read_tokens INTEGER NOT NULL DEFAULT 0,
all_time_cost REAL NOT NULL DEFAULT 0,
all_time_actual_cost REAL NOT NULL DEFAULT 0,
active_days INTEGER NOT NULL DEFAULT 0,
first_active_date INTEGER,
last_active_date INTEGER,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX idx_stats_user_summary_cutoff_date ON stats_user_summary (cutoff_date);
CREATE TABLE IF NOT EXISTS stats_user_daily_model (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
model TEXT NOT NULL,
total_requests INTEGER NOT NULL DEFAULT 0,
success_requests INTEGER NOT NULL DEFAULT 0,
input_tokens INTEGER NOT NULL DEFAULT 0,
effective_input_tokens INTEGER NOT NULL DEFAULT 0,
output_tokens INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
total_input_context INTEGER NOT NULL DEFAULT 0,
cache_creation_tokens INTEGER NOT NULL DEFAULT 0,
cache_creation_ephemeral_5m_tokens INTEGER NOT NULL DEFAULT 0,
cache_creation_ephemeral_1h_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
total_cost REAL NOT NULL DEFAULT 0,
actual_total_cost REAL NOT NULL DEFAULT 0,
response_time_sum_ms REAL NOT NULL DEFAULT 0,
response_time_samples INTEGER NOT NULL DEFAULT 0,
successful_response_time_sum_ms REAL NOT NULL DEFAULT 0,
successful_response_time_samples INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date", model)
);
CREATE INDEX idx_stats_user_daily_model_date ON stats_user_daily_model ("date");
CREATE INDEX idx_stats_user_daily_model_user_id ON stats_user_daily_model (user_id);
CREATE TABLE IF NOT EXISTS stats_user_daily_provider (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
provider_name TEXT NOT NULL,
total_requests INTEGER NOT NULL DEFAULT 0,
success_requests INTEGER NOT NULL DEFAULT 0,
input_tokens INTEGER NOT NULL DEFAULT 0,
effective_input_tokens INTEGER NOT NULL DEFAULT 0,
output_tokens INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
total_input_context INTEGER NOT NULL DEFAULT 0,
cache_creation_tokens INTEGER NOT NULL DEFAULT 0,
cache_creation_ephemeral_5m_tokens INTEGER NOT NULL DEFAULT 0,
cache_creation_ephemeral_1h_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
total_cost REAL NOT NULL DEFAULT 0,
actual_total_cost REAL NOT NULL DEFAULT 0,
response_time_sum_ms REAL NOT NULL DEFAULT 0,
response_time_samples INTEGER NOT NULL DEFAULT 0,
successful_response_time_sum_ms REAL NOT NULL DEFAULT 0,
successful_response_time_samples INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date", provider_name)
);
CREATE INDEX idx_stats_user_daily_provider_date ON stats_user_daily_provider ("date");
CREATE INDEX idx_stats_user_daily_provider_user_id ON stats_user_daily_provider (user_id);
CREATE TABLE IF NOT EXISTS stats_user_daily_api_format (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
api_format TEXT NOT NULL,
total_requests INTEGER NOT NULL DEFAULT 0,
success_requests INTEGER NOT NULL DEFAULT 0,
input_tokens INTEGER NOT NULL DEFAULT 0,
effective_input_tokens INTEGER NOT NULL DEFAULT 0,
output_tokens INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
total_input_context INTEGER NOT NULL DEFAULT 0,
cache_creation_tokens INTEGER NOT NULL DEFAULT 0,
cache_creation_ephemeral_5m_tokens INTEGER NOT NULL DEFAULT 0,
cache_creation_ephemeral_1h_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
total_cost REAL NOT NULL DEFAULT 0,
actual_total_cost REAL NOT NULL DEFAULT 0,
response_time_sum_ms REAL NOT NULL DEFAULT 0,
response_time_samples INTEGER NOT NULL DEFAULT 0,
successful_response_time_sum_ms REAL NOT NULL DEFAULT 0,
successful_response_time_samples INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date", api_format)
);
CREATE INDEX idx_stats_user_daily_api_format_date ON stats_user_daily_api_format ("date");
CREATE INDEX idx_stats_user_daily_api_format_user_id ON stats_user_daily_api_format (user_id);
CREATE TABLE IF NOT EXISTS stats_daily_model_provider (
id TEXT PRIMARY KEY NOT NULL,
"date" INTEGER NOT NULL,
model TEXT NOT NULL,
provider_name TEXT NOT NULL,
total_requests INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
total_cost REAL NOT NULL DEFAULT 0,
response_time_sum_ms REAL NOT NULL DEFAULT 0,
response_time_samples INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE ("date", model, provider_name)
);
CREATE INDEX idx_stats_daily_model_provider_date ON stats_daily_model_provider ("date");
CREATE TABLE IF NOT EXISTS stats_user_daily_model_provider (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
model TEXT NOT NULL,
provider_name TEXT NOT NULL,
total_requests INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
total_cost REAL NOT NULL DEFAULT 0,
response_time_sum_ms REAL NOT NULL DEFAULT 0,
response_time_samples INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date", model, provider_name)
);
CREATE INDEX idx_stats_user_daily_model_provider_date
ON stats_user_daily_model_provider ("date");
CREATE INDEX idx_stats_user_daily_model_provider_user_date
ON stats_user_daily_model_provider (user_id, "date");
CREATE TABLE IF NOT EXISTS stats_daily_cost_savings (
id TEXT PRIMARY KEY NOT NULL,
"date" INTEGER NOT NULL UNIQUE,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS stats_daily_cost_savings_provider (
id TEXT PRIMARY KEY NOT NULL,
"date" INTEGER NOT NULL,
provider_name TEXT NOT NULL,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE ("date", provider_name)
);
CREATE INDEX idx_stats_daily_cost_savings_provider_date
ON stats_daily_cost_savings_provider ("date");
CREATE TABLE IF NOT EXISTS stats_daily_cost_savings_model (
id TEXT PRIMARY KEY NOT NULL,
"date" INTEGER NOT NULL,
model TEXT NOT NULL,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE ("date", model)
);
CREATE INDEX idx_stats_daily_cost_savings_model_date
ON stats_daily_cost_savings_model ("date");
CREATE TABLE IF NOT EXISTS stats_daily_cost_savings_model_provider (
id TEXT PRIMARY KEY NOT NULL,
"date" INTEGER NOT NULL,
model TEXT NOT NULL,
provider_name TEXT NOT NULL,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE ("date", model, provider_name)
);
CREATE INDEX idx_stats_daily_cost_savings_model_provider_date
ON stats_daily_cost_savings_model_provider ("date");
CREATE TABLE IF NOT EXISTS stats_user_daily_cost_savings (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date")
);
CREATE INDEX idx_stats_user_daily_cost_savings_date
ON stats_user_daily_cost_savings ("date");
CREATE TABLE IF NOT EXISTS stats_user_daily_cost_savings_provider (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
provider_name TEXT NOT NULL,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date", provider_name)
);
CREATE INDEX idx_stats_user_daily_cost_savings_provider_date
ON stats_user_daily_cost_savings_provider ("date");
CREATE TABLE IF NOT EXISTS stats_user_daily_cost_savings_model (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
model TEXT NOT NULL,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date", model)
);
CREATE INDEX idx_stats_user_daily_cost_savings_model_date
ON stats_user_daily_cost_savings_model ("date");
CREATE TABLE IF NOT EXISTS stats_user_daily_cost_savings_model_provider (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
username TEXT,
"date" INTEGER NOT NULL,
model TEXT NOT NULL,
provider_name TEXT NOT NULL,
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
cache_read_cost REAL NOT NULL DEFAULT 0,
cache_creation_cost REAL NOT NULL DEFAULT 0,
estimated_full_cost REAL NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (user_id, "date", model, provider_name)
);
CREATE INDEX idx_stats_user_daily_cost_savings_model_provider_date
ON stats_user_daily_cost_savings_model_provider ("date");
-- Existing completed buckets predate the enriched dimensions above. Preserve the rows for
-- reads, but make the bounded aggregation worker replay every historical bucket.
UPDATE stats_hourly SET is_complete = 0 WHERE is_complete <> 0;
UPDATE stats_daily SET is_complete = 0 WHERE is_complete <> 0;
@@ -0,0 +1,70 @@
CREATE TABLE IF NOT EXISTS usage_routing_snapshots (
request_id TEXT PRIMARY KEY NOT NULL,
candidate_id TEXT,
candidate_index INTEGER,
key_name TEXT,
planner_kind TEXT,
route_family TEXT,
route_kind TEXT,
execution_path TEXT,
local_execution_runtime_miss_reason TEXT,
selected_provider_id TEXT,
selected_endpoint_id TEXT,
selected_provider_api_key_id TEXT,
has_format_conversion INTEGER,
created_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s', 'now') AS INTEGER)),
updated_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s', 'now') AS INTEGER)),
FOREIGN KEY (request_id) REFERENCES "usage" (request_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_usage_routing_snapshots_route_family_kind
ON usage_routing_snapshots (route_family, route_kind);
CREATE INDEX IF NOT EXISTS ix_usage_routing_snapshots_candidate_id
ON usage_routing_snapshots (candidate_id);
INSERT INTO usage_routing_snapshots (
request_id,
candidate_id,
candidate_index,
key_name,
planner_kind,
route_family,
route_kind,
execution_path,
local_execution_runtime_miss_reason,
selected_provider_id,
selected_endpoint_id,
selected_provider_api_key_id,
has_format_conversion,
created_at,
updated_at
)
SELECT
request_id,
candidate_id,
candidate_index,
key_name,
planner_kind,
route_family,
route_kind,
execution_path,
local_execution_runtime_miss_reason,
provider_id,
provider_endpoint_id,
provider_api_key_id,
has_format_conversion,
COALESCE(NULLIF(created_at_unix_ms, 0), NULLIF(updated_at_unix_secs, 0), CAST(strftime('%s', 'now') AS INTEGER)),
COALESCE(NULLIF(updated_at_unix_secs, 0), NULLIF(created_at_unix_ms, 0), CAST(strftime('%s', 'now') AS INTEGER))
FROM "usage"
WHERE candidate_id IS NOT NULL
OR candidate_index IS NOT NULL
OR key_name IS NOT NULL
OR planner_kind IS NOT NULL
OR route_family IS NOT NULL
OR route_kind IS NOT NULL
OR execution_path IS NOT NULL
OR local_execution_runtime_miss_reason IS NOT NULL
OR provider_id IS NOT NULL
OR provider_endpoint_id IS NOT NULL
OR provider_api_key_id IS NOT NULL
OR has_format_conversion <> 0;
@@ -0,0 +1,821 @@
-- Complete the legacy import repair for every INTEGER-affinity timestamp column
-- that existed before the 20260725 parity migrations. Invalid values are left
-- untouched so the guard at the end fails the migration instead of coercing data.
UPDATE "announcement_reads"
SET "read_at" = CASE
WHEN typeof("read_at") = 'text' AND strftime('%s', trim("read_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("read_at")) AS INTEGER)
ELSE "read_at"
END
WHERE (typeof("read_at") = 'text' AND strftime('%s', trim("read_at")) IS NOT NULL);
UPDATE "audit_logs"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL);
UPDATE "background_task_events"
SET "created_at_unix_secs" = CASE
WHEN typeof("created_at_unix_secs") = 'text' AND strftime('%s', trim("created_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at_unix_secs")) AS INTEGER)
ELSE "created_at_unix_secs"
END
WHERE (typeof("created_at_unix_secs") = 'text' AND strftime('%s', trim("created_at_unix_secs")) IS NOT NULL);
UPDATE "background_task_runs"
SET "created_at_unix_secs" = CASE
WHEN typeof("created_at_unix_secs") = 'text' AND strftime('%s', trim("created_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at_unix_secs")) AS INTEGER)
ELSE "created_at_unix_secs"
END,
"finished_at_unix_secs" = CASE
WHEN typeof("finished_at_unix_secs") = 'text' AND strftime('%s', trim("finished_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("finished_at_unix_secs")) AS INTEGER)
ELSE "finished_at_unix_secs"
END,
"started_at_unix_secs" = CASE
WHEN typeof("started_at_unix_secs") = 'text' AND strftime('%s', trim("started_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("started_at_unix_secs")) AS INTEGER)
ELSE "started_at_unix_secs"
END,
"updated_at_unix_secs" = CASE
WHEN typeof("updated_at_unix_secs") = 'text' AND strftime('%s', trim("updated_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at_unix_secs")) AS INTEGER)
ELSE "updated_at_unix_secs"
END
WHERE (typeof("created_at_unix_secs") = 'text' AND strftime('%s', trim("created_at_unix_secs")) IS NOT NULL)
OR (typeof("finished_at_unix_secs") = 'text' AND strftime('%s', trim("finished_at_unix_secs")) IS NOT NULL)
OR (typeof("started_at_unix_secs") = 'text' AND strftime('%s', trim("started_at_unix_secs")) IS NOT NULL)
OR (typeof("updated_at_unix_secs") = 'text' AND strftime('%s', trim("updated_at_unix_secs")) IS NOT NULL);
UPDATE "entitlement_usage_ledgers"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL);
UPDATE "gemini_file_mappings"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"expires_at" = CASE
WHEN typeof("expires_at") = 'text' AND strftime('%s', trim("expires_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("expires_at")) AS INTEGER)
ELSE "expires_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("expires_at") = 'text' AND strftime('%s', trim("expires_at")) IS NOT NULL);
UPDATE "ldap_configs"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "pool_member_scores"
SET "last_failure_at" = CASE
WHEN typeof("last_failure_at") = 'text' AND strftime('%s', trim("last_failure_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_failure_at")) AS INTEGER)
ELSE "last_failure_at"
END,
"last_probe_attempt_at" = CASE
WHEN typeof("last_probe_attempt_at") = 'text' AND strftime('%s', trim("last_probe_attempt_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_probe_attempt_at")) AS INTEGER)
ELSE "last_probe_attempt_at"
END,
"last_probe_failure_at" = CASE
WHEN typeof("last_probe_failure_at") = 'text' AND strftime('%s', trim("last_probe_failure_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_probe_failure_at")) AS INTEGER)
ELSE "last_probe_failure_at"
END,
"last_probe_success_at" = CASE
WHEN typeof("last_probe_success_at") = 'text' AND strftime('%s', trim("last_probe_success_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_probe_success_at")) AS INTEGER)
ELSE "last_probe_success_at"
END,
"last_ranked_at" = CASE
WHEN typeof("last_ranked_at") = 'text' AND strftime('%s', trim("last_ranked_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_ranked_at")) AS INTEGER)
ELSE "last_ranked_at"
END,
"last_scheduled_at" = CASE
WHEN typeof("last_scheduled_at") = 'text' AND strftime('%s', trim("last_scheduled_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_scheduled_at")) AS INTEGER)
ELSE "last_scheduled_at"
END,
"last_success_at" = CASE
WHEN typeof("last_success_at") = 'text' AND strftime('%s', trim("last_success_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_success_at")) AS INTEGER)
ELSE "last_success_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("last_failure_at") = 'text' AND strftime('%s', trim("last_failure_at")) IS NOT NULL)
OR (typeof("last_probe_attempt_at") = 'text' AND strftime('%s', trim("last_probe_attempt_at")) IS NOT NULL)
OR (typeof("last_probe_failure_at") = 'text' AND strftime('%s', trim("last_probe_failure_at")) IS NOT NULL)
OR (typeof("last_probe_success_at") = 'text' AND strftime('%s', trim("last_probe_success_at")) IS NOT NULL)
OR (typeof("last_ranked_at") = 'text' AND strftime('%s', trim("last_ranked_at")) IS NOT NULL)
OR (typeof("last_scheduled_at") = 'text' AND strftime('%s', trim("last_scheduled_at")) IS NOT NULL)
OR (typeof("last_success_at") = 'text' AND strftime('%s', trim("last_success_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "proxy_node_events"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL);
UPDATE "proxy_node_metrics_1h"
SET "bucket_start_unix_secs" = CASE
WHEN typeof("bucket_start_unix_secs") = 'text' AND strftime('%s', trim("bucket_start_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("bucket_start_unix_secs")) AS INTEGER)
ELSE "bucket_start_unix_secs"
END
WHERE (typeof("bucket_start_unix_secs") = 'text' AND strftime('%s', trim("bucket_start_unix_secs")) IS NOT NULL);
UPDATE "proxy_node_metrics_1m"
SET "bucket_start_unix_secs" = CASE
WHEN typeof("bucket_start_unix_secs") = 'text' AND strftime('%s', trim("bucket_start_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("bucket_start_unix_secs")) AS INTEGER)
ELSE "bucket_start_unix_secs"
END
WHERE (typeof("bucket_start_unix_secs") = 'text' AND strftime('%s', trim("bucket_start_unix_secs")) IS NOT NULL);
UPDATE "referral_rewards"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "request_candidates"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"finished_at" = CASE
WHEN typeof("finished_at") = 'text' AND strftime('%s', trim("finished_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("finished_at")) AS INTEGER)
ELSE "finished_at"
END,
"started_at" = CASE
WHEN typeof("started_at") = 'text' AND strftime('%s', trim("started_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("started_at")) AS INTEGER)
ELSE "started_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("finished_at") = 'text' AND strftime('%s', trim("finished_at")) IS NOT NULL)
OR (typeof("started_at") = 'text' AND strftime('%s', trim("started_at")) IS NOT NULL);
UPDATE "routing_group_bindings"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "routing_group_versions"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL);
UPDATE "routing_groups"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"published_at" = CASE
WHEN typeof("published_at") = 'text' AND strftime('%s', trim("published_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("published_at")) AS INTEGER)
ELSE "published_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("published_at") = 'text' AND strftime('%s', trim("published_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_daily_api_key"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"date" = CASE
WHEN typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL
THEN CAST(strftime('%s', trim("date")) AS INTEGER)
ELSE "date"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_daily_error"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"date" = CASE
WHEN typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL
THEN CAST(strftime('%s', trim("date")) AS INTEGER)
ELSE "date"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_daily_model"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"date" = CASE
WHEN typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL
THEN CAST(strftime('%s', trim("date")) AS INTEGER)
ELSE "date"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_daily_provider"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"date" = CASE
WHEN typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL
THEN CAST(strftime('%s', trim("date")) AS INTEGER)
ELSE "date"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_daily"
SET "aggregated_at" = CASE
WHEN typeof("aggregated_at") = 'text' AND strftime('%s', trim("aggregated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("aggregated_at")) AS INTEGER)
ELSE "aggregated_at"
END,
"created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"date" = CASE
WHEN typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL
THEN CAST(strftime('%s', trim("date")) AS INTEGER)
ELSE "date"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("aggregated_at") = 'text' AND strftime('%s', trim("aggregated_at")) IS NOT NULL)
OR (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_hourly_model"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"hour_utc" = CASE
WHEN typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL
THEN CAST(strftime('%s', trim("hour_utc")) AS INTEGER)
ELSE "hour_utc"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_hourly_provider"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"hour_utc" = CASE
WHEN typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL
THEN CAST(strftime('%s', trim("hour_utc")) AS INTEGER)
ELSE "hour_utc"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_hourly_user_model"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"hour_utc" = CASE
WHEN typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL
THEN CAST(strftime('%s', trim("hour_utc")) AS INTEGER)
ELSE "hour_utc"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_hourly_user"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"hour_utc" = CASE
WHEN typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL
THEN CAST(strftime('%s', trim("hour_utc")) AS INTEGER)
ELSE "hour_utc"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_hourly"
SET "aggregated_at" = CASE
WHEN typeof("aggregated_at") = 'text' AND strftime('%s', trim("aggregated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("aggregated_at")) AS INTEGER)
ELSE "aggregated_at"
END,
"created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"hour_utc" = CASE
WHEN typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL
THEN CAST(strftime('%s', trim("hour_utc")) AS INTEGER)
ELSE "hour_utc"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("aggregated_at") = 'text' AND strftime('%s', trim("aggregated_at")) IS NOT NULL)
OR (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("hour_utc") = 'text' AND strftime('%s', trim("hour_utc")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "stats_user_daily"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"date" = CASE
WHEN typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL
THEN CAST(strftime('%s', trim("date")) AS INTEGER)
ELSE "date"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("date") = 'text' AND strftime('%s', trim("date")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "usage_counter_deltas"
SET "candidate_last_used_at_unix_secs" = CASE
WHEN typeof("candidate_last_used_at_unix_secs") = 'text' AND strftime('%s', trim("candidate_last_used_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("candidate_last_used_at_unix_secs")) AS INTEGER)
ELSE "candidate_last_used_at_unix_secs"
END,
"created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"last_used_at_unix_secs" = CASE
WHEN typeof("last_used_at_unix_secs") = 'text' AND strftime('%s', trim("last_used_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_used_at_unix_secs")) AS INTEGER)
ELSE "last_used_at_unix_secs"
END,
"processed_at" = CASE
WHEN typeof("processed_at") = 'text' AND strftime('%s', trim("processed_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("processed_at")) AS INTEGER)
ELSE "processed_at"
END,
"removed_last_used_at_unix_secs" = CASE
WHEN typeof("removed_last_used_at_unix_secs") = 'text' AND strftime('%s', trim("removed_last_used_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("removed_last_used_at_unix_secs")) AS INTEGER)
ELSE "removed_last_used_at_unix_secs"
END,
"usage_created_at_unix_secs" = CASE
WHEN typeof("usage_created_at_unix_secs") = 'text' AND strftime('%s', trim("usage_created_at_unix_secs")) IS NOT NULL
THEN CAST(strftime('%s', trim("usage_created_at_unix_secs")) AS INTEGER)
ELSE "usage_created_at_unix_secs"
END
WHERE (typeof("candidate_last_used_at_unix_secs") = 'text' AND strftime('%s', trim("candidate_last_used_at_unix_secs")) IS NOT NULL)
OR (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("last_used_at_unix_secs") = 'text' AND strftime('%s', trim("last_used_at_unix_secs")) IS NOT NULL)
OR (typeof("processed_at") = 'text' AND strftime('%s', trim("processed_at")) IS NOT NULL)
OR (typeof("removed_last_used_at_unix_secs") = 'text' AND strftime('%s', trim("removed_last_used_at_unix_secs")) IS NOT NULL)
OR (typeof("usage_created_at_unix_secs") = 'text' AND strftime('%s', trim("usage_created_at_unix_secs")) IS NOT NULL);
UPDATE "user_invite_codes"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "user_preferences"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "user_referrals"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"first_paid_at" = CASE
WHEN typeof("first_paid_at") = 'text' AND strftime('%s', trim("first_paid_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("first_paid_at")) AS INTEGER)
ELSE "first_paid_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("first_paid_at") = 'text' AND strftime('%s', trim("first_paid_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
UPDATE "user_sessions"
SET "created_at" = CASE
WHEN typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("created_at")) AS INTEGER)
ELSE "created_at"
END,
"expires_at" = CASE
WHEN typeof("expires_at") = 'text' AND strftime('%s', trim("expires_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("expires_at")) AS INTEGER)
ELSE "expires_at"
END,
"last_seen_at" = CASE
WHEN typeof("last_seen_at") = 'text' AND strftime('%s', trim("last_seen_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("last_seen_at")) AS INTEGER)
ELSE "last_seen_at"
END,
"revoked_at" = CASE
WHEN typeof("revoked_at") = 'text' AND strftime('%s', trim("revoked_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("revoked_at")) AS INTEGER)
ELSE "revoked_at"
END,
"rotated_at" = CASE
WHEN typeof("rotated_at") = 'text' AND strftime('%s', trim("rotated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("rotated_at")) AS INTEGER)
ELSE "rotated_at"
END,
"updated_at" = CASE
WHEN typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL
THEN CAST(strftime('%s', trim("updated_at")) AS INTEGER)
ELSE "updated_at"
END
WHERE (typeof("created_at") = 'text' AND strftime('%s', trim("created_at")) IS NOT NULL)
OR (typeof("expires_at") = 'text' AND strftime('%s', trim("expires_at")) IS NOT NULL)
OR (typeof("last_seen_at") = 'text' AND strftime('%s', trim("last_seen_at")) IS NOT NULL)
OR (typeof("revoked_at") = 'text' AND strftime('%s', trim("revoked_at")) IS NOT NULL)
OR (typeof("rotated_at") = 'text' AND strftime('%s', trim("rotated_at")) IS NOT NULL)
OR (typeof("updated_at") = 'text' AND strftime('%s', trim("updated_at")) IS NOT NULL);
DROP TABLE IF EXISTS temp._aether_remaining_timestamp_storage_guard;
CREATE TEMP TABLE _aether_remaining_timestamp_storage_guard (
invalid_count INTEGER NOT NULL CHECK (invalid_count = 0)
);
INSERT INTO _aether_remaining_timestamp_storage_guard (invalid_count)
SELECT
EXISTS (
SELECT 1
FROM "announcement_reads"
WHERE ("read_at" IS NOT NULL AND typeof("read_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "audit_logs"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "background_task_events"
WHERE ("created_at_unix_secs" IS NOT NULL AND typeof("created_at_unix_secs") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "background_task_runs"
WHERE ("created_at_unix_secs" IS NOT NULL AND typeof("created_at_unix_secs") <> 'integer')
OR ("finished_at_unix_secs" IS NOT NULL AND typeof("finished_at_unix_secs") <> 'integer')
OR ("started_at_unix_secs" IS NOT NULL AND typeof("started_at_unix_secs") <> 'integer')
OR ("updated_at_unix_secs" IS NOT NULL AND typeof("updated_at_unix_secs") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "entitlement_usage_ledgers"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "gemini_file_mappings"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "ldap_configs"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "pool_member_scores"
WHERE ("last_failure_at" IS NOT NULL AND typeof("last_failure_at") <> 'integer')
OR ("last_probe_attempt_at" IS NOT NULL AND typeof("last_probe_attempt_at") <> 'integer')
OR ("last_probe_failure_at" IS NOT NULL AND typeof("last_probe_failure_at") <> 'integer')
OR ("last_probe_success_at" IS NOT NULL AND typeof("last_probe_success_at") <> 'integer')
OR ("last_ranked_at" IS NOT NULL AND typeof("last_ranked_at") <> 'integer')
OR ("last_scheduled_at" IS NOT NULL AND typeof("last_scheduled_at") <> 'integer')
OR ("last_success_at" IS NOT NULL AND typeof("last_success_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "proxy_node_events"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "proxy_node_metrics_1h"
WHERE ("bucket_start_unix_secs" IS NOT NULL AND typeof("bucket_start_unix_secs") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "proxy_node_metrics_1m"
WHERE ("bucket_start_unix_secs" IS NOT NULL AND typeof("bucket_start_unix_secs") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "referral_rewards"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "request_candidates"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("finished_at" IS NOT NULL AND typeof("finished_at") <> 'integer')
OR ("started_at" IS NOT NULL AND typeof("started_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "routing_group_bindings"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "routing_group_versions"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "routing_groups"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("published_at" IS NOT NULL AND typeof("published_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_daily_api_key"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("date" IS NOT NULL AND typeof("date") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_daily_error"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("date" IS NOT NULL AND typeof("date") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_daily_model"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("date" IS NOT NULL AND typeof("date") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_daily_provider"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("date" IS NOT NULL AND typeof("date") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_daily"
WHERE ("aggregated_at" IS NOT NULL AND typeof("aggregated_at") <> 'integer')
OR ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("date" IS NOT NULL AND typeof("date") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_hourly_model"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("hour_utc" IS NOT NULL AND typeof("hour_utc") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_hourly_provider"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("hour_utc" IS NOT NULL AND typeof("hour_utc") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_hourly_user_model"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("hour_utc" IS NOT NULL AND typeof("hour_utc") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_hourly_user"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("hour_utc" IS NOT NULL AND typeof("hour_utc") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_hourly"
WHERE ("aggregated_at" IS NOT NULL AND typeof("aggregated_at") <> 'integer')
OR ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("hour_utc" IS NOT NULL AND typeof("hour_utc") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "stats_user_daily"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("date" IS NOT NULL AND typeof("date") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "usage_counter_deltas"
WHERE ("candidate_last_used_at_unix_secs" IS NOT NULL AND typeof("candidate_last_used_at_unix_secs") <> 'integer')
OR ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("last_used_at_unix_secs" IS NOT NULL AND typeof("last_used_at_unix_secs") <> 'integer')
OR ("processed_at" IS NOT NULL AND typeof("processed_at") <> 'integer')
OR ("removed_last_used_at_unix_secs" IS NOT NULL AND typeof("removed_last_used_at_unix_secs") <> 'integer')
OR ("usage_created_at_unix_secs" IS NOT NULL AND typeof("usage_created_at_unix_secs") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "user_invite_codes"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "user_preferences"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "user_referrals"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("first_paid_at" IS NOT NULL AND typeof("first_paid_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
)
+ EXISTS (
SELECT 1
FROM "user_sessions"
WHERE ("created_at" IS NOT NULL AND typeof("created_at") <> 'integer')
OR ("expires_at" IS NOT NULL AND typeof("expires_at") <> 'integer')
OR ("last_seen_at" IS NOT NULL AND typeof("last_seen_at") <> 'integer')
OR ("revoked_at" IS NOT NULL AND typeof("revoked_at") <> 'integer')
OR ("rotated_at" IS NOT NULL AND typeof("rotated_at") <> 'integer')
OR ("updated_at" IS NOT NULL AND typeof("updated_at") <> 'integer')
);
DROP TABLE temp._aether_remaining_timestamp_storage_guard;