feat(security): harden gateway boundaries and usage policies

Consolidate subscription usage policy enforcement, privacy-safe persistence, and gateway security hardening into one reviewable change.

Includes bounded HTTP and execution envelopes, header and protocol guards, DNS and relay validation, authentication and secret projection hardening, secure backup/install paths, and regression coverage.
This commit is contained in:
elky
2026-09-04 03:45:52 +08:00
parent ddcbeb3ae9
commit 579f2c7cc1
1019 changed files with 190437 additions and 26080 deletions
@@ -12,6 +12,7 @@ CREATE TABLE IF NOT EXISTS users (
`email_verified` TINYINT(1) NOT NULL DEFAULT 0,
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
`is_deleted` TINYINT(1) NOT NULL DEFAULT 0,
`security_version` BIGINT NOT NULL DEFAULT 0,
`allowed_models` JSON,
`allowed_models_mode` VARCHAR(32) NOT NULL DEFAULT 'unrestricted',
`allowed_providers` JSON,
@@ -193,6 +194,7 @@ CREATE TABLE IF NOT EXISTS user_preferences (
CREATE TABLE IF NOT EXISTS user_sessions (
`id` VARCHAR(64) NOT NULL,
`user_id` VARCHAR(64) NOT NULL,
`security_version` BIGINT NOT NULL DEFAULT 0,
`client_device_id` VARCHAR(128) NOT NULL,
`device_label` VARCHAR(120),
`device_type` VARCHAR(20) NOT NULL DEFAULT 'unknown',
@@ -45,6 +45,7 @@ CREATE TABLE IF NOT EXISTS oauth_providers (
CREATE TABLE IF NOT EXISTS ldap_configs (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`singleton_key` INT NOT NULL DEFAULT 1,
`server_url` VARCHAR(255) NOT NULL,
`bind_dn` LONGTEXT NOT NULL,
`bind_password_encrypted` LONGTEXT,
@@ -59,7 +60,8 @@ CREATE TABLE IF NOT EXISTS ldap_configs (
`connect_timeout` INT NOT NULL DEFAULT 10,
`created_at` BIGINT NOT NULL,
`updated_at` BIGINT NOT NULL,
PRIMARY KEY (`id`)
PRIMARY KEY (`id`),
UNIQUE KEY ldap_configs_singleton_key_key (`singleton_key`)
);
CREATE TABLE IF NOT EXISTS user_oauth_links (
@@ -3,6 +3,7 @@
CREATE TABLE IF NOT EXISTS proxy_nodes (
`id` VARCHAR(64) NOT NULL,
`tunnel_generation` VARCHAR(64) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`ip` VARCHAR(512) NOT NULL,
`port` INT NOT NULL,
@@ -17,7 +18,7 @@ CREATE TABLE IF NOT EXISTS proxy_nodes (
`is_manual` TINYINT(1) NOT NULL DEFAULT 0,
`proxy_url` VARCHAR(500),
`proxy_username` VARCHAR(255),
`proxy_password` VARCHAR(500),
`proxy_password` TEXT,
`created_at` BIGINT NOT NULL,
`updated_at` BIGINT NOT NULL,
`remote_config` JSON,
@@ -31,7 +32,8 @@ CREATE TABLE IF NOT EXISTS proxy_nodes (
`dns_failures` BIGINT NOT NULL DEFAULT 0,
`stream_errors` BIGINT NOT NULL DEFAULT 0,
`proxy_metadata` JSON,
PRIMARY KEY (`id`)
PRIMARY KEY (`id`),
UNIQUE KEY uq_proxy_node_ip_port (`ip`, `port`)
);
CREATE TABLE IF NOT EXISTS proxy_node_events (
@@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS payment_orders (
`product_snapshot` JSON,
`fulfillment_status` VARCHAR(64) NOT NULL DEFAULT 'pending',
`fulfillment_error` LONGTEXT,
`gateway_order_id` VARCHAR(128),
`gateway_order_id` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin,
`gateway_response` JSON,
`status` VARCHAR(64) NOT NULL DEFAULT 'pending',
`created_at` BIGINT NOT NULL,
@@ -100,6 +100,7 @@ CREATE TABLE IF NOT EXISTS payment_orders (
KEY idx_payment_orders_user_created (`user_id`, `created_at`),
KEY idx_payment_orders_status (`status`),
KEY idx_payment_orders_gateway_order_id (`gateway_order_id`),
UNIQUE KEY uq_payment_orders_payment_method_gateway_order_id (`payment_method`, `gateway_order_id`),
KEY idx_payment_orders_kind_status (`order_kind`, `status`),
KEY idx_payment_orders_product (`product_id`)
);
@@ -130,8 +131,6 @@ CREATE TABLE IF NOT EXISTS user_referrals (
KEY idx_user_referrals_inviter (`inviter_user_id`, `created_at`),
KEY idx_user_referrals_created (`created_at`),
KEY idx_user_referrals_invite_code (`invite_code_snapshot`),
CONSTRAINT user_referrals_inviter_user_id_fkey FOREIGN KEY (`inviter_user_id`) REFERENCES users (`id`) ON DELETE CASCADE,
CONSTRAINT user_referrals_invitee_user_id_fkey FOREIGN KEY (`invitee_user_id`) REFERENCES users (`id`) ON DELETE CASCADE,
CONSTRAINT user_referrals_first_paid_order_fkey FOREIGN KEY (`first_paid_order_id`) REFERENCES payment_orders (`id`) ON DELETE SET NULL
);
@@ -161,8 +160,6 @@ CREATE TABLE IF NOT EXISTS referral_rewards (
KEY idx_referral_rewards_created (`created_at`),
KEY idx_referral_rewards_source_order (`source_order_id`),
CONSTRAINT referral_rewards_referral_id_fkey FOREIGN KEY (`referral_id`) REFERENCES user_referrals (`id`) ON DELETE CASCADE,
CONSTRAINT referral_rewards_inviter_user_id_fkey FOREIGN KEY (`inviter_user_id`) REFERENCES users (`id`) ON DELETE CASCADE,
CONSTRAINT referral_rewards_invitee_user_id_fkey FOREIGN KEY (`invitee_user_id`) REFERENCES users (`id`) ON DELETE CASCADE,
CONSTRAINT referral_rewards_source_order_fkey FOREIGN KEY (`source_order_id`) REFERENCES payment_orders (`id`) ON DELETE SET NULL
);
@@ -173,6 +173,7 @@ CREATE TABLE IF NOT EXISTS usage_counter_deltas (
`request_id` VARCHAR(128) NOT NULL,
`kind` VARCHAR(64) NOT NULL,
`target_id` TEXT NOT NULL,
`target_tunnel_generation` VARCHAR(64),
`request_count_delta` BIGINT NOT NULL DEFAULT 0,
`total_requests_delta` BIGINT NOT NULL DEFAULT 0,
`success_count_delta` BIGINT NOT NULL DEFAULT 0,
@@ -243,3 +244,39 @@ CREATE TABLE IF NOT EXISTS usage_settlement_snapshots (
KEY ix_usage_settlement_snapshots_pricing_source (`billing_pricing_source`)
);
CREATE TABLE IF NOT EXISTS usage_cost_reservations (
`request_id` VARCHAR(128) NOT NULL,
`subject_id` VARCHAR(128) NOT NULL,
`reservation_token` VARCHAR(128) NOT NULL,
`admitted_at` BIGINT NOT NULL,
`reserved_cost_units` BIGINT NOT NULL,
`actual_cost_units` BIGINT,
`state` VARCHAR(20) NOT NULL,
`reservation_expires_at` BIGINT NOT NULL,
`retain_until` BIGINT NOT NULL,
`finalized_at` BIGINT,
`created_at` BIGINT NOT NULL,
`updated_at` BIGINT NOT NULL,
PRIMARY KEY (`reservation_token`),
KEY usage_cost_reservations_request_id_idx (`request_id`),
KEY usage_cost_reservations_subject_admitted_at_idx (`subject_id`, `admitted_at`),
KEY usage_cost_reservations_reservation_expires_at_idx (`reservation_expires_at`),
KEY usage_cost_reservations_retain_until_token_idx (`retain_until`, `reservation_token`),
CONSTRAINT usage_cost_reservations_subject_id_fkey FOREIGN KEY (`subject_id`) REFERENCES users (`id`) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS usage_request_admissions (
`request_id` VARCHAR(128) NOT NULL,
`subject_id` VARCHAR(128) NOT NULL,
`event_token` VARCHAR(128) NOT NULL,
`admitted_at` BIGINT NOT NULL,
`retain_until` BIGINT NOT NULL,
`state` VARCHAR(20) NOT NULL,
`released_at` BIGINT,
`created_at` BIGINT NOT NULL,
PRIMARY KEY (`event_token`),
KEY usage_request_admissions_subject_admitted_at_idx (`subject_id`, `admitted_at`),
KEY usage_request_admissions_retain_until_token_idx (`retain_until`, `event_token`),
CONSTRAINT usage_request_admissions_subject_id_fkey FOREIGN KEY (`subject_id`) REFERENCES users (`id`) ON DELETE CASCADE
);
@@ -12,6 +12,7 @@ CREATE TABLE IF NOT EXISTS public.users (
email_verified boolean DEFAULT false NOT NULL,
is_active boolean DEFAULT true NOT NULL,
is_deleted boolean DEFAULT false NOT NULL,
security_version bigint DEFAULT 0 NOT NULL,
allowed_models jsonb,
allowed_models_mode character varying(32) DEFAULT 'unrestricted' NOT NULL,
allowed_providers jsonb,
@@ -202,6 +203,7 @@ CREATE INDEX IF NOT EXISTS user_preferences_user_id_idx ON public.user_preferenc
CREATE TABLE IF NOT EXISTS public.user_sessions (
id character varying(64) NOT NULL,
user_id character varying(64) NOT NULL,
security_version bigint DEFAULT 0 NOT NULL,
client_device_id character varying(128) NOT NULL,
device_label character varying(120),
device_type character varying(20) DEFAULT 'unknown' NOT NULL,
@@ -48,6 +48,7 @@ ALTER TABLE ONLY public.oauth_providers ADD CONSTRAINT oauth_providers_pkey PRIM
CREATE TABLE IF NOT EXISTS public.ldap_configs (
id bigserial NOT NULL,
singleton_key integer DEFAULT 1 NOT NULL,
server_url character varying(255) NOT NULL,
bind_dn text NOT NULL,
bind_password_encrypted text,
@@ -65,6 +66,7 @@ CREATE TABLE IF NOT EXISTS public.ldap_configs (
);
ALTER TABLE ONLY public.ldap_configs ADD CONSTRAINT ldap_configs_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.ldap_configs ADD CONSTRAINT ldap_configs_singleton_key_key UNIQUE (singleton_key);
CREATE TABLE IF NOT EXISTS public.user_oauth_links (
id character varying(64) NOT NULL,
@@ -3,6 +3,7 @@
CREATE TABLE IF NOT EXISTS public.proxy_nodes (
id character varying(64) NOT NULL,
tunnel_generation character varying(64) NOT NULL,
name character varying(255) NOT NULL,
ip character varying(512) NOT NULL,
port integer NOT NULL,
@@ -17,7 +18,7 @@ CREATE TABLE IF NOT EXISTS public.proxy_nodes (
is_manual boolean DEFAULT false NOT NULL,
proxy_url character varying(500),
proxy_username character varying(255),
proxy_password character varying(500),
proxy_password text,
created_at bigint NOT NULL,
updated_at bigint NOT NULL,
remote_config jsonb,
@@ -34,6 +35,7 @@ CREATE TABLE IF NOT EXISTS public.proxy_nodes (
);
ALTER TABLE ONLY public.proxy_nodes ADD CONSTRAINT proxy_nodes_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.proxy_nodes ADD CONSTRAINT uq_proxy_node_ip_port UNIQUE (ip, port);
CREATE TABLE IF NOT EXISTS public.proxy_node_events (
id bigserial NOT NULL,
@@ -105,6 +105,7 @@ CREATE INDEX IF NOT EXISTS idx_payment_orders_wallet_created ON public.payment_o
CREATE INDEX IF NOT EXISTS idx_payment_orders_user_created ON public.payment_orders USING btree (user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_payment_orders_status ON public.payment_orders USING btree (status);
CREATE INDEX IF NOT EXISTS idx_payment_orders_gateway_order_id ON public.payment_orders USING btree (gateway_order_id);
CREATE UNIQUE INDEX IF NOT EXISTS uq_payment_orders_payment_method_gateway_order_id ON public.payment_orders USING btree (payment_method, gateway_order_id);
CREATE INDEX IF NOT EXISTS idx_payment_orders_kind_status ON public.payment_orders USING btree (order_kind, status);
CREATE INDEX IF NOT EXISTS idx_payment_orders_product ON public.payment_orders USING btree (product_id);
@@ -137,8 +138,6 @@ ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_invitee_use
CREATE INDEX IF NOT EXISTS idx_user_referrals_inviter ON public.user_referrals USING btree (inviter_user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_user_referrals_created ON public.user_referrals USING btree (created_at);
CREATE INDEX IF NOT EXISTS idx_user_referrals_invite_code ON public.user_referrals USING btree (invite_code_snapshot);
ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_inviter_user_id_fkey FOREIGN KEY (inviter_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_invitee_user_id_fkey FOREIGN KEY (invitee_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_first_paid_order_fkey FOREIGN KEY (first_paid_order_id) REFERENCES public.payment_orders(id) ON DELETE SET NULL;
CREATE TABLE IF NOT EXISTS public.referral_rewards (
@@ -169,8 +168,6 @@ CREATE INDEX IF NOT EXISTS idx_referral_rewards_inviter_created ON public.referr
CREATE INDEX IF NOT EXISTS idx_referral_rewards_created ON public.referral_rewards USING btree (created_at);
CREATE INDEX IF NOT EXISTS idx_referral_rewards_source_order ON public.referral_rewards USING btree (source_order_id);
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_referral_id_fkey FOREIGN KEY (referral_id) REFERENCES public.user_referrals(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_inviter_user_id_fkey FOREIGN KEY (inviter_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_invitee_user_id_fkey FOREIGN KEY (invitee_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_source_order_fkey FOREIGN KEY (source_order_id) REFERENCES public.payment_orders(id) ON DELETE SET NULL;
CREATE TABLE IF NOT EXISTS public.payment_gateway_configs (
@@ -177,6 +177,7 @@ CREATE TABLE IF NOT EXISTS public.usage_counter_deltas (
request_id character varying(128) NOT NULL,
kind character varying(64) NOT NULL,
target_id text NOT NULL,
target_tunnel_generation character varying(64),
request_count_delta bigint DEFAULT 0 NOT NULL,
total_requests_delta bigint DEFAULT 0 NOT NULL,
success_count_delta bigint DEFAULT 0 NOT NULL,
@@ -249,3 +250,41 @@ CREATE INDEX IF NOT EXISTS usage_settlement_snapshots_wallet_id_idx ON public.us
CREATE INDEX IF NOT EXISTS ix_usage_settlement_snapshots_schema_version ON public.usage_settlement_snapshots USING btree (settlement_snapshot_schema_version);
CREATE INDEX IF NOT EXISTS ix_usage_settlement_snapshots_pricing_source ON public.usage_settlement_snapshots USING btree (billing_pricing_source);
CREATE TABLE IF NOT EXISTS public.usage_cost_reservations (
request_id character varying(128) NOT NULL,
subject_id character varying(128) NOT NULL,
reservation_token character varying(128) NOT NULL,
admitted_at timestamp with time zone NOT NULL,
reserved_cost_units bigint NOT NULL,
actual_cost_units bigint,
state character varying(20) NOT NULL,
reservation_expires_at timestamp with time zone NOT NULL,
retain_until timestamp with time zone NOT NULL,
finalized_at timestamp with time zone,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL
);
ALTER TABLE ONLY public.usage_cost_reservations ADD CONSTRAINT usage_cost_reservations_pkey PRIMARY KEY (reservation_token);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_request_id_idx ON public.usage_cost_reservations USING btree (request_id);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_subject_admitted_at_idx ON public.usage_cost_reservations USING btree (subject_id, admitted_at);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_reservation_expires_at_idx ON public.usage_cost_reservations USING btree (reservation_expires_at);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_retain_until_token_idx ON public.usage_cost_reservations USING btree (retain_until, reservation_token);
ALTER TABLE ONLY public.usage_cost_reservations ADD CONSTRAINT usage_cost_reservations_subject_id_fkey FOREIGN KEY (subject_id) REFERENCES public.users(id) ON DELETE CASCADE;
CREATE TABLE IF NOT EXISTS public.usage_request_admissions (
request_id character varying(128) NOT NULL,
subject_id character varying(128) NOT NULL,
event_token character varying(128) NOT NULL,
admitted_at timestamp with time zone NOT NULL,
retain_until timestamp with time zone NOT NULL,
state character varying(20) NOT NULL,
released_at timestamp with time zone,
created_at timestamp with time zone NOT NULL
);
ALTER TABLE ONLY public.usage_request_admissions ADD CONSTRAINT usage_request_admissions_pkey PRIMARY KEY (event_token);
CREATE INDEX IF NOT EXISTS usage_request_admissions_subject_admitted_at_idx ON public.usage_request_admissions USING btree (subject_id, admitted_at);
CREATE INDEX IF NOT EXISTS usage_request_admissions_retain_until_token_idx ON public.usage_request_admissions USING btree (retain_until, event_token);
ALTER TABLE ONLY public.usage_request_admissions ADD CONSTRAINT usage_request_admissions_subject_id_fkey FOREIGN KEY (subject_id) REFERENCES public.users(id) ON DELETE CASCADE;
@@ -12,6 +12,7 @@ CREATE TABLE IF NOT EXISTS users (
email_verified INTEGER NOT NULL DEFAULT 0,
is_active INTEGER NOT NULL DEFAULT 1,
is_deleted INTEGER NOT NULL DEFAULT 0,
security_version INTEGER NOT NULL DEFAULT 0,
allowed_models TEXT,
allowed_models_mode TEXT NOT NULL DEFAULT 'unrestricted',
allowed_providers TEXT,
@@ -185,6 +186,7 @@ CREATE INDEX IF NOT EXISTS user_preferences_user_id_idx ON user_preferences (use
CREATE TABLE IF NOT EXISTS user_sessions (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
security_version INTEGER NOT NULL DEFAULT 0,
client_device_id TEXT NOT NULL,
device_label TEXT,
device_type TEXT NOT NULL DEFAULT 'unknown',
@@ -42,6 +42,7 @@ CREATE TABLE IF NOT EXISTS oauth_providers (
CREATE TABLE IF NOT EXISTS ldap_configs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
singleton_key INTEGER NOT NULL DEFAULT 1,
server_url TEXT NOT NULL,
bind_dn TEXT NOT NULL,
bind_password_encrypted TEXT,
@@ -55,7 +56,8 @@ CREATE TABLE IF NOT EXISTS ldap_configs (
use_starttls INTEGER NOT NULL DEFAULT 0,
connect_timeout INTEGER NOT NULL DEFAULT 10,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
updated_at INTEGER NOT NULL,
UNIQUE (singleton_key)
);
CREATE TABLE IF NOT EXISTS user_oauth_links (
@@ -3,6 +3,7 @@
CREATE TABLE IF NOT EXISTS proxy_nodes (
id TEXT PRIMARY KEY NOT NULL,
tunnel_generation TEXT NOT NULL,
name TEXT NOT NULL,
ip TEXT NOT NULL,
port INTEGER NOT NULL,
@@ -30,7 +31,8 @@ CREATE TABLE IF NOT EXISTS proxy_nodes (
failed_requests INTEGER NOT NULL DEFAULT 0,
dns_failures INTEGER NOT NULL DEFAULT 0,
stream_errors INTEGER NOT NULL DEFAULT 0,
proxy_metadata TEXT
proxy_metadata TEXT,
UNIQUE (ip, port)
);
CREATE TABLE IF NOT EXISTS proxy_node_events (
@@ -97,6 +97,7 @@ CREATE INDEX IF NOT EXISTS idx_payment_orders_wallet_created ON payment_orders (
CREATE INDEX IF NOT EXISTS idx_payment_orders_user_created ON payment_orders (user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_payment_orders_status ON payment_orders (status);
CREATE INDEX IF NOT EXISTS idx_payment_orders_gateway_order_id ON payment_orders (gateway_order_id);
CREATE UNIQUE INDEX IF NOT EXISTS uq_payment_orders_payment_method_gateway_order_id ON payment_orders (payment_method, gateway_order_id);
CREATE INDEX IF NOT EXISTS idx_payment_orders_kind_status ON payment_orders (order_kind, status);
CREATE INDEX IF NOT EXISTS idx_payment_orders_product ON payment_orders (product_id);
@@ -121,8 +122,6 @@ CREATE TABLE IF NOT EXISTS user_referrals (
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE (invitee_user_id),
CONSTRAINT user_referrals_inviter_user_id_fkey FOREIGN KEY (inviter_user_id) REFERENCES users (id) ON DELETE CASCADE,
CONSTRAINT user_referrals_invitee_user_id_fkey FOREIGN KEY (invitee_user_id) REFERENCES users (id) ON DELETE CASCADE,
CONSTRAINT user_referrals_first_paid_order_fkey FOREIGN KEY (first_paid_order_id) REFERENCES payment_orders (id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_user_referrals_inviter ON user_referrals (inviter_user_id, created_at);
@@ -150,8 +149,6 @@ CREATE TABLE IF NOT EXISTS referral_rewards (
updated_at INTEGER NOT NULL,
UNIQUE (idempotency_key),
CONSTRAINT referral_rewards_referral_id_fkey FOREIGN KEY (referral_id) REFERENCES user_referrals (id) ON DELETE CASCADE,
CONSTRAINT referral_rewards_inviter_user_id_fkey FOREIGN KEY (inviter_user_id) REFERENCES users (id) ON DELETE CASCADE,
CONSTRAINT referral_rewards_invitee_user_id_fkey FOREIGN KEY (invitee_user_id) REFERENCES users (id) ON DELETE CASCADE,
CONSTRAINT referral_rewards_source_order_fkey FOREIGN KEY (source_order_id) REFERENCES payment_orders (id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_referral_rewards_inviter_status ON referral_rewards (inviter_user_id, status, created_at);
@@ -169,6 +169,7 @@ CREATE TABLE IF NOT EXISTS usage_counter_deltas (
request_id TEXT NOT NULL,
kind TEXT NOT NULL,
target_id TEXT NOT NULL,
target_tunnel_generation TEXT,
request_count_delta INTEGER NOT NULL DEFAULT 0,
total_requests_delta INTEGER NOT NULL DEFAULT 0,
success_count_delta INTEGER NOT NULL DEFAULT 0,
@@ -237,3 +238,37 @@ CREATE INDEX IF NOT EXISTS usage_settlement_snapshots_wallet_id_idx ON usage_set
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 usage_cost_reservations (
request_id TEXT NOT NULL,
subject_id TEXT NOT NULL,
reservation_token TEXT PRIMARY KEY NOT NULL,
admitted_at INTEGER NOT NULL,
reserved_cost_units INTEGER NOT NULL,
actual_cost_units INTEGER,
state TEXT NOT NULL,
reservation_expires_at INTEGER NOT NULL,
retain_until INTEGER NOT NULL,
finalized_at INTEGER,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
CONSTRAINT usage_cost_reservations_subject_id_fkey FOREIGN KEY (subject_id) REFERENCES users (id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_request_id_idx ON usage_cost_reservations (request_id);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_subject_admitted_at_idx ON usage_cost_reservations (subject_id, admitted_at);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_reservation_expires_at_idx ON usage_cost_reservations (reservation_expires_at);
CREATE INDEX IF NOT EXISTS usage_cost_reservations_retain_until_token_idx ON usage_cost_reservations (retain_until, reservation_token);
CREATE TABLE IF NOT EXISTS usage_request_admissions (
request_id TEXT NOT NULL,
subject_id TEXT NOT NULL,
event_token TEXT PRIMARY KEY NOT NULL,
admitted_at INTEGER NOT NULL,
retain_until INTEGER NOT NULL,
state TEXT NOT NULL,
released_at INTEGER,
created_at INTEGER NOT NULL,
CONSTRAINT usage_request_admissions_subject_id_fkey FOREIGN KEY (subject_id) REFERENCES users (id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS usage_request_admissions_subject_admitted_at_idx ON usage_request_admissions (subject_id, admitted_at);
CREATE INDEX IF NOT EXISTS usage_request_admissions_retain_until_token_idx ON usage_request_admissions (retain_until, event_token);