AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告

M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。
含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ben
2026-08-12 11:45:54 +08:00
commit 5759c1862e
807 changed files with 114727 additions and 0 deletions
@@ -0,0 +1,212 @@
CREATE TABLE IF NOT EXISTS gateway.prompt_categories (
id uuid PRIMARY KEY,
name text NOT NULL UNIQUE,
description text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE TABLE IF NOT EXISTS gateway.prompt_templates (
id uuid PRIMARY KEY,
name text NOT NULL UNIQUE,
description text NOT NULL DEFAULT '',
category_id uuid REFERENCES gateway.prompt_categories(id) ON DELETE SET NULL,
tags text[] NOT NULL DEFAULT '{}',
department_ids uuid[] NOT NULL DEFAULT '{}',
enabled boolean NOT NULL DEFAULT true,
current_version integer,
revision bigint NOT NULL DEFAULT 1,
created_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE TABLE IF NOT EXISTS gateway.prompt_versions (
id uuid PRIMARY KEY,
template_id uuid NOT NULL REFERENCES gateway.prompt_templates(id) ON DELETE CASCADE,
version integer NOT NULL CHECK (version > 0),
content text NOT NULL CHECK (length(content) BETWEEN 1 AND 100000),
variables jsonb NOT NULL DEFAULT '[]'::jsonb CHECK (jsonb_typeof(variables) = 'array'),
change_note text NOT NULL DEFAULT '',
created_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
UNIQUE (template_id, version)
);
ALTER TABLE gateway.prompt_templates
ADD CONSTRAINT prompt_templates_current_version_fk
FOREIGN KEY (id, current_version)
REFERENCES gateway.prompt_versions(template_id, version)
DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX IF NOT EXISTS prompt_templates_visible_idx
ON gateway.prompt_templates (enabled, updated_at DESC);
CREATE TABLE IF NOT EXISTS gateway.knowledge_bases (
id uuid PRIMARY KEY,
name text NOT NULL UNIQUE,
description text NOT NULL DEFAULT '',
retrieval_mode text NOT NULL DEFAULT 'postgres_fts'
CHECK (retrieval_mode IN ('postgres_fts')),
chunk_size integer NOT NULL DEFAULT 800 CHECK (chunk_size BETWEEN 200 AND 8000),
chunk_overlap integer NOT NULL DEFAULT 100 CHECK (chunk_overlap >= 0 AND chunk_overlap <= chunk_size / 2),
department_ids uuid[] NOT NULL DEFAULT '{}',
enabled boolean NOT NULL DEFAULT true,
revision bigint NOT NULL DEFAULT 1,
created_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE TABLE IF NOT EXISTS gateway.knowledge_documents (
id uuid PRIMARY KEY,
knowledge_base_id uuid NOT NULL REFERENCES gateway.knowledge_bases(id) ON DELETE CASCADE,
title text NOT NULL,
source_type text NOT NULL DEFAULT 'text' CHECK (source_type IN ('text', 'url', 'import')),
source_uri text NOT NULL DEFAULT '',
content text NOT NULL CHECK (octet_length(content) <= 2097152),
content_sha256 char(64) NOT NULL,
status text NOT NULL DEFAULT 'ready' CHECK (status IN ('ready', 'failed')),
status_message text NOT NULL DEFAULT '',
chunk_count integer NOT NULL DEFAULT 0 CHECK (chunk_count >= 0),
created_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp(),
UNIQUE (knowledge_base_id, content_sha256)
);
CREATE TABLE IF NOT EXISTS gateway.knowledge_chunks (
id uuid PRIMARY KEY,
knowledge_base_id uuid NOT NULL REFERENCES gateway.knowledge_bases(id) ON DELETE CASCADE,
document_id uuid NOT NULL REFERENCES gateway.knowledge_documents(id) ON DELETE CASCADE,
chunk_index integer NOT NULL CHECK (chunk_index >= 0),
content text NOT NULL,
search_vector tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED,
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
UNIQUE (document_id, chunk_index)
);
CREATE INDEX IF NOT EXISTS knowledge_chunks_search_idx
ON gateway.knowledge_chunks USING gin (search_vector);
CREATE INDEX IF NOT EXISTS knowledge_chunks_base_idx
ON gateway.knowledge_chunks (knowledge_base_id, document_id, chunk_index);
CREATE TABLE IF NOT EXISTS gateway.tool_definitions (
id uuid PRIMARY KEY,
code text NOT NULL UNIQUE CHECK (code ~ '^[a-z][a-z0-9_-]{1,63}$'),
name text NOT NULL,
description text NOT NULL DEFAULT '',
endpoint_url text NOT NULL,
http_method text NOT NULL DEFAULT 'POST' CHECK (http_method IN ('GET','POST','PUT','PATCH','DELETE')),
encrypted_headers bytea NOT NULL DEFAULT ''::bytea,
headers_kek_version integer NOT NULL DEFAULT 1,
input_schema jsonb NOT NULL DEFAULT '{}'::jsonb CHECK (jsonb_typeof(input_schema) = 'object'),
timeout_seconds integer NOT NULL DEFAULT 15 CHECK (timeout_seconds BETWEEN 1 AND 120),
department_ids uuid[] NOT NULL DEFAULT '{}',
enabled boolean NOT NULL DEFAULT true,
revision bigint NOT NULL DEFAULT 1,
created_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE TABLE IF NOT EXISTS gateway.applications (
id uuid PRIMARY KEY,
code text NOT NULL UNIQUE CHECK (code ~ '^[a-z][a-z0-9_-]{2,63}$'),
name text NOT NULL,
description text NOT NULL DEFAULT '',
department_ids uuid[] NOT NULL DEFAULT '{}',
status text NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','active','suspended','retired')),
draft_config jsonb NOT NULL DEFAULT '{}'::jsonb CHECK (jsonb_typeof(draft_config) = 'object'),
published_version integer CHECK (published_version > 0),
revision bigint NOT NULL DEFAULT 1,
created_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE TABLE IF NOT EXISTS gateway.tool_runs (
id uuid PRIMARY KEY,
tool_id uuid NOT NULL REFERENCES gateway.tool_definitions(id) ON DELETE CASCADE,
api_key_id uuid REFERENCES gateway.api_keys(id) ON DELETE SET NULL,
request_id text NOT NULL,
status text NOT NULL CHECK (status IN ('success','error')),
response_status integer,
latency_ms bigint NOT NULL DEFAULT 0,
error text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE INDEX IF NOT EXISTS tool_runs_tool_time_idx
ON gateway.tool_runs (tool_id, created_at DESC);
CREATE TABLE IF NOT EXISTS gateway.application_versions (
id uuid PRIMARY KEY,
application_id uuid NOT NULL REFERENCES gateway.applications(id) ON DELETE CASCADE,
version integer NOT NULL CHECK (version > 0),
config jsonb NOT NULL CHECK (jsonb_typeof(config) = 'object'),
change_note text NOT NULL DEFAULT '',
published_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
UNIQUE (application_id, version)
);
ALTER TABLE gateway.applications
ADD CONSTRAINT applications_published_version_fk
FOREIGN KEY (id, published_version)
REFERENCES gateway.application_versions(application_id, version)
DEFERRABLE INITIALLY DEFERRED;
CREATE TABLE IF NOT EXISTS gateway.application_runs (
id uuid PRIMARY KEY,
application_id uuid NOT NULL REFERENCES gateway.applications(id) ON DELETE CASCADE,
version integer NOT NULL,
api_key_id uuid REFERENCES gateway.api_keys(id) ON DELETE SET NULL,
request_id text NOT NULL,
status text NOT NULL CHECK (status IN ('success','error')),
latency_ms bigint NOT NULL DEFAULT 0,
retrieval_count integer NOT NULL DEFAULT 0,
tool_count integer NOT NULL DEFAULT 0,
error text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE INDEX IF NOT EXISTS application_runs_app_time_idx
ON gateway.application_runs (application_id, created_at DESC);
CREATE TABLE IF NOT EXISTS gateway.notification_channels (
id uuid PRIMARY KEY,
name text NOT NULL UNIQUE,
webhook_url text NOT NULL,
encrypted_signing_secret bytea NOT NULL DEFAULT ''::bytea,
signing_secret_kek_version integer NOT NULL DEFAULT 1,
event_patterns text[] NOT NULL DEFAULT '{}',
enabled boolean NOT NULL DEFAULT true,
revision bigint NOT NULL DEFAULT 1,
created_by uuid REFERENCES gateway.admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE TABLE IF NOT EXISTS gateway.notification_deliveries (
id uuid PRIMARY KEY,
channel_id uuid NOT NULL REFERENCES gateway.notification_channels(id) ON DELETE CASCADE,
event_id uuid NOT NULL,
event_type text NOT NULL,
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
status text NOT NULL CHECK (status IN ('pending','delivered','failed')),
attempts integer NOT NULL DEFAULT 0,
response_status integer,
last_error text NOT NULL DEFAULT '',
delivered_at timestamptz,
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
updated_at timestamptz NOT NULL DEFAULT clock_timestamp(),
UNIQUE (channel_id, event_id)
);
CREATE INDEX IF NOT EXISTS notification_deliveries_status_idx
ON gateway.notification_deliveries (status, updated_at DESC);
COMMENT ON TABLE gateway.knowledge_documents IS
'Baseline stores bounded extracted text in PostgreSQL; blob/object storage is deliberately not required.';
COMMENT ON TABLE gateway.application_versions IS
'Immutable published application compositions referencing prompt, knowledge and tool assets.';