feat: scaffold ai gateway identity and design
This commit is contained in:
@@ -49,6 +49,9 @@ CREATE TABLE IF NOT EXISTS integration_platforms (
|
||||
auth_type text NOT NULL DEFAULT 'bearer',
|
||||
credentials jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
visibility_scope text NOT NULL DEFAULT 'global',
|
||||
tenant_id text,
|
||||
tenant_key text,
|
||||
default_pricing_mode text NOT NULL DEFAULT 'inherit_discount',
|
||||
default_discount_factor numeric NOT NULL DEFAULT 1,
|
||||
retry_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
@@ -72,6 +75,9 @@ CREATE INDEX IF NOT EXISTS idx_integration_platforms_status_priority
|
||||
CREATE INDEX IF NOT EXISTS idx_integration_platforms_cooldown
|
||||
ON integration_platforms(cooldown_until);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_integration_platforms_tenant_scope
|
||||
ON integration_platforms(visibility_scope, tenant_id, tenant_key, status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS model_pricing_rules (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
scope_type text NOT NULL,
|
||||
@@ -94,6 +100,240 @@ CREATE INDEX IF NOT EXISTS idx_model_pricing_scope
|
||||
CREATE INDEX IF NOT EXISTS idx_model_pricing_effective
|
||||
ON model_pricing_rules(effective_from, effective_to);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_user_groups (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
group_key text NOT NULL UNIQUE,
|
||||
name text NOT NULL,
|
||||
description text,
|
||||
source text NOT NULL DEFAULT 'gateway',
|
||||
priority integer NOT NULL DEFAULT 100,
|
||||
recharge_discount_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
billing_discount_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
rate_limit_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
quota_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_user_groups_status_priority
|
||||
ON gateway_user_groups(status, priority);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_tenants (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_key text NOT NULL UNIQUE,
|
||||
source text NOT NULL DEFAULT 'gateway',
|
||||
external_tenant_id text,
|
||||
name text NOT NULL,
|
||||
description text,
|
||||
default_user_group_id uuid REFERENCES gateway_user_groups(id) ON DELETE SET NULL,
|
||||
plan_key text,
|
||||
billing_profile jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
rate_limit_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
auth_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
synced_at timestamptz,
|
||||
source_updated_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
deleted_at timestamptz,
|
||||
UNIQUE(source, external_tenant_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_tenants_source_external
|
||||
ON gateway_tenants(source, external_tenant_id)
|
||||
WHERE external_tenant_id IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_tenants_status
|
||||
ON gateway_tenants(status, created_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_users (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_key text NOT NULL UNIQUE,
|
||||
source text NOT NULL DEFAULT 'gateway',
|
||||
external_user_id text,
|
||||
username text NOT NULL,
|
||||
display_name text,
|
||||
email text,
|
||||
phone text,
|
||||
avatar_url text,
|
||||
password_hash text,
|
||||
gateway_tenant_id uuid REFERENCES gateway_tenants(id) ON DELETE SET NULL,
|
||||
tenant_id text,
|
||||
tenant_key text,
|
||||
default_user_group_id uuid REFERENCES gateway_user_groups(id) ON DELETE SET NULL,
|
||||
roles jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
auth_profile jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
last_login_at timestamptz,
|
||||
synced_at timestamptz,
|
||||
source_updated_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
deleted_at timestamptz,
|
||||
UNIQUE(source, external_user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_users_source_external
|
||||
ON gateway_users(source, external_user_id)
|
||||
WHERE external_user_id IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_users_status
|
||||
ON gateway_users(status, created_at DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_users_tenant
|
||||
ON gateway_users(tenant_id, tenant_key, status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_user_group_memberships (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
group_id uuid NOT NULL REFERENCES gateway_user_groups(id) ON DELETE CASCADE,
|
||||
principal_type text NOT NULL,
|
||||
principal_id text NOT NULL,
|
||||
source text NOT NULL DEFAULT 'gateway',
|
||||
priority integer NOT NULL DEFAULT 100,
|
||||
effective_from timestamptz,
|
||||
effective_to timestamptz,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE(group_id, principal_type, principal_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_group_membership_principal
|
||||
ON gateway_user_group_memberships(principal_type, principal_id, status);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_group_membership_effective
|
||||
ON gateway_user_group_memberships(effective_from, effective_to);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_tenant_invitations (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id uuid NOT NULL REFERENCES gateway_tenants(id) ON DELETE CASCADE,
|
||||
invite_code text NOT NULL UNIQUE,
|
||||
role text NOT NULL DEFAULT 'user',
|
||||
user_group_id uuid REFERENCES gateway_user_groups(id) ON DELETE SET NULL,
|
||||
max_uses integer,
|
||||
used_count integer NOT NULL DEFAULT 0,
|
||||
expires_at timestamptz,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_by uuid REFERENCES gateway_users(id) ON DELETE SET NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_invitations_tenant
|
||||
ON gateway_tenant_invitations(tenant_id, status);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_invitations_expiry
|
||||
ON gateway_tenant_invitations(expires_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_api_keys (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
gateway_tenant_id uuid REFERENCES gateway_tenants(id) ON DELETE SET NULL,
|
||||
gateway_user_id uuid REFERENCES gateway_users(id) ON DELETE CASCADE,
|
||||
tenant_id text,
|
||||
tenant_key text,
|
||||
user_id text,
|
||||
key_prefix text NOT NULL,
|
||||
key_hash text NOT NULL UNIQUE,
|
||||
name text NOT NULL,
|
||||
scopes jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
user_group_id uuid REFERENCES gateway_user_groups(id) ON DELETE SET NULL,
|
||||
rate_limit_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
quota_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
expires_at timestamptz,
|
||||
last_used_at timestamptz,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
deleted_at timestamptz
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_api_keys_owner
|
||||
ON gateway_api_keys(gateway_user_id, status, created_at DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_api_keys_prefix
|
||||
ON gateway_api_keys(key_prefix, status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_wallet_accounts (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
gateway_tenant_id uuid REFERENCES gateway_tenants(id) ON DELETE SET NULL,
|
||||
gateway_user_id uuid REFERENCES gateway_users(id) ON DELETE CASCADE,
|
||||
tenant_id text,
|
||||
tenant_key text,
|
||||
user_id text,
|
||||
currency text NOT NULL DEFAULT 'resource',
|
||||
balance numeric NOT NULL DEFAULT 0,
|
||||
frozen_balance numeric NOT NULL DEFAULT 0,
|
||||
total_recharged numeric NOT NULL DEFAULT 0,
|
||||
total_spent numeric NOT NULL DEFAULT 0,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE(gateway_user_id, currency)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_wallet_accounts_tenant
|
||||
ON gateway_wallet_accounts(gateway_tenant_id, status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_wallet_transactions (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
account_id uuid NOT NULL REFERENCES gateway_wallet_accounts(id) ON DELETE CASCADE,
|
||||
gateway_tenant_id uuid REFERENCES gateway_tenants(id) ON DELETE SET NULL,
|
||||
gateway_user_id uuid REFERENCES gateway_users(id) ON DELETE SET NULL,
|
||||
direction text NOT NULL,
|
||||
transaction_type text NOT NULL,
|
||||
amount numeric NOT NULL,
|
||||
balance_before numeric NOT NULL,
|
||||
balance_after numeric NOT NULL,
|
||||
idempotency_key text,
|
||||
reference_type text,
|
||||
reference_id text,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_wallet_transactions_account
|
||||
ON gateway_wallet_transactions(account_id, created_at DESC);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uniq_gateway_wallet_tx_idempotency
|
||||
ON gateway_wallet_transactions(account_id, idempotency_key)
|
||||
WHERE idempotency_key IS NOT NULL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_recharge_orders (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
gateway_tenant_id uuid REFERENCES gateway_tenants(id) ON DELETE SET NULL,
|
||||
gateway_user_id uuid REFERENCES gateway_users(id) ON DELETE CASCADE,
|
||||
tenant_id text,
|
||||
tenant_key text,
|
||||
user_id text,
|
||||
amount numeric NOT NULL,
|
||||
bonus_amount numeric NOT NULL DEFAULT 0,
|
||||
payable_amount numeric NOT NULL,
|
||||
currency text NOT NULL DEFAULT 'resource',
|
||||
channel text NOT NULL DEFAULT 'manual',
|
||||
status text NOT NULL DEFAULT 'created',
|
||||
external_order_id text,
|
||||
idempotency_key text,
|
||||
paid_at timestamptz,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_recharge_orders_user
|
||||
ON gateway_recharge_orders(gateway_user_id, created_at DESC);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uniq_gateway_recharge_order_idempotency
|
||||
ON gateway_recharge_orders(gateway_user_id, idempotency_key)
|
||||
WHERE idempotency_key IS NOT NULL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS platform_models (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
platform_id uuid NOT NULL REFERENCES integration_platforms(id) ON DELETE CASCADE,
|
||||
@@ -135,8 +375,15 @@ CREATE TABLE IF NOT EXISTS gateway_tasks (
|
||||
kind text NOT NULL,
|
||||
run_mode text NOT NULL DEFAULT 'production',
|
||||
user_id text NOT NULL,
|
||||
gateway_user_id uuid REFERENCES gateway_users(id) ON DELETE SET NULL,
|
||||
user_source text NOT NULL DEFAULT 'gateway',
|
||||
gateway_tenant_id uuid REFERENCES gateway_tenants(id) ON DELETE SET NULL,
|
||||
tenant_id text,
|
||||
tenant_key text,
|
||||
api_key_id text,
|
||||
user_group_id uuid REFERENCES gateway_user_groups(id) ON DELETE SET NULL,
|
||||
user_group_key text,
|
||||
user_group_policy_snapshot jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
model text NOT NULL,
|
||||
model_type text,
|
||||
request jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
@@ -226,6 +473,29 @@ CREATE TABLE IF NOT EXISTS gateway_task_events (
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_events_task_created
|
||||
ON gateway_task_events(task_id, created_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_task_callback_outbox (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
task_id uuid NOT NULL REFERENCES gateway_tasks(id) ON DELETE CASCADE,
|
||||
event_id uuid REFERENCES gateway_task_events(id) ON DELETE SET NULL,
|
||||
seq bigint NOT NULL,
|
||||
callback_url text NOT NULL,
|
||||
payload jsonb NOT NULL,
|
||||
status text NOT NULL DEFAULT 'pending',
|
||||
attempts integer NOT NULL DEFAULT 0,
|
||||
next_attempt_at timestamptz NOT NULL DEFAULT now(),
|
||||
last_error text,
|
||||
delivered_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE(task_id, seq, callback_url)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_task_callback_outbox_pending
|
||||
ON gateway_task_callback_outbox(status, next_attempt_at);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_task_callback_outbox_task
|
||||
ON gateway_task_callback_outbox(task_id, seq);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS runtime_client_states (
|
||||
client_id text PRIMARY KEY,
|
||||
platform_id uuid REFERENCES integration_platforms(id) ON DELETE SET NULL,
|
||||
|
||||
Reference in New Issue
Block a user