Files
Neo-ZQYY/docs/database/ddl/zqyy_app__biz.sql
Neo 70324d8542 chore: 文档与 IDE 配置整理
- .kiro/specs/ → docs/specs/(41 个历史需求 spec 迁移,移除 .config.kiro)
- CLAUDE.md 三层拆分:根文件精简 + apps/backend/CLAUDE.md + .claude/commands/
- 新增 /spec-close、/pre-change 两个工作流命令
- DDL 基线刷新(从测试库重新导出 11 个文件,dws 35→38 表,biz 18→21 表)
- BD_Manual → BD_manual 命名统一(48 个文件)
- 修复 3 处文档与数据库不一致(auth.users.status 默认值、scheduled_tasks 字段、RLS 视图数)
- 新增 BD_manual_public_rbac_tables.md(public schema 8 张 RBAC/工作流表)
- 合并 biz.trigger_jobs 文档(10→12 字段,归档独立文档)
- docs/database/README.md 索引更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:02:37 +08:00

391 lines
20 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =============================================================================
-- zqyy_app / biz核心业务表任务/备注/触发器))
-- 生成日期2026-04-05
-- 来源:测试库(通过脚本自动导出)
-- =============================================================================
CREATE SCHEMA IF NOT EXISTS biz;
-- 序列
CREATE SEQUENCE IF NOT EXISTS biz.ai_cache_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.ai_conversations_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.ai_messages_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.ai_run_logs_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.ai_trigger_jobs_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.cfg_task_generator_params_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.coach_task_history_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.coach_task_transfer_log_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.coach_tasks_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.connectors_id_seq AS integer;
CREATE SEQUENCE IF NOT EXISTS biz.dws_assistant_task_monthly_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.excel_upload_log_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.notes_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.salary_adjustments_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.site_code_history_id_seq AS integer;
CREATE SEQUENCE IF NOT EXISTS biz.sites_id_seq AS integer;
CREATE SEQUENCE IF NOT EXISTS biz.stg_finance_expense_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.stg_platform_income_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.stg_recharge_commission_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS biz.tenants_id_seq AS integer;
CREATE SEQUENCE IF NOT EXISTS biz.trigger_jobs_id_seq AS integer;
-- 表
CREATE TABLE biz.ai_cache (
id bigint DEFAULT nextval('biz.ai_cache_id_seq'::regclass) NOT NULL,
cache_type character varying(30) NOT NULL,
site_id bigint NOT NULL,
target_id character varying(100) NOT NULL,
result_json jsonb NOT NULL,
score integer,
triggered_by character varying(100),
created_at timestamp with time zone DEFAULT now() NOT NULL,
expires_at timestamp with time zone,
status character varying(20) DEFAULT 'valid'::character varying
);
CREATE TABLE biz.ai_conversations (
id bigint DEFAULT nextval('biz.ai_conversations_id_seq'::regclass) NOT NULL,
user_id character varying(50) NOT NULL,
nickname character varying(100) DEFAULT ''::character varying NOT NULL,
app_id character varying(30) NOT NULL,
site_id bigint NOT NULL,
source_page character varying(100),
source_context jsonb,
created_at timestamp with time zone DEFAULT now() NOT NULL,
context_type character varying(20),
context_id character varying(50),
title character varying(200),
last_message text,
last_message_at timestamp with time zone,
session_id character varying(100)
);
CREATE TABLE biz.ai_messages (
id bigint DEFAULT nextval('biz.ai_messages_id_seq'::regclass) NOT NULL,
conversation_id bigint NOT NULL,
role character varying(10) NOT NULL,
content text NOT NULL,
tokens_used integer,
created_at timestamp with time zone DEFAULT now() NOT NULL,
reference_card jsonb
);
CREATE TABLE biz.ai_run_logs (
id bigint DEFAULT nextval('biz.ai_run_logs_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
app_type character varying(30) NOT NULL,
trigger_type character varying(20) NOT NULL,
member_id bigint,
request_prompt text,
response_text text,
tokens_used integer DEFAULT 0,
latency_ms integer,
status character varying(20) DEFAULT 'pending'::character varying NOT NULL,
error_message text,
session_id character varying(100),
created_at timestamp with time zone DEFAULT now() NOT NULL,
finished_at timestamp with time zone,
alert_status character varying(20) DEFAULT NULL::character varying
);
CREATE TABLE biz.ai_trigger_jobs (
id bigint DEFAULT nextval('biz.ai_trigger_jobs_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
event_type character varying(30) NOT NULL,
connector_type character varying(30) DEFAULT 'feiqiu'::character varying,
member_id bigint,
payload jsonb,
status character varying(20) DEFAULT 'pending'::character varying NOT NULL,
is_forced boolean DEFAULT false,
app_chain character varying(100),
started_at timestamp with time zone,
finished_at timestamp with time zone,
error_message text,
created_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE biz.cfg_task_generator_params (
id bigint DEFAULT nextval('biz.cfg_task_generator_params_id_seq'::regclass) NOT NULL,
site_id bigint,
param_key character varying(64) NOT NULL,
param_value numeric NOT NULL,
description text,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
updated_by bigint
);
CREATE TABLE biz.coach_task_history (
id bigint DEFAULT nextval('biz.coach_task_history_id_seq'::regclass) NOT NULL,
task_id bigint NOT NULL,
action character varying(50) NOT NULL,
old_status character varying(20),
new_status character varying(20),
old_task_type character varying(50),
new_task_type character varying(50),
detail jsonb,
created_at timestamp with time zone DEFAULT now()
);
CREATE TABLE biz.coach_task_transfer_log (
id bigint DEFAULT nextval('biz.coach_task_transfer_log_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
member_id bigint NOT NULL,
from_assistant_id bigint NOT NULL,
to_assistant_id bigint NOT NULL,
from_task_id bigint NOT NULL,
to_task_id bigint,
transfer_reason text,
guard_checks jsonb,
transfer_score numeric,
created_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE biz.coach_tasks (
id bigint DEFAULT nextval('biz.coach_tasks_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
assistant_id bigint NOT NULL,
member_id bigint NOT NULL,
task_type character varying(50) NOT NULL,
status character varying(20) DEFAULT 'active'::character varying NOT NULL,
priority_score numeric(5,2),
expires_at timestamp with time zone,
is_pinned boolean DEFAULT false,
abandon_reason text,
completed_at timestamp with time zone,
completed_task_type character varying(50),
parent_task_id bigint,
created_at timestamp with time zone DEFAULT now(),
updated_at timestamp with time zone DEFAULT now(),
transfer_count integer DEFAULT 0 NOT NULL,
transferred_from bigint,
transferred_at timestamp with time zone
);
CREATE TABLE biz.connectors (
id integer DEFAULT nextval('biz.connectors_id_seq'::regclass) NOT NULL,
connector_key character varying(50) NOT NULL,
display_name character varying(100) NOT NULL,
is_active boolean DEFAULT true NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE biz.dws_assistant_task_monthly (
id bigint DEFAULT nextval('biz.dws_assistant_task_monthly_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
assistant_id bigint NOT NULL,
stat_month date NOT NULL,
recall_created integer DEFAULT 0 NOT NULL,
follow_up_created integer DEFAULT 0 NOT NULL,
relationship_created integer DEFAULT 0 NOT NULL,
total_created integer DEFAULT 0 NOT NULL,
recall_completed integer DEFAULT 0 NOT NULL,
follow_up_completed integer DEFAULT 0 NOT NULL,
total_completed integer DEFAULT 0 NOT NULL,
abandoned_count integer DEFAULT 0 NOT NULL,
transferred_count integer DEFAULT 0 NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE biz.excel_upload_log (
id bigint DEFAULT nextval('biz.excel_upload_log_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
upload_type character varying(30) NOT NULL,
file_name character varying(255) NOT NULL,
uploaded_by bigint NOT NULL,
row_count integer DEFAULT 0,
conflict_count integer DEFAULT 0,
resolved_count integer DEFAULT 0,
status character varying(20) NOT NULL,
error_detail jsonb,
created_at timestamp with time zone DEFAULT now(),
confirmed_at timestamp with time zone
);
CREATE TABLE biz.notes (
id bigint DEFAULT nextval('biz.notes_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
user_id integer NOT NULL,
target_type character varying(50) NOT NULL,
target_id bigint NOT NULL,
type character varying(20) DEFAULT 'normal'::character varying NOT NULL,
content text NOT NULL,
rating_service_willingness smallint,
rating_revisit_likelihood smallint,
task_id bigint,
ai_score smallint,
ai_analysis text,
created_at timestamp with time zone DEFAULT now(),
updated_at timestamp with time zone DEFAULT now(),
score smallint
);
CREATE TABLE biz.salary_adjustments (
id bigint DEFAULT nextval('biz.salary_adjustments_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
assistant_id bigint,
assistant_name character varying(100) NOT NULL,
assistant_number character varying(50) NOT NULL,
salary_month character varying(7) NOT NULL,
adjustment_type character varying(20) NOT NULL,
amount numeric(12,2) NOT NULL,
reason character varying(200) NOT NULL,
upload_batch_id bigint,
created_at timestamp with time zone DEFAULT now(),
created_by bigint
);
CREATE TABLE biz.site_code_history (
id integer DEFAULT nextval('biz.site_code_history_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
site_code character varying(6) NOT NULL,
is_current boolean DEFAULT false NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
retired_at timestamp with time zone
);
CREATE TABLE biz.sites (
id integer DEFAULT nextval('biz.sites_id_seq'::regclass) NOT NULL,
tenant_id integer NOT NULL,
site_id bigint NOT NULL,
site_name character varying(200),
site_code character varying(6),
site_label character varying(50),
is_active boolean DEFAULT true NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE biz.stg_finance_expense (
id bigint DEFAULT nextval('biz.stg_finance_expense_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
expense_month character varying(7) NOT NULL,
category character varying(50) NOT NULL,
amount numeric(12,2) NOT NULL,
remark text,
upload_batch_id bigint,
synced_at timestamp with time zone,
created_at timestamp with time zone DEFAULT now()
);
CREATE TABLE biz.stg_platform_income (
id bigint DEFAULT nextval('biz.stg_platform_income_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
income_month character varying(7) NOT NULL,
platform_name character varying(100) NOT NULL,
amount numeric(12,2) NOT NULL,
remark text,
upload_batch_id bigint,
synced_at timestamp with time zone,
created_at timestamp with time zone DEFAULT now()
);
CREATE TABLE biz.stg_recharge_commission (
id bigint DEFAULT nextval('biz.stg_recharge_commission_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
recharge_date date NOT NULL,
member_name character varying(100) NOT NULL,
recharge_amount numeric(12,2) NOT NULL,
assigned_assistant character varying(100) NOT NULL,
reward_amount numeric(12,2) NOT NULL,
upload_batch_id bigint,
synced_at timestamp with time zone,
created_at timestamp with time zone DEFAULT now()
);
CREATE TABLE biz.tenants (
id integer DEFAULT nextval('biz.tenants_id_seq'::regclass) NOT NULL,
connector_id integer NOT NULL,
tenant_id bigint NOT NULL,
tenant_name character varying(200),
is_active boolean DEFAULT true NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE biz.trigger_jobs (
id integer DEFAULT nextval('biz.trigger_jobs_id_seq'::regclass) NOT NULL,
job_type character varying(100) NOT NULL,
job_name character varying(100) NOT NULL,
trigger_condition character varying(20) NOT NULL,
trigger_config jsonb NOT NULL,
last_run_at timestamp with time zone,
next_run_at timestamp with time zone,
status character varying(20) DEFAULT 'enabled'::character varying NOT NULL,
created_at timestamp with time zone DEFAULT now(),
last_error text,
description text,
last_stats jsonb
);
-- 约束(主键 / 唯一 / 外键)
ALTER TABLE biz.ai_cache ADD CONSTRAINT ai_cache_pkey PRIMARY KEY (id);
ALTER TABLE biz.ai_conversations ADD CONSTRAINT ai_conversations_pkey PRIMARY KEY (id);
ALTER TABLE biz.ai_messages ADD CONSTRAINT ai_messages_conversation_id_fkey FOREIGN KEY (conversation_id) REFERENCES biz.ai_conversations(id) ON DELETE CASCADE;
ALTER TABLE biz.ai_messages ADD CONSTRAINT ai_messages_pkey PRIMARY KEY (id);
ALTER TABLE biz.ai_run_logs ADD CONSTRAINT ai_run_logs_pkey PRIMARY KEY (id);
ALTER TABLE biz.ai_trigger_jobs ADD CONSTRAINT ai_trigger_jobs_pkey PRIMARY KEY (id);
ALTER TABLE biz.cfg_task_generator_params ADD CONSTRAINT cfg_task_generator_params_pkey PRIMARY KEY (id);
ALTER TABLE biz.cfg_task_generator_params ADD CONSTRAINT cfg_task_generator_params_site_id_param_key_key UNIQUE (site_id, param_key);
ALTER TABLE biz.coach_task_history ADD CONSTRAINT coach_task_history_task_id_fkey FOREIGN KEY (task_id) REFERENCES biz.coach_tasks(id);
ALTER TABLE biz.coach_task_history ADD CONSTRAINT coach_task_history_pkey PRIMARY KEY (id);
ALTER TABLE biz.coach_task_transfer_log ADD CONSTRAINT coach_task_transfer_log_from_task_id_fkey FOREIGN KEY (from_task_id) REFERENCES biz.coach_tasks(id);
ALTER TABLE biz.coach_task_transfer_log ADD CONSTRAINT coach_task_transfer_log_to_task_id_fkey FOREIGN KEY (to_task_id) REFERENCES biz.coach_tasks(id);
ALTER TABLE biz.coach_task_transfer_log ADD CONSTRAINT coach_task_transfer_log_pkey PRIMARY KEY (id);
ALTER TABLE biz.coach_tasks ADD CONSTRAINT coach_tasks_parent_task_id_fkey FOREIGN KEY (parent_task_id) REFERENCES biz.coach_tasks(id);
ALTER TABLE biz.coach_tasks ADD CONSTRAINT fk_coach_tasks_transferred_from FOREIGN KEY (transferred_from) REFERENCES biz.coach_tasks(id);
ALTER TABLE biz.coach_tasks ADD CONSTRAINT coach_tasks_pkey PRIMARY KEY (id);
ALTER TABLE biz.connectors ADD CONSTRAINT connectors_pkey PRIMARY KEY (id);
ALTER TABLE biz.connectors ADD CONSTRAINT connectors_connector_key_key UNIQUE (connector_key);
ALTER TABLE biz.dws_assistant_task_monthly ADD CONSTRAINT dws_assistant_task_monthly_pkey PRIMARY KEY (id);
ALTER TABLE biz.dws_assistant_task_monthly ADD CONSTRAINT dws_assistant_task_monthly_site_id_assistant_id_stat_month_key UNIQUE (site_id, assistant_id, stat_month);
ALTER TABLE biz.excel_upload_log ADD CONSTRAINT excel_upload_log_pkey PRIMARY KEY (id);
ALTER TABLE biz.notes ADD CONSTRAINT notes_task_id_fkey FOREIGN KEY (task_id) REFERENCES biz.coach_tasks(id);
ALTER TABLE biz.notes ADD CONSTRAINT notes_pkey PRIMARY KEY (id);
ALTER TABLE biz.salary_adjustments ADD CONSTRAINT salary_adjustments_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
ALTER TABLE biz.salary_adjustments ADD CONSTRAINT salary_adjustments_pkey PRIMARY KEY (id);
ALTER TABLE biz.site_code_history ADD CONSTRAINT site_code_history_pkey PRIMARY KEY (id);
ALTER TABLE biz.site_code_history ADD CONSTRAINT site_code_history_site_code_key UNIQUE (site_code);
ALTER TABLE biz.sites ADD CONSTRAINT sites_tenant_id_fkey FOREIGN KEY (tenant_id) REFERENCES biz.tenants(id);
ALTER TABLE biz.sites ADD CONSTRAINT sites_pkey PRIMARY KEY (id);
ALTER TABLE biz.sites ADD CONSTRAINT sites_site_code_key UNIQUE (site_code);
ALTER TABLE biz.sites ADD CONSTRAINT sites_site_id_key UNIQUE (site_id);
ALTER TABLE biz.stg_finance_expense ADD CONSTRAINT stg_finance_expense_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
ALTER TABLE biz.stg_finance_expense ADD CONSTRAINT stg_finance_expense_pkey PRIMARY KEY (id);
ALTER TABLE biz.stg_platform_income ADD CONSTRAINT stg_platform_income_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
ALTER TABLE biz.stg_platform_income ADD CONSTRAINT stg_platform_income_pkey PRIMARY KEY (id);
ALTER TABLE biz.stg_recharge_commission ADD CONSTRAINT stg_recharge_commission_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
ALTER TABLE biz.stg_recharge_commission ADD CONSTRAINT stg_recharge_commission_pkey PRIMARY KEY (id);
ALTER TABLE biz.tenants ADD CONSTRAINT tenants_connector_id_fkey FOREIGN KEY (connector_id) REFERENCES biz.connectors(id);
ALTER TABLE biz.tenants ADD CONSTRAINT tenants_pkey PRIMARY KEY (id);
ALTER TABLE biz.tenants ADD CONSTRAINT tenants_connector_id_tenant_id_key UNIQUE (connector_id, tenant_id);
ALTER TABLE biz.trigger_jobs ADD CONSTRAINT trigger_jobs_pkey PRIMARY KEY (id);
ALTER TABLE biz.trigger_jobs ADD CONSTRAINT trigger_jobs_job_name_key UNIQUE (job_name);
-- 索引
CREATE INDEX idx_ai_cache_cleanup ON biz.ai_cache USING btree (cache_type, site_id, target_id, created_at);
CREATE INDEX idx_ai_cache_lookup ON biz.ai_cache USING btree (cache_type, site_id, target_id, created_at DESC);
CREATE INDEX idx_ai_conv_app_site ON biz.ai_conversations USING btree (app_id, site_id, created_at DESC);
CREATE INDEX idx_ai_conv_context ON biz.ai_conversations USING btree (user_id, site_id, context_type, context_id, last_message_at DESC NULLS LAST) WHERE (context_type IS NOT NULL);
CREATE INDEX idx_ai_conv_last_msg ON biz.ai_conversations USING btree (user_id, site_id, last_message_at DESC NULLS LAST);
CREATE INDEX idx_ai_conv_user_site ON biz.ai_conversations USING btree (user_id, site_id, created_at DESC);
CREATE INDEX idx_ai_msg_conv ON biz.ai_messages USING btree (conversation_id, created_at);
CREATE INDEX idx_ai_run_logs_alert ON biz.ai_run_logs USING btree (alert_status, created_at DESC) WHERE ((status)::text = ANY ((ARRAY['failed'::character varying, 'timeout'::character varying, 'circuit_open'::character varying])::text[]));
CREATE INDEX idx_ai_run_logs_created ON biz.ai_run_logs USING btree (created_at);
CREATE INDEX idx_ai_run_logs_created_brin ON biz.ai_run_logs USING brin (created_at) WITH (pages_per_range='32');
CREATE INDEX idx_ai_run_logs_site_app ON biz.ai_run_logs USING btree (site_id, app_type);
CREATE INDEX idx_ai_run_logs_status ON biz.ai_run_logs USING btree (status);
CREATE INDEX idx_ai_trigger_jobs_dedup ON biz.ai_trigger_jobs USING btree (event_type, member_id, site_id, created_at) WHERE ((status)::text <> 'skipped_duplicate'::text);
CREATE INDEX idx_ai_trigger_jobs_site ON biz.ai_trigger_jobs USING btree (site_id, event_type);
CREATE INDEX idx_ai_trigger_jobs_status ON biz.ai_trigger_jobs USING btree (status);
CREATE INDEX idx_transfer_log_member ON biz.coach_task_transfer_log USING btree (member_id, created_at DESC);
CREATE INDEX idx_transfer_log_site_created ON biz.coach_task_transfer_log USING btree (site_id, created_at DESC);
CREATE INDEX idx_coach_tasks_assistant_status ON biz.coach_tasks USING btree (site_id, assistant_id, status);
CREATE UNIQUE INDEX idx_coach_tasks_site_assistant_member_type ON biz.coach_tasks USING btree (site_id, assistant_id, member_id, task_type) WHERE ((status)::text = 'active'::text);
CREATE INDEX idx_task_monthly_assistant ON biz.dws_assistant_task_monthly USING btree (assistant_id, stat_month DESC);
CREATE INDEX idx_task_monthly_site_month ON biz.dws_assistant_task_monthly USING btree (site_id, stat_month DESC);
CREATE INDEX idx_excel_log_site ON biz.excel_upload_log USING btree (site_id, created_at DESC);
CREATE INDEX idx_notes_target ON biz.notes USING btree (site_id, target_type, target_id);
CREATE INDEX idx_salary_adj_assistant_month ON biz.salary_adjustments USING btree (assistant_id, salary_month);
CREATE INDEX idx_salary_adj_site_month ON biz.salary_adjustments USING btree (site_id, salary_month);