merge: 合入本地 Ops 扩展与 origin/main(ECR-009–016)

保留远程用户侧 ECR-009–016 与本地 Ops 目录/RBAC/CMS/危机等能力;文档标注分叉期间 ECR 编号冲突。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-13 01:45:53 +08:00
co-authored by Cursor
593 changed files with 21918 additions and 328 deletions
@@ -0,0 +1,4 @@
UPDATE admin_accounts SET role_id = NULL WHERE role_id IS NOT NULL;
ALTER TABLE admin_accounts DROP COLUMN IF EXISTS role_id;
DROP TABLE IF EXISTS admin_role_permissions;
DROP TABLE IF EXISTS admin_roles;
@@ -0,0 +1,42 @@
-- ECR-013A Admin RBAC
CREATE TABLE IF NOT EXISTS admin_roles (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name varchar(64) NOT NULL UNIQUE,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS admin_role_permissions (
role_id uuid NOT NULL REFERENCES admin_roles(id) ON DELETE CASCADE,
code varchar(64) NOT NULL,
PRIMARY KEY (role_id, code)
);
ALTER TABLE admin_accounts
ADD COLUMN IF NOT EXISTS role_id uuid REFERENCES admin_roles(id);
INSERT INTO admin_roles(id, name, system)
VALUES ('00000000-0000-4000-8000-000000000001', 'super_admin', true)
ON CONFLICT (name) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, p.code
FROM admin_roles r
CROSS JOIN (VALUES
('admin.users.read'),
('admin.users.membership.grant'),
('admin.users.ask_quota.grant'),
('admin.orders.read'),
('admin.audit.read'),
('admin.analytics.read'),
('admin.content.write'),
('admin.roles.read'),
('admin.roles.write')
) AS p(code)
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
UPDATE admin_accounts
SET role_id = (SELECT id FROM admin_roles WHERE name = 'super_admin')
WHERE role_id IS NULL AND deleted_at IS NULL;
@@ -0,0 +1,3 @@
DROP INDEX IF EXISTS idx_account_state_transitions_user;
DROP TABLE IF EXISTS account_state_transitions;
DELETE FROM admin_role_permissions WHERE code = 'admin.users.status.write';
@@ -0,0 +1,20 @@
-- ECR-013B AccountLifecycle / UserStatus
CREATE TABLE IF NOT EXISTS account_state_transitions (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES users(id),
from_status varchar(32) NOT NULL,
to_status varchar(32) NOT NULL,
admin_id uuid NOT NULL REFERENCES admin_accounts(id),
reason text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_account_state_transitions_user
ON account_state_transitions(user_id, created_at DESC);
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.users.status.write'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,3 @@
DELETE FROM admin_role_permissions
WHERE code IN ('admin.membership.plans.read', 'admin.membership.plans.write');
DROP TABLE IF EXISTS membership_plans;
@@ -0,0 +1,27 @@
-- ECR-014 MembershipPlan
CREATE TABLE IF NOT EXISTS membership_plans (
code varchar(32) PRIMARY KEY,
title varchar(64) NOT NULL,
duration_days int NOT NULL CHECK (duration_days > 0),
amount_cents int NOT NULL CHECK (amount_cents >= 0),
active boolean NOT NULL DEFAULT true,
updated_at timestamptz NOT NULL DEFAULT now()
);
INSERT INTO membership_plans(code, title, duration_days, amount_cents, active)
VALUES
('month', '月卡', 31, 2500, true),
('quarter', '季卡', 92, 6800, true),
('year', '年卡', 366, 19800, true)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, p.code
FROM admin_roles r
CROSS JOIN (VALUES
('admin.membership.plans.read'),
('admin.membership.plans.write')
) AS p(code)
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,4 @@
DELETE FROM admin_role_permissions
WHERE code IN ('admin.membership.codes.read', 'admin.membership.codes.write');
DROP TABLE IF EXISTS redemption_codes;
DROP TABLE IF EXISTS redemption_batches;
@@ -0,0 +1,35 @@
-- ECR-015 RedemptionCode
CREATE TABLE IF NOT EXISTS redemption_batches (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
label varchar(64) NOT NULL,
plan_code varchar(32) NOT NULL REFERENCES membership_plans(code),
quantity int NOT NULL CHECK (quantity > 0 AND quantity <= 100),
created_by uuid NOT NULL REFERENCES admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS redemption_codes (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
batch_id uuid NOT NULL REFERENCES redemption_batches(id) ON DELETE CASCADE,
code varchar(32) NOT NULL UNIQUE,
plan_code varchar(32) NOT NULL REFERENCES membership_plans(code),
status varchar(16) NOT NULL DEFAULT 'unused'
CHECK (status IN ('unused','redeemed','disabled')),
redeemed_by uuid NULL REFERENCES users(id),
redeemed_at timestamptz NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_redemption_codes_batch ON redemption_codes(batch_id);
CREATE INDEX IF NOT EXISTS idx_redemption_codes_status ON redemption_codes(status);
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, p.code
FROM admin_roles r
CROSS JOIN (VALUES
('admin.membership.codes.read'),
('admin.membership.codes.write')
) AS p(code)
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,3 @@
-- ECR-017 down
DELETE FROM admin_role_permissions WHERE code = 'admin.ask.read';
@@ -0,0 +1,7 @@
-- ECR-017 AskOperations: admin.ask.read
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.ask.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,4 @@
-- ECR-019 down
DELETE FROM admin_role_permissions WHERE code = 'admin.content_safety.read';
DROP TABLE IF EXISTS filter_rules;
@@ -0,0 +1,33 @@
-- ECR-019 ContentSafety FilterRule
CREATE TABLE IF NOT EXISTS filter_rules (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
category varchar(32) NOT NULL
CHECK (category IN ('crisis','abuse','spam','pii')),
pattern text NOT NULL,
action varchar(32) NOT NULL
CHECK (action IN ('flag','block','escalate')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_filter_rules_category ON filter_rules(category);
CREATE INDEX IF NOT EXISTS idx_filter_rules_active ON filter_rules(active);
INSERT INTO filter_rules(code, title, category, pattern, action, active, system)
VALUES
('crisis_self_harm', '自伤危机关键词', 'crisis', '不想活了', 'escalate', true, true),
('abuse_threat', '人身威胁', 'abuse', '弄死你', 'block', true, true),
('spam_promo', '营销骚扰', 'spam', '加微信领红包', 'flag', true, true),
('pii_id_card', '身份证号形态提示', 'pii', '身份证号', 'flag', true, true)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.content_safety.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,4 @@
-- ECR-020 down
DELETE FROM admin_role_permissions WHERE code = 'admin.ask.feedback.write';
DROP TABLE IF EXISTS ask_quality_feedback;
@@ -0,0 +1,23 @@
-- ECR-020 QualityFeedback
CREATE TABLE IF NOT EXISTS ask_quality_feedback (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
thread_id uuid NOT NULL REFERENCES ask_threads(id),
message_id uuid NULL REFERENCES ask_messages(id),
source varchar(16) NOT NULL CHECK (source IN ('admin','user')),
rating smallint NOT NULL CHECK (rating >= 1 AND rating <= 5),
tag varchar(32) NULL CHECK (tag IS NULL OR tag IN ('helpful','off_topic','unsafe','other')),
note text NULL,
created_by_admin uuid NULL REFERENCES admin_accounts(id),
created_by_user uuid NULL REFERENCES users(id),
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_ask_qf_thread ON ask_quality_feedback(thread_id);
CREATE INDEX IF NOT EXISTS idx_ask_qf_created ON ask_quality_feedback(created_at DESC);
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.ask.feedback.write'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,4 @@
-- ECR-021 down
DELETE FROM admin_role_permissions WHERE code = 'admin.ai_config.read';
DROP TABLE IF EXISTS system_prompts;
@@ -0,0 +1,42 @@
-- ECR-021 AICoreConfig SystemPrompt (read catalog)
CREATE TABLE IF NOT EXISTS system_prompts (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
scene varchar(32) NULL,
body text NOT NULL,
version int NOT NULL DEFAULT 1 CHECK (version > 0),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_system_prompts_active ON system_prompts(active);
INSERT INTO system_prompts(code, title, scene, body, version, active, system)
VALUES (
'ask_default',
'问答默认系统提示',
NULL,
$prompt$你是 AI
宿
{{display_name}} · {{relation}} · {{birth_date}} · {{scene}} · {{report_ctx}}
$prompt$,
1,
true,
true
)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.ai_config.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,4 @@
-- ECR-022 down
DELETE FROM admin_role_permissions WHERE code = 'admin.crisis.read';
DROP TABLE IF EXISTS crisis_policies;
@@ -0,0 +1,49 @@
-- ECR-022 CrisisCare CrisisPolicy
CREATE TABLE IF NOT EXISTS crisis_policies (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
severity varchar(16) NOT NULL
CHECK (severity IN ('high','critical')),
pattern text NOT NULL,
action varchar(32) NOT NULL
CHECK (action IN ('escalate','block','show_helpline')),
helpline_text text NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_crisis_policies_active ON crisis_policies(active);
INSERT INTO crisis_policies(code, title, severity, pattern, action, helpline_text, active, system)
VALUES
(
'self_harm_critical',
'自伤/轻生危机',
'critical',
'不想活了',
'show_helpline',
'若你正处于危机,请立即联系身边可信的人,或拨打当地紧急援助/心理援助热线。愈心谷不能替代急救与专业干预。',
true,
true
),
(
'violence_threat',
'暴力伤害威胁',
'high',
'弄死你',
'escalate',
NULL,
true,
true
)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.crisis.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,2 @@
-- ECR-023 down
DROP TABLE IF EXISTS knowledge_sources;
@@ -0,0 +1,29 @@
-- ECR-023 AICoreConfig KnowledgeSource (read catalog)
CREATE TABLE IF NOT EXISTS knowledge_sources (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
description text NULL,
source_kind varchar(32) NOT NULL
CHECK (source_kind IN ('faq', 'policy', 'guide')),
version int NOT NULL DEFAULT 1 CHECK (version > 0),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_knowledge_sources_active ON knowledge_sources(active);
INSERT INTO knowledge_sources(code, title, description, source_kind, version, active, system)
VALUES (
'ask_grounding',
'问答 grounding 知识源',
'运营可观测的 Ask grounding 目录占位;本切片不含 KnowledgeChunk。',
'faq',
1,
true,
true
)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1,3 @@
-- ECR-024 down
DELETE FROM admin_role_permissions WHERE code = 'admin.cms.read';
DROP TABLE IF EXISTS ops_banners;
@@ -0,0 +1,37 @@
-- ECR-024 OpsCMS Banner (read catalog)
CREATE TABLE IF NOT EXISTS ops_banners (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
placement varchar(32) NOT NULL
CHECK (placement IN ('home','explore','ask')),
image_url text NULL,
link_path varchar(256) NULL,
sort_order int NOT NULL DEFAULT 0,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_ops_banners_active ON ops_banners(active);
INSERT INTO ops_banners(code, title, placement, image_url, link_path, sort_order, active, system)
VALUES (
'home_promo',
'首页运营横幅占位',
'home',
NULL,
'/membership',
10,
true,
true
)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.cms.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS ops_feed_slots;
@@ -0,0 +1,17 @@
-- ECR-025 OpsCMS FeedSlot (read catalog)
CREATE TABLE IF NOT EXISTS ops_feed_slots (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
slot_key varchar(64) NOT NULL,
placement varchar(32) NOT NULL
CHECK (placement IN ('home','explore','ask')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_ops_feed_slots_active ON ops_feed_slots(active);
INSERT INTO ops_feed_slots(code, title, slot_key, placement, active, system)
VALUES ('home_feed_main', '首页主信息流位', 'home.main', 'home', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS ops_scheduled_publications;
@@ -0,0 +1,19 @@
-- ECR-026 ScheduledPublication (read catalog)
CREATE TABLE IF NOT EXISTS ops_scheduled_publications (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
target_kind varchar(32) NOT NULL CHECK (target_kind IN ('banner','feed_slot')),
target_code varchar(64) NOT NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_ops_scheduled_publications_active ON ops_scheduled_publications(active);
INSERT INTO ops_scheduled_publications(code, title, target_kind, target_code, active, system)
VALUES ('home_banner_week', '首页横幅周排期占位', 'banner', 'home_promo', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS knowledge_chunks;
@@ -0,0 +1,19 @@
-- ECR-027 KnowledgeChunk (read catalog)
CREATE TABLE IF NOT EXISTS knowledge_chunks (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
source_code varchar(64) NOT NULL,
title varchar(128) NOT NULL,
body text NOT NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_knowledge_chunks_active ON knowledge_chunks(active);
INSERT INTO knowledge_chunks(code, source_code, title, body, active, system)
VALUES ('ask_grounding_intro', 'ask_grounding', '问答 grounding 引言块', '愈心谷提供陪伴式成长对话,非医疗诊断。', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS tool_definitions;
@@ -0,0 +1,18 @@
-- ECR-028 ToolDefinition (read catalog)
CREATE TABLE IF NOT EXISTS tool_definitions (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
description text NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_tool_definitions_active ON tool_definitions(active);
INSERT INTO tool_definitions(code, title, description, active, system)
VALUES ('fetch_profile_summary', '拉取档案摘要', '只读工具定义占位', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS block_policies;
@@ -0,0 +1,18 @@
-- ECR-029 BlockPolicy (read catalog)
CREATE TABLE IF NOT EXISTS block_policies (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
action varchar(32) NOT NULL CHECK (action IN ('block','mask','review')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_block_policies_active ON block_policies(active);
INSERT INTO block_policies(code, title, action, active, system)
VALUES ('block_spam_link', '外链垃圾拦截策略', 'block', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS moderation_cases;
@@ -0,0 +1,18 @@
-- ECR-030 ModerationCase (read catalog)
CREATE TABLE IF NOT EXISTS moderation_cases (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
status varchar(32) NOT NULL CHECK (status IN ('open','closed')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_moderation_cases_active ON moderation_cases(active);
INSERT INTO moderation_cases(code, title, status, active, system)
VALUES ('demo_case_seed', '示例审核案', 'closed', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS crisis_events;
@@ -0,0 +1,18 @@
-- ECR-031 CrisisEvent (read catalog)
CREATE TABLE IF NOT EXISTS crisis_events (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
severity varchar(16) NOT NULL CHECK (severity IN ('high','critical')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_crisis_events_active ON crisis_events(active);
INSERT INTO crisis_events(code, title, severity, active, system)
VALUES ('demo_crisis_event', '示例危机事件占位', 'high', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS intervention_outcomes;
@@ -0,0 +1,18 @@
-- ECR-032 InterventionOutcome (read catalog)
CREATE TABLE IF NOT EXISTS intervention_outcomes (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
outcome varchar(32) NOT NULL CHECK (outcome IN ('helpline_shown','escalated','blocked')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_intervention_outcomes_active ON intervention_outcomes(active);
INSERT INTO intervention_outcomes(code, title, outcome, active, system)
VALUES ('demo_helpline_shown', '示例展示热线结果', 'helpline_shown', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS ask_handoff_cases;
@@ -0,0 +1,18 @@
-- ECR-033 HandoffCase (read catalog)
CREATE TABLE IF NOT EXISTS ask_handoff_cases (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
status varchar(32) NOT NULL CHECK (status IN ('open','closed')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_ask_handoff_cases_active ON ask_handoff_cases(active);
INSERT INTO ask_handoff_cases(code, title, status, active, system)
VALUES ('demo_handoff', '示例转接案', 'closed', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1,2 @@
DELETE FROM admin_role_permissions WHERE code = 'admin.privacy.read';
DROP TABLE IF EXISTS privacy_requests;
@@ -0,0 +1,25 @@
-- ECR-034 PrivacyRequest (read catalog)
CREATE TABLE IF NOT EXISTS privacy_requests (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
kind varchar(32) NOT NULL CHECK (kind IN ('export','erase')),
status varchar(32) NOT NULL CHECK (status IN ('open','closed')),
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_privacy_requests_active ON privacy_requests(active);
INSERT INTO privacy_requests(code, title, kind, status, active, system)
VALUES ('demo_export_req', '示例数据导出请求', 'export', 'closed', true, true)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.privacy.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,2 @@
DELETE FROM admin_role_permissions WHERE code = 'admin.explore.read';
DROP TABLE IF EXISTS star_configs;
@@ -0,0 +1,23 @@
-- ECR-035 StarConfig (read catalog)
CREATE TABLE IF NOT EXISTS star_configs (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_star_configs_active ON star_configs(active);
INSERT INTO star_configs(code, title, active, system)
VALUES ('default_star', '默认星座配置', true, true)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.explore.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS rhythm_configs;
@@ -0,0 +1,17 @@
-- ECR-036 RhythmConfig (read catalog)
CREATE TABLE IF NOT EXISTS rhythm_configs (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_rhythm_configs_active ON rhythm_configs(active);
INSERT INTO rhythm_configs(code, title, active, system)
VALUES ('default_rhythm', '默认节律配置', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS image_card_decks;
@@ -0,0 +1,17 @@
-- ECR-037 ImageCardDeck (read catalog)
CREATE TABLE IF NOT EXISTS image_card_decks (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_image_card_decks_active ON image_card_decks(active);
INSERT INTO image_card_decks(code, title, active, system)
VALUES ('default_deck', '默认意象牌组', true, true)
ON CONFLICT (code) DO NOTHING;
@@ -0,0 +1,2 @@
DELETE FROM admin_role_permissions WHERE code = 'admin.growth.read';
DROP TABLE IF EXISTS report_templates;
@@ -0,0 +1,24 @@
-- ECR-038 ReportTemplate (read catalog)
CREATE TABLE IF NOT EXISTS report_templates (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
scene varchar(32) NOT NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_report_templates_active ON report_templates(active);
INSERT INTO report_templates(code, title, scene, active, system)
VALUES ('portrait_default', '画像报告模板占位', 'portrait', true, true)
ON CONFLICT (code) DO NOTHING;
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, 'admin.growth.read'
FROM admin_roles r
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;
@@ -0,0 +1 @@
DROP TABLE IF EXISTS funnel_definitions;
@@ -0,0 +1,17 @@
-- ECR-039 FunnelDefinition (read catalog)
CREATE TABLE IF NOT EXISTS funnel_definitions (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
code varchar(64) NOT NULL UNIQUE,
title varchar(128) NOT NULL,
active boolean NOT NULL DEFAULT true,
system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_funnel_definitions_active ON funnel_definitions(active);
INSERT INTO funnel_definitions(code, title, active, system)
VALUES ('signup_to_ask', '注册到问答漏斗占位', true, true)
ON CONFLICT (code) DO NOTHING;