feat(db): generate schema artifacts and align sqlite baseline

This commit is contained in:
ciat-777
2026-03-14 23:04:33 +08:00
parent 5bc5fb7039
commit 6d389cb3af
14 changed files with 3216 additions and 10 deletions
@@ -0,0 +1,57 @@
CREATE TABLE IF NOT EXISTS `account_tokens` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `account_id` INT NOT NULL, `name` TEXT NOT NULL, `token` TEXT NOT NULL, `source` TEXT DEFAULT 'manual', `enabled` BOOLEAN DEFAULT true, `is_default` BOOLEAN DEFAULT false, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'), `token_group` TEXT, FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS `accounts` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `site_id` INT NOT NULL, `username` TEXT, `access_token` TEXT NOT NULL, `api_token` TEXT, `balance` DOUBLE DEFAULT 0, `balance_used` DOUBLE DEFAULT 0, `quota` DOUBLE DEFAULT 0, `unit_cost` DOUBLE, `value_score` DOUBLE DEFAULT 0, `status` TEXT DEFAULT 'active', `checkin_enabled` BOOLEAN DEFAULT true, `last_checkin_at` TEXT, `last_balance_refresh` TEXT, `extra_config` TEXT, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'), `is_pinned` BOOLEAN DEFAULT false, `sort_order` INT DEFAULT 0, FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS `checkin_logs` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `account_id` INT NOT NULL, `status` TEXT NOT NULL, `message` TEXT, `reward` TEXT, `created_at` TEXT DEFAULT datetime('now'), FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS `downstream_api_keys` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` TEXT NOT NULL, `key` TEXT NOT NULL, `description` TEXT, `enabled` BOOLEAN DEFAULT true, `expires_at` TEXT, `max_cost` DOUBLE, `used_cost` DOUBLE DEFAULT 0, `max_requests` INT, `used_requests` INT DEFAULT 0, `supported_models` TEXT, `allowed_route_ids` TEXT, `site_weight_multipliers` TEXT, `last_used_at` TEXT, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS `events` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `type` TEXT NOT NULL, `title` TEXT NOT NULL, `message` TEXT, `level` TEXT NOT NULL DEFAULT 'info', `read` BOOLEAN DEFAULT false, `related_id` INT, `related_type` TEXT, `created_at` TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS `model_availability` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `account_id` INT NOT NULL, `model_name` TEXT NOT NULL, `available` BOOLEAN, `latency_ms` INT, `checked_at` TEXT DEFAULT datetime('now'), FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS `proxy_files` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `public_id` TEXT NOT NULL, `owner_type` TEXT NOT NULL, `owner_id` TEXT NOT NULL, `filename` TEXT NOT NULL, `mime_type` TEXT NOT NULL, `purpose` TEXT, `byte_size` INT NOT NULL, `sha256` TEXT NOT NULL, `content_base64` TEXT NOT NULL, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'), `deleted_at` TEXT);
CREATE TABLE IF NOT EXISTS `proxy_logs` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `route_id` INT, `channel_id` INT, `account_id` INT, `model_requested` TEXT, `model_actual` TEXT, `status` TEXT, `http_status` INT, `latency_ms` INT, `prompt_tokens` INT, `completion_tokens` INT, `total_tokens` INT, `estimated_cost` DOUBLE, `error_message` TEXT, `retry_count` INT DEFAULT 0, `created_at` TEXT DEFAULT datetime('now'), `billing_details` TEXT);
CREATE TABLE IF NOT EXISTS `proxy_video_tasks` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `public_id` TEXT NOT NULL, `upstream_video_id` TEXT NOT NULL, `site_url` TEXT NOT NULL, `token_value` TEXT NOT NULL, `requested_model` TEXT, `actual_model` TEXT, `channel_id` INT, `account_id` INT, `status_snapshot` TEXT, `upstream_response_meta` TEXT, `last_upstream_status` INT, `last_polled_at` TEXT, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS `route_channels` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `route_id` INT NOT NULL, `account_id` INT NOT NULL, `token_id` INT, `source_model` TEXT, `priority` INT DEFAULT 0, `weight` INT DEFAULT 10, `enabled` BOOLEAN DEFAULT true, `manual_override` BOOLEAN DEFAULT false, `success_count` INT DEFAULT 0, `fail_count` INT DEFAULT 0, `total_latency_ms` INT DEFAULT 0, `total_cost` DOUBLE DEFAULT 0, `last_used_at` TEXT, `last_selected_at` TEXT, `last_fail_at` TEXT, `consecutive_fail_count` INT NOT NULL DEFAULT 0, `cooldown_level` INT NOT NULL DEFAULT 0, `cooldown_until` TEXT, FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE, FOREIGN KEY (`route_id`) REFERENCES `token_routes`(`id`) ON DELETE CASCADE, FOREIGN KEY (`token_id`) REFERENCES `account_tokens`(`id`) ON DELETE SET NULL);
CREATE TABLE IF NOT EXISTS `settings` (`key` TEXT NOT NULL PRIMARY KEY, `value` TEXT);
CREATE TABLE IF NOT EXISTS `site_disabled_models` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `site_id` INT NOT NULL, `model_name` TEXT NOT NULL, `created_at` TEXT DEFAULT datetime('now'), FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS `sites` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `platform` TEXT NOT NULL, `status` TEXT NOT NULL DEFAULT 'active', `api_key` TEXT, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'), `is_pinned` BOOLEAN DEFAULT false, `sort_order` INT DEFAULT 0, `proxy_url` TEXT, `use_system_proxy` BOOLEAN DEFAULT false, `custom_headers` TEXT, `external_checkin_url` TEXT, `global_weight` DOUBLE DEFAULT 1);
CREATE TABLE IF NOT EXISTS `token_model_availability` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `token_id` INT NOT NULL, `model_name` TEXT NOT NULL, `available` BOOLEAN, `latency_ms` INT, `checked_at` TEXT DEFAULT datetime('now'), FOREIGN KEY (`token_id`) REFERENCES `account_tokens`(`id`) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS `token_routes` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `model_pattern` TEXT NOT NULL, `model_mapping` TEXT, `enabled` BOOLEAN DEFAULT true, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'), `display_name` TEXT, `display_icon` TEXT, `decision_snapshot` TEXT, `decision_refreshed_at` TEXT, `routing_strategy` TEXT DEFAULT 'weighted');
CREATE UNIQUE INDEX `downstream_api_keys_key_unique` ON `downstream_api_keys` (`key`(191));
CREATE UNIQUE INDEX `model_availability_account_model_unique` ON `model_availability` (`account_id`, `model_name`(191));
CREATE UNIQUE INDEX `proxy_files_public_id_unique` ON `proxy_files` (`public_id`(191));
CREATE UNIQUE INDEX `proxy_video_tasks_public_id_unique` ON `proxy_video_tasks` (`public_id`(191));
CREATE UNIQUE INDEX `site_disabled_models_site_model_unique` ON `site_disabled_models` (`site_id`, `model_name`(191));
CREATE UNIQUE INDEX `token_model_availability_token_model_unique` ON `token_model_availability` (`token_id`, `model_name`(191));
CREATE INDEX `account_tokens_account_enabled_idx` ON `account_tokens` (`account_id`, `enabled`);
CREATE INDEX `account_tokens_account_id_idx` ON `account_tokens` (`account_id`);
CREATE INDEX `account_tokens_enabled_idx` ON `account_tokens` (`enabled`);
CREATE INDEX `accounts_site_id_idx` ON `accounts` (`site_id`);
CREATE INDEX `accounts_site_status_idx` ON `accounts` (`site_id`, `status`(191));
CREATE INDEX `accounts_status_idx` ON `accounts` (`status`(191));
CREATE INDEX `checkin_logs_account_created_at_idx` ON `checkin_logs` (`account_id`, `created_at`(191));
CREATE INDEX `checkin_logs_created_at_idx` ON `checkin_logs` (`created_at`(191));
CREATE INDEX `checkin_logs_status_idx` ON `checkin_logs` (`status`(191));
CREATE INDEX `downstream_api_keys_enabled_idx` ON `downstream_api_keys` (`enabled`);
CREATE INDEX `downstream_api_keys_expires_at_idx` ON `downstream_api_keys` (`expires_at`(191));
CREATE INDEX `downstream_api_keys_name_idx` ON `downstream_api_keys` (`name`(191));
CREATE INDEX `events_created_at_idx` ON `events` (`created_at`(191));
CREATE INDEX `events_read_created_at_idx` ON `events` (`read`, `created_at`(191));
CREATE INDEX `events_type_created_at_idx` ON `events` (`type`(191), `created_at`(191));
CREATE INDEX `model_availability_account_available_idx` ON `model_availability` (`account_id`, `available`);
CREATE INDEX `model_availability_model_name_idx` ON `model_availability` (`model_name`(191));
CREATE INDEX `proxy_files_owner_lookup_idx` ON `proxy_files` (`owner_type`(191), `owner_id`(191), `deleted_at`(191));
CREATE INDEX `proxy_logs_account_created_at_idx` ON `proxy_logs` (`account_id`, `created_at`(191));
CREATE INDEX `proxy_logs_created_at_idx` ON `proxy_logs` (`created_at`(191));
CREATE INDEX `proxy_logs_model_actual_created_at_idx` ON `proxy_logs` (`model_actual`(191), `created_at`(191));
CREATE INDEX `proxy_logs_status_created_at_idx` ON `proxy_logs` (`status`(191), `created_at`(191));
CREATE INDEX `proxy_video_tasks_created_at_idx` ON `proxy_video_tasks` (`created_at`(191));
CREATE INDEX `proxy_video_tasks_upstream_video_id_idx` ON `proxy_video_tasks` (`upstream_video_id`(191));
CREATE INDEX `route_channels_account_id_idx` ON `route_channels` (`account_id`);
CREATE INDEX `route_channels_route_enabled_idx` ON `route_channels` (`route_id`, `enabled`);
CREATE INDEX `route_channels_route_id_idx` ON `route_channels` (`route_id`);
CREATE INDEX `route_channels_route_token_idx` ON `route_channels` (`route_id`, `token_id`);
CREATE INDEX `route_channels_token_id_idx` ON `route_channels` (`token_id`);
CREATE INDEX `site_disabled_models_site_id_idx` ON `site_disabled_models` (`site_id`);
CREATE INDEX `sites_status_idx` ON `sites` (`status`(191));
CREATE INDEX `token_model_availability_available_idx` ON `token_model_availability` (`available`);
CREATE INDEX `token_model_availability_model_name_idx` ON `token_model_availability` (`model_name`(191));
CREATE INDEX `token_model_availability_token_available_idx` ON `token_model_availability` (`token_id`, `available`);
CREATE INDEX `token_routes_enabled_idx` ON `token_routes` (`enabled`);
CREATE INDEX `token_routes_model_pattern_idx` ON `token_routes` (`model_pattern`(191));
+27
View File
@@ -0,0 +1,27 @@
CREATE TABLE IF NOT EXISTS `downstream_api_keys` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` TEXT NOT NULL, `key` TEXT NOT NULL, `description` TEXT, `enabled` BOOLEAN DEFAULT true, `expires_at` TEXT, `max_cost` DOUBLE, `used_cost` DOUBLE DEFAULT 0, `max_requests` INT, `used_requests` INT DEFAULT 0, `supported_models` TEXT, `allowed_route_ids` TEXT, `site_weight_multipliers` TEXT, `last_used_at` TEXT, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS `proxy_files` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `public_id` TEXT NOT NULL, `owner_type` TEXT NOT NULL, `owner_id` TEXT NOT NULL, `filename` TEXT NOT NULL, `mime_type` TEXT NOT NULL, `purpose` TEXT, `byte_size` INT NOT NULL, `sha256` TEXT NOT NULL, `content_base64` TEXT NOT NULL, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'), `deleted_at` TEXT);
CREATE TABLE IF NOT EXISTS `proxy_video_tasks` (`id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY, `public_id` TEXT NOT NULL, `upstream_video_id` TEXT NOT NULL, `site_url` TEXT NOT NULL, `token_value` TEXT NOT NULL, `requested_model` TEXT, `actual_model` TEXT, `channel_id` INT, `account_id` INT, `status_snapshot` TEXT, `upstream_response_meta` TEXT, `last_upstream_status` INT, `last_polled_at` TEXT, `created_at` TEXT DEFAULT datetime('now'), `updated_at` TEXT DEFAULT datetime('now'));
ALTER TABLE `route_channels` ADD COLUMN `source_model` TEXT;
ALTER TABLE `route_channels` ADD COLUMN `last_selected_at` TEXT;
ALTER TABLE `route_channels` ADD COLUMN `consecutive_fail_count` INT NOT NULL DEFAULT 0;
ALTER TABLE `route_channels` ADD COLUMN `cooldown_level` INT NOT NULL DEFAULT 0;
ALTER TABLE `sites` ADD COLUMN `proxy_url` TEXT;
ALTER TABLE `sites` ADD COLUMN `use_system_proxy` BOOLEAN DEFAULT false;
ALTER TABLE `sites` ADD COLUMN `custom_headers` TEXT;
ALTER TABLE `sites` ADD COLUMN `external_checkin_url` TEXT;
ALTER TABLE `sites` ADD COLUMN `global_weight` DOUBLE DEFAULT 1;
ALTER TABLE `token_routes` ADD COLUMN `display_name` TEXT;
ALTER TABLE `token_routes` ADD COLUMN `display_icon` TEXT;
ALTER TABLE `token_routes` ADD COLUMN `decision_snapshot` TEXT;
ALTER TABLE `token_routes` ADD COLUMN `decision_refreshed_at` TEXT;
ALTER TABLE `token_routes` ADD COLUMN `routing_strategy` TEXT DEFAULT 'weighted';
CREATE UNIQUE INDEX `downstream_api_keys_key_unique` ON `downstream_api_keys` (`key`(191));
CREATE UNIQUE INDEX `model_availability_account_model_unique` ON `model_availability` (`account_id`, `model_name`(191));
CREATE UNIQUE INDEX `proxy_files_public_id_unique` ON `proxy_files` (`public_id`(191));
CREATE UNIQUE INDEX `proxy_video_tasks_public_id_unique` ON `proxy_video_tasks` (`public_id`(191));
CREATE INDEX `downstream_api_keys_enabled_idx` ON `downstream_api_keys` (`enabled`);
CREATE INDEX `downstream_api_keys_expires_at_idx` ON `downstream_api_keys` (`expires_at`(191));
CREATE INDEX `downstream_api_keys_name_idx` ON `downstream_api_keys` (`name`(191));
CREATE INDEX `proxy_files_owner_lookup_idx` ON `proxy_files` (`owner_type`(191), `owner_id`(191), `deleted_at`(191));
CREATE INDEX `proxy_video_tasks_created_at_idx` ON `proxy_video_tasks` (`created_at`(191));
CREATE INDEX `proxy_video_tasks_upstream_video_id_idx` ON `proxy_video_tasks` (`upstream_video_id`(191));
@@ -0,0 +1,57 @@
CREATE TABLE IF NOT EXISTS "account_tokens" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "account_id" INTEGER NOT NULL, "name" TEXT NOT NULL, "token" TEXT NOT NULL, "source" TEXT DEFAULT 'manual', "enabled" BOOLEAN DEFAULT true, "is_default" BOOLEAN DEFAULT false, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'), "token_group" TEXT, FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS "accounts" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "site_id" INTEGER NOT NULL, "username" TEXT, "access_token" TEXT NOT NULL, "api_token" TEXT, "balance" DOUBLE PRECISION DEFAULT 0, "balance_used" DOUBLE PRECISION DEFAULT 0, "quota" DOUBLE PRECISION DEFAULT 0, "unit_cost" DOUBLE PRECISION, "value_score" DOUBLE PRECISION DEFAULT 0, "status" TEXT DEFAULT 'active', "checkin_enabled" BOOLEAN DEFAULT true, "last_checkin_at" TEXT, "last_balance_refresh" TEXT, "extra_config" TEXT, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'), "is_pinned" BOOLEAN DEFAULT false, "sort_order" INTEGER DEFAULT 0, FOREIGN KEY ("site_id") REFERENCES "sites"("id") ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS "checkin_logs" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "account_id" INTEGER NOT NULL, "status" TEXT NOT NULL, "message" TEXT, "reward" TEXT, "created_at" TEXT DEFAULT datetime('now'), FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS "downstream_api_keys" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "name" TEXT NOT NULL, "key" TEXT NOT NULL, "description" TEXT, "enabled" BOOLEAN DEFAULT true, "expires_at" TEXT, "max_cost" DOUBLE PRECISION, "used_cost" DOUBLE PRECISION DEFAULT 0, "max_requests" INTEGER, "used_requests" INTEGER DEFAULT 0, "supported_models" TEXT, "allowed_route_ids" TEXT, "site_weight_multipliers" TEXT, "last_used_at" TEXT, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS "events" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "type" TEXT NOT NULL, "title" TEXT NOT NULL, "message" TEXT, "level" TEXT NOT NULL DEFAULT 'info', "read" BOOLEAN DEFAULT false, "related_id" INTEGER, "related_type" TEXT, "created_at" TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS "model_availability" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "account_id" INTEGER NOT NULL, "model_name" TEXT NOT NULL, "available" BOOLEAN, "latency_ms" INTEGER, "checked_at" TEXT DEFAULT datetime('now'), FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS "proxy_files" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "public_id" TEXT NOT NULL, "owner_type" TEXT NOT NULL, "owner_id" TEXT NOT NULL, "filename" TEXT NOT NULL, "mime_type" TEXT NOT NULL, "purpose" TEXT, "byte_size" INTEGER NOT NULL, "sha256" TEXT NOT NULL, "content_base64" TEXT NOT NULL, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'), "deleted_at" TEXT);
CREATE TABLE IF NOT EXISTS "proxy_logs" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "route_id" INTEGER, "channel_id" INTEGER, "account_id" INTEGER, "model_requested" TEXT, "model_actual" TEXT, "status" TEXT, "http_status" INTEGER, "latency_ms" INTEGER, "prompt_tokens" INTEGER, "completion_tokens" INTEGER, "total_tokens" INTEGER, "estimated_cost" DOUBLE PRECISION, "error_message" TEXT, "retry_count" INTEGER DEFAULT 0, "created_at" TEXT DEFAULT datetime('now'), "billing_details" TEXT);
CREATE TABLE IF NOT EXISTS "proxy_video_tasks" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "public_id" TEXT NOT NULL, "upstream_video_id" TEXT NOT NULL, "site_url" TEXT NOT NULL, "token_value" TEXT NOT NULL, "requested_model" TEXT, "actual_model" TEXT, "channel_id" INTEGER, "account_id" INTEGER, "status_snapshot" TEXT, "upstream_response_meta" TEXT, "last_upstream_status" INTEGER, "last_polled_at" TEXT, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS "route_channels" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "route_id" INTEGER NOT NULL, "account_id" INTEGER NOT NULL, "token_id" INTEGER, "source_model" TEXT, "priority" INTEGER DEFAULT 0, "weight" INTEGER DEFAULT 10, "enabled" BOOLEAN DEFAULT true, "manual_override" BOOLEAN DEFAULT false, "success_count" INTEGER DEFAULT 0, "fail_count" INTEGER DEFAULT 0, "total_latency_ms" INTEGER DEFAULT 0, "total_cost" DOUBLE PRECISION DEFAULT 0, "last_used_at" TEXT, "last_selected_at" TEXT, "last_fail_at" TEXT, "consecutive_fail_count" INTEGER NOT NULL DEFAULT 0, "cooldown_level" INTEGER NOT NULL DEFAULT 0, "cooldown_until" TEXT, FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE CASCADE, FOREIGN KEY ("route_id") REFERENCES "token_routes"("id") ON DELETE CASCADE, FOREIGN KEY ("token_id") REFERENCES "account_tokens"("id") ON DELETE SET NULL);
CREATE TABLE IF NOT EXISTS "settings" ("key" TEXT NOT NULL PRIMARY KEY, "value" TEXT);
CREATE TABLE IF NOT EXISTS "site_disabled_models" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "site_id" INTEGER NOT NULL, "model_name" TEXT NOT NULL, "created_at" TEXT DEFAULT datetime('now'), FOREIGN KEY ("site_id") REFERENCES "sites"("id") ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS "sites" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "name" TEXT NOT NULL, "url" TEXT NOT NULL, "platform" TEXT NOT NULL, "status" TEXT NOT NULL DEFAULT 'active', "api_key" TEXT, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'), "is_pinned" BOOLEAN DEFAULT false, "sort_order" INTEGER DEFAULT 0, "proxy_url" TEXT, "use_system_proxy" BOOLEAN DEFAULT false, "custom_headers" TEXT, "external_checkin_url" TEXT, "global_weight" DOUBLE PRECISION DEFAULT 1);
CREATE TABLE IF NOT EXISTS "token_model_availability" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "token_id" INTEGER NOT NULL, "model_name" TEXT NOT NULL, "available" BOOLEAN, "latency_ms" INTEGER, "checked_at" TEXT DEFAULT datetime('now'), FOREIGN KEY ("token_id") REFERENCES "account_tokens"("id") ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS "token_routes" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "model_pattern" TEXT NOT NULL, "model_mapping" TEXT, "enabled" BOOLEAN DEFAULT true, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'), "display_name" TEXT, "display_icon" TEXT, "decision_snapshot" TEXT, "decision_refreshed_at" TEXT, "routing_strategy" TEXT DEFAULT 'weighted');
CREATE UNIQUE INDEX "downstream_api_keys_key_unique" ON "downstream_api_keys" ("key");
CREATE UNIQUE INDEX "model_availability_account_model_unique" ON "model_availability" ("account_id", "model_name");
CREATE UNIQUE INDEX "proxy_files_public_id_unique" ON "proxy_files" ("public_id");
CREATE UNIQUE INDEX "proxy_video_tasks_public_id_unique" ON "proxy_video_tasks" ("public_id");
CREATE UNIQUE INDEX "site_disabled_models_site_model_unique" ON "site_disabled_models" ("site_id", "model_name");
CREATE UNIQUE INDEX "token_model_availability_token_model_unique" ON "token_model_availability" ("token_id", "model_name");
CREATE INDEX "account_tokens_account_enabled_idx" ON "account_tokens" ("account_id", "enabled");
CREATE INDEX "account_tokens_account_id_idx" ON "account_tokens" ("account_id");
CREATE INDEX "account_tokens_enabled_idx" ON "account_tokens" ("enabled");
CREATE INDEX "accounts_site_id_idx" ON "accounts" ("site_id");
CREATE INDEX "accounts_site_status_idx" ON "accounts" ("site_id", "status");
CREATE INDEX "accounts_status_idx" ON "accounts" ("status");
CREATE INDEX "checkin_logs_account_created_at_idx" ON "checkin_logs" ("account_id", "created_at");
CREATE INDEX "checkin_logs_created_at_idx" ON "checkin_logs" ("created_at");
CREATE INDEX "checkin_logs_status_idx" ON "checkin_logs" ("status");
CREATE INDEX "downstream_api_keys_enabled_idx" ON "downstream_api_keys" ("enabled");
CREATE INDEX "downstream_api_keys_expires_at_idx" ON "downstream_api_keys" ("expires_at");
CREATE INDEX "downstream_api_keys_name_idx" ON "downstream_api_keys" ("name");
CREATE INDEX "events_created_at_idx" ON "events" ("created_at");
CREATE INDEX "events_read_created_at_idx" ON "events" ("read", "created_at");
CREATE INDEX "events_type_created_at_idx" ON "events" ("type", "created_at");
CREATE INDEX "model_availability_account_available_idx" ON "model_availability" ("account_id", "available");
CREATE INDEX "model_availability_model_name_idx" ON "model_availability" ("model_name");
CREATE INDEX "proxy_files_owner_lookup_idx" ON "proxy_files" ("owner_type", "owner_id", "deleted_at");
CREATE INDEX "proxy_logs_account_created_at_idx" ON "proxy_logs" ("account_id", "created_at");
CREATE INDEX "proxy_logs_created_at_idx" ON "proxy_logs" ("created_at");
CREATE INDEX "proxy_logs_model_actual_created_at_idx" ON "proxy_logs" ("model_actual", "created_at");
CREATE INDEX "proxy_logs_status_created_at_idx" ON "proxy_logs" ("status", "created_at");
CREATE INDEX "proxy_video_tasks_created_at_idx" ON "proxy_video_tasks" ("created_at");
CREATE INDEX "proxy_video_tasks_upstream_video_id_idx" ON "proxy_video_tasks" ("upstream_video_id");
CREATE INDEX "route_channels_account_id_idx" ON "route_channels" ("account_id");
CREATE INDEX "route_channels_route_enabled_idx" ON "route_channels" ("route_id", "enabled");
CREATE INDEX "route_channels_route_id_idx" ON "route_channels" ("route_id");
CREATE INDEX "route_channels_route_token_idx" ON "route_channels" ("route_id", "token_id");
CREATE INDEX "route_channels_token_id_idx" ON "route_channels" ("token_id");
CREATE INDEX "site_disabled_models_site_id_idx" ON "site_disabled_models" ("site_id");
CREATE INDEX "sites_status_idx" ON "sites" ("status");
CREATE INDEX "token_model_availability_available_idx" ON "token_model_availability" ("available");
CREATE INDEX "token_model_availability_model_name_idx" ON "token_model_availability" ("model_name");
CREATE INDEX "token_model_availability_token_available_idx" ON "token_model_availability" ("token_id", "available");
CREATE INDEX "token_routes_enabled_idx" ON "token_routes" ("enabled");
CREATE INDEX "token_routes_model_pattern_idx" ON "token_routes" ("model_pattern");
@@ -0,0 +1,27 @@
CREATE TABLE IF NOT EXISTS "downstream_api_keys" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "name" TEXT NOT NULL, "key" TEXT NOT NULL, "description" TEXT, "enabled" BOOLEAN DEFAULT true, "expires_at" TEXT, "max_cost" DOUBLE PRECISION, "used_cost" DOUBLE PRECISION DEFAULT 0, "max_requests" INTEGER, "used_requests" INTEGER DEFAULT 0, "supported_models" TEXT, "allowed_route_ids" TEXT, "site_weight_multipliers" TEXT, "last_used_at" TEXT, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'));
CREATE TABLE IF NOT EXISTS "proxy_files" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "public_id" TEXT NOT NULL, "owner_type" TEXT NOT NULL, "owner_id" TEXT NOT NULL, "filename" TEXT NOT NULL, "mime_type" TEXT NOT NULL, "purpose" TEXT, "byte_size" INTEGER NOT NULL, "sha256" TEXT NOT NULL, "content_base64" TEXT NOT NULL, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'), "deleted_at" TEXT);
CREATE TABLE IF NOT EXISTS "proxy_video_tasks" ("id" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "public_id" TEXT NOT NULL, "upstream_video_id" TEXT NOT NULL, "site_url" TEXT NOT NULL, "token_value" TEXT NOT NULL, "requested_model" TEXT, "actual_model" TEXT, "channel_id" INTEGER, "account_id" INTEGER, "status_snapshot" TEXT, "upstream_response_meta" TEXT, "last_upstream_status" INTEGER, "last_polled_at" TEXT, "created_at" TEXT DEFAULT datetime('now'), "updated_at" TEXT DEFAULT datetime('now'));
ALTER TABLE "route_channels" ADD COLUMN "source_model" TEXT;
ALTER TABLE "route_channels" ADD COLUMN "last_selected_at" TEXT;
ALTER TABLE "route_channels" ADD COLUMN "consecutive_fail_count" INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "route_channels" ADD COLUMN "cooldown_level" INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "sites" ADD COLUMN "proxy_url" TEXT;
ALTER TABLE "sites" ADD COLUMN "use_system_proxy" BOOLEAN DEFAULT false;
ALTER TABLE "sites" ADD COLUMN "custom_headers" TEXT;
ALTER TABLE "sites" ADD COLUMN "external_checkin_url" TEXT;
ALTER TABLE "sites" ADD COLUMN "global_weight" DOUBLE PRECISION DEFAULT 1;
ALTER TABLE "token_routes" ADD COLUMN "display_name" TEXT;
ALTER TABLE "token_routes" ADD COLUMN "display_icon" TEXT;
ALTER TABLE "token_routes" ADD COLUMN "decision_snapshot" TEXT;
ALTER TABLE "token_routes" ADD COLUMN "decision_refreshed_at" TEXT;
ALTER TABLE "token_routes" ADD COLUMN "routing_strategy" TEXT DEFAULT 'weighted';
CREATE UNIQUE INDEX "downstream_api_keys_key_unique" ON "downstream_api_keys" ("key");
CREATE UNIQUE INDEX "model_availability_account_model_unique" ON "model_availability" ("account_id", "model_name");
CREATE UNIQUE INDEX "proxy_files_public_id_unique" ON "proxy_files" ("public_id");
CREATE UNIQUE INDEX "proxy_video_tasks_public_id_unique" ON "proxy_video_tasks" ("public_id");
CREATE INDEX "downstream_api_keys_enabled_idx" ON "downstream_api_keys" ("enabled");
CREATE INDEX "downstream_api_keys_expires_at_idx" ON "downstream_api_keys" ("expires_at");
CREATE INDEX "downstream_api_keys_name_idx" ON "downstream_api_keys" ("name");
CREATE INDEX "proxy_files_owner_lookup_idx" ON "proxy_files" ("owner_type", "owner_id", "deleted_at");
CREATE INDEX "proxy_video_tasks_created_at_idx" ON "proxy_video_tasks" ("created_at");
CREATE INDEX "proxy_video_tasks_upstream_video_id_idx" ON "proxy_video_tasks" ("upstream_video_id");
+488 -5
View File
@@ -222,6 +222,106 @@
}
}
},
"downstream_api_keys": {
"columns": {
"id": {
"logicalType": "integer",
"notNull": true,
"defaultValue": null,
"primaryKey": true
},
"name": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"key": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"description": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"enabled": {
"logicalType": "boolean",
"notNull": false,
"defaultValue": "true",
"primaryKey": false
},
"expires_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"max_cost": {
"logicalType": "real",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"used_cost": {
"logicalType": "real",
"notNull": false,
"defaultValue": "0",
"primaryKey": false
},
"max_requests": {
"logicalType": "integer",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"used_requests": {
"logicalType": "integer",
"notNull": false,
"defaultValue": "0",
"primaryKey": false
},
"supported_models": {
"logicalType": "json",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"allowed_route_ids": {
"logicalType": "json",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"site_weight_multipliers": {
"logicalType": "json",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"last_used_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"created_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": "datetime('now')",
"primaryKey": false
},
"updated_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": "datetime('now')",
"primaryKey": false
}
}
},
"events": {
"columns": {
"id": {
@@ -320,6 +420,88 @@
}
}
},
"proxy_files": {
"columns": {
"id": {
"logicalType": "integer",
"notNull": true,
"defaultValue": null,
"primaryKey": true
},
"public_id": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"owner_type": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"owner_id": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"filename": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"mime_type": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"purpose": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"byte_size": {
"logicalType": "integer",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"sha256": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"content_base64": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"created_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": "datetime('now')",
"primaryKey": false
},
"updated_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": "datetime('now')",
"primaryKey": false
},
"deleted_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
}
}
},
"proxy_logs": {
"columns": {
"id": {
@@ -426,6 +608,100 @@
}
}
},
"proxy_video_tasks": {
"columns": {
"id": {
"logicalType": "integer",
"notNull": true,
"defaultValue": null,
"primaryKey": true
},
"public_id": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"upstream_video_id": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"site_url": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"token_value": {
"logicalType": "text",
"notNull": true,
"defaultValue": null,
"primaryKey": false
},
"requested_model": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"actual_model": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"channel_id": {
"logicalType": "integer",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"account_id": {
"logicalType": "integer",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"status_snapshot": {
"logicalType": "json",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"upstream_response_meta": {
"logicalType": "json",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"last_upstream_status": {
"logicalType": "integer",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"last_polled_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"created_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": "datetime('now')",
"primaryKey": false
},
"updated_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": "datetime('now')",
"primaryKey": false
}
}
},
"route_channels": {
"columns": {
"id": {
@@ -446,6 +722,18 @@
"defaultValue": null,
"primaryKey": false
},
"token_id": {
"logicalType": "integer",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"source_model": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"priority": {
"logicalType": "integer",
"notNull": false,
@@ -500,20 +788,32 @@
"defaultValue": null,
"primaryKey": false
},
"last_selected_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"last_fail_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"cooldown_until": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"consecutive_fail_count": {
"logicalType": "integer",
"notNull": true,
"defaultValue": "0",
"primaryKey": false
},
"token_id": {
"cooldown_level": {
"logicalType": "integer",
"notNull": true,
"defaultValue": "0",
"primaryKey": false
},
"cooldown_until": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
@@ -625,6 +925,36 @@
"notNull": false,
"defaultValue": "0",
"primaryKey": false
},
"proxy_url": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"use_system_proxy": {
"logicalType": "boolean",
"notNull": false,
"defaultValue": "false",
"primaryKey": false
},
"custom_headers": {
"logicalType": "json",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"external_checkin_url": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"global_weight": {
"logicalType": "real",
"notNull": false,
"defaultValue": "1",
"primaryKey": false
}
}
},
@@ -705,6 +1035,36 @@
"notNull": false,
"defaultValue": "datetime('now')",
"primaryKey": false
},
"display_name": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"display_icon": {
"logicalType": "text",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"decision_snapshot": {
"logicalType": "json",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"decision_refreshed_at": {
"logicalType": "datetime",
"notNull": false,
"defaultValue": null,
"primaryKey": false
},
"routing_strategy": {
"logicalType": "text",
"notNull": false,
"defaultValue": "'weighted'",
"primaryKey": false
}
}
}
@@ -785,6 +1145,38 @@
],
"unique": false
},
{
"name": "downstream_api_keys_enabled_idx",
"table": "downstream_api_keys",
"columns": [
"enabled"
],
"unique": false
},
{
"name": "downstream_api_keys_expires_at_idx",
"table": "downstream_api_keys",
"columns": [
"expires_at"
],
"unique": false
},
{
"name": "downstream_api_keys_key_unique",
"table": "downstream_api_keys",
"columns": [
"key"
],
"unique": true
},
{
"name": "downstream_api_keys_name_idx",
"table": "downstream_api_keys",
"columns": [
"name"
],
"unique": false
},
{
"name": "events_created_at_idx",
"table": "events",
@@ -820,6 +1212,15 @@
],
"unique": false
},
{
"name": "model_availability_account_model_unique",
"table": "model_availability",
"columns": [
"account_id",
"model_name"
],
"unique": true
},
{
"name": "model_availability_model_name_idx",
"table": "model_availability",
@@ -828,6 +1229,24 @@
],
"unique": false
},
{
"name": "proxy_files_owner_lookup_idx",
"table": "proxy_files",
"columns": [
"owner_type",
"owner_id",
"deleted_at"
],
"unique": false
},
{
"name": "proxy_files_public_id_unique",
"table": "proxy_files",
"columns": [
"public_id"
],
"unique": true
},
{
"name": "proxy_logs_account_created_at_idx",
"table": "proxy_logs",
@@ -863,6 +1282,30 @@
],
"unique": false
},
{
"name": "proxy_video_tasks_created_at_idx",
"table": "proxy_video_tasks",
"columns": [
"created_at"
],
"unique": false
},
{
"name": "proxy_video_tasks_public_id_unique",
"table": "proxy_video_tasks",
"columns": [
"public_id"
],
"unique": true
},
{
"name": "proxy_video_tasks_upstream_video_id_idx",
"table": "proxy_video_tasks",
"columns": [
"upstream_video_id"
],
"unique": false
},
{
"name": "route_channels_account_id_idx",
"table": "route_channels",
@@ -982,6 +1425,35 @@
}
],
"uniques": [
{
"name": "downstream_api_keys_key_unique",
"table": "downstream_api_keys",
"columns": [
"key"
]
},
{
"name": "model_availability_account_model_unique",
"table": "model_availability",
"columns": [
"account_id",
"model_name"
]
},
{
"name": "proxy_files_public_id_unique",
"table": "proxy_files",
"columns": [
"public_id"
]
},
{
"name": "proxy_video_tasks_public_id_unique",
"table": "proxy_video_tasks",
"columns": [
"public_id"
]
},
{
"name": "site_disabled_models_site_model_unique",
"table": "site_disabled_models",
@@ -1066,6 +1538,17 @@
],
"onDelete": "CASCADE"
},
{
"table": "route_channels",
"columns": [
"token_id"
],
"referencedTable": "account_tokens",
"referencedColumns": [
"id"
],
"onDelete": "SET NULL"
},
{
"table": "site_disabled_models",
"columns": [