Files
lijiaoqiao/sql/postgresql/supply_schema_v1.sql

197 lines
8.4 KiB
MySQL
Raw Permalink Normal View History

-- Supply domain schema (PostgreSQL 15)
-- Single executable DDL source for supply_* tables.
-- Updated: 2026-03-25
BEGIN;
CREATE TABLE IF NOT EXISTS supply_accounts (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
user_id BIGINT NOT NULL,
platform VARCHAR(50) NOT NULL,
account_type VARCHAR(20) NOT NULL CHECK (account_type IN ('api_key', 'oauth')),
account_name VARCHAR(100),
encrypted_credentials TEXT NOT NULL,
key_id VARCHAR(100),
status VARCHAR(20) NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'active', 'suspended', 'disabled')),
risk_level VARCHAR(20) NOT NULL DEFAULT 'normal'
CHECK (risk_level IN ('low', 'normal', 'high')),
total_quota NUMERIC(20, 6),
available_quota NUMERIC(20, 6),
frozen_quota NUMERIC(20, 6) DEFAULT 0,
is_verified BOOLEAN DEFAULT FALSE,
verified_at TIMESTAMPTZ,
last_check_at TIMESTAMPTZ,
tos_compliant BOOLEAN DEFAULT TRUE,
tos_check_result TEXT,
total_requests BIGINT DEFAULT 0,
total_tokens BIGINT DEFAULT 0,
total_cost NUMERIC(20, 6) DEFAULT 0,
success_rate NUMERIC(5, 2) DEFAULT 0,
risk_score INT DEFAULT 0,
risk_reason TEXT,
is_frozen BOOLEAN DEFAULT FALSE,
frozen_reason TEXT,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
created_by BIGINT,
updated_by BIGINT
);
CREATE INDEX IF NOT EXISTS idx_supply_accounts_user_id ON supply_accounts (user_id);
CREATE INDEX IF NOT EXISTS idx_supply_accounts_platform ON supply_accounts (platform);
CREATE INDEX IF NOT EXISTS idx_supply_accounts_status ON supply_accounts (status);
CREATE INDEX IF NOT EXISTS idx_supply_accounts_risk_level ON supply_accounts (risk_level);
CREATE TABLE IF NOT EXISTS supply_packages (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
supply_account_id BIGINT NOT NULL REFERENCES supply_accounts(id),
user_id BIGINT NOT NULL,
platform VARCHAR(50) NOT NULL,
model VARCHAR(100) NOT NULL,
total_quota NUMERIC(20, 6) NOT NULL,
available_quota NUMERIC(20, 6) NOT NULL,
sold_quota NUMERIC(20, 6) DEFAULT 0,
reserved_quota NUMERIC(20, 6) DEFAULT 0,
price_per_1m_input NUMERIC(20, 6),
price_per_1m_output NUMERIC(20, 6),
min_purchase NUMERIC(20, 6),
start_at TIMESTAMPTZ,
end_at TIMESTAMPTZ,
valid_days INT,
status VARCHAR(20) NOT NULL DEFAULT 'draft'
CHECK (status IN ('draft', 'active', 'paused', 'sold_out', 'expired')),
max_concurrent INT DEFAULT 10,
rate_limit_rpm INT DEFAULT 60,
total_orders INT DEFAULT 0,
total_revenue NUMERIC(20, 6) DEFAULT 0,
rating NUMERIC(3, 2) DEFAULT 0,
rating_count INT DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_supply_packages_supply_account_id ON supply_packages (supply_account_id);
CREATE INDEX IF NOT EXISTS idx_supply_packages_user_id ON supply_packages (user_id);
CREATE INDEX IF NOT EXISTS idx_supply_packages_platform_model ON supply_packages (platform, model);
CREATE INDEX IF NOT EXISTS idx_supply_packages_status ON supply_packages (status);
CREATE TABLE IF NOT EXISTS supply_orders (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
order_no VARCHAR(64) NOT NULL UNIQUE,
buyer_user_id BIGINT NOT NULL,
buyer_team_id BIGINT,
supply_account_id BIGINT NOT NULL REFERENCES supply_accounts(id),
supplier_user_id BIGINT NOT NULL,
supply_package_id BIGINT NOT NULL REFERENCES supply_packages(id),
platform VARCHAR(50) NOT NULL,
model VARCHAR(100) NOT NULL,
quota_amount NUMERIC(20, 6) NOT NULL,
quota_tokens BIGINT,
unit_price NUMERIC(20, 6) NOT NULL,
total_amount NUMERIC(20, 6) NOT NULL,
platform_fee NUMERIC(20, 6) NOT NULL,
supplier_earnings NUMERIC(20, 6) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'paid', 'using', 'expired', 'refunded')),
used_quota NUMERIC(20, 6) DEFAULT 0,
remaining_quota NUMERIC(20, 6),
expired_at TIMESTAMPTZ,
payment_method VARCHAR(20),
paid_at TIMESTAMPTZ,
payment_transaction_id VARCHAR(100),
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_supply_orders_buyer_user_id ON supply_orders (buyer_user_id);
CREATE INDEX IF NOT EXISTS idx_supply_orders_supplier_user_id ON supply_orders (supplier_user_id);
CREATE INDEX IF NOT EXISTS idx_supply_orders_supply_package_id ON supply_orders (supply_package_id);
CREATE INDEX IF NOT EXISTS idx_supply_orders_status ON supply_orders (status);
CREATE TABLE IF NOT EXISTS supply_usage_records (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES supply_orders(id),
buyer_user_id BIGINT NOT NULL,
supply_account_id BIGINT NOT NULL REFERENCES supply_accounts(id),
supplier_user_id BIGINT NOT NULL,
request_id VARCHAR(64) NOT NULL,
upstream_request_id VARCHAR(128),
api_key_id BIGINT,
platform VARCHAR(50) NOT NULL,
model VARCHAR(100) NOT NULL,
endpoint VARCHAR(100) NOT NULL,
request_tokens BIGINT,
response_tokens BIGINT,
total_tokens BIGINT GENERATED ALWAYS AS (COALESCE(request_tokens, 0) + COALESCE(response_tokens, 0)) STORED,
input_cost NUMERIC(20, 6),
output_cost NUMERIC(20, 6),
total_cost NUMERIC(20, 6) NOT NULL,
unit_price NUMERIC(20, 6) NOT NULL,
response_status INT,
latency_ms INT,
error_message TEXT,
success BOOLEAN DEFAULT TRUE,
started_at TIMESTAMPTZ NOT NULL,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_supply_usage_records_request_id ON supply_usage_records (request_id);
CREATE INDEX IF NOT EXISTS idx_supply_usage_records_order_id ON supply_usage_records (order_id);
CREATE INDEX IF NOT EXISTS idx_supply_usage_records_supply_account_id ON supply_usage_records (supply_account_id);
CREATE INDEX IF NOT EXISTS idx_supply_usage_records_platform_model ON supply_usage_records (platform, model);
CREATE INDEX IF NOT EXISTS idx_supply_usage_records_started_at ON supply_usage_records (started_at);
CREATE TABLE IF NOT EXISTS supply_earnings (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
user_id BIGINT NOT NULL,
supply_account_id BIGINT REFERENCES supply_accounts(id),
order_id BIGINT REFERENCES supply_orders(id),
usage_record_id BIGINT REFERENCES supply_usage_records(id),
earnings_type VARCHAR(20) NOT NULL CHECK (earnings_type IN ('usage', 'bonus', 'refund')),
amount NUMERIC(20, 6) NOT NULL,
currency VARCHAR(10) DEFAULT 'CNY',
status VARCHAR(20) NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'available', 'withdrawn', 'frozen')),
available_amount NUMERIC(20, 6) DEFAULT 0,
frozen_amount NUMERIC(20, 6) DEFAULT 0,
withdrawn_amount NUMERIC(20, 6) DEFAULT 0,
description TEXT,
earned_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
available_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_supply_earnings_user_id ON supply_earnings (user_id);
CREATE INDEX IF NOT EXISTS idx_supply_earnings_status ON supply_earnings (status);
CREATE INDEX IF NOT EXISTS idx_supply_earnings_earned_at ON supply_earnings (earned_at);
CREATE TABLE IF NOT EXISTS supply_settlements (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
settlement_no VARCHAR(64) NOT NULL UNIQUE,
user_id BIGINT NOT NULL,
total_amount NUMERIC(20, 6) NOT NULL,
fee_amount NUMERIC(20, 6) DEFAULT 0,
net_amount NUMERIC(20, 6) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'processing', 'completed', 'failed')),
payment_method VARCHAR(20),
payment_account VARCHAR(100),
payment_transaction_id VARCHAR(100),
paid_at TIMESTAMPTZ,
period_start DATE NOT NULL,
period_end DATE NOT NULL,
total_orders INT DEFAULT 0,
total_usage_records INT DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_supply_settlements_user_id ON supply_settlements (user_id);
CREATE INDEX IF NOT EXISTS idx_supply_settlements_status ON supply_settlements (status);
CREATE INDEX IF NOT EXISTS idx_supply_settlements_period ON supply_settlements (period_start, period_end);
COMMIT;