增加部署说明
This commit is contained in:
parent
4cd86d97bd
commit
0d341f0513
|
|
@ -0,0 +1,555 @@
|
||||||
|
-- public.chat_messages definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.chat_messages;
|
||||||
|
|
||||||
|
CREATE TABLE public.chat_messages (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
thread_id varchar(255) NOT NULL,
|
||||||
|
checkpoint_id varchar(255) NOT NULL,
|
||||||
|
message_index int4 NOT NULL,
|
||||||
|
"role" varchar(20) NOT NULL,
|
||||||
|
"content" text NOT NULL,
|
||||||
|
injected_content text NULL,
|
||||||
|
has_files bool DEFAULT false NULL,
|
||||||
|
metadata jsonb NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
"name" varchar(255) NULL,
|
||||||
|
CONSTRAINT chat_messages_pkey PRIMARY KEY (id),
|
||||||
|
CONSTRAINT uk_checkpoint_message UNIQUE (checkpoint_id, message_index)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_messages_checkpoint_id ON public.chat_messages USING btree (checkpoint_id);
|
||||||
|
CREATE INDEX idx_chat_messages_content_search ON public.chat_messages USING gin (to_tsvector('simple'::regconfig, content));
|
||||||
|
CREATE INDEX idx_chat_messages_has_files ON public.chat_messages USING btree (has_files);
|
||||||
|
CREATE INDEX idx_chat_messages_metadata ON public.chat_messages USING gin (metadata);
|
||||||
|
CREATE INDEX idx_chat_messages_role ON public.chat_messages USING btree (role);
|
||||||
|
CREATE INDEX idx_chat_messages_thread_created ON public.chat_messages USING btree (thread_id, created_at DESC);
|
||||||
|
CREATE INDEX idx_chat_messages_thread_id ON public.chat_messages USING btree (thread_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.checkpoint_blobs definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.checkpoint_blobs;
|
||||||
|
|
||||||
|
CREATE TABLE public.checkpoint_blobs (
|
||||||
|
thread_id text NOT NULL,
|
||||||
|
checkpoint_ns text DEFAULT ''::text NOT NULL,
|
||||||
|
channel text NOT NULL,
|
||||||
|
"version" text NOT NULL,
|
||||||
|
"type" text NOT NULL,
|
||||||
|
"blob" bytea NULL,
|
||||||
|
CONSTRAINT checkpoint_blobs_pkey PRIMARY KEY (thread_id, checkpoint_ns, channel, version)
|
||||||
|
);
|
||||||
|
CREATE INDEX checkpoint_blobs_thread_id_idx ON public.checkpoint_blobs USING btree (thread_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.checkpoint_migrations definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.checkpoint_migrations;
|
||||||
|
|
||||||
|
CREATE TABLE public.checkpoint_migrations (
|
||||||
|
v int4 NOT NULL,
|
||||||
|
CONSTRAINT checkpoint_migrations_pkey PRIMARY KEY (v)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.checkpoint_writes definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.checkpoint_writes;
|
||||||
|
|
||||||
|
CREATE TABLE public.checkpoint_writes (
|
||||||
|
thread_id text NOT NULL,
|
||||||
|
checkpoint_ns text DEFAULT ''::text NOT NULL,
|
||||||
|
checkpoint_id text NOT NULL,
|
||||||
|
task_id text NOT NULL,
|
||||||
|
idx int4 NOT NULL,
|
||||||
|
channel text NOT NULL,
|
||||||
|
"type" text NULL,
|
||||||
|
"blob" bytea NOT NULL,
|
||||||
|
task_path text DEFAULT ''::text NOT NULL,
|
||||||
|
CONSTRAINT checkpoint_writes_pkey PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id, task_id, idx)
|
||||||
|
);
|
||||||
|
CREATE INDEX checkpoint_writes_thread_id_idx ON public.checkpoint_writes USING btree (thread_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.checkpoints definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.checkpoints;
|
||||||
|
|
||||||
|
CREATE TABLE public.checkpoints (
|
||||||
|
thread_id text NOT NULL,
|
||||||
|
checkpoint_ns text DEFAULT ''::text NOT NULL,
|
||||||
|
checkpoint_id text NOT NULL,
|
||||||
|
parent_checkpoint_id text NULL,
|
||||||
|
"type" text NULL,
|
||||||
|
"checkpoint" jsonb NOT NULL,
|
||||||
|
metadata jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||||
|
CONSTRAINT checkpoints_pkey PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX checkpoints_thread_id_idx ON public.checkpoints USING btree (thread_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.enterprise definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.enterprise;
|
||||||
|
|
||||||
|
CREATE TABLE public.enterprise (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
code varchar(64) NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
ai_display_name varchar(128) DEFAULT '智能助手 AI'::character varying NOT NULL,
|
||||||
|
CONSTRAINT enterprise_code_key UNIQUE (code),
|
||||||
|
CONSTRAINT enterprise_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_message_file definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.chat_message_file;
|
||||||
|
|
||||||
|
CREATE TABLE public.chat_message_file (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
thread_id varchar(255) NOT NULL,
|
||||||
|
checkpoint_id varchar(255) NOT NULL,
|
||||||
|
message_index int4 NOT NULL,
|
||||||
|
file_id int4 NOT NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
CONSTRAINT chat_message_file_pkey PRIMARY KEY (id),
|
||||||
|
CONSTRAINT uk_message_file UNIQUE (checkpoint_id, message_index, file_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_message_file_checkpoint ON public.chat_message_file USING btree (checkpoint_id, message_index);
|
||||||
|
CREATE INDEX idx_chat_message_file_file_id ON public.chat_message_file USING btree (file_id);
|
||||||
|
CREATE INDEX idx_chat_message_file_thread_checkpoint ON public.chat_message_file USING btree (thread_id, checkpoint_id);
|
||||||
|
CREATE INDEX idx_chat_message_file_thread_id ON public.chat_message_file USING btree (thread_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_thread_chunk definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.chat_thread_chunk;
|
||||||
|
|
||||||
|
CREATE TABLE public.chat_thread_chunk (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
file_id int4 NOT NULL,
|
||||||
|
thread_id varchar(255) NOT NULL,
|
||||||
|
chunk_index int4 NOT NULL,
|
||||||
|
"content" text NOT NULL,
|
||||||
|
metadata jsonb NULL,
|
||||||
|
vector_id varchar(255) NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
summary text NULL,
|
||||||
|
CONSTRAINT chat_thread_chunk_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_thread_chunk_created_at ON public.chat_thread_chunk USING btree (created_at);
|
||||||
|
CREATE INDEX idx_chat_thread_chunk_file_id ON public.chat_thread_chunk USING btree (file_id);
|
||||||
|
CREATE INDEX idx_chat_thread_chunk_file_thread ON public.chat_thread_chunk USING btree (file_id, thread_id);
|
||||||
|
CREATE INDEX idx_chat_thread_chunk_thread_id ON public.chat_thread_chunk USING btree (thread_id);
|
||||||
|
CREATE INDEX idx_chat_thread_chunk_vector_id ON public.chat_thread_chunk USING btree (vector_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_thread_file definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.chat_thread_file;
|
||||||
|
|
||||||
|
CREATE TABLE public.chat_thread_file (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
thread_id varchar(255) NOT NULL,
|
||||||
|
user_id int4 NOT NULL,
|
||||||
|
file_name varchar(255) NOT NULL,
|
||||||
|
file_path varchar(500) NOT NULL,
|
||||||
|
file_size int4 DEFAULT 0 NULL,
|
||||||
|
file_type varchar(50) DEFAULT 'pdf'::character varying NULL,
|
||||||
|
status varchar(20) DEFAULT 'processing'::character varying NULL,
|
||||||
|
chunk_count int4 DEFAULT 0 NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
is_deleted bool DEFAULT false NULL,
|
||||||
|
deleted_at timestamptz NULL,
|
||||||
|
CONSTRAINT chat_thread_file_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_thread_file_created_at ON public.chat_thread_file USING btree (created_at);
|
||||||
|
CREATE INDEX idx_chat_thread_file_is_deleted ON public.chat_thread_file USING btree (is_deleted);
|
||||||
|
CREATE INDEX idx_chat_thread_file_status ON public.chat_thread_file USING btree (status);
|
||||||
|
CREATE INDEX idx_chat_thread_file_thread_deleted ON public.chat_thread_file USING btree (thread_id, is_deleted);
|
||||||
|
CREATE INDEX idx_chat_thread_file_thread_id ON public.chat_thread_file USING btree (thread_id);
|
||||||
|
CREATE INDEX idx_chat_thread_file_thread_user ON public.chat_thread_file USING btree (thread_id, user_id);
|
||||||
|
CREATE INDEX idx_chat_thread_file_user_id ON public.chat_thread_file USING btree (user_id);
|
||||||
|
CREATE UNIQUE INDEX uk_chat_thread_file_thread_name_active ON public.chat_thread_file USING btree (thread_id, file_name) WHERE (is_deleted = false);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_threads definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.chat_threads;
|
||||||
|
|
||||||
|
CREATE TABLE public.chat_threads (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
thread_id varchar(255) NOT NULL,
|
||||||
|
user_id int4 NOT NULL,
|
||||||
|
title varchar(50) NOT NULL,
|
||||||
|
first_query text NOT NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
message_count int4 DEFAULT 1 NULL,
|
||||||
|
is_deleted bool DEFAULT false NULL,
|
||||||
|
knowledge_base_id int4 NULL,
|
||||||
|
novel_graph_id int4 NULL,
|
||||||
|
knowledge_graph_id int4 NULL,
|
||||||
|
ip varchar(128) NULL,
|
||||||
|
CONSTRAINT chat_threads_pkey PRIMARY KEY (id),
|
||||||
|
CONSTRAINT uk_thread_id UNIQUE (thread_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_chat_threads_created_at ON public.chat_threads USING btree (created_at DESC);
|
||||||
|
CREATE INDEX idx_chat_threads_knowledge_graph_id ON public.chat_threads USING btree (knowledge_graph_id);
|
||||||
|
CREATE INDEX idx_chat_threads_novel_graph_id ON public.chat_threads USING btree (novel_graph_id);
|
||||||
|
CREATE INDEX idx_chat_threads_user_created ON public.chat_threads USING btree (user_id, created_at DESC);
|
||||||
|
CREATE INDEX idx_chat_threads_user_id ON public.chat_threads USING btree (user_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.department definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.department;
|
||||||
|
|
||||||
|
CREATE TABLE public.department (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
enterprise_id int4 NOT NULL,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
parent_id int4 NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
leader_user_id int4 NULL,
|
||||||
|
CONSTRAINT department_pkey PRIMARY KEY (id),
|
||||||
|
CONSTRAINT uq_department_enterprise_name UNIQUE (enterprise_id, name)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_department_enterprise_id ON public.department USING btree (enterprise_id);
|
||||||
|
CREATE INDEX idx_department_leader_user_id ON public.department USING btree (leader_user_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.graphs definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.graphs;
|
||||||
|
|
||||||
|
CREATE TABLE public.graphs (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
user_id int4 NOT NULL,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
description text NULL,
|
||||||
|
csv_file_name varchar(255) NULL,
|
||||||
|
node_count int4 DEFAULT 0 NULL,
|
||||||
|
edge_count int4 DEFAULT 0 NULL,
|
||||||
|
neo4j_graph_id varchar(100) NOT NULL,
|
||||||
|
graph_type varchar(20) DEFAULT 'knowledge'::character varying NOT NULL,
|
||||||
|
build_status varchar(20) NULL,
|
||||||
|
build_error text NULL,
|
||||||
|
rag_chunk_count int4 DEFAULT 0 NOT NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
enterprise_id int4 NOT NULL,
|
||||||
|
department_id int4 NULL,
|
||||||
|
creator_id int4 NOT NULL,
|
||||||
|
visibility varchar(32) DEFAULT 'private'::character varying NOT NULL,
|
||||||
|
CONSTRAINT ck_graphs_visibility CHECK (((visibility)::text = ANY ((ARRAY['private'::character varying, 'department'::character varying, 'enterprise'::character varying])::text[]))),
|
||||||
|
CONSTRAINT graphs_neo4j_graph_id_key UNIQUE (neo4j_graph_id),
|
||||||
|
CONSTRAINT graphs_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_graphs_created_at ON public.graphs USING btree (created_at DESC);
|
||||||
|
CREATE INDEX idx_graphs_creator ON public.graphs USING btree (creator_id);
|
||||||
|
CREATE INDEX idx_graphs_ent_vis ON public.graphs USING btree (enterprise_id, visibility);
|
||||||
|
CREATE INDEX idx_graphs_enterprise ON public.graphs USING btree (enterprise_id);
|
||||||
|
CREATE INDEX idx_graphs_graph_type ON public.graphs USING btree (user_id, graph_type);
|
||||||
|
CREATE INDEX idx_graphs_neo4j_id ON public.graphs USING btree (neo4j_graph_id);
|
||||||
|
CREATE INDEX idx_graphs_user_id ON public.graphs USING btree (user_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.kb_audit_log definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.kb_audit_log;
|
||||||
|
|
||||||
|
CREATE TABLE public.kb_audit_log (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
enterprise_id int4 NOT NULL,
|
||||||
|
actor_id int4 NOT NULL,
|
||||||
|
target_user_id int4 NULL,
|
||||||
|
department_id int4 NULL,
|
||||||
|
kb_id int4 NULL,
|
||||||
|
file_id int4 NULL,
|
||||||
|
"action" varchar(50) NOT NULL,
|
||||||
|
ip varchar(128) NULL,
|
||||||
|
user_agent text NULL,
|
||||||
|
metadata jsonb NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
CONSTRAINT kb_audit_log_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_kb_audit_log_action ON public.kb_audit_log USING btree (action);
|
||||||
|
CREATE INDEX idx_kb_audit_log_actor_id ON public.kb_audit_log USING btree (actor_id);
|
||||||
|
CREATE INDEX idx_kb_audit_log_created_at ON public.kb_audit_log USING btree (created_at DESC);
|
||||||
|
CREATE INDEX idx_kb_audit_log_department_id ON public.kb_audit_log USING btree (department_id);
|
||||||
|
CREATE INDEX idx_kb_audit_log_ent_dept_created ON public.kb_audit_log USING btree (enterprise_id, department_id, created_at DESC);
|
||||||
|
CREATE INDEX idx_kb_audit_log_enterprise_id ON public.kb_audit_log USING btree (enterprise_id);
|
||||||
|
CREATE INDEX idx_kb_audit_log_kb_id ON public.kb_audit_log USING btree (kb_id);
|
||||||
|
CREATE INDEX idx_kb_audit_log_target_user_id ON public.kb_audit_log USING btree (target_user_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_base definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.knowledge_base;
|
||||||
|
|
||||||
|
CREATE TABLE public.knowledge_base (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
user_id int4 NOT NULL,
|
||||||
|
"name" varchar(255) NOT NULL,
|
||||||
|
description text NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
is_deleted bool DEFAULT false NULL,
|
||||||
|
deleted_at timestamptz NULL,
|
||||||
|
enterprise_id int4 DEFAULT 1 NOT NULL,
|
||||||
|
department_id int4 NULL,
|
||||||
|
creator_id int4 NULL,
|
||||||
|
visibility varchar(32) DEFAULT 'private'::character varying NOT NULL,
|
||||||
|
CONSTRAINT ck_knowledge_base_visibility CHECK (((visibility)::text = ANY ((ARRAY['private'::character varying, 'department'::character varying, 'enterprise'::character varying])::text[]))),
|
||||||
|
CONSTRAINT knowledge_base_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_knowledge_base_created_at ON public.knowledge_base USING btree (created_at);
|
||||||
|
CREATE INDEX idx_knowledge_base_creator ON public.knowledge_base USING btree (creator_id);
|
||||||
|
CREATE INDEX idx_knowledge_base_ent_vis ON public.knowledge_base USING btree (enterprise_id, visibility) WHERE (is_deleted = false);
|
||||||
|
CREATE INDEX idx_knowledge_base_enterprise ON public.knowledge_base USING btree (enterprise_id);
|
||||||
|
CREATE INDEX idx_knowledge_base_is_deleted ON public.knowledge_base USING btree (is_deleted);
|
||||||
|
CREATE INDEX idx_knowledge_base_user_deleted ON public.knowledge_base USING btree (user_id, is_deleted);
|
||||||
|
CREATE INDEX idx_knowledge_base_user_id ON public.knowledge_base USING btree (user_id);
|
||||||
|
CREATE INDEX idx_knowledge_base_user_name ON public.knowledge_base USING btree (user_id, name);
|
||||||
|
CREATE UNIQUE INDEX uk_user_knowledge_base_name_active ON public.knowledge_base USING btree (user_id, name) WHERE (is_deleted = false);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_base_chunk definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.knowledge_base_chunk;
|
||||||
|
|
||||||
|
CREATE TABLE public.knowledge_base_chunk (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
file_id int4 NOT NULL,
|
||||||
|
knowledge_base_id int4 NOT NULL,
|
||||||
|
chunk_index int4 NOT NULL,
|
||||||
|
"content" text NOT NULL,
|
||||||
|
metadata jsonb NULL,
|
||||||
|
vector_id varchar(255) NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
summary text NULL,
|
||||||
|
CONSTRAINT knowledge_base_chunk_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_kb_chunk_file_id ON public.knowledge_base_chunk USING btree (file_id);
|
||||||
|
CREATE INDEX idx_kb_chunk_kb_id ON public.knowledge_base_chunk USING btree (knowledge_base_id);
|
||||||
|
CREATE INDEX idx_kb_chunk_metadata ON public.knowledge_base_chunk USING gin (metadata);
|
||||||
|
CREATE INDEX idx_kb_chunk_vector_id ON public.knowledge_base_chunk USING btree (vector_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_base_file definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.knowledge_base_file;
|
||||||
|
|
||||||
|
CREATE TABLE public.knowledge_base_file (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
knowledge_base_id int4 NOT NULL,
|
||||||
|
user_id int4 NOT NULL,
|
||||||
|
file_name varchar(255) NOT NULL,
|
||||||
|
file_path varchar(500) NOT NULL,
|
||||||
|
file_size int8 NOT NULL,
|
||||||
|
file_type varchar(50) DEFAULT 'pdf'::character varying NOT NULL,
|
||||||
|
status varchar(20) DEFAULT 'processing'::character varying NOT NULL,
|
||||||
|
chunk_count int4 DEFAULT 0 NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
is_deleted bool DEFAULT false NULL,
|
||||||
|
deleted_at timestamptz NULL,
|
||||||
|
CONSTRAINT knowledge_base_file_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_kb_file_created_at ON public.knowledge_base_file USING btree (created_at);
|
||||||
|
CREATE INDEX idx_kb_file_kb_id ON public.knowledge_base_file USING btree (knowledge_base_id);
|
||||||
|
CREATE INDEX idx_kb_file_status ON public.knowledge_base_file USING btree (status);
|
||||||
|
CREATE UNIQUE INDEX idx_kb_file_unique_active ON public.knowledge_base_file USING btree (knowledge_base_id, file_name) WHERE (is_deleted = false);
|
||||||
|
CREATE INDEX idx_kb_file_user_id ON public.knowledge_base_file USING btree (user_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_processing_task definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.knowledge_processing_task;
|
||||||
|
|
||||||
|
CREATE TABLE public.knowledge_processing_task (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
user_id int4 NOT NULL,
|
||||||
|
knowledge_base_id int4 NOT NULL,
|
||||||
|
task_name varchar(255) NOT NULL,
|
||||||
|
instruction text NOT NULL,
|
||||||
|
file_ids _int4 NOT NULL,
|
||||||
|
task_type varchar(50) NOT NULL,
|
||||||
|
status varchar(20) DEFAULT 'pending'::character varying NULL,
|
||||||
|
"result" text NULL,
|
||||||
|
result_file_url text NULL,
|
||||||
|
error_message text NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
started_at timestamptz NULL,
|
||||||
|
completed_at timestamptz NULL,
|
||||||
|
CONSTRAINT knowledge_processing_task_pkey PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_kb_processing_created_at ON public.knowledge_processing_task USING btree (created_at DESC);
|
||||||
|
CREATE INDEX idx_kb_processing_kb_id ON public.knowledge_processing_task USING btree (knowledge_base_id);
|
||||||
|
CREATE INDEX idx_kb_processing_status ON public.knowledge_processing_task USING btree (status);
|
||||||
|
CREATE INDEX idx_kb_processing_user_id ON public.knowledge_processing_task USING btree (user_id);
|
||||||
|
CREATE INDEX idx_kb_processing_user_status ON public.knowledge_processing_task USING btree (user_id, status);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.user_list definition
|
||||||
|
|
||||||
|
-- Drop table
|
||||||
|
|
||||||
|
-- DROP TABLE public.user_list;
|
||||||
|
|
||||||
|
CREATE TABLE public.user_list (
|
||||||
|
id serial4 NOT NULL,
|
||||||
|
username varchar(50) NOT NULL,
|
||||||
|
email varchar(255) NOT NULL,
|
||||||
|
phone varchar(255) NOT NULL,
|
||||||
|
github_id varchar(100) NULL,
|
||||||
|
github_username varchar(100) NULL,
|
||||||
|
github_avatar_url text NULL,
|
||||||
|
github_access_token text NULL,
|
||||||
|
github_token_expires_at timestamptz NULL,
|
||||||
|
display_name varchar(100) NULL,
|
||||||
|
avatar_url text NULL,
|
||||||
|
bio text NULL,
|
||||||
|
is_active bool DEFAULT true NULL,
|
||||||
|
email_verified bool DEFAULT false NULL,
|
||||||
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
|
last_login_at timestamptz NULL,
|
||||||
|
hashed_password varchar(255) NULL,
|
||||||
|
is_search bool DEFAULT false NULL,
|
||||||
|
is_reasoner bool DEFAULT false NULL,
|
||||||
|
enterprise_id int4 DEFAULT 1 NOT NULL,
|
||||||
|
department_id int4 NULL,
|
||||||
|
"role" varchar(32) DEFAULT 'employee'::character varying NOT NULL,
|
||||||
|
is_first_login bool DEFAULT true NOT NULL,
|
||||||
|
allow_kb_upload bool DEFAULT true NOT NULL,
|
||||||
|
CONSTRAINT unique_email UNIQUE (email),
|
||||||
|
CONSTRAINT unique_github_id UNIQUE (github_id),
|
||||||
|
CONSTRAINT user_list_phone_key UNIQUE (phone),
|
||||||
|
CONSTRAINT user_list_pkey PRIMARY KEY (id),
|
||||||
|
CONSTRAINT user_list_username_key UNIQUE (username)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_user_list_created_at ON public.user_list USING btree (created_at);
|
||||||
|
CREATE INDEX idx_user_list_department_id ON public.user_list USING btree (department_id);
|
||||||
|
CREATE INDEX idx_user_list_email ON public.user_list USING btree (email);
|
||||||
|
CREATE INDEX idx_user_list_enterprise_id ON public.user_list USING btree (enterprise_id);
|
||||||
|
CREATE INDEX idx_user_list_github_id ON public.user_list USING btree (github_id);
|
||||||
|
CREATE INDEX idx_user_list_role ON public.user_list USING btree (role);
|
||||||
|
CREATE INDEX idx_user_list_username ON public.user_list USING btree (username);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_message_file foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.chat_message_file ADD CONSTRAINT fk_chat_message_file_file FOREIGN KEY (file_id) REFERENCES public.chat_thread_file(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_thread_chunk foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.chat_thread_chunk ADD CONSTRAINT fk_chat_thread_chunk_file FOREIGN KEY (file_id) REFERENCES public.chat_thread_file(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_thread_file foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.chat_thread_file ADD CONSTRAINT fk_chat_thread_file_user FOREIGN KEY (user_id) REFERENCES public.user_list(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.chat_threads foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.chat_threads ADD CONSTRAINT fk_chat_threads_knowledge_graph FOREIGN KEY (knowledge_graph_id) REFERENCES public.graphs(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.chat_threads ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES public.user_list(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.department foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.department ADD CONSTRAINT department_enterprise_id_fkey FOREIGN KEY (enterprise_id) REFERENCES public.enterprise(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE public.department ADD CONSTRAINT department_leader_user_id_fkey FOREIGN KEY (leader_user_id) REFERENCES public.user_list(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.department ADD CONSTRAINT department_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES public.department(id) ON DELETE SET NULL;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.graphs foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.graphs ADD CONSTRAINT fk_graphs_user FOREIGN KEY (user_id) REFERENCES public.user_list(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE public.graphs ADD CONSTRAINT graphs_creator_id_fkey FOREIGN KEY (creator_id) REFERENCES public.user_list(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.graphs ADD CONSTRAINT graphs_department_id_fkey FOREIGN KEY (department_id) REFERENCES public.department(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.graphs ADD CONSTRAINT graphs_enterprise_id_fkey FOREIGN KEY (enterprise_id) REFERENCES public.enterprise(id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.kb_audit_log foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.kb_audit_log ADD CONSTRAINT kb_audit_log_actor_id_fkey FOREIGN KEY (actor_id) REFERENCES public.user_list(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE public.kb_audit_log ADD CONSTRAINT kb_audit_log_department_id_fkey FOREIGN KEY (department_id) REFERENCES public.department(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.kb_audit_log ADD CONSTRAINT kb_audit_log_enterprise_id_fkey FOREIGN KEY (enterprise_id) REFERENCES public.enterprise(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE public.kb_audit_log ADD CONSTRAINT kb_audit_log_file_id_fkey FOREIGN KEY (file_id) REFERENCES public.knowledge_base_file(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.kb_audit_log ADD CONSTRAINT kb_audit_log_kb_id_fkey FOREIGN KEY (kb_id) REFERENCES public.knowledge_base(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.kb_audit_log ADD CONSTRAINT kb_audit_log_target_user_id_fkey FOREIGN KEY (target_user_id) REFERENCES public.user_list(id) ON DELETE SET NULL;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_base foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.knowledge_base ADD CONSTRAINT knowledge_base_creator_id_fkey FOREIGN KEY (creator_id) REFERENCES public.user_list(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE public.knowledge_base ADD CONSTRAINT knowledge_base_department_id_fkey FOREIGN KEY (department_id) REFERENCES public.department(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.knowledge_base ADD CONSTRAINT knowledge_base_enterprise_id_fkey FOREIGN KEY (enterprise_id) REFERENCES public.enterprise(id);
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_base_chunk foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.knowledge_base_chunk ADD CONSTRAINT fk_kb FOREIGN KEY (knowledge_base_id) REFERENCES public.knowledge_base(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE public.knowledge_base_chunk ADD CONSTRAINT fk_kb_file FOREIGN KEY (file_id) REFERENCES public.knowledge_base_file(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_base_file foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.knowledge_base_file ADD CONSTRAINT fk_knowledge_base FOREIGN KEY (knowledge_base_id) REFERENCES public.knowledge_base(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.knowledge_processing_task foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.knowledge_processing_task ADD CONSTRAINT fk_kb_processing_kb FOREIGN KEY (knowledge_base_id) REFERENCES public.knowledge_base(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE public.knowledge_processing_task ADD CONSTRAINT fk_kb_processing_user FOREIGN KEY (user_id) REFERENCES public.user_list(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- public.user_list foreign keys
|
||||||
|
|
||||||
|
ALTER TABLE public.user_list ADD CONSTRAINT user_list_department_id_fkey FOREIGN KEY (department_id) REFERENCES public.department(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE public.user_list ADD CONSTRAINT user_list_enterprise_id_fkey FOREIGN KEY (enterprise_id) REFERENCES public.enterprise(id);
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
# 如何部署 Backend
|
||||||
|
|
||||||
|
本仓库的 HTTP API 由 `backend/` 目录下的 **FastAPI** 服务提供,`frontend` 与 `admin-frontend` 均请求同一套后端接口。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、环境准备
|
||||||
|
|
||||||
|
### 1.1 运行环境
|
||||||
|
|
||||||
|
| 组件 | 版本 / 说明 |
|
||||||
|
|------|-------------|
|
||||||
|
| Python | **3.11**(与 `backend/pyproject.toml` 中 `requires-python` 一致) |
|
||||||
|
| 包管理 | 推荐 [uv](https://docs.astral.sh/uv/)(项目含 `uv.lock`) |
|
||||||
|
| PostgreSQL | **14+**(主库,必选) |
|
||||||
|
| Redis | **6+**(短信验证码、图形验证码等,可选) |
|
||||||
|
| ChromaDB | 向量检索(知识库 RAG,按业务需要部署,必选) |
|
||||||
|
| Neo4j | 知识图谱(按业务需要部署,必选) |
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、数据库初始化
|
||||||
|
|
||||||
|
后端依赖 PostgreSQL。首次部署请在**空库**上执行项目根目录的初始化脚本:
|
||||||
|
|
||||||
|
|
||||||
|
`ddl-init.sql` 会创建完整表结构
|
||||||
|
|
||||||
|
初始化完成后,在 `backend/.env` 中配置与上述库一致的数据库连接(见下文)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、配置环境变量
|
||||||
|
|
||||||
|
在 `backend/` 目录复制示例配置并修改:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
至少修改以下项(生产环境务必使用强密码与随机 `JWT_SECRET_KEY`):
|
||||||
|
|
||||||
|
| 变量 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `API.HOST` / `API.PORT` | 监听地址与端口(默认 `0.0.0.0:7862`) |
|
||||||
|
| `DB_HOST`、`DB_PORT`、`DB_NAME`、`DB_USER`、`DB_PASSWORD` | PostgreSQL,需与 `ddl-init.sql` 执行的库一致 |
|
||||||
|
| `JWT_SECRET_KEY` | JWT 签名密钥 |
|
||||||
|
| `REDIS_HOST`、`REDIS_PORT` | Redis(未在 `.env.example` 列出时,默认 `127.0.0.1:6379`,可在 `.env` 中显式配置) |
|
||||||
|
| `CHROMA_HOST`、`CHROMA_PORT` | ChromaDB 地址(启用知识库向量检索时) |
|
||||||
|
| `NEO4J_URI`、`NEO4J_USER`、`NEO4J_PASSWORD` | Neo4j(启用知识图谱时) |
|
||||||
|
| `DASHSCOPE_API_KEY` / `DEEPSEEK_API_KEY` 等 | 大模型与 Embedding(聊天、RAG 必需) |
|
||||||
|
| `OSS_*` | 阿里云 OSS(文件上传,按需) |
|
||||||
|
| `MODERATION_ENABLED` | 内容审核;关闭时可不配置阿里云审核密钥 |
|
||||||
|
|
||||||
|
完整字段说明见 `backend/.env.example` 与 `backend/core/config.py`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、本地部署(推荐开发 / 单机生产)
|
||||||
|
|
||||||
|
### 4.1 安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
uv sync --frozen
|
||||||
|
```
|
||||||
|
|
||||||
|
仅安装生产依赖(与 Docker 构建一致):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv sync --frozen --no-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 启动服务
|
||||||
|
|
||||||
|
在 **`backend` 目录**下执行(会读取 `backend/.env` 中的 `API.HOST` / `API.PORT`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv run python -m main
|
||||||
|
```
|
||||||
|
|
||||||
|
开发热重载(同样需在 `backend` 目录):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv run python -m main
|
||||||
|
# 或显式指定端口(须与 .env 中 API.PORT 一致)
|
||||||
|
uv run uvicorn main:app --reload --host 0.0.0.0 --port 7862
|
||||||
|
```
|
||||||
|
|
||||||
|
> **注意**:若直接运行 `uvicorn main:app` 且未传 `--port`,默认端口为 **8000**,不会自动读取 `.env` 中的 `API.PORT`。生产环境请使用 `python -m main` 或显式传入 `--port`。
|
||||||
|
|
||||||
|
### 4.3 验证
|
||||||
|
|
||||||
|
- 健康:查看启动日志中是否有「数据库健康检查通过」
|
||||||
|
- API 文档:浏览器打开 `http://<主机>:<端口>/docs`(根路径 `/` 会重定向到 Swagger)
|
||||||
|
- 管理端接口:前缀为 `/api/admin/...`,需 `role=admin` 用户登录后携带 JWT
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
675
sql.txt
675
sql.txt
|
|
@ -1,675 +0,0 @@
|
||||||
create table public.chat_messages
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
thread_id varchar(255) not null,
|
|
||||||
checkpoint_id varchar(255) not null,
|
|
||||||
message_index integer not null,
|
|
||||||
role varchar(20) not null,
|
|
||||||
content text not null,
|
|
||||||
injected_content text,
|
|
||||||
has_files boolean default false,
|
|
||||||
metadata jsonb,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
name varchar(255),
|
|
||||||
constraint uk_checkpoint_message
|
|
||||||
unique (checkpoint_id, message_index)
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on table public.chat_messages is '聊天消息表,存储用户原始消息和AI响应的关键信息';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.thread_id is '会话线程ID';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.checkpoint_id is '关联的checkpoint ID';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.message_index is '消息在checkpoint中的索引(从0开始)';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.role is '消息角色:user、assistant、system、tool';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.content is '用户的原始问题或AI的响应';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.injected_content is '注入给AI的完整内容(包含文件内容)';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.has_files is '是否关联了文件';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.metadata is '额外信息:token、模型、推理内容等';
|
|
||||||
|
|
||||||
comment on column public.chat_messages.name is '工具消息时的工具名称(如 internet_search、text_to_image)';
|
|
||||||
|
|
||||||
alter table public.chat_messages
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_chat_messages_thread_id
|
|
||||||
on public.chat_messages (thread_id);
|
|
||||||
|
|
||||||
create index idx_chat_messages_checkpoint_id
|
|
||||||
on public.chat_messages (checkpoint_id);
|
|
||||||
|
|
||||||
create index idx_chat_messages_thread_created
|
|
||||||
on public.chat_messages (thread_id asc, created_at desc);
|
|
||||||
|
|
||||||
create index idx_chat_messages_role
|
|
||||||
on public.chat_messages (role);
|
|
||||||
|
|
||||||
create index idx_chat_messages_has_files
|
|
||||||
on public.chat_messages (has_files);
|
|
||||||
|
|
||||||
create index idx_chat_messages_metadata
|
|
||||||
on public.chat_messages using gin (metadata);
|
|
||||||
|
|
||||||
create index idx_chat_messages_content_search
|
|
||||||
on public.chat_messages using gin (to_tsvector('simple'::regconfig, content));
|
|
||||||
|
|
||||||
create table public.checkpoint_migrations
|
|
||||||
(
|
|
||||||
v integer not null
|
|
||||||
primary key
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.checkpoint_migrations
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create table public.checkpoints
|
|
||||||
(
|
|
||||||
thread_id text not null,
|
|
||||||
checkpoint_ns text default ''::text not null,
|
|
||||||
checkpoint_id text not null,
|
|
||||||
parent_checkpoint_id text,
|
|
||||||
type text,
|
|
||||||
checkpoint jsonb not null,
|
|
||||||
metadata jsonb default '{}'::jsonb not null,
|
|
||||||
primary key (thread_id, checkpoint_ns, checkpoint_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.checkpoints
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index checkpoints_thread_id_idx
|
|
||||||
on public.checkpoints (thread_id);
|
|
||||||
|
|
||||||
create table public.checkpoint_blobs
|
|
||||||
(
|
|
||||||
thread_id text not null,
|
|
||||||
checkpoint_ns text default ''::text not null,
|
|
||||||
channel text not null,
|
|
||||||
version text not null,
|
|
||||||
type text not null,
|
|
||||||
blob bytea,
|
|
||||||
primary key (thread_id, checkpoint_ns, channel, version)
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.checkpoint_blobs
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index checkpoint_blobs_thread_id_idx
|
|
||||||
on public.checkpoint_blobs (thread_id);
|
|
||||||
|
|
||||||
create table public.checkpoint_writes
|
|
||||||
(
|
|
||||||
thread_id text not null,
|
|
||||||
checkpoint_ns text default ''::text not null,
|
|
||||||
checkpoint_id text not null,
|
|
||||||
task_id text not null,
|
|
||||||
idx integer not null,
|
|
||||||
channel text not null,
|
|
||||||
type text,
|
|
||||||
blob bytea not null,
|
|
||||||
task_path text default ''::text not null,
|
|
||||||
primary key (thread_id, checkpoint_ns, checkpoint_id, task_id, idx)
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.checkpoint_writes
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index checkpoint_writes_thread_id_idx
|
|
||||||
on public.checkpoint_writes (thread_id);
|
|
||||||
|
|
||||||
create table public.enterprise
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
name varchar(255) not null,
|
|
||||||
code varchar(64)
|
|
||||||
unique,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP not null,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP not null
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on table public.enterprise is '企业(单租户部署通常仅一条记录)';
|
|
||||||
|
|
||||||
alter table public.enterprise
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create table public.department
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
enterprise_id integer not null
|
|
||||||
references public.enterprise
|
|
||||||
on delete cascade,
|
|
||||||
name varchar(255) not null,
|
|
||||||
parent_id integer
|
|
||||||
references public.department
|
|
||||||
on delete set null,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP not null,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP not null,
|
|
||||||
constraint uq_department_enterprise_name
|
|
||||||
unique (enterprise_id, name)
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on table public.department is '部门';
|
|
||||||
|
|
||||||
alter table public.department
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create table public.user_list
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
username varchar(50) not null
|
|
||||||
unique,
|
|
||||||
email varchar(255) not null
|
|
||||||
constraint unique_email
|
|
||||||
unique,
|
|
||||||
phone varchar(255) not null
|
|
||||||
unique,
|
|
||||||
github_id varchar(100)
|
|
||||||
constraint unique_github_id
|
|
||||||
unique,
|
|
||||||
github_username varchar(100),
|
|
||||||
github_avatar_url text,
|
|
||||||
github_access_token text,
|
|
||||||
github_token_expires_at timestamp with time zone,
|
|
||||||
display_name varchar(100),
|
|
||||||
avatar_url text,
|
|
||||||
bio text,
|
|
||||||
is_active boolean default true,
|
|
||||||
email_verified boolean default false,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
last_login_at timestamp with time zone,
|
|
||||||
hashed_password varchar(255),
|
|
||||||
is_search boolean default false,
|
|
||||||
is_reasoner boolean default false,
|
|
||||||
enterprise_id integer default 1 not null
|
|
||||||
references public.enterprise,
|
|
||||||
department_id integer
|
|
||||||
references public.department
|
|
||||||
on delete set null,
|
|
||||||
role varchar(32) default 'employee'::character varying not null,
|
|
||||||
is_first_login boolean default true not null
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on column public.user_list.role is 'admin | leader | employee';
|
|
||||||
|
|
||||||
comment on column public.user_list.is_first_login is '首次登录可强制改密(可选业务)';
|
|
||||||
|
|
||||||
alter table public.user_list
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_user_list_github_id
|
|
||||||
on public.user_list (github_id);
|
|
||||||
|
|
||||||
create index idx_user_list_email
|
|
||||||
on public.user_list (email);
|
|
||||||
|
|
||||||
create index idx_user_list_username
|
|
||||||
on public.user_list (username);
|
|
||||||
|
|
||||||
create index idx_user_list_created_at
|
|
||||||
on public.user_list (created_at);
|
|
||||||
|
|
||||||
create index idx_user_list_enterprise_id
|
|
||||||
on public.user_list (enterprise_id);
|
|
||||||
|
|
||||||
create index idx_user_list_department_id
|
|
||||||
on public.user_list (department_id);
|
|
||||||
|
|
||||||
create index idx_user_list_role
|
|
||||||
on public.user_list (role);
|
|
||||||
|
|
||||||
create table public.knowledge_base
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
user_id integer not null,
|
|
||||||
name varchar(255) not null,
|
|
||||||
description text,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
is_deleted boolean default false,
|
|
||||||
deleted_at timestamp with time zone,
|
|
||||||
enterprise_id integer default 1 not null
|
|
||||||
references public.enterprise,
|
|
||||||
department_id integer
|
|
||||||
references public.department
|
|
||||||
on delete set null,
|
|
||||||
creator_id integer not null
|
|
||||||
references public.user_list
|
|
||||||
on delete set null,
|
|
||||||
visibility varchar(32) default 'private'::character varying not null
|
|
||||||
constraint ck_knowledge_base_visibility
|
|
||||||
check ((visibility)::text = ANY
|
|
||||||
((ARRAY ['private'::character varying, 'department'::character varying, 'enterprise'::character varying])::text[]))
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on column public.knowledge_base.creator_id is '创建者(与 user_id 通常一致,用于权限判断)';
|
|
||||||
|
|
||||||
comment on column public.knowledge_base.visibility is 'private | department | enterprise';
|
|
||||||
|
|
||||||
alter table public.knowledge_base
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_knowledge_base_user_id
|
|
||||||
on public.knowledge_base (user_id);
|
|
||||||
|
|
||||||
create index idx_knowledge_base_user_name
|
|
||||||
on public.knowledge_base (user_id, name);
|
|
||||||
|
|
||||||
create index idx_knowledge_base_created_at
|
|
||||||
on public.knowledge_base (created_at);
|
|
||||||
|
|
||||||
create index idx_knowledge_base_is_deleted
|
|
||||||
on public.knowledge_base (is_deleted);
|
|
||||||
|
|
||||||
create index idx_knowledge_base_user_deleted
|
|
||||||
on public.knowledge_base (user_id, is_deleted);
|
|
||||||
|
|
||||||
create unique index uk_user_knowledge_base_name_active
|
|
||||||
on public.knowledge_base (user_id, name)
|
|
||||||
where (is_deleted = false);
|
|
||||||
|
|
||||||
create index idx_knowledge_base_enterprise
|
|
||||||
on public.knowledge_base (enterprise_id);
|
|
||||||
|
|
||||||
create index idx_knowledge_base_creator
|
|
||||||
on public.knowledge_base (creator_id);
|
|
||||||
|
|
||||||
create index idx_knowledge_base_ent_vis
|
|
||||||
on public.knowledge_base (enterprise_id, visibility)
|
|
||||||
where (is_deleted = false);
|
|
||||||
|
|
||||||
create table public.knowledge_base_file
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
knowledge_base_id integer not null
|
|
||||||
constraint fk_knowledge_base
|
|
||||||
references public.knowledge_base
|
|
||||||
on delete cascade,
|
|
||||||
user_id integer not null,
|
|
||||||
file_name varchar(255) not null,
|
|
||||||
file_path varchar(500) not null,
|
|
||||||
file_size bigint not null,
|
|
||||||
file_type varchar(50) default 'pdf'::character varying not null,
|
|
||||||
status varchar(20) default 'processing'::character varying not null,
|
|
||||||
chunk_count integer default 0,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
is_deleted boolean default false,
|
|
||||||
deleted_at timestamp with time zone
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.knowledge_base_file
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_kb_file_kb_id
|
|
||||||
on public.knowledge_base_file (knowledge_base_id);
|
|
||||||
|
|
||||||
create index idx_kb_file_user_id
|
|
||||||
on public.knowledge_base_file (user_id);
|
|
||||||
|
|
||||||
create index idx_kb_file_status
|
|
||||||
on public.knowledge_base_file (status);
|
|
||||||
|
|
||||||
create index idx_kb_file_created_at
|
|
||||||
on public.knowledge_base_file (created_at);
|
|
||||||
|
|
||||||
create unique index idx_kb_file_unique_active
|
|
||||||
on public.knowledge_base_file (knowledge_base_id, file_name)
|
|
||||||
where (is_deleted = false);
|
|
||||||
|
|
||||||
create table public.knowledge_base_chunk
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
file_id integer not null
|
|
||||||
constraint fk_kb_file
|
|
||||||
references public.knowledge_base_file
|
|
||||||
on delete cascade,
|
|
||||||
knowledge_base_id integer not null
|
|
||||||
constraint fk_kb
|
|
||||||
references public.knowledge_base
|
|
||||||
on delete cascade,
|
|
||||||
chunk_index integer not null,
|
|
||||||
content text not null,
|
|
||||||
metadata jsonb,
|
|
||||||
vector_id varchar(255),
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
summary text
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.knowledge_base_chunk
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_kb_chunk_file_id
|
|
||||||
on public.knowledge_base_chunk (file_id);
|
|
||||||
|
|
||||||
create index idx_kb_chunk_kb_id
|
|
||||||
on public.knowledge_base_chunk (knowledge_base_id);
|
|
||||||
|
|
||||||
create index idx_kb_chunk_vector_id
|
|
||||||
on public.knowledge_base_chunk (vector_id);
|
|
||||||
|
|
||||||
create index idx_kb_chunk_metadata
|
|
||||||
on public.knowledge_base_chunk using gin (metadata);
|
|
||||||
|
|
||||||
create table public.chat_thread_file
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
thread_id varchar(255) not null,
|
|
||||||
user_id integer not null
|
|
||||||
constraint fk_chat_thread_file_user
|
|
||||||
references public.user_list
|
|
||||||
on delete cascade,
|
|
||||||
file_name varchar(255) not null,
|
|
||||||
file_path varchar(500) not null,
|
|
||||||
file_size integer default 0,
|
|
||||||
file_type varchar(50) default 'pdf'::character varying,
|
|
||||||
status varchar(20) default 'processing'::character varying,
|
|
||||||
chunk_count integer default 0,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
is_deleted boolean default false,
|
|
||||||
deleted_at timestamp with time zone
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.chat_thread_file
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_chat_thread_file_thread_id
|
|
||||||
on public.chat_thread_file (thread_id);
|
|
||||||
|
|
||||||
create index idx_chat_thread_file_user_id
|
|
||||||
on public.chat_thread_file (user_id);
|
|
||||||
|
|
||||||
create index idx_chat_thread_file_thread_user
|
|
||||||
on public.chat_thread_file (thread_id, user_id);
|
|
||||||
|
|
||||||
create index idx_chat_thread_file_status
|
|
||||||
on public.chat_thread_file (status);
|
|
||||||
|
|
||||||
create index idx_chat_thread_file_is_deleted
|
|
||||||
on public.chat_thread_file (is_deleted);
|
|
||||||
|
|
||||||
create index idx_chat_thread_file_created_at
|
|
||||||
on public.chat_thread_file (created_at);
|
|
||||||
|
|
||||||
create index idx_chat_thread_file_thread_deleted
|
|
||||||
on public.chat_thread_file (thread_id, is_deleted);
|
|
||||||
|
|
||||||
create unique index uk_chat_thread_file_thread_name_active
|
|
||||||
on public.chat_thread_file (thread_id, file_name)
|
|
||||||
where (is_deleted = false);
|
|
||||||
|
|
||||||
create table public.chat_thread_chunk
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
file_id integer not null
|
|
||||||
constraint fk_chat_thread_chunk_file
|
|
||||||
references public.chat_thread_file
|
|
||||||
on delete cascade,
|
|
||||||
thread_id varchar(255) not null,
|
|
||||||
chunk_index integer not null,
|
|
||||||
content text not null,
|
|
||||||
metadata jsonb,
|
|
||||||
vector_id varchar(255),
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
summary text
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.chat_thread_chunk
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_chat_thread_chunk_file_id
|
|
||||||
on public.chat_thread_chunk (file_id);
|
|
||||||
|
|
||||||
create index idx_chat_thread_chunk_thread_id
|
|
||||||
on public.chat_thread_chunk (thread_id);
|
|
||||||
|
|
||||||
create index idx_chat_thread_chunk_file_thread
|
|
||||||
on public.chat_thread_chunk (file_id, thread_id);
|
|
||||||
|
|
||||||
create index idx_chat_thread_chunk_vector_id
|
|
||||||
on public.chat_thread_chunk (vector_id);
|
|
||||||
|
|
||||||
create index idx_chat_thread_chunk_created_at
|
|
||||||
on public.chat_thread_chunk (created_at);
|
|
||||||
|
|
||||||
create table public.chat_message_file
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
thread_id varchar(255) not null,
|
|
||||||
checkpoint_id varchar(255) not null,
|
|
||||||
message_index integer not null,
|
|
||||||
file_id integer not null
|
|
||||||
constraint fk_chat_message_file_file
|
|
||||||
references public.chat_thread_file
|
|
||||||
on delete cascade,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
constraint uk_message_file
|
|
||||||
unique (checkpoint_id, message_index, file_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table public.chat_message_file
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_chat_message_file_thread_id
|
|
||||||
on public.chat_message_file (thread_id);
|
|
||||||
|
|
||||||
create index idx_chat_message_file_checkpoint
|
|
||||||
on public.chat_message_file (checkpoint_id, message_index);
|
|
||||||
|
|
||||||
create index idx_chat_message_file_file_id
|
|
||||||
on public.chat_message_file (file_id);
|
|
||||||
|
|
||||||
create index idx_chat_message_file_thread_checkpoint
|
|
||||||
on public.chat_message_file (thread_id, checkpoint_id);
|
|
||||||
|
|
||||||
create table public.graphs
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
user_id integer not null
|
|
||||||
constraint fk_graphs_user
|
|
||||||
references public.user_list
|
|
||||||
on delete cascade,
|
|
||||||
name varchar(255) not null,
|
|
||||||
description text,
|
|
||||||
csv_file_name varchar(255),
|
|
||||||
node_count integer default 0,
|
|
||||||
edge_count integer default 0,
|
|
||||||
neo4j_graph_id varchar(100) not null
|
|
||||||
unique,
|
|
||||||
graph_type varchar(20) default 'knowledge'::character varying not null,
|
|
||||||
build_status varchar(20),
|
|
||||||
build_error text,
|
|
||||||
rag_chunk_count integer default 0 not null,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
enterprise_id integer not null
|
|
||||||
references public.enterprise,
|
|
||||||
department_id integer
|
|
||||||
references public.department
|
|
||||||
on delete set null,
|
|
||||||
creator_id integer not null
|
|
||||||
references public.user_list
|
|
||||||
on delete set null,
|
|
||||||
visibility varchar(32) default 'private'::character varying not null
|
|
||||||
constraint ck_graphs_visibility
|
|
||||||
check ((visibility)::text = ANY
|
|
||||||
((ARRAY ['private'::character varying, 'department'::character varying, 'enterprise'::character varying])::text[]))
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on table public.graphs is '知识图谱元数据表,图数据在 Neo4j;向量块数量见 rag_chunk_count';
|
|
||||||
|
|
||||||
comment on column public.graphs.neo4j_graph_id is 'Neo4j 中图谱唯一标识';
|
|
||||||
|
|
||||||
comment on column public.graphs.graph_type is '兼容字段,默认 knowledge';
|
|
||||||
|
|
||||||
comment on column public.graphs.build_status is '构建状态:pending/processing/completed/failed';
|
|
||||||
|
|
||||||
comment on column public.graphs.build_error is '构建失败时的错误信息';
|
|
||||||
|
|
||||||
comment on column public.graphs.rag_chunk_count is 'Chroma 中知识图谱 RAG 分块数量';
|
|
||||||
|
|
||||||
comment on column public.graphs.creator_id is '创建者(与 user_id 通常一致,用于权限判断)';
|
|
||||||
|
|
||||||
comment on column public.graphs.visibility is 'private | department | enterprise';
|
|
||||||
|
|
||||||
alter table public.graphs
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_graphs_user_id
|
|
||||||
on public.graphs (user_id);
|
|
||||||
|
|
||||||
create index idx_graphs_created_at
|
|
||||||
on public.graphs (created_at desc);
|
|
||||||
|
|
||||||
create index idx_graphs_neo4j_id
|
|
||||||
on public.graphs (neo4j_graph_id);
|
|
||||||
|
|
||||||
create index idx_graphs_graph_type
|
|
||||||
on public.graphs (user_id, graph_type);
|
|
||||||
|
|
||||||
create index idx_graphs_enterprise
|
|
||||||
on public.graphs (enterprise_id);
|
|
||||||
|
|
||||||
create index idx_graphs_creator
|
|
||||||
on public.graphs (creator_id);
|
|
||||||
|
|
||||||
create index idx_graphs_ent_vis
|
|
||||||
on public.graphs (enterprise_id, visibility);
|
|
||||||
|
|
||||||
create table public.chat_threads
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
thread_id varchar(255) not null
|
|
||||||
constraint uk_thread_id
|
|
||||||
unique,
|
|
||||||
user_id integer not null
|
|
||||||
constraint fk_user_id
|
|
||||||
references public.user_list
|
|
||||||
on delete cascade,
|
|
||||||
title varchar(50) not null,
|
|
||||||
first_query text not null,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
message_count integer default 1,
|
|
||||||
is_deleted boolean default false,
|
|
||||||
knowledge_base_id integer,
|
|
||||||
novel_graph_id integer,
|
|
||||||
knowledge_graph_id integer
|
|
||||||
constraint fk_chat_threads_knowledge_graph
|
|
||||||
references public.graphs
|
|
||||||
on delete set null,
|
|
||||||
ip varchar(128)
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on table public.chat_threads is '聊天会话记录表,记录每个用户的会话基本信息';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.id is '主键 ID';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.thread_id is '会话线程 ID(UUID 格式)';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.user_id is '用户 ID,关联 user_list 表';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.title is '会话标题(首次请求内容的前10个字)';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.first_query is '首次请求的完整内容';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.created_at is '会话创建时间';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.updated_at is '最后更新时间';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.message_count is '该会话的消息总数';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.is_deleted is '是否已删除(软删除标记)';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.knowledge_graph_id is '绑定的知识图谱 graphs.id,与 knowledge_base_id 二选一';
|
|
||||||
|
|
||||||
comment on column public.chat_threads.ip is '最近一次发起聊天时的客户端 IP(可选)';
|
|
||||||
|
|
||||||
alter table public.chat_threads
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_chat_threads_user_id
|
|
||||||
on public.chat_threads (user_id);
|
|
||||||
|
|
||||||
create index idx_chat_threads_created_at
|
|
||||||
on public.chat_threads (created_at desc);
|
|
||||||
|
|
||||||
create index idx_chat_threads_user_created
|
|
||||||
on public.chat_threads (user_id asc, created_at desc);
|
|
||||||
|
|
||||||
create index idx_chat_threads_novel_graph_id
|
|
||||||
on public.chat_threads (novel_graph_id);
|
|
||||||
|
|
||||||
create index idx_chat_threads_knowledge_graph_id
|
|
||||||
on public.chat_threads (knowledge_graph_id);
|
|
||||||
|
|
||||||
create table public.knowledge_processing_task
|
|
||||||
(
|
|
||||||
id serial
|
|
||||||
primary key,
|
|
||||||
user_id integer not null
|
|
||||||
constraint fk_kb_processing_user
|
|
||||||
references public.user_list
|
|
||||||
on delete cascade,
|
|
||||||
knowledge_base_id integer not null
|
|
||||||
constraint fk_kb_processing_kb
|
|
||||||
references public.knowledge_base
|
|
||||||
on delete cascade,
|
|
||||||
task_name varchar(255) not null,
|
|
||||||
instruction text not null,
|
|
||||||
file_ids integer[] not null,
|
|
||||||
task_type varchar(50) not null,
|
|
||||||
status varchar(20) default 'pending'::character varying,
|
|
||||||
result text,
|
|
||||||
result_file_url text,
|
|
||||||
error_message text,
|
|
||||||
created_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
updated_at timestamp with time zone default CURRENT_TIMESTAMP,
|
|
||||||
started_at timestamp with time zone,
|
|
||||||
completed_at timestamp with time zone
|
|
||||||
);
|
|
||||||
|
|
||||||
comment on table public.knowledge_processing_task is '知识加工任务表:合并、对比、总结等异步任务';
|
|
||||||
|
|
||||||
comment on column public.knowledge_processing_task.result_file_url is '加工结果文件的 OSS 下载链接';
|
|
||||||
|
|
||||||
alter table public.knowledge_processing_task
|
|
||||||
owner to zuoleiroot;
|
|
||||||
|
|
||||||
create index idx_kb_processing_user_id
|
|
||||||
on public.knowledge_processing_task (user_id);
|
|
||||||
|
|
||||||
create index idx_kb_processing_kb_id
|
|
||||||
on public.knowledge_processing_task (knowledge_base_id);
|
|
||||||
|
|
||||||
create index idx_kb_processing_status
|
|
||||||
on public.knowledge_processing_task (status);
|
|
||||||
|
|
||||||
create index idx_kb_processing_created_at
|
|
||||||
on public.knowledge_processing_task (created_at desc);
|
|
||||||
|
|
||||||
create index idx_kb_processing_user_status
|
|
||||||
on public.knowledge_processing_task (user_id, status);
|
|
||||||
|
|
||||||
create index idx_department_enterprise_id
|
|
||||||
on public.department (enterprise_id);
|
|
||||||
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
# Test your FastAPI endpoints
|
|
||||||
|
|
||||||
GET http://127.0.0.1:8000/
|
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
GET http://127.0.0.1:8000/hello/User
|
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
-- ================================================================
|
|
||||||
-- 权限方案 A 升级 DDL(在已有表结构基础上执行)
|
|
||||||
-- 执行顺序:按文件从上到下顺序执行
|
|
||||||
-- ================================================================
|
|
||||||
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
-- 1. department:新增部门负责人字段
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
ALTER TABLE public.department
|
|
||||||
ADD COLUMN IF NOT EXISTS leader_user_id INTEGER
|
|
||||||
REFERENCES public.user_list(id) ON DELETE SET NULL;
|
|
||||||
|
|
||||||
COMMENT ON COLUMN public.department.leader_user_id IS '部门负责人 user_id,对应 role=leader 的用户';
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_department_leader_user_id
|
|
||||||
ON public.department (leader_user_id);
|
|
||||||
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
-- 2. user_list:新增「是否允许上传文件到知识库」开关
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
ALTER TABLE public.user_list
|
|
||||||
ADD COLUMN IF NOT EXISTS allow_kb_upload BOOLEAN NOT NULL DEFAULT TRUE;
|
|
||||||
|
|
||||||
COMMENT ON COLUMN public.user_list.allow_kb_upload IS '是否允许上传文件到知识库(上级领导或 admin 可关闭)';
|
|
||||||
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
-- 3. kb_audit_log:知识库操作审计日志表(新建)
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS public.kb_audit_log
|
|
||||||
(
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
enterprise_id INTEGER NOT NULL
|
|
||||||
REFERENCES public.enterprise ON DELETE CASCADE,
|
|
||||||
actor_id INTEGER NOT NULL
|
|
||||||
REFERENCES public.user_list (id) ON DELETE CASCADE,
|
|
||||||
target_user_id INTEGER
|
|
||||||
REFERENCES public.user_list (id) ON DELETE SET NULL,
|
|
||||||
department_id INTEGER
|
|
||||||
REFERENCES public.department (id) ON DELETE SET NULL,
|
|
||||||
kb_id INTEGER
|
|
||||||
REFERENCES public.knowledge_base (id) ON DELETE SET NULL,
|
|
||||||
file_id INTEGER
|
|
||||||
REFERENCES public.knowledge_base_file (id) ON DELETE SET NULL,
|
|
||||||
action VARCHAR(50) NOT NULL,
|
|
||||||
-- upload | download | delete | archive | create_kb | delete_kb | permission_change
|
|
||||||
ip VARCHAR(128),
|
|
||||||
user_agent TEXT,
|
|
||||||
metadata JSONB,
|
|
||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
COMMENT ON TABLE public.kb_audit_log IS '知识库操作审计日志';
|
|
||||||
COMMENT ON COLUMN public.kb_audit_log.action IS
|
|
||||||
'upload | download | delete | archive | create_kb | delete_kb | permission_change';
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_enterprise_id
|
|
||||||
ON public.kb_audit_log (enterprise_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_actor_id
|
|
||||||
ON public.kb_audit_log (actor_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_target_user_id
|
|
||||||
ON public.kb_audit_log (target_user_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_department_id
|
|
||||||
ON public.kb_audit_log (department_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_kb_id
|
|
||||||
ON public.kb_audit_log (kb_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_action
|
|
||||||
ON public.kb_audit_log (action);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_created_at
|
|
||||||
ON public.kb_audit_log (created_at DESC);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_kb_audit_log_ent_dept_created
|
|
||||||
ON public.kb_audit_log (enterprise_id, department_id, created_at DESC);
|
|
||||||
|
|
||||||
ALTER TABLE public.kb_audit_log OWNER TO zuoleiroot;
|
|
||||||
Loading…
Reference in New Issue