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>
This commit is contained in:
Neo
2026-04-06 00:02:37 +08:00
parent 8228b3fa37
commit 70324d8542
185 changed files with 13595 additions and 1219 deletions

View File

@@ -1,6 +1,6 @@
-- =============================================================================
-- etl_feiqiu / dws汇总数据层
-- 生成日期2026-03-15
-- 生成日期2026-04-05
-- 来源:测试库(通过脚本自动导出)
-- =============================================================================
@@ -21,6 +21,9 @@ CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_order_contribution_contribution_
CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_project_tag_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_recharge_commission_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_salary_calc_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_coach_area_hours_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_area_daily_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_board_cache_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_daily_summary_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_discount_detail_id_seq AS bigint;
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_expense_summary_id_seq AS bigint;
@@ -364,6 +367,86 @@ CREATE TABLE dws.dws_assistant_salary_calc (
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE dws.dws_coach_area_hours (
id bigint DEFAULT nextval('dws.dws_coach_area_hours_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
tenant_id bigint NOT NULL,
stat_month date NOT NULL,
assistant_id bigint NOT NULL,
area_code character varying(20) NOT NULL,
base_hours numeric(10,2) DEFAULT 0 NOT NULL,
bonus_hours numeric(10,2) DEFAULT 0 NOT NULL,
room_hours numeric(10,2) DEFAULT 0 NOT NULL,
effective_hours numeric(10,2) DEFAULT 0 NOT NULL,
trashed_hours numeric(10,2) DEFAULT 0 NOT NULL,
base_service_count integer DEFAULT 0 NOT NULL,
bonus_service_count integer DEFAULT 0 NOT NULL,
room_service_count integer DEFAULT 0 NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE dws.dws_finance_area_daily (
id bigint DEFAULT nextval('dws.dws_finance_area_daily_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
tenant_id bigint NOT NULL,
stat_date date NOT NULL,
area_code character varying(20) NOT NULL,
table_fee_amount numeric(14,2) DEFAULT 0 NOT NULL,
goods_amount numeric(14,2) DEFAULT 0 NOT NULL,
assistant_pd_amount numeric(14,2) DEFAULT 0 NOT NULL,
assistant_cx_amount numeric(14,2) DEFAULT 0 NOT NULL,
gross_amount numeric(14,2) DEFAULT 0 NOT NULL,
discount_groupbuy numeric(14,2) DEFAULT 0 NOT NULL,
discount_vip numeric(14,2) DEFAULT 0 NOT NULL,
discount_manual numeric(14,2) DEFAULT 0 NOT NULL,
discount_gift_card numeric(14,2) DEFAULT 0 NOT NULL,
discount_rounding numeric(14,2) DEFAULT 0 NOT NULL,
discount_other numeric(14,2) DEFAULT 0 NOT NULL,
discount_total numeric(14,2) DEFAULT 0 NOT NULL,
confirmed_income numeric(14,2) DEFAULT 0 NOT NULL,
cash_pay_amount numeric(14,2) DEFAULT 0 NOT NULL,
cash_paper_amount numeric(14,2) DEFAULT 0 NOT NULL,
scan_pay_amount numeric(14,2) DEFAULT 0 NOT NULL,
groupbuy_pay_amount numeric(14,2) DEFAULT 0 NOT NULL,
recharge_cash_inflow numeric(14,2) DEFAULT 0 NOT NULL,
cash_inflow_total numeric(14,2) DEFAULT 0 NOT NULL,
cash_outflow_total numeric(14,2) DEFAULT 0 NOT NULL,
cash_balance_change numeric(14,2) DEFAULT 0 NOT NULL,
card_consume_total numeric(14,2) DEFAULT 0 NOT NULL,
recharge_card_consume numeric(14,2) DEFAULT 0 NOT NULL,
gift_card_consume numeric(14,2) DEFAULT 0 NOT NULL,
recharge_cash numeric(14,2) DEFAULT 0 NOT NULL,
first_recharge_cash numeric(14,2) DEFAULT 0 NOT NULL,
renewal_cash numeric(14,2) DEFAULT 0 NOT NULL,
order_count integer DEFAULT 0 NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE dws.dws_finance_board_cache (
id bigint DEFAULT nextval('dws.dws_finance_board_cache_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
time_range character varying(20) NOT NULL,
area_code character varying(20) NOT NULL,
start_date date NOT NULL,
end_date date NOT NULL,
prev_start_date date,
prev_end_date date,
occurrence numeric(14,2) DEFAULT 0 NOT NULL,
discount numeric(14,2) DEFAULT 0 NOT NULL,
discount_rate numeric(8,4) DEFAULT 0 NOT NULL,
confirmed_revenue numeric(14,2) DEFAULT 0 NOT NULL,
cash_in numeric(14,2) DEFAULT 0 NOT NULL,
cash_out numeric(14,2) DEFAULT 0 NOT NULL,
cash_balance numeric(14,2) DEFAULT 0 NOT NULL,
balance_rate numeric(8,4) DEFAULT 0 NOT NULL,
data_fingerprint character varying(64),
computed_at timestamp with time zone DEFAULT now() NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
CREATE TABLE dws.dws_finance_daily_summary (
id bigint DEFAULT nextval('dws.dws_finance_daily_summary_id_seq'::regclass) NOT NULL,
site_id bigint NOT NULL,
@@ -406,7 +489,9 @@ CREATE TABLE dws.dws_finance_daily_summary (
guest_order_count integer DEFAULT 0 NOT NULL,
avg_order_amount numeric(12,2) DEFAULT 0 NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
updated_at timestamp with time zone DEFAULT now() NOT NULL,
cash_paper_amount numeric(14,2) DEFAULT 0 NOT NULL,
scan_pay_amount numeric(14,2) DEFAULT 0 NOT NULL
);
CREATE TABLE dws.dws_finance_discount_detail (
@@ -481,14 +566,14 @@ CREATE TABLE dws.dws_finance_recharge_summary (
total_card_balance numeric(14,2) DEFAULT 0 NOT NULL,
cash_card_balance numeric(14,2) DEFAULT 0 NOT NULL,
gift_card_balance numeric(14,2) DEFAULT 0 NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
gift_liquor_balance numeric(14,2) DEFAULT 0 NOT NULL,
gift_table_fee_balance numeric(14,2) DEFAULT 0 NOT NULL,
gift_voucher_balance numeric(14,2) DEFAULT 0 NOT NULL,
gift_liquor_recharge numeric(14,2) DEFAULT 0 NOT NULL,
gift_table_fee_recharge numeric(14,2) DEFAULT 0 NOT NULL,
gift_voucher_recharge numeric(14,2) DEFAULT 0 NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
gift_voucher_recharge numeric(14,2) DEFAULT 0 NOT NULL
);
CREATE TABLE dws.dws_goods_stock_daily_summary (
@@ -631,7 +716,13 @@ CREATE TABLE dws.dws_member_assistant_relation_index (
ml_display numeric(4,2) DEFAULT 0 NOT NULL,
calc_time timestamp with time zone DEFAULT now() NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
updated_at timestamp with time zone DEFAULT now() NOT NULL,
recall_created_total integer DEFAULT 0 NOT NULL,
recall_completed_total integer DEFAULT 0 NOT NULL,
follow_up_created_total integer DEFAULT 0 NOT NULL,
follow_up_completed_total integer DEFAULT 0 NOT NULL,
total_created integer DEFAULT 0 NOT NULL,
total_completed integer DEFAULT 0 NOT NULL
);
CREATE TABLE dws.dws_member_consumption_summary (
@@ -976,6 +1067,12 @@ ALTER TABLE dws.dws_assistant_project_tag ADD CONSTRAINT uk_dws_assistant_projec
ALTER TABLE dws.dws_assistant_recharge_commission ADD CONSTRAINT dws_assistant_recharge_commission_pkey PRIMARY KEY (id);
ALTER TABLE dws.dws_assistant_salary_calc ADD CONSTRAINT dws_assistant_salary_calc_pkey PRIMARY KEY (id);
ALTER TABLE dws.dws_assistant_salary_calc ADD CONSTRAINT uk_dws_assistant_salary UNIQUE (site_id, assistant_id, salary_month, assistant_level_code);
ALTER TABLE dws.dws_coach_area_hours ADD CONSTRAINT dws_coach_area_hours_pkey PRIMARY KEY (id);
ALTER TABLE dws.dws_coach_area_hours ADD CONSTRAINT dws_coach_area_hours_site_id_stat_month_assistant_id_area_c_key UNIQUE (site_id, stat_month, assistant_id, area_code);
ALTER TABLE dws.dws_finance_area_daily ADD CONSTRAINT dws_finance_area_daily_pkey PRIMARY KEY (id);
ALTER TABLE dws.dws_finance_area_daily ADD CONSTRAINT dws_finance_area_daily_site_id_stat_date_area_code_key UNIQUE (site_id, stat_date, area_code);
ALTER TABLE dws.dws_finance_board_cache ADD CONSTRAINT dws_finance_board_cache_pkey PRIMARY KEY (id);
ALTER TABLE dws.dws_finance_board_cache ADD CONSTRAINT dws_finance_board_cache_site_id_time_range_area_code_key UNIQUE (site_id, time_range, area_code);
ALTER TABLE dws.dws_finance_daily_summary ADD CONSTRAINT dws_finance_daily_summary_pkey PRIMARY KEY (id);
ALTER TABLE dws.dws_finance_daily_summary ADD CONSTRAINT uk_dws_finance_daily UNIQUE (site_id, stat_date);
ALTER TABLE dws.dws_finance_discount_detail ADD CONSTRAINT dws_finance_discount_detail_pkey PRIMARY KEY (id);
@@ -1099,6 +1196,92 @@ CREATE INDEX idx_mv_finance_daily_l3 ON dws.mv_dws_finance_daily_summary_l3 USIN
CREATE INDEX idx_mv_finance_daily_l4 ON dws.mv_dws_finance_daily_summary_l4 USING btree (site_id, stat_date);
-- 视图
CREATE OR REPLACE VIEW dws.v_dws_coach_area_hours AS
SELECT id,
site_id,
tenant_id,
stat_month,
assistant_id,
area_code,
base_hours,
bonus_hours,
room_hours,
effective_hours,
trashed_hours,
base_service_count,
bonus_service_count,
room_service_count,
created_at,
updated_at
FROM dws.dws_coach_area_hours
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
;
CREATE OR REPLACE VIEW dws.v_dws_finance_area_daily AS
SELECT id,
site_id,
tenant_id,
stat_date,
area_code,
table_fee_amount,
goods_amount,
assistant_pd_amount,
assistant_cx_amount,
gross_amount,
discount_groupbuy,
discount_vip,
discount_manual,
discount_gift_card,
discount_rounding,
discount_other,
discount_total,
confirmed_income,
cash_pay_amount,
cash_paper_amount,
scan_pay_amount,
groupbuy_pay_amount,
recharge_cash_inflow,
cash_inflow_total,
cash_outflow_total,
cash_balance_change,
card_consume_total,
recharge_card_consume,
gift_card_consume,
recharge_cash,
first_recharge_cash,
renewal_cash,
order_count,
created_at,
updated_at
FROM dws.dws_finance_area_daily
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
;
CREATE OR REPLACE VIEW dws.v_dws_finance_board_cache AS
SELECT id,
site_id,
time_range,
area_code,
start_date,
end_date,
prev_start_date,
prev_end_date,
occurrence,
discount,
discount_rate,
confirmed_revenue,
cash_in,
cash_out,
cash_balance,
balance_rate,
data_fingerprint,
computed_at,
created_at,
updated_at
FROM dws.dws_finance_board_cache
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
;
CREATE OR REPLACE VIEW dws.v_member_recall_priority AS
SELECT dws_member_winback_index.site_id,
dws_member_winback_index.tenant_id,
@@ -1510,625 +1693,3 @@ CREATE INDEX idx_mv_finance_daily_l2 ON dws.mv_dws_finance_daily_summary_l2 USIN
CREATE INDEX idx_mv_finance_daily_l3 ON dws.mv_dws_finance_daily_summary_l3 USING btree (site_id, stat_date);
CREATE INDEX idx_mv_finance_daily_l4 ON dws.mv_dws_finance_daily_summary_l4 USING btree (site_id, stat_date);
-- =============================================================================
-- 种子数据DWS 配置表初始数据(绩效档位、等级定价、奖金规则、区域分类、技能映射)
-- =============================================================================
-- =============================================================================
-- DWS 配置表初始数据
-- 版本: v4.0
-- 创建日期: 2026-02-01
-- 更新日期: 2026-02-21
-- AI_CHANGELOG [2026-02-21] 取消全文注释,数据已写入 test_etl_feiqiu
-- 新增 2025-01-01~2026-02-28 统一提成档位基础课18元/小时打赏课40%
-- 新增 GUARANTEE 保底奖金规则按等级初级12000/中级16000/高级18000/星级23000
-- 历史分档口径截止日期调整为 2024-12-31
-- 描述: 初始化配置表数据,包含绩效档位、等级定价、奖金规则、区域分类、技能映射
-- =============================================================================
-- =============================================================================
-- 1. cfg_performance_tier - 绩效档位配置(含历史口径)
-- 数据来源DWS 数据库处理需求.md
-- 三段时间线:
-- 2000-01-01 ~ 2024-12-31: 旧方案6档阶梯抽成
-- 2025-01-01 ~ 2026-02-28: 统一提成不分档基础课18元/小时打赏课40%
-- 2026-03-01 ~ 9999-12-31: 新方案5档阶梯抽成
-- =============================================================================
TRUNCATE TABLE dws.cfg_performance_tier RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_performance_tier (
tier_code, tier_name, tier_level,
min_hours, max_hours,
base_deduction, bonus_deduction_ratio, vacation_days, vacation_unlimited,
is_new_hire_tier, effective_from, effective_to, description
) VALUES
-- 旧方案至2024-12-31
('T0', '0档-淘汰压力', 0,
0, 100,
28.00, 0.50, 3, FALSE,
FALSE, '2000-01-01', '2024-12-31',
'旧方案H<100专业课抽成28元/小时打赏课抽成50%休假3天'),
('T1', '1档-及格档', 1,
100, 130,
18.00, 0.40, 4, FALSE,
FALSE, '2000-01-01', '2024-12-31',
'旧方案100≤H<130专业课抽成18元/小时打赏课抽成40%休假4天'),
('T2', '2档-良好档', 2,
130, 160,
15.00, 0.38, 4, FALSE,
FALSE, '2000-01-01', '2024-12-31',
'旧方案130≤H<160专业课抽成15元/小时打赏课抽成38%休假4天'),
('T3', '3档-优秀档', 3,
160, 190,
13.00, 0.35, 5, FALSE,
FALSE, '2000-01-01', '2024-12-31',
'旧方案160≤H<190专业课抽成13元/小时打赏课抽成35%休假5天'),
('T4', '4档-卓越加速档', 4,
190, 220,
10.00, 0.33, 6, FALSE,
FALSE, '2000-01-01', '2024-12-31',
'旧方案190≤H<220专业课抽成10元/小时打赏课抽成33%休假6天'),
('T5', '5档-冠军加速档', 5,
220, NULL,
8.00, 0.30, 0, TRUE,
FALSE, '2000-01-01', '2024-12-31',
'旧方案H≥220专业课抽成8元/小时打赏课抽成30%,休假自由'),
-- 2025-01-01 ~ 2026-02-28: 统一提成(不分档,所有助教统一规则)
-- CHANGE 2026-02-21 | 新增统一提成档位基础课球房提成18元/小时打赏课球房提成40%
('T0', '统一档', 0,
0, NULL,
18.00, 0.40, 0, FALSE,
FALSE, '2025-01-01', '2026-02-28',
'2025-01-01~2026-02-28统一规则基础课球房提成18元/小时打赏课球房提成40%,不分档位'),
-- 新方案2026-03-01起
('T0', '0档-淘汰压力', 0,
0, 120,
28.00, 0.50, 3, FALSE,
FALSE, '2026-03-01', '9999-12-31',
'新方案H<120专业课抽成28元/小时打赏课抽成50%休假3天'),
('T1', '1档-及格档', 1,
120, 150,
18.00, 0.40, 4, FALSE,
FALSE, '2026-03-01', '9999-12-31',
'新方案120≤H<150专业课抽成18元/小时打赏课抽成40%休假4天'),
('T2', '2档-良好档', 2,
150, 180,
13.00, 0.35, 5, FALSE,
FALSE, '2026-03-01', '9999-12-31',
'新方案150≤H<180专业课抽成13元/小时打赏课抽成35%休假5天'),
('T3', '3档-优秀档', 3,
180, 210,
10.00, 0.30, 6, FALSE,
FALSE, '2026-03-01', '9999-12-31',
'新方案180≤H<210专业课抽成10元/小时打赏课抽成30%休假6天'),
('T4', '4档-销冠竞争', 4,
210, NULL,
8.00, 0.25, 0, TRUE,
FALSE, '2026-03-01', '9999-12-31',
'新方案H≥210专业课抽成8元/小时打赏课抽成25%,休假自由');
-- =============================================================================
-- 2. cfg_assistant_level_price - 助教等级定价
-- 说明:
-- - level_code 来自 dim_assistant.assistant_level
-- - 8=助教管理, 10=初级, 20=中级, 30=高级, 40=星级
-- - 价格为客户支付价格(对外价格),助教收入=客户支付-档位抽成
-- - 包厢课基础课统一138元/小时(不随等级变化)
-- =============================================================================
TRUNCATE TABLE dws.cfg_assistant_level_price RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_assistant_level_price (
level_code, level_name,
base_course_price, bonus_course_price,
effective_from, effective_to, description
) VALUES
(10, '初级',
98.00, 190.00,
'2000-01-01', '9999-12-31',
'初级助教基础课98元/时附加课190元/时(客户支付价格)'),
(20, '中级',
108.00, 190.00,
'2000-01-01', '9999-12-31',
'中级助教基础课108元/时附加课190元/时(客户支付价格)'),
(30, '高级',
118.00, 190.00,
'2000-01-01', '9999-12-31',
'高级助教基础课118元/时附加课190元/时(客户支付价格)'),
(40, '星级',
138.00, 190.00,
'2000-01-01', '9999-12-31',
'星级助教基础课138元/时附加课190元/时(客户支付价格)'),
(8, '助教管理',
98.00, 190.00,
'2000-01-01', '9999-12-31',
'助教管理:不参与客户服务计费,默认按初级价格');
-- =============================================================================
-- 3. cfg_bonus_rules - 奖金规则配置
-- 说明:
-- - SPRINT: 冲刺奖金历史口径至2024-12-31
-- - GUARANTEE: 保底月薪线2025-01-01~2026-02-28按等级区分
-- * 保底规则:总课时达标 + 打赏课≥10小时 → 触发保底月薪线
-- * 保底含义:实发 = MAX(课时收入+奖金, 保底金额),非额外奖金
-- * rule_code 中 LV10/LV20/LV30/LV40 对应 level_code
-- - TOP_RANK: Top3排名奖金2026-03-01起
-- CHANGE 2026-02-21 | 新增 GUARANTEE 保底奖金规则
-- =============================================================================
TRUNCATE TABLE dws.cfg_bonus_rules RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_bonus_rules (
rule_type, rule_code, rule_name,
threshold_hours, rank_position, bonus_amount,
is_cumulative, priority,
effective_from, effective_to, description
) VALUES
-- 冲刺奖金历史口径至2024-12-31
('SPRINT', 'SPRINT_190', '冲刺奖金190',
190.00, NULL, 300.00,
FALSE, 1,
'2000-01-01', '2024-12-31',
'历史口径业绩≥190小时获得300元冲刺奖金不累计'),
('SPRINT', 'SPRINT_220', '冲刺奖金220',
220.00, NULL, 800.00,
FALSE, 2,
'2000-01-01', '2024-12-31',
'历史口径业绩≥220小时获得800元冲刺奖金覆盖190档'),
-- 保底奖金2025-01-01 ~ 2026-02-28
-- 按助教等级区分需同时满足总课时和打赏课最低时数≥10小时
('GUARANTEE', 'GUAR_LV10', '初级保底奖金',
130.00, NULL, 12000.00,
FALSE, 10,
'2025-01-01', '2026-02-28',
'初级保底完成130小时课程含≥10小时打赏课保底月薪线12000元实发=MAX(课时收入+奖金, 12000)'),
('GUARANTEE', 'GUAR_LV20', '中级保底奖金',
150.00, NULL, 16000.00,
FALSE, 20,
'2025-01-01', '2026-02-28',
'中级保底完成150小时课程含≥10小时打赏课保底月薪线16000元实发=MAX(课时收入+奖金, 16000)'),
('GUARANTEE', 'GUAR_LV30', '高级保底奖金',
160.00, NULL, 18000.00,
FALSE, 30,
'2025-01-01', '2026-02-28',
'高级保底完成160小时课程含≥10小时打赏课保底月薪线18000元实发=MAX(课时收入+奖金, 18000)'),
('GUARANTEE', 'GUAR_LV40', '星级保底奖金',
170.00, NULL, 23000.00,
FALSE, 40,
'2025-01-01', '2026-02-28',
'星级保底完成170小时课程含≥10小时打赏课保底月薪线23000元实发=MAX(课时收入+奖金, 23000)'),
-- Top排名奖金2026-03-01起
('TOP_RANK', 'TOP_1', 'Top1排名奖金',
NULL, 1, 1000.00,
FALSE, 0,
'2026-03-01', '9999-12-31',
'月度排名第一获得1000元并列都算'),
('TOP_RANK', 'TOP_2', 'Top2排名奖金',
NULL, 2, 600.00,
FALSE, 0,
'2026-03-01', '9999-12-31',
'月度排名第二获得600元并列都算'),
('TOP_RANK', 'TOP_3', 'Top3排名奖金',
NULL, 3, 400.00,
FALSE, 0,
'2026-03-01', '9999-12-31',
'月度排名第三获得400元并列都算');
-- =============================================================================
-- 4. cfg_area_category - 台区分类映射(纯台桌级精确映射)
-- 说明:
-- - 每台桌一行精确映射source_area_name=区域, source_table_name=台桌名
-- - 不使用 LIKE 模糊匹配,仅 EXACT + DEFAULT 兜底
-- - 数据来源: 用户提供的完整台桌清单2026-03-09
-- =============================================================================
TRUNCATE TABLE dws.cfg_area_category RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_area_category (
source_area_name, source_table_name, category_code, category_name,
display_name, short_name,
match_type, match_priority, is_active, description, sort_order
) VALUES
-- ============ BILLIARD 🎱 中式/追分 (sort_order=10) ============
-- A区18台
('A区', 'A1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A1', 10),
('A区', 'A2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A2', 10),
('A区', 'A3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A3', 10),
('A区', 'A4', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A4', 10),
('A区', 'A5', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A5', 10),
('A区', 'A6', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A6', 10),
('A区', 'A7', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A7', 10),
('A区', 'A8', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A8', 10),
('A区', 'A9', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A9', 10),
('A区', 'A10', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A10', 10),
('A区', 'A11', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A11', 10),
('A区', 'A12', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A12', 10),
('A区', 'A13', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A13', 10),
('A区', 'A14', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A14', 10),
('A区', 'A15', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A15', 10),
('A区', 'A16', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A16', 10),
('A区', 'A17', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A17', 10),
('A区', 'A18', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A18', 10),
-- B区15台
('B区', 'B1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B1', 10),
('B区', 'B2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B2', 10),
('B区', 'B3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B3', 10),
('B区', 'B4', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B4', 10),
('B区', 'B5', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B5', 10),
('B区', 'B6', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B6', 10),
('B区', 'B7', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B7', 10),
('B区', 'B8', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B8', 10),
('B区', 'B9', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B9', 10),
('B区', 'B10', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B10', 10),
('B区', 'B11', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B11', 10),
('B区', 'B12', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B12', 10),
('B区', 'B13', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B13', 10),
('B区', 'B14', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B14', 10),
('B区', 'B15', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B15', 10),
-- C区6台
('C区', 'C1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C1', 10),
('C区', 'C2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C2', 10),
('C区', 'C3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C3', 10),
('C区', 'C4', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C4', 10),
('C区', 'C5', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C5', 10),
('C区', 'C6', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C6', 10),
-- VIP包厢 BILLIARD3台
('VIP包厢', 'VIP1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'VIP包厢-VIP1', 10),
('VIP包厢', 'VIP2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'VIP包厢-VIP2', 10),
('VIP包厢', 'VIP3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'VIP包厢-VIP3', 10),
-- TV台1台
('TV台', 'TV', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'TV台-TV', 10),
-- ============ SNOOKER 斯诺克 ============
('VIP包厢', 'VIP5', 'SNOOKER', '斯诺克', '斯诺克', '', 'EXACT', 10, TRUE, 'VIP包厢-VIP5→斯诺克', 20),
('斯诺克区', 'S1', 'SNOOKER', '斯诺克', '斯诺克', '', 'EXACT', 10, TRUE, '斯诺克区-S1', 20),
('斯诺克区', 'S2', 'SNOOKER', '斯诺克', '斯诺克', '', 'EXACT', 10, TRUE, '斯诺克区-S2', 20),
('斯诺克区', 'S3', 'SNOOKER', '斯诺克', '斯诺克', '', 'EXACT', 10, TRUE, '斯诺克区-S3', 20),
('斯诺克区', 'S4', 'SNOOKER', '斯诺克', '斯诺克', '', 'EXACT', 10, TRUE, '斯诺克区-S4', 20),
-- ============ MAHJONG 🀄 麻将/棋牌 ============
('666', '董事办', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '666-董事办', 30),
('666', '666', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '666-666', 30),
('麻将房', '1', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-1', 30),
('麻将房', 'M2', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M2', 30),
('麻将房', 'M3', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M3', 30),
('麻将房', 'M4', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M4', 30),
('麻将房', 'M5', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M5', 30),
('M7', 'M7', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, 'M7-M7', 30),
('M7', '大包麻将房', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, 'M7-大包麻将房', 30),
('M8', 'M8', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, 'M8-M8', 30),
('发财', '发财', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '发财-发财', 30),
-- ============ KTV 🎤 团建/K歌 ============
('K包', '常乐', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-常乐', 40),
('K包', '幸会(纯k)', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-幸会(纯k)', 40),
('K包', '虚拟188', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-虚拟188', 40),
('K包', '888', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-888', 40),
('k包活动区', '大包', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'k包活动区-大包', 40),
('k包活动区', '小包', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'k包活动区-小包', 40),
('幸会158', '纯k', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, '幸会158-纯k', 40),
-- ============ SPECIAL 补时长/虚拟台 ============
('补时长', '补时长', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '补时长-补时长', 900),
('补时长', '补时长2', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '补时长-补时长2', 900),
('补时长', '补时长3', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '补时长-补时长3', 900),
('补时长', '补时长4', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '补时长-补时长4', 900),
('补时长', '补时长5', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '补时长-补时长5', 900),
('补时长', '补时长6', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '补时长-补时长6', 900),
('补时长', '补时长7', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '补时长-补时长7', 900),
('虚拟台', '虚拟台1号', 'SPECIAL', '补时长', '补时长', '', 'EXACT', 10, TRUE, '虚拟台-虚拟台1号', 900),
-- ============ OTHER 兜底 ============
('DEFAULT', NULL, 'OTHER', '其他', '其他', '', 'DEFAULT', 999, TRUE, '兜底规则:无法匹配的归入其他', 999);
-- =============================================================================
-- 5. cfg_skill_type - 技能→课程类型映射
-- 说明:
-- - 将 skill_id 映射到课程类型
-- - 基础课/陪打: skill_id = 2791903611396869
-- - 附加课/超休: skill_id = 2807440316432197
-- - 避免依赖 skill_name 文本匹配
-- =============================================================================
TRUNCATE TABLE dws.cfg_skill_type RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_skill_type (
skill_id, skill_name,
course_type_code, course_type_name,
is_active, description
) VALUES
(2791903611396869, '台球基础陪打',
'BASE', '基础课',
TRUE, '基础课:陪打服务,按助教等级计价'),
(2807440316432197, '台球超休服务',
'BONUS', '附加课',
TRUE, '附加课:超休/激励课固定190元/小时'),
(2807440316432198, '包厢服务',
'BASE', '基础课',
TRUE, '包厢服务归入基础课统计统一按138元/小时计价');
-- =============================================================================
-- 6~8. 优惠类型/支出类型/平台类型 — 作为代码常量使用,不单独建表
-- =============================================================================
-- 优惠类型: GROUPBUY/VIP/GIFT_CARD/MANUAL/ROUNDING/BIG_CUSTOMER/OTHER
-- 支出类型: RENT/UTILITY/PROPERTY/SALARY/REIMBURSE/PLATFORM_FEE/OTHER
-- 平台类型: MEITUAN/DOUYIN/DIANPING/OTHER
-- =============================================================================
-- 验证数据插入
-- =============================================================================
DO $
DECLARE
v_tier_count INTEGER;
v_price_count INTEGER;
v_bonus_count INTEGER;
v_area_count INTEGER;
v_skill_count INTEGER;
BEGIN
SELECT COUNT(*) INTO v_tier_count FROM dws.cfg_performance_tier;
SELECT COUNT(*) INTO v_price_count FROM dws.cfg_assistant_level_price;
SELECT COUNT(*) INTO v_bonus_count FROM dws.cfg_bonus_rules;
SELECT COUNT(*) INTO v_area_count FROM dws.cfg_area_category;
SELECT COUNT(*) INTO v_skill_count FROM dws.cfg_skill_type;
RAISE NOTICE '配置数据初始化完成:';
RAISE NOTICE ' - cfg_performance_tier: % 条', v_tier_count;
RAISE NOTICE ' - cfg_assistant_level_price: % 条', v_price_count;
RAISE NOTICE ' - cfg_bonus_rules: % 条', v_bonus_count;
RAISE NOTICE ' - cfg_area_category: % 条', v_area_count;
RAISE NOTICE ' - cfg_skill_type: % 条', v_skill_count;
END;
$;
-- =============================================================================
-- 种子数据指数算法参数NCI/WBI/RS/OS/MS/ML/SPI
-- =============================================================================
-- =============================================================================
-- 指数算法参数初始化脚本
-- 版本: v3.0
-- 创建日期: 2026-02-13
-- 描述: 仅保留 RS / OS / MS / ML / NCI / WBI 指数参数(已移除 RECALL / INTIMACY
-- AI_CHANGELOG [2026-02-13] 移除 RECALL/INTIMACY 参数及 ML 废弃参数source_mode/recharge_attribute_hours
-- =============================================================================
-- 清理旧版指数参数
DELETE FROM dws.cfg_index_parameters WHERE index_type IN ('RECALL', 'INTIMACY');
-- 清理 ML 已废弃参数
DELETE FROM dws.cfg_index_parameters WHERE index_type = 'ML' AND param_name IN ('source_mode', 'recharge_attribute_hours');
INSERT INTO dws.cfg_index_parameters
(index_type, param_name, param_value, description, effective_from)
VALUES
('NCI', 'active_new_penalty', 0.200000, 'active-new suppression multiplier', DATE '2026-02-06'),
('NCI', 'active_new_recency_days', 7.000000, 'active-new recency window (days)', DATE '2026-02-06'),
('NCI', 'active_new_visit_threshold_14d', 2.000000, 'active-new threshold in 14d visits', DATE '2026-02-06'),
('NCI', 'amount_base_M0', 300.000000, 'spend log base M0', DATE '2026-02-06'),
('NCI', 'balance_base_B0', 500.000000, 'balance log base B0', DATE '2026-02-06'),
('NCI', 'compression_mode', 0.000000, 'compression mode', DATE '2026-02-06'),
('NCI', 'enable_stop_high_balance_exception', 0.000000, 'enable high-balance STOP exception', DATE '2026-02-06'),
('NCI', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
('NCI', 'h_recharge', 7.000000, 'recharge decay half-life (days)', DATE '2026-02-06'),
('NCI', 'high_balance_threshold', 1000.000000, 'high-balance threshold', DATE '2026-02-06'),
('NCI', 'lookback_days_recency', 60.000000, 'recency lookback window (days)', DATE '2026-02-06'),
('NCI', 'new_days_threshold', 30.000000, 'new member days threshold', DATE '2026-02-06'),
('NCI', 'new_recharge_max_visits', 10.000000, 'max visits for new-recharge grouping', DATE '2026-02-06'),
('NCI', 'new_visit_threshold', 2.000000, 'new member visit threshold', DATE '2026-02-06'),
('NCI', 'no_touch_days_new', 3.000000, 'no-touch threshold (days)', DATE '2026-02-06'),
('NCI', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
('NCI', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
('NCI', 'recharge_recent_days', 14.000000, 'recent recharge window (days)', DATE '2026-02-06'),
('NCI', 'salvage_end', 60.000000, 'salvage decay end day', DATE '2026-02-06'),
('NCI', 'salvage_start', 30.000000, 'salvage decay start day', DATE '2026-02-06'),
('NCI', 't2_target_days', 7.000000, 'second-visit target window (days)', DATE '2026-02-06'),
('NCI', 'use_smoothing', 1.000000, 'enable smoothing', DATE '2026-02-06'),
('NCI', 'value_w_bal', 0.800000, 'value weight for balance', DATE '2026-02-06'),
('NCI', 'value_w_spend', 1.000000, 'value weight for spend', DATE '2026-02-06'),
('NCI', 'visit_lookback_days', 180.000000, 'visit history lookback (days)', DATE '2026-02-06'),
('NCI', 'w_need', 1.600000, 'need weight', DATE '2026-02-06'),
('NCI', 'w_re', 0.800000, 'recharge pressure weight', DATE '2026-02-06'),
('NCI', 'w_value', 1.000000, 'value weight', DATE '2026-02-06'),
('NCI', 'w_welcome', 1.000000, 'welcome-stage weight', DATE '2026-02-06'),
('NCI', 'welcome_window_days', 3.000000, 'welcome outreach window for first touch (days)', DATE '2026-02-06'),
('WBI', 'amount_base_M0', 300.000000, 'spend log base M0', DATE '2026-02-06'),
('WBI', 'balance_base_B0', 500.000000, 'balance log base B0', DATE '2026-02-06'),
('WBI', 'compression_mode', 0.000000, 'compression mode', DATE '2026-02-06'),
('WBI', 'enable_stop_high_balance_exception', 0.000000, 'enable high-balance STOP exception', DATE '2026-02-06'),
('WBI', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
('WBI', 'h_recharge', 7.000000, 'recharge decay half-life (days)', DATE '2026-02-06'),
('WBI', 'high_balance_threshold', 1000.000000, 'high-balance threshold', DATE '2026-02-06'),
('WBI', 'lookback_days_recency', 60.000000, 'recency lookback window (days)', DATE '2026-02-06'),
('WBI', 'new_days_threshold', 30.000000, 'new member days threshold', DATE '2026-02-06'),
('WBI', 'new_recharge_max_visits', 10.000000, 'max visits for new-recharge grouping', DATE '2026-02-06'),
('WBI', 'new_visit_threshold', 2.000000, 'new member visit threshold', DATE '2026-02-06'),
('WBI', 'overdue_alpha', 2.000000, 'overdue fallback alpha', DATE '2026-02-06'),
('WBI', 'overdue_weight_blend_min_samples', 8.000000, 'minimum samples to fully trust weighted overdue CDF', DATE '2026-02-07'),
('WBI', 'overdue_weight_halflife_days', 30.000000, 'overdue weighted-CDF interval half-life (days)', DATE '2026-02-07'),
('WBI', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
('WBI', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
('WBI', 'recency_gate_days', 14.000000, 'recency suppression gate center (days)', DATE '2026-02-06'),
('WBI', 'recency_gate_slope_days', 3.000000, 'recency suppression slope (days)', DATE '2026-02-06'),
('WBI', 'recency_hard_floor_days', 14.000000, 'hard floor for winback recency (days)', DATE '2026-02-06'),
('WBI', 'recharge_recent_days', 14.000000, 'recent recharge window (days)', DATE '2026-02-06'),
('WBI', 'use_smoothing', 1.000000, 'enable smoothing', DATE '2026-02-06'),
('WBI', 'value_w_bal', 1.000000, 'value weight for balance', DATE '2026-02-06'),
('WBI', 'value_w_spend', 1.000000, 'value weight for spend', DATE '2026-02-06'),
('WBI', 'visit_lookback_days', 180.000000, 'visit history lookback (days)', DATE '2026-02-06'),
('WBI', 'w_drop', 1.000000, 'drop weight', DATE '2026-02-06'),
('WBI', 'w_over', 2.000000, 'overdue weight', DATE '2026-02-06'),
('WBI', 'w_re', 0.400000, 'recharge pressure weight', DATE '2026-02-06'),
('WBI', 'w_value', 1.200000, 'value weight', DATE '2026-02-06')
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
param_value = EXCLUDED.param_value,
description = EXCLUDED.description,
updated_at = NOW();
-- =============================================================================
-- 关系指数RS/OS/MS/ML参数
-- 生效时间:北京时间 2026-01-01按数据库日期管理
-- =============================================================================
INSERT INTO dws.cfg_index_parameters
(index_type, param_name, param_value, description, effective_from)
VALUES
-- RS关系强度
('RS', 'lookback_days', 60.000000, '服务行为回溯窗口(天)', DATE '2026-01-01'),
('RS', 'session_merge_hours', 4.000000, '会话合并阈值(小时)', DATE '2026-01-01'),
('RS', 'incentive_weight', 1.500000, '激励课权重', DATE '2026-01-01'),
('RS', 'halflife_session', 14.000000, '会话半衰期(天)', DATE '2026-01-01'),
('RS', 'halflife_last', 10.000000, '最近一次服务半衰期(天)', DATE '2026-01-01'),
('RS', 'weight_f', 1.000000, '频次项权重', DATE '2026-01-01'),
('RS', 'weight_d', 0.700000, '时长项权重', DATE '2026-01-01'),
('RS', 'gate_alpha', 0.600000, '最近服务门控指数', DATE '2026-01-01'),
('RS', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
('RS', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
('RS', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-01-01'),
('RS', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
('RS', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01'),
-- OS归属份额
('OS', 'min_rs_raw_for_ownership', 0.050000, '参与归属计算的最小RS_raw', DATE '2026-01-01'),
('OS', 'min_total_rs_raw', 0.100000, '形成稳定归属的最小sum_rs', DATE '2026-01-01'),
('OS', 'ownership_main_threshold', 0.600000, '主责阈值', DATE '2026-01-01'),
('OS', 'ownership_comanage_threshold', 0.350000, '共管阈值', DATE '2026-01-01'),
('OS', 'ownership_gap_threshold', 0.150000, '主责与次席份额差阈值', DATE '2026-01-01'),
('OS', 'eps', 0.000001, '数值稳定项', DATE '2026-01-01'),
-- MS升温动量
('MS', 'lookback_days', 60.000000, '服务行为回溯窗口(天)', DATE '2026-01-01'),
('MS', 'session_merge_hours', 4.000000, '会话合并阈值(小时)', DATE '2026-01-01'),
('MS', 'incentive_weight', 1.500000, '激励课权重', DATE '2026-01-01'),
('MS', 'halflife_short', 7.000000, '短期半衰期(天)', DATE '2026-01-01'),
('MS', 'halflife_long', 30.000000, '长期半衰期(天)', DATE '2026-01-01'),
('MS', 'eps', 0.000001, '数值稳定项', DATE '2026-01-01'),
('MS', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
('MS', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
('MS', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-01-01'),
('MS', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
('MS', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01'),
-- ML付费关联
('ML', 'lookback_days', 60.000000, '充值行为回溯窗口(天)', DATE '2026-01-01'),
('ML', 'amount_base', 500.000000, '金额压缩基准', DATE '2026-01-01'),
('ML', 'halflife_recharge', 21.000000, '充值半衰期(天)', DATE '2026-01-01'),
('ML', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
('ML', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
('ML', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-01-01'),
('ML', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
('ML', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01')
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
param_value = EXCLUDED.param_value,
description = EXCLUDED.description,
updated_at = NOW();
-- =============================================================================
-- SPI消费力指数参数
-- 生效时间:北京时间 2026-02-23
-- =============================================================================
INSERT INTO dws.cfg_index_parameters
(index_type, param_name, param_value, description, effective_from)
VALUES
-- 窗口参数
('SPI', 'spend_window_short_days', 30.000000, '短期消费窗口(天)', DATE '2026-02-23'),
('SPI', 'spend_window_long_days', 90.000000, '长期消费窗口(天)', DATE '2026-02-23'),
('SPI', 'ewma_alpha_daily_spend', 0.300000, '日消费 EWMA 平滑系数', DATE '2026-02-23'),
-- 金额压缩基数(基于典型台球门店消费水平的初始默认值)
('SPI', 'amount_base_spend_30', 500.000000, '30天消费额压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_spend_90', 1500.000000, '90天消费额压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_ticket_90', 200.000000, '90天客单价压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_recharge_90', 1000.000000, '90天充值额压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_speed_abs', 100.000000, '绝对速度压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_ewma_90', 50.000000, '日消费EWMA压缩基数', DATE '2026-02-23'),
-- Level 子分权重
('SPI', 'w_level_spend_30', 0.300000, 'Level子分30天消费权重', DATE '2026-02-23'),
('SPI', 'w_level_spend_90', 0.350000, 'Level子分90天消费权重', DATE '2026-02-23'),
('SPI', 'w_level_ticket_90', 0.200000, 'Level子分90天客单权重', DATE '2026-02-23'),
('SPI', 'w_level_recharge_90', 0.150000, 'Level子分90天充值权重', DATE '2026-02-23'),
-- Speed 子分权重
('SPI', 'w_speed_abs', 0.500000, 'Speed子分绝对速度权重', DATE '2026-02-23'),
('SPI', 'w_speed_rel', 0.300000, 'Speed子分相对速度权重', DATE '2026-02-23'),
('SPI', 'w_speed_ewma', 0.200000, 'Speed子分EWMA速度权重', DATE '2026-02-23'),
-- 总分权重
('SPI', 'weight_level', 0.600000, 'SPI总分Level子分权重', DATE '2026-02-23'),
('SPI', 'weight_speed', 0.300000, 'SPI总分Speed子分权重', DATE '2026-02-23'),
('SPI', 'weight_stability', 0.100000, 'SPI总分Stability子分权重', DATE '2026-02-23'),
-- 稳定性参数
('SPI', 'stability_window_days', 90.000000, '稳定性计算窗口(天)', DATE '2026-02-23'),
('SPI', 'use_stability', 1.000000, '是否启用稳定性子分0=关闭,1=启用', DATE '2026-02-23'),
-- 映射与平滑
('SPI', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-02-23'),
('SPI', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-02-23'),
('SPI', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-02-23'),
('SPI', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-02-23'),
('SPI', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-02-23'),
-- 速度计算
('SPI', 'speed_epsilon', 0.000001, '速度计算防除零小量', DATE '2026-02-23')
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
param_value = EXCLUDED.param_value,
description = EXCLUDED.description,
updated_at = NOW();
-- =============================================================================
-- 验证
-- =============================================================================
DO $
DECLARE
rs_count INTEGER;
os_count INTEGER;
ms_count INTEGER;
ml_count INTEGER;
nci_count INTEGER;
wbi_count INTEGER;
spi_count INTEGER;
BEGIN
SELECT COUNT(*) INTO rs_count
FROM dws.cfg_index_parameters
WHERE index_type = 'RS';
SELECT COUNT(*) INTO os_count
FROM dws.cfg_index_parameters
WHERE index_type = 'OS';
SELECT COUNT(*) INTO ms_count
FROM dws.cfg_index_parameters
WHERE index_type = 'MS';
SELECT COUNT(*) INTO ml_count
FROM dws.cfg_index_parameters
WHERE index_type = 'ML';
SELECT COUNT(*) INTO nci_count
FROM dws.cfg_index_parameters
WHERE index_type = 'NCI';
SELECT COUNT(*) INTO wbi_count
FROM dws.cfg_index_parameters
WHERE index_type = 'WBI';
SELECT COUNT(*) INTO spi_count
FROM dws.cfg_index_parameters
WHERE index_type = 'SPI';
RAISE NOTICE 'RS 参数数量: %', rs_count;
RAISE NOTICE 'OS 参数数量: %', os_count;
RAISE NOTICE 'MS 参数数量: %', ms_count;
RAISE NOTICE 'ML 参数数量: %', ml_count;
RAISE NOTICE '新客转化参数数量: %', nci_count;
RAISE NOTICE '唤回指数参数数量: %', wbi_count;
RAISE NOTICE 'SPI 消费力指数参数数量: %', spi_count;
END $;
SELECT
index_type,
param_name,
param_value,
description,
effective_from
FROM dws.cfg_index_parameters
ORDER BY index_type, param_name, effective_from;